public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2 0/2] Correct absolute (SHN_ABS) symbol run-time calculation [BZ #19818]
@ 2018-02-20 18:40 Maciej W. Rozycki
  2018-02-20 18:52 ` [PATCH v2 1/2] elf: Unify symbol address " Maciej W. Rozycki
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Maciej W. Rozycki @ 2018-02-20 18:40 UTC (permalink / raw)
  To: libc-alpha; +Cc: H.J. Lu, Alan Modra, Cary Coutant

Hi,

 This mini patch series addresses the issue filed as BZ #19818 where 
absolute (SHN_ABS) symbol are incorrectly relocated by the base address at 
run time, whereas their values are supposed to remain unaffected by 
relocation.

 As we have run-time symbol address calculations (often made in a slightly 
but insignificantly different way) scattered throughout our tree I have 
decided to unify all that code, hopefully making it cleaner and easier to 
maintain, and made it patch 1/2 in this series.  Then patch 2/2 is the 
actual fix, which owing to 1/2 has become a one-liner.

 This updated v2 addresses Andreas's concern and an issue with dladdr(3) 
family of calls.  It has been regression-tested with the `i686-linux' and 
`x86_64-linux' targets.

 See individual change descriptions for details.

  Maciej

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 1/2] elf: Unify symbol address run-time calculation [BZ #19818]
  2018-02-20 18:40 [PATCH v2 0/2] Correct absolute (SHN_ABS) symbol run-time calculation [BZ #19818] Maciej W. Rozycki
@ 2018-02-20 18:52 ` Maciej W. Rozycki
  2018-03-07 20:23   ` Adhemerval Zanella
  2018-02-20 20:24 ` [PATCH v2 2/2] elf: Correct absolute (SHN_ABS) symbol " Maciej W. Rozycki
  2018-03-01 15:15 ` [PING][PATCH v2 0/2] " Maciej W. Rozycki
  2 siblings, 1 reply; 9+ messages in thread
From: Maciej W. Rozycki @ 2018-02-20 18:52 UTC (permalink / raw)
  To: libc-alpha; +Cc: H.J. Lu, Alan Modra, Cary Coutant

Wrap symbol address run-time calculation into a macro and use it 
throughout, replacing inline calculations.

There are a couple of variants, most of them different in a functionally 
insignificant way.  Most calculations are right following RESOLVE_MAP, 
at which point either the map or the symbol returned can be checked for 
validity as the macro sets either both or neither.  In some places both 
the symbol and the map has to be checked however.

My initial implementation therefore always checked both, however that 
resulted in code larger by as much as 0.3%, as many places know from 
elsewhere that no check is needed.  I have decided the size growth was 
unacceptable.

Having looked closer I realized that it's the map that is the culprit.  
Therefore I have modified LOOKUP_VALUE_ADDRESS to accept an additional 
boolean argument telling it to access the map without checking it for 
validity.  This in turn has brought quite nice results, with new code 
actually being smaller for i686, and MIPS o32, n32 and little-endian n64 
targets, unchanged in size for x86-64 and, unusually, marginally larger 
for big-endian MIPS n64, as follows:

i686:
   text    data     bss     dec     hex filename
 152255    4052     192  156499   26353 ld-2.27.9000-base.so
 152159    4052     192  156403   262f3 ld-2.27.9000-elf-symbol-value.so
MIPS/o32/el:
   text    data     bss     dec     hex filename
 142906    4396     260  147562   2406a ld-2.27.9000-base.so
 142890    4396     260  147546   2405a ld-2.27.9000-elf-symbol-value.so
MIPS/n32/el:
   text    data     bss     dec     hex filename
 142267    4404     260  146931   23df3 ld-2.27.9000-base.so
 142171    4404     260  146835   23d93 ld-2.27.9000-elf-symbol-value.so
MIPS/n64/el:
   text    data     bss     dec     hex filename
 149835    7376     408  157619   267b3 ld-2.27.9000-base.so
 149787    7376     408  157571   26783 ld-2.27.9000-elf-symbol-value.so
MIPS/o32/eb:
   text    data     bss     dec     hex filename
 142870    4396     260  147526   24046 ld-2.27.9000-base.so
 142854    4396     260  147510   24036 ld-2.27.9000-elf-symbol-value.so
MIPS/n32/eb:
   text    data     bss     dec     hex filename
 142019    4404     260  146683   23cfb ld-2.27.9000-base.so
 141923    4404     260  146587   23c9b ld-2.27.9000-elf-symbol-value.so
MIPS/n64/eb:
   text    data     bss     dec     hex filename
 149763    7376     408  157547   2676b ld-2.27.9000-base.so
 149779    7376     408  157563   2677b ld-2.27.9000-elf-symbol-value.so
x86-64:
   text    data     bss     dec     hex filename
 148462    6452     400  155314   25eb2 ld-2.27.9000-base.so
 148462    6452     400  155314   25eb2 ld-2.27.9000-elf-symbol-value.so

	[BZ #19818]
	* sysdeps/generic/ldsodefs.h (LOOKUP_VALUE_ADDRESS): Add `set'
	parameter.
	(SYMBOL_ADDRESS): New macro.
	[!ELF_FUNCTION_PTR_IS_SPECIAL] (DL_SYMBOL_ADDRESS): Use 
	SYMBOL_ADDRESS for symbol address calculation.
	* elf/dl-runtime.c (_dl_fixup): Likewise.
	(_dl_profile_fixup): Likewise.
	* elf/dl-symaddr.c (_dl_symbol_address): Likewise.
	* elf/rtld.c (dl_main): Likewise.
	* sysdeps/aarch64/dl-machine.h (elf_machine_rela): Likewise.
	* sysdeps/alpha/dl-machine.h (elf_machine_rela): Likewise.
	* sysdeps/arm/dl-machine.h (elf_machine_rel): Likewise.
	(elf_machine_rela): Likewise.
	* sysdeps/hppa/dl-machine.h (elf_machine_rela): Likewise.
	* sysdeps/hppa/dl-symaddr.c (_dl_symbol_address): Likewise.
	* sysdeps/i386/dl-machine.h (elf_machine_rel): Likewise.
	(elf_machine_rela): Likewise.
	* sysdeps/ia64/dl-machine.h (elf_machine_rela): Likewise.
	* sysdeps/m68k/dl-machine.h (elf_machine_rela): Likewise.
	* sysdeps/microblaze/dl-machine.h (elf_machine_rela): Likewise.
	* sysdeps/mips/dl-machine.h (ELF_MACHINE_BEFORE_RTLD_RELOC):
	Likewise.
	(elf_machine_reloc): Likewise.
	(elf_machine_got_rel): Likewise.
	* sysdeps/mips/dl-trampoline.c (__dl_runtime_resolve): Likewise.
	* sysdeps/nios2/dl-machine.h (elf_machine_rela): Likewise.
	* sysdeps/powerpc/powerpc32/dl-machine.h (elf_machine_rela): 
	Likewise.
	* sysdeps/powerpc/powerpc64/dl-machine.h (elf_machine_rela):
	Likewise.
	* sysdeps/riscv/dl-machine.h (elf_machine_rela): Likewise.
	* sysdeps/s390/s390-32/dl-machine.h (elf_machine_rela): 
	Likewise.
	* sysdeps/s390/s390-64/dl-machine.h (elf_machine_rela):
	Likewise.
	* sysdeps/sh/dl-machine.h (elf_machine_rela): Likewise.
	* sysdeps/sparc/sparc32/dl-machine.h (elf_machine_rela): 
	Likewise.
	* sysdeps/sparc/sparc64/dl-machine.h (elf_machine_rela):
	Likewise.
	* sysdeps/tile/dl-machine.h (elf_machine_rela): Likewise.
	* sysdeps/x86_64/dl-machine.h (elf_machine_rela): Likewise.
---
Changes from v1:

- remove extraneous parentheses from the bodies of SYMBOL_ADDRESS and 
  DL_SYMBOL_ADDRESS.

 OK to apply?

  Maciej
---
 elf/dl-runtime.c                       |   11 ++++-------
 elf/dl-symaddr.c                       |    2 +-
 elf/rtld.c                             |    2 +-
 sysdeps/aarch64/dl-machine.h           |    2 +-
 sysdeps/alpha/dl-machine.h             |    2 +-
 sysdeps/arm/dl-machine.h               |    6 +++---
 sysdeps/generic/ldsodefs.h             |   10 ++++++++--
 sysdeps/hppa/dl-machine.h              |   10 +++++-----
 sysdeps/hppa/dl-symaddr.c              |    2 +-
 sysdeps/i386/dl-machine.h              |    4 ++--
 sysdeps/ia64/dl-machine.h              |    2 +-
 sysdeps/m68k/dl-machine.h              |    2 +-
 sysdeps/microblaze/dl-machine.h        |    2 +-
 sysdeps/mips/dl-machine.h              |   14 +++++++-------
 sysdeps/mips/dl-trampoline.c           |    4 ++--
 sysdeps/nios2/dl-machine.h             |    2 +-
 sysdeps/powerpc/powerpc32/dl-machine.h |    2 +-
 sysdeps/powerpc/powerpc64/dl-machine.h |    3 +--
 sysdeps/riscv/dl-machine.h             |    2 +-
 sysdeps/s390/s390-32/dl-machine.h      |    2 +-
 sysdeps/s390/s390-64/dl-machine.h      |    2 +-
 sysdeps/sh/dl-machine.h                |    4 ++--
 sysdeps/sparc/sparc32/dl-machine.h     |    2 +-
 sysdeps/sparc/sparc64/dl-machine.h     |    2 +-
 sysdeps/tile/dl-machine.h              |    2 +-
 sysdeps/x86_64/dl-machine.h            |    3 +--
 26 files changed, 51 insertions(+), 50 deletions(-)

glibc-elf-symbol-value.diff
Index: glibc/elf/dl-runtime.c
===================================================================
--- glibc.orig/elf/dl-runtime.c	2018-02-19 13:10:21.217296821 +0000
+++ glibc/elf/dl-runtime.c	2018-02-19 13:22:14.645504959 +0000
@@ -124,14 +124,13 @@ _dl_fixup (
 	 of the object that defines sym.  Now add in the symbol
 	 offset.  */
       value = DL_FIXUP_MAKE_VALUE (result,
-				   sym ? (LOOKUP_VALUE_ADDRESS (result)
-					  + sym->st_value) : 0);
+				   SYMBOL_ADDRESS (result, sym, false));
     }
   else
     {
       /* We already found the symbol.  The module (and therefore its load
 	 address) is also known.  */
-      value = DL_FIXUP_MAKE_VALUE (l, l->l_addr + sym->st_value);
+      value = DL_FIXUP_MAKE_VALUE (l, SYMBOL_ADDRESS (l, sym, true));
       result = l;
     }
 
@@ -241,9 +240,7 @@ _dl_profile_fixup (
 	     of the object that defines sym.  Now add in the symbol
 	     offset.  */
 	  value = DL_FIXUP_MAKE_VALUE (result,
-				       defsym != NULL
-				       ? LOOKUP_VALUE_ADDRESS (result)
-					 + defsym->st_value : 0);
+				       SYMBOL_ADDRESS (result, defsym, false));
 
 	  if (defsym != NULL
 	      && __builtin_expect (ELFW(ST_TYPE) (defsym->st_info)
@@ -254,7 +251,7 @@ _dl_profile_fixup (
 	{
 	  /* We already found the symbol.  The module (and therefore its load
 	     address) is also known.  */
-	  value = DL_FIXUP_MAKE_VALUE (l, l->l_addr + refsym->st_value);
+	  value = DL_FIXUP_MAKE_VALUE (l, SYMBOL_ADDRESS (l, refsym, true));
 
 	  if (__builtin_expect (ELFW(ST_TYPE) (refsym->st_info)
 				== STT_GNU_IFUNC, 0))
Index: glibc/elf/dl-symaddr.c
===================================================================
--- glibc.orig/elf/dl-symaddr.c	2018-02-19 13:10:21.229481824 +0000
+++ glibc/elf/dl-symaddr.c	2018-02-19 13:22:14.668735741 +0000
@@ -22,7 +22,7 @@
 void *
 _dl_symbol_address (struct link_map *map, const ElfW(Sym) *ref)
 {
-  ElfW(Addr) value = (map ? map->l_addr : 0) + ref->st_value;
+  ElfW(Addr) value = SYMBOL_ADDRESS (map, ref, false);
 
   /* Return the pointer to function descriptor. */
   if (ELFW(ST_TYPE) (ref->st_info) == STT_FUNC)
Index: glibc/elf/rtld.c
===================================================================
--- glibc.orig/elf/rtld.c	2018-02-19 13:10:21.236569266 +0000
+++ glibc/elf/rtld.c	2018-02-19 13:22:14.682984971 +0000
@@ -1917,7 +1917,7 @@ ERROR: ld.so: object '%s' cannot be load
 					  NULL, ELF_RTYPE_CLASS_PLT,
 					  DL_LOOKUP_ADD_DEPENDENCY, NULL);
 
-	    loadbase = LOOKUP_VALUE_ADDRESS (result);
+	    loadbase = LOOKUP_VALUE_ADDRESS (result, false);
 
 	    _dl_printf ("%s found at 0x%0*Zd in object at 0x%0*Zd\n",
 			_dl_argv[i],
Index: glibc/sysdeps/aarch64/dl-machine.h
===================================================================
--- glibc.orig/sysdeps/aarch64/dl-machine.h	2018-02-19 13:10:21.281087487 +0000
+++ glibc/sysdeps/aarch64/dl-machine.h	2018-02-19 13:22:14.737587104 +0000
@@ -254,7 +254,7 @@ elf_machine_rela (struct link_map *map, 
     {
       const ElfW(Sym) *const refsym = sym;
       struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
-      ElfW(Addr) value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
+      ElfW(Addr) value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       if (sym != NULL
 	  && __glibc_unlikely (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC)
Index: glibc/sysdeps/alpha/dl-machine.h
===================================================================
--- glibc.orig/sysdeps/alpha/dl-machine.h	2018-02-19 13:10:21.303514845 +0000
+++ glibc/sysdeps/alpha/dl-machine.h	2018-02-19 13:22:14.768016799 +0000
@@ -419,7 +419,7 @@ elf_machine_rela (struct link_map *map,
       if (sym_map)
 	{
 	  sym_raw_value += sym->st_value;
-	  sym_value = sym_raw_value + sym_map->l_addr;
+	  sym_value += SYMBOL_ADDRESS (sym_map, sym, true);
 	}
 
       if (r_type == R_ALPHA_GLOB_DAT)
Index: glibc/sysdeps/arm/dl-machine.h
===================================================================
--- glibc.orig/sysdeps/arm/dl-machine.h	2018-02-19 13:10:21.321668903 +0000
+++ glibc/sysdeps/arm/dl-machine.h	2018-02-19 13:22:14.779148198 +0000
@@ -392,7 +392,7 @@ elf_machine_rel (struct link_map *map, c
     {
       const Elf32_Sym *const refsym = sym;
       struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
-      Elf32_Addr value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
+      Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       if (sym != NULL
 	  && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)
@@ -452,7 +452,7 @@ elf_machine_rel (struct link_map *map, c
 		 binding found in the user program or a loaded library
 		 rather than the dynamic linker's built-in definitions
 		 used while loading those libraries.  */
-	      value -= map->l_addr + refsym->st_value;
+	      value -= SYMBOL_ADDRESS (map, refsym, true);
 # endif
 	    /* Support relocations on mis-aligned offsets.  */
 	    ((struct unaligned *) reloc_addr)->x += value;
@@ -553,7 +553,7 @@ elf_machine_rela (struct link_map *map, 
       const Elf32_Sym *const refsym = sym;
 # endif
       struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
-      Elf32_Addr value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
+      Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       if (sym != NULL
 	  && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)
Index: glibc/sysdeps/generic/ldsodefs.h
===================================================================
--- glibc.orig/sysdeps/generic/ldsodefs.h	2018-02-19 13:10:21.336828083 +0000
+++ glibc/sysdeps/generic/ldsodefs.h	2018-02-20 16:32:02.743558607 +0000
@@ -66,14 +66,20 @@ __BEGIN_DECLS
 /* Result of the lookup functions and how to retrieve the base address.  */
 typedef struct link_map *lookup_t;
 #define LOOKUP_VALUE(map) map
-#define LOOKUP_VALUE_ADDRESS(map) ((map) ? (map)->l_addr : 0)
+#define LOOKUP_VALUE_ADDRESS(map, set) ((set) || (map) ? (map)->l_addr : 0)
+
+/* Calculate the address of symbol REF using the base address from map MAP,
+   if non-NULL.  Don't check for NULL map if MAP_SET is TRUE.  */
+#define SYMBOL_ADDRESS(map, ref, map_set)				\
+  ((ref) == NULL ? 0							\
+   : LOOKUP_VALUE_ADDRESS (map, map_set) + (ref)->st_value)
 
 /* On some architectures a pointer to a function is not just a pointer
    to the actual code of the function but rather an architecture
    specific descriptor. */
 #ifndef ELF_FUNCTION_PTR_IS_SPECIAL
 # define DL_SYMBOL_ADDRESS(map, ref) \
- (void *) (LOOKUP_VALUE_ADDRESS (map) + ref->st_value)
+ (void *) SYMBOL_ADDRESS (map, ref, false)
 # define DL_LOOKUP_ADDRESS(addr) ((ElfW(Addr)) (addr))
 # define DL_CALL_DT_INIT(map, start, argc, argv, env) \
  ((init_t) (start)) (argc, argv, env)
Index: glibc/sysdeps/hppa/dl-machine.h
===================================================================
--- glibc.orig/sysdeps/hppa/dl-machine.h	2018-02-19 13:10:21.357039796 +0000
+++ glibc/sysdeps/hppa/dl-machine.h	2018-02-19 13:22:14.828577350 +0000
@@ -562,7 +562,7 @@ elf_machine_rela (struct link_map *map,
 
   if (sym_map)
     {
-      value = sym ? sym_map->l_addr + sym->st_value : 0;
+      value = SYMBOL_ADDRESS (sym_map, sym, true);
       value += reloc->r_addend;
     }
   else
@@ -586,8 +586,8 @@ elf_machine_rela (struct link_map *map,
     case R_PARISC_DIR21L:
       {
 	unsigned int insn = *(unsigned int *)reloc_addr;
-	value = sym_map->l_addr + sym->st_value
-		+ ((reloc->r_addend + 0x1000) & -0x2000);
+	value = (SYMBOL_ADDRESS (sym_map, sym, true)
+		 + ((reloc->r_addend + 0x1000) & -0x2000));
 	value = value >> 11;
 	insn = (insn &~ 0x1fffff) | reassemble_21 (value);
 	*(unsigned int *)reloc_addr = insn;
@@ -597,8 +597,8 @@ elf_machine_rela (struct link_map *map,
     case R_PARISC_DIR14R:
       {
 	unsigned int insn = *(unsigned int *)reloc_addr;
-	value = ((sym_map->l_addr + sym->st_value) & 0x7ff)
-		+ (((reloc->r_addend & 0x1fff) ^ 0x1000) - 0x1000);
+	value = ((SYMBOL_ADDRESS (sym_map, sym, true) & 0x7ff)
+ 		 + (((reloc->r_addend & 0x1fff) ^ 0x1000) - 0x1000));
 	insn = (insn &~ 0x3fff) | reassemble_14 (value);
 	*(unsigned int *)reloc_addr = insn;
       }
Index: glibc/sysdeps/hppa/dl-symaddr.c
===================================================================
--- glibc.orig/sysdeps/hppa/dl-symaddr.c	2018-02-19 13:10:21.371154652 +0000
+++ glibc/sysdeps/hppa/dl-symaddr.c	2018-02-19 13:22:14.846783200 +0000
@@ -23,7 +23,7 @@ void *
 _dl_symbol_address (struct link_map *map, const ElfW(Sym) *ref)
 {
   /* Find the "ip" from the "map" and symbol "ref" */
-  Elf32_Addr value = (map ? map->l_addr : 0) + ref->st_value;
+  Elf32_Addr value = SYMBOL_ADDRESS (map, ref, false);
 
   /* On hppa, we have to return the pointer to function descriptor.
      This involves an "| 2" to inform $$dyncall that this is a plabel32  */
Index: glibc/sysdeps/i386/dl-machine.h
===================================================================
--- glibc.orig/sysdeps/i386/dl-machine.h	2018-02-19 13:10:21.385393392 +0000
+++ glibc/sysdeps/i386/dl-machine.h	2018-02-19 13:22:14.857907255 +0000
@@ -320,7 +320,7 @@ elf_machine_rel (struct link_map *map, c
       const Elf32_Sym *const refsym = sym;
 # endif
       struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
-      Elf32_Addr value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
+      Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       if (sym != NULL
 	  && __glibc_unlikely (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC)
@@ -500,7 +500,7 @@ elf_machine_rela (struct link_map *map, 
       const Elf32_Sym *const refsym = sym;
 #  endif
       struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
-      Elf32_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value;
+      Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       if (sym != NULL
 	  && __glibc_likely (sym->st_shndx != SHN_UNDEF)
Index: glibc/sysdeps/ia64/dl-machine.h
===================================================================
--- glibc.orig/sysdeps/ia64/dl-machine.h	2018-02-19 13:10:21.406734115 +0000
+++ glibc/sysdeps/ia64/dl-machine.h	2018-02-19 13:22:14.890118190 +0000
@@ -419,7 +419,7 @@ elf_machine_rela (struct link_map *map,
       /* RESOLVE_MAP() will return NULL if it fail to locate the symbol.  */
       if ((sym_map = RESOLVE_MAP (&sym, version, r_type)))
 	{
-	  value = sym_map->l_addr + sym->st_value + reloc->r_addend;
+	  value = SYMBOL_ADDRESS (sym_map, sym, true) + reloc->r_addend;
 
 	  if (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_DIR64LSB))
 	    ;/* No adjustment.  */
Index: glibc/sysdeps/m68k/dl-machine.h
===================================================================
--- glibc.orig/sysdeps/m68k/dl-machine.h	2018-02-19 13:10:21.419970047 +0000
+++ glibc/sysdeps/m68k/dl-machine.h	2018-02-19 13:22:14.913295094 +0000
@@ -229,7 +229,7 @@ elf_machine_rela (struct link_map *map, 
     {
       const Elf32_Sym *const refsym = sym;
       struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
-      Elf32_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value;
+      Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       switch (r_type)
 	{
Index: glibc/sysdeps/microblaze/dl-machine.h
===================================================================
--- glibc.orig/sysdeps/microblaze/dl-machine.h	2018-02-19 13:10:21.439274732 +0000
+++ glibc/sysdeps/microblaze/dl-machine.h	2018-02-19 13:22:14.939542016 +0000
@@ -223,7 +223,7 @@ elf_machine_rela (struct link_map *map, 
     {
       const Elf32_Sym *const refsym = sym;
       struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
-      Elf32_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value;
+      Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       value += reloc->r_addend;
       if (r_type == R_MICROBLAZE_GLOB_DAT ||
Index: glibc/sysdeps/mips/dl-machine.h
===================================================================
--- glibc.orig/sysdeps/mips/dl-machine.h	2018-02-19 13:10:21.449367276 +0000
+++ glibc/sysdeps/mips/dl-machine.h	2018-02-19 13:22:14.967751342 +0000
@@ -220,7 +220,7 @@ do {									\
   while (i--)								\
     {									\
       if (sym->st_shndx == SHN_UNDEF || sym->st_shndx == SHN_COMMON)	\
-	*got = map->l_addr + sym->st_value;				\
+	*got = SYMBOL_ADDRESS (map, sym, true);				\
       else if (ELFW(ST_TYPE) (sym->st_info) == STT_FUNC			\
 	       && *got != sym->st_value)				\
 	*got += map->l_addr;						\
@@ -230,7 +230,7 @@ do {									\
 	    *got += map->l_addr;					\
 	}								\
       else								\
-	*got = map->l_addr + sym->st_value;				\
+	*got = SYMBOL_ADDRESS (map, sym, true);				\
 									\
       got++;								\
       sym++;								\
@@ -598,7 +598,7 @@ elf_machine_reloc (struct link_map *map,
 #ifndef RTLD_BOOTSTRAP
 		if (map != &GL(dl_rtld_map))
 #endif
-		  reloc_value += sym->st_value + map->l_addr;
+		  reloc_value += SYMBOL_ADDRESS (map, sym, true);
 	      }
 	    else
 	      {
@@ -663,7 +663,7 @@ elf_machine_reloc (struct link_map *map,
 			    "found jump slot relocation with non-zero addend");
 
 	sym_map = RESOLVE_MAP (&sym, version, r_type);
-	value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
+	value = SYMBOL_ADDRESS (sym_map, sym, true);
 	*addr_field = value;
 
 	break;
@@ -677,7 +677,7 @@ elf_machine_reloc (struct link_map *map,
 
 	/* Calculate the address of the symbol.  */
 	sym_map = RESOLVE_MAP (&sym, version, r_type);
-	value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
+	value = SYMBOL_ADDRESS (sym_map, sym, true);
 
 	if (__builtin_expect (sym == NULL, 0))
 	  /* This can happen in trace mode if an object could not be
@@ -798,7 +798,7 @@ elf_machine_got_rel (struct link_map *ma
 	= vernum ? &map->l_versions[vernum[sym_index] & 0x7fff] : NULL;	  \
       struct link_map *sym_map;						  \
       sym_map = RESOLVE_MAP (&ref, version, reloc);			  \
-      ref ? sym_map->l_addr + ref->st_value : 0;			  \
+      SYMBOL_ADDRESS (sym_map, ref, true);				  \
     })
 
   if (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
@@ -842,7 +842,7 @@ elf_machine_got_rel (struct link_map *ma
 	      && !(sym->st_other & STO_MIPS_PLT))
 	    {
 	      if (lazy)
-		*got = sym->st_value + map->l_addr;
+		*got = SYMBOL_ADDRESS (map, sym, true);
 	      else
 		/* This is a lazy-binding stub, so we don't need the
 		   canonical address.  */
Index: glibc/sysdeps/mips/dl-trampoline.c
===================================================================
--- glibc.orig/sysdeps/mips/dl-trampoline.c	2018-02-19 13:10:21.460633510 +0000
+++ glibc/sysdeps/mips/dl-trampoline.c	2018-02-19 13:22:14.977836168 +0000
@@ -192,12 +192,12 @@ __dl_runtime_resolve (ElfW(Word) sym_ind
 
       /* Currently value contains the base load address of the object
 	 that defines sym.  Now add in the symbol offset.  */
-      value = (sym ? sym_map->l_addr + sym->st_value : 0);
+      value = SYMBOL_ADDRESS (sym_map, sym, true);
     }
   else
     /* We already found the symbol.  The module (and therefore its load
        address) is also known.  */
-    value = l->l_addr + sym->st_value;
+    value = SYMBOL_ADDRESS (l, sym, true);
 
   /* Apply the relocation with that value.  */
   *(got + local_gotno + sym_index - gotsym) = value;
Index: glibc/sysdeps/nios2/dl-machine.h
===================================================================
--- glibc.orig/sysdeps/nios2/dl-machine.h	2018-02-19 13:10:21.493021733 +0000
+++ glibc/sysdeps/nios2/dl-machine.h	2018-02-19 13:22:15.012164183 +0000
@@ -250,7 +250,7 @@ elf_machine_rela (struct link_map *map, 
     {
       const Elf32_Sym *const refsym = sym;
       struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
-      Elf32_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value;
+      Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       switch (r_type)
 	{
Index: glibc/sysdeps/powerpc/powerpc32/dl-machine.h
===================================================================
--- glibc.orig/sysdeps/powerpc/powerpc32/dl-machine.h	2018-02-19 13:10:21.522544522 +0000
+++ glibc/sysdeps/powerpc/powerpc32/dl-machine.h	2018-02-19 13:22:15.038500645 +0000
@@ -317,7 +317,7 @@ elf_machine_rela (struct link_map *map, 
   else
     {
       sym_map = RESOLVE_MAP (&sym, version, r_type);
-      value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
+      value = SYMBOL_ADDRESS (sym_map, sym, true);
     }
   value += reloc->r_addend;
 #else
Index: glibc/sysdeps/powerpc/powerpc64/dl-machine.h
===================================================================
--- glibc.orig/sysdeps/powerpc/powerpc64/dl-machine.h	2018-02-19 13:10:21.561010840 +0000
+++ glibc/sysdeps/powerpc/powerpc64/dl-machine.h	2018-02-19 13:22:15.057749426 +0000
@@ -708,8 +708,7 @@ elf_machine_rela (struct link_map *map,
   /* We need SYM_MAP even in the absence of TLS, for elf_machine_fixup_plt
      and STT_GNU_IFUNC.  */
   struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
-  Elf64_Addr value = ((sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value)
-		      + reloc->r_addend);
+  Elf64_Addr value = SYMBOL_ADDRESS (sym_map, sym, true) + reloc->r_addend;
 
   if (sym != NULL
       && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)
Index: glibc/sysdeps/riscv/dl-machine.h
===================================================================
--- glibc.orig/sysdeps/riscv/dl-machine.h	2018-02-19 13:10:21.593351190 +0000
+++ glibc/sysdeps/riscv/dl-machine.h	2018-02-19 13:22:15.082971467 +0000
@@ -172,7 +172,7 @@ elf_machine_rela (struct link_map *map, 
   struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
   ElfW(Addr) value = 0;
   if (sym_map != NULL)
-    value = sym_map->l_addr + sym->st_value + reloc->r_addend;
+    value = SYMBOL_ADDRESS (sym_map, sym, true) + reloc->r_addend;
 
   switch (r_type)
     {
Index: glibc/sysdeps/s390/s390-32/dl-machine.h
===================================================================
--- glibc.orig/sysdeps/s390/s390-32/dl-machine.h	2018-02-19 13:10:21.617644761 +0000
+++ glibc/sysdeps/s390/s390-32/dl-machine.h	2018-02-19 13:22:15.115293869 +0000
@@ -358,7 +358,7 @@ elf_machine_rela (struct link_map *map, 
       const Elf32_Sym *const refsym = sym;
 #endif
       struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
-      Elf32_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value;
+      Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       if (sym != NULL
 	  && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)
Index: glibc/sysdeps/s390/s390-64/dl-machine.h
===================================================================
--- glibc.orig/sysdeps/s390/s390-64/dl-machine.h	2018-02-19 13:10:21.652047072 +0000
+++ glibc/sysdeps/s390/s390-64/dl-machine.h	2018-02-19 13:22:15.137529070 +0000
@@ -305,7 +305,7 @@ elf_machine_rela (struct link_map *map, 
       const Elf64_Sym *const refsym = sym;
 #endif
       struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
-      Elf64_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value;
+      Elf64_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       if (sym != NULL
 	  && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC,
Index: glibc/sysdeps/sh/dl-machine.h
===================================================================
--- glibc.orig/sysdeps/sh/dl-machine.h	2018-02-19 13:10:21.690433963 +0000
+++ glibc/sysdeps/sh/dl-machine.h	2018-02-19 13:22:15.154759248 +0000
@@ -320,7 +320,7 @@ elf_machine_rela (struct link_map *map, 
       const Elf32_Sym *const refsym = sym;
       struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
 
-      value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
+      value = SYMBOL_ADDRESS (sym_map, sym, true);
       value += reloc->r_addend;
 
       switch (r_type)
@@ -406,7 +406,7 @@ elf_machine_rela (struct link_map *map, 
 		 binding found in the user program or a loaded library
 		 rather than the dynamic linker's built-in definitions
 		 used while loading those libraries.  */
-	      value -= map->l_addr + refsym->st_value + reloc->r_addend;
+	      value -= SYMBOL_ADDRESS (map, refsym, true) + reloc->r_addend;
 #endif
 	    COPY_UNALIGNED_WORD (&value, reloc_addr_arg,
 				 (int) reloc_addr_arg & 3);
Index: glibc/sysdeps/sparc/sparc32/dl-machine.h
===================================================================
--- glibc.orig/sysdeps/sparc/sparc32/dl-machine.h	2018-02-19 13:10:21.706556824 +0000
+++ glibc/sysdeps/sparc/sparc32/dl-machine.h	2018-02-19 13:22:15.183043504 +0000
@@ -382,7 +382,7 @@ elf_machine_rela (struct link_map *map, 
   else
     {
       sym_map = RESOLVE_MAP (&sym, version, r_type);
-      value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
+      value = SYMBOL_ADDRESS (sym_map, sym, true);
     }
 #else
   value = 0;
Index: glibc/sysdeps/sparc/sparc64/dl-machine.h
===================================================================
--- glibc.orig/sysdeps/sparc/sparc64/dl-machine.h	2018-02-19 13:10:21.732877229 +0000
+++ glibc/sysdeps/sparc/sparc64/dl-machine.h	2018-02-19 13:22:15.199215250 +0000
@@ -409,7 +409,7 @@ elf_machine_rela (struct link_map *map, 
   else
     {
       sym_map = RESOLVE_MAP (&sym, version, r_type);
-      value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
+      value = SYMBOL_ADDRESS (sym_map, sym, true);
     }
 #else
   value = 0;
Index: glibc/sysdeps/tile/dl-machine.h
===================================================================
--- glibc.orig/sysdeps/tile/dl-machine.h	2018-02-19 13:10:21.756279043 +0000
+++ glibc/sysdeps/tile/dl-machine.h	2018-02-19 13:22:15.212498221 +0000
@@ -430,7 +430,7 @@ elf_machine_rela (struct link_map *map, 
   else if (ELFW_ST_TYPE (sym->st_info) == STT_SECTION)
     value = map->l_addr;  /* like a RELATIVE reloc */
   else
-    value = sym_map->l_addr + sym->st_value;
+    value = SYMBOL_ADDRESS (sym_map, sym, true);
 
   if (sym != NULL
       && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)
Index: glibc/sysdeps/x86_64/dl-machine.h
===================================================================
--- glibc.orig/sysdeps/x86_64/dl-machine.h	2018-02-19 13:10:21.776588898 +0000
+++ glibc/sysdeps/x86_64/dl-machine.h	2018-02-19 13:22:15.235786558 +0000
@@ -306,8 +306,7 @@ elf_machine_rela (struct link_map *map, 
       const ElfW(Sym) *const refsym = sym;
 # endif
       struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
-      ElfW(Addr) value = (sym == NULL ? 0
-			  : (ElfW(Addr)) sym_map->l_addr + sym->st_value);
+      ElfW(Addr) value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       if (sym != NULL
 	  && __glibc_unlikely (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC)

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 2/2] elf: Correct absolute (SHN_ABS) symbol run-time calculation [BZ #19818]
  2018-02-20 18:40 [PATCH v2 0/2] Correct absolute (SHN_ABS) symbol run-time calculation [BZ #19818] Maciej W. Rozycki
  2018-02-20 18:52 ` [PATCH v2 1/2] elf: Unify symbol address " Maciej W. Rozycki
@ 2018-02-20 20:24 ` Maciej W. Rozycki
  2018-03-07 20:25   ` Adhemerval Zanella
  2018-03-01 15:15 ` [PING][PATCH v2 0/2] " Maciej W. Rozycki
  2 siblings, 1 reply; 9+ messages in thread
From: Maciej W. Rozycki @ 2018-02-20 20:24 UTC (permalink / raw)
  To: libc-alpha; +Cc: H.J. Lu, Alan Modra, Cary Coutant

Do not relocate absolute symbols by the base address.  Such symbols have 
SHN_ABS as the section index and their value is not supposed to be 
affected by relocation as per the ELF gABI[1]:

"SHN_ABS
    The symbol has an absolute value that will not change because of
    relocation."

The reason for our non-conformance here seems to be an old SysV linker 
bug causing symbols like _DYNAMIC to be incorrectly emitted as absolute 
symbols[2].  However in a previous discussion it was pointed that this 
is seriously flawed by preventing the lone purpose of the existence of 
absolute symbols from being used[3]:

"On the contrary, the only interpretation that makes sense to me is that 
it will not change because of relocation at link time or at load time.  
Absolute symbols, from the days of the earliest linking loaders, have 
been used to represent addresses that are outside the address space of 
the module (e.g., memory-mapped addresses or kernel gateway pages).  
They've even been used to represent true symbolic constants (e.g., 
system entry point numbers, sizes, version numbers).  There's no other 
way to represent a true absolute symbol, while the meaning you seek is 
easily represented by giving the symbol a non-negative st_shndx value." 

and we ought to stop supporting our current broken interpretation.

Update processing for dladdr(3) and dladdr1(3) so that SHN_ABS symbols 
are ignored, because under the corrected interpretation they do not 
represent addresses within a mapped file and therefore are not supposed 
to be considered.

References:

[1] "System V Application Binary Interface - DRAFT - 19 October 2010",
    The SCO Group, Section "Symbol Table",
    <http://www.sco.com/developers/gabi/2012-12-31/ch4.symtab.html>

[2] Alan Modra, "Absolute symbols" 
    <https://sourceware.org/ml/binutils/2012-05/msg00019.html>

[3] Cary Coutant, "Re: Absolute symbols"
    <https://sourceware.org/ml/binutils/2012-05/msg00020.html>

	[BZ #19818]
	* sysdeps/generic/ldsodefs.h (SYMBOL_ADDRESS): Handle SHN_ABS 
	symbols.
	* elf/dl-addr.c (determine_info): Ignore SHN_ABS symbols.
	* elf/tst-absolute-sym.c: New file.
	* elf/tst-absolute-sym-lib.c: New file.
	* elf/tst-absolute-sym-lib.lds: New file.
	* elf/Makefile (tests): Add `tst-absolute-sym'.
	(modules-names): Add `tst-absolute-sym-lib'.
	(LDLIBS-tst-absolute-sym-lib.so): New variable.
	($(objpfx)tst-absolute-sym-lib.so): New dependency.
	($(objpfx)tst-absolute-sym): New dependency.
---
Changes from v1:

- Ignore SHN_ABS symbols in `determine_info',

- Regenerate for the 1/2 update.

 OK to apply?

  Maciej
---
 elf/Makefile                 |    8 ++++++--
 elf/dl-addr.c                |    2 ++
 elf/tst-absolute-sym-lib.c   |   25 +++++++++++++++++++++++++
 elf/tst-absolute-sym-lib.lds |   19 +++++++++++++++++++
 elf/tst-absolute-sym.c       |   38 ++++++++++++++++++++++++++++++++++++++
 sysdeps/generic/ldsodefs.h   |    3 ++-
 6 files changed, 92 insertions(+), 3 deletions(-)

glibc-elf-shn-abs.diff
Index: glibc/elf/Makefile
===================================================================
--- glibc.orig/elf/Makefile	2018-02-20 11:35:52.000000000 +0000
+++ glibc/elf/Makefile	2018-02-20 16:34:25.160539142 +0000
@@ -187,7 +187,7 @@ tests += restest1 preloadtest loadfail m
 	 tst-tlsalign tst-tlsalign-extern tst-nodelete-opened \
 	 tst-nodelete2 tst-audit11 tst-audit12 tst-dlsym-error tst-noload \
 	 tst-latepthread tst-tls-manydynamic tst-nodelete-dlclose \
-	 tst-debug1 tst-main1
+	 tst-debug1 tst-main1 tst-absolute-sym
 #	 reldep9
 tests-internal += loadtest unload unload2 circleload1 \
 	 neededtest neededtest2 neededtest3 neededtest4 \
@@ -272,7 +272,7 @@ modules-names = testobj1 testobj2 testob
 		tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12 \
 		tst-latepthreadmod $(tst-tls-many-dynamic-modules) \
 		tst-nodelete-dlclose-dso tst-nodelete-dlclose-plugin \
-		tst-main1mod tst-libc_dlvsym-dso
+		tst-main1mod tst-libc_dlvsym-dso tst-absolute-sym-lib
 ifeq (yes,$(have-mtls-dialect-gnu2))
 tests += tst-gnu2-tls1
 modules-names += tst-gnu2-tls1mod
@@ -1437,6 +1437,10 @@ tst-main1-no-pie = yes
 LDLIBS-tst-main1 = $(libsupport)
 tst-main1mod.so-no-z-defs = yes
 
+LDLIBS-tst-absolute-sym-lib.so = tst-absolute-sym-lib.lds
+$(objpfx)tst-absolute-sym-lib.so: $(LDLIBS-tst-absolute-sym-lib.so)
+$(objpfx)tst-absolute-sym: $(objpfx)tst-absolute-sym-lib.so
+
 # Both the main program and the DSO for tst-libc_dlvsym need to link
 # against libdl.
 $(objpfx)tst-libc_dlvsym: $(libdl)
Index: glibc/elf/dl-addr.c
===================================================================
--- glibc.orig/elf/dl-addr.c	2018-02-20 11:35:52.000000000 +0000
+++ glibc/elf/dl-addr.c	2018-02-20 16:34:25.163584547 +0000
@@ -59,6 +59,7 @@ determine_info (const ElfW(Addr) addr, s
 		     we can omit that test here.  */
 		  if ((symtab[symndx].st_shndx != SHN_UNDEF
 		       || symtab[symndx].st_value != 0)
+		      && symtab[symndx].st_shndx != SHN_ABS
 		      && ELFW(ST_TYPE) (symtab[symndx].st_info) != STT_TLS
 		      && DL_ADDR_SYM_MATCH (match, &symtab[symndx],
 					    matchsym, addr)
@@ -91,6 +92,7 @@ determine_info (const ElfW(Addr) addr, s
 	    && ELFW(ST_TYPE) (symtab->st_info) != STT_TLS
 	    && (symtab->st_shndx != SHN_UNDEF
 		|| symtab->st_value != 0)
+	    && symtab->st_shndx != SHN_ABS
 	    && DL_ADDR_SYM_MATCH (match, symtab, matchsym, addr)
 	    && symtab->st_name < strtabsize)
 	  matchsym = (ElfW(Sym) *) symtab;
Index: glibc/elf/tst-absolute-sym-lib.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ glibc/elf/tst-absolute-sym-lib.c	2018-02-20 16:34:25.185804348 +0000
@@ -0,0 +1,25 @@
+/* BZ #19818 absolute symbol calculation shared module.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+extern char absolute;
+
+void *
+get_absolute (void)
+{
+  return &absolute;
+}
Index: glibc/elf/tst-absolute-sym-lib.lds
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ glibc/elf/tst-absolute-sym-lib.lds	2018-02-20 16:34:25.204877904 +0000
@@ -0,0 +1,19 @@
+/* BZ #19818 absolute symbol calculation linker script.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+"absolute" = 0x55aa;
Index: glibc/elf/tst-absolute-sym.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ glibc/elf/tst-absolute-sym.c	2018-02-20 16:34:25.232178264 +0000
@@ -0,0 +1,38 @@
+/* BZ #19818 absolute symbol calculation main executable.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <support/check.h>
+#include <support/support.h>
+#include <support/test-driver.h>
+
+void *get_absolute (void);
+
+static int
+do_test (void)
+{
+  void *ref = (void *) 0x55aa;
+  void *ptr;
+
+  ptr = get_absolute ();
+  if (ptr != ref)
+    FAIL_EXIT1 ("Got %p, expected %p\n", ptr, ref);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
Index: glibc/sysdeps/generic/ldsodefs.h
===================================================================
--- glibc.orig/sysdeps/generic/ldsodefs.h	2018-02-20 16:32:02.000000000 +0000
+++ glibc/sysdeps/generic/ldsodefs.h	2018-02-20 16:34:25.271185000 +0000
@@ -72,7 +72,8 @@ typedef struct link_map *lookup_t;
    if non-NULL.  Don't check for NULL map if MAP_SET is TRUE.  */
 #define SYMBOL_ADDRESS(map, ref, map_set)				\
   ((ref) == NULL ? 0							\
-   : LOOKUP_VALUE_ADDRESS (map, map_set) + (ref)->st_value)
+   : (__glibc_unlikely ((ref)->st_shndx == SHN_ABS) ? 0			\
+      : LOOKUP_VALUE_ADDRESS (map, map_set)) + (ref)->st_value)
 
 /* On some architectures a pointer to a function is not just a pointer
    to the actual code of the function but rather an architecture

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PING][PATCH v2 0/2] Correct absolute (SHN_ABS) symbol run-time calculation [BZ #19818]
  2018-02-20 18:40 [PATCH v2 0/2] Correct absolute (SHN_ABS) symbol run-time calculation [BZ #19818] Maciej W. Rozycki
  2018-02-20 18:52 ` [PATCH v2 1/2] elf: Unify symbol address " Maciej W. Rozycki
  2018-02-20 20:24 ` [PATCH v2 2/2] elf: Correct absolute (SHN_ABS) symbol " Maciej W. Rozycki
@ 2018-03-01 15:15 ` Maciej W. Rozycki
  2 siblings, 0 replies; 9+ messages in thread
From: Maciej W. Rozycki @ 2018-03-01 15:15 UTC (permalink / raw)
  To: libc-alpha; +Cc: H.J. Lu, Alan Modra, Cary Coutant

On Tue, 20 Feb 2018, Maciej W. Rozycki wrote:

>  This mini patch series addresses the issue filed as BZ #19818 where 
> absolute (SHN_ABS) symbol are incorrectly relocated by the base address at 
> run time, whereas their values are supposed to remain unaffected by 
> relocation.

 Ping!

  Maciej

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 1/2] elf: Unify symbol address run-time calculation [BZ #19818]
  2018-02-20 18:52 ` [PATCH v2 1/2] elf: Unify symbol address " Maciej W. Rozycki
@ 2018-03-07 20:23   ` Adhemerval Zanella
  2018-04-04 22:18     ` Maciej W. Rozycki
  0 siblings, 1 reply; 9+ messages in thread
From: Adhemerval Zanella @ 2018-03-07 20:23 UTC (permalink / raw)
  To: libc-alpha



On 20/02/2018 15:37, Maciej W. Rozycki wrote:
> Wrap symbol address run-time calculation into a macro and use it 
> throughout, replacing inline calculations.
> 
> There are a couple of variants, most of them different in a functionally 
> insignificant way.  Most calculations are right following RESOLVE_MAP, 
> at which point either the map or the symbol returned can be checked for 
> validity as the macro sets either both or neither.  In some places both 
> the symbol and the map has to be checked however.
> 
> My initial implementation therefore always checked both, however that 
> resulted in code larger by as much as 0.3%, as many places know from 
> elsewhere that no check is needed.  I have decided the size growth was 
> unacceptable.
> 
> Having looked closer I realized that it's the map that is the culprit.  
> Therefore I have modified LOOKUP_VALUE_ADDRESS to accept an additional 
> boolean argument telling it to access the map without checking it for 
> validity.  This in turn has brought quite nice results, with new code 
> actually being smaller for i686, and MIPS o32, n32 and little-endian n64 
> targets, unchanged in size for x86-64 and, unusually, marginally larger 
> for big-endian MIPS n64, as follows:
> 
> i686:
>    text    data     bss     dec     hex filename
>  152255    4052     192  156499   26353 ld-2.27.9000-base.so
>  152159    4052     192  156403   262f3 ld-2.27.9000-elf-symbol-value.so
> MIPS/o32/el:
>    text    data     bss     dec     hex filename
>  142906    4396     260  147562   2406a ld-2.27.9000-base.so
>  142890    4396     260  147546   2405a ld-2.27.9000-elf-symbol-value.so
> MIPS/n32/el:
>    text    data     bss     dec     hex filename
>  142267    4404     260  146931   23df3 ld-2.27.9000-base.so
>  142171    4404     260  146835   23d93 ld-2.27.9000-elf-symbol-value.so
> MIPS/n64/el:
>    text    data     bss     dec     hex filename
>  149835    7376     408  157619   267b3 ld-2.27.9000-base.so
>  149787    7376     408  157571   26783 ld-2.27.9000-elf-symbol-value.so
> MIPS/o32/eb:
>    text    data     bss     dec     hex filename
>  142870    4396     260  147526   24046 ld-2.27.9000-base.so
>  142854    4396     260  147510   24036 ld-2.27.9000-elf-symbol-value.so
> MIPS/n32/eb:
>    text    data     bss     dec     hex filename
>  142019    4404     260  146683   23cfb ld-2.27.9000-base.so
>  141923    4404     260  146587   23c9b ld-2.27.9000-elf-symbol-value.so
> MIPS/n64/eb:
>    text    data     bss     dec     hex filename
>  149763    7376     408  157547   2676b ld-2.27.9000-base.so
>  149779    7376     408  157563   2677b ld-2.27.9000-elf-symbol-value.so
> x86-64:
>    text    data     bss     dec     hex filename
>  148462    6452     400  155314   25eb2 ld-2.27.9000-base.so
>  148462    6452     400  155314   25eb2 ld-2.27.9000-elf-symbol-value.so
> 
> 	[BZ #19818]
> 	* sysdeps/generic/ldsodefs.h (LOOKUP_VALUE_ADDRESS): Add `set'
> 	parameter.
> 	(SYMBOL_ADDRESS): New macro.
> 	[!ELF_FUNCTION_PTR_IS_SPECIAL] (DL_SYMBOL_ADDRESS): Use 
> 	SYMBOL_ADDRESS for symbol address calculation.
> 	* elf/dl-runtime.c (_dl_fixup): Likewise.
> 	(_dl_profile_fixup): Likewise.
> 	* elf/dl-symaddr.c (_dl_symbol_address): Likewise.
> 	* elf/rtld.c (dl_main): Likewise.
> 	* sysdeps/aarch64/dl-machine.h (elf_machine_rela): Likewise.
> 	* sysdeps/alpha/dl-machine.h (elf_machine_rela): Likewise.
> 	* sysdeps/arm/dl-machine.h (elf_machine_rel): Likewise.
> 	(elf_machine_rela): Likewise.
> 	* sysdeps/hppa/dl-machine.h (elf_machine_rela): Likewise.
> 	* sysdeps/hppa/dl-symaddr.c (_dl_symbol_address): Likewise.
> 	* sysdeps/i386/dl-machine.h (elf_machine_rel): Likewise.
> 	(elf_machine_rela): Likewise.
> 	* sysdeps/ia64/dl-machine.h (elf_machine_rela): Likewise.
> 	* sysdeps/m68k/dl-machine.h (elf_machine_rela): Likewise.
> 	* sysdeps/microblaze/dl-machine.h (elf_machine_rela): Likewise.
> 	* sysdeps/mips/dl-machine.h (ELF_MACHINE_BEFORE_RTLD_RELOC):
> 	Likewise.
> 	(elf_machine_reloc): Likewise.
> 	(elf_machine_got_rel): Likewise.
> 	* sysdeps/mips/dl-trampoline.c (__dl_runtime_resolve): Likewise.
> 	* sysdeps/nios2/dl-machine.h (elf_machine_rela): Likewise.
> 	* sysdeps/powerpc/powerpc32/dl-machine.h (elf_machine_rela): 
> 	Likewise.
> 	* sysdeps/powerpc/powerpc64/dl-machine.h (elf_machine_rela):
> 	Likewise.
> 	* sysdeps/riscv/dl-machine.h (elf_machine_rela): Likewise.
> 	* sysdeps/s390/s390-32/dl-machine.h (elf_machine_rela): 
> 	Likewise.
> 	* sysdeps/s390/s390-64/dl-machine.h (elf_machine_rela):
> 	Likewise.
> 	* sysdeps/sh/dl-machine.h (elf_machine_rela): Likewise.
> 	* sysdeps/sparc/sparc32/dl-machine.h (elf_machine_rela): 
> 	Likewise.
> 	* sysdeps/sparc/sparc64/dl-machine.h (elf_machine_rela):
> 	Likewise.
> 	* sysdeps/tile/dl-machine.h (elf_machine_rela): Likewise.
> 	* sysdeps/x86_64/dl-machine.h (elf_machine_rela): Likewise.

LGTM, thanks.

Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 2/2] elf: Correct absolute (SHN_ABS) symbol run-time calculation [BZ #19818]
  2018-02-20 20:24 ` [PATCH v2 2/2] elf: Correct absolute (SHN_ABS) symbol " Maciej W. Rozycki
@ 2018-03-07 20:25   ` Adhemerval Zanella
  2018-03-08 15:40     ` Florian Weimer
  0 siblings, 1 reply; 9+ messages in thread
From: Adhemerval Zanella @ 2018-03-07 20:25 UTC (permalink / raw)
  To: libc-alpha; +Cc: Andreas Schwab, Florian Weimer



On 20/02/2018 15:38, Maciej W. Rozycki wrote:
> Do not relocate absolute symbols by the base address.  Such symbols have 
> SHN_ABS as the section index and their value is not supposed to be 
> affected by relocation as per the ELF gABI[1]:
> 
> "SHN_ABS
>     The symbol has an absolute value that will not change because of
>     relocation."
> 
> The reason for our non-conformance here seems to be an old SysV linker 
> bug causing symbols like _DYNAMIC to be incorrectly emitted as absolute 
> symbols[2].  However in a previous discussion it was pointed that this 
> is seriously flawed by preventing the lone purpose of the existence of 
> absolute symbols from being used[3]:
> 
> "On the contrary, the only interpretation that makes sense to me is that 
> it will not change because of relocation at link time or at load time.  
> Absolute symbols, from the days of the earliest linking loaders, have 
> been used to represent addresses that are outside the address space of 
> the module (e.g., memory-mapped addresses or kernel gateway pages).  
> They've even been used to represent true symbolic constants (e.g., 
> system entry point numbers, sizes, version numbers).  There's no other 
> way to represent a true absolute symbol, while the meaning you seek is 
> easily represented by giving the symbol a non-negative st_shndx value." 
> 
> and we ought to stop supporting our current broken interpretation.
> 
> Update processing for dladdr(3) and dladdr1(3) so that SHN_ABS symbols 
> are ignored, because under the corrected interpretation they do not 
> represent addresses within a mapped file and therefore are not supposed 
> to be considered.
> 
> References:
> 
> [1] "System V Application Binary Interface - DRAFT - 19 October 2010",
>     The SCO Group, Section "Symbol Table",
>     <http://www.sco.com/developers/gabi/2012-12-31/ch4.symtab.html>
> 
> [2] Alan Modra, "Absolute symbols" 
>     <https://sourceware.org/ml/binutils/2012-05/msg00019.html>
> 
> [3] Cary Coutant, "Re: Absolute symbols"
>     <https://sourceware.org/ml/binutils/2012-05/msg00020.html>
> 
> 	[BZ #19818]
> 	* sysdeps/generic/ldsodefs.h (SYMBOL_ADDRESS): Handle SHN_ABS 
> 	symbols.
> 	* elf/dl-addr.c (determine_info): Ignore SHN_ABS symbols.
> 	* elf/tst-absolute-sym.c: New file.
> 	* elf/tst-absolute-sym-lib.c: New file.
> 	* elf/tst-absolute-sym-lib.lds: New file.
> 	* elf/Makefile (tests): Add `tst-absolute-sym'.
> 	(modules-names): Add `tst-absolute-sym-lib'.
> 	(LDLIBS-tst-absolute-sym-lib.so): New variable.
> 	($(objpfx)tst-absolute-sym-lib.so): New dependency.
> 	($(objpfx)tst-absolute-sym): New dependency.

The patch and rationale looks reasonable, Andrea and Florian do you still have
objections or doubts about the patch?

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 2/2] elf: Correct absolute (SHN_ABS) symbol run-time calculation [BZ #19818]
  2018-03-07 20:25   ` Adhemerval Zanella
@ 2018-03-08 15:40     ` Florian Weimer
  2018-04-04 22:20       ` Maciej W. Rozycki
  0 siblings, 1 reply; 9+ messages in thread
From: Florian Weimer @ 2018-03-08 15:40 UTC (permalink / raw)
  To: Adhemerval Zanella, libc-alpha; +Cc: Andreas Schwab

On 03/07/2018 09:25 PM, Adhemerval Zanella wrote:

> The patch and rationale looks reasonable, Andrea and Florian do you still have
> objections or doubts about the patch?

I have no further comments/objections.

Thanks,
Florian

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 1/2] elf: Unify symbol address run-time calculation [BZ #19818]
  2018-03-07 20:23   ` Adhemerval Zanella
@ 2018-04-04 22:18     ` Maciej W. Rozycki
  0 siblings, 0 replies; 9+ messages in thread
From: Maciej W. Rozycki @ 2018-04-04 22:18 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

On Wed, 7 Mar 2018, Adhemerval Zanella wrote:

> LGTM, thanks.
> 
> Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>

 Committed now, thanks for your review.

  Maciej

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 2/2] elf: Correct absolute (SHN_ABS) symbol run-time calculation [BZ #19818]
  2018-03-08 15:40     ` Florian Weimer
@ 2018-04-04 22:20       ` Maciej W. Rozycki
  0 siblings, 0 replies; 9+ messages in thread
From: Maciej W. Rozycki @ 2018-04-04 22:20 UTC (permalink / raw)
  To: Florian Weimer; +Cc: Adhemerval Zanella, libc-alpha, Andreas Schwab

On Thu, 8 Mar 2018, Florian Weimer wrote:

> > The patch and rationale looks reasonable, Andrea and Florian do you still
> > have
> > objections or doubts about the patch?
> 
> I have no further comments/objections.

 Committed now and bug closed.  Thanks to everyone involved.

  Maciej

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2018-04-04 22:20 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-20 18:40 [PATCH v2 0/2] Correct absolute (SHN_ABS) symbol run-time calculation [BZ #19818] Maciej W. Rozycki
2018-02-20 18:52 ` [PATCH v2 1/2] elf: Unify symbol address " Maciej W. Rozycki
2018-03-07 20:23   ` Adhemerval Zanella
2018-04-04 22:18     ` Maciej W. Rozycki
2018-02-20 20:24 ` [PATCH v2 2/2] elf: Correct absolute (SHN_ABS) symbol " Maciej W. Rozycki
2018-03-07 20:25   ` Adhemerval Zanella
2018-03-08 15:40     ` Florian Weimer
2018-04-04 22:20       ` Maciej W. Rozycki
2018-03-01 15:15 ` [PING][PATCH v2 0/2] " Maciej W. Rozycki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).