Permalink
Browse files

The value of AT_BASE should be the offset between where the ELF inter…

…preter

expected to be loaded (as expressed in the ELF headers) and where it was
actually loaded, and not (as valgrind was doing) the absolute value of the
load address for the interpreter.

Note that when prelink is not in use the two are normally the same, as the
intpreter (like all shared libraries) is normally linked with a zero load
address. When prelinked that is no longer true.

With that fixed, the hack to patch out AT_BASE to avoid confusing gdb on
systems where prelink is in use is no longer needed.

Fixes BZ#329612


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13768 a5019735-40e9-0310-863c-91ae7b9d1cf9
  • Loading branch information...
tom
tom committed Jan 7, 2014
1 parent 57b8a93 commit e35481f150e4c1b13b8aec1f9fe0099c08c84070
Showing with 9 additions and 27 deletions.
  1. +1 −0 NEWS
  2. +1 −13 coregrind/m_initimg/initimg-linux.c
  3. +3 −10 coregrind/m_ume/elf.c
  4. +4 −4 coregrind/pub_core_ume.h
1 NEWS
@@ -40,6 +40,7 @@ where XXXXXX is the bug number as listed below.
328205 Implement additional Xen hypercalls
328455 s390x: SIGILL after emitting wrong register pair for ldxbr
328711 valgrind.1 manpage "memcheck options" section is badly generated
329612 Incorrect handling of AT_BASE for image execution

Release 3.9.0 (31 October 2013)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -664,19 +664,7 @@ Addr setup_client_stack( void* init_sp,
break;

case AT_BASE:
/* When gdbserver sends the auxv to gdb, the AT_BASE has
to be ignored, as otherwise gdb adds this offset
to loaded shared libs, causing wrong address
relocation e.g. when inserting breaks.
However, ignoring AT_BASE makes V crash on Android 4.1.
So, keep the AT_BASE on android for now.
??? Need to dig in depth about AT_BASE/GDB interaction */
# if !defined(VGPV_arm_linux_android) \
&& !defined(VGPV_x86_linux_android) \
&& !defined(VGPV_mips32_linux_android)
auxv->a_type = AT_IGNORE;
# endif
auxv->u.a_val = info->interp_base;
auxv->u.a_val = info->interp_offset;
break;

case AT_PLATFORM:
@@ -310,11 +310,6 @@ Int VG_(load_ELF)(Int fd, const HChar* name, /*MOD*/ExeInfo* info)
void *entry;
ESZ(Addr) ebase = 0;

/* The difference between where the interpreter got mapped and
where it asked to be mapped. Needed for computing the ppc64 ELF
entry point and initial tocptr (R2) value. */
ESZ(Word) interp_offset = 0;

# if defined(HAVE_PIE)
ebase = info->exe_base;
# endif
@@ -500,8 +495,7 @@ Int VG_(load_ELF)(Int fd, const HChar* name, /*MOD*/ExeInfo* info)
VG_(close)(interp->fd);

entry = (void *)(advised - interp_addr + interp->e.e_entry);
info->interp_base = (ESZ(Addr))advised;
interp_offset = advised - interp_addr;
info->interp_offset = advised - interp_addr;

VG_(free)(interp->p);
VG_(free)(interp);
@@ -518,12 +512,11 @@ Int VG_(load_ELF)(Int fd, const HChar* name, /*MOD*/ExeInfo* info)
is the static chain value. */
info->init_ip = ((ULong*)entry)[0];
info->init_toc = ((ULong*)entry)[1];
info->init_ip += interp_offset;
info->init_toc += interp_offset;
info->init_ip += info->interp_offset;
info->init_toc += info->interp_offset;
#else
info->init_ip = (Addr)entry;
info->init_toc = 0; /* meaningless on this platform */
(void) interp_offset; /* stop gcc complaining it is unused */
#endif
VG_(free)(e->p);
VG_(free)(e);
@@ -52,10 +52,10 @@ typedef
Addr exe_end; // INOUT: highest (allowed) address

#if !defined(VGO_darwin)
Addr phdr; // OUT: address phdr was mapped at
Int phnum; // OUT: number of phdrs
UInt stack_prot; // OUT: stack permissions
Addr interp_base; // OUT: where interpreter (ld.so) was mapped
Addr phdr; // OUT: address phdr was mapped at
Int phnum; // OUT: number of phdrs
UInt stack_prot; // OUT: stack permissions
PtrdiffT interp_offset; // OUT: relocation offset for ld.so
#else
Addr stack_start; // OUT: address of start of stack segment (hot)
Addr stack_end; // OUT: address of end of stack segment (cold)

0 comments on commit e35481f

Please sign in to comment.