0

I created the following program:

char*_="Hello, world!";

Then create an object file:

gcc -c test.c

When I look at the object file I see:

cat test.o
ELF>�@@
             Hello, world!GCC: (GNU) 5.3.1 20160406 (Red Hat 5.3.1-6).symtab.strtab.shstrtab.text.rela.data.bss.rodata.str1.1.comment.note.GNU-stack��test.c_@&!@�  H12H@0V-I��Y��
    �

I can see my string in the program. HOw does it work?

It's not in .rodata:

objdump -s -j .rodata test.o
objdump: section '.rodata' mentioned in a -j option, but not found in any input file
  • 1
    Where do you think your string literal should get stored? – Sourav Ghosh May 15 '16 at 10:59
  • 2
    Possible duplicate of [C String literals: Where do they go?](http://stackoverflow.com/questions/2589949/c-string-literals-where-do-they-go) – kaylum May 15 '16 at 11:04
  • @kaylum Nope, try it yourself – user6336793 May 15 '16 at 11:06
  • Your string is static data. It has to be encoded *somehow*, and in fact it's stored just as it would appear in memory. There's a Unix command called `strings` that tries to extract all of the printable strings from a binary file. I suggest trying `strings test.o` for a more readable version of what you're looking at. – Tom Karzes May 15 '16 at 11:07
  • @user6336793 If you read the answers carefully you will understand that the behaviour is platform and compiler dependent. On my platform (x86 Linux, gcc 4.8.4) the string is indeed stored in a read only data section. Anyway, what exactly are you trying to ask? Suffice it to say that the string is stored somewhere in the object and is viewable when the object is inspected. – kaylum May 15 '16 at 11:16
  • "*`objdump -s -j .rodata test.o`*" works for me. I get "`[...] Contents of section .rodata: [...] Hello, world!.`" – alk May 15 '16 at 11:57

1 Answers1

0

The symbol is not in .rodata because it is not read-only, even if it addresses a string literal, which is read-only:

foo.c

char * HelloWorld = "Hello, world!";

See:

$ gcc -c foo.c
$ objdump -t foo.o

foo.o:     file format elf64-x86-64

SYMBOL TABLE:
0000000000000000 l    df *ABS*  0000000000000000 foo.c
0000000000000000 l    d  .text  0000000000000000 .text
0000000000000000 l    d  .data  0000000000000000 .data
0000000000000000 l    d  .bss   0000000000000000 .bss
0000000000000000 l    d  .rodata    0000000000000000 .rodata
0000000000000000 l    d  .note.GNU-stack    0000000000000000 .note.GNU-stack
0000000000000000 l    d  .comment   0000000000000000 .comment
0000000000000000 g     O .data  0000000000000008 HelloWorld

The symbol is in .data, and:

$ objdump -s -j .rodata foo.o

foo.o:     file format elf64-x86-64

Contents of section .rodata:
 0000 48656c6c 6f2c2077 6f726c64 2100      Hello, world!.

the string literal is in .rodata

bar.c

char * const HelloWorld = "Hello, world!";

Here the symbol is read-only, and it's in .rodata

$ gcc -c bar.c
$ objdump -t bar.o

bar.o:     file format elf64-x86-64

SYMBOL TABLE:
0000000000000000 l    df *ABS*  0000000000000000 bar.c
0000000000000000 l    d  .text  0000000000000000 .text
0000000000000000 l    d  .data  0000000000000000 .data
0000000000000000 l    d  .bss   0000000000000000 .bss
0000000000000000 l    d  .rodata    0000000000000000 .rodata
0000000000000000 l    d  .note.GNU-stack    0000000000000000 .note.GNU-stack
0000000000000000 l    d  .comment   0000000000000000 .comment
0000000000000010 g     O .rodata    0000000000000008 HelloWorld

And the string literal is also in .rodata:

$ objdump -s -j .rodata bar.o

bar.o:     file format elf64-x86-64

Contents of section .rodata:
 0000 48656c6c 6f2c2077 6f726c64 21000000  Hello, world!...
 0010 00000000 00000000                    ........  
Mike Kinghan
  • 55,740
  • 12
  • 153
  • 182