forked from OSchip/llvm-project
[mach-o] add support for old x86 __eh_frame sections
Over time the symbols and relocations have changed for dwarf unwind info in the __eh_frame section. Add test cases for older and new style. llvm-svn: 213585
This commit is contained in:
parent
586448763e
commit
03e16f2ab4
|
@ -83,6 +83,7 @@ private:
|
|||
funcRel32, /// ex: movl _foo-L1(%eax), %eax
|
||||
pointer32, /// ex: .long _foo
|
||||
delta32, /// ex: .long _foo - .
|
||||
negDelta32, /// ex: .long . - _foo
|
||||
|
||||
// Kinds introduced by Passes:
|
||||
lazyPointer, /// Location contains a lazy pointer.
|
||||
|
@ -120,6 +121,7 @@ const Registry::KindStrings ArchHandler_x86::_sKindStrings[] = {
|
|||
LLD_KIND_STRING_ENTRY(funcRel32),
|
||||
LLD_KIND_STRING_ENTRY(pointer32),
|
||||
LLD_KIND_STRING_ENTRY(delta32),
|
||||
LLD_KIND_STRING_ENTRY(negDelta32),
|
||||
LLD_KIND_STRING_ENTRY(lazyPointer),
|
||||
LLD_KIND_STRING_ENTRY(lazyImmediateLocation),
|
||||
LLD_KIND_STRING_END
|
||||
|
@ -302,22 +304,28 @@ ArchHandler_x86::getPairReferenceInfo(const normalized::Relocation &reloc1,
|
|||
ec = atomFromAddr(0, fromAddress, &fromTarget, &offsetInFrom);
|
||||
if (ec)
|
||||
return ec;
|
||||
if (fromTarget != inAtom)
|
||||
return make_dynamic_error_code(Twine("SECTDIFF relocation where "
|
||||
"subtrahend label is not in atom"));
|
||||
*kind = ((perms & DefinedAtom::permR_X) == DefinedAtom::permR_X) ? funcRel32
|
||||
: delta32;
|
||||
if (*kind == funcRel32) {
|
||||
// SECTDIFF relocations are used in i386 codegen where the function
|
||||
// prolog does a CALL to the next instruction which POPs the return
|
||||
// address into EBX which becomes the pic-base register. The POP
|
||||
// instruction is label the used for the subtrahend in expressions.
|
||||
// The funcRel32 kind represents the 32-bit delta to some symbol from
|
||||
// the start of the function (atom) containing the funcRel32.
|
||||
uint32_t ta = fromAddress + value - toAddress;
|
||||
*addend = ta - offsetInFrom;
|
||||
if (fromTarget != inAtom) {
|
||||
if (*target != inAtom)
|
||||
return make_dynamic_error_code(Twine("SECTDIFF relocation where "
|
||||
"neither target is in atom"));
|
||||
*kind = negDelta32;
|
||||
*addend = toAddress - value - fromAddress;
|
||||
*target = fromTarget;
|
||||
} else {
|
||||
*addend = fromAddress + value - toAddress;
|
||||
if ((perms & DefinedAtom::permR_X) == DefinedAtom::permR_X) {
|
||||
// SECTDIFF relocations are used in i386 codegen where the function
|
||||
// prolog does a CALL to the next instruction which POPs the return
|
||||
// address into EBX which becomes the pic-base register. The POP
|
||||
// instruction is label the used for the subtrahend in expressions.
|
||||
// The funcRel32 kind represents the 32-bit delta to some symbol from
|
||||
// the start of the function (atom) containing the funcRel32.
|
||||
*kind = funcRel32;
|
||||
uint32_t ta = fromAddress + value - toAddress;
|
||||
*addend = ta - offsetInFrom;
|
||||
} else {
|
||||
*kind = delta32;
|
||||
*addend = fromAddress + value - toAddress;
|
||||
}
|
||||
}
|
||||
return std::error_code();
|
||||
break;
|
||||
|
@ -379,6 +387,9 @@ void ArchHandler_x86::applyFixupFinal(const Reference &ref, uint8_t *location,
|
|||
case delta32:
|
||||
write32(*loc32, _swap, targetAddress - fixupAddress + ref.addend());
|
||||
break;
|
||||
case negDelta32:
|
||||
write32(*loc32, _swap, fixupAddress - targetAddress + ref.addend());
|
||||
break;
|
||||
case lazyPointer:
|
||||
case lazyImmediateLocation:
|
||||
// do nothing
|
||||
|
@ -420,6 +431,9 @@ void ArchHandler_x86::applyFixupRelocatable(const Reference &ref,
|
|||
case delta32:
|
||||
write32(*loc32, _swap, targetAddress - fixupAddress + ref.addend());
|
||||
break;
|
||||
case negDelta32:
|
||||
write32(*loc32, _swap, fixupAddress - targetAddress + ref.addend());
|
||||
break;
|
||||
case lazyPointer:
|
||||
case lazyImmediateLocation:
|
||||
// do nothing
|
||||
|
@ -507,17 +521,24 @@ void ArchHandler_x86::appendSectionRelocations(
|
|||
}
|
||||
break;
|
||||
case funcRel32:
|
||||
appendReloc(relocs, sectionOffset, 0, addressForAtom(*ref.target()),
|
||||
GENERIC_RELOC_SECTDIFF | rScattered | rLength4);
|
||||
appendReloc(relocs, sectionOffset, 0, addressForAtom(atom) - ref.addend(),
|
||||
GENERIC_RELOC_PAIR | rScattered | rLength4);
|
||||
appendReloc(relocs, sectionOffset, 0, addressForAtom(*ref.target()),
|
||||
GENERIC_RELOC_SECTDIFF | rScattered | rLength4);
|
||||
appendReloc(relocs, sectionOffset, 0, addressForAtom(atom) - ref.addend(),
|
||||
GENERIC_RELOC_PAIR | rScattered | rLength4);
|
||||
break;
|
||||
case delta32:
|
||||
appendReloc(relocs, sectionOffset, 0, addressForAtom(*ref.target()),
|
||||
GENERIC_RELOC_SECTDIFF | rScattered | rLength4);
|
||||
appendReloc(relocs, sectionOffset, 0, addressForAtom(atom) +
|
||||
ref.offsetInAtom(),
|
||||
GENERIC_RELOC_PAIR | rScattered | rLength4);
|
||||
appendReloc(relocs, sectionOffset, 0, addressForAtom(*ref.target()),
|
||||
GENERIC_RELOC_SECTDIFF | rScattered | rLength4);
|
||||
appendReloc(relocs, sectionOffset, 0, addressForAtom(atom) +
|
||||
ref.offsetInAtom(),
|
||||
GENERIC_RELOC_PAIR | rScattered | rLength4);
|
||||
break;
|
||||
case negDelta32:
|
||||
appendReloc(relocs, sectionOffset, 0, addressForAtom(atom) +
|
||||
ref.offsetInAtom(),
|
||||
GENERIC_RELOC_SECTDIFF | rScattered | rLength4);
|
||||
appendReloc(relocs, sectionOffset, 0, addressForAtom(*ref.target()),
|
||||
GENERIC_RELOC_PAIR | rScattered | rLength4);
|
||||
break;
|
||||
case lazyPointer:
|
||||
case lazyImmediateLocation:
|
||||
|
|
|
@ -62,6 +62,7 @@ const MachORelocatableSectionToAtomType sectsToAtomType[] = {
|
|||
ENTRY("__TEXT", "__const", S_REGULAR, typeConstant),
|
||||
ENTRY("__TEXT", "__const_coal", S_COALESCED, typeConstant),
|
||||
ENTRY("__TEXT", "__eh_frame", S_COALESCED, typeCFI),
|
||||
ENTRY("__TEXT", "__eh_frame", S_REGULAR, typeCFI),
|
||||
ENTRY("__TEXT", "__literal4", S_4BYTE_LITERALS, typeLiteral4),
|
||||
ENTRY("__TEXT", "__literal8", S_8BYTE_LITERALS, typeLiteral8),
|
||||
ENTRY("__TEXT", "__literal16", S_16BYTE_LITERALS, typeLiteral16),
|
||||
|
@ -149,7 +150,7 @@ void sectionParseInfo(DefinedAtom::ContentType atomType,
|
|||
atomizeUTF8),
|
||||
ENTRY(typeUTF16String, 1, scopeLinkageUnit, mergeByContent,
|
||||
atomizeUTF16),
|
||||
ENTRY(typeCFI, 1, scopeTranslationUnit, mergeNo,
|
||||
ENTRY(typeCFI, 4, scopeTranslationUnit, mergeNo,
|
||||
atomizeCFI),
|
||||
ENTRY(typeLiteral4, 4, scopeLinkageUnit, mergeByContent,
|
||||
atomizeFixedSize),
|
||||
|
@ -165,8 +166,6 @@ void sectionParseInfo(DefinedAtom::ContentType atomType,
|
|||
atomizePointerSize),
|
||||
ENTRY(typeCompactUnwindInfo, 4, scopeTranslationUnit, mergeNo,
|
||||
atomizeCU),
|
||||
ENTRY(typeCFI, 4, scopeTranslationUnit, mergeNo,
|
||||
atomizeFixedSize),
|
||||
ENTRY(typeGOT, 4, scopeLinkageUnit, mergeByContent,
|
||||
atomizePointerSize),
|
||||
ENTRY(typeUnknown, 1, scopeGlobal, mergeNo,
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
# RUN: lld -flavor darwin -arch i386 -r -print_atoms %s -o %t | FileCheck %s
|
||||
#
|
||||
# Test parsing of new __eh_frame (dwarf unwind) section that has no .eh labels
|
||||
# and no relocations.
|
||||
#
|
||||
|
||||
--- !mach-o
|
||||
arch: x86
|
||||
file-type: MH_OBJECT
|
||||
flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
|
||||
OS: unknown
|
||||
sections:
|
||||
- segment: __TEXT
|
||||
section: __text
|
||||
type: S_REGULAR
|
||||
attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
|
||||
address: 0x0000000000000000
|
||||
content: [ 0x55, 0x89, 0xE5, 0x56, 0x83, 0xEC, 0x14, 0xE8,
|
||||
0x00, 0x00, 0x00, 0x00, 0x5E, 0xC7, 0x04, 0x24,
|
||||
0x04, 0x00, 0x00, 0x00, 0xE8, 0xE7, 0xFF, 0xFF,
|
||||
0xFF, 0xC7, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x8B,
|
||||
0x8E, 0x38, 0x00, 0x00, 0x00, 0x89, 0x4C, 0x24,
|
||||
0x04, 0x89, 0x04, 0x24, 0xC7, 0x44, 0x24, 0x08,
|
||||
0x00, 0x00, 0x00, 0x00, 0xE8, 0xC7, 0xFF, 0xFF,
|
||||
0xFF, 0x55, 0x89, 0xE5, 0x83, 0xEC, 0x08, 0xE8,
|
||||
0xBC, 0xFF, 0xFF, 0xFF ]
|
||||
relocations:
|
||||
- offset: 0x00000040
|
||||
type: GENERIC_RELOC_VANILLA
|
||||
length: 2
|
||||
pc-rel: true
|
||||
extern: false
|
||||
symbol: 1
|
||||
- offset: 0x00000035
|
||||
type: GENERIC_RELOC_VANILLA
|
||||
length: 2
|
||||
pc-rel: true
|
||||
extern: true
|
||||
symbol: 4
|
||||
- offset: 0x00000021
|
||||
scattered: true
|
||||
type: GENERIC_RELOC_LOCAL_SECTDIFF
|
||||
length: 2
|
||||
pc-rel: false
|
||||
value: 0x00000044
|
||||
- offset: 0x00000000
|
||||
scattered: true
|
||||
type: GENERIC_RELOC_PAIR
|
||||
length: 2
|
||||
pc-rel: false
|
||||
value: 0x0000000C
|
||||
- offset: 0x00000015
|
||||
type: GENERIC_RELOC_VANILLA
|
||||
length: 2
|
||||
pc-rel: true
|
||||
extern: true
|
||||
symbol: 3
|
||||
- segment: __IMPORT
|
||||
section: __pointers
|
||||
type: S_NON_LAZY_SYMBOL_POINTERS
|
||||
attributes: [ ]
|
||||
address: 0x0000000000000044
|
||||
content: [ 0x00, 0x00, 0x00, 0x00 ]
|
||||
indirect-syms: [ 5 ]
|
||||
- segment: __TEXT
|
||||
section: __eh_frame
|
||||
type: S_REGULAR
|
||||
attributes: [ ]
|
||||
alignment: 2
|
||||
address: 0x0000000000000048
|
||||
content: [ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x7A, 0x52, 0x00, 0x01, 0x7C, 0x08, 0x01,
|
||||
0x10, 0x0C, 0x05, 0x04, 0x88, 0x01, 0x00, 0x00,
|
||||
0x18, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,
|
||||
0x98, 0xFF, 0xFF, 0xFF, 0x39, 0x00, 0x00, 0x00,
|
||||
0x00, 0x41, 0x0E, 0x08, 0x84, 0x02, 0x42, 0x0D,
|
||||
0x04, 0x44, 0x86, 0x03, 0x18, 0x00, 0x00, 0x00,
|
||||
0x38, 0x00, 0x00, 0x00, 0xB5, 0xFF, 0xFF, 0xFF,
|
||||
0x0B, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0E, 0x08,
|
||||
0x84, 0x02, 0x42, 0x0D, 0x04, 0x00, 0x00, 0x00 ]
|
||||
global-symbols:
|
||||
- name: __Z3barv
|
||||
type: N_SECT
|
||||
scope: [ N_EXT ]
|
||||
sect: 1
|
||||
value: 0x0000000000000039
|
||||
- name: __Z3foov
|
||||
type: N_SECT
|
||||
scope: [ N_EXT ]
|
||||
sect: 1
|
||||
value: 0x0000000000000000
|
||||
undefined-symbols:
|
||||
- name: __ZTIi
|
||||
type: N_UNDF
|
||||
scope: [ N_EXT ]
|
||||
value: 0x0000000000000000
|
||||
- name: ___cxa_allocate_exception
|
||||
type: N_UNDF
|
||||
scope: [ N_EXT ]
|
||||
value: 0x0000000000000000
|
||||
- name: ___cxa_throw
|
||||
type: N_UNDF
|
||||
scope: [ N_EXT ]
|
||||
value: 0x0000000000000000
|
||||
...
|
||||
|
||||
# CHECK: defined-atoms:
|
||||
# FIXME: - ref-name: [[CIE:L[L0-9]+]]
|
||||
# CHECK: type: unwind-cfi
|
||||
# CHECK: content:
|
||||
# CHECK: - type: unwind-cfi
|
||||
# CHECK: content:
|
||||
# FIXME: references:
|
||||
# FIXME: - kind: negDelta32
|
||||
# FIXME: offset: 4
|
||||
# FIXME: target: [[CIE]]
|
||||
# FIXME: - kind: delta32
|
||||
# FIXME: offset: 8
|
||||
# FIXME: target: __Z3foov
|
||||
# CHECK: - type: unwind-cfi
|
||||
# CHECK: content:
|
||||
# FIXME: references:
|
||||
# FIXME: - kind: negDelta32
|
||||
# FIXME: offset: 4
|
||||
# FIXME: target: [[CIE]]
|
||||
# FIXME: - kind: delta32
|
||||
# FIXME: offset: 8
|
||||
# FIXME: target: __Z3barv
|
||||
|
|
@ -0,0 +1,193 @@
|
|||
# RUN: lld -flavor darwin -arch i386 -r -print_atoms %s -o %t | FileCheck %s
|
||||
#
|
||||
# Test parsing of old __eh_frame (dwarf unwind) section that has .eh labels
|
||||
# and relocations.
|
||||
#
|
||||
|
||||
--- !mach-o
|
||||
arch: x86
|
||||
file-type: MH_OBJECT
|
||||
flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
|
||||
OS: unknown
|
||||
sections:
|
||||
- segment: __TEXT
|
||||
section: __text
|
||||
type: S_REGULAR
|
||||
attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
|
||||
address: 0x0000000000000000
|
||||
content: [ 0x55, 0x89, 0xE5, 0x56, 0x83, 0xEC, 0x14, 0xE8,
|
||||
0x00, 0x00, 0x00, 0x00, 0x5E, 0xC7, 0x04, 0x24,
|
||||
0x04, 0x00, 0x00, 0x00, 0xE8, 0xE7, 0xFF, 0xFF,
|
||||
0xFF, 0xC7, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x8B,
|
||||
0x8E, 0x38, 0x00, 0x00, 0x00, 0x89, 0x4C, 0x24,
|
||||
0x04, 0x89, 0x04, 0x24, 0xC7, 0x44, 0x24, 0x08,
|
||||
0x00, 0x00, 0x00, 0x00, 0xE8, 0xC7, 0xFF, 0xFF,
|
||||
0xFF, 0x55, 0x89, 0xE5, 0x83, 0xEC, 0x08, 0xE8,
|
||||
0xBC, 0xFF, 0xFF, 0xFF ]
|
||||
relocations:
|
||||
- offset: 0x00000040
|
||||
type: GENERIC_RELOC_VANILLA
|
||||
length: 2
|
||||
pc-rel: true
|
||||
extern: false
|
||||
symbol: 1
|
||||
- offset: 0x00000035
|
||||
type: GENERIC_RELOC_VANILLA
|
||||
length: 2
|
||||
pc-rel: true
|
||||
extern: true
|
||||
symbol: 7
|
||||
- offset: 0x00000021
|
||||
scattered: true
|
||||
type: GENERIC_RELOC_LOCAL_SECTDIFF
|
||||
length: 2
|
||||
pc-rel: false
|
||||
value: 0x00000044
|
||||
- offset: 0x00000000
|
||||
scattered: true
|
||||
type: GENERIC_RELOC_PAIR
|
||||
length: 2
|
||||
pc-rel: false
|
||||
value: 0x0000000C
|
||||
- offset: 0x00000015
|
||||
type: GENERIC_RELOC_VANILLA
|
||||
length: 2
|
||||
pc-rel: true
|
||||
extern: true
|
||||
symbol: 6
|
||||
- segment: __IMPORT
|
||||
section: __pointers
|
||||
type: S_NON_LAZY_SYMBOL_POINTERS
|
||||
attributes: [ ]
|
||||
address: 0x0000000000000044
|
||||
content: [ 0x00, 0x00, 0x00, 0x00 ]
|
||||
indirect-syms: [ 5 ]
|
||||
- segment: __TEXT
|
||||
section: __eh_frame
|
||||
type: S_REGULAR
|
||||
attributes: [ ]
|
||||
alignment: 2
|
||||
address: 0x0000000000000048
|
||||
content: [ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x7A, 0x52, 0x00, 0x01, 0x7C, 0x08, 0x01,
|
||||
0x10, 0x0C, 0x05, 0x04, 0x88, 0x01, 0x00, 0x00,
|
||||
0x18, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,
|
||||
0x98, 0xFF, 0xFF, 0xFF, 0x39, 0x00, 0x00, 0x00,
|
||||
0x00, 0x41, 0x0E, 0x08, 0x84, 0x02, 0x42, 0x0D,
|
||||
0x04, 0x44, 0x86, 0x03, 0x18, 0x00, 0x00, 0x00,
|
||||
0x38, 0x00, 0x00, 0x00, 0xB5, 0xFF, 0xFF, 0xFF,
|
||||
0x0B, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0E, 0x08,
|
||||
0x84, 0x02, 0x42, 0x0D, 0x04, 0x00, 0x00, 0x00 ]
|
||||
relocations:
|
||||
- offset: 0x0000001C
|
||||
scattered: true
|
||||
type: GENERIC_RELOC_LOCAL_SECTDIFF
|
||||
length: 2
|
||||
pc-rel: false
|
||||
value: 0x00000064
|
||||
- offset: 0x00000000
|
||||
scattered: true
|
||||
type: GENERIC_RELOC_PAIR
|
||||
length: 2
|
||||
pc-rel: false
|
||||
value: 0x00000048
|
||||
- offset: 0x00000020
|
||||
scattered: true
|
||||
type: GENERIC_RELOC_SECTDIFF
|
||||
length: 2
|
||||
pc-rel: false
|
||||
value: 0x00000000
|
||||
- offset: 0x00000000
|
||||
scattered: true
|
||||
type: GENERIC_RELOC_PAIR
|
||||
length: 2
|
||||
pc-rel: false
|
||||
value: 0x00000068
|
||||
- offset: 0x00000038
|
||||
scattered: true
|
||||
type: GENERIC_RELOC_LOCAL_SECTDIFF
|
||||
length: 2
|
||||
pc-rel: false
|
||||
value: 0x00000080
|
||||
- offset: 0x00000000
|
||||
scattered: true
|
||||
type: GENERIC_RELOC_PAIR
|
||||
length: 2
|
||||
pc-rel: false
|
||||
value: 0x00000048
|
||||
- offset: 0x0000003C
|
||||
scattered: true
|
||||
type: GENERIC_RELOC_SECTDIFF
|
||||
length: 2
|
||||
pc-rel: false
|
||||
value: 0x00000039
|
||||
- offset: 0x00000000
|
||||
scattered: true
|
||||
type: GENERIC_RELOC_PAIR
|
||||
length: 2
|
||||
pc-rel: false
|
||||
value: 0x00000084
|
||||
local-symbols:
|
||||
- name: EH_frame0
|
||||
type: N_SECT
|
||||
sect: 3
|
||||
value: 0x0000000000000048
|
||||
global-symbols:
|
||||
- name: __Z3barv
|
||||
type: N_SECT
|
||||
scope: [ N_EXT ]
|
||||
sect: 1
|
||||
value: 0x0000000000000039
|
||||
- name: __Z3barv.eh
|
||||
type: N_SECT
|
||||
scope: [ N_EXT ]
|
||||
sect: 3
|
||||
value: 0x000000000000007C
|
||||
- name: __Z3foov
|
||||
type: N_SECT
|
||||
scope: [ N_EXT ]
|
||||
sect: 1
|
||||
value: 0x0000000000000000
|
||||
- name: __Z3foov.eh
|
||||
type: N_SECT
|
||||
scope: [ N_EXT ]
|
||||
sect: 3
|
||||
value: 0x0000000000000060
|
||||
undefined-symbols:
|
||||
- name: __ZTIi
|
||||
type: N_UNDF
|
||||
scope: [ N_EXT ]
|
||||
value: 0x0000000000000000
|
||||
- name: ___cxa_allocate_exception
|
||||
type: N_UNDF
|
||||
scope: [ N_EXT ]
|
||||
value: 0x0000000000000000
|
||||
- name: ___cxa_throw
|
||||
type: N_UNDF
|
||||
scope: [ N_EXT ]
|
||||
value: 0x0000000000000000
|
||||
...
|
||||
|
||||
# CHECK: defined-atoms:
|
||||
# CHECK: - ref-name: [[CIE:L[L0-9]+]]
|
||||
# CHECK: type: unwind-cfi
|
||||
# CHECK: content:
|
||||
# CHECK: - type: unwind-cfi
|
||||
# CHECK: content:
|
||||
# CHECK: references:
|
||||
# CHECK: - kind: negDelta32
|
||||
# CHECK: offset: 4
|
||||
# CHECK: target: [[CIE]]
|
||||
# CHECK: - kind: delta32
|
||||
# CHECK: offset: 8
|
||||
# CHECK: target: __Z3foov
|
||||
# CHECK: - type: unwind-cfi
|
||||
# CHECK: content:
|
||||
# CHECK: references:
|
||||
# CHECK: - kind: negDelta32
|
||||
# CHECK: offset: 4
|
||||
# CHECK: target: [[CIE]]
|
||||
# CHECK: - kind: delta32
|
||||
# CHECK: offset: 8
|
||||
# CHECK: target: __Z3barv
|
||||
|
Loading…
Reference in New Issue