PE/COFF: add support to import functions in ARM NT

This is necessary to support linking a basic program which references symbols
outside of the module itself.  Add the import thunk for ARM NT style imports.
This allows us to create the reference.  However, it is still insufficient to
generate executables that will run due to base relocations not being emitted for
the import.

llvm-svn: 225428
This commit is contained in:
Saleem Abdulrasool 2015-01-08 04:19:08 +00:00
parent 341f0e6ee0
commit b9c402ed25
5 changed files with 117 additions and 7 deletions

View File

@ -154,10 +154,18 @@ const uint8_t FuncAtomContentX86[] = {
0xcc, 0xcc // INT 3; INT 3
};
const uint8_t FuncAtomContentARMNT[] = {
0x40, 0xf2, 0x00, 0x0c, // mov.w ip, #0
0xc0, 0xf2, 0x00, 0x0c, // mov.t ip, #0
0xdc, 0xf8, 0x00, 0xf0, // ldr.w pc, [ip]
};
static void setJumpInstTarget(COFFLinkerInternalAtom *src, const Atom *dst,
int off, MachineTypes machine) {
COFFReference *ref;
switch (machine) {
default: llvm::report_fatal_error("unsupported machine type");
case llvm::COFF::IMAGE_FILE_MACHINE_I386:
ref = new COFFReference(dst, off, llvm::COFF::IMAGE_REL_I386_DIR32,
Reference::KindArch::x86);
@ -166,9 +174,12 @@ static void setJumpInstTarget(COFFLinkerInternalAtom *src, const Atom *dst,
ref = new COFFReference(dst, off, llvm::COFF::IMAGE_REL_AMD64_REL32,
Reference::KindArch::x86_64);
break;
default:
llvm::report_fatal_error("unsupported machine type");
case llvm::COFF::IMAGE_FILE_MACHINE_ARMNT:
ref = new COFFReference(dst, off, llvm::COFF::IMAGE_REL_ARM_MOV32T,
Reference::KindArch::ARM);
break;
}
src->addReference(std::unique_ptr<COFFReference>(ref));
}
@ -177,9 +188,22 @@ class FuncAtom : public COFFLinkerInternalAtom {
public:
FuncAtom(const File &file, StringRef symbolName,
const COFFSharedLibraryAtom *impAtom, MachineTypes machine)
: COFFLinkerInternalAtom(file, /*oridnal*/ 0, createContent(),
: COFFLinkerInternalAtom(file, /*oridnal*/ 0, createContent(machine),
symbolName) {
setJumpInstTarget(this, impAtom, 2, machine);
size_t Offset;
switch (machine) {
default: llvm::report_fatal_error("unsupported machine type");
case llvm::COFF::IMAGE_FILE_MACHINE_I386:
case llvm::COFF::IMAGE_FILE_MACHINE_AMD64:
Offset = 2;
break;
case llvm::COFF::IMAGE_FILE_MACHINE_ARMNT:
Offset = 0;
break;
}
setJumpInstTarget(this, impAtom, Offset, machine);
}
uint64_t ordinal() const override { return 0; }
@ -189,9 +213,24 @@ public:
ContentPermissions permissions() const override { return permR_X; }
private:
std::vector<uint8_t> createContent() const {
return std::vector<uint8_t>(
FuncAtomContentX86, FuncAtomContentX86 + sizeof(FuncAtomContentX86));
std::vector<uint8_t> createContent(MachineTypes machine) const {
const uint8_t *Data;
size_t Size;
switch (machine) {
default: llvm::report_fatal_error("unsupported machine type");
case llvm::COFF::IMAGE_FILE_MACHINE_I386:
case llvm::COFF::IMAGE_FILE_MACHINE_AMD64:
Data = FuncAtomContentX86;
Size = sizeof(FuncAtomContentX86);
break;
case llvm::COFF::IMAGE_FILE_MACHINE_ARMNT:
Data = FuncAtomContentARMNT;
Size = sizeof(FuncAtomContentARMNT);
break;
}
return std::vector<uint8_t>(Data, Data + Size);
}
};

View File

@ -0,0 +1,39 @@
---
header:
Machine: IMAGE_FILE_MACHINE_ARMNT
Characteristics: [ ]
sections:
- Name: .text
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
Alignment: 4
SectionData: 40F20000C0F2000000680047
Relocations:
- VirtualAddress: 0
SymbolName: __imp_function
Type: 17
symbols:
- Name: .text
Value: 0
SectionNumber: 1
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 12
NumberOfRelocations: 1
NumberOfLinenumbers: 0
CheckSum: 0
Number: 1
- Name: mainCRTStartup
Value: 0
SectionNumber: 1
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
- Name: __imp_function
Value: 0
SectionNumber: 0
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
...

View File

@ -0,0 +1,21 @@
# void __declspec(dllimport) function(void);
# int mainCRTStartup(void) { return function(); }
.syntax unified
.thumb
.text
.def mainCRTStartup
.scl 2
.type 32
.endef
.global mainCRTStartup
.align 2
.thumb_func
mainCRTStartup:
movw r0, :lower16:__imp_function
movt r0, :upper16:__imp_function
ldr r0, [r0]
bx r0

Binary file not shown.

View File

@ -0,0 +1,11 @@
# RUN: yaml2obj -format coff -o %t.obj %p/Inputs/armnt-import.obj.yaml
# RUN: lld -flavor link /out:%t.exe /subsystem:console %t.obj %p/Inputs/library.lib
# RUN: llvm-readobj -coff-imports %t.exe | FileCheck %s
CHECK: Import {
CHECK: Name: library.dll
CHECK: ImportLookupTableRVA: 0x4000
CHECK: ImportAddressTableRVA: 0x2000
CHECK: Symbol: function (0)
CHECK: }