Page 1 of 1

GNU ld question

Posted: Wed Jan 04, 2017 1:51 pm
by bzt
I have a really simple question. The elf documentation states:
.strtab
Strings, most commonly the strings that represent the names associated with symbol table entries. If the file has a loadable segment that includes the symbol string table, the section's attributes will include the SHF_ALLOC bit. Otherwise, that bit will be turned off.

.symtab
Symbol table, as "Symbol Table" describes. If the file has a loadable segment that includes the symbol table, the section's attributes will include the SHF_ALLOC bit. Otherwise, that bit will be turned off.
So my question is, how to do that? How to tell ld to include those sections in a loadable segment? The documentation neglect to tell that little detail...

I can control any other sections, but not these, because ld simply ignores my rules (so does objdump ignore these sections). I've tried all variations I could think of, I've googled a lot but nothing. I've also checked command line options and maybe if PHDRS command has some magic keyword for it, but nothing. Here's my linker script that I think should work:

Code: Select all

    .text CORE_ADDRESS + SIZEOF_HEADERS + (8192): AT(ADDR(.text) - CORE_ADDRESS + SIZEOF_HEADERS)
    {
           ...
        *(.text)
        *(.symtab)
        *(.strtab)
           ...
    } :text
And the output:

Code: Select all

Section Headers:
     ....
  [10] .symtab           SYMTAB           0000000000000000  000224a8
       0000000000001bf0  0000000000000018          11    96     8
  [11] .strtab           STRTAB           0000000000000000  00024098
       0000000000000b9c  0000000000000000           0     0     1

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000000000 0xffffffffffe02000 0x0000000000002078
                 0x0000000000018140 0x0000000000018140  RWE    80

 Section to Segment mapping:
  Segment Sections...
   00     .text .got.plt
As you can see, LOAD segment ends at 18140, and symbol table starts at 24098 and not listed in segment mapping.

Please somebody restore my faith in GNU software...

Re: GNU ld question

Posted: Wed Jan 04, 2017 10:05 pm
by bzt
Nobody?

Re: GNU ld question

Posted: Wed Jan 04, 2017 11:34 pm
by alexfru
Compile and link with something like -g option?

Re: GNU ld question

Posted: Thu Jan 05, 2017 4:17 am
by bzt
alexfru wrote:Compile and link with something like -g option?
Thank you for your answer!

Actually it makes the situation even worse, as -g puts some more sections between the text section and the symtab, so the symbol table gets further away from the loadable segment :-(

It's not nice at all, but I've workarounded by loading the entire file instead of the segment and adding ". += 4096" before the bss_start in linker script.

Re: GNU ld question

Posted: Thu Jan 05, 2017 5:00 am
by cyr1x
Add a DYNAMIC program header like this:

Code: Select all

PHDRS
{
    text PT_LOAD FLAGS(5);
...
    dynamic PT_DYNAMIC;
}
The symbol and string tables will be located therein.

Re: GNU ld question

Posted: Thu Jan 05, 2017 5:19 am
by alexfru
bzt wrote:
alexfru wrote:Compile and link with something like -g option?
Thank you for your answer!

Actually it makes the situation even worse, as -g puts some more sections between the text section and the symtab, so the symbol table gets further away from the loadable segment :-(

It's not nice at all, but I've workarounded by loading the entire file instead of the segment and adding ". += 4096" before the bss_start in linker script.
I think the symbol and string sections, even if they're loadable, should (or can be made to) work at any location.

Re: GNU ld question

Posted: Thu Jan 05, 2017 5:37 am
by xenos
I don't know about .symtab and .strtab (I haven't tried with those so far), but if you have a dynamic object / shared library, then the .dynsym and .dynstr sections can definitely be placed in loadable segments. If you have exported symbols that you want to access, they will be in these sections anyway, so these would be the ones you need. I guess this is also what cyr1x was referring to. Have a look at my linker script, this is how it works in my kernel:

https://github.com/xenos1984/NOS/blob/m ... script#L60

Re: GNU ld question

Posted: Thu Jan 05, 2017 5:41 am
by bzt
cyr1x wrote:Add a DYNAMIC program header like this:

Code: Select all

PHDRS
{
    text PT_LOAD FLAGS(5);
...
    dynamic PT_DYNAMIC;
}
The symbol and string tables will be located therein.
Good thinking, already tried that, but my dynamic section is empty:

Code: Select all

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000000000 0xffffffffffe02000 0x00000000000000b0
                 0x0000000000019000 0x0000000000019000  R E    80
  DYNAMIC        0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000         8
Doesn't matter whether I add the following to linker script or not

Code: Select all

    .dynamic : { *(.dynamic) } :text :dynamic
After a long google session it turned out it's a bug in ld that came in somewhere around 2.23 and still exists in my version 2.27
http://stackoverflow.com/questions/2929 ... mbol-table
But I appreciate it, it was a good advice btw.

Re: GNU ld question

Posted: Thu Jan 05, 2017 5:43 am
by bzt
alexfru wrote:I think the symbol and string sections, even if they're loadable, should (or can be made to) work at any location.
You are absolutely right. My problem was:
1. the symbol table is not in the loadable segment, so it was not loaded into memory in the first place
2. even when I modified my loader to load the entire file, the address of symbol table is above __bss_start, so it's got overwritten as soon as I initialize pmm.

Re: GNU ld question

Posted: Thu Jan 05, 2017 5:50 am
by alexfru
bzt wrote:
alexfru wrote:I think the symbol and string sections, even if they're loadable, should (or can be made to) work at any location.
You are absolutely right. My problem was:
1. the symbol table is not in the loadable segment, so it was not loaded into memory in the first place
2. even when I modified my loader to load the entire file, the address of symbol table is above __bss_start, so it's got overwritten as soon as I initialize pmm.
If the symbol and string tables aren't loadable (as is the case in object files prior to linking), they clearly don't have any designated location and any should do. They are not essential for execution. Look up the ELF spec. The symbol/string info is tied to sections in relative terms (section index, offset within section and so on). Where this info is located itself doesn't matter.

Re: GNU ld question

Posted: Thu Jan 05, 2017 5:54 am
by cyr1x
XenOS wrote:I don't know about .symtab and .strtab (I haven't tried with those so far), but if you have a dynamic object / shared library, then the .dynsym and .dynstr sections can definitely be placed in loadable segments. If you have exported symbols that you want to access, they will be in these sections anyway, so these would be the ones you need. I guess this is also what cyr1x was referring to.
You are absolutely right. Now I remember this was the exact same problem I faced. Switching to .dynsym and .dynstr fixed it for me.

Re: GNU ld question

Posted: Thu Jan 05, 2017 5:54 am
by bzt
XenOS wrote:I don't know about .symtab and .strtab (I haven't tried with those so far), but if you have a dynamic object / shared library, then the .dynsym and .dynstr sections can definitely be placed in loadable segments. If you have exported symbols that you want to access, they will be in these sections anyway, so these would be the ones you need. I guess this is also what cyr1x was referring to. Have a look at my linker script, this is how it works in my kernel:

https://github.com/xenos1984/NOS/blob/m ... script#L60
Thanks, I've tried that, but my kernel is not a shared library. Maybe that's the reason why my dynamic section is empty? Anyway I managed to create a workaround :-)

About .symtab and .strtab: they are exactly the same as .dynsym and .dynstr, only it's not in loader's view (phdr) but in linker's view (shdr). For debugging it's better as .symtab has all the symbols, not just the exported public ones. I've wrote an wiki page on how to find them.