[LLD][COFF] Implement support for hybrid IAT on ARM64X (#124189)
In hybrid images, the PE header references a single IAT for both native and EC views, merging entries where possible. When merging isn't feasible, different imports are grouped together, and ARM64X relocations are emitted as needed.
This commit is contained in:
@@ -1172,11 +1172,12 @@ uint64_t Arm64XRelocVal::get() const {
|
||||
|
||||
size_t Arm64XDynamicRelocEntry::getSize() const {
|
||||
switch (type) {
|
||||
case IMAGE_DVRT_ARM64X_FIXUP_TYPE_ZEROFILL:
|
||||
return sizeof(uint16_t); // Just a header.
|
||||
case IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE:
|
||||
return sizeof(uint16_t) + size; // A header and a payload.
|
||||
case IMAGE_DVRT_ARM64X_FIXUP_TYPE_DELTA:
|
||||
case IMAGE_DVRT_ARM64X_FIXUP_TYPE_ZEROFILL:
|
||||
llvm_unreachable("unsupported type");
|
||||
return 2 * sizeof(uint16_t); // A header and a delta.
|
||||
}
|
||||
llvm_unreachable("invalid type");
|
||||
}
|
||||
@@ -1186,6 +1187,9 @@ void Arm64XDynamicRelocEntry::writeTo(uint8_t *buf) const {
|
||||
*out = (offset.get() & 0xfff) | (type << 12);
|
||||
|
||||
switch (type) {
|
||||
case IMAGE_DVRT_ARM64X_FIXUP_TYPE_ZEROFILL:
|
||||
*out |= ((bit_width(size) - 1) << 14); // Encode the size.
|
||||
break;
|
||||
case IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE:
|
||||
*out |= ((bit_width(size) - 1) << 14); // Encode the size.
|
||||
switch (size) {
|
||||
@@ -1203,8 +1207,23 @@ void Arm64XDynamicRelocEntry::writeTo(uint8_t *buf) const {
|
||||
}
|
||||
break;
|
||||
case IMAGE_DVRT_ARM64X_FIXUP_TYPE_DELTA:
|
||||
case IMAGE_DVRT_ARM64X_FIXUP_TYPE_ZEROFILL:
|
||||
llvm_unreachable("unsupported type");
|
||||
int delta = value.get();
|
||||
// Negative offsets use a sign bit in the header.
|
||||
if (delta < 0) {
|
||||
*out |= 1 << 14;
|
||||
delta = -delta;
|
||||
}
|
||||
// Depending on the value, the delta is encoded with a shift of 2 or 3 bits.
|
||||
if (delta & 7) {
|
||||
assert(!(delta & 3));
|
||||
delta >>= 2;
|
||||
} else {
|
||||
*out |= (1 << 15);
|
||||
delta >>= 3;
|
||||
}
|
||||
out[1] = delta;
|
||||
assert(!(delta & ~0xffff));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
146
lld/COFF/DLL.cpp
146
lld/COFF/DLL.cpp
@@ -716,6 +716,63 @@ private:
|
||||
void IdataContents::create(COFFLinkerContext &ctx) {
|
||||
std::vector<std::vector<DefinedImportData *>> v = binImports(ctx, imports);
|
||||
|
||||
// In hybrid images, EC and native code are usually very similar,
|
||||
// resulting in a highly similar set of imported symbols. Consequently,
|
||||
// their import tables can be shared, with ARM64X relocations handling any
|
||||
// differences. Identify matching import files used by EC and native code, and
|
||||
// merge them into a single hybrid import entry.
|
||||
if (ctx.hybridSymtab) {
|
||||
for (std::vector<DefinedImportData *> &syms : v) {
|
||||
std::vector<DefinedImportData *> hybridSyms;
|
||||
ImportFile *prev = nullptr;
|
||||
for (DefinedImportData *sym : syms) {
|
||||
ImportFile *file = sym->file;
|
||||
// At this stage, symbols are sorted by base name, ensuring that
|
||||
// compatible import files, if present, are adjacent. Check if the
|
||||
// current symbol's file imports the same symbol as the previously added
|
||||
// one (if any and if it was not already merged). Additionally, verify
|
||||
// that one of them is native while the other is EC. In rare cases,
|
||||
// separate matching import entries may exist within the same namespace,
|
||||
// which cannot be merged.
|
||||
if (!prev || file->isEC() == prev->isEC() ||
|
||||
!file->isSameImport(prev)) {
|
||||
// We can't merge the import file, just add it to hybridSyms
|
||||
// and set prev to its file so that we can try to match the next
|
||||
// symbol.
|
||||
hybridSyms.push_back(sym);
|
||||
prev = file;
|
||||
continue;
|
||||
}
|
||||
|
||||
// A matching symbol may appear in syms in any order. The native variant
|
||||
// exposes a subset of EC symbols and chunks, so always use the EC
|
||||
// variant as the hybrid import file. If the native file was already
|
||||
// added, replace it with the EC symbol in hybridSyms. Otherwise, the EC
|
||||
// variant is already pushed, so we can simply merge it.
|
||||
if (file->isEC()) {
|
||||
hybridSyms.pop_back();
|
||||
hybridSyms.push_back(sym);
|
||||
}
|
||||
|
||||
// Merge import files by storing their hybrid form in the corresponding
|
||||
// file class.
|
||||
prev->hybridFile = file;
|
||||
file->hybridFile = prev;
|
||||
prev = nullptr; // A hybrid import file cannot be merged again.
|
||||
}
|
||||
|
||||
// Sort symbols by type: native-only files first, followed by merged
|
||||
// hybrid files, and then EC-only files.
|
||||
llvm::stable_sort(hybridSyms,
|
||||
[](DefinedImportData *a, DefinedImportData *b) {
|
||||
if (a->file->hybridFile)
|
||||
return !b->file->hybridFile && b->file->isEC();
|
||||
return !a->file->isEC() && b->file->isEC();
|
||||
});
|
||||
syms = std::move(hybridSyms);
|
||||
}
|
||||
}
|
||||
|
||||
// Create .idata contents for each DLL.
|
||||
for (std::vector<DefinedImportData *> &syms : v) {
|
||||
// Create lookup and address tables. If they have external names,
|
||||
@@ -723,19 +780,56 @@ void IdataContents::create(COFFLinkerContext &ctx) {
|
||||
// If they don't (if they are import-by-ordinals), we store only
|
||||
// ordinal values to the table.
|
||||
size_t base = lookups.size();
|
||||
Chunk *lookupsTerminator = nullptr, *addressesTerminator = nullptr;
|
||||
for (DefinedImportData *s : syms) {
|
||||
uint16_t ord = s->getOrdinal();
|
||||
HintNameChunk *hintChunk = nullptr;
|
||||
Chunk *lookupsChunk, *addressesChunk;
|
||||
|
||||
if (s->getExternalName().empty()) {
|
||||
lookups.push_back(make<OrdinalOnlyChunk>(ctx, ord));
|
||||
addresses.push_back(make<OrdinalOnlyChunk>(ctx, ord));
|
||||
lookupsChunk = make<OrdinalOnlyChunk>(ctx, ord);
|
||||
addressesChunk = make<OrdinalOnlyChunk>(ctx, ord);
|
||||
} else {
|
||||
auto *c = make<HintNameChunk>(s->getExternalName(), ord);
|
||||
lookups.push_back(make<LookupChunk>(ctx, c));
|
||||
addresses.push_back(make<LookupChunk>(ctx, c));
|
||||
hints.push_back(c);
|
||||
hintChunk = make<HintNameChunk>(s->getExternalName(), ord);
|
||||
lookupsChunk = make<LookupChunk>(ctx, hintChunk);
|
||||
addressesChunk = make<LookupChunk>(ctx, hintChunk);
|
||||
hints.push_back(hintChunk);
|
||||
}
|
||||
|
||||
if (s->file->impECSym) {
|
||||
// Detect the first EC-only import in the hybrid IAT. Emit null chunk
|
||||
// as a terminator for the native view, and add an ARM64X relocation to
|
||||
// replace it with the correct import for the EC view.
|
||||
//
|
||||
// Additionally, for MSVC compatibility, store the lookup and address
|
||||
// chunks and append them at the end of EC-only imports, where a null
|
||||
// terminator chunk would typically be placed. Since they appear after
|
||||
// the native terminator, they will be ignored in the native view.
|
||||
// In the EC view, they should act as terminators, so emit ZEROFILL
|
||||
// relocations overriding them.
|
||||
if (ctx.hybridSymtab && !lookupsTerminator && s->file->isEC() &&
|
||||
!s->file->hybridFile) {
|
||||
lookupsTerminator = lookupsChunk;
|
||||
addressesTerminator = addressesChunk;
|
||||
lookupsChunk = make<NullChunk>(ctx);
|
||||
addressesChunk = make<NullChunk>(ctx);
|
||||
|
||||
Arm64XRelocVal relocVal = hintChunk;
|
||||
if (!hintChunk)
|
||||
relocVal = (1ULL << 63) | ord;
|
||||
ctx.dynamicRelocs->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE,
|
||||
sizeof(uint64_t), lookupsChunk, relocVal);
|
||||
ctx.dynamicRelocs->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE,
|
||||
sizeof(uint64_t), addressesChunk, relocVal);
|
||||
ctx.dynamicRelocs->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_ZEROFILL,
|
||||
sizeof(uint64_t), lookupsTerminator);
|
||||
ctx.dynamicRelocs->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_ZEROFILL,
|
||||
sizeof(uint64_t), addressesTerminator);
|
||||
}
|
||||
|
||||
lookups.push_back(lookupsChunk);
|
||||
addresses.push_back(addressesChunk);
|
||||
|
||||
if (s->file->isEC()) {
|
||||
auto chunk = make<AuxImportChunk>(s->file);
|
||||
auxIat.push_back(chunk);
|
||||
s->file->impECSym->setLocation(chunk);
|
||||
@@ -743,18 +837,27 @@ void IdataContents::create(COFFLinkerContext &ctx) {
|
||||
chunk = make<AuxImportChunk>(s->file);
|
||||
auxIatCopy.push_back(chunk);
|
||||
s->file->auxImpCopySym->setLocation(chunk);
|
||||
} else if (ctx.hybridSymtab) {
|
||||
// Fill the auxiliary IAT with null chunks for native-only imports.
|
||||
auxIat.push_back(make<NullChunk>(ctx));
|
||||
auxIatCopy.push_back(make<NullChunk>(ctx));
|
||||
}
|
||||
}
|
||||
// Terminate with null values.
|
||||
lookups.push_back(make<NullChunk>(ctx));
|
||||
addresses.push_back(make<NullChunk>(ctx));
|
||||
if (ctx.config.machine == ARM64EC) {
|
||||
lookups.push_back(lookupsTerminator ? lookupsTerminator
|
||||
: make<NullChunk>(ctx));
|
||||
addresses.push_back(addressesTerminator ? addressesTerminator
|
||||
: make<NullChunk>(ctx));
|
||||
if (ctx.symtabEC) {
|
||||
auxIat.push_back(make<NullChunk>(ctx));
|
||||
auxIatCopy.push_back(make<NullChunk>(ctx));
|
||||
}
|
||||
|
||||
for (int i = 0, e = syms.size(); i < e; ++i)
|
||||
for (int i = 0, e = syms.size(); i < e; ++i) {
|
||||
syms[i]->setLocation(addresses[base + i]);
|
||||
if (syms[i]->file->hybridFile)
|
||||
syms[i]->file->hybridFile->impSym->setLocation(addresses[base + i]);
|
||||
}
|
||||
|
||||
// Create the import table header.
|
||||
dllNames.push_back(make<StringChunk>(syms[0]->getDLLName()));
|
||||
@@ -762,6 +865,27 @@ void IdataContents::create(COFFLinkerContext &ctx) {
|
||||
dir->lookupTab = lookups[base];
|
||||
dir->addressTab = addresses[base];
|
||||
dirs.push_back(dir);
|
||||
|
||||
if (ctx.hybridSymtab) {
|
||||
// If native-only imports exist, they will appear as a prefix to all
|
||||
// imports. Emit ARM64X relocations to skip them in the EC view.
|
||||
uint32_t nativeOnly =
|
||||
llvm::find_if(syms,
|
||||
[](DefinedImportData *s) { return s->file->isEC(); }) -
|
||||
syms.begin();
|
||||
if (nativeOnly) {
|
||||
ctx.dynamicRelocs->add(
|
||||
IMAGE_DVRT_ARM64X_FIXUP_TYPE_DELTA, 0,
|
||||
Arm64XRelocVal(
|
||||
dir, offsetof(ImportDirectoryTableEntry, ImportLookupTableRVA)),
|
||||
nativeOnly * sizeof(uint64_t));
|
||||
ctx.dynamicRelocs->add(
|
||||
IMAGE_DVRT_ARM64X_FIXUP_TYPE_DELTA, 0,
|
||||
Arm64XRelocVal(dir, offsetof(ImportDirectoryTableEntry,
|
||||
ImportAddressTableRVA)),
|
||||
nativeOnly * sizeof(uint64_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add null terminator.
|
||||
dirs.push_back(make<NullChunk>(sizeof(ImportDirectoryTableEntry), 4));
|
||||
|
||||
@@ -1129,15 +1129,21 @@ void ObjFile::enqueuePdbFile(StringRef path, ObjFile *fromFile) {
|
||||
}
|
||||
|
||||
ImportFile::ImportFile(COFFLinkerContext &ctx, MemoryBufferRef m)
|
||||
: InputFile(ctx.symtab, ImportKind, m), live(!ctx.config.doGC) {}
|
||||
: InputFile(ctx.getSymtab(getMachineType(m)), ImportKind, m),
|
||||
live(!ctx.config.doGC) {}
|
||||
|
||||
MachineTypes ImportFile::getMachineType() const {
|
||||
MachineTypes ImportFile::getMachineType(MemoryBufferRef m) {
|
||||
uint16_t machine =
|
||||
reinterpret_cast<const coff_import_header *>(mb.getBufferStart())
|
||||
->Machine;
|
||||
reinterpret_cast<const coff_import_header *>(m.getBufferStart())->Machine;
|
||||
return MachineTypes(machine);
|
||||
}
|
||||
|
||||
bool ImportFile::isSameImport(const ImportFile *other) const {
|
||||
if (!externalName.empty())
|
||||
return other->externalName == externalName;
|
||||
return hdr->OrdinalHint == other->hdr->OrdinalHint;
|
||||
}
|
||||
|
||||
ImportThunkChunk *ImportFile::makeImportThunk() {
|
||||
switch (hdr->Machine) {
|
||||
case AMD64:
|
||||
|
||||
@@ -351,11 +351,15 @@ public:
|
||||
explicit ImportFile(COFFLinkerContext &ctx, MemoryBufferRef m);
|
||||
|
||||
static bool classof(const InputFile *f) { return f->kind() == ImportKind; }
|
||||
MachineTypes getMachineType() const override;
|
||||
MachineTypes getMachineType() const override { return getMachineType(mb); }
|
||||
static MachineTypes getMachineType(MemoryBufferRef m);
|
||||
bool isSameImport(const ImportFile *other) const;
|
||||
bool isEC() const { return impECSym != nullptr; }
|
||||
|
||||
DefinedImportData *impSym = nullptr;
|
||||
Defined *thunkSym = nullptr;
|
||||
ImportThunkChunkARM64EC *impchkThunk = nullptr;
|
||||
ImportFile *hybridFile = nullptr;
|
||||
std::string dllName;
|
||||
|
||||
private:
|
||||
|
||||
533
lld/test/COFF/arm64x-import.test
Normal file
533
lld/test/COFF/arm64x-import.test
Normal file
@@ -0,0 +1,533 @@
|
||||
REQUIRES: aarch64
|
||||
RUN: split-file %s %t.dir && cd %t.dir
|
||||
|
||||
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows func12-thunks-arm64ec.s -o func12-thunks-arm64ec.obj
|
||||
RUN: llvm-mc -filetype=obj -triple=aarch64-windows func12-thunks-arm64.s -o func12-thunks-arm64.obj
|
||||
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows func12-arm64ec.s -o func12-arm64ec.obj
|
||||
RUN: llvm-mc -filetype=obj -triple=aarch64-windows func123-arm64.s -o func123-arm64.obj
|
||||
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows func123-arm64ec.s -o func123-arm64ec.obj
|
||||
RUN: llvm-mc -filetype=obj -triple=aarch64-windows func12-arm64.s -o func12-arm64.obj
|
||||
RUN: llvm-mc -filetype=obj -triple=aarch64-windows func234-arm64.s -o func234-arm64.obj
|
||||
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows func12o-arm64ec.s -o func12o-arm64ec.obj
|
||||
RUN: llvm-mc -filetype=obj -triple=aarch64-windows func34-arm64.s -o func34-arm64.obj
|
||||
RUN: llvm-mc -filetype=obj -triple=aarch64-windows func34o-arm64.s -o func34o-arm64.obj
|
||||
RUN: llvm-mc -filetype=obj -triple=aarch64-windows funco-arm64.s -o funco-arm64.obj
|
||||
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows icall.s -o icall.obj
|
||||
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows %S/Inputs/loadconfig-arm64ec.s -o loadconfig-arm64ec.obj
|
||||
RUN: llvm-mc -filetype=obj -triple=aarch64-windows %S/Inputs/loadconfig-arm64.s -o loadconfig-arm64.obj
|
||||
RUN: llvm-lib -machine:arm64ec -def:imp.def -out:imp-arm64ec.lib
|
||||
RUN: llvm-lib -machine:arm64 -def:imp.def -out:imp-arm64.lib
|
||||
RUN: llvm-lib -machine:arm64x -def:imp.def -defArm64Native:imp.def -out:imp-arm64x.lib
|
||||
RUN: llvm-lib -machine:arm64x -def:imp-ord10.def -defArm64Native:imp.def -out:imp-ecord.lib
|
||||
RUN: llvm-lib -machine:arm64x -def:imp-ord10.def -defArm64Native:imp-ord20.def -out:imp-ecord.lib
|
||||
RUN: llvm-lib -machine:arm64x -def:imp2.def -defArm64Native:imp2.def -out:imp2.lib
|
||||
RUN: llvm-lib -machine:arm64x -def:noname-ec.def -defArm64Native:noname-native.def -out:noname.lib
|
||||
RUN: llvm-lib -machine:arm64x -def:dup-ec.def -defArm64Native:dup-native.def -out:dup.lib
|
||||
|
||||
|
||||
# Link to the imported func1, func2, and func1's thunks from both native and EC code.
|
||||
|
||||
RUN: lld-link -machine:arm64x -dll -noentry -out:test-12-thunks.dll loadconfig-arm64.obj loadconfig-arm64ec.obj \
|
||||
RUN: icall.obj func12-thunks-arm64ec.obj func12-thunks-arm64.obj imp-arm64ec.lib imp-arm64.lib
|
||||
|
||||
RUN: llvm-objdump -d test-12-thunks.dll | FileCheck --check-prefix=DISASM-12T %s
|
||||
DISASM-12T: 0000000180001000 <.text>:
|
||||
DISASM-12T-NEXT: 180001000: f0000010 adrp x16, 0x180004000
|
||||
DISASM-12T-NEXT: 180001004: f9400610 ldr x16, [x16, #0x8]
|
||||
DISASM-12T-NEXT: 180001008: d61f0200 br x16
|
||||
DISASM-12T-NEXT: ...
|
||||
DISASM-12T-NEXT: 180002000: 52800040 mov w0, #0x2 // =2
|
||||
DISASM-12T-NEXT: 180002004: d65f03c0 ret
|
||||
DISASM-12T-NEXT: 180002008: 90000030 adrp x16, 0x180006000
|
||||
DISASM-12T-NEXT: 18000200c: f9400210 ldr x16, [x16]
|
||||
DISASM-12T-NEXT: 180002010: d61f0200 br x16
|
||||
DISASM-12T-NEXT: 180002014: d000000b adrp x11, 0x180004000
|
||||
DISASM-12T-NEXT: 180002018: f940016b ldr x11, [x11]
|
||||
DISASM-12T-NEXT: 18000201c: 9000000a adrp x10, 0x180002000 <.text+0x1000>
|
||||
DISASM-12T-NEXT: 180002020: 9100f14a add x10, x10, #0x3c
|
||||
DISASM-12T-NEXT: 180002024: 17fffff7 b 0x180002000 <.text+0x1000>
|
||||
DISASM-12T-NEXT: 180002028: d000000b adrp x11, 0x180004000
|
||||
DISASM-12T-NEXT: 18000202c: f940056b ldr x11, [x11, #0x8]
|
||||
DISASM-12T-NEXT: 180002030: d0ffffea adrp x10, 0x180000000
|
||||
DISASM-12T-NEXT: 180002034: 9100014a add x10, x10, #0x0
|
||||
DISASM-12T-NEXT: 180002038: 17fffff2 b 0x180002000 <.text+0x1000>
|
||||
DISASM-12T-NEXT: 18000203c: 52800060 mov w0, #0x3 // =3
|
||||
DISASM-12T-NEXT: 180002040: d65f03c0 ret
|
||||
DISASM-12T-NEXT: ...
|
||||
DISASM-12T-NEXT: 180003000: ff 25 fa 0f 00 00 jmpq *0xffa(%rip) # 0x180004000
|
||||
|
||||
RUN: llvm-readobj --coff-imports test-12-thunks.dll | FileCheck --check-prefix=IMPORTS-12 %s
|
||||
IMPORTS-12: Import {
|
||||
IMPORTS-12-NEXT: Name: test.dll
|
||||
IMPORTS-12-NEXT: ImportLookupTableRVA: 0x5348
|
||||
IMPORTS-12-NEXT: ImportAddressTableRVA: 0x4000
|
||||
IMPORTS-12-NEXT: Symbol: func1 (0)
|
||||
IMPORTS-12-NEXT: Symbol: func2 (0)
|
||||
IMPORTS-12-NEXT: }
|
||||
IMPORTS-12-NEXT: HybridObject {
|
||||
IMPORTS-12: Import {
|
||||
IMPORTS-12-NEXT: Name: test.dll
|
||||
IMPORTS-12-NEXT: ImportLookupTableRVA: 0x5348
|
||||
IMPORTS-12-NEXT: ImportAddressTableRVA: 0x4000
|
||||
IMPORTS-12-NEXT: Symbol: func1 (0)
|
||||
IMPORTS-12-NEXT: Symbol: func2 (0)
|
||||
IMPORTS-12-NEXT: }
|
||||
IMPORTS-12-NEXT: }
|
||||
|
||||
RUN: llvm-readobj --hex-dump=.test test-12-thunks.dll | FileCheck --check-prefix=FUNC-12-THUNKS %s
|
||||
FUNC-12-THUNKS: 0x180009000 00600000 00400000 00300000 08200000
|
||||
FUNC-12-THUNKS-NEXT: 0x180009010 08600000 08400000
|
||||
|
||||
RUN: llvm-readobj --hex-dump=.testa test-12-thunks.dll | FileCheck --check-prefix=FUNC-12-THUNKSA %s
|
||||
FUNC-12-THUNKSA: 0x18000a000 00400000 08400000 00100000
|
||||
|
||||
|
||||
# If the ordinals of named imports don't match, use the EC value.
|
||||
|
||||
RUN: lld-link -machine:arm64x -dll -noentry -out:test-12-thunks-ord.dll loadconfig-arm64.obj loadconfig-arm64ec.obj \
|
||||
RUN: icall.obj func12-thunks-arm64ec.obj func12-thunks-arm64.obj imp-ecord.lib
|
||||
RUN: llvm-readobj --coff-imports test-12-thunks-ord.dll | FileCheck --check-prefix=IMPORTS-ORD %s
|
||||
|
||||
IMPORTS-ORD: Format: COFF-ARM64X
|
||||
IMPORTS-ORD-NEXT: Arch: aarch64
|
||||
IMPORTS-ORD-NEXT: AddressSize: 64bit
|
||||
IMPORTS-ORD-NEXT: Import {
|
||||
IMPORTS-ORD-NEXT: Name: test.dll
|
||||
IMPORTS-ORD-NEXT: ImportLookupTableRVA: 0x5348
|
||||
IMPORTS-ORD-NEXT: ImportAddressTableRVA: 0x4000
|
||||
IMPORTS-ORD-NEXT: Symbol: func1 (11)
|
||||
IMPORTS-ORD-NEXT: Symbol: func2 (12)
|
||||
IMPORTS-ORD-NEXT: }
|
||||
IMPORTS-ORD-NEXT: HybridObject {
|
||||
IMPORTS-ORD-NEXT: Format: COFF-ARM64EC
|
||||
IMPORTS-ORD-NEXT: Arch: aarch64
|
||||
IMPORTS-ORD-NEXT: AddressSize: 64bit
|
||||
IMPORTS-ORD-NEXT: Import {
|
||||
IMPORTS-ORD-NEXT: Name: test.dll
|
||||
IMPORTS-ORD-NEXT: ImportLookupTableRVA: 0x5348
|
||||
IMPORTS-ORD-NEXT: ImportAddressTableRVA: 0x4000
|
||||
IMPORTS-ORD-NEXT: Symbol: func1 (11)
|
||||
IMPORTS-ORD-NEXT: Symbol: func2 (12)
|
||||
IMPORTS-ORD-NEXT: }
|
||||
IMPORTS-ORD-NEXT: }
|
||||
|
||||
|
||||
# Link to NONAME imports.
|
||||
|
||||
RUN: lld-link -machine:arm64x -dll -noentry -out:test-noname.dll loadconfig-arm64.obj loadconfig-arm64ec.obj \
|
||||
RUN: icall.obj func12-thunks-arm64ec.obj func12-thunks-arm64.obj noname.lib
|
||||
RUN: llvm-readobj --coff-imports test-noname.dll | FileCheck --check-prefix=IMPORTS-ORD2 %s
|
||||
|
||||
IMPORTS-ORD2: Format: COFF-ARM64X
|
||||
IMPORTS-ORD2-NEXT: Arch: aarch64
|
||||
IMPORTS-ORD2-NEXT: AddressSize: 64bit
|
||||
IMPORTS-ORD2-NEXT: Import {
|
||||
IMPORTS-ORD2-NEXT: Name: test.dll
|
||||
IMPORTS-ORD2-NEXT: ImportLookupTableRVA: 0x5348
|
||||
IMPORTS-ORD2-NEXT: ImportAddressTableRVA: 0x4000
|
||||
IMPORTS-ORD2-NEXT: Symbol: (12)
|
||||
IMPORTS-ORD2-NEXT: Symbol: (11)
|
||||
IMPORTS-ORD2-NEXT: }
|
||||
IMPORTS-ORD2-NEXT: HybridObject {
|
||||
IMPORTS-ORD2-NEXT: Format: COFF-ARM64EC
|
||||
IMPORTS-ORD2-NEXT: Arch: aarch64
|
||||
IMPORTS-ORD2-NEXT: AddressSize: 64bit
|
||||
IMPORTS-ORD2-NEXT: Import {
|
||||
IMPORTS-ORD2-NEXT: Name: test.dll
|
||||
IMPORTS-ORD2-NEXT: ImportLookupTableRVA: 0x5350
|
||||
IMPORTS-ORD2-NEXT: ImportAddressTableRVA: 0x4008
|
||||
IMPORTS-ORD2-NEXT: Symbol: (11)
|
||||
IMPORTS-ORD2-NEXT: Symbol: (10)
|
||||
IMPORTS-ORD2-NEXT: }
|
||||
IMPORTS-ORD2-NEXT: }
|
||||
|
||||
# Link to the imported func1 and func2 from both native and EC code, and func3 from native code.
|
||||
|
||||
RUN: lld-link -machine:arm64x -dll -noentry -out:test2.dll loadconfig-arm64.obj loadconfig-arm64ec.obj \
|
||||
RUN: icall.obj func12-arm64ec.obj func123-arm64.obj imp-arm64x.lib
|
||||
|
||||
RUN: llvm-readobj --coff-imports test2.dll | FileCheck --check-prefix=IMPORTS-123-12 %s
|
||||
IMPORTS-123-12: Import {
|
||||
IMPORTS-123-12-NEXT: Name: test.dll
|
||||
IMPORTS-123-12-NEXT: ImportLookupTableRVA: 0x3338
|
||||
IMPORTS-123-12-NEXT: ImportAddressTableRVA: 0x2000
|
||||
IMPORTS-123-12-NEXT: Symbol: func3 (0)
|
||||
IMPORTS-123-12-NEXT: Symbol: func1 (0)
|
||||
IMPORTS-123-12-NEXT: Symbol: func2 (0)
|
||||
IMPORTS-123-12-NEXT: }
|
||||
IMPORTS-123-12-NEXT: HybridObject {
|
||||
IMPORTS-123-12: Import {
|
||||
IMPORTS-123-12-NEXT: Name: test.dll
|
||||
IMPORTS-123-12-NEXT: ImportLookupTableRVA: 0x3340
|
||||
IMPORTS-123-12-NEXT: ImportAddressTableRVA: 0x2008
|
||||
IMPORTS-123-12-NEXT: Symbol: func1 (0)
|
||||
IMPORTS-123-12-NEXT: Symbol: func2 (0)
|
||||
IMPORTS-123-12-NEXT: }
|
||||
IMPORTS-123-12-NEXT: }
|
||||
|
||||
RUN: llvm-readobj --hex-dump=.test test2.dll | FileCheck --check-prefix=TEST-123-12 %s
|
||||
TEST-123-12: 0x180007000 08400000 08200000 10400000 10200000
|
||||
|
||||
RUN: llvm-readobj --hex-dump=.testa test2.dll | FileCheck --check-prefix=TEST-123-12A %s
|
||||
TEST-123-12A: 0x180008000 08200000 10200000 00200000
|
||||
|
||||
RUN: llvm-readobj --hex-dump=.rdata test2.dll | FileCheck --check-prefix=TEST-123-12AUX %s
|
||||
TEST-123-12AUX: 0x180004000 00000000 00000000 08100080 01000000
|
||||
TEST-123-12AUX-NEXT: 0x180004010 1c100080 01000000 00000000 00000000
|
||||
|
||||
|
||||
# Link to the imported func1 and func2 from both native and EC code, and func3 from EC code.
|
||||
|
||||
RUN: lld-link -machine:arm64x -dll -noentry -out:func-12-123.dll loadconfig-arm64.obj loadconfig-arm64ec.obj \
|
||||
RUN: icall.obj func123-arm64ec.obj func12-arm64.obj imp-arm64x.lib
|
||||
|
||||
RUN: llvm-readobj --coff-imports func-12-123.dll | FileCheck --check-prefix=IMPORTS-12-123 %s
|
||||
IMPORTS-12-123: Import {
|
||||
IMPORTS-12-123-NEXT: Name: test.dll
|
||||
IMPORTS-12-123-NEXT: ImportLookupTableRVA: 0x3338
|
||||
IMPORTS-12-123-NEXT: ImportAddressTableRVA: 0x2000
|
||||
IMPORTS-12-123-NEXT: Symbol: func1 (0)
|
||||
IMPORTS-12-123-NEXT: Symbol: func2 (0)
|
||||
IMPORTS-12-123-NEXT: }
|
||||
IMPORTS-12-123-NEXT: HybridObject {
|
||||
IMPORTS-12-123: Import {
|
||||
IMPORTS-12-123-NEXT: Name: test.dll
|
||||
IMPORTS-12-123-NEXT: ImportLookupTableRVA: 0x3338
|
||||
IMPORTS-12-123-NEXT: ImportAddressTableRVA: 0x2000
|
||||
IMPORTS-12-123-NEXT: Symbol: func1 (0)
|
||||
IMPORTS-12-123-NEXT: Symbol: func2 (0)
|
||||
IMPORTS-12-123-NEXT: Symbol: func3 (0)
|
||||
IMPORTS-12-123-NEXT: }
|
||||
IMPORTS-12-123-NEXT: }
|
||||
|
||||
RUN: llvm-readobj --hex-dump=.test func-12-123.dll | FileCheck --check-prefix=TEST-12-123 %s
|
||||
TEST-12-123: 0x180007000 00400000 00200000 08400000 08200000
|
||||
TEST-12-123-NEXT: 0x180007010 10400000 10200000
|
||||
|
||||
RUN: llvm-readobj --hex-dump=.testa func-12-123.dll | FileCheck --check-prefix=TEST-12-123A %s
|
||||
TEST-12-123A: 0x180008000 00200000 08200000
|
||||
|
||||
RUN: llvm-readobj --hex-dump=.rdata func-12-123.dll | FileCheck --check-prefix=TEST-12-123AUX %s
|
||||
TEST-12-123AUX: 0x180004000 08100080 01000000 1c100080 01000000
|
||||
TEST-12-123AUX-NEXT: 0x180004010 30100080 01000000 00000000 00000000
|
||||
|
||||
|
||||
# Link to the imported func2 and func3 from both native and EC code, func4 from native code,
|
||||
# and func1 from EC code.
|
||||
|
||||
RUN: lld-link -machine:arm64x -dll -noentry -out:test-234-123.dll loadconfig-arm64.obj loadconfig-arm64ec.obj \
|
||||
RUN: icall.obj func123-arm64ec.obj func234-arm64.obj imp-arm64x.lib
|
||||
|
||||
RUN: llvm-readobj --coff-imports test-234-123.dll | FileCheck --check-prefix=IMPORTS-234-123 %s
|
||||
IMPORTS-234-123: Import {
|
||||
IMPORTS-234-123-NEXT: Name: test.dll
|
||||
IMPORTS-234-123-NEXT: ImportLookupTableRVA: 0x3338
|
||||
IMPORTS-234-123-NEXT: ImportAddressTableRVA: 0x2000
|
||||
IMPORTS-234-123-NEXT: Symbol: func4 (0)
|
||||
IMPORTS-234-123-NEXT: Symbol: func2 (0)
|
||||
IMPORTS-234-123-NEXT: Symbol: func3 (0)
|
||||
IMPORTS-234-123-NEXT: }
|
||||
IMPORTS-234-123-NEXT: HybridObject {
|
||||
IMPORTS-234-123: Import {
|
||||
IMPORTS-234-123-NEXT: Name: test.dll
|
||||
IMPORTS-234-123-NEXT: ImportLookupTableRVA: 0x3340
|
||||
IMPORTS-234-123-NEXT: ImportAddressTableRVA: 0x2008
|
||||
IMPORTS-234-123-NEXT: Symbol: func2 (0)
|
||||
IMPORTS-234-123-NEXT: Symbol: func3 (0)
|
||||
IMPORTS-234-123-NEXT: Symbol: func1 (0)
|
||||
IMPORTS-234-123-NEXT: }
|
||||
IMPORTS-234-123-NEXT: }
|
||||
|
||||
RUN: llvm-readobj --hex-dump=.test test-234-123.dll | FileCheck --check-prefix=TEST-234-123 %s
|
||||
TEST-234-123: 0x180007000 18400000 18200000 08400000 08200000
|
||||
TEST-234-123-NEXT: 0x180007010 10400000 1020000
|
||||
|
||||
RUN: llvm-readobj --hex-dump=.testa test-234-123.dll | FileCheck --check-prefix=TEST-234-123A %s
|
||||
TEST-234-123A: 0x180008000 08200000 10200000 00200000
|
||||
|
||||
|
||||
# Link to the imported func3 and func4 from native code, and func1 and func2 from EC code.
|
||||
|
||||
RUN: lld-link -machine:arm64x -dll -noentry -out:test-34-12.dll loadconfig-arm64.obj loadconfig-arm64ec.obj \
|
||||
RUN: icall.obj func12o-arm64ec.obj func34o-arm64.obj imp-arm64x.lib imp2.lib
|
||||
|
||||
RUN: llvm-readobj --coff-imports test-34-12.dll | FileCheck --check-prefix=IMPORTS-34-12 %s
|
||||
IMPORTS-34-12: Import {
|
||||
IMPORTS-34-12-NEXT: Name: test.dll
|
||||
IMPORTS-34-12-NEXT: ImportLookupTableRVA: 0x3350
|
||||
IMPORTS-34-12-NEXT: ImportAddressTableRVA: 0x2000
|
||||
IMPORTS-34-12-NEXT: Symbol: func3 (0)
|
||||
IMPORTS-34-12-NEXT: Symbol: func4 (0)
|
||||
IMPORTS-34-12-NEXT: }
|
||||
IMPORTS-34-12-NEXT: Import {
|
||||
IMPORTS-34-12-NEXT: Name: test2.dll
|
||||
IMPORTS-34-12-NEXT: ImportLookupTableRVA: 0x3378
|
||||
IMPORTS-34-12-NEXT: ImportAddressTableRVA: 0x2028
|
||||
IMPORTS-34-12-NEXT: Symbol: otherfunc (0)
|
||||
IMPORTS-34-12-NEXT: }
|
||||
IMPORTS-34-12-NEXT: HybridObject {
|
||||
IMPORTS-34-12: Import {
|
||||
IMPORTS-34-12-NEXT: Name: test.dll
|
||||
IMPORTS-34-12-NEXT: ImportLookupTableRVA: 0x3360
|
||||
IMPORTS-34-12-NEXT: ImportAddressTableRVA: 0x2010
|
||||
IMPORTS-34-12-NEXT: Symbol: func1 (0)
|
||||
IMPORTS-34-12-NEXT: Symbol: func2 (0)
|
||||
IMPORTS-34-12-NEXT: }
|
||||
IMPORTS-34-12-NEXT: Import {
|
||||
IMPORTS-34-12-NEXT: Name: test2.dll
|
||||
IMPORTS-34-12-NEXT: ImportLookupTableRVA: 0x3378
|
||||
IMPORTS-34-12-NEXT: ImportAddressTableRVA: 0x2028
|
||||
IMPORTS-34-12-NEXT: Symbol: otherfunc (0)
|
||||
IMPORTS-34-12-NEXT: }
|
||||
IMPORTS-34-12-NEXT: }
|
||||
|
||||
RUN: llvm-readobj --hex-dump=.test test-34-12.dll | FileCheck --check-prefix=TEST-23-12 %s
|
||||
TEST-23-12: 0x180007000 10400000 10200000 18400000 18200000
|
||||
TEST-23-12-NEXT: 0x180007010 28400000 28200000
|
||||
|
||||
RUN: llvm-readobj --hex-dump=.testa test-34-12.dll | FileCheck --check-prefix=TEST-23-12A %s
|
||||
TEST-23-12A: 0x180008000 00200000 08200000 28200000
|
||||
|
||||
|
||||
# Link only to imported EC functions, with no native imports.
|
||||
|
||||
RUN: lld-link -machine:arm64x -dll -noentry -out:test-ec12.dll loadconfig-arm64.obj loadconfig-arm64ec.obj \
|
||||
RUN: icall.obj func12-arm64ec.obj funco-arm64.obj imp-arm64x.lib imp2.lib
|
||||
|
||||
RUN: llvm-readobj --coff-imports test-ec12.dll | FileCheck --check-prefix=IMPORTS-EC12 %s
|
||||
|
||||
IMPORTS-EC12: File: test-ec12.dll
|
||||
IMPORTS-EC12-NEXT: Format: COFF-ARM64X
|
||||
IMPORTS-EC12-NEXT: Arch: aarch64
|
||||
IMPORTS-EC12-NEXT: AddressSize: 64bit
|
||||
IMPORTS-EC12-NEXT: Import {
|
||||
IMPORTS-EC12-NEXT: Name: test.dll
|
||||
IMPORTS-EC12-NEXT: ImportLookupTableRVA: 0x3350
|
||||
IMPORTS-EC12-NEXT: ImportAddressTableRVA: 0x2000
|
||||
IMPORTS-EC12-NEXT: }
|
||||
IMPORTS-EC12-NEXT: Import {
|
||||
IMPORTS-EC12-NEXT: Name: test2.dll
|
||||
IMPORTS-EC12-NEXT: ImportLookupTableRVA: 0x3368
|
||||
IMPORTS-EC12-NEXT: ImportAddressTableRVA: 0x2018
|
||||
IMPORTS-EC12-NEXT: Symbol: otherfunc (0)
|
||||
IMPORTS-EC12-NEXT: }
|
||||
IMPORTS-EC12-NEXT: HybridObject {
|
||||
IMPORTS-EC12-NEXT: Format: COFF-ARM64EC
|
||||
IMPORTS-EC12-NEXT: Arch: aarch64
|
||||
IMPORTS-EC12-NEXT: AddressSize: 64bit
|
||||
IMPORTS-EC12-NEXT: Import {
|
||||
IMPORTS-EC12-NEXT: Name: test.dll
|
||||
IMPORTS-EC12-NEXT: ImportLookupTableRVA: 0x3350
|
||||
IMPORTS-EC12-NEXT: ImportAddressTableRVA: 0x2000
|
||||
IMPORTS-EC12-NEXT: Symbol: func1 (0)
|
||||
IMPORTS-EC12-NEXT: Symbol: func2 (0)
|
||||
IMPORTS-EC12-NEXT: }
|
||||
IMPORTS-EC12-NEXT: Import {
|
||||
IMPORTS-EC12-NEXT: Name: test2.dll
|
||||
IMPORTS-EC12-NEXT: ImportLookupTableRVA: 0x3370
|
||||
IMPORTS-EC12-NEXT: ImportAddressTableRVA: 0x2020
|
||||
IMPORTS-EC12-NEXT: }
|
||||
IMPORTS-EC12-NEXT: }
|
||||
|
||||
|
||||
# Link only to imported native functions, with no EC imports.
|
||||
|
||||
RUN: lld-link -machine:arm64x -dll -noentry -out:test-n12.dll loadconfig-arm64.obj loadconfig-arm64ec.obj \
|
||||
RUN: func12-arm64.obj imp-arm64x.lib
|
||||
|
||||
RUN: llvm-readobj --coff-imports test-n12.dll | FileCheck --check-prefix=IMPORTS-N12 %s
|
||||
|
||||
IMPORTS-N12: Arch: aarch64
|
||||
IMPORTS-N12-NEXT: AddressSize: 64bit
|
||||
IMPORTS-N12-NEXT: Import {
|
||||
IMPORTS-N12-NEXT: Name: test.dll
|
||||
IMPORTS-N12-NEXT: ImportLookupTableRVA: 0x2330
|
||||
IMPORTS-N12-NEXT: ImportAddressTableRVA: 0x1000
|
||||
IMPORTS-N12-NEXT: Symbol: func1 (0)
|
||||
IMPORTS-N12-NEXT: Symbol: func2 (0)
|
||||
IMPORTS-N12-NEXT: }
|
||||
IMPORTS-N12-NEXT: HybridObject {
|
||||
IMPORTS-N12-NEXT: Format: COFF-ARM64EC
|
||||
IMPORTS-N12-NEXT: Arch: aarch64
|
||||
IMPORTS-N12-NEXT: AddressSize: 64bit
|
||||
IMPORTS-N12-NEXT: Import {
|
||||
IMPORTS-N12-NEXT: Name: test.dll
|
||||
IMPORTS-N12-NEXT: ImportLookupTableRVA: 0x2340
|
||||
IMPORTS-N12-NEXT: ImportAddressTableRVA: 0x1010
|
||||
IMPORTS-N12-NEXT: }
|
||||
IMPORTS-N12-NEXT: }
|
||||
|
||||
|
||||
RUN: lld-link -machine:arm64x -dll -noentry -out:test-dup.dll loadconfig-arm64.obj loadconfig-arm64ec.obj icall.obj \
|
||||
RUN: func12-arm64ec.obj func34-arm64.obj dup.lib
|
||||
|
||||
RUN: llvm-readobj --coff-imports test-dup.dll | FileCheck --check-prefix=IMPORTS-DUP %s
|
||||
IMPORTS-DUP: Format: COFF-ARM64X
|
||||
IMPORTS-DUP-NEXT: Arch: aarch64
|
||||
IMPORTS-DUP-NEXT: AddressSize: 64bit
|
||||
IMPORTS-DUP-NEXT: Import {
|
||||
IMPORTS-DUP-NEXT: Name: test.dll
|
||||
IMPORTS-DUP-NEXT: ImportLookupTableRVA: 0x3338
|
||||
IMPORTS-DUP-NEXT: ImportAddressTableRVA: 0x2000
|
||||
IMPORTS-DUP-NEXT: Symbol: func4 (0)
|
||||
IMPORTS-DUP-NEXT: Symbol: func4 (0)
|
||||
IMPORTS-DUP-NEXT: }
|
||||
IMPORTS-DUP-NEXT: HybridObject {
|
||||
IMPORTS-DUP-NEXT: Format: COFF-ARM64EC
|
||||
IMPORTS-DUP-NEXT: Arch: aarch64
|
||||
IMPORTS-DUP-NEXT: AddressSize: 64bit
|
||||
IMPORTS-DUP-NEXT: Import {
|
||||
IMPORTS-DUP-NEXT: Name: test.dll
|
||||
IMPORTS-DUP-NEXT: ImportLookupTableRVA: 0x3348
|
||||
IMPORTS-DUP-NEXT: ImportAddressTableRVA: 0x2010
|
||||
IMPORTS-DUP-NEXT: Symbol: func1 (0)
|
||||
IMPORTS-DUP-NEXT: Symbol: func1 (0)
|
||||
IMPORTS-DUP-NEXT: }
|
||||
IMPORTS-DUP-NEXT: }
|
||||
|
||||
#--- func12-thunks-arm64ec.s
|
||||
.section .test, "r"
|
||||
.rva __imp_func1
|
||||
.rva __imp_aux_func1
|
||||
.rva func1
|
||||
.rva "#func1"
|
||||
.rva __imp_func2
|
||||
.rva __imp_aux_func2
|
||||
|
||||
#--- func12-thunks-arm64.s
|
||||
.section .testa, "r"
|
||||
.rva __imp_func1
|
||||
.rva __imp_func2
|
||||
.rva func2
|
||||
|
||||
#--- func12-arm64ec.s
|
||||
.section .test, "r"
|
||||
.rva __imp_func1
|
||||
.rva __imp_aux_func1
|
||||
.rva __imp_func2
|
||||
.rva __imp_aux_func2
|
||||
|
||||
#--- func123-arm64.s
|
||||
.section .testa, "r"
|
||||
.rva __imp_func1
|
||||
.rva __imp_func2
|
||||
.rva __imp_func3
|
||||
|
||||
#--- func123-arm64ec.s
|
||||
.section .test, "r"
|
||||
.rva __imp_func1
|
||||
.rva __imp_aux_func1
|
||||
.rva __imp_func2
|
||||
.rva __imp_aux_func2
|
||||
.rva __imp_func3
|
||||
.rva __imp_aux_func3
|
||||
|
||||
#--- func12-arm64.s
|
||||
.section .testa, "r"
|
||||
.rva __imp_func1
|
||||
.rva __imp_func2
|
||||
|
||||
#--- func234-arm64.s
|
||||
.section .testa, "r"
|
||||
.rva __imp_func2
|
||||
.rva __imp_func3
|
||||
.rva __imp_func4
|
||||
|
||||
#--- func12o-arm64ec.s
|
||||
.section .test, "r"
|
||||
.rva __imp_func1
|
||||
.rva __imp_aux_func1
|
||||
.rva __imp_func2
|
||||
.rva __imp_aux_func2
|
||||
.rva __imp_otherfunc
|
||||
.rva __imp_aux_otherfunc
|
||||
|
||||
#--- func34-arm64.s
|
||||
.section .testa, "r"
|
||||
.rva __imp_func3
|
||||
.rva __imp_func4
|
||||
|
||||
#--- func34o-arm64.s
|
||||
.section .testa, "r"
|
||||
.rva __imp_func3
|
||||
.rva __imp_func4
|
||||
.rva __imp_otherfunc
|
||||
|
||||
#--- funco-arm64.s
|
||||
.section .testa, "r"
|
||||
.rva __imp_otherfunc
|
||||
|
||||
#--- icall.s
|
||||
.text
|
||||
.globl __icall_helper_arm64ec
|
||||
.p2align 2, 0x0
|
||||
__icall_helper_arm64ec:
|
||||
mov w0, #2
|
||||
ret
|
||||
|
||||
.section .hybmp$x, "yi"
|
||||
.symidx __imp_func1
|
||||
.symidx func1_exit_thunk
|
||||
.word 4
|
||||
|
||||
.section .wowthk$aa,"xr",discard,func1_exit_thunk
|
||||
.globl func1_exit_thunk
|
||||
func1_exit_thunk:
|
||||
mov w0, #3
|
||||
ret
|
||||
|
||||
#--- imp.def
|
||||
NAME test.dll
|
||||
EXPORTS
|
||||
data_sym DATA
|
||||
func1
|
||||
func2
|
||||
func3
|
||||
func4
|
||||
|
||||
#--- imp-ord10.def
|
||||
NAME test.dll
|
||||
EXPORTS
|
||||
data_sym DATA @10
|
||||
func1 @11
|
||||
func2 @12
|
||||
func3 @13
|
||||
func4 @14
|
||||
|
||||
#--- imp-ord20.def
|
||||
NAME test.dll
|
||||
EXPORTS
|
||||
data_sym DATA @10
|
||||
func1 @21
|
||||
func2 @22
|
||||
func3 @23
|
||||
func4 @24
|
||||
|
||||
#--- imp2.def
|
||||
NAME test2.dll
|
||||
EXPORTS
|
||||
otherfunc
|
||||
|
||||
#--- noname-ec.def
|
||||
NAME test.dll
|
||||
EXPORTS
|
||||
func1 @10 NONAME
|
||||
func2 @11 NONAME
|
||||
|
||||
#--- noname-native.def
|
||||
NAME test.dll
|
||||
EXPORTS
|
||||
func1 @12 NONAME
|
||||
func2 @11 NONAME
|
||||
|
||||
#--- dup-ec.def
|
||||
NAME test.dll
|
||||
EXPORTS
|
||||
func1
|
||||
func2 EXPORTAS func1
|
||||
|
||||
#--- dup-native.def
|
||||
NAME test.dll
|
||||
EXPORTS
|
||||
func3 EXPORTAS func4
|
||||
func4
|
||||
Reference in New Issue
Block a user