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.