[lld] r209700 - [mach-o] Add support for initializers and terminators in object files
Nick Kledzik
kledzik at apple.com
Tue May 27 16:20:53 PDT 2014
Author: kledzik
Date: Tue May 27 18:20:52 2014
New Revision: 209700
URL: http://llvm.org/viewvc/llvm-project?rev=209700&view=rev
Log:
[mach-o] Add support for initializers and terminators in object files
Added:
lld/trunk/test/mach-o/parse-initializers32.yaml
lld/trunk/test/mach-o/parse-initializers64.yaml
Modified:
lld/trunk/lib/ReaderWriter/MachO/Atoms.h
lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
Modified: lld/trunk/lib/ReaderWriter/MachO/Atoms.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/Atoms.h?rev=209700&r1=209699&r2=209700&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/Atoms.h (original)
+++ lld/trunk/lib/ReaderWriter/MachO/Atoms.h Tue May 27 18:20:52 2014
@@ -36,6 +36,14 @@ public:
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);
Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp?rev=209700&r1=209699&r2=209700&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp Tue May 27 18:20:52 2014
@@ -179,6 +179,12 @@ SectionInfo *Util::makeSection(DefinedAt
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);
Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp?rev=209700&r1=209699&r2=209700&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp Tue May 27 18:20:52 2014
@@ -109,8 +109,9 @@ static void processUndefindeSymbol(MachO
}
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 @@ static error_code processSection(MachOFi
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 @@ normalizedObjectToAtoms(const Normalized
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;
}
Added: lld/trunk/test/mach-o/parse-initializers32.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/parse-initializers32.yaml?rev=209700&view=auto
==============================================================================
--- lld/trunk/test/mach-o/parse-initializers32.yaml (added)
+++ lld/trunk/test/mach-o/parse-initializers32.yaml Tue May 27 18:20:52 2014
@@ -0,0 +1,84 @@
+# RUN: lld -flavor darwin -arch i386 -r -print_atoms %s -o %t | FileCheck %s
+#
+# Test parsing of literal sections.
+#
+
+--- !mach-o
+arch: x86
+file-type: MH_OBJECT
+flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
+has-UUID: false
+OS: unknown
+sections:
+ - segment: __TEXT
+ section: __text
+ type: S_REGULAR
+ attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
+ address: 0x0000000000000000
+ content: [ 0x55, 0x89, 0xE5, 0x5D, 0xC3, 0x55, 0x89, 0xE5,
+ 0x5D, 0xC3, 0x55, 0x89, 0xE5, 0x5D, 0xC3 ]
+ - segment: __DATA
+ section: __mod_init_func
+ type: S_MOD_INIT_FUNC_POINTERS
+ attributes: [ ]
+ alignment: 2
+ address: 0x0000000000000044
+ content: [ 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00 ]
+ relocations:
+ - offset: 0x00000000
+ type: GENERIC_RELOC_VANILLA
+ length: 2
+ pc-rel: false
+ extern: false
+ symbol: 1
+ - offset: 0x00000004
+ type: GENERIC_RELOC_VANILLA
+ length: 2
+ pc-rel: false
+ extern: false
+ symbol: 1
+ - segment: __DATA
+ section: __mod_term_func
+ type: S_MOD_TERM_FUNC_POINTERS
+ attributes: [ ]
+ alignment: 2
+ address: 0x0000000000000104
+ content: [ 0x0A, 0x00, 0x00, 0x00 ]
+global-symbols:
+ - name: _init
+ type: N_SECT
+ scope: [ N_EXT ]
+ sect: 1
+ value: 0x0000000000000000
+ - name: _init2
+ type: N_SECT
+ scope: [ N_EXT ]
+ sect: 1
+ value: 0x0000000000000005
+ - name: _term
+ type: N_SECT
+ scope: [ N_EXT ]
+ sect: 1
+ value: 0x000000000000000A
+...
+
+
+# CHECK:defined-atoms:
+# CHECK: - type: initializer-pointer
+# CHECK: content: [ 00, 00, 00, 00 ]
+# CHECK: dead-strip: never
+# CHECK: - type: initializer-pointer
+# CHECK: content: [ 05, 00, 00, 00 ]
+# CHECK: dead-strip: never
+# CHECK: - type: terminator-pointer
+# CHECK: content: [ 0A, 00, 00, 00 ]
+# CHECK: dead-strip: never
+# CHECK: - name: _init
+# CHECK: scope: global
+# CHECK: content: [ 55, 89, E5, 5D, C3 ]
+# CHECK: - name: _init2
+# CHECK: scope: global
+# CHECK: content: [ 55, 89, E5, 5D, C3 ]
+# CHECK: - name: _term
+# CHECK: scope: global
+# CHECK: content: [ 55, 89, E5, 5D, C3 ]
Added: lld/trunk/test/mach-o/parse-initializers64.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/parse-initializers64.yaml?rev=209700&view=auto
==============================================================================
--- lld/trunk/test/mach-o/parse-initializers64.yaml (added)
+++ lld/trunk/test/mach-o/parse-initializers64.yaml Tue May 27 18:20:52 2014
@@ -0,0 +1,93 @@
+# RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s
+#
+# Test parsing of literal sections.
+#
+
+--- !mach-o
+arch: x86_64
+file-type: MH_OBJECT
+flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
+has-UUID: false
+OS: unknown
+sections:
+ - segment: __TEXT
+ section: __text
+ type: S_REGULAR
+ attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
+ address: 0x0000000000000000
+ content: [ 0x55, 0x48, 0x89, 0xE5, 0x5D, 0xC3, 0x55, 0x48,
+ 0x89, 0xE5, 0x5D, 0xC3, 0x55, 0x48, 0x89, 0xE5,
+ 0x5D, 0xC3 ]
+ - segment: __DATA
+ section: __mod_init_func
+ type: S_MOD_INIT_FUNC_POINTERS
+ attributes: [ ]
+ alignment: 0
+ address: 0x0000000000000100
+ content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
+ relocations:
+ - offset: 0x00000000
+ type: X86_64_RELOC_UNSIGNED
+ length: 3
+ pc-rel: false
+ extern: true
+ symbol: 1
+ - offset: 0x00000008
+ type: X86_64_RELOC_UNSIGNED
+ length: 3
+ pc-rel: false
+ extern: true
+ symbol: 2
+ - segment: __DATA
+ section: __mod_term_func
+ type: S_MOD_TERM_FUNC_POINTERS
+ attributes: [ ]
+ alignment: 3
+ address: 0x0000000000000108
+ content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
+ relocations:
+ - offset: 0x00000000
+ type: X86_64_RELOC_UNSIGNED
+ length: 3
+ pc-rel: false
+ extern: true
+ symbol: 3
+global-symbols:
+ - name: _init
+ type: N_SECT
+ scope: [ N_EXT ]
+ sect: 1
+ value: 0x0000000000000000
+ - name: _init2
+ type: N_SECT
+ scope: [ N_EXT ]
+ sect: 1
+ value: 0x0000000000000006
+ - name: _term
+ type: N_SECT
+ scope: [ N_EXT ]
+ sect: 1
+ value: 0x000000000000000C
+...
+
+
+# CHECK:defined-atoms:
+# CHECK: - type: initializer-pointer
+# CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]
+# CHECK: dead-strip: never
+# CHECK: - type: initializer-pointer
+# CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]
+# CHECK: dead-strip: never
+# CHECK: - type: terminator-pointer
+# CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]
+# CHECK: dead-strip: never
+# CHECK: - name: _init
+# CHECK: scope: global
+# CHECK: content: [ 55, 48, 89, E5, 5D, C3 ]
+# CHECK: - name: _init2
+# CHECK: scope: global
+# CHECK: content: [ 55, 48, 89, E5, 5D, C3 ]
+# CHECK: - name: _term
+# CHECK: scope: global
+# CHECK: content: [ 55, 48, 89, E5, 5D, C3 ]
More information about the llvm-commits
mailing list