From f6ad0453665f63cf036fcb01f26fb4f023e4cfbb Mon Sep 17 00:00:00 2001 From: Alexander Shaposhnikov Date: Thu, 1 Apr 2021 17:48:09 -0700 Subject: [PATCH] [lld][MachO] Make emitEndFunStab independent from .subsections_via_symbols This diff addresses FIXME in SyntheticSections.cpp and removes the dependency of emitEndFunStab on .subsections_via_symbols. Test plan: make check-lld-macho Differential revision: https://reviews.llvm.org/D99054 --- lld/MachO/Driver.cpp | 1 + lld/MachO/InputFiles.cpp | 29 ++++++++++++++++++++--------- lld/MachO/SymbolTable.cpp | 9 +++++---- lld/MachO/SymbolTable.h | 3 ++- lld/MachO/Symbols.h | 9 +++++---- lld/MachO/SyntheticSections.cpp | 11 +++++------ lld/MachO/UnwindInfoSection.cpp | 4 ++-- 7 files changed, 40 insertions(+), 26 deletions(-) diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp index 267adbc..befaf67 100644 --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -531,6 +531,7 @@ static void replaceCommonSymbols() { inputSections.push_back(isec); replaceSymbol(sym, sym->getName(), isec->file, isec, /*value=*/0, + /*size=*/0, /*isWeakDef=*/false, /*isExternal=*/true, common->privateExtern); } diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp index d37db36..e31c506 100644 --- a/lld/MachO/InputFiles.cpp +++ b/lld/MachO/InputFiles.cpp @@ -332,7 +332,7 @@ void ObjFile::parseRelocations(const section_64 &sec, static macho::Symbol *createDefined(const structs::nlist_64 &sym, StringRef name, InputSection *isec, - uint64_t value) { + uint64_t value, uint64_t size) { // Symbol scope is determined by sym.n_type & (N_EXT | N_PEXT): // N_EXT: Global symbols // N_EXT | N_PEXT: Linkage unit (think: dylib) scoped @@ -342,10 +342,11 @@ static macho::Symbol *createDefined(const structs::nlist_64 &sym, if (sym.n_type & (N_EXT | N_PEXT)) { assert((sym.n_type & N_EXT) && "invalid input"); - return symtab->addDefined(name, isec->file, isec, value, + return symtab->addDefined(name, isec->file, isec, value, size, sym.n_desc & N_WEAK_DEF, sym.n_type & N_PEXT); } - return make(name, isec->file, isec, value, sym.n_desc & N_WEAK_DEF, + return make(name, isec->file, isec, value, size, + sym.n_desc & N_WEAK_DEF, /*isExternal=*/false, /*isPrivateExtern=*/false); } @@ -381,10 +382,11 @@ static macho::Symbol *createAbsolute(const structs::nlist_64 &sym, InputFile *file, StringRef name) { if (sym.n_type & (N_EXT | N_PEXT)) { assert((sym.n_type & N_EXT) && "invalid input"); - return symtab->addDefined(name, file, nullptr, sym.n_value, + return symtab->addDefined(name, file, nullptr, sym.n_value, /*size=*/0, /*isWeakDef=*/false, sym.n_type & N_PEXT); } - return make(name, file, nullptr, sym.n_value, /*isWeakDef=*/false, + return make(name, file, nullptr, sym.n_value, /*size=*/0, + /*isWeakDef=*/false, /*isExternal=*/false, /*isPrivateExtern=*/false); } @@ -477,16 +479,25 @@ void ObjFile::parseSymbols(ArrayRef nList, uint64_t offset = sym.n_value - sec.addr; + auto it = llvm::upper_bound( + subsecMap, offset, [](int64_t value, SubsectionEntry subsectionEntry) { + return value < subsectionEntry.offset; + }); + uint32_t size = it != subsecMap.end() + ? it->offset - offset + : subsecMap.front().isec->getSize() - offset; + // If the input file does not use subsections-via-symbols, all symbols can // use the same subsection. Otherwise, we must split the sections along // symbol boundaries. if (!subsectionsViaSymbols) { - symbols[i] = createDefined(sym, name, subsecMap.front().isec, offset); + symbols[i] = + createDefined(sym, name, subsecMap.front().isec, offset, size); continue; } - InputSection *subsec = findContainingSubsection(subsecMap, &offset); - symbols[i] = createDefined(sym, name, subsec, offset); + InputSection *subsec = (--it)->isec; + symbols[i] = createDefined(sym, name, subsec, offset - it->offset, size); } if (!subsectionsViaSymbols) @@ -864,7 +875,7 @@ static macho::Symbol *createBitcodeSymbol(const lto::InputFile::Symbol &objSym, } return symtab->addDefined(name, &file, /*isec=*/nullptr, /*value=*/0, - objSym.isWeak(), isPrivateExtern); + /*size=*/0, objSym.isWeak(), isPrivateExtern); } BitcodeFile::BitcodeFile(MemoryBufferRef mbref) diff --git a/lld/MachO/SymbolTable.cpp b/lld/MachO/SymbolTable.cpp index 311c001..0a565b3 100644 --- a/lld/MachO/SymbolTable.cpp +++ b/lld/MachO/SymbolTable.cpp @@ -38,8 +38,9 @@ std::pair SymbolTable::insert(StringRef name) { } Defined *SymbolTable::addDefined(StringRef name, InputFile *file, - InputSection *isec, uint32_t value, - bool isWeakDef, bool isPrivateExtern) { + InputSection *isec, uint64_t value, + uint64_t size, bool isWeakDef, + bool isPrivateExtern) { Symbol *s; bool wasInserted; bool overridesWeakDef = false; @@ -66,7 +67,7 @@ Defined *SymbolTable::addDefined(StringRef name, InputFile *file, } Defined *defined = - replaceSymbol(s, name, file, isec, value, isWeakDef, + replaceSymbol(s, name, file, isec, value, size, isWeakDef, /*isExternal=*/true, isPrivateExtern); defined->overridesWeakDef = overridesWeakDef; return defined; @@ -160,7 +161,7 @@ Symbol *SymbolTable::addLazy(StringRef name, ArchiveFile *file, Defined *SymbolTable::addSynthetic(StringRef name, InputSection *isec, uint32_t value, bool isPrivateExtern, bool includeInSymtab) { - Defined *s = addDefined(name, nullptr, isec, value, + Defined *s = addDefined(name, nullptr, isec, value, /*size*/ 0, /*isWeakDef=*/false, isPrivateExtern); s->includeInSymtab = includeInSymtab; return s; diff --git a/lld/MachO/SymbolTable.h b/lld/MachO/SymbolTable.h index 9aed8c9..8a5c16c 100644 --- a/lld/MachO/SymbolTable.h +++ b/lld/MachO/SymbolTable.h @@ -38,7 +38,8 @@ class Undefined; class SymbolTable { public: Defined *addDefined(StringRef name, InputFile *, InputSection *, - uint32_t value, bool isWeakDef, bool isPrivateExtern); + uint64_t value, uint64_t size, bool isWeakDef, + bool isPrivateExtern); Symbol *addUndefined(StringRef name, InputFile *, bool isWeakRef); diff --git a/lld/MachO/Symbols.h b/lld/MachO/Symbols.h index 8a3004a..cb678ac 100644 --- a/lld/MachO/Symbols.h +++ b/lld/MachO/Symbols.h @@ -95,9 +95,9 @@ protected: class Defined : public Symbol { public: - Defined(StringRefZ name, InputFile *file, InputSection *isec, uint32_t value, - bool isWeakDef, bool isExternal, bool isPrivateExtern) - : Symbol(DefinedKind, name, file), isec(isec), value(value), + Defined(StringRefZ name, InputFile *file, InputSection *isec, uint64_t value, + uint64_t size, bool isWeakDef, bool isExternal, bool isPrivateExtern) + : Symbol(DefinedKind, name, file), isec(isec), value(value), size(size), overridesWeakDef(false), privateExtern(isPrivateExtern), includeInSymtab(true), weakDef(isWeakDef), external(isExternal) {} @@ -119,7 +119,8 @@ public: InputFile *file; InputSection *isec; - uint32_t value; + uint64_t value; + uint64_t size; bool overridesWeakDef : 1; // Whether this symbol should appear in the output binary's export trie. diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp index 6233079..341802a 100644 --- a/lld/MachO/SyntheticSections.cpp +++ b/lld/MachO/SyntheticSections.cpp @@ -454,9 +454,10 @@ void StubHelperSection::setup() { in.got->addEntry(stubBinder); inputSections.push_back(in.imageLoaderCache); - dyldPrivate = make("__dyld_private", nullptr, in.imageLoaderCache, 0, - /*isWeakDef=*/false, - /*isExternal=*/false, /*isPrivateExtern=*/false); + dyldPrivate = + make("__dyld_private", nullptr, in.imageLoaderCache, 0, 0, + /*isWeakDef=*/false, + /*isExternal=*/false, /*isPrivateExtern=*/false); } ImageLoaderCacheSection::ImageLoaderCacheSection() { @@ -663,9 +664,7 @@ void SymtabSection::emitObjectFileStab(ObjFile *file) { void SymtabSection::emitEndFunStab(Defined *defined) { StabsEntry stab(N_FUN); - // FIXME this should be the size of the symbol. Using the section size in - // lieu is only correct if .subsections_via_symbols is set. - stab.value = defined->isec->getSize(); + stab.value = defined->size; stabs.emplace_back(std::move(stab)); } diff --git a/lld/MachO/UnwindInfoSection.cpp b/lld/MachO/UnwindInfoSection.cpp index ed7ae57..949d16f 100644 --- a/lld/MachO/UnwindInfoSection.cpp +++ b/lld/MachO/UnwindInfoSection.cpp @@ -148,8 +148,8 @@ void macho::prepareCompactUnwind(InputSection *isec) { // symbols for them in the GOT. Symbol *&s = personalityTable[{referentIsec, r.addend}]; if (s == nullptr) { - s = make("", nullptr, referentIsec, r.addend, false, - false, false); + s = make("", nullptr, referentIsec, r.addend, 0, + false, false, false); in.got->addEntry(s); } r.referent = s; -- 2.7.4