2929#include " llvm/LTO/LTO.h"
3030#include " llvm/Object/Binary.h"
3131#include " llvm/Object/COFF.h"
32+ #include " llvm/Object/COFFImportFile.h"
3233#include " llvm/Support/Casting.h"
3334#include " llvm/Support/Endian.h"
3435#include " llvm/Support/Error.h"
@@ -122,6 +123,8 @@ ArchiveFile::ArchiveFile(COFFLinkerContext &ctx, MemoryBufferRef m)
122123
123124void ArchiveFile::parse () {
124125 COFFLinkerContext &ctx = symtab.ctx ;
126+ SymbolTable *archiveSymtab = &symtab;
127+
125128 // Parse a MemoryBufferRef as an archive file.
126129 file = CHECK (Archive::create (mb), this );
127130
@@ -136,12 +139,50 @@ void ArchiveFile::parse() {
136139 // Read both EC and native symbols on ARM64X.
137140 if (!ctx.hybridSymtab )
138141 return ;
142+ } else if (ctx.hybridSymtab ) {
143+ // If the ECSYMBOLS section is missing in the archive, the archive could
144+ // be either a native-only ARM64 or x86_64 archive. Check the machine type
145+ // of the object containing a symbol to determine which symbol table to
146+ // use.
147+ Archive::symbol_iterator sym = file->symbol_begin ();
148+ if (sym != file->symbol_end ()) {
149+ MachineTypes machine = IMAGE_FILE_MACHINE_UNKNOWN;
150+ Archive::Child child =
151+ CHECK (sym->getMember (),
152+ file->getFileName () +
153+ " : could not get the buffer for a child of the archive" );
154+ MemoryBufferRef mb = CHECK (
155+ child.getMemoryBufferRef (),
156+ file->getFileName () +
157+ " : could not get the buffer for a child buffer of the archive" );
158+ switch (identify_magic (mb.getBuffer ())) {
159+ case file_magic::coff_object: {
160+ std::unique_ptr<COFFObjectFile> obj =
161+ CHECK (COFFObjectFile::create (mb),
162+ check (child.getName ()) + " :" + " : not a valid COFF file" );
163+ machine = MachineTypes (obj->getMachine ());
164+ break ;
165+ }
166+ case file_magic::coff_import_library:
167+ machine = MachineTypes (COFFImportFile (mb).getMachine ());
168+ break ;
169+ case file_magic::bitcode: {
170+ std::unique_ptr<lto::InputFile> obj =
171+ check (lto::InputFile::create (mb));
172+ machine = BitcodeFile::getMachineType (obj.get ());
173+ break ;
174+ }
175+ default :
176+ break ;
177+ }
178+ archiveSymtab = &ctx.getSymtab (machine);
179+ }
139180 }
140181 }
141182
142183 // Read the symbol table to construct Lazy objects.
143184 for (const Archive::Symbol &sym : file->symbols ())
144- ctx. symtab . addLazyArchive (this , sym);
185+ archiveSymtab-> addLazyArchive (this , sym);
145186}
146187
147188// Returns a buffer pointing to a member file containing a given symbol.
0 commit comments