This is an archive of the discontinued LLVM Phabricator instance.

[DWARFLinker][dsymutil][NFC] add section index into address range.
Needs ReviewPublic

Authored by avl on Mar 12 2020, 11:43 AM.

Details

Summary

dsymutil reads address ranges from DebugMap, which contains addresses
inside object file. These addresses could be used as unique identifiers
of address ranges since --function-sections is not used on darwin. i.e. all
code is inside one section. For the case when DWARFLinker optimizes
debug info for --function-sections (Remove obsolete debug info: D74169)
it is necessary to have additional identifier for addresses(since addresses for different
sections could clash). This patch adds SectionIndex to address ranges
to have a unique identifier for the address range.

Testing: it passes "check-all" lit testing. MD5 checksum for clang .dSYM
bundle matches for the dsymutil with/without that patch.

Diff Detail

Event Timeline

avl created this revision.Mar 12 2020, 11:43 AM

My only rough thought here (as I'm not especially versed in the DWARFLinker code) is that this feature (doing debug info redundancy elimination during ld -r) seems more like a stretch/later goal & I'd have thought it'd be likely/better to implement this for non"-r" linking first, since that's close(r) to the llvm-dsymutil functionality already in DWARFLinker, then in subsequent patches generalize this (in the way you're proposing) to handle the "-r" sort of case, which is probably (likely/actually) more complicated (or at least more new code, since it's not something that DWARFLuinker has had to support until this point), keeping track of addresses, etc.

Could changes like this be tested (possibly unit tested) in some way? I guess DWARFLinker funcitonality's been tested in llvm-dsymutil up until this point - but this is the first major/new functionality DWARFLinker will support that llvm-dsymutil does not support, so some in-tree testing story will need to be created.

avl added a comment.Mar 13 2020, 4:40 AM

My only rough thought here (as I'm not especially versed in the DWARFLinker code) is that this feature (doing debug info redundancy elimination during ld -r) seems more like a stretch/later goal & I'd have thought it'd be likely/better to implement this for non"-r" linking first, since that's close(r) to the llvm-dsymutil functionality already in DWARFLinker, then in subsequent patches generalize this (in the way you're proposing) to handle the "-r" sort of case, which is probably (likely/actually) more complicated (or at least more new code, since it's not something that DWARFLuinker has had to support until this point), keeping track of addresses, etc.

At this point, I do not plan to support ld -r, since "-r and --gc-sections may not be used together". So this change is for non "-r" linking.

I think it is better not to implement "debug info redundancy elimination in lld" using the standard dsymutil scenario. Instead, it is better to use an optimized scenario:

  1. standard dsymutil scenario:
  • lld creates liveness map for sections.
  • lld resolves relocations and generates contents of output sections.
  • lld creates a debug map for DWARFLinker.
  • DWARFLinker links debug info(creates a tree of cloned DIEs).
  • DWARFLinker generates new content for output sections.

    Memory objects:
  • source debug info sections.
  • NON-optimized debug info sections.
  • DIEs tree.
  • optimized output debug info sections.
  1. optimized dsymutil scenario:
  • lld creates liveness map for sections.
  • DWARFLinker links debug info(creates a tree of cloned DIEs).
  • DWARFLinker generates new content for output sections.
  • lld resolves relocations and generates contents of output sections.

    Memory objects:
  • source debug info sections.
  • DIEs tree.
  • optimized debug info sections.
  • optimized output debug info sections.

The second scenario does not need to create a debug map. It also requires less memory.
Thus I am planning to use this second scenario.

If we would do the first scenario and later would implement second, then all lld integration part should be thrown away and replaced with the new implementation. So implementing the first scenario would be just a waste of time.

I think it makes sense to implement the second scenario from scratch.

Could changes like this be tested (possibly unit tested) in some way? I guess DWARFLinker funcitonality's been tested in llvm-dsymutil up until this point - but this is the first major/new functionality DWARFLinker will support that llvm-dsymutil does not support, so some in-tree testing story will need to be created.

Yes. I am going to add tests together with new functionality. My overall development plan looks like this :

  1. create a first version that would work for .debug_info/.debug_ranges tables. This version could be taken for evaluation, as requested in D74169.
    1. D76085 patch.
    2. internal patch implementing AddressesMap in lld.
    3. internal patch implementing DebugInputSection in lld.
    4. internal patch dumping DIEs into bytes array.
    5. internal patch implementing DwarfEmitter(dump DIEs into bytes array).
  1. divide the above patch into smaller patches and integrate them with a set of tests.
  1. implement the rest of the debug info tables.

So I assumed that D76085 would be done as NFC for the current codebase. And changes in interfaces would be used while integrating patches on step 2.

In D76085#1921389, @avl wrote:

My only rough thought here (as I'm not especially versed in the DWARFLinker code) is that this feature (doing debug info redundancy elimination during ld -r) seems more like a stretch/later goal & I'd have thought it'd be likely/better to implement this for non"-r" linking first, since that's close(r) to the llvm-dsymutil functionality already in DWARFLinker, then in subsequent patches generalize this (in the way you're proposing) to handle the "-r" sort of case, which is probably (likely/actually) more complicated (or at least more new code, since it's not something that DWARFLuinker has had to support until this point), keeping track of addresses, etc.

At this point, I do not plan to support ld -r, since "-r and --gc-sections may not be used together". So this change is for non "-r" linking.

I think it is better not to implement "debug info redundancy elimination in lld" using the standard dsymutil scenario. Instead, it is better to use an optimized scenario:

  1. standard dsymutil scenario:
  • lld creates liveness map for sections.
  • lld resolves relocations and generates contents of output sections.
  • lld creates a debug map for DWARFLinker.
  • DWARFLinker links debug info(creates a tree of cloned DIEs).
  • DWARFLinker generates new content for output sections.

    Memory objects:
  • source debug info sections.
  • NON-optimized debug info sections.

I'm not sure where this ^ happens in the scenario list you describe above. And is this fundamentally necessary for the llvm-dsymutil functionality, but not needed for lld? Or is this an improvement that could be made (& tested) in llvm-dsymutil independently/prior to the lld work?

  • DIEs tree.
  • optimized output debug info sections.
  1. optimized dsymutil scenario:
  • lld creates liveness map for sections.
  • DWARFLinker links debug info(creates a tree of cloned DIEs).
  • DWARFLinker generates new content for output sections.
  • lld resolves relocations and generates contents of output sections.

    Memory objects:
  • source debug info sections.
  • DIEs tree.
  • optimized debug info sections.
  • optimized output debug info sections.

The second scenario does not need to create a debug map. It also requires less memory.
Thus I am planning to use this second scenario.

If we would do the first scenario and later would implement second, then all lld integration part should be thrown away and replaced with the new implementation. So implementing the first scenario would be just a waste of time.

I think it makes sense to implement the second scenario from scratch.

Could changes like this be tested (possibly unit tested) in some way? I guess DWARFLinker funcitonality's been tested in llvm-dsymutil up until this point - but this is the first major/new functionality DWARFLinker will support that llvm-dsymutil does not support, so some in-tree testing story will need to be created.

Yes. I am going to add tests together with new functionality.

Changes to code in the llvm/ repository should generally be tested that repository - not only by tests in another project like lld.

My overall development plan looks like this :

  1. create a first version that would work for .debug_info/.debug_ranges tables. This version could be taken for evaluation, as requested in D74169.
    1. D76085 patch.
    2. internal patch implementing AddressesMap in lld.
    3. internal patch implementing DebugInputSection in lld.
    4. internal patch dumping DIEs into bytes array.
    5. internal patch implementing DwarfEmitter(dump DIEs into bytes array).
  1. divide the above patch into smaller patches and integrate them with a set of tests.
  1. implement the rest of the debug info tables.

So I assumed that D76085 would be done as NFC for the current codebase. And changes in interfaces would be used while integrating patches on step 2.

avl added a comment.Mar 13 2020, 12:53 PM

Memory objects:
source debug info sections.
NON-optimized debug info sections.

I'm not sure where this ^ happens in the scenario list you describe above.

it happens at point 3. "lld resolves relocations and generates contents of output sections."
the result of this step would be non-optimized debug info section with resolved relocations(*).
this result should be later passed to dsymutil if we speak about standard dsymutil scenario.

And is this fundamentally necessary for the llvm-dsymutil functionality,
but not needed for lld? Or is this an improvement that could be made
(& tested) in llvm-dsymutil independently/prior to the lld work?

Yes. This is fundamentally necessary for dsymutil functionality.
dsymutil gets on the input - debug map(which maps symbol addresses in the object file and their linked addresses in binary)
and linked binary. So to preserve dsymutil behavior, we need to create the same input: debug map and linked binary.

But for "debug info linking" in general, it is not necessary to have linked binary and debug map.
All information available in lld before output sections are linked and generated.
As soon as the linker built liveness information for the sections, the debug info could be optimized/linked.
As a result, when lld would resolve relocations and generate output - the size of generated sections would be smaller than in (*).
That possibility is the advantage of "linking debug info in lld" before "linking debug info in dsymutil".

This optimized behavior could not be tested with dsymutil, since dsymutil is not ready to work with a non-linked binary.

But, we could test this functionality from lld.

Changes to code in the llvm/ repository should generally be tested that repository - not only by tests in another project like lld.

I agree. Having unit-tests for old dsymutil functionality and for this new functionality would be good. I am OK to do them.
Though, if that is possible, I would prefer to make them later and integrate together with related functionality.
This concrete change does not add new functionality. It only changes interface and this change is tested by existing dsymutil tests.
If that is not OK for current moment - I would start to work on creating set of unit-tests.

In D76085#1922182, @avl wrote:

Memory objects:
source debug info sections.
NON-optimized debug info sections.

I'm not sure where this ^ happens in the scenario list you describe above.

it happens at point 3. "lld resolves relocations and generates contents of output sections."
the result of this step would be non-optimized debug info section with resolved relocations(*).
this result should be later passed to dsymutil if we speak about standard dsymutil scenario.

But in the dsymutil scenario, debug info is not linked into the executable - so there would be no "non-optimized linked debug info sections". So I'm still confused here.

And is this fundamentally necessary for the llvm-dsymutil functionality,
but not needed for lld? Or is this an improvement that could be made
(& tested) in llvm-dsymutil independently/prior to the lld work?

Yes. This is fundamentally necessary for dsymutil functionality.
dsymutil gets on the input - debug map(which maps symbol addresses in the object file and their linked addresses in binary)
and linked binary. So to preserve dsymutil behavior, we need to create the same input: debug map and linked binary.

Why does dsymutil need the linked binary? Isn't the debug map sufficient? & couldn't a similar mapping be produced part-way through linking inside lld?

But for "debug info linking" in general, it is not necessary to have linked binary and debug map.
All information available in lld before output sections are linked and generated.
As soon as the linker built liveness information for the sections, the debug info could be optimized/linked.
As a result, when lld would resolve relocations and generate output - the size of generated sections would be smaller than in (*).
That possibility is the advantage of "linking debug info in lld" before "linking debug info in dsymutil".

This optimized behavior could not be tested with dsymutil, since dsymutil is not ready to work with a non-linked binary.

But, we could test this functionality from lld.

Changes to code in the llvm/ repository should generally be tested that repository - not only by tests in another project like lld.

I agree. Having unit-tests for old dsymutil functionality and for this new functionality would be good.

Since dsymutil is in the llvm subproject it's not necessary to re-test its functionality at the unit level, though it can be handy to write unit tests for more targeted testing that might be hard to reach via end-to-end testing using llvm-dsymutil itself.
For the new functionality, it should be tested in the llvm subproject /somewhere/ when it's added - testing it only in lld is insufficient (because it would be easy for llvm developers to regress/break the functionality as they aren't required to test all other subprojects for their changes).

I am OK to do them.
Though, if that is possible, I would prefer to make them later and integrate together with related functionality.
This concrete change does not add new functionality.

What would add new functionality? If by new functionality you mean new user-visible functionality in some llvm installed executable (like lld or llvm-dsymutil) then, yes, one can write lots of untested code that adds no new functionality, until it does - when that new code is finally called from some production binary. The problem with only testing once that functionality surfaces into a binary is that we'll lose track of what all the new code is taht now needs testing - it's best to add testing as the behavior is implemented in the code.

It only changes interface and this change is tested by existing dsymutil tests.
If that is not OK for current moment - I would start to work on creating set of unit-tests.

avl added a comment.Mar 14 2020, 3:52 AM

But in the dsymutil scenario, debug info is not linked into the executable - so there would be no "non-optimized linked debug info sections". So I'm still confused here.

Right. I had in mind the current behavior of LLD - it has a final stage where output generated and relocations resolved for all sections. Since we need linked addresses, we need to execute that stage. As a result, the output would be generated for all sections(.text and .debug_info).

But that behavior could be changed. Debug info sections could be handled separately in two steps. lld could link non-debug sections first, then generate debug map, optimize debug info sections and finally link debug info sections.

Doing that way would avoid "NON-optimized debug info sections." generation.

Thus the only additional thing would be the generation of debug map.

Why does dsymutil need the linked binary? Isn't the debug map sufficient? & couldn't a similar mapping be produced part-way through linking inside lld?

debug map could be produced by lld.
Though it would be an additional step. That step could be avoided if DWARFLinker becomes to work with sectioned addresses.

The problem with only testing once that functionality surfaces into a binary is that we'll lose track of what all the new code is taht now needs testing - it's best to add testing as the behavior is implemented in the code.

I planned to add tests with code which would use sectioned addresses.
I will add it now, If making DWARFLinker to work with sectioned addresses is OK in general.

In D76085#1922838, @avl wrote:

But in the dsymutil scenario, debug info is not linked into the executable - so there would be no "non-optimized linked debug info sections". So I'm still confused here.

Right. I had in mind the current behavior of LLD - it has a final stage where output generated and relocations resolved for all sections. Since we need linked addresses, we need to execute that stage.

I assume LLD has to figure out the final locations of things before it actually generates the output and resolves relocations (I mean, during generating the output it could then compute the final locations - but I think the final locations would be known and /then/ those sections would all be written to the output file).

As a result, the output would be generated for all sections(.text and .debug_info).

But that behavior could be changed. Debug info sections could be handled separately in two steps. lld could link non-debug sections first, then generate debug map, optimize debug info sections and finally link debug info sections.

Doing that way would avoid "NON-optimized debug info sections." generation.

Thus the only additional thing would be the generation of debug map.

If by "debug map" you mean a literal file, or file in memory - I think that could reasonably be avoided & changes to DWARFLinker to support an API-level description of the semantic contents of the debug map ("this address/section ended up at this final addresS" sort of info) would be quite reasonable.

Why does dsymutil need the linked binary? Isn't the debug map sufficient? & couldn't a similar mapping be produced part-way through linking inside lld?

debug map could be produced by lld.
Though it would be an additional step. That step could be avoided if DWARFLinker becomes to work with sectioned addresses.

The problem with only testing once that functionality surfaces into a binary is that we'll lose track of what all the new code is taht now needs testing - it's best to add testing as the behavior is implemented in the code.

I planned to add tests with code which would use sectioned addresses.
I will add it now, If making DWARFLinker to work with sectioned addresses is OK in general.

avl added a comment.Mar 17 2020, 9:19 AM

If by "debug map" you mean a literal file, or file in memory - I think that could reasonably be avoided & changes to DWARFLinker to support an API-level description of the semantic contents of the debug map ("this address/section ended up at this final addresS" sort of info) would be quite reasonable.

But even if that map would be done as API-level description - this map would require time to be build and memory to be kept. Wouldn`t it be good if we are able to not do it?

In D76085#1926829, @avl wrote:

If by "debug map" you mean a literal file, or file in memory - I think that could reasonably be avoided & changes to DWARFLinker to support an API-level description of the semantic contents of the debug map ("this address/section ended up at this final addresS" sort of info) would be quite reasonable.

But even if that map would be done as API-level description - this map would require time to be build and memory to be kept. Wouldn`t it be good if we are able to not do it?

I'm not sure I understand the alternative - are you picturing doing the DWARF reduction and updating relocations and then feeding the reduced but unrelocated DWARF into lld's linking step?

The debug map seems like it should be the same data structure that would be used for applying relocations anyway - is it not? I'd be surprised if it was significantly different/new cost to have that data available for the DWARF linking as it would be for the relocation application.

avl added a comment.Mar 17 2020, 12:00 PM

I'm not sure I understand the alternative - are you picturing doing the DWARF reduction and updating relocations and then feeding the reduced but unrelocated DWARF into lld's linking step?

yes. I planned to do in that way.

  1. Do DWARF reduction. (Do not patch DWARF address values(LowPC, HighPC...) as dsymutil usually does, fix relocations in-sections offsets)
  2. Go through usual linking process which would resolve relocations and put proper address values.

The debug map seems like it should be the same data structure that would be used for applying relocations anyway - is it not? I'd be surprised if it was significantly different/new cost to have that data available for the DWARF linking as it would be for the relocation application.

I would check it more. If all necessary info could be produced from the single relocation(without preliminary gathering data and creating additional maps) then - yes, it is cheap.

In D76085#1927241, @avl wrote:

I'm not sure I understand the alternative - are you picturing doing the DWARF reduction and updating relocations and then feeding the reduced but unrelocated DWARF into lld's linking step?

yes. I planned to do in that way.

  1. Do DWARF reduction. (Do not patch DWARF address values(LowPC, HighPC...) as dsymutil usually does, fix relocations in-sections offsets)
  2. Go through usual linking process which would resolve relocations and put proper address values.

While these are understandably different situations, keeping them similar seems like there's some value - so I'd be inclined to encourage you to see if there's a way to make the lld situation more like the llvm-dsymutil situation (where the DWARF reduction also applies relocations, essentially) or potentially make the llvm-dsymutil situation more like lld (could be useful to reuse pieces of lld that make for efficient section rewriting, etc, to improve llvm-dsymutil/share more code there).

Certainly llvm-dwp would probably benefit from being rephrased in terms of lld functionality (as binutils dwp uses some of gold's infrastructure - though admittedly not a lot, in part because dwp doesn't need to apply relocations, for instance).

The debug map seems like it should be the same data structure that would be used for applying relocations anyway - is it not? I'd be surprised if it was significantly different/new cost to have that data available for the DWARF linking as it would be for the relocation application.

I would check it more. If all necessary info could be produced from the single relocation(without preliminary gathering data and creating additional maps) then - yes, it is cheap.

I think that'd be worthwhile to investigate/understand.

avl added a comment.Mar 19 2020, 10:17 AM

While these are understandably different situations, keeping them similar seems like there's some value - so I'd be inclined to encourage you to see if there's a way to make the lld situation more like the llvm-dsymutil situation (where the DWARF reduction also applies relocations, essentially) or potentially make the llvm-dsymutil situation more like lld (could be useful to reuse pieces of lld that make for efficient section rewriting, etc, to improve llvm-dsymutil/share more code there).

Certainly llvm-dwp would probably benefit from being rephrased in terms of lld functionality (as binutils dwp uses some of gold's infrastructure - though admittedly not a lot, in part because dwp doesn't need to apply relocations, for instance).

Agreed. It would be good if DWARFLinker would use the same handling for both dsymutil and lld.

I think that'd be worthwhile to investigate/understand.

I prototyped this scheme - DWARF reduction is done in lld after addresses assigned, but before output sections are generated; DWARF reduction also applies relocations; DebugMap information created from relocations: It is equally cheap. It does not need additional time and memory for creating DebugMap.

So from the point of required resources and performance : both schemes are equal.

But this patch is still necessary. The problem is that in darwin case -ffunction-sections does nothing. And address ranges do not clash. Thus following code is working:

auto LowPc = dwarf::toAddress(DIE.find(dwarf::DW_AT_low_pc));

Ranges[*LowPc] = ObjFileAddressRange(*HighPc, MyInfo.AddrAdjust);

But in linux case all address ranges start from 0(in -ffunction-sections case). So above code would not work.
It is necessary to add SectionIndex to have possibility to differentiate address ranges.

So, I am going to add unit tests to this patch...

In D76085#1931600, @avl wrote:

While these are understandably different situations, keeping them similar seems like there's some value - so I'd be inclined to encourage you to see if there's a way to make the lld situation more like the llvm-dsymutil situation (where the DWARF reduction also applies relocations, essentially) or potentially make the llvm-dsymutil situation more like lld (could be useful to reuse pieces of lld that make for efficient section rewriting, etc, to improve llvm-dsymutil/share more code there).

Certainly llvm-dwp would probably benefit from being rephrased in terms of lld functionality (as binutils dwp uses some of gold's infrastructure - though admittedly not a lot, in part because dwp doesn't need to apply relocations, for instance).

Agreed. It would be good if DWARFLinker would use the same handling for both dsymutil and lld.

I think that'd be worthwhile to investigate/understand.

I prototyped this scheme - DWARF reduction is done in lld after addresses assigned, but before output sections are generated; DWARF reduction also applies relocations; DebugMap information created from relocations: It is equally cheap. It does not need additional time and memory for creating DebugMap.

So from the point of required resources and performance : both schemes are equal.

But this patch is still necessary. The problem is that in darwin case -ffunction-sections does nothing. And address ranges do not clash. Thus following code is working:

auto LowPc = dwarf::toAddress(DIE.find(dwarf::DW_AT_low_pc));

Ranges[*LowPc] = ObjFileAddressRange(*HighPc, MyInfo.AddrAdjust);

But in linux case all address ranges start from 0(in -ffunction-sections case). So above code would not work.
It is necessary to add SectionIndex to have possibility to differentiate address ranges.

So, I am going to add unit tests to this patch...

Sounds good (& FWIW, even without function-sections, inline functions, and function template implicit specializations also end up in their own sections, etc (or you might've put functions in sections explicitly with attribute((section("..."))) attribute)) - thankss for all the due diligence and explanation!

avl updated this revision to Diff 253714.Mar 30 2020, 3:13 PM

addressed comments: added unit test for compile unit addresses ranges.
(I put the unit test into the unittests/DebugInfo/DWARF/ instead of
separate unittests/DWARFLinker, since unittests/DebugInfo/DWARF
already has an implementation of DwarfGenerator for unit tests).

avl added a comment.Apr 6 2020, 5:38 AM

@dblaikie David, Does added unit test do what you`ve asked for?

@aprantl Would probably prefer one of you folks more familiar with dsymutil/DWARFLinker to do final review on this

llvm/lib/DWARFLinker/DWARFLinker.cpp
1035–1048

What happened here? (is this change related/necessary for the rest of this patch)

1097–1102

Skip unnecessary refactors (if this is unnecessary)

1636

(similarly - best to leave out changes that aren't related to this patch, if that's the case here)

1657

Is this change motivated by/necessary/related to the rest of this patch? If not, best to leave it out.

llvm/lib/DWARFLinker/DWARFLinkerCompileUnit.cpp
138–146

Probably commit the "this->" removal as a separate patch (no need to send that for review) to keep this change on-topic.

llvm/tools/dsymutil/DwarfLinkerForBinary.h
118

Why the change in () here?

llvm/tools/dsymutil/DwarfStreamer.cpp
390–391 ↗(On Diff #253714)

What's the purpose of this change?

avl marked 2 inline comments as done.Apr 7 2020, 9:45 AM
avl added inline comments.
llvm/lib/DWARFLinker/DWARFLinker.cpp
1035–1048

I would remove this and others unrelated changes.

llvm/tools/dsymutil/DwarfLinkerForBinary.h
118

It looks like it needs explicit type conversion for braced initialization.

avl updated this revision to Diff 255781.Apr 7 2020, 12:58 PM

addressed comments(removed unrelated refactorings).

avl edited the summary of this revision. (Show Details)Apr 23 2020, 4:37 AM
avl added a reviewer: aprantl.
avl added a comment.Apr 23 2020, 4:39 AM

@JDevlieghere @clayborg @aprantl Could you take a look at this review, please ?

Sorry about the delay, I had comments on this but I never submitted them!...

Structure is good. Just a few nits about cleaning up using std::numeric_limits<uint64_t>::max() and -1ULL for max address and cleaning the code up by not having multiple locations that are implementing SectionAddress::contains() and SectionAddress::operator <= manually.

llvm/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h
107

Remove whitespace only change.

llvm/lib/DWARFLinker/DWARFLinker.cpp
451

do we need to use dwarf::toSectionedAddress() and verify sections are the same?

1033–1034

Can we make a constexpr MAX_ADDR or INVALID_ADDR for the max address and use it here instead of std::numeric_limits<uint64_t>::max() being inlined everywhere?

1036–1038

constexpr MAX_ADDR or INVALID_ADDR

1097–1100

constexpr MAX_ADDR or INVALID_ADDR

1473–1474

constexpr MAX_ADDR or INVALID_ADDR and do we need to use dwarf::toSectionedAddress() now?

1473–1475

use dwarf::toSectionedAddress here? We don't want to assume anything about the low PC section here do we?

1477–1478

constexpr MAX_ADDR or INVALID_ADDR

1498–1502

This code would be much cleaner if we add a SectionedAddress::contains() method.

1627–1630

If we had a object::SectionAddressRange this code would look a lot cleaner:

if (!CurrRange.contains(Row.Address) || (Row.Address.Address == CurrRange.stop().Address && !Row.EndSequence))
1634

constexpr MAX_ADDR or INVALID_ADDR

1637–1638

This code would be much cleaner if we add a SectionedAddress::operator <=() method.

1640

constexpr MAX_ADDR or INVALID_ADDR

1652–1653

This code would be much cleaner if we add a SectionedAddress::operator <=() method.

1657

constexpr MAX_ADDR or INVALID_ADDR

llvm/lib/DWARFLinker/DWARFStreamer.cpp
303–305

This code would be much cleaner if we add a SectionedAddress::contains() method.

avl marked 14 inline comments as done.Apr 24 2020, 10:59 AM
avl added inline comments.
llvm/lib/DWARFLinker/DWARFLinker.cpp
1473–1474

We do not need to have SectionedAddress here. LowPc/Unit.getLowPc() is a property of Compile unit. We could not have values pointing to different sections here. And Unit.getLowPc() is recalculated in terms of resulting binary address :

LowPc = std::min(*LowPc, FuncLowPc.Address + PcOffset);

avl updated this revision to Diff 259995.Apr 24 2020, 2:11 PM

addressed comments(added Optional values, added contains function for interval).

lgtm now. Probably best to have someone that worked on llvm-dsymutil do the final accept on this.