forked from OSchip/llvm-project
COFF: ARM: Fix relocations to thumb code.
Windows ARM is the thumb ARM environment, and pointers to thumb code needs to have its LSB set. When we apply relocations, we need to adjust the LSB if it points to an executable section. llvm-svn: 243560
This commit is contained in:
parent
56965f4b32
commit
8bc43a142b
|
@ -105,6 +105,9 @@ static void applyBranchImm(uint8_t *Off, int32_t V) {
|
||||||
void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, Defined *Sym,
|
void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, Defined *Sym,
|
||||||
uint64_t P) {
|
uint64_t P) {
|
||||||
uint64_t S = Sym->getRVA();
|
uint64_t S = Sym->getRVA();
|
||||||
|
// Pointer to thumb code must have the LSB set.
|
||||||
|
if (Sym->isExecutable())
|
||||||
|
S |= 1;
|
||||||
switch (Type) {
|
switch (Type) {
|
||||||
case IMAGE_REL_ARM_ADDR32: add32(Off, S + Config->ImageBase); break;
|
case IMAGE_REL_ARM_ADDR32: add32(Off, S + Config->ImageBase); break;
|
||||||
case IMAGE_REL_ARM_ADDR32NB: add32(Off, S); break;
|
case IMAGE_REL_ARM_ADDR32NB: add32(Off, S); break;
|
||||||
|
|
|
@ -138,6 +138,10 @@ public:
|
||||||
// Returns the output section index.
|
// Returns the output section index.
|
||||||
// Used to implement SECTION relocation type.
|
// Used to implement SECTION relocation type.
|
||||||
uint64_t getSectionIndex();
|
uint64_t getSectionIndex();
|
||||||
|
|
||||||
|
// Returns true if this symbol points to an executable (e.g. .text) section.
|
||||||
|
// Used to implement ARM relocations.
|
||||||
|
bool isExecutable();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Symbols defined via a COFF object file.
|
// Symbols defined via a COFF object file.
|
||||||
|
|
|
@ -690,5 +690,12 @@ uint64_t Defined::getSectionIndex() {
|
||||||
llvm::report_fatal_error("SECTION relocation points to a non-regular symbol");
|
llvm::report_fatal_error("SECTION relocation points to a non-regular symbol");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Defined::isExecutable() {
|
||||||
|
const auto X = IMAGE_SCN_MEM_EXECUTE;
|
||||||
|
if (auto *D = dyn_cast<DefinedRegular>(this))
|
||||||
|
return D->getChunk()->getOutputSection()->getPermissions() & X;
|
||||||
|
return isa<DefinedImportThunk>(this);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace coff
|
} // namespace coff
|
||||||
} // namespace lld
|
} // namespace lld
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
# RUN: yaml2obj < %s > %t.obj
|
# RUN: yaml2obj < %s > %t.obj
|
||||||
# RUN: llvm-objdump -d %t.obj | FileCheck %s -check-prefix BEFORE
|
# RUN: llvm-objdump -d %t.obj | FileCheck %s -check-prefix BEFORE
|
||||||
# RUN: lld -flavor link /out:%t.exe /subsystem:console /entry:get_function %t.obj
|
# RUN: lld -flavor link2 /out:%t.exe /subsystem:console /entry:get_function %t.obj
|
||||||
# RUN: llvm-objdump -d %t.exe | FileCheck %s -check-prefix AFTER
|
# RUN: llvm-objdump -d %t.exe | FileCheck %s -check-prefix AFTER
|
||||||
|
|
||||||
# BEFORE: Disassembly of section .text:
|
# BEFORE: Disassembly of section .text:
|
||||||
|
|
Loading…
Reference in New Issue