summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLang Hames <lhames@gmail.com>2015-12-11 23:25:09 +0000
committerLang Hames <lhames@gmail.com>2015-12-11 23:25:09 +0000
commitac2adce66bf223efd01e19cda94813ef93cdaddb (patch)
tree632fe0153d700eda8b629ae32f4a54fd54489f74
parent10cf124bb920b85efcea7f7b313f7e3053f2b87c (diff)
downloadbcm5719-llvm-ac2adce66bf223efd01e19cda94813ef93cdaddb.tar.gz
bcm5719-llvm-ac2adce66bf223efd01e19cda94813ef93cdaddb.zip
[lld][MachO] Recognize __thread_bss sections as zero-fill and set all the
appropriate bits. This fixes the remaining clang regression test failures when linking clang with lld on Darwin. llvm-svn: 255390
-rw-r--r--lld/lib/ReaderWriter/MachO/Atoms.h6
-rw-r--r--lld/lib/ReaderWriter/MachO/File.h17
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFile.h8
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp12
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp4
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp4
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp2
-rw-r--r--lld/test/mach-o/run-tlv-pass-x86-64.yaml21
8 files changed, 55 insertions, 19 deletions
diff --git a/lld/lib/ReaderWriter/MachO/Atoms.h b/lld/lib/ReaderWriter/MachO/Atoms.h
index a143df2848f..9f2e5acad99 100644
--- a/lld/lib/ReaderWriter/MachO/Atoms.h
+++ b/lld/lib/ReaderWriter/MachO/Atoms.h
@@ -25,11 +25,11 @@ public:
// Constructor for zero-fill content
MachODefinedAtom(const File &f, const StringRef name, Scope scope,
- uint64_t size, bool noDeadStrip, Alignment align)
+ ContentType type, uint64_t size, bool noDeadStrip,
+ Alignment align)
: SimpleDefinedAtom(f), _name(name),
_content(ArrayRef<uint8_t>(nullptr, size)), _align(align),
- _contentType(DefinedAtom::typeZeroFill),
- _scope(scope), _merge(mergeNo), _thumb(false),
+ _contentType(type), _scope(scope), _merge(mergeNo), _thumb(false),
_noDeadStrip(noDeadStrip) {}
uint64_t size() const override { return _content.size(); }
diff --git a/lld/lib/ReaderWriter/MachO/File.h b/lld/lib/ReaderWriter/MachO/File.h
index e9f2eed23a4..c97dfa142b8 100644
--- a/lld/lib/ReaderWriter/MachO/File.h
+++ b/lld/lib/ReaderWriter/MachO/File.h
@@ -87,9 +87,22 @@ public:
DefinedAtom::Alignment align(
inSection->alignment,
sectionOffset % inSection->alignment);
+
+ DefinedAtom::ContentType type = DefinedAtom::typeUnknown;
+ switch (inSection->type) {
+ case llvm::MachO::S_ZEROFILL:
+ type = DefinedAtom::typeZeroFill;
+ break;
+ case llvm::MachO::S_THREAD_LOCAL_ZEROFILL:
+ type = DefinedAtom::typeTLVInitialZeroFill;
+ break;
+ default:
+ llvm_unreachable("Unrecognized zero-fill section");
+ }
+
auto *atom =
- new (allocator()) MachODefinedAtom(*this, name, scope, size, noDeadStrip,
- align);
+ new (allocator()) MachODefinedAtom(*this, name, scope, type, size,
+ noDeadStrip, align);
addAtomForSection(inSection, atom, sectionOffset);
}
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h b/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h
index c5f8fbc2b18..7b55fdd17bc 100644
--- a/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h
+++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h
@@ -142,6 +142,14 @@ struct Symbol {
Hex64 value;
};
+/// Check whether the given section type indicates a zero-filled section.
+// FIXME: Utility functions of this kind should probably be moved into
+// llvm/Support.
+inline bool isZeroFillSection(SectionType T) {
+ return (T == llvm::MachO::S_ZEROFILL ||
+ T == llvm::MachO::S_THREAD_LOCAL_ZEROFILL);
+}
+
/// A typedef so that YAML I/O can (de/en)code the protection bits of a segment.
LLVM_YAML_STRONG_TYPEDEF(uint32_t, VMProtect)
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
index 45dea1c2742..4ecfece0629 100644
--- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
@@ -289,12 +289,12 @@ MachOFileLayout::MachOFileLayout(const NormalizedFile &file)
unsigned relocCount = 0;
uint64_t offset = _startOfSectionsContent;
for (const Section &sect : file.sections) {
- if (sect.type != llvm::MachO::S_ZEROFILL) {
+ if (isZeroFillSection(sect.type))
+ _sectInfo[&sect].fileOffset = 0;
+ else {
offset = llvm::RoundUpToAlignment(offset, sect.alignment);
_sectInfo[&sect].fileOffset = offset;
offset += sect.content.size();
- } else {
- _sectInfo[&sect].fileOffset = 0;
}
relocCount += sect.relocations.size();
}
@@ -530,7 +530,7 @@ void MachOFileLayout::buildFileOffsets() {
for (const Section *s : _segInfo[&sg].sections) {
uint32_t sectOffset = s->address - sg.address;
uint32_t sectFileSize =
- s->type == llvm::MachO::S_ZEROFILL ? 0 : s->content.size();
+ isZeroFillSection(s->type) ? 0 : s->content.size();
segFileSize = std::max(segFileSize, sectOffset + sectFileSize);
_sectInfo[s].fileOffset = _segInfo[&sg].fileOffset + sectOffset;
@@ -655,7 +655,7 @@ std::error_code MachOFileLayout::writeSegmentLoadCommands(uint8_t *&lc) {
setString16(section->segmentName, sect->segname);
sect->addr = section->address;
sect->size = section->content.size();
- if (section->type == llvm::MachO::S_ZEROFILL)
+ if (isZeroFillSection(section->type))
sect->offset = 0;
else
sect->offset = section->address - seg.address + segInfo.fileOffset;
@@ -883,7 +883,7 @@ std::error_code MachOFileLayout::writeLoadCommands() {
void MachOFileLayout::writeSectionContent() {
for (const Section &s : _file.sections) {
// Copy all section content to output buffer.
- if (s.type == llvm::MachO::S_ZEROFILL)
+ if (isZeroFillSection(s.type))
continue;
if (s.content.empty())
continue;
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
index d6e0c922686..f80e2ac467f 100644
--- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
@@ -253,6 +253,8 @@ const MachOFinalSectionFromAtomType sectsToAtomType[] = {
typeTLVInitialData),
ENTRY("__DATA", "__thread_ptrs", S_THREAD_LOCAL_VARIABLE_POINTERS,
typeTLVInitializerPtr),
+ ENTRY("__DATA", "__thread_bss", S_THREAD_LOCAL_ZEROFILL,
+ typeTLVInitialZeroFill),
ENTRY("__DATA", "__bss", S_ZEROFILL, typeZeroFill),
ENTRY("__DATA", "__interposing", S_INTERPOSING, typeInterposingTuples),
};
@@ -582,7 +584,7 @@ void Util::copySectionContent(NormalizedFile &file) {
for (SectionInfo *si : _sectionInfos) {
Section *normSect = &file.sections[si->normalizedSectionIndex];
- if (si->type == llvm::MachO::S_ZEROFILL) {
+ if (isZeroFillSection(si->type)) {
const uint8_t *empty = nullptr;
normSect->content = llvm::makeArrayRef(empty, si->size);
continue;
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
index 649bd542415..7ed79555722 100644
--- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
@@ -82,6 +82,8 @@ const MachORelocatableSectionToAtomType sectsToAtomType[] = {
ENTRY("__DATA", "__thread_vars", S_THREAD_LOCAL_VARIABLES,
typeThunkTLV),
ENTRY("__DATA", "__thread_data", S_THREAD_LOCAL_REGULAR, typeTLVInitialData),
+ ENTRY("__DATA", "__thread_bss", S_THREAD_LOCAL_ZEROFILL,
+ typeTLVInitialZeroFill),
ENTRY("", "", S_INTERPOSING, typeInterposingTuples),
ENTRY("__LD", "__compact_unwind", S_REGULAR,
typeCompactUnwindInfo),
@@ -232,7 +234,7 @@ void atomFromSymbol(DefinedAtom::ContentType atomType, const Section &section,
uint64_t size = nextSymbolAddr - symbolAddr;
uint64_t offset = symbolAddr - section.address;
bool noDeadStrip = (symbolDescFlags & N_NO_DEAD_STRIP) || !scatterable;
- if (section.type == llvm::MachO::S_ZEROFILL) {
+ if (isZeroFillSection(section.type)) {
file.addZeroFillDefinedAtom(symbolName, symbolScope, offset, size,
noDeadStrip, copyRefs, &section);
} else {
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp
index a653c5f38c8..0b92a68eeae 100644
--- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp
@@ -278,7 +278,7 @@ struct MappingTraits<Section> {
io.mapOptional("attributes", sect.attributes);
io.mapOptional("alignment", sect.alignment, (uint16_t)1);
io.mapRequired("address", sect.address);
- if (sect.type == llvm::MachO::S_ZEROFILL) {
+ if (isZeroFillSection(sect.type)) {
// S_ZEROFILL sections use "size:" instead of "content:"
uint64_t size = sect.content.size();
io.mapOptional("size", size);
diff --git a/lld/test/mach-o/run-tlv-pass-x86-64.yaml b/lld/test/mach-o/run-tlv-pass-x86-64.yaml
index 74400a14365..0e648458645 100644
--- a/lld/test/mach-o/run-tlv-pass-x86-64.yaml
+++ b/lld/test/mach-o/run-tlv-pass-x86-64.yaml
@@ -1,6 +1,7 @@
# RUN: lld -flavor darwin -macosx_version_min 10.7 -arch x86_64 -print_atoms %s -o %t | FileCheck %s
# RUN: not lld -flavor darwin -macosx_version_min 10.6 -arch x86_64 -o %t %s 2> %t2
# RUN: FileCheck < %t2 %s --check-prefix=CHECK-ERROR
+# RUN: llvm-objdump -macho -private-headers %t | FileCheck %s --check-prefix=CHECK-LOADCMDS
#
# Test parsing of x86_64 tlv relocations.
@@ -30,12 +31,12 @@ sections:
extern: true
symbol: 2
- segment: __DATA
- section: __thread_data
- type: S_THREAD_LOCAL_REGULAR
+ section: __thread_bss
+ type: S_THREAD_LOCAL_ZEROFILL
attributes: [ ]
alignment: 4
address: 0x0000000000000014
- content: [ 0x07, 0x00, 0x00, 0x00 ]
+ size: 4
- segment: __DATA
section: __thread_vars
type: S_THREAD_LOCAL_VARIABLES
@@ -111,8 +112,8 @@ page-size: 0x00000000
# CHECK-NEXT: - kind: tlvInitSectionOffset
# CHECK-NEXT: offset: 16
# CHECK-NEXT: target: '_x$tlv$init'
-# CHECK-NEXT: - name: '_x$tlv$init'
-# CHECK-NEXT: type: tlv-data
+# CHECK: - name: '_x$tlv$init'
+# CHECK-NEXT: type: tlv-zero-fill
# CHECK: - name: _main
# CHECK-NOT: - name:
# CHECK: references:
@@ -131,3 +132,13 @@ page-size: 0x00000000
# CHECK-NEXT: target: _x
# CHECK-ERROR: targeted OS version does not support use of thread local variables in _main for architecture x86_64
+
+# CHECK-LOADCMDS: sectname __thread_bss
+# CHECK-LOADCMDS: segname __DATA
+# CHECK-LOADCMDS: addr 0x{{[0-9A-F]*}}
+# CHECK-LOADCMDS: size 0x0000000000000004
+# CHECK-LOADCMDS: offset 0
+# CHECK-LOADCMDS: align 2^2 (4)
+# CHECK-LOADCMDS: reloff 0
+# CHECK-LOADCMDS: nreloc 0
+# CHECK-LOADCMDS: type S_THREAD_LOCAL_ZEROFILL
OpenPOWER on IntegriCloud