<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Sep 9, 2015, at 10:40 AM, David Blaikie <<a href="mailto:dblaikie@gmail.com" class="">dblaikie@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><br class="Apple-interchange-newline"><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_quote" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">On Wed, Sep 9, 2015 at 9:52 AM, Frédéric Riss<span class="Apple-converted-space"> </span><span dir="ltr" class=""><<a href="mailto:friss@apple.com" target="_blank" class="">friss@apple.com</a>></span><span class="Apple-converted-space"> </span>wrote:<br class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><br class=""><div class=""><div class=""><div class="h5"><blockquote type="cite" class=""><div class="">On Sep 9, 2015, at 8:36 AM, David Blaikie <<a href="mailto:dblaikie@gmail.com" target="_blank" class="">dblaikie@gmail.com</a>> wrote:</div><br class=""><div class=""><br class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><div class="gmail_quote" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;">On Wed, Sep 9, 2015 at 8:16 AM, Frédéric Riss<span class=""> </span><span dir="ltr" class=""><<a href="mailto:friss@apple.com" target="_blank" class="">friss@apple.com</a>></span><span class=""> </span>wrote:<br class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><br class=""><div class=""><div class=""><div class=""><blockquote type="cite" class=""><div class="">On Sep 8, 2015, at 10:09 PM, David Blaikie <<a href="mailto:dblaikie@gmail.com" target="_blank" class="">dblaikie@gmail.com</a>> wrote:</div><br class=""><div class=""><div dir="ltr" class=""><br class=""><div class="gmail_extra"><br class=""><div class="gmail_quote">On Tue, Sep 8, 2015 at 1:10 PM, Frédéric Riss<span class=""> </span><span dir="ltr" class=""><<a href="mailto:friss@apple.com" target="_blank" class="">friss@apple.com</a>></span><span class=""> </span>wrote:<br class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><br class=""><div class=""><span class=""><blockquote type="cite" class=""><div class="">On Sep 8, 2015, at 12:24 PM, David Blaikie <<a href="mailto:dblaikie@gmail.com" target="_blank" class="">dblaikie@gmail.com</a>> wrote:</div><br class=""><div class=""><br class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><div class="gmail_quote" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;">On Mon, Aug 31, 2015 at 11:10 AM, Frédéric Riss<span class=""> </span><span dir="ltr" class=""><<a href="mailto:friss@apple.com" target="_blank" class="">friss@apple.com</a>></span><span class=""> </span>wrote:<br class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><br class=""><div class=""><span class=""><blockquote type="cite" class=""><div class="">On Aug 31, 2015, at 9:07 AM, David Blaikie <<a href="mailto:dblaikie@gmail.com" target="_blank" class="">dblaikie@gmail.com</a>> wrote:</div><br class=""><div class=""><div dir="ltr" class=""><br class=""><div class="gmail_extra"><br class=""><div class="gmail_quote">On Mon, Aug 31, 2015 at 9:05 AM, David Blaikie<span class=""> </span><span dir="ltr" class=""><<a href="mailto:dblaikie@gmail.com" target="_blank" class="">dblaikie@gmail.com</a>></span><span class=""> </span>wrote:<br class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div dir="ltr" class=""><br class=""><div class="gmail_extra"><br class=""><div class="gmail_quote"><span class="">On Sun, Aug 30, 2015 at 6:43 PM, Frederic Riss via llvm-commits<span class=""> </span><span dir="ltr" class=""><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank" class="">llvm-commits@lists.llvm.org</a>></span><span class=""> </span>wrote:<br class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;">Author: friss<br class="">Date: Sun Aug 30 20:43:14 2015<br class="">New Revision: 246406<br class=""><br class="">URL:<span class=""> </span><a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject-3Frev-3D246406-26view-3Drev&d=BQMFaQ&c=eEvniauFctOgLOKGJOplqw&r=_sX2G1Du1KZyzi5BD4_ddw&m=FkrVlXa3-EdUHEUklJrpTIxLR2zDdr3ysgnj0hyNiNc&s=-yp_b9w-sonxhFICg6npPkz6_FLOw29qR_X8EIzjwWY&e=" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project?rev=246406&view=rev</a><br class="">Log:<br class="">[dsymutil] Fix handling of inlined_subprogram low_pcs<br class=""><br class="">The value of an inlined subprogram low_pc attribute should not<br class="">get relocated, but it can happen that it matches the enclosing<br class="">function's start address and thus gets the generic treatment.<br class="">Special case it to avoid applying the PC offset twice.<br class=""></blockquote></span><div class=""><br class="">I'm a tad confused - do you store the low_pcs as offsets relative to the function<br class=""></div></div></div></div></blockquote><div class=""><br class="">(sorry, bouncy shuttle to work & accidentally sent before I finished that sentence...)<br class=""><br class="">do you store the low_pcs as offsets relative to the function's low_pc? That's interesting - and perhaps something we should standardize/generalize to reduce relocations in all our DWARF output (but I don't think there's any standard for it yet in DWARF), but I'm not sure why that would require special casing the case where the two low_pcs are equal - wouldn't that just mean the low_pc of the inlined subroutine would be at zero offset from the subprogram's low_pc? (& still not relocated)</div></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">dsymutil takes the debug map as input that only contains the function (and variables) start addresses. That’s the only thing we can count on being exact. We then do a pass over all the debug_info relocations to find the ones that correspond to those addresses (and the DIEs where we find the ‘interesting’ relocations are the ones that define which part of the DIE tree we keep). Then — once we decided what to keep — we go over the kept DIEs and we clone them, applying the relocations in the process. But note that the relocations we’ve chosen are only for the entry points, thus we need to have the code around to handle the lexical_block/inlined_subroutine, and this code doesn’t use the relocations (it applies an offset that we computed when handling the subprogram DIE).</div><div class=""><br class=""></div><div class="">What  happened here is that the generic code that applied the relocations would also patch the inlined_subroutine low_pc because the relocation was the same as the entry point. And then the code handling the low_pc attributes for the inlined_subroutine would apply the offset a second time.</div></div></div></blockquote><div class=""><br class=""></div><div class="">OK - what I'm wondering is whether it would work better/as well to generalize this code, rather than two distinct passes/processes.<span class=""> </span></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">I don’t think there’s a way to generalize this code. But I agree that storing the low_/high_pcs as offsets from their enclosing function low_pc would save quite a few relocations.</div></div></div></blockquote><div class=""><br class="">Sorry, that wasn't what I was trying to describe,</div></div></div></div></div></blockquote><div class=""><br class=""></div></div></div><div class="">I must admit that I didn’t really get your ‘2 distinct passes/processes’ so I replied to you original point. But now I think I see what you meant and I hope the rest of my answer did address that.</div><span class=""><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class="">but it's certainly something we've discussed before (actually I made a silly prototype of using dwarf expressions and debug address pool indicies to do reloc sharing (using one reloc per section (macho would use one reloc per function, due to the implied function-sections like behavior) - never did get around to running good numbers on it, though)).<br class=""> </div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><div class=""><div class="">Note that there is precedent for something like this: the ranges are encoded as offsets from the *CU* low_pc. Maybe it would be more natural to use that then?</div></div></div></blockquote></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">Note to myself: I said ‘more natural’ above, but I didn’t really mean it (more in the line of the standard would have been a better expression of my thought). I never understood why the standard used the CU low_pc as a base. It’s hard to use for the compiler (cf the kludge we use by setting the CU low_pc to 0 when we have multiple address ranges).<span class=""> </span></div></div></div></blockquote><div class=""><br class="">Do we still put the low_pc to 0 when we have DW_AT_ranges on the CU? I guess maybe we do - been a while since I looked. (debuggers should just have "no base" essentially, when the CU has ranges)<br class=""> </div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><div class=""><div class="">Maybe I’m missing something, but the start of the function would have been much easier.</div></div></div></blockquote><div class=""><br class=""></div><div class="">Yeah, I was thinking generalizing it a bit "you can use a constant address value which will be interpreted relative to the nearest enclosing low_pc" - so even if you have a split CU, but a contiguous subprogram, you can still share the low_pc of your subprogram. Or if you have a split subprogram but a contiguous CU (as in the hot/cold splitting case) you could still use that, etc. (this could happen further into subprograms too - split CU, split subprogram, but possibly a contiguous lexical block there, etc) - this wouldn't entirely minimize relocations, though - if you had a split subprogram and a similarly split lexical block - the lexical block ranges wouldn't share the base relocs of the subprogram's ranges relocs, for example. (or if you had a split subprogram, split CU, but contiguous lexical block - you still wouldn't get to share whichever subprogram/cu reloc refers to the chunk that the lexical block is in)<br class=""></div></div></div></blockquote><div class=""><br class=""></div></div></div><div class="">Just out of curiosity: we do not do any form of function splitting (eg hot/cold partitioning) AFAIK, so all these ‘problems’ are mostly theoretical for now, right?</div></div></div></blockquote><div class=""><br class=""></div><div class="">Right - just thinking about how general of a feature we might want to propose for DWARF standardization to address this issue.<br class=""><br class="">Currently all LLVM functions are contiguous, but CUs can be discontiguous and lexical scopes can be discontiguous.<br class=""><br class="">So just "use the nearest parental low_pc" would still be suboptimal for LLVM in some cases (not on MachO where function-sections-like behavior is the only behavior so there's no cases where you share relocs between functions) - several functions could share a reloc even if they're discontiguous but in a single section (ie: a non-debug function may be between two debug functions, but all in the same section together) or there might be several contiguous functions but within a CU with a discontiguous range (because there's a non-debug function elsewhere, or functions in other sections (comdat, etc)).</div><div class=""> </div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><div class=""><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div class="gmail_quote" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><div class="">That's why the prototype I did was fission-based, because there's already address pooling implemented there (& we use fission anyway, so it was in the space I was thinking of). It'd still need some extensions for ranges, if I recall correctly, to allow ranges to use addr+offset as well. (& I don't really think using generalized dwarf expressions is the right solution for the addr+offset in DWARF attributes, but it was a fun way to prototype it)</div><div class=""> </div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><div class=""><span class=""><br class=""><blockquote type="cite" class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class="">If we had a (probably/preferably compact) encoding to describe this, it would probably be ideal.<br class=""><br class="">DWARF4 already has this /sort/ of thing for high_pc (where it can be encoded as a static offset relative to the low_pc - so it's not another relocation). That could possibly be generalized further to allow high_pcs to be a static offset relative to their enclosing high_pc (if one exists, otherwise it would be an unacceptable encoding (this could occur for functions - if the CU isn't a contiguous PC range (non-CU functions in between CU functions, functions in other sections, etc) or if a function itself is discontiguous (hot/cold code splitting)).<br class=""><br class="">Eric & I have bandied that around now & then, which lead to the aforementioned prototype I played around with, but didn't go any further than that - my improvements to Clang's debug info emission had already brought it down to half the size of GCC's, so we didn't have any particular need to push further at the time.</div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">Interesting to know.</div><span class=""><br class=""><blockquote type="cite" class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><div class=""><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div class="gmail_quote" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><div class="">low_pc should just be a zero-offset relocation, right?<br class=""></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">Not on mach-o. Most relocations will be of the form __text+offset. That’s why there is no way for me to differentiate a __text+offset references the end of a range from the exact same relocation that references the beginning of another one (and as the linker can tear apart sections, that distinction is fundamental).</div></div></div></blockquote><div class=""><br class=""></div><div class="">OK, so you search through looking for a subprogram that has a subprogram low_pc at __text+offset? then assume all the other low/high pcs (and ranges) are relative to that function starting point? (this is how you remove the ambiguity of the start/end?)</div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">Basically yes. It’s a bit more complicated because it’s a multi-phase process, but the end result is that while linking the DIEs we know if we are in a function and we know it’s object file and its linked address. We just apply that same offset to all the other object file addresses within that function.</div></div></div></blockquote><div class=""><br class=""></div><div class="">OK, I'll see if I can understand this/explain myself:<br class=""><br class="">It sounds like you search through for the subprogram DIE with the appropriate low_pc matching the debug map entry you received, then you update that low_pc, record the base offset of the subprogram and add that to all the address attributes in the subprogram?<br class=""><br class="">But you don't search for the low_pc of the subprogram, you just search for any low_pcs - update them all, then do the addition as a second pass.<br class=""></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">Not exactly (sorry I should have given a more detailed answer upfront). The phases I was referring to are:</div><div class=""> 1/ Scan the relocations (without touching the debug info contents) to look for interesting relics (i.e. matching something in the debug map)</div><div class=""> 2/ Scan the debug info a first time to match these interesting relics to subprograms low_pcs or variables locations (and from these ‘seeds’  construct the full tree of DIEs to link)</div><div class=""> 3/ Clone/Link the selected DIEs</div><div class=""><br class=""></div><div class="">3/ is where everything happens. 1/ and 2/ are just here to gather information. During 3/ I apply the relocations *and* I use the special casing code to workaround the bad attribute values it would generate.</div></div></div></blockquote><div class=""><br class=""></div><div class="">And I'm trying to understand how the clone/link leads to bad values that need to be revised/treated specially.<br class=""><br class="">The way I would imagine/picture it is that 2/ finds the interesting low_pcs, says "this DIE subtree is interesting, we should link it" then while linking it, anything in the subtree would be updated using the same generic address updating algorithm relative to the "interesting address" from the debug map. I'm not seeing where this updating algorithm would need special cases for high or low pc at that point. Where does the special case/problematic results come in?<br class=""><br class="">I'll try to use more words... <br class=""><br class="">so looking at a simple example of two trivial (empty) functions targeting osx (I picked a random triple from the Clang codegen tests: -target x86_64-apple-macosx10.7.0) I get two CUs:<br class=""><br class=""><div class=""><font face="monospace, monospace" class="">  DW_TAG_subprogram [2]  </font></div><div class=""><font face="monospace, monospace" class="">    DW_AT_low_pc [DW_FORM_addr]     (0x0000000000000000)</font></div><div class=""><font face="monospace, monospace" class="">    DW_AT_high_pc [DW_FORM_addr]    (0x0000000000000006)<br class="">    ...  </font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">  DW_TAG_subprogram [2]  </font></div><div class=""><font face="monospace, monospace" class="">    DW_AT_low_pc [DW_FORM_addr]     (0x0000000000000010)</font></div><div class=""><font face="monospace, monospace" class="">    DW_AT_high_pc [DW_FORM_addr]    (0x0000000000000016)</font><br class=""><font face="monospace, monospace" class="">    ...</font></div><div class=""><font face="monospace, monospace" class=""><br class=""></font></div><div class="">And, if I understand correctly there are no relocations or anything in there - it's just literal fixed values. </div></div></div></div></blockquote><div><br class=""></div><div>No, those will all have relocations (but the way the relocations work on mach-o, the content of the file where you should apply the relocation actually corresponds to the address in the object file).</div><br class=""><blockquote type="cite" class=""><div class=""><div class="gmail_quote" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class=""><div class="">So the debug map must say things like "function at 0x0 actually ended up at X, function at 0x10 actually ended up at Y”?</div></div></div></div></blockquote><div><br class=""></div><div>Yes, that’s it.</div><div><br class=""></div><blockquote type="cite" class=""><div class=""><div class="gmail_quote" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class=""><div class="">I then picture the algorithm in 2/ identifying the first subprogram as being at X, and the second subprogram being at Y.<br class=""></div></div></div></div></blockquote><div><br class=""></div><div>In 2/, we just say “that subprogram has a relocation in its low_pc attribute that corresponds to something described in the debug map, let’s mark all its dependencies as required”.</div><br class=""><blockquote type="cite" class=""><div class=""><div class="gmail_quote" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class=""><div class="">As the DIE tree for the first subprogram is cloned, I would imagine X - 0x0 is added to every address value. End result: low = X, high = X + 0x6<br class=""><br class="">As the DIE tree for the second subprogram is cloned, I would imagine Y - 0x10 is added to every address value. End result: low = Y, high = Y + 0x6<br class=""><br class="">I don't see where the high or low pc special cases end up coming into the equation. They seem to fall out, at least from the way I'm picturing it.</div></div></div></div></blockquote><div><br class=""></div><div>Before doing the special casing, I apply the relocations without even looking at what attribute they correspond. So you end up with the correct low_pcs, and then I go through the DIE and patch up the high_pc with the right offset. In this case, everything would work on your example, but consider:</div><div><br class=""></div><div><div class="gmail_quote"><div class=""><div class=""><font face="monospace, monospace" class="">  DW_TAG_subprogram [2]  </font></div><div class=""><font face="monospace, monospace" class="">    DW_AT_low_pc [DW_FORM_addr]     (0x0000000000000000)</font></div><div class=""><font face="monospace, monospace" class="">    DW_AT_high_pc [DW_FORM_addr]    (0x0000000000000010)</font></div><div class=""><font face="monospace, monospace" class="">    ...  </font></div></div><div class=""><div class=""><font face="monospace, monospace" class="">    DW_TAG_inlined_subroutine</font></div><div class=""><font face="monospace, monospace" class="">      DW_AT_low_pc [DW_FORM_addr]     (0x0000000000000000)</font></div><div class=""><font face="monospace, monospace" class="">    ...  </font></div><div class=""><font face="monospace, monospace" class=""> DW_TAG_subprogram [2] </font></div><div class=""><font face="monospace, monospace" class="">    DW_AT_low_pc [DW_FORM_addr]     (0x0000000000000010)</font></div><div class=""><font face="monospace, monospace" class="">    DW_AT_high_pc [DW_FORM_addr]    (0x0000000000000016)</font><br class=""><font face="monospace, monospace" class="">    ...</font></div></div></div></div><div><br class=""></div><div>Here the low_pc of the inlined subroutine has the same relocation as the low_pc of the first subprogram and the high_pc of the first subprogram has the same relocation as the low_pc of the second one. Generically applying the interesting relocations will update all these places and then we would update them again with the offsets if we do not special case them.</div><br class=""><blockquote type="cite" class=""><div class=""><div class="gmail_quote" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class=""><div class=""><br class=""></div></div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><div class=""><span class=""><br class=""><blockquote type="cite" class=""><div class="gmail_quote" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><div class="">Things I'm confused by:<br class=""><br class="">* Why does the second pass not touch the subprogram (how does the subprogram's high_pc get updated? Is that a special case? Does it need to be?)<br class=""></div></div></blockquote><div class=""><br class=""></div></span><div class="">The high_pcs are special cased because of Dwarf2 where they hold addresses (and these addresses could correspond to the wrong thing). This patch added special casing for low_pcs very similar to what was already there for high_pcs.</div><span class=""><br class=""><blockquote type="cite" class=""><div class="gmail_quote" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><div class="">* Why is the low_pc (or low_pcs) get updated eagerly, rather than deferring it to be handled with the second pass/addition code? (so then it wouldn't need a special case, with another special case on top to workaround it)</div></div></blockquote><div class=""><br class=""></div></span><div class="">To be extra clear, I don’t eagerly update low_pcs. I try to generically apply relocations which happens to be mostly about updating the low_pcs (I do that one every DIE that has a valid relocation, not only subprograms). But there are other cases like for example:</div><div class=""><br class=""></div><div class="">void foo();</div><div class="">template <void (*T)()> struct S {};</div><div class="">S<foo> s;</div><div class=""><br class=""></div><div class="">The debug info for the template value parameter will have a relocation for foo that I need to apply.<span class="Apple-converted-space"> </span></div></div></div></blockquote><div class=""><br class=""></div><div class="">OK, that's certainly interesting. And that could be exactly the same as the high_pc (if it's the same as the low_pc, there's nothing bad there - it should still be updated the same as every other address). So the question is how to resolve the ambiguity within a subprogram tree.<br class=""></div></div></div></blockquote><div><br class=""></div><div>There shouldn’t be any ambiguity here. We get a relocation for a function that *must* be in the debug map. And the fact that this function’s low_pc could be the same as the high_pc isn’t relevant, there simply is no ambiguity.</div><div><br class=""></div><blockquote type="cite" class=""><div class="gmail_quote" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class="">Currently you resolve this ambiguity by assuming all references except the high_pc (any high_pc, or just the high_pc of the subprogram?) refer to other entities (the next subprogram, etc), not the "one off the end" case?</div></div></blockquote><div><br class=""></div><div>All the high_pcs and also all the low_pcs that aren’t a subprogram low_pc need special casing.</div><br class=""><blockquote type="cite" class=""><div class="gmail_quote" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><div class=""><div class="">Also global variable locations might have complex expression that contain a relocations. Instead of special casing all the attributes that might contain a relocation I just apply the relocations and then patch up the places that I know could be wrong.</div></div></div></blockquote><div class=""><br class=""></div><div class="">I'm trying to better understand which ones could be wrong and why, and how you identify them.<br class=""><br class="">(and secondarily, specifically why the low_pc could be wrong)</div></div></blockquote><div><br class=""></div><div>I think I gave a example of that above. Let me state the issue a bit differently: I want to apply y all the relocations that correspond to debug map entries. I do that without looking at exactly where the relocation falls. Some of the spots where these relocations where applied weren’t actually meant to be relocated this way, but they were because their (object-file) addresses matched something in the debug map. This can happen in 2 cases that I know of: a block low_pc matching the enclosing function’s low_pc and a function/block high_pc matching another function’s low_pc.</div><br class=""><blockquote type="cite" class=""><div class="gmail_quote" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class=""> </div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><div class=""><div class="">Doing it this way is forward looking. For example when I once get back to submitting my default argument value debug info patch, we will have blobs in the debug info that might contain relocations. dsymutil shouldn’t need any updating to handle that because of the way it’s done.</div><div class="">dsymutil would need updating if we add a new attribute containing a relocation that might be ambiguous,<span class="Apple-converted-space"> </span></div></div></div></blockquote><div class=""><br class=""></div><div class="">Ambiguous like high_pc, you mean? *nod* It seems reasonable to special case that in some way, I haven't thought about it enough to know just how special, but "high_pc within a gives subprogram DIE tree is always relative to that subprogram, not a reference to some other subprogram" seems OK (& sounds like what you're doing).</div></div></blockquote><div><br class=""></div><div>Yes. </div><div><br class=""></div><div>Fred</div><br class=""><blockquote type="cite" class=""><div class="gmail_quote" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><div class=""><div class="">but my thinking is that this is much less likely that adding relocations that aren’t.</div><div class=""><br class=""></div><div class="">Fred  </div><span class=""><br class=""><blockquote type="cite" class=""><div class="gmail_quote" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><div class=""><span class=""><br class=""><blockquote type="cite" class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><div class=""><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div class="gmail_quote" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><div class="">Maybe I'm not understanding/explaining very well, though.</div><div class=""> </div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><div class=""><div class="">We might be able to completely remove any specific handling and just ‘promote’ all the relocations that fall inside a linked function as interesting. At the point we do that triaging relocs, we are not exploring the DIE tree though, just looking at the relocation list, so it would require us to trust the size field of the debug map, and I’m not sure we can do that 100% of the time (I know that this field is not accurate, it’s usually too big because it factors in alignment, but that might not be an issue if nothing gets allocated in the alignment padding).<br class=""></div></div></div></blockquote><div class=""><br class=""></div><div class="">Hmm - not sure I follow this. You're suggesting that if a non-debug-aware tool applied the relocations in the object file/debug info, it would mangle/damage the debug info?<br class=""></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">Basically yes. As I explain above a relocation based off the __text section with a constant offset could be replaced by different values depending on the context. I already said that, but I guess the message is hard to get through: dsymutil uses the object file relocations to know what to link, but it doesn’t do relocation processing in the usual sense, because this simply wouldn’t work (More precisely, it tries to do as much standard relocation processing as possible, but it needs some code to workaround the cases where that logic gives the wrong result).</div></div></div></blockquote><div class=""><br class="">It's slowly sinking in, I appreciate your patience in (repeatedly) explaining it to me.<br class=""></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">I hope I didn’t come through as complaining about that. I was merely acknowledging that it’s very different from other platforms and thus hard to convey to people not working with that platform. I really appreciate your interest.</div><div class=""><br class=""></div><div class="">Fred </div></div></div></blockquote></div></blockquote></span></div></div></blockquote></div></blockquote></div><br class=""></body></html>