diff options
author | Lang Hames <lhames@gmail.com> | 2015-12-11 23:25:09 +0000 |
---|---|---|
committer | Lang Hames <lhames@gmail.com> | 2015-12-11 23:25:09 +0000 |
commit | ac2adce66bf223efd01e19cda94813ef93cdaddb (patch) | |
tree | 632fe0153d700eda8b629ae32f4a54fd54489f74 | |
parent | 10cf124bb920b85efcea7f7b313f7e3053f2b87c (diff) | |
download | bcm5719-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.h | 6 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/File.h | 17 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFile.h | 8 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp | 12 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp | 4 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp | 4 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp | 2 | ||||
-rw-r--r-- | lld/test/mach-o/run-tlv-pass-x86-64.yaml | 21 |
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 § : file.sections) { - if (sect.type != llvm::MachO::S_ZEROFILL) { + if (isZeroFillSection(sect.type)) + _sectInfo[§].fileOffset = 0; + else { offset = llvm::RoundUpToAlignment(offset, sect.alignment); _sectInfo[§].fileOffset = offset; offset += sect.content.size(); - } else { - _sectInfo[§].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 §ion, 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, §ion); } 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 |