forked from OSchip/llvm-project
Sort sections in relocatable files.
The final section order in relocatable files was just a side effect of the atom sorter. This meant that sections like __data were before __text because __data has RW permissions and __text RX and RW was less than RX in our enum. Final linked images had an actual section/segment sorter. There was no reason for the difference, so simplify a bunch of code and just use the same sorted for everything. Reviewed by Lang Hames. http://reviews.llvm.org/D15868 llvm-svn: 256786
This commit is contained in:
parent
204efe2de8
commit
bd364ce694
|
@ -406,14 +406,8 @@ bool Util::TextSectionSorter::operator()(const SectionInfo *left,
|
|||
}
|
||||
|
||||
void Util::organizeSections() {
|
||||
if (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT) {
|
||||
// Leave sections ordered as normalized file specified.
|
||||
uint32_t sectionIndex = 1;
|
||||
for (SectionInfo *si : _sectionInfos) {
|
||||
si->finalSectionIndex = sectionIndex++;
|
||||
}
|
||||
} else {
|
||||
switch (_ctx.outputMachOType()) {
|
||||
// NOTE!: Keep this in sync with assignAddressesToSections.
|
||||
switch (_ctx.outputMachOType()) {
|
||||
case llvm::MachO::MH_EXECUTE:
|
||||
// Main executables, need a zero-page segment
|
||||
segmentForName("__PAGEZERO");
|
||||
|
@ -425,32 +419,30 @@ void Util::organizeSections() {
|
|||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Group sections into segments.
|
||||
for (SectionInfo *si : _sectionInfos) {
|
||||
SegmentInfo *seg = segmentForName(si->segmentName);
|
||||
seg->sections.push_back(si);
|
||||
}
|
||||
// Sort segments.
|
||||
std::sort(_segmentInfos.begin(), _segmentInfos.end(), SegmentSorter());
|
||||
}
|
||||
// Group sections into segments.
|
||||
for (SectionInfo *si : _sectionInfos) {
|
||||
SegmentInfo *seg = segmentForName(si->segmentName);
|
||||
seg->sections.push_back(si);
|
||||
}
|
||||
// Sort segments.
|
||||
std::sort(_segmentInfos.begin(), _segmentInfos.end(), SegmentSorter());
|
||||
|
||||
// Sort sections within segments.
|
||||
for (SegmentInfo *seg : _segmentInfos) {
|
||||
if (seg->name.equals("__TEXT")) {
|
||||
std::sort(seg->sections.begin(), seg->sections.end(),
|
||||
TextSectionSorter());
|
||||
}
|
||||
// Sort sections within segments.
|
||||
for (SegmentInfo *seg : _segmentInfos) {
|
||||
if (seg->name.equals("__TEXT")) {
|
||||
std::sort(seg->sections.begin(), seg->sections.end(),
|
||||
TextSectionSorter());
|
||||
}
|
||||
}
|
||||
|
||||
// Record final section indexes.
|
||||
uint32_t segmentIndex = 0;
|
||||
uint32_t sectionIndex = 1;
|
||||
for (SegmentInfo *seg : _segmentInfos) {
|
||||
seg->normalizedSegmentIndex = segmentIndex++;
|
||||
for (SectionInfo *sect : seg->sections) {
|
||||
sect->finalSectionIndex = sectionIndex++;
|
||||
}
|
||||
}
|
||||
// Record final section indexes.
|
||||
uint32_t segmentIndex = 0;
|
||||
uint32_t sectionIndex = 1;
|
||||
for (SegmentInfo *seg : _segmentInfos) {
|
||||
seg->normalizedSegmentIndex = segmentIndex++;
|
||||
for (SectionInfo *sect : seg->sections)
|
||||
sect->finalSectionIndex = sectionIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -487,54 +479,39 @@ void Util::layoutSectionsInTextSegment(size_t hlcSize, SegmentInfo *seg,
|
|||
}
|
||||
|
||||
void Util::assignAddressesToSections(const NormalizedFile &file) {
|
||||
// NOTE!: Keep this in sync with organizeSections.
|
||||
size_t hlcSize = headerAndLoadCommandsSize(file);
|
||||
uint64_t address = 0;
|
||||
if (_ctx.outputMachOType() != llvm::MachO::MH_OBJECT) {
|
||||
for (SegmentInfo *seg : _segmentInfos) {
|
||||
if (seg->name.equals("__PAGEZERO")) {
|
||||
seg->size = _ctx.pageZeroSize();
|
||||
address += seg->size;
|
||||
}
|
||||
else if (seg->name.equals("__TEXT")) {
|
||||
// _ctx.baseAddress() == 0 implies it was either unspecified or
|
||||
// pageZeroSize is also 0. In either case resetting address is safe.
|
||||
address = _ctx.baseAddress() ? _ctx.baseAddress() : address;
|
||||
layoutSectionsInTextSegment(hlcSize, seg, address);
|
||||
} else
|
||||
layoutSectionsInSegment(seg, address);
|
||||
for (SegmentInfo *seg : _segmentInfos) {
|
||||
if (seg->name.equals("__PAGEZERO")) {
|
||||
seg->size = _ctx.pageZeroSize();
|
||||
address += seg->size;
|
||||
}
|
||||
else if (seg->name.equals("__TEXT")) {
|
||||
// _ctx.baseAddress() == 0 implies it was either unspecified or
|
||||
// pageZeroSize is also 0. In either case resetting address is safe.
|
||||
address = _ctx.baseAddress() ? _ctx.baseAddress() : address;
|
||||
layoutSectionsInTextSegment(hlcSize, seg, address);
|
||||
} else
|
||||
layoutSectionsInSegment(seg, address);
|
||||
|
||||
address = llvm::RoundUpToAlignment(address, _ctx.pageSize());
|
||||
}
|
||||
DEBUG_WITH_TYPE("WriterMachO-norm",
|
||||
llvm::dbgs() << "assignAddressesToSections()\n";
|
||||
for (SegmentInfo *sgi : _segmentInfos) {
|
||||
llvm::dbgs() << " address=" << llvm::format("0x%08llX", sgi->address)
|
||||
<< ", size=" << llvm::format("0x%08llX", sgi->size)
|
||||
<< ", segment-name='" << sgi->name
|
||||
<< "'\n";
|
||||
for (SectionInfo *si : sgi->sections) {
|
||||
llvm::dbgs()<< " addr=" << llvm::format("0x%08llX", si->address)
|
||||
<< ", size=" << llvm::format("0x%08llX", si->size)
|
||||
<< ", section-name='" << si->sectionName
|
||||
<< "\n";
|
||||
}
|
||||
}
|
||||
);
|
||||
} else {
|
||||
for (SectionInfo *sect : _sectionInfos) {
|
||||
sect->address = llvm::RoundUpToAlignment(address, sect->alignment);
|
||||
address = sect->address + sect->size;
|
||||
}
|
||||
DEBUG_WITH_TYPE("WriterMachO-norm",
|
||||
llvm::dbgs() << "assignAddressesToSections()\n";
|
||||
for (SectionInfo *si : _sectionInfos) {
|
||||
llvm::dbgs() << " section=" << si->sectionName
|
||||
<< " address= " << llvm::format("0x%08X", si->address)
|
||||
<< " size= " << llvm::format("0x%08X", si->size)
|
||||
<< "\n";
|
||||
}
|
||||
);
|
||||
address = llvm::RoundUpToAlignment(address, _ctx.pageSize());
|
||||
}
|
||||
DEBUG_WITH_TYPE("WriterMachO-norm",
|
||||
llvm::dbgs() << "assignAddressesToSections()\n";
|
||||
for (SegmentInfo *sgi : _segmentInfos) {
|
||||
llvm::dbgs() << " address=" << llvm::format("0x%08llX", sgi->address)
|
||||
<< ", size=" << llvm::format("0x%08llX", sgi->size)
|
||||
<< ", segment-name='" << sgi->name
|
||||
<< "'\n";
|
||||
for (SectionInfo *si : sgi->sections) {
|
||||
llvm::dbgs()<< " addr=" << llvm::format("0x%08llX", si->address)
|
||||
<< ", size=" << llvm::format("0x%08llX", si->size)
|
||||
<< ", section-name='" << si->sectionName
|
||||
<< "\n";
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void Util::copySegmentInfo(NormalizedFile &file) {
|
||||
|
@ -604,16 +581,9 @@ void Util::copySectionContent(NormalizedFile &file) {
|
|||
|
||||
void Util::copySectionInfo(NormalizedFile &file) {
|
||||
file.sections.reserve(_sectionInfos.size());
|
||||
// For final linked images, write sections grouped by segment.
|
||||
if (_ctx.outputMachOType() != llvm::MachO::MH_OBJECT) {
|
||||
for (SegmentInfo *sgi : _segmentInfos) {
|
||||
for (SectionInfo *si : sgi->sections) {
|
||||
appendSection(si, file);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Object files write sections in default order.
|
||||
for (SectionInfo *si : _sectionInfos) {
|
||||
// Write sections grouped by segment.
|
||||
for (SegmentInfo *sgi : _segmentInfos) {
|
||||
for (SectionInfo *si : sgi->sections) {
|
||||
appendSection(si, file);
|
||||
}
|
||||
}
|
||||
|
@ -621,20 +591,12 @@ void Util::copySectionInfo(NormalizedFile &file) {
|
|||
|
||||
void Util::updateSectionInfo(NormalizedFile &file) {
|
||||
file.sections.reserve(_sectionInfos.size());
|
||||
if (_ctx.outputMachOType() != llvm::MachO::MH_OBJECT) {
|
||||
// For final linked images, sections grouped by segment.
|
||||
for (SegmentInfo *sgi : _segmentInfos) {
|
||||
Segment *normSeg = &file.segments[sgi->normalizedSegmentIndex];
|
||||
normSeg->address = sgi->address;
|
||||
normSeg->size = sgi->size;
|
||||
for (SectionInfo *si : sgi->sections) {
|
||||
Section *normSect = &file.sections[si->normalizedSectionIndex];
|
||||
normSect->address = si->address;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Object files write sections in default order.
|
||||
for (SectionInfo *si : _sectionInfos) {
|
||||
// sections grouped by segment.
|
||||
for (SegmentInfo *sgi : _segmentInfos) {
|
||||
Segment *normSeg = &file.segments[sgi->normalizedSegmentIndex];
|
||||
normSeg->address = sgi->address;
|
||||
normSeg->size = sgi->size;
|
||||
for (SectionInfo *si : sgi->sections) {
|
||||
Section *normSect = &file.sections[si->normalizedSectionIndex];
|
||||
normSect->address = si->address;
|
||||
}
|
||||
|
@ -999,11 +961,9 @@ void Util::segIndexForSection(const SectionInfo *sect, uint8_t &segmentIndex,
|
|||
|
||||
uint32_t Util::sectionIndexForAtom(const Atom *atom) {
|
||||
uint64_t address = _atomToAddress[atom];
|
||||
uint32_t index = 1;
|
||||
for (const SectionInfo *si : _sectionInfos) {
|
||||
if ((si->address <= address) && (address < si->address+si->size))
|
||||
return index;
|
||||
++index;
|
||||
return si->finalSectionIndex;
|
||||
}
|
||||
llvm_unreachable("atom not in any section");
|
||||
}
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
# The reference from FDE->CIE is implicitly created as a negDelta32.
|
||||
# We don't emit these in to the binary as relocations, so we need to
|
||||
# make sure that the offset in the FDE to the CIE is the correct value.
|
||||
# CHECK: 0010 10000000 00000000 017a5200 01781e01
|
||||
# CHECK: 0020 100c1f00 20000000 18000000 e4ffffff
|
||||
# CHECK: {{[0-9abcdef]*}} 10000000 00000000 017a5200 01781e01
|
||||
# CHECK: {{[0-9abcdef]*}} 100c1f00 20000000 18000000 e4ffffff
|
||||
# Note, this one that matters ^~~~~~~~
|
||||
# It needs to be 0x18 as that is the offset back to 0 where the CIE is.
|
||||
# CHECK: 0030 ffffffff 20000000 00000000 00480e10
|
||||
# CHECK: 0040 9e019d02 00000000
|
||||
# CHECK: {{[0-9abcdef]*}} ffffffff 20000000 00000000 00480e10
|
||||
# CHECK: {{[0-9abcdef]*}} 9e019d02 00000000
|
||||
|
||||
--- !mach-o
|
||||
arch: arm64
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
# RUN: lld -flavor darwin -arch arm64 -r -print_atoms %s -o %t
|
||||
# RUN: lld -flavor darwin -arch arm64 -r -print_atoms %t -o %t2
|
||||
# RUN: llvm-objdump -section-headers %t | FileCheck %s
|
||||
# RUN: llvm-objdump -section-headers %t2 | FileCheck %s
|
||||
|
||||
# Make sure that the sections are sorted. Currently we want this order:
|
||||
# __text, __unwind_info
|
||||
|
||||
# CHECK: Sections:
|
||||
# CHECK: 0 __text {{.*}} TEXT
|
||||
# CHECK: 1 __compact_unwind {{.*}}
|
||||
|
||||
|
||||
--- !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: 8
|
||||
address: 0x0000000000000000
|
||||
content: [ 0xC0, 0x03, 0x5F, 0xD6, 0xC0, 0x03, 0x5F, 0xD6 ]
|
||||
- segment: __LD
|
||||
section: __compact_unwind
|
||||
type: S_REGULAR
|
||||
attributes: [ ]
|
||||
alignment: 8
|
||||
address: 0x0000000000000008
|
||||
content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x04, 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: 0x00000020
|
||||
type: ARM64_RELOC_UNSIGNED
|
||||
length: 3
|
||||
pc-rel: false
|
||||
extern: false
|
||||
symbol: 1
|
||||
- offset: 0x00000000
|
||||
type: ARM64_RELOC_UNSIGNED
|
||||
length: 3
|
||||
pc-rel: false
|
||||
extern: false
|
||||
symbol: 1
|
||||
global-symbols:
|
||||
- name: __Z3fooi
|
||||
type: N_SECT
|
||||
scope: [ N_EXT ]
|
||||
sect: 1
|
||||
value: 0x0000000000000000
|
||||
- name: __Z4foo2i
|
||||
type: N_SECT
|
||||
scope: [ N_EXT ]
|
||||
sect: 1
|
||||
value: 0x0000000000000004
|
|
@ -268,7 +268,7 @@ page-size: 0x00000000
|
|||
# CHECK: type: data
|
||||
# CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00, 04, 00, 00, 00,
|
||||
# CHECK: 00, 00, 00, 00, F0, FF, FF, FF, FF, FF, FF, FF,
|
||||
# CHECK: {{..}}, 00, 00, 00, 00, 00, 00, 00, {{..}}, 00, 00, 00,
|
||||
# CHECK: {{..}}, {{..}}, 00, 00, 00, 00, 00, 00, {{..}}, {{..}}, 00, 00,
|
||||
# CHECK: 00, 00, 00, 00, D8, FF, FF, FF, FF, FF, FF, FF,
|
||||
# CHECK: D4, FF, FF, FF, FF, FF, FF, FF, {{..}}, {{..}}, {{..}}, {{..}},
|
||||
# CHECK: {{..}}, {{..}}, {{..}}, {{..}}, C0, FF, FF, FF, C0, FF, FF, FF,
|
||||
|
|
Loading…
Reference in New Issue