forked from OSchip/llvm-project
[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
This commit is contained in:
parent
10cf124bb9
commit
ac2adce66b
|
@ -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(); }
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue