COFF: Support 32-bit x86 DLL import table.

llvm-svn: 241767
This commit is contained in:
Rui Ueyama 2015-07-09 00:45:50 +00:00
parent c4a25be568
commit 25522f5d4a
5 changed files with 111 additions and 8 deletions

View File

@ -20,6 +20,7 @@
namespace lld {
namespace coff {
using llvm::COFF::IMAGE_FILE_MACHINE_AMD64;
using llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN;
using llvm::COFF::WindowsSubsystem;
using llvm::StringRef;
@ -45,6 +46,7 @@ struct Export {
// Global configuration.
struct Configuration {
enum ManifestKind { SideBySide, Embed, No };
bool is64() { return MachineType == IMAGE_FILE_MACHINE_AMD64; }
llvm::COFF::MachineTypes MachineType = IMAGE_FILE_MACHINE_UNKNOWN;
bool Verbose = false;

View File

@ -31,13 +31,13 @@ using namespace llvm::support::endian;
using namespace llvm::COFF;
using llvm::RoundUpToAlignment;
static const size_t LookupChunkSize = sizeof(uint64_t);
namespace lld {
namespace coff {
// Import table
static int ptrSize() { return Config->is64() ? 8 : 4; }
// A chunk for the import descriptor table.
class HintNameChunk : public Chunk {
public:
@ -63,7 +63,7 @@ private:
class LookupChunk : public Chunk {
public:
explicit LookupChunk(Chunk *C) : HintName(C) {}
size_t getSize() const override { return LookupChunkSize; }
size_t getSize() const override { return ptrSize(); }
void writeTo(uint8_t *Buf) override {
write32le(Buf + FileOff, HintName->getRVA());
@ -78,12 +78,16 @@ public:
class OrdinalOnlyChunk : public Chunk {
public:
explicit OrdinalOnlyChunk(uint16_t V) : Ordinal(V) {}
size_t getSize() const override { return sizeof(uint64_t); }
size_t getSize() const override { return ptrSize(); }
void writeTo(uint8_t *Buf) override {
// An import-by-ordinal slot has MSB 1 to indicate that
// this is import-by-ordinal (and not import-by-name).
write64le(Buf + FileOff, (uint64_t(1) << 63) | Ordinal);
if (Config->is64()) {
write64le(Buf + FileOff, (1ULL << 63) | Ordinal);
} else {
write32le(Buf + FileOff, (1ULL << 31) | Ordinal);
}
}
uint16_t Ordinal;
@ -125,7 +129,7 @@ uint64_t IdataContents::getDirSize() {
}
uint64_t IdataContents::getIATSize() {
return Addresses.size() * LookupChunkSize;
return Addresses.size() * ptrSize();
}
// Returns a list of .idata contents.
@ -196,8 +200,8 @@ void IdataContents::create() {
Hints.push_back(std::move(C));
}
// Terminate with null values.
Lookups.push_back(make_unique<NullChunk>(LookupChunkSize));
Addresses.push_back(make_unique<NullChunk>(LookupChunkSize));
Lookups.push_back(make_unique<NullChunk>(ptrSize()));
Addresses.push_back(make_unique<NullChunk>(ptrSize()));
for (int I = 0, E = Syms.size(); I < E; ++I)
Syms[I]->setLocation(Addresses[Base + I].get());

View File

@ -0,0 +1,82 @@
---
header:
Machine: IMAGE_FILE_MACHINE_I386
Characteristics: []
sections:
- Name: .text
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
Alignment: 16
SectionData: 33DB538D0500000000508D05000000005053E80000000050E800000000
Relocations:
- VirtualAddress: 5
SymbolName: caption
Type: IMAGE_REL_I386_DIR32
- VirtualAddress: 12
SymbolName: message
Type: IMAGE_REL_I386_DIR32
- VirtualAddress: 19
SymbolName: '_MessageBoxA@16'
Type: IMAGE_REL_I386_REL32
- VirtualAddress: 25
SymbolName: '_ExitProcess@4'
Type: IMAGE_REL_I386_REL32
- Name: .data
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
Alignment: 16
SectionData: 48656C6C6F0048656C6C6F20576F726C642100
symbols:
- Name: .text
Value: 0
SectionNumber: 1
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 29
NumberOfRelocations: 4
NumberOfLinenumbers: 0
CheckSum: 0
Number: 0
- Name: .data
Value: 0
SectionNumber: 2
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 19
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 0
Number: 0
- Name: '_ExitProcess@4'
Value: 0
SectionNumber: 0
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
- Name: '_MessageBoxA@16'
Value: 0
SectionNumber: 0
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
- Name: message
Value: 6
SectionNumber: 2
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
- Name: caption
Value: 0
SectionNumber: 2
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
- Name: '_main@0'
Value: 0
SectionNumber: 1
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
...

Binary file not shown.

View File

@ -0,0 +1,15 @@
# RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj
# RUN: lld -flavor link2 %t.obj %p/Inputs/std32.lib /subsystem:console \
# RUN: /entry:_main@0 /out:%t.exe
# RUN: llvm-readobj -coff-imports %t.exe | FileCheck %s
CHECK: Format: COFF-i386
CHECK: Arch: i386
CHECK: AddressSize: 32bit
CHECK: Import {
CHECK: Name: std32.dll
CHECK: ImportLookupTableRVA: 0x3028
CHECK: ImportAddressTableRVA: 0x3034
CHECK: Symbol: ExitProcess (0)
CHECK: Symbol: MessageBoxA (1)
CHECK: }