[lld] r220348 - [mach-o] Support missing MH_SUBSECTIONS_VIA_SYMBOLS
Nick Kledzik
kledzik at apple.com
Tue Oct 21 16:45:37 PDT 2014
Author: kledzik
Date: Tue Oct 21 18:45:37 2014
New Revision: 220348
URL: http://llvm.org/viewvc/llvm-project?rev=220348&view=rev
Log:
[mach-o] Support missing MH_SUBSECTIONS_VIA_SYMBOLS
All compiler generated mach-o object files are marked with MH_SUBSECTIONS_VIA_SYMBOLS.
But hand written assembly files need to opt-in if they are written correctly.
The flag means the linker can break up a sections at symbol addresses and
dead strip or re-order functions.
This change recognizes object files without the flag and marks its atoms as
not dead strippable and adds a layout-after chain of references so that the
atoms cannot be re-ordered.
Added:
lld/trunk/test/mach-o/arm-subsections-via-symbols.yaml
Modified:
lld/trunk/lib/ReaderWriter/MachO/ArchHandler.h
lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp
lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp
lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
lld/trunk/test/mach-o/parse-data-relocs-x86_64.yaml
Modified: lld/trunk/lib/ReaderWriter/MachO/ArchHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler.h?rev=220348&r1=220347&r2=220348&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler.h Tue Oct 21 18:45:37 2014
@@ -134,7 +134,7 @@ public:
const normalized::Relocation &reloc2,
const DefinedAtom *inAtom,
uint32_t offsetInAtom,
- uint64_t fixupAddress, bool swap,
+ uint64_t fixupAddress, bool swap, bool scatterable,
FindAtomBySectionAndAddress atomFromAddress,
FindAtomBySymbolIndex atomFromSymbolIndex,
Reference::KindValue *kind,
Modified: lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp?rev=220348&r1=220347&r2=220348&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp Tue Oct 21 18:45:37 2014
@@ -77,7 +77,7 @@ public:
const normalized::Relocation &reloc2,
const DefinedAtom *inAtom,
uint32_t offsetInAtom,
- uint64_t fixupAddress, bool swap,
+ uint64_t fixupAddress, bool swap, bool scatterable,
FindAtomBySectionAndAddress atomFromAddress,
FindAtomBySymbolIndex atomFromSymbolIndex,
Reference::KindValue *kind,
@@ -627,6 +627,7 @@ ArchHandler_arm::getPairReferenceInfo(co
const DefinedAtom *inAtom,
uint32_t offsetInAtom,
uint64_t fixupAddress, bool swap,
+ bool scatterable,
FindAtomBySectionAndAddress atomFromAddr,
FindAtomBySymbolIndex atomFromSymbolIndex,
Reference::KindValue *kind,
@@ -795,7 +796,7 @@ ArchHandler_arm::getPairReferenceInfo(co
ec = atomFromAddr(0, fromAddress, &fromTarget, &offsetInFrom);
if (ec)
return ec;
- if (fromTarget != inAtom)
+ if (scatterable && (fromTarget != inAtom))
return make_dynamic_error_code(Twine("SECTDIFF relocation where "
"subtrahend label is not in atom"));
*kind = delta32;
Modified: lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp?rev=220348&r1=220347&r2=220348&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp Tue Oct 21 18:45:37 2014
@@ -120,7 +120,7 @@ public:
const normalized::Relocation &reloc2,
const DefinedAtom *inAtom,
uint32_t offsetInAtom,
- uint64_t fixupAddress, bool swap,
+ uint64_t fixupAddress, bool swap, bool scatterable,
FindAtomBySectionAndAddress atomFromAddress,
FindAtomBySymbolIndex atomFromSymbolIndex,
Reference::KindValue *kind,
@@ -418,7 +418,7 @@ std::error_code ArchHandler_arm64::getRe
std::error_code ArchHandler_arm64::getPairReferenceInfo(
const normalized::Relocation &reloc1, const normalized::Relocation &reloc2,
const DefinedAtom *inAtom, uint32_t offsetInAtom, uint64_t fixupAddress,
- bool swap, FindAtomBySectionAndAddress atomFromAddress,
+ bool swap, bool scatterable, FindAtomBySectionAndAddress atomFromAddress,
FindAtomBySymbolIndex atomFromSymbolIndex, Reference::KindValue *kind,
const lld::Atom **target, Reference::Addend *addend) {
const uint8_t *fixupContent = &inAtom->rawContent()[offsetInAtom];
Modified: lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp?rev=220348&r1=220347&r2=220348&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp Tue Oct 21 18:45:37 2014
@@ -80,7 +80,7 @@ public:
const normalized::Relocation &reloc2,
const DefinedAtom *inAtom,
uint32_t offsetInAtom,
- uint64_t fixupAddress, bool swap,
+ uint64_t fixupAddress, bool swap, bool scatterable,
FindAtomBySectionAndAddress atomFromAddress,
FindAtomBySymbolIndex atomFromSymbolIndex,
Reference::KindValue *kind,
@@ -337,6 +337,7 @@ ArchHandler_x86::getPairReferenceInfo(co
const DefinedAtom *inAtom,
uint32_t offsetInAtom,
uint64_t fixupAddress, bool swap,
+ bool scatterable,
FindAtomBySectionAndAddress atomFromAddr,
FindAtomBySymbolIndex atomFromSymbolIndex,
Reference::KindValue *kind,
Modified: lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp?rev=220348&r1=220347&r2=220348&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp Tue Oct 21 18:45:37 2014
@@ -122,7 +122,7 @@ public:
const normalized::Relocation &reloc2,
const DefinedAtom *inAtom,
uint32_t offsetInAtom,
- uint64_t fixupAddress, bool swap,
+ uint64_t fixupAddress, bool swap, bool scatterable,
FindAtomBySectionAndAddress atomFromAddress,
FindAtomBySymbolIndex atomFromSymbolIndex,
Reference::KindValue *kind,
@@ -401,6 +401,7 @@ ArchHandler_x86_64::getPairReferenceInfo
const DefinedAtom *inAtom,
uint32_t offsetInAtom,
uint64_t fixupAddress, bool swap,
+ bool scatterable,
FindAtomBySectionAndAddress atomFromAddress,
FindAtomBySymbolIndex atomFromSymbolIndex,
Reference::KindValue *kind,
Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp?rev=220348&r1=220347&r2=220348&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp Tue Oct 21 18:45:37 2014
@@ -220,12 +220,12 @@ void appendSymbolsInSection(const std::v
void atomFromSymbol(DefinedAtom::ContentType atomType, const Section §ion,
MachOFile &file, uint64_t symbolAddr, StringRef symbolName,
uint16_t symbolDescFlags, Atom::Scope symbolScope,
- uint64_t nextSymbolAddr, bool copyRefs) {
+ uint64_t nextSymbolAddr, bool scatterable, bool copyRefs) {
// Mach-O symbol table does have size in it. Instead the size is the
// difference between this and the next symbol.
uint64_t size = nextSymbolAddr - symbolAddr;
uint64_t offset = symbolAddr - section.address;
- bool noDeadStrip = (symbolDescFlags & N_NO_DEAD_STRIP);
+ bool noDeadStrip = (symbolDescFlags & N_NO_DEAD_STRIP) || !scatterable;
if (section.type == llvm::MachO::S_ZEROFILL) {
file.addZeroFillDefinedAtom(symbolName, symbolScope, offset, size,
noDeadStrip, copyRefs, §ion);
@@ -256,7 +256,8 @@ void atomFromSymbol(DefinedAtom::Content
std::error_code processSymboledSection(DefinedAtom::ContentType atomType,
const Section §ion,
const NormalizedFile &normalizedFile,
- MachOFile &file, bool copyRefs) {
+ MachOFile &file, bool scatterable,
+ bool copyRefs) {
// Find section's index.
uint32_t sectIndex = 1;
for (auto § : normalizedFile.sections) {
@@ -309,13 +310,14 @@ std::error_code processSymboledSection(D
// Section has no symbols, put all content in one anoymous atom.
atomFromSymbol(atomType, section, file, section.address, StringRef(),
0, Atom::scopeTranslationUnit,
- section.address + section.content.size(), copyRefs);
+ section.address + section.content.size(),
+ scatterable, copyRefs);
}
else if (symbols.front()->value != section.address) {
// Section has anonymous content before first symbol.
atomFromSymbol(atomType, section, file, section.address, StringRef(),
0, Atom::scopeTranslationUnit, symbols.front()->value,
- copyRefs);
+ scatterable, copyRefs);
}
const Symbol *lastSym = nullptr;
@@ -328,7 +330,7 @@ std::error_code processSymboledSection(D
|| !lastSym->name.startswith("ltmp")) {
atomFromSymbol(atomType, section, file, lastSym->value, lastSym->name,
lastSym->desc, atomScope(lastSym->scope), sym->value,
- copyRefs);
+ scatterable, copyRefs);
}
}
lastSym = sym;
@@ -336,8 +338,23 @@ std::error_code processSymboledSection(D
if (lastSym != nullptr) {
atomFromSymbol(atomType, section, file, lastSym->value, lastSym->name,
lastSym->desc, atomScope(lastSym->scope),
- section.address + section.content.size(), copyRefs);
+ section.address + section.content.size(),
+ scatterable, copyRefs);
}
+
+ // If object built without .subsections_via_symbols, add reference chain.
+ if (!scatterable) {
+ MachODefinedAtom *prevAtom = nullptr;
+ file.eachAtomInSection(section,
+ [&](MachODefinedAtom *atom, uint64_t offset)->void {
+ if (prevAtom)
+ prevAtom->addReference(0, Reference::kindLayoutAfter, atom, 0,
+ Reference::KindArch::all,
+ Reference::KindNamespace::all);
+ prevAtom = atom;
+ });
+ }
+
return std::error_code();
}
@@ -345,7 +362,8 @@ std::error_code processSection(DefinedAt
const Section §ion,
bool customSectionName,
const NormalizedFile &normalizedFile,
- MachOFile &file, bool copyRefs) {
+ MachOFile &file, bool scatterable,
+ bool copyRefs) {
const bool is64 = MachOLinkingContext::is64Bit(normalizedFile.arch);
const bool swap = !MachOLinkingContext::isHostEndian(normalizedFile.arch);
@@ -368,7 +386,7 @@ std::error_code processSection(DefinedAt
if (atomizeModel == atomizeAtSymbols) {
// Break section up into atoms each with a fixed size.
return processSymboledSection(atomType, section, normalizedFile, file,
- copyRefs);
+ scatterable, copyRefs);
} else {
const uint32_t *cfi;
unsigned int size;
@@ -483,6 +501,7 @@ findAtomCoveringAddress(const Normalized
// creates corresponding lld::Reference objects.
std::error_code convertRelocs(const Section §ion,
const NormalizedFile &normalizedFile,
+ bool scatterable,
MachOFile &file,
ArchHandler &handler) {
// Utility function for ArchHandler to find atom by its address.
@@ -577,9 +596,10 @@ std::error_code convertRelocs(const Sect
if (handler.isPairedReloc(reloc)) {
// Handle paired relocations together.
relocErr = handler.getPairReferenceInfo(reloc, *++it, inAtom,
- offsetInAtom, fixupAddress, swap,
- atomByAddr, atomBySymbol, &kind,
- &target, &addend);
+ offsetInAtom, fixupAddress, swap,
+ scatterable, atomByAddr,
+ atomBySymbol, &kind,
+ &target, &addend);
}
else {
// Use ArchHandler to convert relocation record into information
@@ -697,6 +717,8 @@ ErrorOr<std::unique_ptr<lld::File>>
normalizedObjectToAtoms(const NormalizedFile &normalizedFile, StringRef path,
bool copyRefs) {
std::unique_ptr<MachOFile> file(new MachOFile(path));
+ bool scatterable = ((normalizedFile.flags & MH_SUBSECTIONS_VIA_SYMBOLS) != 0);
+
// Create atoms from each section.
for (auto § : normalizedFile.sections) {
if (isDebugInfoSection(sect))
@@ -706,7 +728,7 @@ normalizedObjectToAtoms(const Normalized
customSectionName);
if (std::error_code ec =
processSection(atomType, sect, customSectionName, normalizedFile,
- *file, copyRefs))
+ *file, scatterable, copyRefs))
return ec;
}
// Create atoms from undefined symbols.
@@ -726,7 +748,8 @@ normalizedObjectToAtoms(const Normalized
for (auto § : normalizedFile.sections) {
if (isDebugInfoSection(sect))
continue;
- if (std::error_code ec = convertRelocs(sect, normalizedFile, *file, *handler))
+ if (std::error_code ec = convertRelocs(sect, normalizedFile, scatterable,
+ *file, *handler))
return ec;
}
Added: lld/trunk/test/mach-o/arm-subsections-via-symbols.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/arm-subsections-via-symbols.yaml?rev=220348&view=auto
==============================================================================
--- lld/trunk/test/mach-o/arm-subsections-via-symbols.yaml (added)
+++ lld/trunk/test/mach-o/arm-subsections-via-symbols.yaml Tue Oct 21 18:45:37 2014
@@ -0,0 +1,60 @@
+# RUN: lld -flavor darwin -arch armv7 %s -r -print_atoms -o %t | FileCheck %s
+#
+# Test that assembly written without .subsections_via_symbols is parsed so
+# that atoms are non-dead-strip and there is a layout-after references
+# chaining atoms together.
+#
+
+--- !mach-o
+arch: armv7
+file-type: MH_OBJECT
+flags: [ ]
+has-UUID: false
+OS: unknown
+sections:
+ - segment: __TEXT
+ section: __text
+ type: S_REGULAR
+ attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
+ alignment: 2
+ address: 0x0000000000000000
+ content: [ 0x04, 0x10, 0x9F, 0xE5, 0x04, 0x20, 0x9F, 0xE5,
+ 0x1E, 0xFF, 0x2F, 0xE1, 0x78, 0x56, 0x34, 0x12,
+ 0x21, 0x43, 0x65, 0x87 ]
+local-symbols:
+ - name: constants1
+ type: N_SECT
+ sect: 1
+ value: 0x000000000000000C
+ - name: constants2
+ type: N_SECT
+ sect: 1
+ value: 0x0000000000000010
+global-symbols:
+ - name: _foo
+ type: N_SECT
+ scope: [ N_EXT ]
+ sect: 1
+ value: 0x0000000000000000
+...
+
+
+# CHECK:defined-atoms:
+# CHECK: - name: _foo
+# CHECK: scope: global
+# CHECK: content: [ 04, 10, 9F, E5, 04, 20, 9F, E5, 1E, FF, 2F, E1 ]
+# CHECK: dead-strip: never
+# CHECK: references:
+# CHECK: - kind: layout-after
+# CHECK: offset: 0
+# CHECK: target: constants1
+# CHECK: - name: constants1
+# CHECK: content: [ 78, 56, 34, 12 ]
+# CHECK: dead-strip: never
+# CHECK: references:
+# CHECK: - kind: layout-after
+# CHECK: offset: 0
+# CHECK: target: constants2
+# CHECK: - name: constants2
+# CHECK: content: [ 21, 43, 65, 87 ]
+# CHECK: dead-strip: never
Modified: lld/trunk/test/mach-o/parse-data-relocs-x86_64.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/parse-data-relocs-x86_64.yaml?rev=220348&r1=220347&r2=220348&view=diff
==============================================================================
--- lld/trunk/test/mach-o/parse-data-relocs-x86_64.yaml (original)
+++ lld/trunk/test/mach-o/parse-data-relocs-x86_64.yaml Tue Oct 21 18:45:37 2014
@@ -1,3 +1,4 @@
+
# RUN: lld -flavor darwin -arch x86_64 -r %s -o %t -print_atoms | FileCheck %s \
# RUN: && lld -flavor darwin -arch x86_64 %t -r -print_atoms -o %t2 | FileCheck %s
#
@@ -36,7 +37,7 @@
--- !mach-o
arch: x86_64
file-type: MH_OBJECT
-flags: [ ]
+flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
has-UUID: false
OS: unknown
sections:
More information about the llvm-commits
mailing list