mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-03 18:13:01 +00:00
Add support for PIC executables (e.g. firefox on Ubuntu 11) by adding
the "auxv" protocol packet to gdbsrv. (Philippe Waroquiers, philippe.waroquiers@skynet.be). Bug 214909 comment 108. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11836
This commit is contained in:
parent
5689679404
commit
7be9d63ed0
@ -51,6 +51,10 @@ Addr VG_(clstk_base) = 0;
|
||||
Addr VG_(clstk_end) = 0;
|
||||
UWord VG_(clstk_id) = 0;
|
||||
|
||||
/* linux only: where is the client auxv ? */
|
||||
/* This is set up as part of setup_client_stack in initimg-linux.c. */
|
||||
UWord* VG_(client_auxv) = NULL;
|
||||
|
||||
Addr VG_(brk_base) = 0; /* start of brk */
|
||||
Addr VG_(brk_limit) = 0; /* current brk */
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#include "pub_core_options.h"
|
||||
#include "pub_core_translate.h"
|
||||
#include "pub_core_mallocfree.h"
|
||||
#include "pub_core_initimg.h"
|
||||
|
||||
unsigned long cont_thread;
|
||||
unsigned long general_thread;
|
||||
@ -580,6 +581,59 @@ void handle_query (char *arg_own_buf, int *new_packet_len_p)
|
||||
}
|
||||
}
|
||||
|
||||
if (strncmp ("qXfer:auxv:read:", arg_own_buf, 16) == 0) {
|
||||
unsigned char *data;
|
||||
int n;
|
||||
CORE_ADDR ofs;
|
||||
unsigned int len;
|
||||
char *annex;
|
||||
|
||||
/* Reject any annex; grab the offset and length. */
|
||||
if (decode_xfer_read (arg_own_buf + 16, &annex, &ofs, &len) < 0
|
||||
|| annex[0] != '\0') {
|
||||
strcpy (arg_own_buf, "E00");
|
||||
return;
|
||||
}
|
||||
|
||||
if (len > PBUFSIZ - 2)
|
||||
len = PBUFSIZ - 2;
|
||||
data = malloc (len);
|
||||
|
||||
{
|
||||
UWord *client_auxv = VG_(client_auxv);
|
||||
unsigned int client_auxv_len = 0;
|
||||
while (*client_auxv != 0) {
|
||||
dlog(4, "auxv %lld %llx\n",
|
||||
(ULong)*client_auxv,
|
||||
(ULong)*(client_auxv+1));
|
||||
client_auxv++;
|
||||
client_auxv++;
|
||||
client_auxv_len += 2 * sizeof(UWord);
|
||||
}
|
||||
client_auxv_len += 2 * sizeof(UWord);
|
||||
dlog(4, "auxv len %d\n", client_auxv_len);
|
||||
|
||||
if (ofs >= client_auxv_len)
|
||||
n = -1;
|
||||
else {
|
||||
n = client_auxv_len - ofs;
|
||||
VG_(memcpy) (data, (unsigned char *) VG_(client_auxv), n);
|
||||
}
|
||||
}
|
||||
|
||||
if (n < 0)
|
||||
write_enn (arg_own_buf);
|
||||
else if (n > len)
|
||||
*new_packet_len_p = write_qxfer_response (arg_own_buf, data, len, 1);
|
||||
else
|
||||
*new_packet_len_p = write_qxfer_response (arg_own_buf, data, n, 0);
|
||||
|
||||
free (data);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Protocol features query. */
|
||||
if (strncmp ("qSupported", arg_own_buf, 10) == 0
|
||||
&& (arg_own_buf[10] == ':' || arg_own_buf[10] == '\0')) {
|
||||
@ -589,6 +643,8 @@ void handle_query (char *arg_own_buf, int *new_packet_len_p)
|
||||
|
||||
strcat (arg_own_buf, ";QStartNoAckMode+");
|
||||
strcat (arg_own_buf, ";QPassSignals+");
|
||||
if (VG_(client_auxv))
|
||||
strcat (arg_own_buf, ";qXfer:auxv:read+");
|
||||
|
||||
if ((*the_target->target_xml)() != NULL
|
||||
|| (*the_target->shadow_target_xml)() != NULL) {
|
||||
|
||||
@ -611,6 +611,11 @@ Addr setup_client_stack( void* init_sp,
|
||||
/* --- auxv --- */
|
||||
auxv = (struct auxv *)ptr;
|
||||
*client_auxv = (UInt *)auxv;
|
||||
VG_(client_auxv) = (UWord *)*client_auxv;
|
||||
// ??? According to 'man proc', auxv is a array of unsigned long
|
||||
// terminated by two zeros. Why is valgrind working with UInt ?
|
||||
// We do not take ULong* (as ULong 8 bytes on a 32 bits),
|
||||
// => we take UWord*
|
||||
|
||||
# if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
|
||||
auxv[0].a_type = AT_IGNOREPPC;
|
||||
@ -658,6 +663,11 @@ 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. */
|
||||
auxv->a_type = AT_IGNORE;
|
||||
auxv->u.a_val = info->interp_base;
|
||||
break;
|
||||
|
||||
|
||||
@ -46,6 +46,10 @@ extern Addr VG_(clstk_base); // client stack range
|
||||
extern Addr VG_(clstk_end);
|
||||
extern UWord VG_(clstk_id); // client stack id
|
||||
|
||||
/* linux only: where is the client auxv ? */
|
||||
/* This is setup as part of setup_client_stack in initimg-linux.c. */
|
||||
extern UWord* VG_(client_auxv);
|
||||
|
||||
extern Addr VG_(brk_base); // start of brk
|
||||
extern Addr VG_(brk_limit); // current brk
|
||||
|
||||
|
||||
@ -44,6 +44,7 @@ EXTRA_DIST = \
|
||||
mcleak.stdinB.gdb \
|
||||
mcleak.stdoutB.exp \
|
||||
mcleak.vgtest \
|
||||
mcmain_pic.vgtest \
|
||||
mcsignopass.stderrB.exp \
|
||||
mcsignopass.stderr.exp \
|
||||
mcsignopass.stdinB.gdb \
|
||||
@ -82,6 +83,7 @@ check_PROGRAMS = \
|
||||
clean_after_fork \
|
||||
fork_chain \
|
||||
sleepers \
|
||||
main_pic \
|
||||
t \
|
||||
watchpoints
|
||||
|
||||
@ -89,3 +91,6 @@ AM_CFLAGS += $(AM_FLAG_M3264_PRI)
|
||||
AM_CXXFLAGS += $(AM_FLAG_M3264_PRI)
|
||||
|
||||
LDADD = -lpthread
|
||||
|
||||
main_pic_LDFLAGS = -pie
|
||||
main_pic_CFLAGS = $(AM_CFLAGS) -fPIC
|
||||
|
||||
14
gdbserver_tests/main_pic.c
Normal file
14
gdbserver_tests/main_pic.c
Normal file
@ -0,0 +1,14 @@
|
||||
#include <stdio.h>
|
||||
|
||||
static void another_func(char *msg)
|
||||
{
|
||||
printf ("another func called msg %s\n", msg);
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
printf("address of main %p\n", &main);
|
||||
printf("address of another_func %p\n", &another_func);
|
||||
another_func("called from main");
|
||||
return 0;
|
||||
}
|
||||
13
gdbserver_tests/mcmain_pic.stderr.exp
Normal file
13
gdbserver_tests/mcmain_pic.stderr.exp
Normal file
@ -0,0 +1,13 @@
|
||||
|
||||
(action at startup) vgdb me ...
|
||||
|
||||
|
||||
|
||||
HEAP SUMMARY:
|
||||
in use at exit: 16 bytes in 1 blocks
|
||||
total heap usage: 1 allocs, 0 frees, 16 bytes allocated
|
||||
|
||||
For a detailed leak analysis, rerun with: --leak-check=full
|
||||
|
||||
For counts of detected and suppressed errors, rerun with: -v
|
||||
ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
|
||||
3
gdbserver_tests/mcmain_pic.stderrB.exp
Normal file
3
gdbserver_tests/mcmain_pic.stderrB.exp
Normal file
@ -0,0 +1,3 @@
|
||||
relaying data between gdb and process ....
|
||||
vgdb-error value changed from 0 to 999999
|
||||
Remote connection closed
|
||||
16
gdbserver_tests/mcmain_pic.stdinB.gdb
Normal file
16
gdbserver_tests/mcmain_pic.stdinB.gdb
Normal file
@ -0,0 +1,16 @@
|
||||
# connect gdb to Valgrind gdbserver:
|
||||
target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcmain_pic
|
||||
echo vgdb launched process attached\n
|
||||
monitor vg.set vgdb-error 999999
|
||||
#
|
||||
# break
|
||||
break main
|
||||
#
|
||||
continue
|
||||
# first break encountered.
|
||||
print another_func("called from gdb")
|
||||
#
|
||||
print &main
|
||||
print &another_func
|
||||
continue
|
||||
quit
|
||||
4
gdbserver_tests/mcmain_pic.stdout.exp
Normal file
4
gdbserver_tests/mcmain_pic.stdout.exp
Normal file
@ -0,0 +1,4 @@
|
||||
another func called msg called from gdb
|
||||
address of main 0x........
|
||||
address of another_func 0x........
|
||||
another func called msg called from main
|
||||
8
gdbserver_tests/mcmain_pic.stdoutB.exp
Normal file
8
gdbserver_tests/mcmain_pic.stdoutB.exp
Normal file
@ -0,0 +1,8 @@
|
||||
Breakpoint 1 at 0x........: file main_pic.c, line 10.
|
||||
Continuing.
|
||||
Breakpoint 1, main (argc=1, argv=0x........) at main_pic.c:10
|
||||
10 printf("address of main %p\n", &main);
|
||||
$1 = void
|
||||
$2 = (int (*)(int, char **)) 0x........ <main>
|
||||
$3 = (void (*)(char *)) 0x........ <another_func>
|
||||
Continuing.
|
||||
16
gdbserver_tests/mcmain_pic.vgtest
Normal file
16
gdbserver_tests/mcmain_pic.vgtest
Normal file
@ -0,0 +1,16 @@
|
||||
# test that gdbserver/gdb properly handle a PIC executable
|
||||
# On linux, this implies a proper transfer of the auxv
|
||||
# information via the gdbserver protocol packet qXfer:auxv:read:
|
||||
# The content of the auxv data can be shown by gdb using
|
||||
# gdb command 'info auxv'
|
||||
prereq: test -e gdb
|
||||
prog: main_pic
|
||||
vgopts: --tool=memcheck --vgdb=yes --vgdb-error=0 --vgdb-prefix=./vgdb-prefix-mcmain_pic
|
||||
stdout_filter: filter_gdb
|
||||
stderr_filter: filter_memcheck_monitor
|
||||
progB: gdb
|
||||
argsB: --quiet -l 60 --nx ./main_pic
|
||||
stdinB: mcmain_pic.stdinB.gdb
|
||||
stdoutB_filter: filter_gdb
|
||||
stderrB_filter: filter_memcheck_monitor
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user