]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Finally fix the bug causing dynamic ppc64-linux executables not to
authorJulian Seward <jseward@acm.org>
Fri, 30 Dec 2005 22:52:20 +0000 (22:52 +0000)
committerJulian Seward <jseward@acm.org>
Fri, 30 Dec 2005 22:52:20 +0000 (22:52 +0000)
work: start with with the correct toc pointer (r2), rather than some
nonsense value.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@5465

coregrind/m_main.c
coregrind/m_ume.c
coregrind/pub_core_ume.h

index 0bb7161a43e1ed717a003a2df597fdb006cb695c..63e5e1448f00778b34b0f7e05aca2af2d0364c52 100644 (file)
@@ -299,7 +299,7 @@ static char *copy_str(char **tab, const char *str)
 static 
 Addr setup_client_stack( void*  init_sp,
                          char** orig_envp, 
-                         const struct exeinfo *info,
+                         const ExeInfo* info,
                          UInt** client_auxv,
                          Addr   clstack_end,
                          SizeT  clstack_max_size )
@@ -819,8 +819,9 @@ static void config_error ( Char* msg )
 
 /* Load the client whose name is VG_(argv_the_exename). */
 
-static void load_client ( /*OUT*/struct exeinfo* info, 
-                          /*OUT*/Addr* client_eip)
+static void load_client ( /*OUT*/ExeInfo* info, 
+                          /*OUT*/Addr*    client_ip,
+                         /*OUT*/Addr*    client_toc)
 {
    HChar* exe_name;
    Int    ret;
@@ -849,7 +850,8 @@ static void load_client ( /*OUT*/struct exeinfo* info,
       VG_(cl_exec_fd) = res.val;
 
    /* Copy necessary bits of 'info' that were filled in */
-   *client_eip = info->init_eip;
+   *client_ip  = info->init_ip;
+   *client_toc = info->init_toc;
    VG_(brk_base) = VG_(brk_limit) = VG_PGROUNDUP(info->brkbase);
 }
 
@@ -1698,7 +1700,7 @@ static void setup_file_descriptors(void)
 */
 static void init_thread1state ( Addr client_ip, 
                                 Addr client_sp,
-                                Addr entry,
+                                Addr client_toc,
                                 /*inout*/ ThreadArchState* arch )
 {
 #if defined(VGA_x86)
@@ -1761,7 +1763,7 @@ static void init_thread1state ( Addr client_ip,
 
    /* Put essential stuff into the new state. */
    arch->vex.guest_GPR1 = client_sp;
-   arch->vex.guest_GPR2 = ((ULong*)entry)[1];  // TOC ptr
+   arch->vex.guest_GPR2 = client_toc;
    arch->vex.guest_CIA  = client_ip;
 #else
 #  error Unknown arch
@@ -1919,18 +1921,19 @@ static Addr* get_seg_starts ( /*OUT*/Int* n_acquired )
 
 Int main(Int argc, HChar **argv, HChar **envp)
 {
-   HChar*  toolname          = "memcheck";    // default to Memcheck
-   HChar** env               = NULL;
-   Int     need_help         = 0; // 0 = no, 1 = --help, 2 = --help-debug
-   Addr    initial_client_IP = 0;
-   Addr    initial_client_SP = 0;
-   Addr    clstack_top       = 0;
-   SizeT   clstack_max_size  = 0;
+   HChar*  toolname           = "memcheck";    // default to Memcheck
+   HChar** env                = NULL;
+   Int     need_help          = 0; // 0 = no, 1 = --help, 2 = --help-debug
+   Addr    initial_client_IP  = 0;
+   Addr    initial_client_SP  = 0;
+   Addr    initial_client_TOC = 0;
+   Addr    clstack_top        = 0;
+   SizeT   clstack_max_size   = 0;
    UInt*   client_auxv;
    Int     loglevel, i;
    Bool    logging_to_fd;
    struct vki_rlimit zero = { 0, 0 };
-   struct exeinfo info;
+   ExeInfo info;
 
    //============================================================
    //
@@ -2127,7 +2130,7 @@ Int main(Int argc, HChar **argv, HChar **envp)
       if (VG_(args_the_exename) == NULL)
          missing_prog();
 
-      load_client(&info, &initial_client_IP);
+      load_client(&info, &initial_client_IP, &initial_client_TOC);
    }
 
    //--------------------------------------------------------------
@@ -2164,9 +2167,10 @@ Int main(Int argc, HChar **argv, HChar **envp)
 
       VG_(debugLog)(2, "main",
                        "Client info: "
-                       "initial_IP=%p initial_SP=%p brk_base=%p\n",
+                       "initial_IP=%p initial_SP=%p initial_TOC=%p brk_base=%p\n",
                        (void*)initial_client_IP, 
                        (void*)initial_client_SP,
+                       (void*)initial_client_TOC,
                        (void*)VG_(brk_base) );
    }
 
@@ -2483,8 +2487,9 @@ Int main(Int argc, HChar **argv, HChar **envp)
    //      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, 
-                      info.entry,
+   init_thread1state( initial_client_IP, 
+                      initial_client_SP, 
+                      initial_client_TOC,
                       &VG_(threads)[1].arch);
 
    //--------------------------------------------------------------
index 30cbfb9faafe2db70f862fc0d2331166037def6b..1b8c67052cfeb25c10c37746e8f3e5cf9b05c027 100644 (file)
@@ -93,7 +93,7 @@ struct ume_auxv *VG_(find_auxv)(UWord* sp)
       sp++;
    sp++;
    
-#if defined(VGA_ppc32)
+#if defined(VGA_ppc32) || defined(VGA_ppc64)
 # if defined AT_IGNOREPPC
    while (*sp == AT_IGNOREPPC)        // skip AT_IGNOREPPC entries
       sp += 2;
@@ -315,7 +315,7 @@ static Bool match_ELF(const char *hdr, Int len)
 
    - 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 *info)
+static Int load_ELF(Int fd, const HChar* name, /*MOD*/ExeInfo* info)
 {
    SysRes sres;
    struct elfinfo *e;
@@ -498,9 +498,11 @@ static Int load_ELF(Int fd, const char *name, /*MOD*/struct exeinfo *info)
       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 = ((ULong*)entry)[0];
+   info->init_ip  = ((ULong*)entry)[0];
+   info->init_toc = ((ULong*)entry)[1];
 #else
-   info->init_eip = (Addr)entry;
+   info->init_ip  = (Addr)entry;
+   info->init_toc = 0; /* meaningless on this platform */
 #endif
    VG_(free)(e->p);
    VG_(free)(e);
@@ -532,10 +534,10 @@ static Bool match_script(char *hdr, Int len)
 }
 
 // Forward declaration.
-static Int do_exec_inner(const char *exe, struct exeinfo *info);
+static Int do_exec_inner(const HChar* exe, ExeInfo* info);
 
 /* returns: 0 = 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 = VKI_PAGE_SIZE;
@@ -608,7 +610,7 @@ typedef enum {
 } ExeFormat;
 
 // 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 @@ SysRes VG_(pre_exec_check)(const Char* exe_name, Int* out_fd)
 // We can execute only ELF binaries or scripts that begin with "#!".  (Not,
 // 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 @@ static Bool is_binary_file(Char* f)
 // 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 = "/bin/sh";
    SysRes res;
@@ -797,7 +799,7 @@ static Int do_exec_shell_followup(Int ret, Char* exe_name,
 // See ume.h for an indication of which entries of 'info' are inputs, which
 // are outputs, and which are both.
 /* returns: 0 = 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;
    
index 1054e9b08eb2ed4da6aba41e41d070cf7d647a92..0b0aa3145a459bec31380a3e71f4650844b07154 100644 (file)
 
 // 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
-
-   Addr exe_base;       // INOUT: lowest (allowed) address of exe
-   Addr exe_end;        // INOUT: highest (allowed) address
-
-   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
-
-   // These are the extra args added by #! scripts
-   char*  interp_name;  // OUT: the interpreter name
-   char*  interp_args;  // OUT: the args for the interpreter
-};
+typedef
+   struct {
+      HChar** argv;       // IN: the original argv
+
+      Addr exe_base;     // INOUT: lowest (allowed) address of exe
+      Addr exe_end;      // INOUT: highest (allowed) address
+
+      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)
+
+      // 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;
 
 // 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 in
 // either ELF or "#!" format.  On success, 'out_fd' gets the fd of the file
 // 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);
 
 // Does everything short of actually running 'exe': finds the file,
 // checks execute permissions, sets up interpreter if program is a script, 
 // reads headers, maps file into memory, and returns important info about
 // the program.
-extern Int VG_(do_exec)(const char *exe, struct exeinfo *info);
+extern Int VG_(do_exec)(const HChar* exe, ExeInfo* info);
 
 /*------------------------------------------------------------*/
 /*--- Finding and dealing with auxv                        ---*/