diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2022-07-27 19:50:45 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2022-07-27 19:50:54 +0000 |
| commit | 08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (patch) | |
| tree | 041e72e32710b1e742516d8c9f1575bf0116d3e3 /lld/MachO | |
| parent | 4b4fe385e49bd883fd183b5f21c1ea486c722e61 (diff) | |
Vendor import of llvm-project main llvmorg-15-init-17826-g1f8ae9d7e7e4,vendor/llvm-project/llvmorg-15-init-17827-gd77882e66779vendor/llvm-project/llvmorg-15-init-17826-g1f8ae9d7e7e4
the last commit before the upstream release/16.x branch was created.
Diffstat (limited to 'lld/MachO')
| -rw-r--r-- | lld/MachO/Driver.cpp | 20 | ||||
| -rw-r--r-- | lld/MachO/DriverUtils.cpp | 1 | ||||
| -rw-r--r-- | lld/MachO/InputFiles.cpp | 60 | ||||
| -rw-r--r-- | lld/MachO/InputFiles.h | 12 | ||||
| -rw-r--r-- | lld/MachO/InputSection.cpp | 2 | ||||
| -rw-r--r-- | lld/MachO/Options.td | 10 | ||||
| -rw-r--r-- | lld/MachO/SyntheticSections.h | 6 |
7 files changed, 71 insertions, 40 deletions
diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp index 454708fad4ef..ce2d55bef456 100644 --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -266,7 +266,8 @@ static DenseMap<StringRef, ArchiveFileInfo> loadedArchives; static InputFile *addFile(StringRef path, LoadType loadType, bool isLazy = false, bool isExplicit = true, - bool isBundleLoader = false) { + bool isBundleLoader = false, + bool isForceHidden = false) { Optional<MemoryBufferRef> buffer = readFile(path); if (!buffer) return nullptr; @@ -293,7 +294,7 @@ static InputFile *addFile(StringRef path, LoadType loadType, if (!archive->isEmpty() && !archive->hasSymbolTable()) error(path + ": archive has no index; run ranlib to add one"); - file = make<ArchiveFile>(std::move(archive)); + file = make<ArchiveFile>(std::move(archive), isForceHidden); } else { file = entry->second.file; // Command-line loads take precedence. If file is previously loaded via @@ -406,10 +407,12 @@ static InputFile *addFile(StringRef path, LoadType loadType, } static void addLibrary(StringRef name, bool isNeeded, bool isWeak, - bool isReexport, bool isExplicit, LoadType loadType) { + bool isReexport, bool isHidden, bool isExplicit, + LoadType loadType) { if (Optional<StringRef> path = findLibrary(name)) { if (auto *dylibFile = dyn_cast_or_null<DylibFile>( - addFile(*path, loadType, /*isLazy=*/false, isExplicit))) { + addFile(*path, loadType, /*isLazy=*/false, isExplicit, + /*isBundleLoader=*/false, isHidden))) { if (isNeeded) dylibFile->forceNeeded = true; if (isWeak) @@ -473,7 +476,7 @@ void macho::parseLCLinkerOption(InputFile *f, unsigned argc, StringRef data) { StringRef arg = argv[i]; if (arg.consume_front("-l")) { addLibrary(arg, /*isNeeded=*/false, /*isWeak=*/false, - /*isReexport=*/false, /*isExplicit=*/false, + /*isReexport=*/false, /*isHidden=*/false, /*isExplicit=*/false, LoadType::LCLinkerOption); } else if (arg == "-framework") { StringRef name = argv[++i]; @@ -1035,12 +1038,19 @@ static void createFiles(const InputArgList &args) { case OPT_force_load: addFile(rerootPath(arg->getValue()), LoadType::CommandLineForce); break; + case OPT_load_hidden: + addFile(rerootPath(arg->getValue()), LoadType::CommandLine, + /*isLazy=*/false, /*isExplicit=*/true, /*isBundleLoader=*/false, + /*isForceHidden=*/true); + break; case OPT_l: case OPT_needed_l: case OPT_reexport_l: case OPT_weak_l: + case OPT_hidden_l: addLibrary(arg->getValue(), opt.getID() == OPT_needed_l, opt.getID() == OPT_weak_l, opt.getID() == OPT_reexport_l, + opt.getID() == OPT_hidden_l, /*isExplicit=*/true, LoadType::CommandLine); break; case OPT_framework: diff --git a/lld/MachO/DriverUtils.cpp b/lld/MachO/DriverUtils.cpp index b52d5e851c62..d8e474d15cfd 100644 --- a/lld/MachO/DriverUtils.cpp +++ b/lld/MachO/DriverUtils.cpp @@ -150,6 +150,7 @@ std::string macho::createResponseFile(const InputArgList &args) { break; case OPT_force_load: case OPT_weak_library: + case OPT_load_hidden: os << arg->getSpelling() << " " << quote(rewriteInputPath(arg->getValue())) << "\n"; break; 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<SectionHeader> sectionHeaders, template <class NList> 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 <class NList> 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 <class NList> 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<typename LP::section> 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<typename LP::section> sectionHeaders, // 4. If we have a literal section (e.g. __cstring and __literal4). if (!subsectionsViaSymbols || symbolOffset == 0 || sym.n_desc & N_ALT_ENTRY || !isa<ConcatInputSection>(isec)) { - symbols[symIndex] = - createDefined(sym, name, isec, symbolOffset, symbolSize); + symbols[symIndex] = createDefined(sym, name, isec, symbolOffset, + symbolSize, forceHidden); continue; } auto *concatIsec = cast<ConcatInputSection>(isec); @@ -998,8 +1004,8 @@ void ObjFile::parseSymbols(ArrayRef<typename LP::section> 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<object::Archive> &&f) - : InputFile(ArchiveKind, f->getMemoryBufferRef()), file(std::move(f)) {} +ArchiveFile::ArchiveFile(std::unique_ptr<object::Archive> &&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<InputFile *> loadArchiveMember(MemoryBufferRef mb, - uint32_t modTime, - StringRef archiveName, - uint64_t offsetInArchive) { +static Expected<InputFile *> +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<ObjFile>(mb, modTime, archiveName); + return make<ObjFile>(mb, modTime, archiveName, /*lazy=*/false, forceHidden); case file_magic::bitcode: - return make<BitcodeFile>(mb, archiveName, offsetInArchive); + return make<BitcodeFile>(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<InputFile *> file = - loadArchiveMember(*mb, toTimeT(*modTime), getName(), c.getChildOffset()); + Expected<InputFile *> 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 diff --git a/lld/MachO/InputFiles.h b/lld/MachO/InputFiles.h index 5deb05272a6b..ea6802814e4c 100644 --- a/lld/MachO/InputFiles.h +++ b/lld/MachO/InputFiles.h @@ -156,7 +156,7 @@ struct FDE { class ObjFile final : public InputFile { public: ObjFile(MemoryBufferRef mb, uint32_t modTime, StringRef archiveName, - bool lazy = false); + bool lazy = false, bool forceHidden = false); ArrayRef<llvm::MachO::data_in_code_entry> getDataInCode() const; template <class LP> void parse(); @@ -171,6 +171,7 @@ public: std::unique_ptr<lld::DWARFCache> dwarfCache; Section *addrSigSection = nullptr; const uint32_t modTime; + bool forceHidden; std::vector<ConcatInputSection *> debugSections; std::vector<CallGraphEntry> callGraph; llvm::DenseMap<ConcatInputSection *, FDE> fdes; @@ -259,7 +260,8 @@ private: // .a file class ArchiveFile final : public InputFile { public: - explicit ArchiveFile(std::unique_ptr<llvm::object::Archive> &&file); + explicit ArchiveFile(std::unique_ptr<llvm::object::Archive> &&file, + bool forceHidden); void addLazySymbols(); void fetch(const llvm::object::Archive::Symbol &); // LLD normally doesn't use Error for error-handling, but the underlying @@ -273,16 +275,20 @@ private: // Keep track of children fetched from the archive by tracking // which address offsets have been fetched already. llvm::DenseSet<uint64_t> seen; + // Load all symbols with hidden visibility (-load_hidden). + bool forceHidden; }; class BitcodeFile final : public InputFile { public: explicit BitcodeFile(MemoryBufferRef mb, StringRef archiveName, - uint64_t offsetInArchive, bool lazy = false); + uint64_t offsetInArchive, bool lazy = false, + bool forceHidden = false); static bool classof(const InputFile *f) { return f->kind() == BitcodeKind; } void parse(); std::unique_ptr<llvm::lto::InputFile> obj; + bool forceHidden; private: void parseLazy(); diff --git a/lld/MachO/InputSection.cpp b/lld/MachO/InputSection.cpp index 76b11d9da4f8..ca073f8ac6f3 100644 --- a/lld/MachO/InputSection.cpp +++ b/lld/MachO/InputSection.cpp @@ -67,7 +67,7 @@ std::string InputSection::getLocation(uint64_t off) const { // First, try to find a symbol that's near the offset. Use it as a reference // point. if (auto *sym = getContainingSymbol(off)) - return (toString(getFile()) + ":(symbol " + sym->getName() + "+0x" + + return (toString(getFile()) + ":(symbol " + toString(*sym) + "+0x" + Twine::utohexstr(off - sym->value) + ")") .str(); diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td index b3d74a83f582..064862fb1bb0 100644 --- a/lld/MachO/Options.td +++ b/lld/MachO/Options.td @@ -240,6 +240,14 @@ def force_load : Separate<["-"], "force_load">, def force_load_swift_libs : Flag<["-"], "force_load_swift_libs">, HelpText<"Apply -force_load to libraries listed in LC_LINKER_OPTIONS whose names start with 'swift'">, Group<grp_libs>; +def load_hidden : Separate<["-"], "load_hidden">, + MetaVarName<"<path>">, + HelpText<"Load all symbols from static library with hidden visibility">, + Group<grp_libs>; +def hidden_l : Joined<["-"], "hidden-l">, + MetaVarName<"<name>">, + HelpText<"Like -l<name>, but load all symbols with hidden visibility">, + Group<grp_libs>; def grp_content : OptionGroup<"content">, HelpText<"ADDITIONAL CONTENT">; @@ -1174,7 +1182,7 @@ def allow_simulator_linking_to_macosx_dylibs : Flag<["-"], "allow_simulator_link HelpText<"This option is undocumented in ld64">, Flags<[HelpHidden]>, Group<grp_undocumented>; -def bitcode_process_mode : Flag<["-"], "bitcode_process_mode">, +def bitcode_process_mode : Separate<["-"], "bitcode_process_mode">, HelpText<"This option is undocumented in ld64">, Flags<[HelpHidden]>, Group<grp_undocumented>; diff --git a/lld/MachO/SyntheticSections.h b/lld/MachO/SyntheticSections.h index afdd46d8a7de..29c2d98c6625 100644 --- a/lld/MachO/SyntheticSections.h +++ b/lld/MachO/SyntheticSections.h @@ -70,7 +70,7 @@ public: // Sections in __LINKEDIT are special: their offsets are recorded in the // load commands like LC_DYLD_INFO_ONLY and LC_SYMTAB, instead of in section // headers. - bool isHidden() const override final { return true; } + bool isHidden() const final { return true; } virtual uint64_t getRawSize() const = 0; @@ -80,9 +80,7 @@ public: // // NOTE: This assumes that the extra bytes required for alignment can be // zero-valued bytes. - uint64_t getSize() const override final { - return llvm::alignTo(getRawSize(), align); - } + uint64_t getSize() const final { return llvm::alignTo(getRawSize(), align); } }; // The header of the Mach-O file, which must have a file offset of zero. |
