]>
Commit | Line | Data |
---|---|---|
ccc18225 JP |
1 | From 71daaa22dfaa3a99599c08b0d6681cb05b18e4ae Mon Sep 17 00:00:00 2001 |
2 | From: Rui Ueyama <ruiu@bluewhale.systems> | |
3 | Date: Sat, 20 Aug 2022 21:19:33 +0800 | |
4 | Subject: [PATCH] [ELF] Fix ARM32 exception handling | |
5 | ||
6 | Fixes https://github.com/rui314/mold/issues/646 | |
7 | --- | |
8 | elf/arch-arm32.cc | 8 ++++---- | |
9 | test/elf/issue646.sh | 40 ++++++++++++++++++++++++++++++++++++++++ | |
10 | 2 files changed, 44 insertions(+), 4 deletions(-) | |
11 | create mode 100755 test/elf/issue646.sh | |
12 | ||
13 | diff --git a/elf/arch-arm32.cc b/elf/arch-arm32.cc | |
14 | index a470136d..473f50e1 100644 | |
15 | --- a/elf/arch-arm32.cc | |
16 | +++ b/elf/arch-arm32.cc | |
17 | @@ -583,9 +583,9 @@ void sort_arm_exidx(Context<E> &ctx) { | |
18 | ||
19 | tbb::parallel_for((i64)0, num_entries, [&](i64 i) { | |
20 | i64 offset = sizeof(Entry) * i; | |
21 | - ent[i].addr = sign_extend(ent[i].addr, 30) - offset; | |
22 | + ent[i].addr = sign_extend(ent[i].addr, 30) + offset; | |
23 | if (is_relative(ent[i].val)) | |
24 | - ent[i].val = 0x7fff'ffff & (sign_extend(ent[i].val, 30) - offset); | |
25 | + ent[i].val = 0x7fff'ffff & (sign_extend(ent[i].val, 30) + offset); | |
26 | }); | |
27 | ||
28 | tbb::parallel_sort(ent, ent + num_entries, [](const Entry &a, const Entry &b) { | |
29 | @@ -595,9 +595,9 @@ void sort_arm_exidx(Context<E> &ctx) { | |
30 | // Write back the sorted records while adjusting relative addresses | |
31 | tbb::parallel_for((i64)0, num_entries, [&](i64 i) { | |
32 | i64 offset = sizeof(Entry) * i; | |
33 | - ent[i].addr = 0x7fff'ffff & (ent[i].addr + offset); | |
34 | + ent[i].addr = 0x7fff'ffff & (ent[i].addr - offset); | |
35 | if (is_relative(ent[i].val)) | |
36 | - ent[i].val = 0x7fff'ffff & (ent[i].val + offset); | |
37 | + ent[i].val = 0x7fff'ffff & (ent[i].val - offset); | |
38 | }); | |
39 | } | |
40 | ||
41 | diff --git a/test/elf/issue646.sh b/test/elf/issue646.sh | |
42 | new file mode 100755 | |
43 | index 00000000..816fca9b | |
44 | --- /dev/null | |
45 | +++ b/test/elf/issue646.sh | |
46 | @@ -0,0 +1,40 @@ | |
47 | +#!/bin/bash | |
48 | +export LC_ALL=C | |
49 | +set -e | |
50 | +CC="${TEST_CC:-cc}" | |
51 | +CXX="${TEST_CXX:-c++}" | |
52 | +GCC="${TEST_GCC:-gcc}" | |
53 | +GXX="${TEST_GXX:-g++}" | |
54 | +OBJDUMP="${OBJDUMP:-objdump}" | |
55 | +MACHINE="${MACHINE:-$(uname -m)}" | |
56 | +testname=$(basename "$0" .sh) | |
57 | +echo -n "Testing $testname ... " | |
58 | +t=out/test/elf/$MACHINE/$testname | |
59 | +mkdir -p $t | |
60 | + | |
61 | +cat <<EOF | $CXX -o $t/a.o -c -xc++ - | |
62 | +#include <iostream> | |
63 | +#include <stdexcept> | |
64 | + | |
65 | +class Foo : public std::runtime_error { | |
66 | +public: | |
67 | + using std::runtime_error::runtime_error; | |
68 | +}; | |
69 | + | |
70 | +static void do_throw() { | |
71 | + throw Foo("exception"); | |
72 | +} | |
73 | + | |
74 | +int main() { | |
75 | + try { | |
76 | + do_throw(); | |
77 | + } catch (const Foo &e) { | |
78 | + std::cout << "error: " << e.what() << std::endl; | |
79 | + } | |
80 | +} | |
81 | +EOF | |
82 | + | |
83 | +$CXX -B. -o $t/exe $t/a.o | |
84 | +$QEMU $t/exe | grep -q 'error: exception' | |
85 | + | |
86 | +echo OK |