void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, Defined *Sym,
uint64_t P) {
uint64_t S = Sym->getRVA();
+ // Pointer to thumb code must have the LSB set.
+ if (Sym->isExecutable())
+ S |= 1;
switch (Type) {
case IMAGE_REL_ARM_ADDR32: add32(Off, S + Config->ImageBase); break;
case IMAGE_REL_ARM_ADDR32NB: add32(Off, S); break;
// Returns the output section index.
// Used to implement SECTION relocation type.
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.
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 lld
# RUN: yaml2obj < %s > %t.obj
# 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
# BEFORE: Disassembly of section .text: