mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-13 11:22:03 +00:00
[lld][MachO] Prune unused EH frames.
llvm-svn: 251095
This commit is contained in:
parent
81595bd9d2
commit
5e7cfe4e2b
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user