<div dir="ltr"><div dir="ltr">On Thu, May 28, 2020 at 2:52 PM Robinson, Paul <<a href="mailto:paul.robinson@sony.com">paul.robinson@sony.com</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">





<div bgcolor="white" lang="EN-US">
<div class="gmail-m_-3332068910741502497WordSection1">
<p class="MsoNormal">As has been mentioned elsewhere, Sony generally fixes up references from debug info to stripped functions (of any length) using -1, because that’s a less-likely-to-be-real address than 0x0 or 0x1.  (0x0 is a typical base address for shared
 libraries, I’d think using it has the potential to mislead various consumers.)  For .debug_ranges we use -2, because both a 0/0 pair and a -1/-1 pair have a reserved meaning in that section.</p></div></div></blockquote><div><br>Any harm in using -2 everywhere, for consistency?<br><br>(also, I had a silly idea, but what would happen if we added a CU attribute with an address value that was a reference to a weak always-unused symbol, that way the linker would fix it up with whatever its preferred magic value was, and the consumer would then know what the magic value was that represented dead code? (though this would only work if the value were used consistently everywhere - which is zero for gold/lld (well, almost... you can still create situations where a non-zero value is used even for a low_pc), but wouldn't work for binutils ld (1 in debug_ranges, 0 elsewhere) or Sony (-2 in debug_ranges, -1 elsewhere)... - so, wouldn't actually work for any producer currently, so maybe there's little value in that as a feature))<br> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div bgcolor="white" lang="EN-US"><div class="gmail-m_-3332068910741502497WordSection1"><p class="MsoNormal"><u></u><u></u></p>
<p class="MsoNormal"><u></u> If you’re looking only at zero-length functions, you can stop there; but I’m not sure why stopping there solves much of a real problem, as zero-length functions seem like a weird corner case.</p></div></div></blockquote><div><br>They're the case that breaks existing usage by terminating the range list early - the other existing usage seems to be fine with "resolve to addend" strategy that lld and gold use - in that it moves most dead/deduplicated functions outside the executable range and so consumers never come asking for "what code is at instruction 5" because they're never executing code at a pc of 5. But, yes, this existing solution doesn't work once you have code mapped into low address spaces or have utterly massive functions that might have a length that would reach into the executable address space even when their start is remapped to zero.<br> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div bgcolor="white" lang="EN-US"><div class="gmail-m_-3332068910741502497WordSection1"><p class="MsoNormal"> Linkers know how to strip dead functions (gc)
 or deduplicate them (icf, COMDAT) and people do this all the time, in some cases (COMDAT) without explicitly asking for it, so non-zero-length functions seem like the much more interesting case.  In that situation, -1 (or -2) seems like a much wiser choice
 of blessed-as-not-real address, versus 0x0 or 0x1.</p><p class="MsoNormal"><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Stripping non-zero-length functions does mean you have to care about more sections.  For example .debug_locs would want to be fixed up the same way as .debug_ranges, not because a debugger would care but so that dumpers would not run into
 the 0/0 brick wall.  </p></div></div></blockquote><div><br></div><div>Yep - in theory a consumer could actually use a loclist across multiple sections (if a global variable got hoisted into a register for a function for instance), but I don't know of any producers doing this today - until then, yeah, it's just a dumping problem and ld.bfd does produce DWARF that has that problem (because it resolves both relocations to dead code (begin/end of a range) to zero in all sections except debug_ranges, so terminates the loclist list early) - binutils objdump avoids dumping the following corrupted fragment by only dumping hunks of debug_loc starting at places referenced from debug_info. Without debug_info it won't dump anything from debug_loc - and if the references from debug_info, parsed until the 0,0 terminator don't cover the whole debug_loc section, it prints messages saying there are "gaps".<br><br>Agreed that you'd want debug_loc to have the same special handling as debug_ranges if it has special handling. Though ideally we'd pick a value that works equally everywhere? (-2, by the sounds of it)</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div bgcolor="white" lang="EN-US"><div class="gmail-m_-3332068910741502497WordSection1"><p class="MsoNormal">We also fix up lengths in .debug_aranges to zero, although there might be history behind that tactic that I’m not aware of; it seems like it ought to be unnecessary, if consumers are aware of the special address(es).</p></div></div></blockquote><div><br></div><div>Yeah, no idea about debug_aranges... I'd have thought it'd be fine with the same approach as debug_ranges, but I haven't looked at debug_aranges in a long time.<br><br>I guess the only remaining question is: Since it's possible to have code on some systems down at address zero, or close enough to it that [0, length) might overlap with real exxecutable code addresses - does anyone know of the inverse: where code is mapped up near uint32 max? Such that that usage wouldn't be able to sacrifice uint32 max - 1 to use as a blessed value here?<br><br>- Dave</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div bgcolor="white" lang="EN-US"><div class="gmail-m_-3332068910741502497WordSection1"><p class="MsoNormal"><u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">--paulr<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<div style="border-top:none;border-right:none;border-bottom:none;border-left:1.5pt solid blue;padding:0in 0in 0in 4pt">
<div>
<div style="border-right:none;border-bottom:none;border-left:none;border-top:1pt solid rgb(225,225,225);padding:3pt 0in 0in">
<p class="MsoNormal"><b>From:</b> Alexey Lapshin <<a href="mailto:alapshin@accesssoftek.com" target="_blank">alapshin@accesssoftek.com</a>> <br>
<b>Sent:</b> Thursday, May 28, 2020 9:03 AM<br>
<b>To:</b> Sriraman Tallam <<a href="mailto:tmsriram@google.com" target="_blank">tmsriram@google.com</a>>; Wei Mi <<a href="mailto:wmi@google.com" target="_blank">wmi@google.com</a>>; Robinson, Paul <<a href="mailto:paul.robinson@sony.com" target="_blank">paul.robinson@sony.com</a>>; Adrian Prantl <<a href="mailto:aprantl@apple.com" target="_blank">aprantl@apple.com</a>>; Jonas Devlieghere <<a href="mailto:jdevlieghere@apple.com" target="_blank">jdevlieghere@apple.com</a>>; Alexey Lapshin <<a href="mailto:a.v.lapshin@mail.ru" target="_blank">a.v.lapshin@mail.ru</a>>; Eric Christopher <<a href="mailto:echristo@gmail.com" target="_blank">echristo@gmail.com</a>>;
 Fangrui Song <<a href="mailto:maskray@google.com" target="_blank">maskray@google.com</a>>; David Blaikie <<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>>; <a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<b>Subject:</b> Re: [llvm-dev] Range lists, zero-length functions, linker gc<u></u><u></u></p>
</div>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<p><span style="font-size:12pt;color:black">Hi David,<u></u><u></u></span></p>
<p><span style="font-size:12pt;color:black"><u></u> <u></u></span></p>
<p><span style="font-size:12pt;color:black">>So there have been several recent discussions about the issues around
<u></u><u></u></span></p>
<p><span style="font-size:12pt;color:black">>DWARF-agnostic linking and gc-sections, linkonce function definitions being
<u></u><u></u></span></p>
<p><span style="font-size:12pt;color:black">>dropped, etc - and just how much DWARF-awareness would be suitable
<u></u><u></u></span></p>
<p><span style="font-size:12pt;color:black">>in a linker to help with this situation.<u></u><u></u></span></p>
<div>
<div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:12pt;color:rgb(33,33,33)"><br>
> I'd like to discuss a narrower instance of this issue: Zero length gc'd/deduplicated functions.<br>
<br>
> LLVM seems to at least produce zero length functions in a few cases:<br>
> * non-void function without a return statement<br>
> * function definition containing only llvm_unreachable<br>
> (both of these trap at -O0, but at higher optimization levels even the trap <u></u>
<u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12pt;color:rgb(33,33,33)">> instruction is removed & you get the full power UB of control flowing off
<u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12pt;color:rgb(33,33,33)">> the end of the function into whatever other bytes are after that function)<br>
<br>
> So, for context, debug_ranges (this whole issue doesn't exist in DWARFv5, <u></u>
<u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12pt;color:rgb(33,33,33)">> FWIW) is a list of address pairs, terminated by a pair of zeros.<u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12pt;color:rgb(33,33,33)">> With function sections, or even just with normal C++ inline functions,
<u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12pt;color:rgb(33,33,33)">> the CU will have a range entry for that function that consists of two relocations
<u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12pt;color:rgb(33,33,33)">> - to the start and end of the function. Generally the start of the function is the
<u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12pt;color:rgb(33,33,33)">> start of the section, and the end is "start of function + length of function (aka addend)".<br>
<br>
>  Usually any relocation to the section would keep that section "alive" during linking -
<u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12pt;color:rgb(33,33,33)">> but that would cause debug info to defeat linker GC and deduplication. So there's
<u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12pt;color:rgb(33,33,33)">> special rules for how linkers handle these relocations in debug info to allow the
<u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12pt;color:rgb(33,33,33)">> sections to be dropped - what do you write in the bytes that requested the relocation?<br>
<br>
> Binutils ld: Special cases only debug_ranges, resolving all relocations to dead
<u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12pt;color:rgb(33,33,33)">> code to 1. In other debug sections, these values are all resolved to zero.<u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12pt;color:rgb(33,33,33)">> Gold and lld: Special cases all debug info sections - resolving all relocations
<u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12pt;color:rgb(33,33,33)">> to "addend" (so begin usually goes to zero, end goes to "size of function")<br>
<br>
> These special rules are designed to ensure omitted/gc'd/deduplicated functions <u></u>
<u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12pt;color:rgb(33,33,33)">> don't cause the range list to terminate prematurely (which would happen if begin/end
<u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12pt;color:rgb(33,33,33)">> were both resolved to zero).<br>
<br>
>But with an empty function, gold and lld's strategy here fails to avoid terminating a
<u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12pt;color:rgb(33,33,33)">>range list by accident.<br>
<br>
> What should we do about it?<br>
<br>
>  1) Ensure no zero-length functions exist? (doesn't address backwards <u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12pt;color:rgb(33,33,33)">> compatibility/existing functions/other compilers)<br>
> 2) adopt the binutils approach to this (at least in debug_ranges - maybe in all
<u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12pt;color:rgb(33,33,33)">> debug sections? (doing it in other sections could break )<br>
>  3) Revisit the discussion about using an even more 'blessed' value, <u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12pt;color:rgb(33,33,33)">> like int max-1? ( <a href="https://urldefense.com/v3/__https:/reviews.llvm.org/D59553__;!!JmoZiZGBv3RvKRSx!r2Jqc2yEgxrb2QcQEocDHJBizj0KUKE70_57b4_rsj1TN0qB8NpBvVKtY63HSqgMOg$" target="_blank">https://reviews.llvm.org/D59553</a> )<br>
<br>
>  (I don't have links to all the recent threads about this discussion - I think D59553
<u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12pt;color:rgb(33,33,33)">> might've spawned a separate broader discussion/non-review - oh, Alexey wrote a
<u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12pt;color:rgb(33,33,33)">> good summary with links to other discussions here:<u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12pt;color:rgb(33,33,33)">>  <a href="https://urldefense.com/v3/__http:/lists.llvm.org/pipermail/llvm-dev/2019-September/135068.html__;!!JmoZiZGBv3RvKRSx!r2Jqc2yEgxrb2QcQEocDHJBizj0KUKE70_57b4_rsj1TN0qB8NpBvVKtY638NIRu2g$" target="_blank">
http://lists.llvm.org/pipermail/llvm-dev/2019-September/135068.html</a> )<br>
<br>
> Thoughts?<u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12pt;color:rgb(33,33,33)"><u></u> <u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12pt;color:rgb(33,33,33)">I think for the problem of "zero length functions and .debug_ranges" binutils approach looks good:<br>
<br>
>Special cases only debug_ranges, resolving all relocations to<br>
>dead code to 1. In other debug sections, these values are all resolved to<br>
>zero.<br>
<br>
But, this would not completely solve the problem from <a href="https://urldefense.com/v3/__https:/reviews.llvm.org/D59553__;!!JmoZiZGBv3RvKRSx!r2Jqc2yEgxrb2QcQEocDHJBizj0KUKE70_57b4_rsj1TN0qB8NpBvVKtY63HSqgMOg$" target="_blank">
https://reviews.llvm.org/D59553</a> - Overlapped address ranges. Binutils approach will solve the problem if the address range specified as start_address:end_address. While resolving relocations, it would replace such a range with 1:1.<br>
However, It would not work if address ranges were specified as start_address:length since the length is not relocated. This case could be additionally fixed by fast scan debug_info for High_PC defined as length and changing it to 1. Something which you suggested
 here: <a href="https://urldefense.com/v3/__http:/lists.llvm.org/pipermail/llvm-dev/2020-May/141599.html__;!!JmoZiZGBv3RvKRSx!r2Jqc2yEgxrb2QcQEocDHJBizj0KUKE70_57b4_rsj1TN0qB8NpBvVKtY63PsubKJQ$" target="_blank">
http://lists.llvm.org/pipermail/llvm-dev/2020-May/141599.html</a>.<br>
<br>
So it looks like following solution could fix both problems and be relatively fast:
<br>
<br>
"Resolve all relocations from debug sections into dead code to 1. Parse debug sections and replace HighPc of an address range pointing to dead code and specified as length to 1".<br>
<br>
As the result all address ranges pointing into dead code would be marked as zero length.<br>
<br>
There still exist another problem: <br>
<br>
DWARF4: "A range list entry (but not a base address selection or end of list entry) whose beginning and<br>
ending addresses are equal has no effect because the size of the range covered by such an<br>
entry is zero."<br>
<br>
DWARF5: "A bounded range entry whose beginning and ending address offsets are equal<br>
(including zero) indicates an empty range and may be ignored."<br>
<br>
These rules allow us to ignore zero-length address ranges. I.e., some tool reading DWARF is permitted to ignore related DWARF entries. In that case, there could be ignored essential descriptions. That problem could happen with -flto=thin example
<a href="https://urldefense.com/v3/__https:/reviews.llvm.org/D54747*1503720__;Iw!!JmoZiZGBv3RvKRSx!r2Jqc2yEgxrb2QcQEocDHJBizj0KUKE70_57b4_rsj1TN0qB8NpBvVKtY637ju_eQw$" target="_blank">
https://reviews.llvm.org/D54747#1503720</a> . In this example, all type definitions except one were replaced with declarations by thinlto. The definition, which was left, is in a piece of debug info related to deleted code. According to zero-length rule, that
 definition could be ignored, and finally, incomplete debug info could be used.<br>
<br>
So, it probably should be forbidden to generate debug_info, which could become incomplete after removing pieces related to zero length address ranges. Otherwise, creating zero-length address ranges could lead to incomplete debug info.<u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12pt;color:rgb(33,33,33)"><u></u> <u></u></span></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:12pt"><span style="font-size:12pt;color:rgb(33,33,33)">Thank you, Alexey.<br>
<br>
<br>
<u></u><u></u></span></p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

</blockquote></div></div>