summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2014-11-04 21:57:32 +0000
committerTim Northover <tnorthover@apple.com>2014-11-04 21:57:32 +0000
commitf98b1c99603d7da0e7d3700e446fe864506294f8 (patch)
tree75a37eed9a137efe1ebad5e070ba7fb4ac7c1380
parenta16974a5c06463d0191760388a790421b155164d (diff)
downloadbcm5719-llvm-f98b1c99603d7da0e7d3700e446fe864506294f8.tar.gz
bcm5719-llvm-f98b1c99603d7da0e7d3700e446fe864506294f8.zip
[mach-o] remove __compact_unwind atoms once __unwind_info has been generated
The job of the CompactUnwind pass is to turn __compact_unwind data (and __eh_frame) into the compressed final form in __unwind_info. After it's done, the original atoms are no longer relevant and should be deleted (they cause problems during actual execution, quite apart from the fact that they're not needed). llvm-svn: 221301
-rw-r--r--lld/include/lld/Core/File.h4
-rw-r--r--lld/include/lld/Core/Resolver.h4
-rw-r--r--lld/include/lld/Core/Simple.h6
-rw-r--r--lld/lib/Core/Resolver.cpp7
-rw-r--r--lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp6
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp6
-rw-r--r--lld/test/mach-o/unwind-info-simple-x86_64.yaml1
-rw-r--r--lld/test/mach-o/write-final-sections.yaml10
8 files changed, 28 insertions, 16 deletions
diff --git a/lld/include/lld/Core/File.h b/lld/include/lld/Core/File.h
index 2e9dbaaddf4..8ab44528c6a 100644
--- a/lld/include/lld/Core/File.h
+++ b/lld/include/lld/Core/File.h
@@ -17,6 +17,7 @@
#include "lld/Core/UndefinedAtom.h"
#include "lld/Core/range.h"
#include "llvm/Support/ErrorHandling.h"
+#include <functional>
#include <vector>
namespace lld {
@@ -222,6 +223,9 @@ public:
typedef range<std::vector<const DefinedAtom *>::iterator> DefinedAtomRange;
virtual DefinedAtomRange definedAtoms() = 0;
+ virtual void
+ removeDefinedAtomsIf(std::function<bool(const DefinedAtom *)> pred) = 0;
+
protected:
/// \brief only subclasses of MutableFile can be instantiated
MutableFile(StringRef p) : File(p, kindObject) {}
diff --git a/lld/include/lld/Core/Resolver.h b/lld/include/lld/Core/Resolver.h
index 64f962e8234..e001b499a15 100644
--- a/lld/include/lld/Core/Resolver.h
+++ b/lld/include/lld/Core/Resolver.h
@@ -89,8 +89,12 @@ private:
void addAtoms(std::vector<const Atom*>& atoms);
void addAtom(const Atom& atom) override;
+
DefinedAtomRange definedAtoms() override;
+ void removeDefinedAtomsIf(
+ std::function<bool(const DefinedAtom *)> pred) override;
+
private:
atom_collection_vector<DefinedAtom> _definedAtoms;
atom_collection_vector<UndefinedAtom> _undefinedAtoms;
diff --git a/lld/include/lld/Core/Simple.h b/lld/include/lld/Core/Simple.h
index ee29f5b214b..a8282d11fee 100644
--- a/lld/include/lld/Core/Simple.h
+++ b/lld/include/lld/Core/Simple.h
@@ -40,6 +40,12 @@ public:
}
}
+ void removeDefinedAtomsIf(std::function<bool(const DefinedAtom *)> pred) {
+ auto &atoms = _definedAtoms._atoms;
+ auto newEnd = std::remove_if(atoms.begin(), atoms.end(), pred);
+ atoms.erase(newEnd, atoms.end());
+ }
+
const atom_collection<DefinedAtom> &defined() const override {
return _definedAtoms;
}
diff --git a/lld/lib/Core/Resolver.cpp b/lld/lib/Core/Resolver.cpp
index 16578661602..e4a1b53cc33 100644
--- a/lld/lib/Core/Resolver.cpp
+++ b/lld/lib/Core/Resolver.cpp
@@ -445,6 +445,13 @@ MutableFile::DefinedAtomRange Resolver::MergedFile::definedAtoms() {
_definedAtoms._atoms.begin(), _definedAtoms._atoms.end());
}
+void Resolver::MergedFile::removeDefinedAtomsIf(
+ std::function<bool(const DefinedAtom *)> pred) {
+ auto &atoms = _definedAtoms._atoms;
+ auto newEnd = std::remove_if(atoms.begin(), atoms.end(), pred);
+ atoms.erase(newEnd, atoms.end());
+}
+
void Resolver::MergedFile::addAtoms(std::vector<const Atom *> &all) {
ScopedTask task(getDefaultDomain(), "addAtoms");
DEBUG_WITH_TYPE("resolver", llvm::dbgs() << "Resolver final atom list:\n");
diff --git a/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp b/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp
index f440cede201..9280ec43320 100644
--- a/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp
+++ b/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp
@@ -337,11 +337,15 @@ private:
<< " has " << entriesInPage << " entries\n");
} while (pageStart < unwindInfos.size());
- // FIXME: we should also erase all compact-unwind atoms; their job is done.
UnwindInfoAtom *unwind = new (_file.allocator())
UnwindInfoAtom(_archHandler, _file, _isBig, std::vector<uint32_t>(),
personalities, pages, numLSDAs);
mergedFile->addAtom(*unwind);
+
+ // Finally, remove all __compact_unwind atoms now that we've processed them.
+ mergedFile->removeDefinedAtomsIf([](const DefinedAtom *atom) {
+ return atom->contentType() == DefinedAtom::typeCompactUnwindInfo;
+ });
}
void collectCompactUnwindEntries(
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
index 4a4ba792028..dc015c5f296 100644
--- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
@@ -231,12 +231,6 @@ const MachOFinalSectionFromAtomType sectsToAtomType[] = {
ENTRY("__DATA", "___got", S_NON_LAZY_SYMBOL_POINTERS,
typeGOT),
ENTRY("__DATA", "___bss", S_ZEROFILL, typeZeroFill),
-
- // FIXME: __compact_unwind actually needs to be processed by a pass and put
- // into __TEXT,__unwind_info. For now, forwarding it back to
- // __LD,__compact_unwind is harmless (it's ignored by the unwinder, which then
- // proceeds to process __TEXT,__eh_frame for its instructions).
- ENTRY("__LD", "__compact_unwind", S_REGULAR, typeCompactUnwindInfo),
};
#undef ENTRY
diff --git a/lld/test/mach-o/unwind-info-simple-x86_64.yaml b/lld/test/mach-o/unwind-info-simple-x86_64.yaml
index 2c42ada405e..8886e527166 100644
--- a/lld/test/mach-o/unwind-info-simple-x86_64.yaml
+++ b/lld/test/mach-o/unwind-info-simple-x86_64.yaml
@@ -24,6 +24,7 @@
# CHECK: [2]: function offset=0x00000efd, encoding=0x04000018
# CHECK: [3]: function offset=0x00000efe, encoding=0x04000040
# CHECK: [4]: function offset=0x00000eff, encoding=0x00000000
+# CHECK-NOT: Contents of __compact_unwind section
--- !native
path: '<linker-internal>'
diff --git a/lld/test/mach-o/write-final-sections.yaml b/lld/test/mach-o/write-final-sections.yaml
index 8701f405bea..b8b8cc67d91 100644
--- a/lld/test/mach-o/write-final-sections.yaml
+++ b/lld/test/mach-o/write-final-sections.yaml
@@ -140,17 +140,9 @@ defined-atoms:
# CHECK-NEXT: 0000: 0D000000 00000000
# CHECK-NEXT: )
-# FIXME: this should really end up in __TEXT,__unwind_info after being
-# processed. Most important fact here is that its presence doesn't trigger an
-# assert, but __LD,__compact_unwind is a harmless enough place to stash it.
-
- type: compact-unwind
content: [ 0E, 00, 00, 00, 00, 00, 00, 00 ]
-# CHECK: Name: __compact_unwind
-# CHECK: Segment: __LD
-# CHECK: SectionData (
-# CHECK-NEXT: 0000: 0E000000 00000000
-# CHECK-NEXT: )
+# CHECK-NOT: Name: __compact_unwind
--- !mach-o
OpenPOWER on IntegriCloud