[lld][MachO] Prune unused EH frames.

llvm-svn: 251095
This commit is contained in:
Lang Hames 2015-10-23 05:39:16 +00:00
parent 81595bd9d2
commit 5e7cfe4e2b
3 changed files with 92 additions and 3 deletions

View File

@ -310,6 +310,9 @@ private:
std::vector<CompactUnwindEntry> unwindInfos = createUnwindInfoEntries(
mergedFile, unwindLocs, personalities, dwarfFrames);
// Remove any unused eh-frame atoms.
pruneUnusedEHFrames(mergedFile, unwindInfos, unwindLocs, dwarfFrames);
// Finally, we can start creating pages based on these entries.
DEBUG(llvm::dbgs() << " Splitting entries into pages\n");
@ -470,6 +473,54 @@ private:
return unwindInfos;
}
/// Remove unused EH frames.
///
/// An EH frame is considered unused if there is a corresponding compact
/// unwind atom that doesn't require the EH frame.
void pruneUnusedEHFrames(
SimpleFile &mergedFile,
const std::vector<CompactUnwindEntry> &unwindInfos,
const std::map<const Atom *, CompactUnwindEntry> &unwindLocs,
const std::map<const Atom *, const Atom *> &dwarfFrames) {
// Worklist of all 'used' FDEs.
std::vector<const DefinedAtom *> usedDwarfWorklist;
// We have to check two conditions when building the worklist:
// (1) EH frames used by compact unwind entries.
for (auto &entry : unwindInfos)
if (entry.ehFrame)
usedDwarfWorklist.push_back(cast<DefinedAtom>(entry.ehFrame));
// (2) EH frames that reference functions with no corresponding compact
// unwind info.
for (auto &entry : dwarfFrames)
if (!unwindLocs.count(entry.first))
usedDwarfWorklist.push_back(cast<DefinedAtom>(entry.second));
// Add all transitively referenced CFI atoms by processing the worklist.
std::set<const Atom *> usedDwarfFrames;
while (!usedDwarfWorklist.empty()) {
const DefinedAtom *cfiAtom = usedDwarfWorklist.back();
usedDwarfWorklist.pop_back();
usedDwarfFrames.insert(cfiAtom);
for (const auto *ref : *cfiAtom) {
const DefinedAtom *cfiTarget = dyn_cast<DefinedAtom>(ref->target());
if (cfiTarget->contentType() == DefinedAtom::typeCFI)
usedDwarfWorklist.push_back(cfiTarget);
}
}
// Finally, delete all unreferenced CFI atoms.
mergedFile.removeDefinedAtomsIf([&](const DefinedAtom *atom) {
if ((atom->contentType() == DefinedAtom::typeCFI) &&
!usedDwarfFrames.count(atom))
return true;
return false;
});
}
CompactUnwindEntry finalizeUnwindInfoEntryForAtom(
const DefinedAtom *function,
const std::map<const Atom *, CompactUnwindEntry> &unwindLocs,

View File

@ -67,7 +67,8 @@ defined-atoms:
target: _needsDwarfButNoCompactUnwind
# Generic x86_64 CIE:
- type: unwind-cfi
- name: LCIE
type: unwind-cfi
content: [ 14, 00, 00, 00, 00, 00, 00, 00, 01, 7A, 52, 00,
01, 78, 10, 01, 10, 0C, 07, 08, 90, 01, 00, 00 ]
@ -80,6 +81,9 @@ defined-atoms:
- kind: unwindFDEToFunction
offset: 8
target: _needsDwarfButNoCompactUnwind
- kind: negDelta32
offset: 4
target: LCIE
- type: unwind-cfi
content: [ 24, 00, 00, 00, 44, 00, 00, 00, C8, FE, FF, FF,
@ -90,7 +94,22 @@ defined-atoms:
- kind: unwindFDEToFunction
offset: 8
target: _needsDwarfSaysCompactUnwind
- kind: negDelta32
offset: 4
target: LCIE
- type: unwind-cfi
content: [ 24, 00, 00, 00, 6C, 00, 00, 00, C8, FE, FF, FF,
FF, FF, FF, FF, 01, 00, 00, 00, 00, 00, 00, 00,
00, 41, 0E, 10, 86, 02, 43, 0D, 06, 00, 00, 00,
00, 00, 00, 00 ]
references:
- kind: unwindFDEToFunction
offset: 8
target: _main
- kind: negDelta32
offset: 4
target: LCIE
- name: __Z3barv
scope: global

View File

@ -69,12 +69,31 @@ defined-atoms:
# CHECK-NEXT: )
# For __TEXT, __eh_frame, (with typeCFI)
- name: LCIE
type: unwind-cfi
content: [ 14, 00, 00, 00, 00, 00, 00, 00, 01, 7A, 52, 00,
01, 78, 10, 01, 10, 0C, 07, 08, 90, 01, 00, 00 ]
- type: unwind-cfi
content: [ 07 ]
content: [ 24, 00, 00, 00, 1C, 00, 00, 00, C8, FE, FF, FF,
FF, FF, FF, FF, 01, 00, 00, 00, 00, 00, 00, 00,
00, 41, 0E, 10, 86, 02, 43, 0D, 06, 00, 00, 00,
00, 00, 00, 00 ]
references:
- kind: unwindFDEToFunction
offset: 8
target: _foo
- kind: negDelta32
offset: 4
target: LCIE
# CHECK: Name: __eh_frame
# CHECK: Segment: __TEXT
# CHECK: SectionData (
# CHECK-NEXT: 0000: 07
# CHECK-NEXT: 0000: 14000000 00000000 017A5200 01781001
# CHECK-NEXT: 0010: 100C0708 90010000 24000000 1C000000
# CHECK-NEXT: 0020: 70FFFFFF FFFFFFFF 01000000 00000000
# CHECK-NEXT: 0030: 00410E10 8602430D 06000000 00000000
# CHECK-NEXT: )
# For __DATA, __data, (with typeData)