The previous implementation of UnwindInfoSection materialized
all the compact unwind entries & applied their relocations, then parsed
the resulting data to generate the final unwind info. This design had
some unfortunate conseqeuences: since relocations can only be applied
after their referents have had addresses assigned, operations that need
to happen before address assignment must contort themselves. (See
{D113582} and observe how this diff greatly simplifies it.)
Moreover, it made synthesizing new compact unwind entries awkward.
Handling PR50956 will require us to do this synthesis, and is the main
motivation behind this diff.
Previously, instead of generating a new CompactUnwindEntry directly, we
would have had to generate a ConcatInputSection with a number of
`Reloc`s that would then get "flattened" into a CompactUnwindEntry.
This diff introduces an internal representation of `CompactUnwindEntry`
(the former `CompactUnwindEntry` has been renamed to
`CompactUnwindLayout`). The new CompactUnwindEntry stores references to
its personality symbol and LSDA section directly, without the use of
`Reloc` structs.
In addition to being easier to work with, this diff also allows us to
handle unwind info whose personality symbols are located in sections
placed after the `__unwind_info`.
Reviewed By: #lld-macho, oontvoo
Differential Revision: https://reviews.llvm.org/D123276
Previously, our unwind info finalization logic assumed that the LSDA
section referenced by `__compact_unwind` was already finalized before
`__TEXT,__unwind_info` itself. However, that assumption could be broken
by the use of `-rename_section` -- it could be (and is) used to move
`__gcc_except_tab` it into a different segment later in the file.
(__TEXT is always the first non-zerofill segment, so any rename
basically guarantees that the section will be ordered after
`__unwind_info`.)
To handle this case, we compare LSDA relocations instead of their final
values in `UnwindInfoSection::finalize()`, and we actually relocate
those LSDAs in `UnwindInfoSection::writeTo()`. In order to do this, we
need an easy way to track which Symbol a given CUE corresponds to. My
solution was to change our `cuPtrVector` into a vector of indices, with
each index used for both the symbols vector (`symbolsVec`) as well as
the CUE vector (`cuVector`).
This change seems perf neutral. Numbers for linking chromium_framework
on my 16 core Mac Pro:
base diff difference (95% CI)
sys_time 1.248 ± 0.025 1.245 ± 0.026 [ -1.3% .. +0.8%]
user_time 3.588 ± 0.045 3.587 ± 0.037 [ -0.6% .. +0.5%]
wall_time 4.605 ± 0.069 4.595 ± 0.069 [ -1.0% .. +0.5%]
samples 42 26
Reviewed By: #lld-macho, oontvoo
Differential Revision: https://reviews.llvm.org/D113582
D101513 means that we no longer need to specify `-pie` in most of our
test RUN commands. Let's clean up the unused flags so as not to confuse
future test writers.
Reviewed By: #lld-macho, oontvoo, MaskRay
Differential Revision: https://reviews.llvm.org/D113114
If the input has compact unwind info but all of it is removed
after dead stripping, we would crash. Now we don't write any
__unwind_info section at all, like ld64.
This is a bit awkward to implement because we only know the final
state of unwind info after UnwindInfoSectionImpl<Ptr>::finalize(),
which is called after sections are added. So add a small amount of
bookkeeping to relocateCompactUnwind() instead (which runs earlier)
so that we can predict what finalize() will do before it runs.
Fixes PR51010.
Differential Revision: https://reviews.llvm.org/D105557
Two bugs:
1. This tries to take the address of the last symbol plus the length
of the last symbol. However, the sorted vector is cuPtrVector,
not cuVector. Also, cuPtrVector has tombstone values removed
and cuVector doesn't. If there was a stripped value at the end,
the "last" element's value was UINT64_MAX, which meant the
sentinel value was one less than the length of that "last"
dead symbol.
2. We have to subtract in.header->addr. For 64-bit binaries that's
(1 << 32) and functionAddress is 32-bit so this is a no-op, but
for 32-bit binaries the sentinel's value was too large.
I believe this has no effect in practice since the first-level
binary search code in libunwind (in UnwindCursor.hpp) does:
uint32_t low = 0;
uint32_t high = sectionHeader.indexCount();
uint32_t last = high - 1;
while (low < high) {
uint32_t mid = (low + high) / 2;
if ((mid == last) ||
(topIndex.functionOffset(mid + 1) > targetFunctionOffset)) {
low = mid;
break;
} else {
low = mid + 1;
}
So the address of the last entry in the first-level table isn't really
checked -- except for the very end, but the check against `last` means
we just run the loop once more than necessary. But it makes `unwinddump` output
look less confusing, and it's what it looks was the intention here.
(No test since I can't think of a way to make FileCheck check that one
number is larger than another.)
Differential Revision: https://reviews.llvm.org/D105404
Fixes PR50529. With this, lld-linked Chromium base_unittests passes on arm macs.
Surprisingly, no measurable impact on link time.
Differential Revision: https://reviews.llvm.org/D104681
D101114 enforced proper version checks, which exposed a variety of version
mismatch issues in our tests. We previously changed the test inputs to
target 10.0, which was the simpler thing to do, but we should really
just have our lit.local.cfg default to targeting 10.15, which is what is done
here. We're not likely to ever have proper support for the older versions
anyway, as that would require more work for unclear benefit; for instance,
llvm-mc seems to generate a different compact unwind format for older macOS
versions, which would cause our compact-unwind.s test to fail.
Targeting 10.15 by default causes the following behavioral changes:
* `__mh_execute_header` is now a section symbol instead of an absolute symbol
* LC_BUILD_VERSION gets emitted instead of LC_VERSION_MIN_MACOSX. The former is
32 bytes in size whereas the latter is 16 bytes, so a bunch of hardcoded
address offsets in our tests had to be updated.
* >= 10.6 executables are PIE by default
Note that this diff was stacked atop of a local revert of most of the test
changes in rG8c17a875150f8e736e8f9061ddf084397f45f4c5, to make review easier.
Reviewed By: #lld-macho, oontvoo
Differential Revision: https://reviews.llvm.org/D101119
We had got it backwards... the minimum version of the target
should be higher than the min version of the object files, presumably
since new platforms are backwards-compatible with older formats.
Fixes PR50078.
The original commit (aa05439c9c) broke many tests that had inputs too
new for our target platform (10.0). This commit changes the inputs to
target 10.0, which was the simpler thing to do, but we should really
just have our lit.local.cfg default to targeting 10.15... we're not
likely to ever have proper support for the older versions anyway. I will
follow up with a change to that effect.
Differential Revision: https://reviews.llvm.org/D101114
This could probably have been part of D99633, but I split it up to make
things a bit more reviewable. I also fixed some bugs in the implementation that
were masked through integer underflows when operating in 64-bit mode.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D99823
This could probably have been part of D99633, but I split it up to make
things a bit more reviewable. I also fixed some bugs in the implementation that
were masked through integer underflows when operating in 64-bit mode.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D99823
{D95809} introduced a mechanism for synthetic symbol creation of personality
pointers. When multiple section relocations referred to the same personality
pointer, it would deduplicate them. However, it neglected to consider that we
could have symbol relocations that also refer to the same personality pointer.
This diff fixes it.
In practice, this mix of relocations arises when there is a statically-linked
personality routine that is referenced from multiple object files. Within the
same object file, it will be referred to via section relocations, but
(obviously) other object files will refer to it via symbol relocations. Failing
to deduplicate these references resulted in us going over the
3-personality-pointer limit when linking some larger applications.
Fixes llvm.org/PR48389.
Reviewed By: #lld-macho, thakis, alexshap
Differential Revision: https://reviews.llvm.org/D97245
The LSDA pointers are encoded as offsets from the image base,
and arranged in one big contiguous array. Each second-level page records
the offset within that LSDA array which corresponds to the LSDA for its
first CU entry.
Reviewed By: clayborg
Differential Revision: https://reviews.llvm.org/D95810
Note that there is a triple indirection involved with
personalities and compact unwind:
1. Two bits of each CU encoding are used as an offset into the
personality array.
2. Each entry of the personality array is an offset from the image base.
The resulting address (after adding the image base) should point within the
GOT.
3. The corresponding GOT entry contains the actual pointer to the
personality function.
To further complicate things, when the personality function is in the
object file (as opposed to a dylib), its references in
`__compact_unwind` may refer to it via a section + offset relocation
instead of a symbol relocation. Since our GOT implementation can only
create entries for symbols, we have to create a synthetic symbol at the
given section offset.
Reviewed By: clayborg
Differential Revision: https://reviews.llvm.org/D95809