[LLD][COFF] Make /wholearchive thin-archive member identifiers consistent (#145487)
A thin archive is an archive/library format where the archive itself contains only references to member object files on disk, rather than embedding the file contents. For the non-/wholearchive case, we use the path to the archive member as the identifier for thin-archive members (see comments in `enqueueArchiveMember`). This patch modifies the /wholearchive path to behave the same way. Apart from consistency, my motivation for fixing this is DTLTO (#126654), where having the member identifier be the path on disk allows distribution of bitcode members during ThinLTO. (cherry picked from commit 9f733f4324412ef89cc7729bf027cdcab912ceff)
This commit is contained in:
parent
f66e874504
commit
64a274fada
@ -274,8 +274,13 @@ void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> mb,
|
||||
make<std::unique_ptr<Archive>>(std::move(file)); // take ownership
|
||||
|
||||
int memberIndex = 0;
|
||||
for (MemoryBufferRef m : getArchiveMembers(ctx, archive))
|
||||
addArchiveBuffer(m, "<whole-archive>", filename, memberIndex++);
|
||||
for (MemoryBufferRef m : getArchiveMembers(ctx, archive)) {
|
||||
if (!archive->isThin())
|
||||
addArchiveBuffer(m, "<whole-archive>", filename, memberIndex++);
|
||||
else
|
||||
addThinArchiveBuffer(m, "<whole-archive>");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
addFile(make<ArchiveFile>(ctx, mbref));
|
||||
@ -386,6 +391,14 @@ void LinkerDriver::addArchiveBuffer(MemoryBufferRef mb, StringRef symName,
|
||||
Log(ctx) << "Loaded " << obj << " for " << symName;
|
||||
}
|
||||
|
||||
void LinkerDriver::addThinArchiveBuffer(MemoryBufferRef mb, StringRef symName) {
|
||||
// Pass an empty string as the archive name and an offset of 0 so that
|
||||
// the original filename is used as the buffer identifier. This is
|
||||
// useful for DTLTO, where having the member identifier be the actual
|
||||
// path on disk enables distribution of bitcode files during ThinLTO.
|
||||
addArchiveBuffer(mb, symName, /*parentName=*/"", /*OffsetInArchive=*/0);
|
||||
}
|
||||
|
||||
void LinkerDriver::enqueueArchiveMember(const Archive::Child &c,
|
||||
const Archive::Symbol &sym,
|
||||
StringRef parentName) {
|
||||
@ -422,11 +435,8 @@ void LinkerDriver::enqueueArchiveMember(const Archive::Child &c,
|
||||
reportBufferError(errorCodeToError(mbOrErr.second), childName);
|
||||
llvm::TimeTraceScope timeScope("Archive: ",
|
||||
mbOrErr.first->getBufferIdentifier());
|
||||
// Pass empty string as archive name so that the original filename is
|
||||
// used as the buffer identifier.
|
||||
ctx.driver.addArchiveBuffer(takeBuffer(std::move(mbOrErr.first)),
|
||||
toCOFFString(ctx, sym), "",
|
||||
/*OffsetInArchive=*/0);
|
||||
ctx.driver.addThinArchiveBuffer(takeBuffer(std::move(mbOrErr.first)),
|
||||
toCOFFString(ctx, sym));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -173,6 +173,7 @@ private:
|
||||
bool lazy);
|
||||
void addArchiveBuffer(MemoryBufferRef mbref, StringRef symName,
|
||||
StringRef parentName, uint64_t offsetInArchive);
|
||||
void addThinArchiveBuffer(MemoryBufferRef mbref, StringRef symName);
|
||||
|
||||
void enqueueTask(std::function<void()> task);
|
||||
bool run();
|
||||
|
@ -22,23 +22,34 @@
|
||||
# SYMTAB: ?f@@YAHXZ in
|
||||
# NO-SYMTAB-NOT: ?f@@YAHXZ in
|
||||
|
||||
# RUN: lld-link /entry:main %t.main.obj %t.lib /out:%t.exe 2>&1 | \
|
||||
# RUN: FileCheck --allow-empty %s
|
||||
# RUN: lld-link /entry:main %t.main.obj %t_thin.lib /out:%t.exe 2>&1 | \
|
||||
# RUN: FileCheck --allow-empty %s
|
||||
# RUN: lld-link /entry:main %t.main.obj /wholearchive:%t_thin.lib /out:%t.exe 2>&1 | \
|
||||
# RUN: FileCheck --allow-empty %s
|
||||
# RUN: echo "/entry:main \"%t.main.obj\" /out:\"%t.exe\"" > %t.rsp
|
||||
|
||||
# RUN: lld-link @%t.rsp %t.lib /verbose 2>&1 | \
|
||||
# RUN: FileCheck %s --check-prefix=LOAD_NON_THIN
|
||||
# RUN: lld-link @%t.rsp %t_thin.lib /verbose 2>&1 | \
|
||||
# RUN: FileCheck %s --check-prefix=LOAD_THIN_SYM
|
||||
# RUN: lld-link @%t.rsp /wholearchive:%t_thin.lib /verbose 2>&1 | \
|
||||
# RUN: FileCheck %s --check-prefix=LOAD_THIN_WHOLE
|
||||
# RUN: lld-link @%t.rsp /wholearchive %t_thin.lib /verbose 2>&1 | \
|
||||
# RUN: FileCheck %s --check-prefix=LOAD_THIN_WHOLE
|
||||
|
||||
# LOAD_NON_THIN: Loaded {{.*}}.lib({{.*}}.obj) for int __cdecl f(void)
|
||||
# LOAD_THIN_SYM: Loaded {{.*}}.obj for int __cdecl f(void)
|
||||
# LOAD_THIN_WHOLE: Loaded {{.*}}.obj for <whole-archive>
|
||||
|
||||
# RUN: rm %t.lib.obj
|
||||
# RUN: lld-link /entry:main %t.main.obj %t.lib /out:%t.exe 2>&1 | \
|
||||
# RUN: FileCheck --allow-empty %s
|
||||
# RUN: env LLD_IN_TEST=1 not lld-link /entry:main %t.main.obj %t_thin.lib \
|
||||
# RUN: /out:%t.exe 2>&1 | FileCheck --check-prefix=NOOBJ %s
|
||||
# RUN: env LLD_IN_TEST=1 not lld-link /entry:main %t.main.obj %t_thin.lib /out:%t.exe \
|
||||
# RUN: /demangle:no 2>&1 | FileCheck --check-prefix=NOOBJNODEMANGLE %s
|
||||
# RUN: lld-link @%t.rsp %t.lib 2>&1 | \
|
||||
# RUN: FileCheck %s --check-prefix=ERR --allow-empty
|
||||
# RUN: env LLD_IN_TEST=1 not lld-link @%t.rsp %t_thin.lib 2>&1 | \
|
||||
# RUN: FileCheck %s --check-prefix=NOOBJ
|
||||
# RUN: env LLD_IN_TEST=1 not lld-link @%t.rsp /wholearchive:%t_thin.lib 2>&1 | \
|
||||
# RUN: FileCheck %s --check-prefix=NOOBJWHOLE
|
||||
# RUN: env LLD_IN_TEST=1 not lld-link @%t.rsp %t_thin.lib /demangle:no 2>&1 | \
|
||||
# RUN: FileCheck %s --check-prefix=NOOBJNODEMANGLE
|
||||
|
||||
# CHECK-NOT: error: could not get the buffer for the member defining
|
||||
# ERR-NOT: error: could not get the buffer for the member defining
|
||||
# NOOBJ: error: could not get the buffer for the member defining symbol int __cdecl f(void): {{.*}}.lib({{.*}}.lib.obj):
|
||||
# NOOBJWHOLE: error: {{.*}}.lib: could not get the buffer for a child of the archive: '{{.*}}.obj'
|
||||
# NOOBJNODEMANGLE: error: could not get the buffer for the member defining symbol ?f@@YAHXZ: {{.*}}.lib({{.*}}.lib.obj):
|
||||
|
||||
.text
|
||||
|
Loading…
x
Reference in New Issue
Block a user