@@ -117,8 +117,6 @@ static coff_symbol_generic *cloneSymbol(COFFSymbolRef sym) {
117117// Skip importing DllMain thunks from import libraries.
118118static bool fixupDllMain (COFFLinkerContext &ctx, llvm::object::Archive *file,
119119 const Archive::Symbol &sym, bool &skipDllMain) {
120- if (skipDllMain)
121- return true ;
122120 const Archive::Child &c =
123121 CHECK (sym.getMember (), file->getFileName () +
124122 " : could not get the member for symbol " +
@@ -144,15 +142,15 @@ static bool fixupDllMain(COFFLinkerContext &ctx, llvm::object::Archive *file,
144142}
145143
146144ArchiveFile::ArchiveFile (COFFLinkerContext &ctx, MemoryBufferRef m)
147- : InputFile(ctx.symtab, ArchiveKind, m) {}
145+ : InputFile(ctx.symtab, ArchiveKind, m) {
146+ // Parse a MemoryBufferRef as an archive file.
147+ file = CHECK (Archive::create (mb), this );
148+ }
148149
149150void ArchiveFile::parse () {
150151 COFFLinkerContext &ctx = symtab.ctx ;
151152 SymbolTable *archiveSymtab = &symtab;
152153
153- // Parse a MemoryBufferRef as an archive file.
154- file = CHECK (Archive::create (mb), this );
155-
156154 // Try to read symbols from ECSYMBOLS section on ARM64EC.
157155 if (ctx.symtab .isEC ()) {
158156 iterator_range<Archive::symbol_iterator> symbols =
@@ -168,56 +166,79 @@ void ArchiveFile::parse() {
168166 // be either a native-only ARM64 or x86_64 archive. Check the machine type
169167 // of the object containing a symbol to determine which symbol table to
170168 // use.
171- Archive::symbol_iterator sym = file->symbol_begin ();
172- if (sym != file->symbol_end ()) {
173- MachineTypes machine = IMAGE_FILE_MACHINE_UNKNOWN;
174- Archive::Child child =
175- CHECK (sym->getMember (),
176- file->getFileName () +
177- " : could not get the buffer for a child of the archive" );
178- MemoryBufferRef mb = CHECK (
179- child.getMemoryBufferRef (),
180- file->getFileName () +
181- " : could not get the buffer for a child buffer of the archive" );
182- switch (identify_magic (mb.getBuffer ())) {
183- case file_magic::coff_object: {
184- std::unique_ptr<COFFObjectFile> obj =
185- CHECK (COFFObjectFile::create (mb),
186- check (child.getName ()) + " :" + " : not a valid COFF file" );
187- machine = MachineTypes (obj->getMachine ());
188- break ;
189- }
190- case file_magic::coff_import_library:
191- machine = MachineTypes (COFFImportFile (mb).getMachine ());
192- break ;
193- case file_magic::bitcode: {
194- std::unique_ptr<lto::InputFile> obj =
195- check (lto::InputFile::create (mb));
196- machine = BitcodeFile::getMachineType (obj.get ());
197- break ;
198- }
199- default :
200- break ;
201- }
169+ MachineTypes machine = getMachineType ();
170+ if (machine != IMAGE_FILE_MACHINE_UNKNOWN)
202171 archiveSymtab = &ctx.getSymtab (machine);
203- }
204172 }
205173 }
206174
207- // Read the symbol table to construct Lazy objects.
208175 bool skipDllMain = false ;
176+ StringRef mangledDllMain, impMangledDllMain;
177+
178+ // The calls below will fail if we haven't set the machine type yet. Instead
179+ // of failing, it is preferable to skip this "imported DllMain" check if we
180+ // don't know the machine type at this point.
181+ if (!file->isEmpty () && ctx.config .machine != IMAGE_FILE_MACHINE_UNKNOWN) {
182+ mangledDllMain = archiveSymtab->mangle (" DllMain" );
183+ impMangledDllMain = uniqueSaver ().save (" __imp_" + mangledDllMain);
184+ }
185+
186+ // Read the symbol table to construct Lazy objects.
209187 for (const Archive::Symbol &sym : file->symbols ()) {
210188 // If an import library provides the DllMain symbol, skip importing it, as
211189 // we should be using our own DllMain, not another DLL's DllMain.
212- if (sym. getName () == " __imp_DllMain " || sym.getName () == " DllMain " ||
213- sym.getName () == " _DllMain " ) {
214- if (fixupDllMain (ctx, file.get (), sym, skipDllMain))
190+ if (!mangledDllMain. empty () && ( sym.getName () == mangledDllMain ||
191+ sym.getName () == impMangledDllMain) ) {
192+ if (skipDllMain || fixupDllMain (ctx, file.get (), sym, skipDllMain))
215193 continue ;
216194 }
217195 archiveSymtab->addLazyArchive (this , sym);
218196 }
219197}
220198
199+ MachineTypes ArchiveFile::getMachineType () const {
200+ if (!file)
201+ return IMAGE_FILE_MACHINE_UNKNOWN;
202+ if (file->isEmpty ())
203+ return IMAGE_FILE_MACHINE_UNKNOWN;
204+ Archive::symbol_iterator sym = file->symbol_begin ();
205+ if (sym != file->symbol_end ()) {
206+ Expected<Archive::Child> child = sym->getMember ();
207+ if (!child) {
208+ consumeError (child.takeError ());
209+ return IMAGE_FILE_MACHINE_UNKNOWN;
210+ }
211+ Expected<MemoryBufferRef> mb = child->getMemoryBufferRef ();
212+ if (!mb) {
213+ consumeError (mb.takeError ());
214+ return IMAGE_FILE_MACHINE_UNKNOWN;
215+ }
216+ switch (identify_magic (mb->getBuffer ())) {
217+ case file_magic::coff_object: {
218+ Expected<std::unique_ptr<COFFObjectFile>> obj =
219+ COFFObjectFile::create (*mb);
220+ if (!obj) {
221+ consumeError (obj.takeError ());
222+ return IMAGE_FILE_MACHINE_UNKNOWN;
223+ }
224+ return MachineTypes ((*obj)->getMachine ());
225+ break ;
226+ }
227+ case file_magic::coff_import_library:
228+ return MachineTypes (COFFImportFile (*mb).getMachine ());
229+ break ;
230+ case file_magic::bitcode: {
231+ std::unique_ptr<lto::InputFile> obj = check (lto::InputFile::create (*mb));
232+ return BitcodeFile::getMachineType (obj.get ());
233+ break ;
234+ }
235+ default :
236+ break ;
237+ }
238+ }
239+ return IMAGE_FILE_MACHINE_UNKNOWN;
240+ }
241+
221242// Returns a buffer pointing to a member file containing a given symbol.
222243void ArchiveFile::addMember (const Archive::Symbol &sym) {
223244 const Archive::Child &c =
0 commit comments