[mach-o] Add support for initializers and terminators in object files
llvm-svn: 209700
diff --git a/lld/lib/ReaderWriter/MachO/Atoms.h b/lld/lib/ReaderWriter/MachO/Atoms.h
index 0d41d60..9f505a2 100644
--- a/lld/lib/ReaderWriter/MachO/Atoms.h
+++ b/lld/lib/ReaderWriter/MachO/Atoms.h
@@ -36,6 +36,14 @@
Scope scope() const override { return _scope; }
+ DeadStripKind deadStrip() const override {
+ if (_contentType == DefinedAtom::typeInitializerPtr)
+ return deadStripNever;
+ if (_contentType == DefinedAtom::typeTerminatorPtr)
+ return deadStripNever;
+ return deadStripNormal;
+ }
+
ArrayRef<uint8_t> rawContent() const override {
// Zerofill atoms have a content pointer which is null.
assert(_content.data() != nullptr);
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
index c6d1e2c..1b548d9 100644
--- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
@@ -179,6 +179,12 @@
case DefinedAtom::typeZeroFill:
return new (_allocator) SectionInfo("__DATA", "__bss",
S_ZEROFILL);
+ case DefinedAtom::typeInitializerPtr:
+ return new (_allocator) SectionInfo("__DATA", "__mod_init_func",
+ S_MOD_INIT_FUNC_POINTERS);
+ case DefinedAtom::typeTerminatorPtr:
+ return new (_allocator) SectionInfo("__DATA", "__mod_term_func",
+ S_MOD_TERM_FUNC_POINTERS);
case DefinedAtom::typeLiteral4:
return new (_allocator) SectionInfo("__TEXT", "__literal4",
S_4BYTE_LITERALS);
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
index 69ff193..2b87c23 100644
--- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
@@ -109,8 +109,9 @@
}
static error_code processSection(MachOFile &file, const Section §ion,
- bool copyRefs) {
+ bool is64, bool copyRefs) {
unsigned offset = 0;
+ const unsigned pointerSize = (is64 ? 8 : 4);
switch (section.type) {
case llvm::MachO::S_REGULAR:
if (section.segmentName.equals("__TEXT") &&
@@ -142,6 +143,40 @@
case llvm::MachO::S_ZEROFILL:
// These sections are broken in to atoms based on symbols.
break;
+ case S_MOD_INIT_FUNC_POINTERS:
+ if ((section.content.size() % pointerSize) != 0) {
+ return make_dynamic_error_code(Twine("Section ") + section.segmentName
+ + "/" + section.sectionName
+ + " has type S_MOD_INIT_FUNC_POINTERS but "
+ "its size ("
+ + Twine(section.content.size())
+ + ") is not a multiple of "
+ + Twine(pointerSize));
+ }
+ for (size_t i = 0, e = section.content.size(); i != e; i += pointerSize) {
+ ArrayRef<uint8_t> bytes = section.content.slice(offset, pointerSize);
+ file.addDefinedAtom(StringRef(), DefinedAtom::scopeTranslationUnit,
+ DefinedAtom::typeInitializerPtr, bytes, copyRefs);
+ offset += pointerSize;
+ }
+ break;
+ case S_MOD_TERM_FUNC_POINTERS:
+ if ((section.content.size() % pointerSize) != 0) {
+ return make_dynamic_error_code(Twine("Section ") + section.segmentName
+ + "/" + section.sectionName
+ + " has type S_MOD_TERM_FUNC_POINTERS but "
+ "its size ("
+ + Twine(section.content.size())
+ + ") is not a multiple of "
+ + Twine(pointerSize));
+ }
+ for (size_t i = 0, e = section.content.size(); i != e; i += pointerSize) {
+ ArrayRef<uint8_t> bytes = section.content.slice(offset, pointerSize);
+ file.addDefinedAtom(StringRef(), DefinedAtom::scopeTranslationUnit,
+ DefinedAtom::typeTerminatorPtr, bytes, copyRefs);
+ offset += pointerSize;
+ }
+ break;
case llvm::MachO::S_CSTRING_LITERALS:
for (size_t i = 0, e = section.content.size(); i != e; ++i) {
if (section.content[i] == 0) {
@@ -227,8 +262,9 @@
processUndefindeSymbol(*file, sym, copyRefs);
}
// Create atoms from sections that don't have symbols.
+ bool is64 = MachOLinkingContext::is64Bit(normalizedFile.arch);
for (auto § : normalizedFile.sections) {
- if (error_code ec = processSection(*file, sect, copyRefs))
+ if (error_code ec = processSection(*file, sect, is64, copyRefs))
return ec;
}