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:
Pete Cooper 2016-01-07 21:07:26 +00:00
parent 841085c561
commit ac03979000
4 changed files with 209 additions and 8 deletions

View File

@ -168,7 +168,8 @@ void relocatableSectionInfoForContentType(DefinedAtom::ContentType atomType,
StringRef &segmentName,
StringRef &sectionName,
SectionType &sectionType,
SectionAttr &sectionAttrs);
SectionAttr &sectionAttrs,
bool &relocsToDefinedCanBeImplicit);
} // namespace normalized
} // namespace mach_o

View File

@ -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,

View File

@ -1034,7 +1034,8 @@ void relocatableSectionInfoForContentType(DefinedAtom::ContentType atomType,
StringRef &segmentName,
StringRef &sectionName,
SectionType &sectionType,
SectionAttr &sectionAttrs) {
SectionAttr &sectionAttrs,
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");

View File

@ -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