Skip to content

Commit 2b8514d

Browse files
Ard BiesheuvelRussell King
authored andcommitted
ARM: 8219/1: handle interworking and out-of-range relocations separately
Currently, interworking calls on module boundaries are not supported, and are handled by the same error handling code path as non-interworking calls whose targets are simply out of range. Before modifying the handling of those out-of-range jump and call relocations in a subsequent patch, move the handling of interworking restrictions out of it. Acked-by: Nicolas Pitre <nico@linaro.org> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
1 parent c517d83 commit 2b8514d

File tree

1 file changed

+24
-14
lines changed

1 file changed

+24
-14
lines changed

arch/arm/kernel/module.c

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -98,14 +98,19 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
9898
case R_ARM_PC24:
9999
case R_ARM_CALL:
100100
case R_ARM_JUMP24:
101+
if (sym->st_value & 3) {
102+
pr_err("%s: section %u reloc %u sym '%s': unsupported interworking call (ARM -> Thumb)\n",
103+
module->name, relindex, i, symname);
104+
return -ENOEXEC;
105+
}
106+
101107
offset = __mem_to_opcode_arm(*(u32 *)loc);
102108
offset = (offset & 0x00ffffff) << 2;
103109
if (offset & 0x02000000)
104110
offset -= 0x04000000;
105111

106112
offset += sym->st_value - loc;
107-
if (offset & 3 ||
108-
offset <= (s32)0xfe000000 ||
113+
if (offset <= (s32)0xfe000000 ||
109114
offset >= (s32)0x02000000) {
110115
pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n",
111116
module->name, relindex, i, symname,
@@ -155,6 +160,22 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
155160
#ifdef CONFIG_THUMB2_KERNEL
156161
case R_ARM_THM_CALL:
157162
case R_ARM_THM_JUMP24:
163+
/*
164+
* For function symbols, only Thumb addresses are
165+
* allowed (no interworking).
166+
*
167+
* For non-function symbols, the destination
168+
* has no specific ARM/Thumb disposition, so
169+
* the branch is resolved under the assumption
170+
* that interworking is not required.
171+
*/
172+
if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&
173+
!(sym->st_value & 1)) {
174+
pr_err("%s: section %u reloc %u sym '%s': unsupported interworking call (Thumb -> ARM)\n",
175+
module->name, relindex, i, symname);
176+
return -ENOEXEC;
177+
}
178+
158179
upper = __mem_to_opcode_thumb16(*(u16 *)loc);
159180
lower = __mem_to_opcode_thumb16(*(u16 *)(loc + 2));
160181

@@ -182,18 +203,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
182203
offset -= 0x02000000;
183204
offset += sym->st_value - loc;
184205

185-
/*
186-
* For function symbols, only Thumb addresses are
187-
* allowed (no interworking).
188-
*
189-
* For non-function symbols, the destination
190-
* has no specific ARM/Thumb disposition, so
191-
* the branch is resolved under the assumption
192-
* that interworking is not required.
193-
*/
194-
if ((ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&
195-
!(offset & 1)) ||
196-
offset <= (s32)0xff000000 ||
206+
if (offset <= (s32)0xff000000 ||
197207
offset >= (s32)0x01000000) {
198208
pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n",
199209
module->name, relindex, i, symname,

0 commit comments

Comments
 (0)