<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none"><!--P{margin-top:0;margin-bottom:0;} p
        {margin-top:0;
        margin-bottom:0}--></style>
</head>
<body dir="ltr" style="font-size:12pt;color:#000000;background-color:#FFFFFF;font-family:Calibri,Arial,Helvetica,sans-serif;">
<p>Hi David,<br>
</p>
<p><br>
</p>
<p>>So there have been several recent discussions about the issues around </p>
<p>>DWARF-agnostic linking and gc-sections, linkonce function definitions being </p>
<p>>dropped, etc - and just how much DWARF-awareness would be suitable </p>
<p>>in a linker to help with this situation.<br>
</p>
<div style="color:rgb(33,33,33)">
<div>
<div>
<div dir="ltr"><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 </div>
<div dir="ltr">> instruction is removed & you get the full power UB of control flowing off
</div>
<div dir="ltr">> 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, </div>
<div dir="ltr">> FWIW) is a list of address pairs, terminated by a pair of zeros.</div>
<div dir="ltr">> With function sections, or even just with normal C++ inline functions,
</div>
<div dir="ltr">> the CU will have a range entry for that function that consists of two relocations
</div>
<div dir="ltr">> - to the start and end of the function. Generally the start of the function is the
</div>
<div dir="ltr">> 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 -
</div>
<div dir="ltr">> but that would cause debug info to defeat linker GC and deduplication. So there's
</div>
<div dir="ltr">> special rules for how linkers handle these relocations in debug info to allow the
</div>
<div dir="ltr">> 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
</div>
<div dir="ltr">> code to 1. In other debug sections, these values are all resolved to zero.</div>
<div dir="ltr">> Gold and lld: Special cases all debug info sections - resolving all relocations
</div>
<div dir="ltr">> 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 </div>
<div dir="ltr">> don't cause the range list to terminate prematurely (which would happen if begin/end
</div>
<div dir="ltr">> were both resolved to zero).<br>
<br>
>But with an empty function, gold and lld's strategy here fails to avoid terminating a
</div>
<div dir="ltr">>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 </div>
<div dir="ltr">> compatibility/existing functions/other compilers)<br>
> 2) adopt the binutils approach to this (at least in debug_ranges - maybe in all
</div>
<div dir="ltr">> debug sections? (doing it in other sections could break )<br>
>  3) Revisit the discussion about using an even more 'blessed' value, </div>
<div dir="ltr">> like int max-1? ( <a href="https://reviews.llvm.org/D59553" rel="noreferrer" 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
</div>
<div dir="ltr">> might've spawned a separate broader discussion/non-review - oh, Alexey wrote a
</div>
<div dir="ltr">> good summary with links to other discussions here:</div>
<div dir="ltr">>  <a href="http://lists.llvm.org/pipermail/llvm-dev/2019-September/135068.html">
http://lists.llvm.org/pipermail/llvm-dev/2019-September/135068.html</a> )<br>
<br>
> Thoughts?</div>
<div dir="ltr"><br>
</div>
<div dir="ltr">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 https://reviews.llvm.org/D59553 - 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: http://lists.llvm.org/pipermail/llvm-dev/2020-May/141599.html.<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 https://reviews.llvm.org/D54747#1503720
 . 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.</div>
<div dir="ltr"><br>
</div>
<div dir="ltr">Thank you, Alexey.<br>
<br>
<br>
<br>
</div>
</div>
</div>
</div>
</body>
</html>