From 33ec4222c05c985b737e88850259218cf8336d46 Mon Sep 17 00:00:00 2001 From: Andrei Dinu Date: Mon, 24 Sep 2012 18:12:28 +0300 Subject: eglibc: Fix for dynamic linker broken offset Solution provided by Donn Seeley in bug 1443: https://bugzilla.yoctoproject.org/show_bug.cgi?id=1443 worked when testing with core-image-sato-sdk for qemuarm. [YOCTO #2577] Signed-off-by: Andrei Dinu Signed-off-by: Saul Wold --- .../eglibc-2.16/0001-R_ARM_TLS_DTPOFF32.patch | 56 ++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 meta/recipes-core/eglibc/eglibc-2.16/0001-R_ARM_TLS_DTPOFF32.patch (limited to 'meta/recipes-core/eglibc/eglibc-2.16') diff --git a/meta/recipes-core/eglibc/eglibc-2.16/0001-R_ARM_TLS_DTPOFF32.patch b/meta/recipes-core/eglibc/eglibc-2.16/0001-R_ARM_TLS_DTPOFF32.patch new file mode 100644 index 0000000000..b4489e9ae9 --- /dev/null +++ b/meta/recipes-core/eglibc/eglibc-2.16/0001-R_ARM_TLS_DTPOFF32.patch @@ -0,0 +1,56 @@ + +Quote from bug 1443 which explains what the patch does : + + We build some random program and link it with -lust. When we run it, + it dies with a SIGSEGV before reaching main(). + + Libust.so depends on liburcu-bp.so from the usermode-rcu package. + Although libust.so is not prelinked, liburcu-bp.so IS prelinked; this + is critical. + + Libust.so uses a TLS / __thread variable that is defined in liburcu- + bp.so. There are special ARM-specific relocation types that allow two + shared libraries to share thread-specific data. This is critical too. + + One more critical issue: although liburcu-bp.so is prelinked, we can't + load it at its prelinked address, because we also link against + librt.so, and librt.so uses that address. + + The dynamic linker is forced to relink liburcu-bp.so at a different + address. In the course of relinking, it processes the special ARM + relocation record mentioned above. The prelinker has already filled + in the information, which is a short offset into a table of thread- + specific data that is allocated per-thread for each library that uses + TLS. Because the normal behavior of a relocation is to add the symbol + value to an addend stored at the address being relocated, we end up + adding the short offset to itself, doubling it. + + Now we have an awkward situation. The libust.so library doesn't know + about the addend, so its TLS data for this element is correct. The + liburcu-bp.so library has a different offset for the element. When we + go to initialize the element for the first time in liburcu-bp.so, we + write the address of the result at the doubled (broken) offset. + Later, when we refer to the address from libust.so, we check the value + at the correct offset, but it's NULL, so we eat hot SIGSEGV. + +Upstream-Status: Pending + +Signed-off-by: Andrei Dinu +--- + .../libc/ports/sysdeps/arm/dl-machine.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +ndex 8d905e8..dcfa71e 100644 +--- libc.orig/ports/sysdeps/arm/dl-machine.h ++++ libc/ports/sysdeps/arm/dl-machine.h +@@ -503,7 +503,7 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, + + case R_ARM_TLS_DTPOFF32: + if (sym != NULL) +- *reloc_addr += sym->st_value; ++ *reloc_addr = sym->st_value; + break; + + case R_ARM_TLS_TPOFF32: +-- + -- cgit 1.2.3-korg