submitted-strip-bit-0
authorGNU Libc Maintainers <debian-glibc@lists.debian.org>
Sat, 2 Dec 2017 10:07:17 +0000 (10:07 +0000)
committerAurelien Jarno <aurel32@debian.org>
Sat, 2 Dec 2017 10:07:17 +0000 (10:07 +0000)
2017-07-12  Jiong Wang  <jiong.wang@arm.com>

        * sysdeps/arm/dl-machine.h (elf_machine_load_address):  Also strip bit 0
        of pcrel_address under Thumb mode.

Gbp-Pq: Topic arm
Gbp-Pq: Name submitted-strip-bit-0.diff

sysdeps/arm/dl-machine.h

index 2c72972bd22723c82ae4ae897604fd7f8da9c207..d47a99d67a038c45bbc733ffe0f7f07e7e2951d6 100644 (file)
@@ -56,11 +56,19 @@ elf_machine_load_address (void)
   extern Elf32_Addr internal_function __dl_start (void *) asm ("_dl_start");
   Elf32_Addr got_addr = (Elf32_Addr) &__dl_start;
   Elf32_Addr pcrel_addr;
+  asm ("adr %0, _dl_start" : "=r" (pcrel_addr));
 #ifdef __thumb__
-  /* Clear the low bit of the funciton address.  */
+  /* Clear the low bit of the funciton address.
+
+     NOTE: got_addr is from GOT table whose lsb is always set by linker if it's
+     Thumb function address.  PCREL_ADDR comes from PC-relative calculation
+     which will finish during assembling.  GAS assembler before the fix for
+     PR gas/21458 was not setting the lsb but does after that.  Always do the
+     strip for both, so the code works with various combinations of glibc and
+     Binutils.  */
   got_addr &= ~(Elf32_Addr) 1;
+  pcrel_addr &= ~(Elf32_Addr) 1;
 #endif
-  asm ("adr %0, _dl_start" : "=r" (pcrel_addr));
   return pcrel_addr - got_addr;
 }