Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why static string in .rodata section has a four dots prefix in GCC?

Tags:

c

gcc

assembly

For the following code:

#include <stdio.h>

int main() {
    printf("Hello World");
    printf("Hello World1");
    return 0;
}

the generated assembly for calling printf is as follows (64 bits):

  400474:   be 24 06 40 00          mov    esi,0x400624
  400479:   bf 01 00 00 00          mov    edi,0x1
  40047e:   31 c0                   xor    eax,eax
  400480:   e8 db ff ff ff          call   400460 <__printf_chk@plt>
  400485:   be 30 06 40 00          mov    esi,0x400630
  40048a:   bf 01 00 00 00          mov    edi,0x1
  40048f:   31 c0                   xor    eax,eax
  400491:   e8 ca ff ff ff          call   400460 <__printf_chk@plt>

And the .rodata section is as follows:

Contents of section .rodata:
 400620 01000200 48656c6c 6f20576f 726c6400  ....Hello World.
 400630 48656c6c 6f20576f 726c6431 00        Hello World1.

Based on the assembly code, the first call for printf has the argument with address 400624 which has a 4 byte offset from the start of .rodata. I know it skips the first 4 bytes for these 4 dots prefix here. But my question is why GCC/linker produce this prefix for string in .rodata ? I am using 4.8.4 GCC on Ubuntu 14.04. The compilation cmd is just: gcc -Ofast my-source.c -o my-program.

like image 639
dianpeng Avatar asked Dec 28 '25 16:12

dianpeng


2 Answers

For starters, those are not four dots, the dot just means unprintable character. You can see in the hex dump that those bytes are 01 00 02 00.

The final program contains other object files added by the linker, which are part of the C runtime library. This data is used by code there.

You can see the address is 0x400620. You can then try to find a matching symbol, for example you can load it into gdb and use the info symbol command:

(gdb) info symbol 0x4005f8
_IO_stdin_used in section .rodata of /tmp/a.out

(Note I had a different address.)

Taking it further, you can actually find the source for this in glibc:

/* This records which stdio is linked against in the application. */
const int _IO_stdin_used = _G_IO_IO_FILE_VERSION;

and

#define _G_IO_IO_FILE_VERSION 0x20001

Which corresponds to the value you see if you account for little-endian storage.

like image 91
Jester Avatar answered Dec 30 '25 06:12

Jester


It does not prefix the data. The .rodata can contain anything. The first four bytes are [seemingly] a string, but it just happens to link there (i.e. it's for something else). It is unrelated to your "Hello World"

like image 35
Craig Estey Avatar answered Dec 30 '25 06:12

Craig Estey



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!