From 08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Wed, 27 Jul 2022 21:50:45 +0200 Subject: Vendor import of llvm-project main llvmorg-15-init-17826-g1f8ae9d7e7e4, the last commit before the upstream release/16.x branch was created. --- lld/MachO/InputFiles.cpp | 60 +++++++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 26 deletions(-) (limited to 'lld/MachO/InputFiles.cpp') diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp index e3bf553e5334..b463d7817594 100644 --- a/lld/MachO/InputFiles.cpp +++ b/lld/MachO/InputFiles.cpp @@ -768,7 +768,7 @@ void ObjFile::parseRelocations(ArrayRef sectionHeaders, template static macho::Symbol *createDefined(const NList &sym, StringRef name, InputSection *isec, uint64_t value, - uint64_t size) { + uint64_t size, bool forceHidden) { // Symbol scope is determined by sym.n_type & (N_EXT | N_PEXT): // N_EXT: Global symbols. These go in the symbol table during the link, // and also in the export table of the output so that the dynamic @@ -787,7 +787,10 @@ static macho::Symbol *createDefined(const NList &sym, StringRef name, (sym.n_desc & (N_WEAK_DEF | N_WEAK_REF)) == (N_WEAK_DEF | N_WEAK_REF); if (sym.n_type & N_EXT) { - bool isPrivateExtern = sym.n_type & N_PEXT; + // -load_hidden makes us treat global symbols as linkage unit scoped. + // Duplicates are reported but the symbol does not go in the export trie. + bool isPrivateExtern = sym.n_type & N_PEXT || forceHidden; + // lld's behavior for merging symbols is slightly different from ld64: // ld64 picks the winning symbol based on several criteria (see // pickBetweenRegularAtoms() in ld64's SymbolTable.cpp), while lld @@ -844,11 +847,12 @@ static macho::Symbol *createDefined(const NList &sym, StringRef name, // InputSection. They cannot be weak. template static macho::Symbol *createAbsolute(const NList &sym, InputFile *file, - StringRef name) { + StringRef name, bool forceHidden) { if (sym.n_type & N_EXT) { + bool isPrivateExtern = sym.n_type & N_PEXT || forceHidden; return symtab->addDefined( name, file, nullptr, sym.n_value, /*size=*/0, - /*isWeakDef=*/false, sym.n_type & N_PEXT, sym.n_desc & N_ARM_THUMB_DEF, + /*isWeakDef=*/false, isPrivateExtern, sym.n_desc & N_ARM_THUMB_DEF, /*isReferencedDynamically=*/false, sym.n_desc & N_NO_DEAD_STRIP, /*isWeakDefCanBeHidden=*/false); } @@ -864,15 +868,16 @@ template macho::Symbol *ObjFile::parseNonSectionSymbol(const NList &sym, StringRef name) { uint8_t type = sym.n_type & N_TYPE; + bool isPrivateExtern = sym.n_type & N_PEXT || forceHidden; switch (type) { case N_UNDF: return sym.n_value == 0 ? symtab->addUndefined(name, this, sym.n_desc & N_WEAK_REF) : symtab->addCommon(name, this, sym.n_value, 1 << GET_COMM_ALIGN(sym.n_desc), - sym.n_type & N_PEXT); + isPrivateExtern); case N_ABS: - return createAbsolute(sym, this, name); + return createAbsolute(sym, this, name, forceHidden); case N_PBUD: case N_INDR: error("TODO: support symbols of type " + std::to_string(type)); @@ -944,7 +949,8 @@ void ObjFile::parseSymbols(ArrayRef sectionHeaders, " at misaligned offset"); continue; } - symbols[symIndex] = createDefined(sym, name, isec, 0, isec->getSize()); + symbols[symIndex] = + createDefined(sym, name, isec, 0, isec->getSize(), forceHidden); } continue; } @@ -979,8 +985,8 @@ void ObjFile::parseSymbols(ArrayRef sectionHeaders, // 4. If we have a literal section (e.g. __cstring and __literal4). if (!subsectionsViaSymbols || symbolOffset == 0 || sym.n_desc & N_ALT_ENTRY || !isa(isec)) { - symbols[symIndex] = - createDefined(sym, name, isec, symbolOffset, symbolSize); + symbols[symIndex] = createDefined(sym, name, isec, symbolOffset, + symbolSize, forceHidden); continue; } auto *concatIsec = cast(isec); @@ -998,8 +1004,8 @@ void ObjFile::parseSymbols(ArrayRef sectionHeaders, // By construction, the symbol will be at offset zero in the new // subsection. - symbols[symIndex] = - createDefined(sym, name, nextIsec, /*value=*/0, symbolSize); + symbols[symIndex] = createDefined(sym, name, nextIsec, /*value=*/0, + symbolSize, forceHidden); // TODO: ld64 appears to preserve the original alignment as well as each // subsection's offset from the last aligned address. We should consider // emulating that behavior. @@ -1036,8 +1042,8 @@ OpaqueFile::OpaqueFile(MemoryBufferRef mb, StringRef segName, } ObjFile::ObjFile(MemoryBufferRef mb, uint32_t modTime, StringRef archiveName, - bool lazy) - : InputFile(ObjKind, mb, lazy), modTime(modTime) { + bool lazy, bool forceHidden) + : InputFile(ObjKind, mb, lazy), modTime(modTime), forceHidden(forceHidden) { this->archiveName = std::string(archiveName); if (lazy) { if (target->wordSize == 8) @@ -2061,26 +2067,27 @@ void DylibFile::checkAppExtensionSafety(bool dylibIsAppExtensionSafe) const { warn("using '-application_extension' with unsafe dylib: " + toString(this)); } -ArchiveFile::ArchiveFile(std::unique_ptr &&f) - : InputFile(ArchiveKind, f->getMemoryBufferRef()), file(std::move(f)) {} +ArchiveFile::ArchiveFile(std::unique_ptr &&f, bool forceHidden) + : InputFile(ArchiveKind, f->getMemoryBufferRef()), file(std::move(f)), + forceHidden(forceHidden) {} void ArchiveFile::addLazySymbols() { for (const object::Archive::Symbol &sym : file->symbols()) symtab->addLazyArchive(sym.getName(), this, sym); } -static Expected loadArchiveMember(MemoryBufferRef mb, - uint32_t modTime, - StringRef archiveName, - uint64_t offsetInArchive) { +static Expected +loadArchiveMember(MemoryBufferRef mb, uint32_t modTime, StringRef archiveName, + uint64_t offsetInArchive, bool forceHidden) { if (config->zeroModTime) modTime = 0; switch (identify_magic(mb.getBuffer())) { case file_magic::macho_object: - return make(mb, modTime, archiveName); + return make(mb, modTime, archiveName, /*lazy=*/false, forceHidden); case file_magic::bitcode: - return make(mb, archiveName, offsetInArchive); + return make(mb, archiveName, offsetInArchive, /*lazy=*/false, + forceHidden); default: return createStringError(inconvertibleErrorCode(), mb.getBufferIdentifier() + @@ -2104,8 +2111,8 @@ Error ArchiveFile::fetch(const object::Archive::Child &c, StringRef reason) { if (!modTime) return modTime.takeError(); - Expected file = - loadArchiveMember(*mb, toTimeT(*modTime), getName(), c.getChildOffset()); + Expected file = loadArchiveMember( + *mb, toTimeT(*modTime), getName(), c.getChildOffset(), forceHidden); if (!file) return file.takeError(); @@ -2153,7 +2160,8 @@ static macho::Symbol *createBitcodeSymbol(const lto::InputFile::Symbol &objSym, case GlobalValue::DefaultVisibility: break; } - isPrivateExtern = isPrivateExtern || objSym.canBeOmittedFromSymbolTable(); + isPrivateExtern = isPrivateExtern || objSym.canBeOmittedFromSymbolTable() || + file.forceHidden; if (objSym.isCommon()) return symtab->addCommon(name, &file, objSym.getCommonSize(), @@ -2168,8 +2176,8 @@ static macho::Symbol *createBitcodeSymbol(const lto::InputFile::Symbol &objSym, } BitcodeFile::BitcodeFile(MemoryBufferRef mb, StringRef archiveName, - uint64_t offsetInArchive, bool lazy) - : InputFile(BitcodeKind, mb, lazy) { + uint64_t offsetInArchive, bool lazy, bool forceHidden) + : InputFile(BitcodeKind, mb, lazy), forceHidden(forceHidden) { this->archiveName = std::string(archiveName); std::string path = mb.getBufferIdentifier().str(); // ThinLTO assumes that all MemoryBufferRefs given to it have a unique -- cgit v1.3