29
29
#include " llvm/LTO/LTO.h"
30
30
#include " llvm/Object/Binary.h"
31
31
#include " llvm/Object/COFF.h"
32
+ #include " llvm/Object/COFFImportFile.h"
32
33
#include " llvm/Support/Casting.h"
33
34
#include " llvm/Support/Endian.h"
34
35
#include " llvm/Support/Error.h"
@@ -122,6 +123,8 @@ ArchiveFile::ArchiveFile(COFFLinkerContext &ctx, MemoryBufferRef m)
122
123
123
124
void ArchiveFile::parse () {
124
125
COFFLinkerContext &ctx = symtab.ctx ;
126
+ SymbolTable *archiveSymtab = &symtab;
127
+
125
128
// Parse a MemoryBufferRef as an archive file.
126
129
file = CHECK (Archive::create (mb), this );
127
130
@@ -136,12 +139,50 @@ void ArchiveFile::parse() {
136
139
// Read both EC and native symbols on ARM64X.
137
140
if (!ctx.hybridSymtab )
138
141
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
+ }
139
180
}
140
181
}
141
182
142
183
// Read the symbol table to construct Lazy objects.
143
184
for (const Archive::Symbol &sym : file->symbols ())
144
- ctx. symtab . addLazyArchive (this , sym);
185
+ archiveSymtab-> addLazyArchive (this , sym);
145
186
}
146
187
147
188
// Returns a buffer pointing to a member file containing a given symbol.
0 commit comments