|
From: <sv...@va...> - 2014-01-07 22:28:09
|
Author: tom
Date: Tue Jan 7 22:27:57 2014
New Revision: 13768
Log:
The value of AT_BASE should be the offset between where the ELF interpreter
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
Modified:
trunk/NEWS
trunk/coregrind/m_initimg/initimg-linux.c
trunk/coregrind/m_ume/elf.c
trunk/coregrind/pub_core_ume.h
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Tue Jan 7 22:27:57 2014
@@ -40,6 +40,7 @@
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)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Modified: trunk/coregrind/m_initimg/initimg-linux.c
==============================================================================
--- trunk/coregrind/m_initimg/initimg-linux.c (original)
+++ trunk/coregrind/m_initimg/initimg-linux.c Tue Jan 7 22:27:57 2014
@@ -664,19 +664,7 @@
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:
Modified: trunk/coregrind/m_ume/elf.c
==============================================================================
--- trunk/coregrind/m_ume/elf.c (original)
+++ trunk/coregrind/m_ume/elf.c Tue Jan 7 22:27:57 2014
@@ -310,11 +310,6 @@
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 @@
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 @@
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);
Modified: trunk/coregrind/pub_core_ume.h
==============================================================================
--- trunk/coregrind/pub_core_ume.h (original)
+++ trunk/coregrind/pub_core_ume.h Tue Jan 7 22:27:57 2014
@@ -52,10 +52,10 @@
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)
|