summary refs log tree commit diff
path: root/sysdeps/arm/dl-machine.h
diff options
context:
space:
mode:
authorJulian Brown <julian@codesourcery.com>2014-04-30 16:17:59 +0000
committerJoseph Myers <joseph@codesourcery.com>2014-04-30 16:17:59 +0000
commit60c8f1f60b45fb5ba02a0f76ff4b9fda203935e5 (patch)
treea2a09590b09d8d191392b1a9bc958167c321cbce /sysdeps/arm/dl-machine.h
parentd0f5b3f851cfced84e3228977eb8dfdc9c607231 (diff)
downloadglibc-60c8f1f60b45fb5ba02a0f76ff4b9fda203935e5.tar.gz
glibc-60c8f1f60b45fb5ba02a0f76ff4b9fda203935e5.tar.xz
glibc-60c8f1f60b45fb5ba02a0f76ff4b9fda203935e5.zip
ARM: Fix R_ARM_IRELATIVE RELA relocations.
This patch fixes what I believe to be a bug in the handling of
R_ARM_IRELATIVE RELA relocations. At present, these are handled the
same as REL relocations: i.e. the addend is loaded from the relocation
address. Most of the time this isn't a problem because RELA relocations
aren't used on ARM (GNU/Linux at least) anyway, but it causes problems
with prelink, which uses RELA on all targets for its conflict table.
(Support for ifunc prelinking requires a prelink patch, not yet posted.)

Anyway, this patch works, though I'm not 100% sure if it is correct: I
notice that this code path received attention last year:

https://sourceware.org/ml/libc-ports/2013-07/msg00000.html

I'm not sure under what circumstances that patch would have had an
effect, nor if my patch conflicts with that case.

No regressions using Mentor's usual glibc cross-testing infrastructure.

	[BZ #16888]
	* sysdeps/arm/dl-machine.h (elf_machine_rela): Fix R_ARM_IRELATIVE
	handling.
Diffstat (limited to 'sysdeps/arm/dl-machine.h')
-rw-r--r--sysdeps/arm/dl-machine.h2
1 files changed, 1 insertions, 1 deletions
diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h
index 02d1a5ebdf..899b2568f3 100644
--- a/sysdeps/arm/dl-machine.h
+++ b/sysdeps/arm/dl-machine.h
@@ -594,7 +594,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 	    }
 	  break;
 	case R_ARM_IRELATIVE:
-	  value = map->l_addr + *reloc_addr;
+	  value = map->l_addr + reloc->r_addend;
 	  value = ((Elf32_Addr (*) (int)) value) (GLRO(dl_hwcap));
 	  *reloc_addr = value;
 	  break;