aboutsummaryrefslogtreecommitdiff
path: root/lld/COFF/InputFiles.cpp
diff options
context:
space:
mode:
authorJacek Caban <jacek@codeweavers.com>2025-02-22 11:20:58 +0100
committerGitHub <noreply@github.com>2025-02-22 11:20:58 +0100
commitb09dfbd6995bf83ce9546807ccc285c6d957f6db (patch)
tree7fefc43c2e27223bbf2df3489842a34bf4b1b234 /lld/COFF/InputFiles.cpp
parent3747ba48477a9592979fed0cd6bdcf29235eacbc (diff)
downloadllvm-b09dfbd6995bf83ce9546807ccc285c6d957f6db.tar.gz
llvm-b09dfbd6995bf83ce9546807ccc285c6d957f6db.tar.bz2
llvm-b09dfbd6995bf83ce9546807ccc285c6d957f6db.zip
[LLD][COFF] Add support for x86_64 archives on ARM64X (#128241)
If the ECSYMBOLS section is missing in the archive, the archive could be either a native-only ARM64 or x86_64 archive. Check the machine type of the object containing a symbol to determine which symbol table to use.
Diffstat (limited to 'lld/COFF/InputFiles.cpp')
-rw-r--r--lld/COFF/InputFiles.cpp43
1 files changed, 42 insertions, 1 deletions
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index 7b105fb4c17a..bb9f1407b51f 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -29,6 +29,7 @@
#include "llvm/LTO/LTO.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/COFF.h"
+#include "llvm/Object/COFFImportFile.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
@@ -122,6 +123,8 @@ ArchiveFile::ArchiveFile(COFFLinkerContext &ctx, MemoryBufferRef m)
void ArchiveFile::parse() {
COFFLinkerContext &ctx = symtab.ctx;
+ SymbolTable *archiveSymtab = &symtab;
+
// Parse a MemoryBufferRef as an archive file.
file = CHECK(Archive::create(mb), this);
@@ -136,12 +139,50 @@ void ArchiveFile::parse() {
// Read both EC and native symbols on ARM64X.
if (!ctx.hybridSymtab)
return;
+ } else if (ctx.hybridSymtab) {
+ // If the ECSYMBOLS section is missing in the archive, the archive could
+ // be either a native-only ARM64 or x86_64 archive. Check the machine type
+ // of the object containing a symbol to determine which symbol table to
+ // use.
+ Archive::symbol_iterator sym = file->symbol_begin();
+ if (sym != file->symbol_end()) {
+ MachineTypes machine = IMAGE_FILE_MACHINE_UNKNOWN;
+ Archive::Child child =
+ CHECK(sym->getMember(),
+ file->getFileName() +
+ ": could not get the buffer for a child of the archive");
+ MemoryBufferRef mb = CHECK(
+ child.getMemoryBufferRef(),
+ file->getFileName() +
+ ": could not get the buffer for a child buffer of the archive");
+ switch (identify_magic(mb.getBuffer())) {
+ case file_magic::coff_object: {
+ std::unique_ptr<COFFObjectFile> obj =
+ CHECK(COFFObjectFile::create(mb),
+ check(child.getName()) + ":" + ": not a valid COFF file");
+ machine = MachineTypes(obj->getMachine());
+ break;
+ }
+ case file_magic::coff_import_library:
+ machine = MachineTypes(COFFImportFile(mb).getMachine());
+ break;
+ case file_magic::bitcode: {
+ std::unique_ptr<lto::InputFile> obj =
+ check(lto::InputFile::create(mb));
+ machine = BitcodeFile::getMachineType(obj.get());
+ break;
+ }
+ default:
+ break;
+ }
+ archiveSymtab = &ctx.getSymtab(machine);
+ }
}
}
// Read the symbol table to construct Lazy objects.
for (const Archive::Symbol &sym : file->symbols())
- ctx.symtab.addLazyArchive(this, sym);
+ archiveSymtab->addLazyArchive(this, sym);
}
// Returns a buffer pointing to a member file containing a given symbol.