]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Fix more ppc64-linux function wrapping and symbol-table bits and pieces.
authorJulian Seward <jseward@acm.org>
Thu, 12 Jan 2006 21:15:35 +0000 (21:15 +0000)
committerJulian Seward <jseward@acm.org>
Thu, 12 Jan 2006 21:15:35 +0000 (21:15 +0000)
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@5523

coregrind/m_debuginfo/symtab.c
coregrind/m_dispatch/dispatch-ppc32-linux.S
coregrind/m_dispatch/dispatch-ppc64-linux.S
coregrind/m_main.c
coregrind/m_redir.c
coregrind/m_scheduler/scheduler.c
coregrind/m_stacktrace.c
coregrind/m_trampoline.S
coregrind/pub_core_trampoline.h
include/valgrind.h

index eea9ff38d296e2a597c6bad6b6f34f3c146bef2e..074767a3db2012104e072f442be253bbf78587b9 100644 (file)
@@ -1106,20 +1106,38 @@ static Bool is_interesting_symbol( SegInfo*   si,
                                                             (ppc64-linux only) */
                                   /*OUT*/Addr* sym_addr_really )
 {
+   Bool plausible;
+
    /* Set default real address for the symbol. */
    *sym_addr_really = sym_addr;
 
-   /* Figure out if we're interested in the symbol.
-      Firstly, is it of the right flavour?  */
-   if ( ! ( (ELFXX_ST_BIND(sym->st_info) == STB_GLOBAL ||
-             ELFXX_ST_BIND(sym->st_info) == STB_LOCAL ||
-             ELFXX_ST_BIND(sym->st_info) == STB_WEAK)
-          &&
-            (ELFXX_ST_TYPE(sym->st_info) == STT_FUNC ||
-             (VG_(needs).data_syms 
-              && ELFXX_ST_TYPE(sym->st_info) == STT_OBJECT))
-          )
-      )
+   /* Figure out if we're interested in the symbol.  Firstly, is it of
+      the right flavour?  */
+   plausible 
+      = (ELFXX_ST_BIND(sym->st_info) == STB_GLOBAL 
+         || ELFXX_ST_BIND(sym->st_info) == STB_LOCAL 
+         || ELFXX_ST_BIND(sym->st_info) == STB_WEAK
+        )
+        &&
+        (ELFXX_ST_TYPE(sym->st_info) == STT_FUNC 
+         || (VG_(needs).data_syms 
+             && ELFXX_ST_TYPE(sym->st_info) == STT_OBJECT)
+        );
+
+#  if defined(VGP_ppc64_linux)
+   /* Allow STT_NOTYPE in the very special case where we're running on
+      ppc64-linux and the symbol is one which the .opd-chasing hack
+      below will chase. */
+   if (!plausible
+       && ELFXX_ST_TYPE(sym->st_info) == STT_NOTYPE
+       && sym->st_size > 0
+       && si->opd_start_vma != 0
+       && sym_addr >= si->opd_start_vma
+       && sym_addr <  si->opd_start_vma + si->opd_size)
+      plausible = True;
+#  endif
+
+   if (!plausible)
       return False;
 
    /* Secondly, if it's apparently in a GOT or PLT, it's really
@@ -1287,7 +1305,8 @@ void read_symtab( SegInfo* si, Char* tab_name, Bool do_intercepts,
       }               
 
       // Record interesting symbols in our symtab.
-      if ( is_interesting_symbol(si, sym, sym_name, sym_addr, opd_filea, &sym_addr_really) ) {
+      if ( is_interesting_symbol(si, sym, sym_name, sym_addr, 
+                                     opd_filea, &sym_addr_really) ) {
          vg_assert(sym->st_name != 0);
          vg_assert(sym_name[0]  != 0);
 #        if defined(VGP_ppc64_linux)
@@ -1299,12 +1318,30 @@ void read_symtab( SegInfo* si, Char* tab_name, Bool do_intercepts,
          vg_assert(sym_addr_really + sym->st_size <= si->opd_start_vma
                    || sym_addr_really >= si->opd_start_vma + si->opd_size);
 #        endif
+#        if defined(VGP_ppc64_linux)
+         /* Another ppc64-linux kludge, for the pre-"dotless" ABI
+            (prior to gcc 4.0.0).  If the symbol to be added has a
+            leading dot and it wasn't derived via an indirect through
+            .opd, remove the dot before adding it. */
+         if (sym_addr_really == sym_addr && sym_name[0] == '.')
+            sym_name++;
+#        endif
+
          name = ML_(addStr) ( si, sym_name, -1 );
          vg_assert(name != NULL);
+
          risym.addr  = sym_addr_really;
          risym.size  = sym->st_size;
          risym.name  = name;
          addSym ( si, &risym );
+
+         if (VG_(clo_trace_symtab))
+            VG_(printf)("    record [%d]:          "
+                        " value %p, size %d, name %s\n",
+                        i, (void*)risym.addr, (Int)risym.size, 
+                           (HChar*)risym.name
+            );
+
       }
    }
 }
index 1a672896b2fde30541ba1767592e3944402b7a0c..0f3226bbc7a3a8b26b80fd41ab18ec3ba4ab3837 100644 (file)
@@ -562,7 +562,6 @@ void VG_(run_a_noredir_translation) ( UWord* argblock );
       2: output: next guest PC
       3: output: guest state pointer afterwards (== thread return code)
 */
-.align 16
 .global VG_(run_a_noredir_translation)
 VG_(run_a_noredir_translation):
        /* save callee-save int regs, & lr */
index f9b11dee18fc89965b7e492b5509b9c6140d32b3..458a7e76a765293a6f4590b7554bc8fe17f38ebb 100644 (file)
         .tc vgPlain_machine_ppc64_has_VMX[TC],vgPlain_machine_ppc64_has_VMX
 
 /*------------------------------------------------------------*/
-/*--- The dispatch loop.                                   ---*/
+/*---                                                      ---*/
+/*--- The dispatch loop.  VG_(run_innerloop) is used to    ---*/
+/*--- run all translations except no-redir ones.           ---*/
+/*---                                                      ---*/
 /*------------------------------------------------------------*/
 
 /*----------------------------------------------------*/
@@ -570,6 +573,95 @@ VG_(run_innerloop__dispatch_profiled):
         blr
 
 
+/*------------------------------------------------------------*/
+/*---                                                      ---*/
+/*--- A special dispatcher, for running no-redir           ---*/
+/*--- translations.  Just runs the given translation once. ---*/
+/*---                                                      ---*/
+/*------------------------------------------------------------*/
+
+/* signature:
+void VG_(run_a_noredir_translation) ( UWord* argblock );
+*/
+
+/* Run a no-redir translation.  argblock points to 4 UWords, 2 to carry args
+   and 2 to carry results:
+      0: input:  ptr to translation
+      1: input:  ptr to guest state
+      2: output: next guest PC
+      3: output: guest state pointer afterwards (== thread return code)
+*/
+.section ".text"
+.align   2
+.globl VG_(run_a_noredir_translation)
+.section ".opd","aw"
+.align   3
+VG_(run_a_noredir_translation):
+.quad    .VG_(run_a_noredir_translation),.TOC.@tocbase,0
+.previous
+.type    .VG_(run_a_noredir_translation),@function
+.globl   .VG_(run_a_noredir_translation)
+.VG_(run_a_noredir_translation):
+       /* save callee-save int regs, & lr */
+       stdu 1,-512(1)
+       std  14,256(1)
+       std  15,264(1)
+       std  16,272(1)
+       std  17,280(1)
+       std  18,288(1)
+       std  19,296(1)
+       std  20,304(1)
+       std  21,312(1)
+       std  22,320(1)
+       std  23,328(1)
+       std  24,336(1)
+       std  25,344(1)
+       std  26,352(1)
+       std  27,360(1)
+       std  28,368(1)
+       std  29,376(1)
+       std  30,384(1)
+       std  31,392(1)
+       mflr 31
+       std  31,400(1)
+       std   2,408(1)  /* also preserve R2, just in case .. */
+
+       stw  3,416(1)
+       lwz  31,8(3)
+       lwz  30,0(3)
+       mtlr 30
+       blrl
+
+       lwz  4,416(1)
+       stw  3, 16(4)
+       stw  31,24(4)
+
+       ld   14,256(1)
+       ld   15,264(1)
+       ld   16,272(1)
+       ld   17,280(1)
+       ld   18,288(1)
+       ld   19,296(1)
+       ld   20,304(1)
+       ld   21,312(1)
+       ld   22,320(1)
+       ld   23,328(1)
+       ld   24,336(1)
+       ld   25,344(1)
+       ld   26,352(1)
+       ld   27,360(1)
+       ld   28,368(1)
+       ld   29,376(1)
+       ld   30,384(1)
+       ld   31,400(1)
+       mtlr 31
+       ld   31,392(1)
+       ld    2,408(1)  /* also preserve R2, just in case .. */
+
+       addi 1,1,512
+       blr
+
+
 /* Let the linker know we don't need an executable stack */
 .section .note.GNU-stack,"",@progbits
 
index a66fdb9e1c148c72d644438e6e9b8d5a9adfce87..8cd1e944f87074a22ad854b2114b7ed9037e0d58 100644 (file)
@@ -2399,12 +2399,8 @@ Int main(Int argc, HChar **argv, HChar **envp)
    //   p: aspacem
    //--------------------------------------------------------------
    { Bool change_ownership_v_c_OK;
-     Addr co_start   = VG_PGROUNDDN( 
-                          (Addr)VG_(fnptr_to_fnentry)( 
-                             &VG_(trampoline_stuff_start) ) );
-     Addr co_endPlus = VG_PGROUNDUP( 
-                          (Addr)VG_(fnptr_to_fnentry)( 
-                             &VG_(trampoline_stuff_end) ) );
+     Addr co_start   = VG_PGROUNDDN( (Addr)&VG_(trampoline_stuff_start) );
+     Addr co_endPlus = VG_PGROUNDUP( (Addr)&VG_(trampoline_stuff_end) );
      VG_(debugLog)(1,"redir",
                      "transfer ownership V -> C of 0x%llx .. 0x%llx\n",
                      (ULong)co_start, (ULong)co_endPlus-1 );
@@ -2703,8 +2699,11 @@ static void final_tidyup(ThreadId tid)
                   "Caught __NR_exit; running __libc_freeres()");
       
    /* set thread context to point to libc_freeres_wrapper */
+   /* ppc64-linux note: __libc_freeres_wrapper gives us the real
+      function entry point, not a fn descriptor, so can use it
+      directly.  However, we need to set R2 (the toc pointer)
+      appropriately. */
    VG_(set_IP)(tid, __libc_freeres_wrapper);
-   // XXX should we use a special stack?
 
    /* Block all blockable signals by copying the real block state into
       the thread's block state*/
index df3fcae537b61ee43abc2506cfa232aec214c61b..d4ccdb3471f66708c713023435368af3d8ab3a9d 100644 (file)
@@ -767,11 +767,16 @@ void VG_(redir_initialise) ( void )
       the start, otherwise ld.so makes a lot of noise. */
    if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
 
-      add_redirect_sym_to_addr(
-         "soname:ld64.so.1", "strlen",
+      add_hardwired_spec(
+         "ld64.so.1", "strlen",
          (Addr)VG_(fnptr_to_fnentry)( &VG_(ppc64_linux_REDIR_FOR_strlen) )
       );   
 
+      add_hardwired_spec(
+         "ld64.so.1", "index",
+         (Addr)VG_(fnptr_to_fnentry)( &VG_(ppc64_linux_REDIR_FOR_strchr) )
+      );   
+
    }
 
 #  else
index 275f73b1e3db9a815ff4a5bbe37bd943cd191540..0b5246592f6e7f899cffbe99e8c0dcd97946af9f 100644 (file)
@@ -522,7 +522,7 @@ static inline void do_pre_run_checks ( volatile ThreadState* tst )
 static UInt run_thread_for_a_while ( ThreadId tid )
 {
    volatile Int          jumped;
-   volatile ThreadState* tst
+   volatile ThreadState* tst = NULL; /* stop gcc complaining */
    volatile UInt         trc;
    volatile Int          dispatch_ctr_SAVED;
    volatile Int          done_this_time;
index a9ad219630374edef4c9f57c576b2b402805ec2b..2e866d69469e37698d0e567ae90dae74eed6582b 100644 (file)
@@ -389,8 +389,10 @@ void VG_(apply_StackTrace)( void(*action)(UInt n, Addr ip),
          mybuf[MYBUF_LEN-1] = 0; // paranoia
          if ( VG_STREQ("main", mybuf)
 #             if defined(VGO_linux)
-              || VG_STREQ("__libc_start_main", mybuf)  // glibc glibness
-              || VG_STREQ("generic_start_main", mybuf) // Yellow Dog doggedness
+              || VG_STREQ("__libc_start_main", mybuf)   // glibc glibness
+              || VG_STREQ("generic_start_main", mybuf)  // Yellow Dog doggedness
+              || VG_STREQ(".__libc_start_main", mybuf)  // ppc64 dottyness
+              || VG_STREQ(".generic_start_main", mybuf) // ditto
 #             endif
             )
             main_done = True;
index f2e0c8a32fb0e66785019f34d67cd8968b69aae6..85428df2c784b68d46dd2f9e11cd73069e069c8a 100644 (file)
@@ -299,25 +299,21 @@ VG_(trampoline_stuff_end):
        /* a leading page of unexecutable code */
        UD2_PAGE
 
-.align 2
 .global VG_(trampoline_stuff_start)
-.section ".opd","aw"
-.align 3
 VG_(trampoline_stuff_start):
-.quad .VG_(trampoline_stuff_start),.TOC.@tocbase,0
-.previous
-.type .VG_(trampoline_stuff_start),@function
-.global  .VG_(trampoline_stuff_start)
-.VG_(trampoline_stuff_start):
-
-.align 2
-.globl VG_(ppc64_linux_REDIR_FOR_strlen)
-.section        ".opd","aw"
-.align 3
+
+       /* this function is written using the "dotless" ABI convention */
+       .align 2
+       .globl VG_(ppc64_linux_REDIR_FOR_strlen)
+       .section        ".opd","aw"
+       .align 3
 VG_(ppc64_linux_REDIR_FOR_strlen):
-.quad   .L.VG_(ppc64_linux_REDIR_FOR_strlen),.TOC.@tocbase
-.previous
-.type   VG_(ppc64_linux_REDIR_FOR_strlen), @function
+       .quad   .L.VG_(ppc64_linux_REDIR_FOR_strlen),.TOC.@tocbase,0
+       .previous
+       .size   VG_(ppc64_linux_REDIR_FOR_strlen), \
+                       .L0end-.L.VG_(ppc64_linux_REDIR_FOR_strlen)
+       .type   VG_(ppc64_linux_REDIR_FOR_strlen), @function
+
 .L.VG_(ppc64_linux_REDIR_FOR_strlen):
         mr 9,3
         lbz 0,0(3)
@@ -325,27 +321,51 @@ VG_(ppc64_linux_REDIR_FOR_strlen):
         cmpwi 7,0,0
         beqlr 7
         li 3,0
-.L5:
+.L01:
         addi 0,3,1
         extsw 3,0
         lbzx 0,9,3
         cmpwi 7,0,0
-        bne 7,.L5
+        bne 7,.L01
         blr
         .long 0
         .byte 0,0,0,0,0,0,0,0
-        .size   VG_(ppc64_linux_REDIR_FOR_strlen),.-.L.VG_(ppc64_linux_REDIR_FOR_strlen)
+.L0end:
+
+        /* this function is written using the "dotless" ABI convention */
+        .align 2
+        .globl VG_(ppc64_linux_REDIR_FOR_strchr)
+       .section        ".opd","aw"
+       .align 3
+VG_(ppc64_linux_REDIR_FOR_strchr):
+        .quad   .L.VG_(ppc64_linux_REDIR_FOR_strchr),.TOC.@tocbase,0
+        .previous
+        .size   VG_(ppc64_linux_REDIR_FOR_strchr), \
+                        .L1end-.L.VG_(ppc64_linux_REDIR_FOR_strchr)
+        .type   VG_(ppc64_linux_REDIR_FOR_strchr),@function
+       
+.L.VG_(ppc64_linux_REDIR_FOR_strchr):
+        rldicl 4,4,0,56
+        li 9,0
+.L11:
+        lbz 0,0(3)
+        cmpw 7,0,4
+        bne+ 7,.L12
+        mr 9,3
+.L12:
+        lbz 0,0(3)
+        addi 3,3,1
+        cmpwi 7,0,0
+        bne+ 7,.L11
+        mr 3,9
+        blr
+        .long 0
+        .byte 0,0,0,0,0,0,0,0
+.L1end:
 
-.align 2
+       
 .global VG_(trampoline_stuff_end)
-.section ".opd","aw"
-.align 3
 VG_(trampoline_stuff_end):
-.quad .VG_(trampoline_stuff_end),.TOC.@tocbase,0
-.previous
-.type .VG_(trampoline_stuff_end),@function
-.global  .VG_(trampoline_stuff_end)
-.VG_(trampoline_stuff_end):
 
        /* and a trailing page of unexecutable code */
        UD2_PAGE
index 0113fa70cbd49af6c4ef7b9c08f6f6b4a79dc94f..2034c41d86bd7be5179fc6b253c8f7f53b32c353 100644 (file)
@@ -68,6 +68,7 @@ extern void* VG_(ppc32_linux_REDIR_FOR_strchr)( void*, Int );
 
 #if defined(VGP_ppc64_linux)
 extern UInt  VG_(ppc64_linux_REDIR_FOR_strlen)( void* );
+extern void* VG_(ppc64_linux_REDIR_FOR_strchr)( void*, Int );
 #endif
  
 #endif   // __PUB_CORE_TRAMPOLINE_H
index 6864d40923858584e285e8418803b1f5db450547..0865fa95d1d51a055ff1f20154d0e73d7fec8ff1 100644 (file)
 #if defined(ARCH_x86)
 #define __SPECIAL_INSTRUCTION_PREAMBLE                            \
                      "roll $3,  %%edi ; roll $13, %%edi\n\t"      \
-                     "roll $29, %%edi ; roll $19, %%edi\n\t"      \
+                     "roll $29, %%edi ; roll $19, %%edi\n\t"
 
 #define VALGRIND_DO_CLIENT_REQUEST(                               \
         _zzq_rlval, _zzq_default, _zzq_request,                   \
 #if defined(ARCH_amd64)
 #define __SPECIAL_INSTRUCTION_PREAMBLE                            \
                      "rolq $3,  %%rdi ; rolq $13, %%rdi\n\t"      \
-                     "rolq $61, %%rdi ; rolq $51, %%rdi\n\t"      \
+                     "rolq $61, %%rdi ; rolq $51, %%rdi\n\t"
 
 #define VALGRIND_DO_CLIENT_REQUEST(                               \
         _zzq_rlval, _zzq_default, _zzq_request,                   \
 #if defined(ARCH_ppc32)
 #define __SPECIAL_INSTRUCTION_PREAMBLE                            \
                      "rlwinm 0,0,3,0,0  ; rlwinm 0,0,13,0,0\n\t"  \
-                     "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"  \
+                     "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
 
 #define VALGRIND_DO_CLIENT_REQUEST(                               \
         _zzq_rlval, _zzq_default, _zzq_request,                   \
         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4)               \
                                                                   \
-  { volatile unsigned int _zzq_args[5];                           \
-    register unsigned int _zzq_result __asm__("r3");              \
-    register volatile unsigned int *_zzq_ptr __asm__("r4");       \
+  {          unsigned int  _zzq_args[5];                          \
+    register unsigned int  _zzq_result __asm__("r3");             \
+    register unsigned int* _zzq_ptr __asm__("r4");                \
     _zzq_args[0] = (unsigned int)(_zzq_request);                  \
     _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
     _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
 /* --------------------------- ppc64 --------------------------- */
 
 #if defined(ARCH_ppc64)
+#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
+                     "rotldi 0,0,3  ; rotldi 0,0,13\n\t"          \
+                     "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
+
 #define VALGRIND_DO_CLIENT_REQUEST(                               \
         _zzq_rlval, _zzq_default, _zzq_request,                   \
         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4)               \
                                                                   \
-  { volatile unsigned long long int _zzq_args[5];                 \
-    register unsigned long long int _zzq_tmp __asm__("r3");       \
-    register volatile unsigned long long int *_zzq_ptr __asm__("r4"); \
-    _zzq_args[0] = (volatile unsigned long long int)(_zzq_request);   \
-    _zzq_args[1] = (volatile unsigned long long int)(_zzq_arg1);  \
-    _zzq_args[2] = (volatile unsigned long long int)(_zzq_arg2);  \
-    _zzq_args[3] = (volatile unsigned long long int)(_zzq_arg3);  \
-    _zzq_args[4] = (volatile unsigned long long int)(_zzq_arg4);  \
+  {          unsigned long long int  _zzq_args[5];                \
+    register unsigned long long int  _zzq_result __asm__("r3");   \
+    register unsigned long long int* _zzq_ptr __asm__("r4");      \
+    _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
+    _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
+    _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
+    _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
+    _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
     _zzq_ptr = _zzq_args;                                         \
-    __asm__ volatile("tw 0,3,27\n\t"                              \
-                     "rotldi  0,0,61\n\t"                         \
-                     "rotldi  0,0,3\n\t"                          \
-                     "rotldi  0,0,13\n\t"                         \
-                     "rotldi  0,0,51\n\t"                         \
-                     "nop\n\t"                                    \
-                     : "=r" (_zzq_tmp)                            \
+    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
+                     /* %R3 = client_request ( %R4 ) */           \
+                     "or 1,1,1"                                   \
+                     : "=r" (_zzq_result)                         \
                      : "0" (_zzq_default), "r" (_zzq_ptr)         \
-                     : "memory");                                 \
-    _zzq_rlval = (__typeof__(_zzq_rlval)) _zzq_tmp;               \
+                     : "cc", "memory");                           \
+    _zzq_rlval = _zzq_result;                                     \
+  }
+
+#define VALGRIND_GET_NRADDR(_zzq_rlval)                           \
+  { register unsigned long long int __addr __asm__("r3");         \
+    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
+                     /* %R3 = guest_NRADDR */                     \
+                     "or 2,2,2"                                   \
+                     : "=r" (__addr)                              \
+                     :                                            \
+                     : "cc", "memory"                             \
+                    );                                            \
+    _zzq_rlval = (void*)__addr;                                   \
   }
+
+#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
+                     __SPECIAL_INSTRUCTION_PREAMBLE               \
+                     /* branch-and-link-to-noredir *%R11 */       \
+                     "or 3,3,3\n\t"
+
 #endif /* ARCH_ppc64 */
 
 /* Insert assembly code for other architectures here... */