[lld-macho] Fix assertion when two symbols at same addr have unwind info
If there are multiple symbols at the same address, our unwind info implementation assumes that we always register unwind entries to a single canonical symbol. This assumption was violated by the `registerEhFrame` code. Fixes #56570. Reviewed By: #lld-macho, thakis Differential Revision: https://reviews.llvm.org/D130208
This commit is contained in:
parent
1da3119025
commit
241f62d8d3
|
@ -1528,6 +1528,13 @@ void ObjFile::registerEhFrames(Section &ehFrameSection) {
|
|||
Defined *funcSym;
|
||||
if (funcAddrRelocIt != isec->relocs.end()) {
|
||||
funcSym = targetSymFromCanonicalSubtractor(isec, funcAddrRelocIt);
|
||||
// Canonicalize the symbol. If there are multiple symbols at the same
|
||||
// address, we want both `registerEhFrame` and `registerCompactUnwind`
|
||||
// to register the unwind entry under same symbol.
|
||||
// This is not particularly efficient, but we should run into this case
|
||||
// infrequently (only when handling the output of `ld -r`).
|
||||
funcSym = findSymbolAtOffset(cast<ConcatInputSection>(funcSym->isec),
|
||||
funcSym->value);
|
||||
} else {
|
||||
funcSym = findSymbolAtAddress(sections, funcAddr);
|
||||
ehRelocator.makePcRel(funcAddrOff, funcSym, target->p2WordSize);
|
||||
|
|
|
@ -211,7 +211,7 @@ void UnwindInfoSection::addSymbol(const Defined *d) {
|
|||
// we use that as the key here.
|
||||
auto p = symbols.insert({{d->isec, d->value}, d});
|
||||
// If we have multiple symbols at the same address, only one of them can have
|
||||
// an associated CUE.
|
||||
// an associated unwind entry.
|
||||
if (!p.second && d->unwindEntry) {
|
||||
assert(!p.first->second->unwindEntry);
|
||||
p.first->second = d;
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
--- !mach-o
|
||||
FileHeader:
|
||||
magic: 0xFEEDFACF
|
||||
cputype: 0x1000007
|
||||
cpusubtype: 0x3
|
||||
filetype: 0x1
|
||||
ncmds: 4
|
||||
sizeofcmds: 384
|
||||
flags: 0x2000
|
||||
reserved: 0x0
|
||||
LoadCommands:
|
||||
- cmd: LC_SEGMENT_64
|
||||
cmdsize: 312
|
||||
segname: ''
|
||||
vmaddr: 0
|
||||
vmsize: 96
|
||||
fileoff: 448
|
||||
filesize: 96
|
||||
maxprot: 7
|
||||
initprot: 7
|
||||
nsects: 3
|
||||
flags: 0
|
||||
Sections:
|
||||
- sectname: __text
|
||||
segname: __TEXT
|
||||
addr: 0x0
|
||||
size: 2
|
||||
offset: 0x1C0
|
||||
align: 0
|
||||
reloff: 0x0
|
||||
nreloc: 0
|
||||
flags: 0x80000400
|
||||
reserved1: 0x0
|
||||
reserved2: 0x0
|
||||
reserved3: 0x0
|
||||
content: '9090'
|
||||
- sectname: __eh_frame
|
||||
segname: __TEXT
|
||||
addr: 0x8
|
||||
size: 56
|
||||
offset: 0x1C8
|
||||
align: 3
|
||||
reloff: 0x220
|
||||
nreloc: 4
|
||||
flags: 0x0
|
||||
reserved1: 0x0
|
||||
reserved2: 0x0
|
||||
reserved3: 0x0
|
||||
content: 1400000000000000017A520001781001100C0708900100001C00000004000000F8FFFFFFFFFFFFFF0100000000000000000E080000000000
|
||||
relocations:
|
||||
- address: 0x1C
|
||||
symbolnum: 3
|
||||
pcrel: false
|
||||
length: 2
|
||||
extern: true
|
||||
type: 5
|
||||
scattered: false
|
||||
value: 0
|
||||
- address: 0x1C
|
||||
symbolnum: 4
|
||||
pcrel: false
|
||||
length: 2
|
||||
extern: true
|
||||
type: 0
|
||||
scattered: false
|
||||
value: 0
|
||||
- address: 0x20
|
||||
symbolnum: 4
|
||||
pcrel: false
|
||||
length: 3
|
||||
extern: true
|
||||
type: 5
|
||||
scattered: false
|
||||
value: 0
|
||||
- address: 0x20
|
||||
symbolnum: 2
|
||||
pcrel: false
|
||||
length: 3
|
||||
extern: true
|
||||
type: 0
|
||||
scattered: false
|
||||
value: 0
|
||||
- sectname: __compact_unwind
|
||||
segname: __LD
|
||||
addr: 0x40
|
||||
size: 32
|
||||
offset: 0x200
|
||||
align: 3
|
||||
reloff: 0x240
|
||||
nreloc: 1
|
||||
flags: 0x2000000
|
||||
reserved1: 0x0
|
||||
reserved2: 0x0
|
||||
reserved3: 0x0
|
||||
content: '0000000000000000010000000000010200000000000000000000000000000000'
|
||||
relocations:
|
||||
- address: 0x0
|
||||
symbolnum: 2
|
||||
pcrel: false
|
||||
length: 3
|
||||
extern: true
|
||||
type: 0
|
||||
scattered: false
|
||||
value: 0
|
||||
- cmd: LC_SYMTAB
|
||||
cmdsize: 24
|
||||
symoff: 584
|
||||
nsyms: 5
|
||||
stroff: 664
|
||||
strsize: 40
|
||||
- cmd: LC_BUILD_VERSION
|
||||
cmdsize: 32
|
||||
platform: 1
|
||||
minos: 659200
|
||||
sdk: 0
|
||||
ntools: 1
|
||||
Tools:
|
||||
- tool: 3
|
||||
version: 50069504
|
||||
- cmd: LC_DATA_IN_CODE
|
||||
cmdsize: 16
|
||||
dataoff: 584
|
||||
datasize: 0
|
||||
LinkEditData:
|
||||
NameList:
|
||||
- n_strx: 2
|
||||
n_type: 0xE
|
||||
n_sect: 1
|
||||
n_desc: 0
|
||||
n_value: 0
|
||||
- n_strx: 10
|
||||
n_type: 0xE
|
||||
n_sect: 1
|
||||
n_desc: 0
|
||||
n_value: 1
|
||||
- n_strx: 16
|
||||
n_type: 0xE
|
||||
n_sect: 1
|
||||
n_desc: 0
|
||||
n_value: 1
|
||||
- n_strx: 21
|
||||
n_type: 0xE
|
||||
n_sect: 2
|
||||
n_desc: 0
|
||||
n_value: 8
|
||||
- n_strx: 31
|
||||
n_type: 0xE
|
||||
n_sect: 2
|
||||
n_desc: 0
|
||||
n_value: 32
|
||||
StringTable:
|
||||
- ' '
|
||||
- _spacer
|
||||
- ltmp1
|
||||
- _foo
|
||||
- EH_Frame1
|
||||
- func.eh
|
||||
- ''
|
||||
...
|
|
@ -0,0 +1,26 @@
|
|||
## When changing the assembly input, uncomment these lines to re-generate the
|
||||
## YAML.
|
||||
# COM: llvm-mc --emit-dwarf-unwind=always -filetype=obj -triple=x86_64-apple-macos10.15 %s -o %t.o
|
||||
# COM: ld -r %t.o -o %t-r.o
|
||||
# COM: obj2yaml %t-r.o > %S/Inputs/double-unwind-info.yaml
|
||||
|
||||
# RUN: yaml2obj %S/Inputs/double-unwind-info.yaml > %t-r.o
|
||||
# RUN: %lld -dylib -lSystem %t-r.o -o /dev/null
|
||||
|
||||
.text
|
||||
## eh_frame function address relocations are only emitted if the function isn't
|
||||
## at address 0x0.
|
||||
_spacer:
|
||||
nop
|
||||
|
||||
## Check that we perform unwind info registration correctly when there are
|
||||
## multiple symbols at the same address. This would previously hit an assertion
|
||||
## error (PR56570).
|
||||
_foo:
|
||||
ltmp1:
|
||||
.cfi_startproc
|
||||
.cfi_def_cfa_offset 8
|
||||
nop
|
||||
.cfi_endproc
|
||||
|
||||
.subsections_via_symbols
|
Loading…
Reference in New Issue