This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc 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: gold vs libc


> In https://sourceware.org/ml/libc-alpha/2014-03/msg01012.html
> I said:
>
>     IMHO it would be acceptable to simply disable .eh_frame optimization when
>     there are any symbols in input .eh_frame sections that will survive to
>     affect the output of anything except the .eh_frame output section's
>     contents.  (That tortured wording is to distinguish __EH_FRAME_BEGIN__,
>     whose value is used by relocs in other sections like .text, from the
>     various .L* symbols used within individual input sections that are only
>     used in arithmetic producing values inside the section.)  What's not
>     acceptable is breaking the core semantics of linking that would apply if
>     nobody had ever thought of .eh_frame optimization.

As hard as that is to describe, it seems like it would be fragile.

> and also, in response to the cited suggestion from Ian:
>
>     > The current code has a simple algorithm that usually produces the
>     > result we want: we simply copy .eh_frame sections until we find one we
>     > can optimize.  Perhaps we could change to a different algorithm: put
>     > all unoptimized .eh_frame sections first, then all optimized .eh_frame
>     > sections.
>
>     In the concrete scenario, that would violate the abstract principles I
>     described but would deliver an even better practical result.  The empty
>     .eh_frame section (and its __EH_FRAME_BEGIN__ symbol) from crtbeginT.o
>     count as "unoptimized", while the .eh_frame content from crt1.o could count
>     as "optimized".  So it would place the emptiness and __EH_FRAME_BEGIN__
>     first, and everything else (including crt1.o's contributions) after, even
>     though crt1.o appears before crtbeginT.o in the link.
>
>     I think either this or disabling the optimization entirely are acceptable
>     resolutions to the bug.
>
> I think that when Ian said, "we've identified a fix," he was referring to,
> "put all unoptimized .eh_frame sections first, then all optimized .eh_frame
> sections."

That solution will end up putting the unoptimized end-bracket section
from crtend.o before the optimized contents. I've already fixed a bug
where --sort-section made that happen. Sure, that could be fixed, but
only by piling on another special case.

What we really want to do is put the optimized sections in between the
two bracketing sections. Identifying those bracketing sections is the
challenge.

>> If the .eh_frame data in crt1.o really does need to come before
>> __EH_FRAME_BEGIN__, another thing you could do is simply make it so
>> gold treats it as non-optimizable. Adding a null relocation to the
>> first word of the section should do it; inserting a zero-length entry
>> anywhere but the end would do it (if that doesn't have adverse affects
>> elsewhere).
>
> It doesn't need to and in fact it's undesireable that it do so.  That is
> one reason in favor of Ian's suggestion: though it doesn't adhere to any
> clear abstract principle I can see, as a pragmatic solution to the actual
> case in point, it magically makes something even better in practice than
> the status quo ante (ante as in before switching linkers) long before a fix
> for the underlying wrongness (in GCC's link order) will be available.
> OTOH, it certainly seems like it has more risk of unintended consequences
> we aren't now able to predict than does simply disabling optimization.

So that's an argument against just turning off the optimization.

>> Since the problem comes from an optimizations that knows what
>> .eh_frame is, maybe it could learn that __EH_FRAME_BEGIN__ and
>> __EH_FRAME_END__ are special symbols marking the start and end of the
>> section?
>
> I think that would be acceptable too.  It would have the same benefits of
> "magically fixing" the crt1/crtbegin ordering snafu, but it seems much
> simpler and thus it seems that predicting possible downsides would be
> easier (I haven't thought of any).

I don't like the idea of checking for specific symbol name to give
special treatment to a section. I wouldn't mind simply making
__EH_FRAME_BEGIN__ and __EH_FRAME_END__ linker-defined symbols that
would override any definitions found in the object files.

I could also special case by filename -- check
is_in_system_directory(), and if true, check the filename to see if it
contains "begin" or "end".

I think I'd prefer to do the first. We have precedent for providing
linker-defined bracketing symbols -- not for having them override any
definitions already present, but I don't think that's a big problem in
this case. It's also simple, and lets us preserve the simple rule of
putting the linker-generated contents in the place of the first
optimized section.

BTW, my copy of crtend.o doesn't define __EH_FRAME_END__. It does
define __FRAME_END, but it's a local symbol. Having the linker provide
__EH_FRAME_END__ would be consistent, and shouldn't break anything.
With this proposal, __FRAME_END would get the right value anyway.
(Until, that is, someone comes along with another crtend-like file and
decides it needs CFI as well!)

-cary


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