diff options
| author | Andrei Dinu <andrei.adrianx.dinu@intel.com> | 2012-09-24 18:12:28 +0300 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2012-09-28 11:07:38 +0100 |
| commit | e1913fbb01af52feee74bd6ab239678211c7ebb2 (patch) | |
| tree | ad383f669296f40a8d880d0dd2903f420a0ea41b | |
| parent | ea5913fa8402a09cc9a18be6a21c93e54d56d279 (diff) | |
| download | poky-e1913fbb01af52feee74bd6ab239678211c7ebb2.tar.gz | |
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]
(From OE-Core rev: 33ec4222c05c985b737e88850259218cf8336d46)
Signed-off-by: Andrei Dinu <andrei.adrianx.dinu@intel.com>
Signed-off-by: Saul Wold <sgw@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
| -rw-r--r-- | meta/recipes-core/eglibc/eglibc-2.16/0001-R_ARM_TLS_DTPOFF32.patch | 56 | ||||
| -rw-r--r-- | meta/recipes-core/eglibc/eglibc_2.16.bb | 3 |
2 files changed, 58 insertions, 1 deletions
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 @@ | |||
| 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 | |||
diff --git a/meta/recipes-core/eglibc/eglibc_2.16.bb b/meta/recipes-core/eglibc/eglibc_2.16.bb index 7642ae37cc..72cf0f9041 100644 --- a/meta/recipes-core/eglibc/eglibc_2.16.bb +++ b/meta/recipes-core/eglibc/eglibc_2.16.bb | |||
| @@ -3,7 +3,7 @@ require eglibc.inc | |||
| 3 | SRCREV = "20393" | 3 | SRCREV = "20393" |
| 4 | 4 | ||
| 5 | DEPENDS += "gperf-native kconfig-frontends-native" | 5 | DEPENDS += "gperf-native kconfig-frontends-native" |
| 6 | PR = "r10" | 6 | PR = "r11" |
| 7 | PR_append = "+svnr${SRCPV}" | 7 | PR_append = "+svnr${SRCPV}" |
| 8 | 8 | ||
| 9 | EGLIBC_BRANCH="eglibc-2_16" | 9 | EGLIBC_BRANCH="eglibc-2_16" |
| @@ -31,6 +31,7 @@ SRC_URI = "svn://www.eglibc.org/svn/branches/;module=${EGLIBC_BRANCH};protocol=h | |||
| 31 | file://0003-eglibc-menuconfig-build-instructions.patch \ | 31 | file://0003-eglibc-menuconfig-build-instructions.patch \ |
| 32 | file://0001-Add-name_to_handle_at-open_by_handle-etc.-to-PowerPC.patch \ | 32 | file://0001-Add-name_to_handle_at-open_by_handle-etc.-to-PowerPC.patch \ |
| 33 | file://fsl-ppc-no-fsqrt.patch \ | 33 | file://fsl-ppc-no-fsqrt.patch \ |
| 34 | file://0001-R_ARM_TLS_DTPOFF32.patch \ | ||
| 34 | " | 35 | " |
| 35 | LIC_FILES_CHKSUM = "file://LICENSES;md5=98a1128c4b58120182cbea3b1752d8b9 \ | 36 | LIC_FILES_CHKSUM = "file://LICENSES;md5=98a1128c4b58120182cbea3b1752d8b9 \ |
| 36 | file://COPYING;md5=393a5ca445f6965873eca0259a17f833 \ | 37 | file://COPYING;md5=393a5ca445f6965873eca0259a17f833 \ |
