Skip to content

Commit 146eb7a

Browse files
committed
Re-land "COFF: migrate def parser from LLD to LLVM"
This reverts commit r304561 and re-lands r303490 & co. The fix was to use "SymbolName" when translating LLD's internal export list to lib/Object's short export struct. The SymbolName reflects the actual symbol name, which may include fastcall and stdcall mangling bits not included in the /EXPORT or .def file EXPORTS name: @@ -434,8 +434,7 @@ std::vector<COFFShortExport> createCOFFShortExportFromConfig() { std::vector<COFFShortExport> Exports; for (Export &E1 : Config->Exports) { COFFShortExport E2; - E2.Name = E1.Name; + // Use SymbolName, which will have any stdcall or fastcall qualifiers. + E2.Name = E1.SymbolName; E2.ExtName = E1.ExtName; E2.Ordinal = E1.Ordinal; E2.Noname = E1.Noname; llvm-svn: 304573
1 parent 5a1ed78 commit 146eb7a

File tree

8 files changed

+329
-140
lines changed

8 files changed

+329
-140
lines changed

lld/COFF/CMakeLists.txt

-2
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,9 @@ add_lld_library(lldCOFF
1414
Error.cpp
1515
ICF.cpp
1616
InputFiles.cpp
17-
Librarian.cpp
1817
LTO.cpp
1918
MapFile.cpp
2019
MarkLive.cpp
21-
ModuleDef.cpp
2220
PDB.cpp
2321
Strings.cpp
2422
SymbolTable.cpp

lld/COFF/Driver.cpp

+84-4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include "llvm/ADT/Optional.h"
2020
#include "llvm/ADT/StringSwitch.h"
2121
#include "llvm/Object/ArchiveWriter.h"
22+
#include "llvm/Object/COFFImportFile.h"
23+
#include "llvm/Object/COFFModuleDefinition.h"
2224
#include "llvm/Option/Arg.h"
2325
#include "llvm/Option/ArgList.h"
2426
#include "llvm/Option/Option.h"
@@ -35,6 +37,7 @@
3537
#include <future>
3638

3739
using namespace llvm;
40+
using namespace llvm::object;
3841
using namespace llvm::COFF;
3942
using llvm::sys::Process;
4043
using llvm::sys::fs::file_magic;
@@ -419,6 +422,85 @@ static std::string getMapFile(const opt::InputArgList &Args) {
419422
return (OutFile.substr(0, OutFile.rfind('.')) + ".map").str();
420423
}
421424

425+
static std::string getImplibPath() {
426+
if (!Config->Implib.empty())
427+
return Config->Implib;
428+
SmallString<128> Out = StringRef(Config->OutputFile);
429+
sys::path::replace_extension(Out, ".lib");
430+
return Out.str();
431+
}
432+
433+
std::vector<COFFShortExport> createCOFFShortExportFromConfig() {
434+
std::vector<COFFShortExport> Exports;
435+
for (Export &E1 : Config->Exports) {
436+
COFFShortExport E2;
437+
// Use SymbolName, which will have any stdcall or fastcall qualifiers.
438+
E2.Name = E1.SymbolName;
439+
E2.ExtName = E1.ExtName;
440+
E2.Ordinal = E1.Ordinal;
441+
E2.Noname = E1.Noname;
442+
E2.Data = E1.Data;
443+
E2.Private = E1.Private;
444+
E2.Constant = E1.Constant;
445+
Exports.push_back(E2);
446+
}
447+
return Exports;
448+
}
449+
450+
static void createImportLibrary() {
451+
std::vector<COFFShortExport> Exports = createCOFFShortExportFromConfig();
452+
std::string DLLName = sys::path::filename(Config->OutputFile);
453+
std::string Path = getImplibPath();
454+
writeImportLibrary(DLLName, Path, Exports, Config->Machine);
455+
}
456+
457+
static void parseModuleDefs(StringRef Path) {
458+
std::unique_ptr<MemoryBuffer> MB = check(
459+
MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path);
460+
MemoryBufferRef MBRef = MB->getMemBufferRef();
461+
462+
Expected<COFFModuleDefinition> Def =
463+
parseCOFFModuleDefinition(MBRef, Config->Machine);
464+
if (!Def)
465+
fatal(errorToErrorCode(Def.takeError()).message());
466+
467+
COFFModuleDefinition &M = *Def;
468+
if (Config->OutputFile.empty())
469+
Config->OutputFile = Saver.save(M.OutputFile);
470+
471+
if (M.ImageBase)
472+
Config->ImageBase = M.ImageBase;
473+
if (M.StackReserve)
474+
Config->StackReserve = M.StackReserve;
475+
if (M.StackCommit)
476+
Config->StackCommit = M.StackCommit;
477+
if (M.HeapReserve)
478+
Config->HeapReserve = M.HeapReserve;
479+
if (M.HeapCommit)
480+
Config->HeapCommit = M.HeapCommit;
481+
if (M.MajorImageVersion)
482+
Config->MajorImageVersion = M.MajorImageVersion;
483+
if (M.MinorImageVersion)
484+
Config->MinorImageVersion = M.MinorImageVersion;
485+
if (M.MajorOSVersion)
486+
Config->MajorOSVersion = M.MajorOSVersion;
487+
if (M.MinorOSVersion)
488+
Config->MinorOSVersion = M.MinorOSVersion;
489+
490+
for (COFFShortExport E1 : M.Exports) {
491+
Export E2;
492+
E2.Name = Saver.save(E1.Name);
493+
if (E1.isWeak())
494+
E2.ExtName = Saver.save(E1.ExtName);
495+
E2.Ordinal = E1.Ordinal;
496+
E2.Noname = E1.Noname;
497+
E2.Data = E1.Data;
498+
E2.Private = E1.Private;
499+
E2.Constant = E1.Constant;
500+
Config->Exports.push_back(E2);
501+
}
502+
}
503+
422504
std::vector<MemoryBufferRef> getArchiveMembers(Archive *File) {
423505
std::vector<MemoryBufferRef> V;
424506
Error Err = Error::success();
@@ -912,9 +994,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
912994
// Handle /def
913995
if (auto *Arg = Args.getLastArg(OPT_deffile)) {
914996
// parseModuleDefs mutates Config object.
915-
parseModuleDefs(
916-
takeBuffer(check(MemoryBuffer::getFile(Arg->getValue()),
917-
Twine("could not open ") + Arg->getValue())));
997+
parseModuleDefs(Arg->getValue());
918998
}
919999

9201000
// Handle /delayload
@@ -1034,7 +1114,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
10341114
// need to create a .lib file.
10351115
if (!Config->Exports.empty() || Config->DLL) {
10361116
fixupExports();
1037-
writeImportLibrary();
1117+
createImportLibrary();
10381118
assignExportOrdinals();
10391119
}
10401120

lld/COFF/Driver.h

-3
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,6 @@ class LinkerDriver {
124124
std::vector<MemoryBufferRef> Resources;
125125
};
126126

127-
void parseModuleDefs(MemoryBufferRef MB);
128-
void writeImportLibrary();
129-
130127
// Functions below this line are defined in DriverUtils.cpp.
131128

132129
void printHelp(const char *Argv0);

llvm/include/llvm/Object/COFFImportFile.h

+33-1
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@
99
//
1010
// COFF short import file is a special kind of file which contains
1111
// only symbol names for DLL-exported symbols. This class implements
12-
// SymbolicFile interface for the file.
12+
// exporting of Symbols to create libraries and a SymbolicFile
13+
// interface for the file type.
1314
//
1415
//===----------------------------------------------------------------------===//
1516

1617
#ifndef LLVM_OBJECT_COFF_IMPORT_FILE_H
1718
#define LLVM_OBJECT_COFF_IMPORT_FILE_H
1819

20+
#include "llvm/ADT/ArrayRef.h"
1921
#include "llvm/Object/COFF.h"
2022
#include "llvm/Object/IRObjectFile.h"
2123
#include "llvm/Object/ObjectFile.h"
@@ -68,6 +70,36 @@ class COFFImportFile : public SymbolicFile {
6870
}
6971
};
7072

73+
struct COFFShortExport {
74+
std::string Name;
75+
std::string ExtName;
76+
77+
uint16_t Ordinal = 0;
78+
bool Noname = false;
79+
bool Data = false;
80+
bool Private = false;
81+
bool Constant = false;
82+
83+
bool isWeak() {
84+
return ExtName.size() && ExtName != Name;
85+
}
86+
87+
friend bool operator==(const COFFShortExport &L, const COFFShortExport &R) {
88+
return L.Name == R.Name && L.ExtName == R.ExtName &&
89+
L.Ordinal == R.Ordinal && L.Noname == R.Noname &&
90+
L.Data == R.Data && L.Private == R.Private;
91+
}
92+
93+
friend bool operator!=(const COFFShortExport &L, const COFFShortExport &R) {
94+
return !(L == R);
95+
}
96+
};
97+
98+
std::error_code writeImportLibrary(StringRef DLLName,
99+
StringRef Path,
100+
ArrayRef<COFFShortExport> Exports,
101+
COFF::MachineTypes Machine);
102+
71103
} // namespace object
72104
} // namespace llvm
73105

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//===--- COFFModuleDefinition.h ---------------------------------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
// Windows-specific.
11+
// A parser for the module-definition file (.def file).
12+
// Parsed results are directly written to Config global variable.
13+
//
14+
// The format of module-definition files are described in this document:
15+
// https://msdn.microsoft.com/en-us/library/28d6s79h.aspx
16+
//
17+
//===----------------------------------------------------------------------===//
18+
19+
20+
#ifndef LLVM_OBJECT_COFF_MODULE_DEFINITION_H
21+
#define LLVM_OBJECT_COFF_MODULE_DEFINITION_H
22+
23+
#include "llvm/Object/COFFImportFile.h"
24+
#include "llvm/Object/COFF.h"
25+
26+
namespace llvm {
27+
namespace object {
28+
29+
struct COFFModuleDefinition {
30+
std::vector<COFFShortExport> Exports;
31+
std::string OutputFile;
32+
uint64_t ImageBase = 0;
33+
uint64_t StackReserve = 0;
34+
uint64_t StackCommit = 0;
35+
uint64_t HeapReserve = 0;
36+
uint64_t HeapCommit = 0;
37+
uint32_t MajorImageVersion = 0;
38+
uint32_t MinorImageVersion = 0;
39+
uint32_t MajorOSVersion = 0;
40+
uint32_t MinorOSVersion = 0;
41+
};
42+
43+
Expected<COFFModuleDefinition>
44+
parseCOFFModuleDefinition(MemoryBufferRef MB, COFF::MachineTypes Machine);
45+
46+
} // End namespace object.
47+
} // End namespace llvm.
48+
49+
#endif

llvm/lib/Object/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ add_llvm_library(LLVMObject
22
Archive.cpp
33
ArchiveWriter.cpp
44
Binary.cpp
5+
COFFImportFile.cpp
6+
COFFModuleDefinition.cpp
57
COFFObjectFile.cpp
68
Decompressor.cpp
79
ELF.cpp

0 commit comments

Comments
 (0)