Skip to content

Commit a2c683b

Browse files
authored
[LLD][COFF] Use EC symbol table for exports defined in module definition files (#123849)
1 parent 68c6b2e commit a2c683b

File tree

5 files changed

+77
-65
lines changed

5 files changed

+77
-65
lines changed

lld/COFF/Driver.cpp

Lines changed: 1 addition & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
#include "llvm/LTO/LTO.h"
3131
#include "llvm/Object/ArchiveWriter.h"
3232
#include "llvm/Object/COFFImportFile.h"
33-
#include "llvm/Object/COFFModuleDefinition.h"
3433
#include "llvm/Option/Arg.h"
3534
#include "llvm/Option/ArgList.h"
3635
#include "llvm/Option/Option.h"
@@ -1012,67 +1011,6 @@ void LinkerDriver::createImportLibrary(bool asLib) {
10121011
}
10131012
}
10141013

1015-
void LinkerDriver::parseModuleDefs(StringRef path) {
1016-
llvm::TimeTraceScope timeScope("Parse def file");
1017-
std::unique_ptr<MemoryBuffer> mb =
1018-
CHECK(MemoryBuffer::getFile(path, /*IsText=*/false,
1019-
/*RequiresNullTerminator=*/false,
1020-
/*IsVolatile=*/true),
1021-
"could not open " + path);
1022-
COFFModuleDefinition m = check(parseCOFFModuleDefinition(
1023-
mb->getMemBufferRef(), ctx.config.machine, ctx.config.mingw));
1024-
1025-
// Include in /reproduce: output if applicable.
1026-
ctx.driver.takeBuffer(std::move(mb));
1027-
1028-
if (ctx.config.outputFile.empty())
1029-
ctx.config.outputFile = std::string(saver().save(m.OutputFile));
1030-
ctx.config.importName = std::string(saver().save(m.ImportName));
1031-
if (m.ImageBase)
1032-
ctx.config.imageBase = m.ImageBase;
1033-
if (m.StackReserve)
1034-
ctx.config.stackReserve = m.StackReserve;
1035-
if (m.StackCommit)
1036-
ctx.config.stackCommit = m.StackCommit;
1037-
if (m.HeapReserve)
1038-
ctx.config.heapReserve = m.HeapReserve;
1039-
if (m.HeapCommit)
1040-
ctx.config.heapCommit = m.HeapCommit;
1041-
if (m.MajorImageVersion)
1042-
ctx.config.majorImageVersion = m.MajorImageVersion;
1043-
if (m.MinorImageVersion)
1044-
ctx.config.minorImageVersion = m.MinorImageVersion;
1045-
if (m.MajorOSVersion)
1046-
ctx.config.majorOSVersion = m.MajorOSVersion;
1047-
if (m.MinorOSVersion)
1048-
ctx.config.minorOSVersion = m.MinorOSVersion;
1049-
1050-
for (COFFShortExport e1 : m.Exports) {
1051-
Export e2;
1052-
// Renamed exports are parsed and set as "ExtName = Name". If Name has
1053-
// the form "OtherDll.Func", it shouldn't be a normal exported
1054-
// function but a forward to another DLL instead. This is supported
1055-
// by both MS and GNU linkers.
1056-
if (!e1.ExtName.empty() && e1.ExtName != e1.Name &&
1057-
StringRef(e1.Name).contains('.')) {
1058-
e2.name = saver().save(e1.ExtName);
1059-
e2.forwardTo = saver().save(e1.Name);
1060-
} else {
1061-
e2.name = saver().save(e1.Name);
1062-
e2.extName = saver().save(e1.ExtName);
1063-
}
1064-
e2.exportAs = saver().save(e1.ExportAs);
1065-
e2.importName = saver().save(e1.ImportName);
1066-
e2.ordinal = e1.Ordinal;
1067-
e2.noname = e1.Noname;
1068-
e2.data = e1.Data;
1069-
e2.isPrivate = e1.Private;
1070-
e2.constant = e1.Constant;
1071-
e2.source = ExportSource::ModuleDefinition;
1072-
ctx.symtab.exports.push_back(e2);
1073-
}
1074-
}
1075-
10761014
void LinkerDriver::enqueueTask(std::function<void()> task) {
10771015
taskQueue.push_back(std::move(task));
10781016
}
@@ -2352,7 +2290,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
23522290
// Handle /def
23532291
if (auto *arg = args.getLastArg(OPT_deffile)) {
23542292
// parseModuleDefs mutates Config object.
2355-
parseModuleDefs(arg->getValue());
2293+
mainSymtab.parseModuleDefs(arg->getValue());
23562294
}
23572295

23582296
// Handle generation of import library from a def file.

lld/COFF/Driver.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,6 @@ class LinkerDriver {
143143
// Used by the resolver to parse .drectve section contents.
144144
void parseDirectives(InputFile *file);
145145

146-
void parseModuleDefs(StringRef path);
147-
148146
// Parse an /order file. If an option is given, the linker places COMDAT
149147
// sections int he same order as their names appear in the given file.
150148
void parseOrderFile(StringRef arg);

lld/COFF/SymbolTable.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "llvm/IR/LLVMContext.h"
2121
#include "llvm/IR/Mangler.h"
2222
#include "llvm/LTO/LTO.h"
23+
#include "llvm/Object/COFFModuleDefinition.h"
2324
#include "llvm/Support/Debug.h"
2425
#include "llvm/Support/GlobPattern.h"
2526
#include "llvm/Support/Parallel.h"
@@ -29,6 +30,7 @@
2930

3031
using namespace llvm;
3132
using namespace llvm::COFF;
33+
using namespace llvm::object;
3234
using namespace llvm::support;
3335

3436
namespace lld::coff {
@@ -1253,6 +1255,67 @@ void SymbolTable::assignExportOrdinals() {
12531255
<< Twine(std::numeric_limits<uint16_t>::max()) << ")";
12541256
}
12551257

1258+
void SymbolTable::parseModuleDefs(StringRef path) {
1259+
llvm::TimeTraceScope timeScope("Parse def file");
1260+
std::unique_ptr<MemoryBuffer> mb =
1261+
CHECK(MemoryBuffer::getFile(path, /*IsText=*/false,
1262+
/*RequiresNullTerminator=*/false,
1263+
/*IsVolatile=*/true),
1264+
"could not open " + path);
1265+
COFFModuleDefinition m = check(parseCOFFModuleDefinition(
1266+
mb->getMemBufferRef(), machine, ctx.config.mingw));
1267+
1268+
// Include in /reproduce: output if applicable.
1269+
ctx.driver.takeBuffer(std::move(mb));
1270+
1271+
if (ctx.config.outputFile.empty())
1272+
ctx.config.outputFile = std::string(saver().save(m.OutputFile));
1273+
ctx.config.importName = std::string(saver().save(m.ImportName));
1274+
if (m.ImageBase)
1275+
ctx.config.imageBase = m.ImageBase;
1276+
if (m.StackReserve)
1277+
ctx.config.stackReserve = m.StackReserve;
1278+
if (m.StackCommit)
1279+
ctx.config.stackCommit = m.StackCommit;
1280+
if (m.HeapReserve)
1281+
ctx.config.heapReserve = m.HeapReserve;
1282+
if (m.HeapCommit)
1283+
ctx.config.heapCommit = m.HeapCommit;
1284+
if (m.MajorImageVersion)
1285+
ctx.config.majorImageVersion = m.MajorImageVersion;
1286+
if (m.MinorImageVersion)
1287+
ctx.config.minorImageVersion = m.MinorImageVersion;
1288+
if (m.MajorOSVersion)
1289+
ctx.config.majorOSVersion = m.MajorOSVersion;
1290+
if (m.MinorOSVersion)
1291+
ctx.config.minorOSVersion = m.MinorOSVersion;
1292+
1293+
for (COFFShortExport e1 : m.Exports) {
1294+
Export e2;
1295+
// Renamed exports are parsed and set as "ExtName = Name". If Name has
1296+
// the form "OtherDll.Func", it shouldn't be a normal exported
1297+
// function but a forward to another DLL instead. This is supported
1298+
// by both MS and GNU linkers.
1299+
if (!e1.ExtName.empty() && e1.ExtName != e1.Name &&
1300+
StringRef(e1.Name).contains('.')) {
1301+
e2.name = saver().save(e1.ExtName);
1302+
e2.forwardTo = saver().save(e1.Name);
1303+
} else {
1304+
e2.name = saver().save(e1.Name);
1305+
e2.extName = saver().save(e1.ExtName);
1306+
}
1307+
e2.exportAs = saver().save(e1.ExportAs);
1308+
e2.importName = saver().save(e1.ImportName);
1309+
e2.ordinal = e1.Ordinal;
1310+
e2.noname = e1.Noname;
1311+
e2.data = e1.Data;
1312+
e2.isPrivate = e1.Private;
1313+
e2.constant = e1.Constant;
1314+
e2.source = ExportSource::ModuleDefinition;
1315+
exports.push_back(e2);
1316+
}
1317+
}
1318+
12561319
Symbol *SymbolTable::addUndefined(StringRef name) {
12571320
return addUndefined(name, nullptr, false);
12581321
}

lld/COFF/SymbolTable.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ class SymbolTable {
160160

161161
void fixupExports();
162162
void assignExportOrdinals();
163+
void parseModuleDefs(StringRef path);
163164

164165
// Iterates symbols in non-determinstic hash table order.
165166
template <typename T> void forEachSymbol(T callback) {

lld/test/COFF/arm64x-export.test

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@ RUN: loadconfig-arm64.obj loadconfig-arm64ec.obj arm64ec-drectve.obj -n
5555
RUN: llvm-objdump -d out-drectve-ec.dll | FileCheck --check-prefix=DISASM-EC %s
5656
RUN: llvm-readobj --headers --coff-exports out-drectve-ec.dll | FileCheck --check-prefix=EXPORTS-EC %s
5757

58+
# A command-line def file applies only to EC exports.
59+
60+
RUN: lld-link -machine:arm64x -dll -out:out-def-ec.dll arm64ec-func.obj arm64-func.obj \
61+
RUN: loadconfig-arm64.obj loadconfig-arm64ec.obj -def:func.def -noentry
62+
RUN: llvm-objdump -d out-def-ec.dll | FileCheck --check-prefix=DISASM-EC %s
63+
RUN: llvm-readobj --headers --coff-exports out-def-ec.dll | FileCheck --check-prefix=EXPORTS-EC %s
64+
5865
# Export using the EC .edata section.
5966

6067
RUN: lld-link -machine:arm64x -dll -out:out-edata-ec.dll arm64ec-func.obj arm64-func.obj \
@@ -227,3 +234,8 @@ funcname_func:
227234

228235
name:
229236
.asciz "out-edata.dll"
237+
238+
#--- func.def
239+
LIBRARY out.dll
240+
EXPORTS
241+
func

0 commit comments

Comments
 (0)