forked from OSchip/llvm-project
[mach-o] Add support for initializers and terminators in object files
llvm-svn: 209700
This commit is contained in:
parent
329912f54c
commit
a4a08d31cf
|
@ -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);
|
||||
|
|
|
@ -179,6 +179,12 @@ SectionInfo *Util::makeSection(DefinedAtom::ContentType type) {
|
|||
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);
|
||||
|
|
|
@ -109,8 +109,9 @@ static void processUndefindeSymbol(MachOFile &file, const Symbol &sym,
|
|||
}
|
||||
|
||||
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(MachOFile &file, const Section §ion,
|
|||
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 NormalizedFile &normalizedFile, StringRef path,
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ]
|
|
@ -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 ]
|
Loading…
Reference in New Issue