Mercurial > hg > CbC > CbC_llvm
diff lld/ELF/Symbols.cpp @ 207:2e18cbf3894f
LLVM12
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 08 Jun 2021 06:07:14 +0900 |
parents | 0572611fdcc8 |
children | c4bab56944e8 |
line wrap: on
line diff
--- a/lld/ELF/Symbols.cpp Mon May 25 11:55:54 2020 +0900 +++ b/lld/ELF/Symbols.cpp Tue Jun 08 06:07:14 2021 +0900 @@ -37,11 +37,9 @@ StringRef name = sym.getName(); std::string ret = demangle(name); - // If sym has a non-default version, its name may have been truncated at '@' - // by Symbol::parseSymbolVersion(). Add the trailing part. This check is safe - // because every symbol name ends with '\0'. - if (name.data()[name.size()] == '@') - ret += name.data() + name.size(); + const char *suffix = sym.getVersionSuffix(); + if (*suffix == '@') + ret += suffix; return ret; } @@ -64,7 +62,8 @@ Defined *ElfSym::relaIpltEnd; Defined *ElfSym::riscvGlobalPointer; Defined *ElfSym::tlsModuleBase; -DenseMap<const Symbol *, const InputFile *> elf::backwardReferences; +DenseMap<const Symbol *, std::pair<const InputFile *, const InputFile *>> + elf::backwardReferences; static uint64_t getSymVA(const Symbol &sym, int64_t &addend) { switch (sym.kind()) { @@ -161,7 +160,9 @@ return in.got->getVA() + getGotOffset(); } -uint64_t Symbol::getGotOffset() const { return gotIndex * config->wordsize; } +uint64_t Symbol::getGotOffset() const { + return gotIndex * target->gotEntrySize; +} uint64_t Symbol::getGotPltVA() const { if (isInIplt) @@ -171,8 +172,8 @@ uint64_t Symbol::getGotPltOffset() const { if (isInIplt) - return pltIndex * config->wordsize; - return (pltIndex + target->gotPltHeaderEntriesNum) * config->wordsize; + return pltIndex * target->gotEntrySize; + return (pltIndex + target->gotPltHeaderEntriesNum) * target->gotEntrySize; } uint64_t Symbol::getPltVA() const { @@ -278,7 +279,7 @@ if (config->relocatable) return binding; if ((visibility != STV_DEFAULT && visibility != STV_PROTECTED) || - (versionId == VER_NDX_LOCAL && isDefined())) + (versionId == VER_NDX_LOCAL && !isLazy())) return STB_LOCAL; if (!config->gnuUnique && binding == STB_GNU_UNIQUE) return STB_GLOBAL; @@ -365,21 +366,29 @@ if (!config->shared) return false; - // If the dynamic list is present, it specifies preemptable symbols in a DSO. - if (config->hasDynamicList) + // If -Bsymbolic or --dynamic-list is specified, or -Bsymbolic-functions is + // specified and the symbol is STT_FUNC, the symbol is preemptible iff it is + // in the dynamic list. + if (config->symbolic || (config->bsymbolicFunctions && sym.isFunc())) return sym.inDynamicList; - - // -Bsymbolic means that definitions are not preempted. - if (config->bsymbolic || (config->bsymbolicFunctions && sym.isFunc())) - return false; return true; } void elf::reportBackrefs() { for (auto &it : backwardReferences) { const Symbol &sym = *it.first; - warn("backward reference detected: " + sym.getName() + " in " + - toString(it.second) + " refers to " + toString(sym.file)); + std::string to = toString(it.second.second); + // Some libraries have known problems and can cause noise. Filter them out + // with --warn-backrefs-exclude=. to may look like *.o or *.a(*.o). + bool exclude = false; + for (const llvm::GlobPattern &pat : config->warnBackrefsExclude) + if (pat.match(to)) { + exclude = true; + break; + } + if (!exclude) + warn("backward reference detected: " + sym.getName() + " in " + + toString(it.second.first) + " refers to " + to); } } @@ -515,17 +524,6 @@ // group assignment rule simulates the traditional linker's semantics. bool backref = config->warnBackrefs && other.file && file->groupId < other.file->groupId; - if (backref) { - // Some libraries have known problems and can cause noise. Filter them out - // with --warn-backrefs-exclude=. - StringRef name = - !file->archiveName.empty() ? file->archiveName : file->getName(); - for (const llvm::GlobPattern &pat : config->warnBackrefsExclude) - if (pat.match(name)) { - backref = false; - break; - } - } fetch(); // We don't report backward references to weak symbols as they can be @@ -534,9 +532,10 @@ // A traditional linker does not error for -ldef1 -lref -ldef2 (linking // sandwich), where def2 may or may not be the same as def1. We don't want // to warn for this case, so dismiss the warning if we see a subsequent lazy - // definition. + // definition. this->file needs to be saved because in the case of LTO it + // may be reset to nullptr or be replaced with a file named lto.tmp. if (backref && !isWeak()) - backwardReferences.try_emplace(this, other.file); + backwardReferences.try_emplace(this, std::make_pair(other.file, file)); return; } @@ -692,7 +691,33 @@ other.value); } +template <class LazyT> +static void replaceCommon(Symbol &oldSym, const LazyT &newSym) { + backwardReferences.erase(&oldSym); + oldSym.replace(newSym); + newSym.fetch(); +} + template <class LazyT> void Symbol::resolveLazy(const LazyT &other) { + // For common objects, we want to look for global or weak definitions that + // should be fetched as the canonical definition instead. + if (isCommon() && elf::config->fortranCommon) { + if (auto *laSym = dyn_cast<LazyArchive>(&other)) { + ArchiveFile *archive = cast<ArchiveFile>(laSym->file); + const Archive::Symbol &archiveSym = laSym->sym; + if (archive->shouldFetchForCommon(archiveSym)) { + replaceCommon(*this, other); + return; + } + } else if (auto *loSym = dyn_cast<LazyObject>(&other)) { + LazyObjFile *obj = cast<LazyObjFile>(loSym->file); + if (obj->shouldFetchForCommon(loSym->getName())) { + replaceCommon(*this, other); + return; + } + } + } + if (!isUndefined()) { // See the comment in resolveUndefined(). if (isDefined())