This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: Section (.sdata2) being omitted but SIZEOF(.sdata2) is not zero?


> I'm thinking that I might now have gotten up the courage to add some
> instrumentation to ld to try to figure this out.  If it's outputting a map file
> entry for .sdata2  but not an elf section, maybe I'll be able to figure out why it
> seems to be losing track of .sdata2 between outputting the map and
> outputting the elf.

My head hurts from wading through code that I really don't understand well at all, so I need a break.  I have a working theory that I'm hoping you can either shoot down or tell me if I'm on the right track.

What I know so far is that when .sdata2 is not output to the output elf file, the reason is that it is having SEC_EXCLUDE set here:

(gdb) bt
#0  strip_excluded_output_sections () at ldlang.c:3900
#1  0x0000000000420ae2 in before_allocation_default () at ldemul.c:241
#2  0x0000000000428515 in gldelf32ppc_before_allocation () at eelf32ppc.c:1300
#3  0x0000000000426788 in ppc_before_allocation () at eelf32ppc.c:198
#4  0x0000000000420716 in ldemul_before_allocation () at ldemul.c:78
#5  0x00000000004173df in lang_process () at ldlang.c:6737
#6  0x000000000041afba in main (argc=1101, argv=0x7dc170) at ./ldmain.c:411

I think the reason this is happening is that some or all of the 4KB alignment calculations are being done on addresses before some sections have been removed due to --gc-sections.  For example,
at line 861 in binutils-2.24/ld/ldexp.c the line " nextdot = expld.result.value;" is executed from the following traceback:

(gdb) bt
#0  exp_fold_tree_1 (tree=0x7d5fb0) at ldexp.c:861
#1  0x000000000041faed in exp_fold_tree (tree=0x7d5fb0, current_section=0x80d080, dotp=0x7fffffffd108)
    at ldexp.c:982
#2  0x0000000000414b46 in lang_size_sections_1 (prev=0x7d5ca0, output_section_statement=0x7de810,
    fill=0x0, dot=29884416, relax=0x0, check_regions=0) at ldlang.c:5193
#3  0x00000000004141ce in lang_size_sections_1 (prev=0x7d9f38, output_section_statement=0x7de600,
    fill=0x0, dot=29884416, relax=0x0, check_regions=0) at ldlang.c:4924
#4  0x0000000000414f51 in one_lang_size_sections_pass (relax=0x0, check_regions=0) at ldlang.c:5350
#5  0x0000000000412098 in strip_excluded_output_sections () at ldlang.c:3848
#6  0x0000000000420ae2 in before_allocation_default () at ldemul.c:241
#7  0x0000000000428515 in gldelf32ppc_before_allocation () at eelf32ppc.c:1300
#8  0x0000000000426788 in ppc_before_allocation () at eelf32ppc.c:198
#9  0x0000000000420716 in ldemul_before_allocation () at ldemul.c:78
#10 0x00000000004173df in lang_process () at ldlang.c:6737
#11 0x000000000041afba in main (argc=1101, argv=0x7dc170) at ./ldmain.c:411

In the scenario that does not work, expld.result.value is zero, whereas when it does work, that value is non-zero.  I think the reason this bit of code decided that no padding was necessary is because the value of "dot" passed into the outermost occurrence of lang_size_sections_1() in the backtrace above is 0x1c80000, ie: it's page aligned.  I don't know what the value of dot represents in the code at that point.  This invocation of lang_size_sections_1 is related to .sdata2 (output_section_statement->name is ".sdata2") and once this link is complete, there is no output .sdata2 section and .data is at 01c7a000.  0x1c80000 is an address in the middle of the final .data section.  I'm guessing that some bit of code looked at 0x1c80000 and decided that no padding was necessary because of all those zeroes, even though that location counter is going to be adjusted later?

When I trace through the same bit of code in a link that actually works because the text segment size is different, I see expld.result.value is 0x9ac at the same point in the linker's execution, and when that is then added to expld.section->vma a few lines below, the result is 0x1c81000.  But here again, 0x1c81000 is not the start address of any section; it's an address in the middle of .data.  In this case, .data starts at 01c7b000 and .sdata2 contains 0xbac bytes of padding.

Since other parts of the linker think that .sdata2 contains 0x200 bytes of padding, I'm guessing that strip_included_output_sections() performs this calculation just to determine whether or not to discard the section.  Other code performs the same calculation, excepts does it bases on the correct value of dot.

--Doug


--Doug


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]