[lld] f6b6e72 - [lld-macho] Factor out common InputSection members
Jez Ng via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 1 18:23:05 PDT 2021
Author: Jez Ng
Date: 2021-07-01T21:22:39-04:00
New Revision: f6b6e7214366fc12469aba2fe16495e5f7a375a6
URL: https://github.com/llvm/llvm-project/commit/f6b6e7214366fc12469aba2fe16495e5f7a375a6
DIFF: https://github.com/llvm/llvm-project/commit/f6b6e7214366fc12469aba2fe16495e5f7a375a6.diff
LOG: [lld-macho] Factor out common InputSection members
We have been creating many ConcatInputSections with identical values due
to .subsections_via_symbols. This diff factors out the identical values
into a Shared struct, to reduce memory consumption and make copying
cheaper.
I also changed `callSiteCount` from a uint32_t to a 31-bit field to save an
extra word.
All in all, this takes InputSection from 120 to 72 bytes (and
ConcatInputSection from 160 to 112 bytes), i.e. 30% size reduction in
ConcatInputSection.
Numbers for linking chromium_framework on my 3.2 GHz 16-Core Intel Xeon W:
N Min Max Median Avg Stddev
x 20 4.14 4.24 4.18 4.183 0.027548999
+ 20 4.04 4.11 4.075 4.0775 0.018027756
Difference at 95.0% confidence
-0.1055 +/- 0.0149005
-2.52211% +/- 0.356215%
(Student's t, pooled s = 0.0232803)
Reviewed By: #lld-macho, thakis
Differential Revision: https://reviews.llvm.org/D105305
Added:
Modified:
lld/MachO/ConcatOutputSection.cpp
lld/MachO/Driver.cpp
lld/MachO/Dwarf.cpp
lld/MachO/ICF.cpp
lld/MachO/InputFiles.cpp
lld/MachO/InputSection.cpp
lld/MachO/InputSection.h
lld/MachO/MarkLive.cpp
lld/MachO/SymbolTable.cpp
lld/MachO/Symbols.h
lld/MachO/SyntheticSections.cpp
lld/MachO/UnwindInfoSection.cpp
lld/MachO/Writer.cpp
Removed:
################################################################################
diff --git a/lld/MachO/ConcatOutputSection.cpp b/lld/MachO/ConcatOutputSection.cpp
index 1c3c055b8930..99e4558ab82f 100644
--- a/lld/MachO/ConcatOutputSection.cpp
+++ b/lld/MachO/ConcatOutputSection.cpp
@@ -27,7 +27,7 @@ using namespace lld::macho;
void ConcatOutputSection::addInput(ConcatInputSection *input) {
if (inputs.empty()) {
align = input->align;
- flags = input->flags;
+ flags = input->getFlags();
} else {
align = std::max(align, input->align);
finalizeFlags(input);
@@ -288,7 +288,8 @@ void ConcatOutputSection::finalize() {
// unfinalized inputs[finalIdx].
fatal(Twine(__FUNCTION__) + ": FIXME: thunk range overrun");
}
- thunkInfo.isec = make<ConcatInputSection>(isec->segname, isec->name);
+ thunkInfo.isec =
+ make<ConcatInputSection>(isec->getSegName(), isec->getName());
thunkInfo.isec->parent = this;
StringRef thunkName = saver.save(funcSym->getName() + ".thunk." +
std::to_string(thunkInfo.sequence++));
@@ -332,8 +333,7 @@ void ConcatOutputSection::writeTo(uint8_t *buf) const {
}
void ConcatOutputSection::finalizeFlags(InputSection *input) {
- uint8_t inputType = input->flags & SECTION_TYPE;
- switch (inputType) {
+ switch (sectionType(input->getFlags())) {
default /*type-unspec'ed*/:
// FIXME: Add additional logics here when supporting emitting obj files.
break;
@@ -351,7 +351,7 @@ void ConcatOutputSection::finalizeFlags(InputSection *input) {
case S_THREAD_LOCAL_VARIABLE_POINTERS:
case S_NON_LAZY_SYMBOL_POINTERS:
case S_SYMBOL_STUBS:
- flags |= input->flags;
+ flags |= input->getFlags();
break;
}
}
diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index a64d34ba5689..5a17941e5dff 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -546,20 +546,19 @@ static void replaceCommonSymbols() {
if (common == nullptr)
continue;
- auto *isec =
- make<ConcatInputSection>(segment_names::data, section_names::common);
- isec->file = common->getFile();
- isec->align = common->align;
// Casting to size_t will truncate large values on 32-bit architectures,
// but it's not really worth supporting the linking of 64-bit programs on
// 32-bit archs.
- isec->data = {nullptr, static_cast<size_t>(common->size)};
- isec->flags = S_ZEROFILL;
+ ArrayRef<uint8_t> data = {nullptr, static_cast<size_t>(common->size)};
+ auto *isec = make<ConcatInputSection>(
+ segment_names::data, section_names::common, common->getFile(), data,
+ common->align, S_ZEROFILL);
inputSections.push_back(isec);
// FIXME: CommonSymbol should store isReferencedDynamically, noDeadStrip
// and pass them on here.
- replaceSymbol<Defined>(sym, sym->getName(), isec->file, isec, /*value=*/0,
+ replaceSymbol<Defined>(sym, sym->getName(), isec->getFile(), isec,
+ /*value=*/0,
/*size=*/0,
/*isWeakDef=*/false,
/*isExternal=*/true, common->privateExtern,
@@ -994,8 +993,8 @@ static void gatherInputSections() {
if (auto *isec = dyn_cast<ConcatInputSection>(entry.isec)) {
if (isec->isCoalescedWeak())
continue;
- if (isec->segname == segment_names::ld) {
- assert(isec->name == section_names::compactUnwind);
+ if (isec->getSegName() == segment_names::ld) {
+ assert(isec->getName() == section_names::compactUnwind);
in.unwindInfo->addInput(isec);
continue;
}
diff --git a/lld/MachO/Dwarf.cpp b/lld/MachO/Dwarf.cpp
index 29b39ddf6416..c142cc1b169f 100644
--- a/lld/MachO/Dwarf.cpp
+++ b/lld/MachO/Dwarf.cpp
@@ -27,7 +27,7 @@ std::unique_ptr<DwarfObject> DwarfObject::create(ObjFile *obj) {
// ourselves.
for (const InputSection *isec : obj->debugSections) {
if (StringRef *s =
- StringSwitch<StringRef *>(isec->name)
+ StringSwitch<StringRef *>(isec->getName())
.Case(section_names::debugInfo, &dObj->infoSection.Data)
.Case(section_names::debugAbbrev, &dObj->abbrevSection)
.Case(section_names::debugStr, &dObj->strSection)
diff --git a/lld/MachO/ICF.cpp b/lld/MachO/ICF.cpp
index fbd7cb36514f..a27a0f5accbd 100644
--- a/lld/MachO/ICF.cpp
+++ b/lld/MachO/ICF.cpp
@@ -88,7 +88,7 @@ static bool equalsConstant(const ConcatInputSection *ia,
return false;
if (ia->data != ib->data)
return false;
- if (ia->flags != ib->flags)
+ if (ia->getFlags() != ib->getFlags())
return false;
if (ia->relocs.size() != ib->relocs.size())
return false;
diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp
index 6caf48232ad9..b8c8b0956421 100644
--- a/lld/MachO/InputFiles.cpp
+++ b/lld/MachO/InputFiles.cpp
@@ -295,8 +295,8 @@ void ObjFile::parseSections(ArrayRef<Section> sections) {
} else {
auto *isec =
make<ConcatInputSection>(segname, name, this, data, align, flags);
- if (!(isDebugSection(isec->flags) &&
- isec->segname == segment_names::dwarf)) {
+ if (!(isDebugSection(isec->getFlags()) &&
+ isec->getSegName() == segment_names::dwarf)) {
subsections.push_back({{0, isec}});
} else {
// Instead of emitting DWARF sections, we emit STABS symbols to the
@@ -522,7 +522,7 @@ static macho::Symbol *createDefined(const NList &sym, StringRef name,
isPrivateExtern = true;
return symtab->addDefined(
- name, isec->file, isec, value, size, sym.n_desc & N_WEAK_DEF,
+ name, isec->getFile(), isec, value, size, sym.n_desc & N_WEAK_DEF,
isPrivateExtern, sym.n_desc & N_ARM_THUMB_DEF,
sym.n_desc & REFERENCED_DYNAMICALLY, sym.n_desc & N_NO_DEAD_STRIP);
}
@@ -530,7 +530,7 @@ static macho::Symbol *createDefined(const NList &sym, StringRef name,
assert(!isWeakDefCanBeHidden &&
"weak_def_can_be_hidden on already-hidden symbol?");
return make<Defined>(
- name, isec->file, isec, value, size, sym.n_desc & N_WEAK_DEF,
+ name, isec->getFile(), isec, value, size, sym.n_desc & N_WEAK_DEF,
/*isExternal=*/false, /*isPrivateExtern=*/false,
sym.n_desc & N_ARM_THUMB_DEF, sym.n_desc & REFERENCED_DYNAMICALLY,
sym.n_desc & N_NO_DEAD_STRIP);
@@ -672,7 +672,7 @@ void ObjFile::parseSymbols(ArrayRef<typename LP::section> sectionHeaders,
auto *nextIsec = make<ConcatInputSection>(*concatIsec);
nextIsec->numRefs = 0;
nextIsec->wasCoalesced = false;
- if (isZeroFill(isec->flags)) {
+ if (isZeroFill(isec->getFlags())) {
// Zero-fill sections have NULL data.data() non-zero data.size()
nextIsec->data = {nullptr, isec->data.size() - symbolOffset};
isec->data = {nullptr, symbolOffset};
@@ -698,11 +698,11 @@ void ObjFile::parseSymbols(ArrayRef<typename LP::section> sectionHeaders,
OpaqueFile::OpaqueFile(MemoryBufferRef mb, StringRef segName,
StringRef sectName)
: InputFile(OpaqueKind, mb) {
- ConcatInputSection *isec =
- make<ConcatInputSection>(segName.take_front(16), sectName.take_front(16));
- isec->file = this;
const auto *buf = reinterpret_cast<const uint8_t *>(mb.getBufferStart());
- isec->data = {buf, mb.getBufferSize()};
+ ArrayRef<uint8_t> data = {buf, mb.getBufferSize()};
+ ConcatInputSection *isec =
+ make<ConcatInputSection>(segName.take_front(16), sectName.take_front(16),
+ /*file=*/this, data);
isec->live = true;
subsections.push_back({{0, isec}});
}
diff --git a/lld/MachO/InputSection.cpp b/lld/MachO/InputSection.cpp
index 5f1eab349ba5..5762e4ef59f0 100644
--- a/lld/MachO/InputSection.cpp
+++ b/lld/MachO/InputSection.cpp
@@ -28,7 +28,7 @@ using namespace lld::macho;
std::vector<ConcatInputSection *> macho::inputSections;
uint64_t InputSection::getFileSize() const {
- return isZeroFill(flags) ? 0 : getSize();
+ return isZeroFill(getFlags()) ? 0 : getSize();
}
uint64_t InputSection::getVA(uint64_t off) const {
@@ -49,7 +49,7 @@ static uint64_t resolveSymbolVA(const Symbol *sym, uint8_t type) {
// ICF needs to hash any section that might potentially be duplicated so
// that it can match on content rather than identity.
bool ConcatInputSection::isHashableForICF() const {
- switch (sectionType(flags)) {
+ switch (sectionType(getFlags())) {
case S_REGULAR:
return true;
case S_CSTRING_LITERALS:
@@ -127,7 +127,7 @@ void ConcatInputSection::writeTo(uint8_t *buf) {
target->relaxGotLoad(loc, r.type);
referentVA = resolveSymbolVA(referentSym, r.type) + r.addend;
- if (isThreadLocalVariables(flags)) {
+ if (isThreadLocalVariables(getFlags())) {
// References from thread-local variable sections are treated as offsets
// relative to the start of the thread-local data memory area, which
// is initialized via copying all the TLV data sections (which are all
@@ -203,7 +203,7 @@ WordLiteralInputSection::WordLiteralInputSection(StringRef segname,
uint64_t WordLiteralInputSection::getOffset(uint64_t off) const {
auto *osec = cast<WordLiteralSection>(parent);
const uint8_t *buf = data.data();
- switch (sectionType(flags)) {
+ switch (sectionType(getFlags())) {
case S_4BYTE_LITERALS:
return osec->getLiteral4Offset(buf + off);
case S_8BYTE_LITERALS:
@@ -216,16 +216,16 @@ uint64_t WordLiteralInputSection::getOffset(uint64_t off) const {
}
bool macho::isCodeSection(const InputSection *isec) {
- uint32_t type = sectionType(isec->flags);
+ uint32_t type = sectionType(isec->getFlags());
if (type != S_REGULAR && type != S_COALESCED)
return false;
- uint32_t attr = isec->flags & SECTION_ATTRIBUTES_USR;
+ uint32_t attr = isec->getFlags() & SECTION_ATTRIBUTES_USR;
if (attr == S_ATTR_PURE_INSTRUCTIONS)
return true;
- if (isec->segname == segment_names::text)
- return StringSwitch<bool>(isec->name)
+ if (isec->getSegName() == segment_names::text)
+ return StringSwitch<bool>(isec->getName())
.Cases(section_names::textCoalNt, section_names::staticInit, true)
.Default(false);
@@ -233,10 +233,10 @@ bool macho::isCodeSection(const InputSection *isec) {
}
bool macho::isCfStringSection(const InputSection *isec) {
- return isec->name == section_names::cfString &&
- isec->segname == segment_names::data;
+ return isec->getName() == section_names::cfString &&
+ isec->getSegName() == segment_names::data;
}
std::string lld::toString(const InputSection *isec) {
- return (toString(isec->file) + ":(" + isec->name + ")").str();
+ return (toString(isec->getFile()) + ":(" + isec->getName() + ")").str();
}
diff --git a/lld/MachO/InputSection.h b/lld/MachO/InputSection.h
index a7d8b6e29fcf..a10457087043 100644
--- a/lld/MachO/InputSection.h
+++ b/lld/MachO/InputSection.h
@@ -13,6 +13,7 @@
#include "Relocations.h"
#include "lld/Common/LLVM.h"
+#include "lld/Common/Memory.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/CachedHashString.h"
@@ -33,9 +34,13 @@ class InputSection {
WordLiteralKind,
};
- Kind kind() const { return sectionKind; }
+ Kind kind() const { return shared->sectionKind; }
virtual ~InputSection() = default;
virtual uint64_t getSize() const { return data.size(); }
+ InputFile *getFile() const { return shared->file; }
+ StringRef getName() const { return shared->name; }
+ StringRef getSegName() const { return shared->segname; }
+ uint32_t getFlags() const { return shared->flags; }
uint64_t getFileSize() const;
// Translates \p off -- an offset relative to this InputSection -- into an
// offset from the beginning of its parent OutputSection.
@@ -47,33 +52,43 @@ class InputSection {
virtual void markLive(uint64_t off) = 0;
virtual InputSection *canonical() { return this; }
- InputFile *file = nullptr;
- StringRef name;
- StringRef segname;
-
OutputSection *parent = nullptr;
uint32_t align = 1;
- uint32_t flags = 0;
- uint32_t callSiteCount = 0;
-
+ uint32_t callSiteCount : 31;
// is address assigned?
- bool isFinal = false;
+ uint32_t isFinal : 1;
ArrayRef<uint8_t> data;
std::vector<Reloc> relocs;
protected:
+ // The fields in this struct are immutable. Since we create a lot of
+ // InputSections with identical values for them (due to
+ // .subsections_via_symbols), factoring them out into a shared struct reduces
+ // memory consumption and makes copying cheaper.
+ struct Shared {
+ InputFile *file;
+ StringRef name;
+ StringRef segname;
+ uint32_t flags;
+ Kind sectionKind;
+ Shared(InputFile *file, StringRef name, StringRef segname, uint32_t flags,
+ Kind kind)
+ : file(file), name(name), segname(segname), flags(flags),
+ sectionKind(kind) {}
+ };
+
InputSection(Kind kind, StringRef segname, StringRef name)
- : name(name), segname(segname), sectionKind(kind) {}
+ : callSiteCount(0), isFinal(false),
+ shared(make<Shared>(nullptr, name, segname, 0, kind)) {}
InputSection(Kind kind, StringRef segname, StringRef name, InputFile *file,
ArrayRef<uint8_t> data, uint32_t align, uint32_t flags)
- : file(file), name(name), segname(segname), align(align), flags(flags),
- data(data), sectionKind(kind) {}
+ : align(align), callSiteCount(0), isFinal(false), data(data),
+ shared(make<Shared>(file, name, segname, flags, kind)) {}
-private:
- Kind sectionKind;
+ const Shared *const shared;
};
// ConcatInputSections are combined into (Concat)OutputSections through simple
@@ -85,7 +100,8 @@ class ConcatInputSection final : public InputSection {
: InputSection(ConcatKind, segname, name) {}
ConcatInputSection(StringRef segname, StringRef name, InputFile *file,
- ArrayRef<uint8_t> data, uint32_t align, uint32_t flags)
+ ArrayRef<uint8_t> data, uint32_t align = 1,
+ uint32_t flags = 0)
: InputSection(ConcatKind, segname, name, file, data, align, flags) {}
uint64_t getOffset(uint64_t off) const override { return outSecOff + off; }
@@ -128,6 +144,11 @@ class ConcatInputSection final : public InputSection {
uint64_t outSecOff = 0;
};
+// Verify ConcatInputSection's size on 64-bit builds.
+static_assert(sizeof(int) != 8 || sizeof(ConcatInputSection) == 112,
+ "Try to minimize ConcatInputSection's size, we create many "
+ "instances of it");
+
// Helper functions to make it easy to sprinkle asserts.
inline bool shouldOmitFromOutput(InputSection *isec) {
diff --git a/lld/MachO/MarkLive.cpp b/lld/MachO/MarkLive.cpp
index 7962ff9b094a..8e2c1aa47292 100644
--- a/lld/MachO/MarkLive.cpp
+++ b/lld/MachO/MarkLive.cpp
@@ -103,14 +103,14 @@ void markLive() {
addSym(stubBinder);
for (ConcatInputSection *isec : inputSections) {
// Sections marked no_dead_strip
- if (isec->flags & S_ATTR_NO_DEAD_STRIP) {
+ if (isec->getFlags() & S_ATTR_NO_DEAD_STRIP) {
enqueue(isec, 0);
continue;
}
// mod_init_funcs, mod_term_funcs sections
- if (sectionType(isec->flags) == S_MOD_INIT_FUNC_POINTERS ||
- sectionType(isec->flags) == S_MOD_TERM_FUNC_POINTERS) {
+ if (sectionType(isec->getFlags()) == S_MOD_INIT_FUNC_POINTERS ||
+ sectionType(isec->getFlags()) == S_MOD_TERM_FUNC_POINTERS) {
enqueue(isec, 0);
continue;
}
@@ -161,7 +161,7 @@ void markLive() {
for (ConcatInputSection *isec : inputSections) {
// FIXME: Check if copying all S_ATTR_LIVE_SUPPORT sections into a
// separate vector and only walking that here is faster.
- if (!(isec->flags & S_ATTR_LIVE_SUPPORT) || isec->live)
+ if (!(isec->getFlags() & S_ATTR_LIVE_SUPPORT) || isec->live)
continue;
for (const Reloc &r : isec->relocs) {
diff --git a/lld/MachO/SymbolTable.cpp b/lld/MachO/SymbolTable.cpp
index c0ae11bfd2f0..b2a6046e81cf 100644
--- a/lld/MachO/SymbolTable.cpp
+++ b/lld/MachO/SymbolTable.cpp
@@ -54,7 +54,7 @@ Defined *SymbolTable::addDefined(StringRef name, InputFile *file,
std::tie(s, wasInserted) = insert(name, file);
assert(!isWeakDef || (isa<BitcodeFile>(file) && !isec) ||
- (isa<ObjFile>(file) && file == isec->file));
+ (isa<ObjFile>(file) && file == isec->getFile()));
if (!wasInserted) {
if (auto *defined = dyn_cast<Defined>(s)) {
diff --git a/lld/MachO/Symbols.h b/lld/MachO/Symbols.h
index 3d3c84c79952..c30fbb9d6885 100644
--- a/lld/MachO/Symbols.h
+++ b/lld/MachO/Symbols.h
@@ -129,7 +129,7 @@ class Defined : public Symbol {
return isWeakDef() && isExternal() && !privateExtern;
}
bool isTlv() const override {
- return !isAbsolute() && isThreadLocalVariables(isec->flags);
+ return !isAbsolute() && isThreadLocalVariables(isec->getFlags());
}
bool isExternal() const { return external; }
diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp
index 07406650dfd8..2a409bfcfa11 100644
--- a/lld/MachO/SyntheticSections.cpp
+++ b/lld/MachO/SyntheticSections.cpp
@@ -746,7 +746,7 @@ void SymtabSection::emitStabs() {
if (defined->isAbsolute())
continue;
InputSection *isec = defined->isec;
- ObjFile *file = dyn_cast_or_null<ObjFile>(isec->file);
+ ObjFile *file = dyn_cast_or_null<ObjFile>(isec->getFile());
if (!file || !file->compileUnit)
continue;
symbolsNeedingStabs.push_back(defined);
@@ -754,7 +754,7 @@ void SymtabSection::emitStabs() {
}
llvm::stable_sort(symbolsNeedingStabs, [&](Defined *a, Defined *b) {
- return a->isec->file->id < b->isec->file->id;
+ return a->isec->getFile()->id < b->isec->getFile()->id;
});
// Emit STABS symbols so that dsymutil and/or the debugger can map address
@@ -763,7 +763,7 @@ void SymtabSection::emitStabs() {
InputFile *lastFile = nullptr;
for (Defined *defined : symbolsNeedingStabs) {
InputSection *isec = defined->isec;
- ObjFile *file = cast<ObjFile>(isec->file);
+ ObjFile *file = cast<ObjFile>(isec->getFile());
if (lastFile == nullptr || lastFile != file) {
if (lastFile != nullptr)
@@ -1264,7 +1264,7 @@ void WordLiteralSection::finalizeContents() {
// finalized.
isec->isFinal = true;
const uint8_t *buf = isec->data.data();
- switch (sectionType(isec->flags)) {
+ switch (sectionType(isec->getFlags())) {
case S_4BYTE_LITERALS: {
for (size_t off = 0, e = isec->data.size(); off < e; off += 4) {
if (!isec->isLive(off))
diff --git a/lld/MachO/UnwindInfoSection.cpp b/lld/MachO/UnwindInfoSection.cpp
index 567e18a607e2..5c9c5e03d1c1 100644
--- a/lld/MachO/UnwindInfoSection.cpp
+++ b/lld/MachO/UnwindInfoSection.cpp
@@ -142,8 +142,8 @@ void UnwindInfoSection::prepareRelocations() {
template <class Ptr>
void UnwindInfoSectionImpl<Ptr>::addInput(ConcatInputSection *isec) {
- assert(isec->segname == segment_names::ld &&
- isec->name == section_names::compactUnwind);
+ assert(isec->getSegName() == segment_names::ld &&
+ isec->getName() == section_names::compactUnwind);
compactUnwindSection->addInput(isec);
}
@@ -220,7 +220,7 @@ void UnwindInfoSectionImpl<Ptr>::prepareRelocations(ConcatInputSection *isec) {
// the exact addresses that it references. So it is safe for compact unwind to
// reference addresses in __TEXT, but not addresses in any other segment.
static ConcatInputSection *checkTextSegment(InputSection *isec) {
- if (isec->segname != segment_names::text)
+ if (isec->getSegName() != segment_names::text)
error("compact unwind references address in " + toString(isec) +
" which is not in segment __TEXT");
// __text should always be a ConcatInputSection.
diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp
index 7e3dc70cd18d..874708e376a7 100644
--- a/lld/MachO/Writer.cpp
+++ b/lld/MachO/Writer.cpp
@@ -582,7 +582,7 @@ static void prepareSymbolRelocation(Symbol *sym, const InputSection *isec,
// References from thread-local variable sections are treated as offsets
// relative to the start of the referent section, and therefore have no
// need of rebase opcodes.
- if (!(isThreadLocalVariables(isec->flags) && isa<Defined>(sym)))
+ if (!(isThreadLocalVariables(isec->getFlags()) && isa<Defined>(sym)))
addNonLazyBindingEntries(sym, isec, r.offset, r.addend);
}
}
@@ -802,7 +802,8 @@ static DenseMap<const InputSection *, size_t> buildInputSectionPriorities() {
SymbolPriorityEntry &entry = it->second;
size_t &priority = sectionPriorities[sym.isec];
- priority = std::max(priority, getSymbolPriority(entry, sym.isec->file));
+ priority =
+ std::max(priority, getSymbolPriority(entry, sym.isec->getFile()));
};
// TODO: Make sure this handles weak symbols correctly.
@@ -889,7 +890,7 @@ template <class LP> void Writer::createOutputSections() {
for (ConcatInputSection *isec : inputSections) {
if (isec->shouldOmitFromOutput())
continue;
- NamePair names = maybeRenameSection({isec->segname, isec->name});
+ NamePair names = maybeRenameSection({isec->getSegName(), isec->getName()});
ConcatOutputSection *&osec = concatOutputSections[names];
if (!osec)
osec = make<ConcatOutputSection>(names.second);
@@ -913,7 +914,8 @@ template <class LP> void Writer::createOutputSections() {
if (it == concatOutputSections.end()) {
getOrCreateOutputSegment(ssec->segname)->addOutputSection(ssec);
} else {
- fatal("section from " + toString(it->second->firstSection()->file) +
+ fatal("section from " +
+ toString(it->second->firstSection()->getFile()) +
" conflicts with synthetic section " + ssec->segname + "," +
ssec->name);
}
More information about the llvm-commits
mailing list