forked from OSchip/llvm-project
Don't emit relocs for the __eh_frame section as they can be implicit.
The __eh_frame section contains relocations which can always be implicitly generated. This patch tracks whether sections have only implicitly relocations and skips emitting them to the object file if that is the case. The test case here ensures that this is the case for __eh_frame sections. Reviewed by Lang Hames. http://reviews.llvm.org/D15594 llvm-svn: 257099
This commit is contained in:
parent
841085c561
commit
ac03979000
|
@ -168,7 +168,8 @@ void relocatableSectionInfoForContentType(DefinedAtom::ContentType atomType,
|
|||
StringRef &segmentName,
|
||||
StringRef §ionName,
|
||||
SectionType §ionType,
|
||||
SectionAttr §ionAttrs);
|
||||
SectionAttr §ionAttrs,
|
||||
bool &relocsToDefinedCanBeImplicit);
|
||||
|
||||
} // namespace normalized
|
||||
} // namespace mach_o
|
||||
|
|
|
@ -50,7 +50,8 @@ struct AtomInfo {
|
|||
|
||||
struct SectionInfo {
|
||||
SectionInfo(StringRef seg, StringRef sect, SectionType type,
|
||||
const MachOLinkingContext &ctxt, uint32_t attr=0);
|
||||
const MachOLinkingContext &ctxt, uint32_t attr,
|
||||
bool relocsToDefinedCanBeImplicit);
|
||||
|
||||
StringRef segmentName;
|
||||
StringRef sectionName;
|
||||
|
@ -59,15 +60,25 @@ struct SectionInfo {
|
|||
uint64_t address;
|
||||
uint64_t size;
|
||||
uint16_t alignment;
|
||||
|
||||
/// If this is set, the any relocs in this section which point to defined
|
||||
/// addresses can be implicitly generated. This is the case for the
|
||||
/// __eh_frame section where references to the function can be implicit if the
|
||||
/// function is defined.
|
||||
bool relocsToDefinedCanBeImplicit;
|
||||
|
||||
|
||||
std::vector<AtomInfo> atomsAndOffsets;
|
||||
uint32_t normalizedSectionIndex;
|
||||
uint32_t finalSectionIndex;
|
||||
};
|
||||
|
||||
SectionInfo::SectionInfo(StringRef sg, StringRef sct, SectionType t,
|
||||
const MachOLinkingContext &ctxt, uint32_t attrs)
|
||||
const MachOLinkingContext &ctxt, uint32_t attrs,
|
||||
bool relocsToDefinedCanBeImplicit)
|
||||
: segmentName(sg), sectionName(sct), type(t), attributes(attrs),
|
||||
address(0), size(0), alignment(1),
|
||||
relocsToDefinedCanBeImplicit(relocsToDefinedCanBeImplicit),
|
||||
normalizedSectionIndex(0), finalSectionIndex(0) {
|
||||
uint16_t align = 1;
|
||||
if (ctxt.sectionAligned(segmentName, sectionName, align)) {
|
||||
|
@ -193,10 +204,12 @@ SectionInfo *Util::getRelocatableSection(DefinedAtom::ContentType type) {
|
|||
StringRef sectionName;
|
||||
SectionType sectionType;
|
||||
SectionAttr sectionAttrs;
|
||||
bool relocsToDefinedCanBeImplicit;
|
||||
|
||||
// Use same table used by when parsing .o files.
|
||||
relocatableSectionInfoForContentType(type, segmentName, sectionName,
|
||||
sectionType, sectionAttrs);
|
||||
sectionType, sectionAttrs,
|
||||
relocsToDefinedCanBeImplicit);
|
||||
// If we already have a SectionInfo with this name, re-use it.
|
||||
// This can happen if two ContentType map to the same mach-o section.
|
||||
for (auto sect : _sectionMap) {
|
||||
|
@ -207,7 +220,8 @@ SectionInfo *Util::getRelocatableSection(DefinedAtom::ContentType type) {
|
|||
}
|
||||
// Otherwise allocate new SectionInfo object.
|
||||
auto *sect = new (_allocator)
|
||||
SectionInfo(segmentName, sectionName, sectionType, _ctx, sectionAttrs);
|
||||
SectionInfo(segmentName, sectionName, sectionType, _ctx, sectionAttrs,
|
||||
relocsToDefinedCanBeImplicit);
|
||||
_sectionInfos.push_back(sect);
|
||||
_sectionMap[type] = sect;
|
||||
return sect;
|
||||
|
@ -287,7 +301,8 @@ SectionInfo *Util::getFinalSection(DefinedAtom::ContentType atomType) {
|
|||
}
|
||||
// Otherwise allocate new SectionInfo object.
|
||||
auto *sect = new (_allocator) SectionInfo(
|
||||
p.segmentName, p.sectionName, p.sectionType, _ctx, sectionAttrs);
|
||||
p.segmentName, p.sectionName, p.sectionType, _ctx, sectionAttrs,
|
||||
/* relocsToDefinedCanBeImplicit */ false);
|
||||
_sectionInfos.push_back(sect);
|
||||
_sectionMap[atomType] = sect;
|
||||
return sect;
|
||||
|
@ -320,7 +335,8 @@ SectionInfo *Util::sectionForAtom(const DefinedAtom *atom) {
|
|||
StringRef segName = customName.slice(0, seperatorIndex);
|
||||
StringRef sectName = customName.drop_front(seperatorIndex + 1);
|
||||
auto *sect =
|
||||
new (_allocator) SectionInfo(segName, sectName, S_REGULAR, _ctx);
|
||||
new (_allocator) SectionInfo(segName, sectName, S_REGULAR, _ctx,
|
||||
0, /* relocsToDefinedCanBeImplicit */ false);
|
||||
_customSections.push_back(sect);
|
||||
_sectionInfos.push_back(sect);
|
||||
return sect;
|
||||
|
@ -1024,6 +1040,11 @@ void Util::addSectionRelocs(const lld::File &, NormalizedFile &file) {
|
|||
for (const AtomInfo &info : si->atomsAndOffsets) {
|
||||
const DefinedAtom *atom = info.atom;
|
||||
for (const Reference *ref : *atom) {
|
||||
// Skip emitting relocs for sections which are always able to be
|
||||
// implicitly regenerated and where the relocation targets an address
|
||||
// which is defined.
|
||||
if (si->relocsToDefinedCanBeImplicit && isa<DefinedAtom>(ref->target()))
|
||||
continue;
|
||||
_archHandler.appendSectionRelocations(*atom, info.offsetInSection, *ref,
|
||||
symIndexForAtom,
|
||||
sectIndexForAtom,
|
||||
|
|
|
@ -1034,7 +1034,8 @@ void relocatableSectionInfoForContentType(DefinedAtom::ContentType atomType,
|
|||
StringRef &segmentName,
|
||||
StringRef §ionName,
|
||||
SectionType §ionType,
|
||||
SectionAttr §ionAttrs) {
|
||||
SectionAttr §ionAttrs,
|
||||
bool &relocsToDefinedCanBeImplicit) {
|
||||
|
||||
for (const MachORelocatableSectionToAtomType *p = sectsToAtomType ;
|
||||
p->atomType != DefinedAtom::typeUnknown; ++p) {
|
||||
|
@ -1047,8 +1048,11 @@ void relocatableSectionInfoForContentType(DefinedAtom::ContentType atomType,
|
|||
sectionName = p->sectionName;
|
||||
sectionType = p->sectionType;
|
||||
sectionAttrs = 0;
|
||||
relocsToDefinedCanBeImplicit = false;
|
||||
if (atomType == DefinedAtom::typeCode)
|
||||
sectionAttrs = S_ATTR_PURE_INSTRUCTIONS;
|
||||
if (atomType == DefinedAtom::typeCFI)
|
||||
relocsToDefinedCanBeImplicit = true;
|
||||
return;
|
||||
}
|
||||
llvm_unreachable("content type not yet supported");
|
||||
|
|
|
@ -0,0 +1,175 @@
|
|||
# RUN: lld -flavor darwin -arch arm64 -r -print_atoms %s -o %t | FileCheck %s
|
||||
# RUN: lld -flavor darwin -arch arm64 -r -print_atoms %t -o %t2 | FileCheck %s
|
||||
# RUN: llvm-objdump -r -macho %t | FileCheck -check-prefix=CODE %s
|
||||
# RUN: llvm-objdump -r -macho %t2 | FileCheck -check-prefix=CODE %s
|
||||
|
||||
|
||||
--- !mach-o
|
||||
arch: arm64
|
||||
file-type: MH_OBJECT
|
||||
flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
|
||||
compat-version: 0.0
|
||||
current-version: 0.0
|
||||
has-UUID: false
|
||||
OS: unknown
|
||||
sections:
|
||||
- segment: __TEXT
|
||||
section: __text
|
||||
type: S_REGULAR
|
||||
attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
|
||||
alignment: 4
|
||||
address: 0x0000000000000000
|
||||
content: [ 0xFD, 0x7B, 0xBF, 0xA9, 0xFD, 0x03, 0x00, 0x91,
|
||||
0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x91,
|
||||
0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x80, 0x52,
|
||||
0xFD, 0x7B, 0xC1, 0xA8, 0xC0, 0x03, 0x5F, 0xD6 ]
|
||||
relocations:
|
||||
- offset: 0x00000010
|
||||
type: ARM64_RELOC_BRANCH26
|
||||
length: 2
|
||||
pc-rel: true
|
||||
extern: true
|
||||
symbol: 9
|
||||
- offset: 0x0000000C
|
||||
type: ARM64_RELOC_PAGEOFF12
|
||||
length: 2
|
||||
pc-rel: false
|
||||
extern: true
|
||||
symbol: 1
|
||||
- offset: 0x00000008
|
||||
type: ARM64_RELOC_PAGE21
|
||||
length: 2
|
||||
pc-rel: true
|
||||
extern: true
|
||||
symbol: 1
|
||||
- segment: __TEXT
|
||||
section: __cstring
|
||||
type: S_CSTRING_LITERALS
|
||||
attributes: [ ]
|
||||
address: 0x0000000000000020
|
||||
content: [ 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F,
|
||||
0x72, 0x6C, 0x64, 0x00 ]
|
||||
- segment: __LD
|
||||
section: __compact_unwind
|
||||
type: S_REGULAR
|
||||
attributes: [ ]
|
||||
alignment: 8
|
||||
address: 0x0000000000000030
|
||||
content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
|
||||
relocations:
|
||||
- offset: 0x00000000
|
||||
type: ARM64_RELOC_UNSIGNED
|
||||
length: 3
|
||||
pc-rel: false
|
||||
extern: false
|
||||
symbol: 1
|
||||
- segment: __TEXT
|
||||
section: __eh_frame
|
||||
type: S_COALESCED
|
||||
attributes: [ ]
|
||||
alignment: 8
|
||||
address: 0x0000000000000050
|
||||
content: [ 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x7A, 0x50, 0x4C, 0x52, 0x00, 0x01, 0x78,
|
||||
0x1E, 0x0B, 0x00, 0xED, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0x00, 0x10, 0x0C, 0x1F, 0x00,
|
||||
0x24, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x48, 0x0E, 0x10, 0x9E, 0x01, 0x9D, 0x02 ]
|
||||
local-symbols:
|
||||
- name: ltmp0
|
||||
type: N_SECT
|
||||
sect: 1
|
||||
value: 0x0000000000000000
|
||||
- name: L_str
|
||||
type: N_SECT
|
||||
sect: 2
|
||||
value: 0x0000000000000020
|
||||
- name: ltmp1
|
||||
type: N_SECT
|
||||
sect: 2
|
||||
value: 0x0000000000000020
|
||||
- name: ltmp2
|
||||
type: N_SECT
|
||||
sect: 3
|
||||
value: 0x0000000000000030
|
||||
- name: ltmp3
|
||||
type: N_SECT
|
||||
sect: 4
|
||||
value: 0x0000000000000050
|
||||
- name: ltmp4
|
||||
type: N_SECT
|
||||
sect: 4
|
||||
value: 0x0000000000000070
|
||||
global-symbols:
|
||||
- name: __Z3fooi
|
||||
type: N_SECT
|
||||
scope: [ N_EXT ]
|
||||
sect: 1
|
||||
value: 0x0000000000000000
|
||||
undefined-symbols:
|
||||
- name: __gxx_personality_v0
|
||||
type: N_UNDF
|
||||
scope: [ N_EXT ]
|
||||
value: 0x0000000000000000
|
||||
- name: _bar
|
||||
type: N_UNDF
|
||||
scope: [ N_EXT ]
|
||||
value: 0x0000000000000000
|
||||
- name: _puts
|
||||
type: N_UNDF
|
||||
scope: [ N_EXT ]
|
||||
value: 0x0000000000000000
|
||||
page-size: 0x00000000
|
||||
|
||||
# CHECK: defined-atoms:
|
||||
# CHECK: - ref-name: L{{[0-9]*}}
|
||||
# CHECK: scope: hidden
|
||||
# CHECK: type: c-string
|
||||
# CHECK: content: [ 48, 65, 6C, 6C, 6F, 20, 77, 6F, 72, 6C, 64, 00 ]
|
||||
# CHECK: merge: by-content
|
||||
# CHECK: type: unwind-cfi
|
||||
# CHECK: content: [ 1C, 00, 00, 00, 00, 00, 00, 00, 01, 7A, 50, 4C,
|
||||
# CHECK: 52, 00, 01, 78, 1E, 0B, 00, ED, FF, FF, FF, FF,
|
||||
# CHECK: FF, FF, FF, 00, 10, 0C, 1F, 00 ]
|
||||
# CHECK: alignment: 8
|
||||
# CHECK: - ref-name: L{{[0-9]*}}
|
||||
# CHECK: type: unwind-cfi
|
||||
# CHECK: content: [ 24, 00, 00, 00, 24, 00, 00, 00, 00, 00, 00, 00,
|
||||
# CHECK: 00, 00, 00, 00, 20, 00, 00, 00, 00, 00, 00, 00,
|
||||
# CHECK: 08, 00, 00, 00, 00, 00, 00, 00, 00, 48, 0E, 10,
|
||||
# CHECK: 9E, 01, 9D, 02 ]
|
||||
# CHECK: alignment: 8
|
||||
# CHECK: - type: compact-unwind
|
||||
# CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00, 20, 00, 00, 00,
|
||||
# CHECK: 00, 00, 00, 03, 00, 00, 00, 00, 00, 00, 00, 00,
|
||||
# CHECK: 00, 00, 00, 00, 00, 00, 00, 00 ]
|
||||
# CHECK: alignment: 8
|
||||
# CHECK: references:
|
||||
# CHECK: - kind: pointer64
|
||||
# CHECK: offset: 0
|
||||
# CHECK: target: __Z3fooi
|
||||
# CHECK: - name: __Z3fooi
|
||||
# CHECK: scope: global
|
||||
# CHECK: content: [ FD, 7B, BF, A9, FD, 03, 00, 91, 00, 00, 00, 90,
|
||||
# CHECK: 00, 00, 00, 91, 00, 00, 00, 94, 00, 00, 80, 52,
|
||||
# CHECK: FD, 7B, C1, A8, C0, 03, 5F, D6 ]
|
||||
# CHECK: alignment: 4
|
||||
# CHECK: references:
|
||||
# CHECK: - kind: page21
|
||||
# CHECK: offset: 8
|
||||
# CHECK: target: L{{[0-9]*}}
|
||||
# CHECK: - kind: offset12
|
||||
# CHECK: offset: 12
|
||||
# CHECK: target: L{{[0-9]*}}
|
||||
# CHECK: - kind: branch26
|
||||
# CHECK: offset: 16
|
||||
# CHECK: target: _puts
|
||||
|
||||
# Make sure we don't have any relocations in the __eh_frame section
|
||||
# CODE-NOT: __eh_frame
|
Loading…
Reference in New Issue