summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/lib/ReaderWriter/MachO/ArchHandler.h2
-rw-r--r--lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp5
-rw-r--r--lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp4
-rw-r--r--lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp3
-rw-r--r--lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp3
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp51
-rw-r--r--lld/test/mach-o/arm-subsections-via-symbols.yaml60
-rw-r--r--lld/test/mach-o/parse-data-relocs-x86_64.yaml3
8 files changed, 109 insertions, 22 deletions
diff --git a/lld/lib/ReaderWriter/MachO/ArchHandler.h b/lld/lib/ReaderWriter/MachO/ArchHandler.h
index 2f4a3cb18b9..0dedf81aebd 100644
--- a/lld/lib/ReaderWriter/MachO/ArchHandler.h
+++ b/lld/lib/ReaderWriter/MachO/ArchHandler.h
@@ -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,
diff --git a/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp b/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp
index 64d3fbe325e..c4fc87986a6 100644
--- a/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp
+++ b/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp
@@ -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(const normalized::Relocation &reloc1,
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(const normalized::Relocation &reloc1,
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;
diff --git a/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp b/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
index c70ee8eac90..330f1829ddd 100644
--- a/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
+++ b/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
@@ -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::getReferenceInfo(
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];
diff --git a/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp b/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp
index abc8d79619e..1d6b6c09a27 100644
--- a/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp
+++ b/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp
@@ -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(const normalized::Relocation &reloc1,
const DefinedAtom *inAtom,
uint32_t offsetInAtom,
uint64_t fixupAddress, bool swap,
+ bool scatterable,
FindAtomBySectionAndAddress atomFromAddr,
FindAtomBySymbolIndex atomFromSymbolIndex,
Reference::KindValue *kind,
diff --git a/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp b/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
index 193b3e8c8b4..352bc12b0d3 100644
--- a/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
+++ b/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
@@ -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 normalized::Relocation &reloc1,
const DefinedAtom *inAtom,
uint32_t offsetInAtom,
uint64_t fixupAddress, bool swap,
+ bool scatterable,
FindAtomBySectionAndAddress atomFromAddress,
FindAtomBySymbolIndex atomFromSymbolIndex,
Reference::KindValue *kind,
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
index 3875c6263b1..ba8a08b862d 100644
--- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
@@ -220,12 +220,12 @@ void appendSymbolsInSection(const std::vector<Symbol> &inSymbols,
void atomFromSymbol(DefinedAtom::ContentType atomType, const Section &section,
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, &section);
@@ -256,7 +256,8 @@ void atomFromSymbol(DefinedAtom::ContentType atomType, const Section &section,
std::error_code processSymboledSection(DefinedAtom::ContentType atomType,
const Section &section,
const NormalizedFile &normalizedFile,
- MachOFile &file, bool copyRefs) {
+ MachOFile &file, bool scatterable,
+ bool copyRefs) {
// Find section's index.
uint32_t sectIndex = 1;
for (auto &sect : normalizedFile.sections) {
@@ -309,13 +310,14 @@ std::error_code processSymboledSection(DefinedAtom::ContentType atomType,
// 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(DefinedAtom::ContentType atomType,
|| !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(DefinedAtom::ContentType atomType,
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(DefinedAtom::ContentType atomType,
const Section &section,
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(DefinedAtom::ContentType atomType,
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 NormalizedFile &normalizedFile, MachOFile &file,
// creates corresponding lld::Reference objects.
std::error_code convertRelocs(const Section &section,
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 Section &section,
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 &sect : normalizedFile.sections) {
if (isDebugInfoSection(sect))
@@ -706,7 +728,7 @@ normalizedObjectToAtoms(const NormalizedFile &normalizedFile, StringRef path,
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 NormalizedFile &normalizedFile, StringRef path,
for (auto &sect : 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;
}
diff --git a/lld/test/mach-o/arm-subsections-via-symbols.yaml b/lld/test/mach-o/arm-subsections-via-symbols.yaml
new file mode 100644
index 00000000000..b704568f37b
--- /dev/null
+++ b/lld/test/mach-o/arm-subsections-via-symbols.yaml
@@ -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
diff --git a/lld/test/mach-o/parse-data-relocs-x86_64.yaml b/lld/test/mach-o/parse-data-relocs-x86_64.yaml
index 6ba2e48d285..ae93c1bb75d 100644
--- a/lld/test/mach-o/parse-data-relocs-x86_64.yaml
+++ b/lld/test/mach-o/parse-data-relocs-x86_64.yaml
@@ -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:
OpenPOWER on IntegriCloud