summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/COFF/Chunks.cpp3
-rw-r--r--lld/COFF/Symbols.h4
-rw-r--r--lld/COFF/Writer.cpp7
-rw-r--r--lld/test/COFF/armnt-mov32t-exec.test2
4 files changed, 15 insertions, 1 deletions
diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp
index a68e258efc4..4e41f2fcea9 100644
--- a/lld/COFF/Chunks.cpp
+++ b/lld/COFF/Chunks.cpp
@@ -105,6 +105,9 @@ static void applyBranchImm(uint8_t *Off, int32_t V) {
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;
diff --git a/lld/COFF/Symbols.h b/lld/COFF/Symbols.h
index eae1bfa203e..eb9afd38008 100644
--- a/lld/COFF/Symbols.h
+++ b/lld/COFF/Symbols.h
@@ -138,6 +138,10 @@ public:
// 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.
diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index 62ac95cc95a..4a9c5f896af 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -690,5 +690,12 @@ uint64_t Defined::getSectionIndex() {
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
diff --git a/lld/test/COFF/armnt-mov32t-exec.test b/lld/test/COFF/armnt-mov32t-exec.test
index 847c7b92a62..91b814caa5e 100644
--- a/lld/test/COFF/armnt-mov32t-exec.test
+++ b/lld/test/COFF/armnt-mov32t-exec.test
@@ -2,7 +2,7 @@
# 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:
OpenPOWER on IntegriCloud