diff options
author | Nicholas Piggin <npiggin@gmail.com> | 2016-10-14 07:47:31 +0200 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2016-11-14 01:11:51 +0100 |
commit | 61a92f703120daf7ed25e046275aa8a2d3085ad4 (patch) | |
tree | 0ded0103f9cc2e2a6fc53e0fcc5bb6c4c2329265 /tools | |
parent | powerpc: EX_TABLE macro for exception tables (diff) | |
download | linux-61a92f703120daf7ed25e046275aa8a2d3085ad4.tar.xz linux-61a92f703120daf7ed25e046275aa8a2d3085ad4.zip |
powerpc: Add support for relative exception tables
This halves the exception table size on 64-bit builds, and it allows
build-time sorting of exception tables to work on relocated kernels.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
[mpe: Minor asm fixups and bits to keep the selftests working]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/testing/selftests/powerpc/primitives/load_unaligned_zeropad.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/tools/testing/selftests/powerpc/primitives/load_unaligned_zeropad.c b/tools/testing/selftests/powerpc/primitives/load_unaligned_zeropad.c index cd7af4e1b65a..ed3239bbfae2 100644 --- a/tools/testing/selftests/powerpc/primitives/load_unaligned_zeropad.c +++ b/tools/testing/selftests/powerpc/primitives/load_unaligned_zeropad.c @@ -73,19 +73,23 @@ extern char __stop___ex_table[]; #error implement UCONTEXT_NIA #endif +struct extbl_entry { + int insn; + int fixup; +}; static void segv_handler(int signr, siginfo_t *info, void *ptr) { ucontext_t *uc = (ucontext_t *)ptr; unsigned long addr = (unsigned long)info->si_addr; unsigned long *ip = &UCONTEXT_NIA(uc); - unsigned long *ex_p = (unsigned long *)__start___ex_table; + struct extbl_entry *entry = (struct extbl_entry *)__start___ex_table; - while (ex_p < (unsigned long *)__stop___ex_table) { + while (entry < (struct extbl_entry *)__stop___ex_table) { unsigned long insn, fixup; - insn = *ex_p++; - fixup = *ex_p++; + insn = (unsigned long)&entry->insn + entry->insn; + fixup = (unsigned long)&entry->fixup + entry->fixup; if (insn == *ip) { *ip = fixup; |