[llvm] big archive recognition by the llvm-symbolizer (PR #150401)
James Henderson via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 8 00:47:49 PDT 2025
================
@@ -557,19 +559,101 @@ LLVMSymbolizer::getOrCreateObjectPair(const std::string &Path,
if (!DbgObj)
DbgObj = Obj;
ObjectPair Res = std::make_pair(Obj, DbgObj);
- std::string DbgObjPath = DbgObj->getFileName().str();
auto Pair =
ObjectPairForPathArch.emplace(std::make_pair(Path, ArchName), Res);
- BinaryForPath.find(DbgObjPath)->second.pushEvictor([this, I = Pair.first]() {
+ std::string DbgObjPath = DbgObj->getFileName().str();
+ auto BinIter = BinaryForPath.find(DbgObjPath);
+ if (BinIter != BinaryForPath.end()) {
+ BinIter->second.pushEvictor([this, I = Pair.first]() {
ObjectPairForPathArch.erase(I);
- });
+ });
+ }
return Res;
}
+Expected<ObjectFile *> LLVMSymbolizer::getOrCreateObjectFromArchive(StringRef ArchivePath,
+ StringRef MemberName,
+ const std::string &ArchName) {
+ Binary *Bin = nullptr;
+ auto Pair = BinaryForPath.emplace(ArchivePath.str(), OwningBinary<Binary>());
+ if (!Pair.second) {
+ Bin = Pair.first->second->getBinary();
+ recordAccess(Pair.first->second);
+ } else {
+ Expected<OwningBinary<Binary>> ArchiveOrErr = createBinary(ArchivePath);
+ if (!ArchiveOrErr) {
+ return ArchiveOrErr.takeError();
+ }
+
+ CachedBinary &CachedBin = Pair.first->second;
+ CachedBin = std::move(ArchiveOrErr.get());
+ CachedBin.pushEvictor([this, I = Pair.first]() { BinaryForPath.erase(I); });
+ LRUBinaries.push_back(CachedBin);
+ CacheSize += CachedBin.size();
+ Bin = CachedBin->getBinary();
+ }
+
+ if (!Bin || !isa<object::Archive>(Bin))
+ return errorCodeToError(object_error::invalid_file_type);
+
+ object::Archive *Archive = cast<object::Archive>(Bin);
+ Error Err = Error::success();
+
+ // On AIX, archives can contain multiple members with same name but different types
+ // We need to check all matches and find one that matches both name and architecture
+ for (auto &Child : Archive->children(Err, /*SkipInternal=*/true)) {
+ Expected<StringRef> NameOrErr = Child.getName();
+ if (!NameOrErr)
+ continue;
+ if (*NameOrErr == llvm::sys::path::filename(MemberName)) {
+ Expected<std::unique_ptr<object::Binary>> MemberOrErr = Child.getAsBinary();
+ if (!MemberOrErr)
+ continue;
+
+ std::unique_ptr<object::Binary> Binary = std::move(*MemberOrErr);
+ if (auto *Obj = dyn_cast<object::ObjectFile>(Binary.get())) {
+#if defined(_AIX)
+ Triple::ArchType ObjArch = Obj->makeTriple().getArch();
+ Triple RequestedTriple;
+ RequestedTriple.setArch(Triple::getArchTypeForLLVMName(ArchName));
+ if (ObjArch != RequestedTriple.getArch())
+ continue;
+#endif
+ ArchiveCacheKey CacheKey{ArchivePath.str(), MemberName.str(), ArchName};
+ auto I = ObjectForArchivePathAndArch.find(CacheKey);
+ if (I != ObjectForArchivePathAndArch.end())
+ return I->second.get();
+
+ auto CachedObj = std::unique_ptr<ObjectFile>(Obj);
+ auto NewEntry = ObjectForArchivePathAndArch.emplace(
+ CacheKey, std::move(CachedObj));
+ Binary.release();
+ BinaryForPath.find(ArchivePath.str())->second.pushEvictor(
+ [this, Iter = NewEntry.first]() { ObjectForArchivePathAndArch.erase(Iter); });
+ return NewEntry.first->second.get();
+ }
+ }
+ }
+ if (Err)
+ return std::move(Err);
+ return errorCodeToError(object_error::arch_not_found);
+}
+
Expected<ObjectFile *>
LLVMSymbolizer::getOrCreateObject(const std::string &Path,
const std::string &ArchName) {
- Binary *Bin;
+ // First check for archive(member) format - more efficient to check closing paren first
----------------
jh7370 wrote:
Ping. The second part of this comment hasn't been addressed as far as I can tell.
https://github.com/llvm/llvm-project/pull/150401
More information about the llvm-commits
mailing list