[llvm-branch-commits] [lld] 76c36c1 - [lld-macho] Don't load dylibs more than once
Jez Ng via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Dec 10 16:03:04 PST 2020
Author: Jez Ng
Date: 2020-12-10T15:57:52-08:00
New Revision: 76c36c11a9c620a5eeced5750b844a1097ab7586
URL: https://github.com/llvm/llvm-project/commit/76c36c11a9c620a5eeced5750b844a1097ab7586
DIFF: https://github.com/llvm/llvm-project/commit/76c36c11a9c620a5eeced5750b844a1097ab7586.diff
LOG: [lld-macho] Don't load dylibs more than once
Also remove `DylibFile::reexported` since it's unused.
Fixes llvm.org/PR48393.
Reviewed By: thakis
Differential Revision: https://reviews.llvm.org/D93001
Added:
Modified:
lld/MachO/Driver.cpp
lld/MachO/Driver.h
lld/MachO/DriverUtils.cpp
lld/MachO/InputFiles.cpp
lld/MachO/InputFiles.h
lld/test/MachO/dylink.s
lld/test/MachO/implicit-dylibs.s
lld/test/MachO/lc-linker-option.ll
Removed:
################################################################################
diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index 469ab801bfe8..73846d420096 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -309,10 +309,8 @@ static InputFile *addFile(StringRef path, bool forceLoadArchive) {
break;
case file_magic::macho_dynamically_linked_shared_lib:
case file_magic::macho_dynamically_linked_shared_lib_stub:
- newFile = make<DylibFile>(mbref);
- break;
case file_magic::tapi_file: {
- if (Optional<DylibFile *> dylibFile = makeDylibFromTAPI(mbref))
+ if (Optional<DylibFile *> dylibFile = loadDylib(mbref))
newFile = *dylibFile;
break;
}
diff --git a/lld/MachO/Driver.h b/lld/MachO/Driver.h
index 9a6a05af0e0d..97b897f0271b 100644
--- a/lld/MachO/Driver.h
+++ b/lld/MachO/Driver.h
@@ -43,8 +43,8 @@ std::string createResponseFile(const llvm::opt::InputArgList &args);
// Check for both libfoo.dylib and libfoo.tbd (in that order).
llvm::Optional<std::string> resolveDylibPath(llvm::StringRef path);
-llvm::Optional<DylibFile *> makeDylibFromTAPI(llvm::MemoryBufferRef mbref,
- DylibFile *umbrella = nullptr);
+llvm::Optional<DylibFile *> loadDylib(llvm::MemoryBufferRef mbref,
+ DylibFile *umbrella = nullptr);
uint32_t getModTime(llvm::StringRef path);
diff --git a/lld/MachO/DriverUtils.cpp b/lld/MachO/DriverUtils.cpp
index 9f06901d3847..05677a9df78d 100644
--- a/lld/MachO/DriverUtils.cpp
+++ b/lld/MachO/DriverUtils.cpp
@@ -14,6 +14,8 @@
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Memory.h"
#include "lld/Common/Reproduce.h"
+#include "llvm/ADT/CachedHashString.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/Option.h"
@@ -166,7 +168,7 @@ Optional<std::string> macho::resolveDylibPath(StringRef path) {
return {};
}
-Optional<DylibFile *> macho::makeDylibFromTAPI(MemoryBufferRef mbref,
+static Optional<DylibFile *> makeDylibFromTapi(MemoryBufferRef mbref,
DylibFile *umbrella) {
Expected<std::unique_ptr<InterfaceFile>> result = TextAPIReader::get(mbref);
if (!result) {
@@ -177,6 +179,24 @@ Optional<DylibFile *> macho::makeDylibFromTAPI(MemoryBufferRef mbref,
return make<DylibFile>(**result, umbrella);
}
+static DenseSet<CachedHashStringRef> loadedDylibs;
+
+Optional<DylibFile *> macho::loadDylib(MemoryBufferRef mbref,
+ DylibFile *umbrella) {
+ StringRef path = mbref.getBufferIdentifier();
+ if (loadedDylibs.contains(CachedHashStringRef(path)))
+ return {};
+ loadedDylibs.insert(CachedHashStringRef(path));
+
+ file_magic magic = identify_magic(mbref.getBuffer());
+ if (magic == file_magic::tapi_file)
+ return makeDylibFromTapi(mbref, umbrella);
+
+ assert(magic == file_magic::macho_dynamically_linked_shared_lib ||
+ magic == file_magic::macho_dynamically_linked_shared_lib_stub);
+ return make<DylibFile>(mbref, umbrella);
+}
+
uint32_t macho::getModTime(StringRef path) {
fs::file_status stat;
if (!fs::status(path, stat))
diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp
index e9e71e0c6a40..92fc7d10ebb0 100644
--- a/lld/MachO/InputFiles.cpp
+++ b/lld/MachO/InputFiles.cpp
@@ -457,12 +457,7 @@ static Optional<DylibFile *> loadDylib(StringRef path, DylibFile *umbrella) {
error("could not read dylib file at " + path);
return {};
}
-
- file_magic magic = identify_magic(mbref->getBuffer());
- if (magic == file_magic::tapi_file)
- return makeDylibFromTAPI(*mbref, umbrella);
- assert(magic == file_magic::macho_dynamically_linked_shared_lib);
- return make<DylibFile>(*mbref, umbrella);
+ return loadDylib(*mbref, umbrella);
}
// TBD files are parsed into a series of TAPI documents (InterfaceFiles), with
@@ -518,11 +513,10 @@ static bool isImplicitlyLinked(StringRef path) {
// -sub_umbrella first to write a test case.
}
-static Optional<DylibFile *> loadReexport(StringRef path, DylibFile *umbrella) {
+void loadReexport(StringRef path, DylibFile *umbrella) {
Optional<DylibFile *> reexport = loadReexportHelper(path, umbrella);
if (reexport && isImplicitlyLinked(path))
inputFiles.push_back(*reexport);
- return reexport;
}
DylibFile::DylibFile(MemoryBufferRef mb, DylibFile *umbrella)
@@ -572,8 +566,7 @@ DylibFile::DylibFile(MemoryBufferRef mb, DylibFile *umbrella)
auto *c = reinterpret_cast<const dylib_command *>(cmd);
StringRef reexportPath =
reinterpret_cast<const char *>(c) + read32le(&c->dylib.name);
- if (Optional<DylibFile *> reexport = loadReexport(reexportPath, umbrella))
- reexported.push_back(*reexport);
+ loadReexport(reexportPath, umbrella);
}
}
@@ -621,9 +614,7 @@ DylibFile::DylibFile(const InterfaceFile &interface, DylibFile *umbrella)
}
for (InterfaceFileRef intfRef : interface.reexportedLibraries())
- if (Optional<DylibFile *> reexport =
- loadReexport(intfRef.getInstallName(), umbrella))
- reexported.push_back(*reexport);
+ loadReexport(intfRef.getInstallName(), umbrella);
if (isTopLevelTapi)
currentTopLevelTapi = nullptr;
diff --git a/lld/MachO/InputFiles.h b/lld/MachO/InputFiles.h
index 2b492280c6f5..e5a1566dda20 100644
--- a/lld/MachO/InputFiles.h
+++ b/lld/MachO/InputFiles.h
@@ -134,7 +134,6 @@ class DylibFile : public InputFile {
uint64_t ordinal = 0; // Ordinal numbering starts from 1, so 0 is a sentinel
bool reexport = false;
bool forceWeakImport = false;
- std::vector<DylibFile *> reexported;
};
// .a file
diff --git a/lld/test/MachO/dylink.s b/lld/test/MachO/dylink.s
index 99d4ef8e081a..2a8e19d966d6 100644
--- a/lld/test/MachO/dylink.s
+++ b/lld/test/MachO/dylink.s
@@ -38,6 +38,20 @@
# CHECK-DAG: __DATA __data 0x{{0*}}[[#%x, DATA_ADDR + 8]] pointer 8 libhello _hello_its_me
# CHECK-DAG: __DATA __data 0x{{0*}}[[#%x, DATA_ADDR + 16]] pointer -15 libgoodbye _goodbye_world
+# RUN: llvm-objdump --macho --all-headers %t/dylink | FileCheck %s \
+# RUN: --check-prefix=LOAD --implicit-check-not LC_LOAD_DYLIB
+## Check that we don't create duplicate LC_LOAD_DYLIBs.
+# RUN: %lld -o %t/dylink -L%t -lhello -lhello -lgoodbye -lgoodbye %t/dylink.o
+# RUN: llvm-objdump --macho --all-headers %t/dylink | FileCheck %s \
+# RUN: --check-prefix=LOAD --implicit-check-not LC_LOAD_DYLIB
+
+# LOAD: cmd LC_LOAD_DYLIB
+# LOAD-NEXT: cmdsize
+# LOAD-NEXT: name @executable_path/libhello.dylib
+# LOAD: cmd LC_LOAD_DYLIB
+# LOAD-NEXT: cmdsize
+# LOAD-NEXT: name @executable_path/libgoodbye.dylib
+
.section __TEXT,__text
.globl _main
diff --git a/lld/test/MachO/implicit-dylibs.s b/lld/test/MachO/implicit-dylibs.s
index 292fedb31dde..2030da423020 100644
--- a/lld/test/MachO/implicit-dylibs.s
+++ b/lld/test/MachO/implicit-dylibs.s
@@ -31,6 +31,11 @@
# RUN: llvm-objdump --macho --all-headers %t/test | FileCheck %s \
# RUN: --check-prefix=LOAD -DDIR=%t --implicit-check-not LC_LOAD_DYLIB
+## Check that we don't create duplicate LC_LOAD_DYLIBs.
+# RUN: %lld -syslibroot %t -o %t/test -lSystem -L%t -lreexporter -ltoplevel %t/test.o
+# RUN: llvm-objdump --macho --all-headers %t/test | FileCheck %s \
+# RUN: --check-prefix=LOAD -DDIR=%t --implicit-check-not LC_LOAD_DYLIB
+
# LOAD: cmd LC_LOAD_DYLIB
# LOAD-NEXT: cmdsize
# LOAD-NEXT: name /usr/lib/libSystem.B.dylib
diff --git a/lld/test/MachO/lc-linker-option.ll b/lld/test/MachO/lc-linker-option.ll
index f3ad60d946f2..617de53d38f9 100644
--- a/lld/test/MachO/lc-linker-option.ll
+++ b/lld/test/MachO/lc-linker-option.ll
@@ -4,14 +4,21 @@
# RUN: llvm-as %t/framework.ll -o %t/framework.o
# RUN: %lld %t/framework.o -o %t/frame
-# RUN: llvm-objdump --macho --all-headers %t/frame | FileCheck --check-prefix=FRAME %s
+# RUN: llvm-objdump --macho --all-headers %t/frame | FileCheck --check-prefix=FRAME %s \
+# RUN: --implicit-check-not LC_LOAD_DYLIB
# FRAME: cmd LC_LOAD_DYLIB
# FRAME-NEXT: cmdsize
# FRAME-NEXT: name /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation
# RUN: llvm-as %t/l.ll -o %t/l.o
# RUN: %lld %t/l.o -o %t/l
-# RUN: llvm-objdump --macho --all-headers %t/l | FileCheck --check-prefix=LIB %s
+# RUN: llvm-objdump --macho --all-headers %t/l | FileCheck --check-prefix=LIB %s \
+# RUN: --implicit-check-not LC_LOAD_DYLIB
+
+## Check that we don't create duplicate LC_LOAD_DYLIBs.
+# RUN: %lld -lSystem %t/l.o -o %t/l
+# RUN: llvm-objdump --macho --all-headers %t/l | FileCheck --check-prefix=LIB %s \
+# RUN: --implicit-check-not LC_LOAD_DYLIB
# LIB: cmd LC_LOAD_DYLIB
# LIB-NEXT: cmdsize
# LIB-NEXT: name /usr/lib/libSystem.B.dylib
@@ -36,7 +43,7 @@ target triple = "x86_64-apple-macosx10.15.0"
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
!0 = !{!"-lSystem"}
-!llvm.linker.options = !{!0}
+!llvm.linker.options = !{!0, !0}
define void @main() {
ret void
More information about the llvm-branch-commits
mailing list