|
From: <sv...@va...> - 2005-12-30 22:52:23
|
Author: sewardj
Date: 2005-12-30 22:52:20 +0000 (Fri, 30 Dec 2005)
New Revision: 5465
Log:
Finally fix the bug causing dynamic ppc64-linux executables not to
work: start with with the correct toc pointer (r2), rather than some
nonsense value.
Modified:
trunk/coregrind/m_main.c
trunk/coregrind/m_ume.c
trunk/coregrind/pub_core_ume.h
Modified: trunk/coregrind/m_main.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/m_main.c 2005-12-30 22:50:01 UTC (rev 5464)
+++ trunk/coregrind/m_main.c 2005-12-30 22:52:20 UTC (rev 5465)
@@ -299,7 +299,7 @@
static=20
Addr setup_client_stack( void* init_sp,
char** orig_envp,=20
- const struct exeinfo *info,
+ const ExeInfo* info,
UInt** client_auxv,
Addr clstack_end,
SizeT clstack_max_size )
@@ -819,8 +819,9 @@
=20
/* Load the client whose name is VG_(argv_the_exename). */
=20
-static void load_client ( /*OUT*/struct exeinfo* info,=20
- /*OUT*/Addr* client_eip)
+static void load_client ( /*OUT*/ExeInfo* info,=20
+ /*OUT*/Addr* client_ip,
+ /*OUT*/Addr* client_toc)
{
HChar* exe_name;
Int ret;
@@ -849,7 +850,8 @@
VG_(cl_exec_fd) =3D res.val;
=20
/* Copy necessary bits of 'info' that were filled in */
- *client_eip =3D info->init_eip;
+ *client_ip =3D info->init_ip;
+ *client_toc =3D info->init_toc;
VG_(brk_base) =3D VG_(brk_limit) =3D VG_PGROUNDUP(info->brkbase);
}
=20
@@ -1698,7 +1700,7 @@
*/
static void init_thread1state ( Addr client_ip,=20
Addr client_sp,
- Addr entry,
+ Addr client_toc,
/*inout*/ ThreadArchState* arch )
{
#if defined(VGA_x86)
@@ -1761,7 +1763,7 @@
=20
/* Put essential stuff into the new state. */
arch->vex.guest_GPR1 =3D client_sp;
- arch->vex.guest_GPR2 =3D ((ULong*)entry)[1]; // TOC ptr
+ arch->vex.guest_GPR2 =3D client_toc;
arch->vex.guest_CIA =3D client_ip;
#else
# error Unknown arch
@@ -1919,18 +1921,19 @@
=20
Int main(Int argc, HChar **argv, HChar **envp)
{
- HChar* toolname =3D "memcheck"; // default to Memcheck
- HChar** env =3D NULL;
- Int need_help =3D 0; // 0 =3D no, 1 =3D --help, 2 =3D --h=
elp-debug
- Addr initial_client_IP =3D 0;
- Addr initial_client_SP =3D 0;
- Addr clstack_top =3D 0;
- SizeT clstack_max_size =3D 0;
+ HChar* toolname =3D "memcheck"; // default to Memcheck
+ HChar** env =3D NULL;
+ Int need_help =3D 0; // 0 =3D no, 1 =3D --help, 2 =3D --=
help-debug
+ Addr initial_client_IP =3D 0;
+ Addr initial_client_SP =3D 0;
+ Addr initial_client_TOC =3D 0;
+ Addr clstack_top =3D 0;
+ SizeT clstack_max_size =3D 0;
UInt* client_auxv;
Int loglevel, i;
Bool logging_to_fd;
struct vki_rlimit zero =3D { 0, 0 };
- struct exeinfo info;
+ ExeInfo info;
=20
//=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
//
@@ -2127,7 +2130,7 @@
if (VG_(args_the_exename) =3D=3D NULL)
missing_prog();
=20
- load_client(&info, &initial_client_IP);
+ load_client(&info, &initial_client_IP, &initial_client_TOC);
}
=20
//--------------------------------------------------------------
@@ -2164,9 +2167,10 @@
=20
VG_(debugLog)(2, "main",
"Client info: "
- "initial_IP=3D%p initial_SP=3D%p brk_base=3D%p\n"=
,
+ "initial_IP=3D%p initial_SP=3D%p initial_TOC=3D%p=
brk_base=3D%p\n",
(void*)initial_client_IP,=20
(void*)initial_client_SP,
+ (void*)initial_client_TOC,
(void*)VG_(brk_base) );
}
=20
@@ -2483,8 +2487,9 @@
// setup_scheduler() [for the rest of state 1 stuff]
//--------------------------------------------------------------
VG_(debugLog)(1, "main", "Initialise thread 1's state\n");
- init_thread1state( initial_client_IP, initial_client_SP,=20
- info.entry,
+ init_thread1state( initial_client_IP,=20
+ initial_client_SP,=20
+ initial_client_TOC,
&VG_(threads)[1].arch);
=20
//--------------------------------------------------------------
Modified: trunk/coregrind/m_ume.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/m_ume.c 2005-12-30 22:50:01 UTC (rev 5464)
+++ trunk/coregrind/m_ume.c 2005-12-30 22:52:20 UTC (rev 5465)
@@ -93,7 +93,7 @@
sp++;
sp++;
=20
-#if defined(VGA_ppc32)
+#if defined(VGA_ppc32) || defined(VGA_ppc64)
# if defined AT_IGNOREPPC
while (*sp =3D=3D AT_IGNOREPPC) // skip AT_IGNOREPPC entries
sp +=3D 2;
@@ -315,7 +315,7 @@
=20
- The entry point in INFO is set to the interpreter's entry point,
and we're done. */
-static Int load_ELF(Int fd, const char *name, /*MOD*/struct exeinfo *inf=
o)
+static Int load_ELF(Int fd, const HChar* name, /*MOD*/ExeInfo* info)
{
SysRes sres;
struct elfinfo *e;
@@ -498,9 +498,11 @@
TOC entry contains three words; the first word is the function
address, the second word is the TOC ptr (r2), and the third word
is the static chain value. */
- info->init_eip =3D ((ULong*)entry)[0];
+ info->init_ip =3D ((ULong*)entry)[0];
+ info->init_toc =3D ((ULong*)entry)[1];
#else
- info->init_eip =3D (Addr)entry;
+ info->init_ip =3D (Addr)entry;
+ info->init_toc =3D 0; /* meaningless on this platform */
#endif
VG_(free)(e->p);
VG_(free)(e);
@@ -532,10 +534,10 @@
}
=20
// Forward declaration.
-static Int do_exec_inner(const char *exe, struct exeinfo *info);
+static Int do_exec_inner(const HChar* exe, ExeInfo* info);
=20
/* returns: 0 =3D success, non-0 is failure */
-static Int load_script(Int fd, const char *name, struct exeinfo *info)
+static Int load_script(Int fd, const HChar* name, ExeInfo* info)
{
Char hdr[VKI_PAGE_SIZE];
Int len =3D VKI_PAGE_SIZE;
@@ -608,7 +610,7 @@
} ExeFormat;
=20
// Check the file looks executable.
-SysRes VG_(pre_exec_check)(const Char* exe_name, Int* out_fd)
+SysRes VG_(pre_exec_check)(const HChar* exe_name, Int* out_fd)
{
Int fd, ret;
SysRes res;
@@ -663,7 +665,7 @@
// We can execute only ELF binaries or scripts that begin with "#!". (N=
ot,
// for example, scripts that don't begin with "#!"; see the VG_(do_exec=
)()
// invocation from m_main.c for how that's handled.)
-static Int do_exec_inner(const char *exe, struct exeinfo *info)
+static Int do_exec_inner(const HChar *exe, ExeInfo* info)
{
SysRes res;
Int fd;
@@ -728,8 +730,8 @@
// bash as a guide). It's worth noting that the shell can execute some
// things that VG_(do_exec)() (which subsitutes for the kernel's exec())
// will refuse to (eg. scripts lacking a "#!" prefix).
-static Int do_exec_shell_followup(Int ret, Char* exe_name,
- struct exeinfo* info)
+static Int do_exec_shell_followup(Int ret, HChar* exe_name,
+ ExeInfo* info)
{
Char* default_interp_name =3D "/bin/sh";
SysRes res;
@@ -797,7 +799,7 @@
// See ume.h for an indication of which entries of 'info' are inputs, wh=
ich
// are outputs, and which are both.
/* returns: 0 =3D success, non-0 is failure */
-Int VG_(do_exec)(const char *exe_name, struct exeinfo *info)
+Int VG_(do_exec)(const HChar* exe_name, ExeInfo* info)
{
Int ret;
=20
Modified: trunk/coregrind/pub_core_ume.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/pub_core_ume.h 2005-12-30 22:50:01 UTC (rev 5464)
+++ trunk/coregrind/pub_core_ume.h 2005-12-30 22:52:20 UTC (rev 5465)
@@ -74,36 +74,40 @@
=20
// Info needed to load and run a program. IN/INOUT/OUT refers to the
// inputs/outputs of do_exec().
-struct exeinfo
-{
- char** argv; // IN: the original argv
+typedef
+ struct {
+ HChar** argv; // IN: the original argv
=20
- Addr exe_base; // INOUT: lowest (allowed) address of exe
- Addr exe_end; // INOUT: highest (allowed) address
+ Addr exe_base; // INOUT: lowest (allowed) address of exe
+ Addr exe_end; // INOUT: highest (allowed) address
=20
- Addr phdr; // OUT: address phdr was mapped at
- int phnum; // OUT: number of phdrs
- Addr interp_base; // OUT: where interpreter (ld.so) was mapped
- Addr entry; // OUT: entrypoint in main executable
- Addr init_eip; // OUT: initial eip
- Addr brkbase; // OUT: base address of brk segment
+ Addr phdr; // OUT: address phdr was mapped at
+ Int phnum; // OUT: number of phdrs
+ Addr interp_base; // OUT: where interpreter (ld.so) was mapped
+ Addr entry; // OUT: entrypoint in main executable
+ Addr init_ip; // OUT: address of first instruction to execute
+ Addr brkbase; // OUT: base address of brk segment
+ Addr init_toc; // OUT: address of table-of-contents, on
+ // platforms for which that makes sense
+ // (ppc64-linux only)
=20
- // These are the extra args added by #! scripts
- char* interp_name; // OUT: the interpreter name
- char* interp_args; // OUT: the args for the interpreter
-};
+ // These are the extra args added by #! scripts
+ HChar* interp_name; // OUT: the interpreter name
+ HChar* interp_args; // OUT: the args for the interpreter
+ }
+ ExeInfo;
=20
// Do a number of appropriate checks to see if the file looks executable=
by
// the kernel: ie. it's a file, it's readable and executable, and it's i=
n
// either ELF or "#!" format. On success, 'out_fd' gets the fd of the f=
ile
// if it's non-NULL. Otherwise the fd is closed.
-extern SysRes VG_(pre_exec_check)(const Char* exe_name, Int* out_fd);
+extern SysRes VG_(pre_exec_check)(const HChar* exe_name, Int* out_fd);
=20
// Does everything short of actually running 'exe': finds the file,
// checks execute permissions, sets up interpreter if program is a scrip=
t,=20
// reads headers, maps file into memory, and returns important info abou=
t
// the program.
-extern Int VG_(do_exec)(const char *exe, struct exeinfo *info);
+extern Int VG_(do_exec)(const HChar* exe, ExeInfo* info);
=20
/*------------------------------------------------------------*/
/*--- Finding and dealing with auxv ---*/
|
|
From: Cerion Armour-B. <ce...@op...> - 2006-01-02 13:50:36
|
On Monday 02 January 2006 14:18, Julian Seward wrote: > > I don't see why this fix works... i followed it through, and it looks > > like the only relevant change is to picking up "((ULong*)entry)[1]" in > > load_ELF() instead of later in init_thread1state()... ? > > Because there are two different variables called "entry" which are > unrelated :-). ugh! |