On Aug 19, 2015, at 7:25 AM, Richard Biener <[email protected]> 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.