On Wed, 19 Aug 2015, Mike Stump wrote:

> On Aug 19, 2015, at 7:25 AM, Richard Biener <rguent...@suse.de> wrote:
> > 
> > This is needed so that we can output references to $early-debug-symbol + 
> > constant offset where $early-debug-symbol is the beginning of a 
> > .debug_info section containing early debug info from the compile-stage.
> > Constant offsets are always fine for any object formats I know,
> 
> On darwin, they generally speaking, are not. subsections_via_symbols can shed 
> some light on the topic, if one is interested all the fun.  I’ll give a quick 
> intro below.
> 
>   foo+n
> 
> only works if there is not other label of a certain type between label and 
> foo+4, and there are no labels of a certain type at foo+4, and foo+n refers 
> to at least one byte after that label, and n is non-negative and …
> 
> So, for example, in
> 
>       nop
>   foo:
>       nop
> 
> foo+32 would be invalid as nops are 4 bytes or so, and +32 is beyond the size 
> of the region.  foo+0 be fine.  foo+4 would be invalid, assuming nop 
> generates 4 bytes.  foo-4 would be invalid.
> 
> In:
> 
>   foo:
>       nop
>   bar:
>       nop
> 
> foo+4 would be invalid, as bar exists.
> 
> In:
> 
> foo:
>       nop
> L12:
>       nop
> 
> foo+4 is fine, as local labels don’t participate.  One way to think about 
> this is imagine that each global label points to an independent section and 
> that section isn’t loaded unless something refers to it, and one can only 
> have pointers to the bytes inside that section, and that sections on output 
> can be arbitrarily ordered.
> 
>   bar: nop
>   foo: nop
> 
> bar+4, even if you deferred this to running code, need not refer to foo.
> 
> I say this as background.
> 
> In the optimization where gcc tries to bunch up global variables together and 
> form base+offset to get to the different data, this does not work on darwin 
> because base+offset isn’t a valid way to go from one global label to the 
> next, even in the same section.
> 
> Now, if you merely sneak in data into the section with no labels and you 
> need to account for N extra bytes before then you can change the 
> existing reference to what it was before + N, without any worry.  If you 
> remove the interior labels to form your new base, and concatenate all 
> the data together, then base+N to refer to the data is fine, if there 
> are at least N+1 bytes of data after base.
>
> foo: nop
> bar: nop
> 
> would become:
> 
> base:
> Lfoo: nop
> Lbar: nop
> 
> base+0 and base+4.
> 
> So, if you confident you know and follow the rules, ok from my 
> perspective.  If you’re unsure, I can try and read a .s file and see if 
> it looks ok.  Testing would may not catch broken things unless you also 
> select dead code stripping and try test cases with dead code.

I believe that we in the end have

Ldebug_info_from_t1.c:
 ...
Ldebug_info_from_t2.c:
 ...
debug_info:
 refer to Ldebug_info_from_t1.c + offset
 refer to Ldebug_info_from_t2.c + offset

where the references always use positive offset and are based on the
next previous lable (so Ldebug_info_from_t1.c is not refering to
an entity at Ldebug_info_from_t2.c or beyond).  So that seems to
follow the restrictions you laid out above.

If basic testing doesn't help I'll refrain from doing it ;)  It
can only break LTO in the end.

Richard.

Reply via email to