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.

> The LTO support adds a single call here:
> 
> @@ -9064,8 +9248,12 @@ output_die (dw_die_ref die)
>                    size = DWARF2_ADDR_SIZE;
>                  else
>                    size = DWARF_OFFSET_SIZE;
> -                 dw2_asm_output_offset (size, sym, debug_info_section, 
> "%s",
> -                                        name);
> +                 if (AT_ref (a)->with_offset)
> +                   dw2_asm_output_offset (size, sym, AT_ref 
> (a)->die_offset,
> +                                          debug_info_section, "%s", 
> name);
> +                 else
> +                   dw2_asm_output_offset (size, sym, debug_info_section, 
> "%s",
> +                                          name);
>                }

So, I glanced around this call site, and it would seem safe if all you’re doing 
is adding die_offset bytes of data or more and no global labels.

Reply via email to