diff options
| author | Jacek Caban <jacek@codeweavers.com> | 2025-02-22 11:20:58 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-02-22 11:20:58 +0100 |
| commit | b09dfbd6995bf83ce9546807ccc285c6d957f6db (patch) | |
| tree | 7fefc43c2e27223bbf2df3489842a34bf4b1b234 /lld/COFF/InputFiles.cpp | |
| parent | 3747ba48477a9592979fed0cd6bdcf29235eacbc (diff) | |
| download | llvm-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.cpp | 43 |
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. |
