diff options
Diffstat (limited to 'meta/recipes-core/eglibc/eglibc-2.18/0001-R_ARM_TLS_DTPOFF32.patch')
-rw-r--r-- | meta/recipes-core/eglibc/eglibc-2.18/0001-R_ARM_TLS_DTPOFF32.patch | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/meta/recipes-core/eglibc/eglibc-2.18/0001-R_ARM_TLS_DTPOFF32.patch b/meta/recipes-core/eglibc/eglibc-2.18/0001-R_ARM_TLS_DTPOFF32.patch new file mode 100644 index 0000000000..b4489e9ae9 --- /dev/null +++ b/meta/recipes-core/eglibc/eglibc-2.18/0001-R_ARM_TLS_DTPOFF32.patch | |||
@@ -0,0 +1,56 @@ | |||
1 | |||
2 | Quote from bug 1443 which explains what the patch does : | ||
3 | |||
4 | We build some random program and link it with -lust. When we run it, | ||
5 | it dies with a SIGSEGV before reaching main(). | ||
6 | |||
7 | Libust.so depends on liburcu-bp.so from the usermode-rcu package. | ||
8 | Although libust.so is not prelinked, liburcu-bp.so IS prelinked; this | ||
9 | is critical. | ||
10 | |||
11 | Libust.so uses a TLS / __thread variable that is defined in liburcu- | ||
12 | bp.so. There are special ARM-specific relocation types that allow two | ||
13 | shared libraries to share thread-specific data. This is critical too. | ||
14 | |||
15 | One more critical issue: although liburcu-bp.so is prelinked, we can't | ||
16 | load it at its prelinked address, because we also link against | ||
17 | librt.so, and librt.so uses that address. | ||
18 | |||
19 | The dynamic linker is forced to relink liburcu-bp.so at a different | ||
20 | address. In the course of relinking, it processes the special ARM | ||
21 | relocation record mentioned above. The prelinker has already filled | ||
22 | in the information, which is a short offset into a table of thread- | ||
23 | specific data that is allocated per-thread for each library that uses | ||
24 | TLS. Because the normal behavior of a relocation is to add the symbol | ||
25 | value to an addend stored at the address being relocated, we end up | ||
26 | adding the short offset to itself, doubling it. | ||
27 | |||
28 | Now we have an awkward situation. The libust.so library doesn't know | ||
29 | about the addend, so its TLS data for this element is correct. The | ||
30 | liburcu-bp.so library has a different offset for the element. When we | ||
31 | go to initialize the element for the first time in liburcu-bp.so, we | ||
32 | write the address of the result at the doubled (broken) offset. | ||
33 | Later, when we refer to the address from libust.so, we check the value | ||
34 | at the correct offset, but it's NULL, so we eat hot SIGSEGV. | ||
35 | |||
36 | Upstream-Status: Pending | ||
37 | |||
38 | Signed-off-by: Andrei Dinu <andrei.adrianx.dinu@intel.com> | ||
39 | --- | ||
40 | .../libc/ports/sysdeps/arm/dl-machine.h | 2 +- | ||
41 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
42 | |||
43 | ndex 8d905e8..dcfa71e 100644 | ||
44 | --- libc.orig/ports/sysdeps/arm/dl-machine.h | ||
45 | +++ libc/ports/sysdeps/arm/dl-machine.h | ||
46 | @@ -503,7 +503,7 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, | ||
47 | |||
48 | case R_ARM_TLS_DTPOFF32: | ||
49 | if (sym != NULL) | ||
50 | - *reloc_addr += sym->st_value; | ||
51 | + *reloc_addr = sym->st_value; | ||
52 | break; | ||
53 | |||
54 | case R_ARM_TLS_TPOFF32: | ||
55 | -- | ||
56 | |||