forked from OSchip/llvm-project
COFF: Split ImportThunkChunk into x86 and x64. NFC.
This change should make it easy to port this code to ARM. llvm-svn: 243195
This commit is contained in:
parent
1c341a54de
commit
28df04211c
|
@ -245,31 +245,27 @@ void StringChunk::writeTo(uint8_t *Buf) {
|
||||||
memcpy(Buf + FileOff, Str.data(), Str.size());
|
memcpy(Buf + FileOff, Str.data(), Str.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
ImportThunkChunk::ImportThunkChunk(Defined *S) : ImpSymbol(S) {
|
ImportThunkChunkX64::ImportThunkChunkX64(Defined *S) : ImpSymbol(S) {
|
||||||
// Intel Optimization Manual says that all branch targets
|
// Intel Optimization Manual says that all branch targets
|
||||||
// should be 16-byte aligned. MSVC linker does this too.
|
// should be 16-byte aligned. MSVC linker does this too.
|
||||||
if (Config->MachineType == AMD64)
|
if (Config->MachineType == AMD64)
|
||||||
Align = 16;
|
Align = 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImportThunkChunk::getBaserels(std::vector<uint32_t> *Res) {
|
void ImportThunkChunkX64::writeTo(uint8_t *Buf) {
|
||||||
if (Config->MachineType == I386)
|
memcpy(Buf + FileOff, ImportThunkX86, sizeof(ImportThunkX86));
|
||||||
Res->push_back(getRVA() + 2);
|
// The first two bytes is a JMP instruction. Fill its operand.
|
||||||
|
write32le(Buf + FileOff + 2, ImpSymbol->getRVA() - RVA - getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImportThunkChunk::writeTo(uint8_t *Buf) {
|
void ImportThunkChunkX86::getBaserels(std::vector<uint32_t> *Res) {
|
||||||
memcpy(Buf + FileOff, ImportThunkData, sizeof(ImportThunkData));
|
Res->push_back(getRVA() + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImportThunkChunkX86::writeTo(uint8_t *Buf) {
|
||||||
|
memcpy(Buf + FileOff, ImportThunkX86, sizeof(ImportThunkX86));
|
||||||
// The first two bytes is a JMP instruction. Fill its operand.
|
// The first two bytes is a JMP instruction. Fill its operand.
|
||||||
switch (Config->MachineType) {
|
write32le(Buf + FileOff + 2, ImpSymbol->getRVA() + Config->ImageBase);
|
||||||
case AMD64:
|
|
||||||
write32le(Buf + FileOff + 2, ImpSymbol->getRVA() - RVA - getSize());
|
|
||||||
break;
|
|
||||||
case I386:
|
|
||||||
write32le(Buf + FileOff + 2, ImpSymbol->getRVA() + Config->ImageBase);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
llvm_unreachable("unsupported machine type");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalImportChunk::getBaserels(std::vector<uint32_t> *Res) {
|
void LocalImportChunk::getBaserels(std::vector<uint32_t> *Res) {
|
||||||
|
|
|
@ -223,17 +223,27 @@ private:
|
||||||
StringRef Str;
|
StringRef Str;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t ImportThunkData[] = {
|
static const uint8_t ImportThunkX86[] = {
|
||||||
0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // JMP *0x0
|
0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // JMP *0x0
|
||||||
};
|
};
|
||||||
|
|
||||||
// Windows-specific.
|
// Windows-specific.
|
||||||
// A chunk for DLL import jump table entry. In a final output, it's
|
// A chunk for DLL import jump table entry. In a final output, it's
|
||||||
// contents will be a JMP instruction to some __imp_ symbol.
|
// contents will be a JMP instruction to some __imp_ symbol.
|
||||||
class ImportThunkChunk : public Chunk {
|
class ImportThunkChunkX64 : public Chunk {
|
||||||
public:
|
public:
|
||||||
explicit ImportThunkChunk(Defined *ImpSymbol);
|
explicit ImportThunkChunkX64(Defined *S);
|
||||||
size_t getSize() const override { return sizeof(ImportThunkData); }
|
size_t getSize() const override { return sizeof(ImportThunkX86); }
|
||||||
|
void writeTo(uint8_t *Buf) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Defined *ImpSymbol;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ImportThunkChunkX86 : public Chunk {
|
||||||
|
public:
|
||||||
|
explicit ImportThunkChunkX86(Defined *S) : ImpSymbol(S) {}
|
||||||
|
size_t getSize() const override { return sizeof(ImportThunkX86); }
|
||||||
void getBaserels(std::vector<uint32_t> *Res) override;
|
void getBaserels(std::vector<uint32_t> *Res) override;
|
||||||
void writeTo(uint8_t *Buf) override;
|
void writeTo(uint8_t *Buf) override;
|
||||||
|
|
||||||
|
|
|
@ -320,8 +320,10 @@ std::error_code ImportFile::parse() {
|
||||||
// If type is function, we need to create a thunk which jump to an
|
// If type is function, we need to create a thunk which jump to an
|
||||||
// address pointed by the __imp_ symbol. (This allows you to call
|
// address pointed by the __imp_ symbol. (This allows you to call
|
||||||
// DLL functions just like regular non-DLL functions.)
|
// DLL functions just like regular non-DLL functions.)
|
||||||
if (Hdr->getType() == llvm::COFF::IMPORT_CODE)
|
if (Hdr->getType() == llvm::COFF::IMPORT_CODE) {
|
||||||
SymbolBodies.push_back(new (Alloc) DefinedImportThunk(Name, ImpSym));
|
auto *B = new (Alloc) DefinedImportThunk(Name, ImpSym, Hdr->Machine);
|
||||||
|
SymbolBodies.push_back(B);
|
||||||
|
}
|
||||||
return std::error_code();
|
return std::error_code();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -196,6 +196,21 @@ COFFSymbolRef DefinedCOFF::getCOFFSymbol() {
|
||||||
return COFFSymbolRef(reinterpret_cast<const coff_symbol32 *>(Sym));
|
return COFFSymbolRef(reinterpret_cast<const coff_symbol32 *>(Sym));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DefinedImportThunk::DefinedImportThunk(StringRef Name, DefinedImportData *S,
|
||||||
|
uint16_t MachineType)
|
||||||
|
: Defined(DefinedImportThunkKind, Name) {
|
||||||
|
switch (MachineType) {
|
||||||
|
case AMD64:
|
||||||
|
Data.reset(new ImportThunkChunkX64(S));
|
||||||
|
return;
|
||||||
|
case I386:
|
||||||
|
Data.reset(new ImportThunkChunkX86(S));
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
llvm_unreachable("unknown machine type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ErrorOr<std::unique_ptr<InputFile>> Lazy::getMember() {
|
ErrorOr<std::unique_ptr<InputFile>> Lazy::getMember() {
|
||||||
auto MBRefOrErr = File->getMember(&Sym);
|
auto MBRefOrErr = File->getMember(&Sym);
|
||||||
if (auto EC = MBRefOrErr.getError())
|
if (auto EC = MBRefOrErr.getError())
|
||||||
|
|
|
@ -327,20 +327,19 @@ private:
|
||||||
// a regular name. A function pointer is given as a DefinedImportData.
|
// a regular name. A function pointer is given as a DefinedImportData.
|
||||||
class DefinedImportThunk : public Defined {
|
class DefinedImportThunk : public Defined {
|
||||||
public:
|
public:
|
||||||
DefinedImportThunk(StringRef N, DefinedImportData *S)
|
DefinedImportThunk(StringRef Name, DefinedImportData *S,
|
||||||
: Defined(DefinedImportThunkKind, N), Data(S) {}
|
uint16_t MachineType);
|
||||||
|
|
||||||
static bool classof(const SymbolBody *S) {
|
static bool classof(const SymbolBody *S) {
|
||||||
return S->kind() == DefinedImportThunkKind;
|
return S->kind() == DefinedImportThunkKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t getRVA() { return Data.getRVA(); }
|
uint64_t getRVA() { return Data->getRVA(); }
|
||||||
uint64_t getFileOff() { return Data.getFileOff(); }
|
uint64_t getFileOff() { return Data->getFileOff(); }
|
||||||
|
Chunk *getChunk() { return Data.get(); }
|
||||||
Chunk *getChunk() { return &Data; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ImportThunkChunk Data;
|
std::unique_ptr<Chunk> Data;
|
||||||
};
|
};
|
||||||
|
|
||||||
// If you have a symbol "__imp_foo" in your object file, a symbol name
|
// If you have a symbol "__imp_foo" in your object file, a symbol name
|
||||||
|
|
Loading…
Reference in New Issue