Example #1
0
void VG_(setup_code_redirect_table) ( void )
{
   // Initialise resolved_redirs list.
   resolved_redirs = VG_(OSet_Create)(offsetof(CodeRedirect, from_addr),
                                      NULL,     // Use fast comparison
                                      symtab_alloc,
                                      symtab_free);

#if defined(VGP_x86_linux)
   /* Redirect _dl_sysinfo_int80, which is glibc's default system call
      routine, to our copy so that the special sysinfo unwind hack in
      m_stacktrace.c will kick in.  */
   add_redirect_sym_to_addr(
      "soname:ld-linux.so.2", "_dl_sysinfo_int80",
      (Addr)&VG_(x86_linux_REDIR_FOR__dl_sysinfo_int80)
   );
   /* If we're using memcheck, use this intercept right from the
      start, otherwise ld.so (glibc-2.3.5) makes a lot of noise. */
   if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
      add_redirect_sym_to_addr(
         "soname:ld-linux.so.2", "index",
         (Addr)&VG_(x86_linux_REDIR_FOR_index)
      );   
   }

#elif defined(VGP_amd64_linux)

   /* Redirect vsyscalls to local versions */
   add_redirect_addr_to_addr(
      0xFFFFFFFFFF600000ULL,
      (Addr)&VG_(amd64_linux_REDIR_FOR_vgettimeofday) 
   );
   add_redirect_addr_to_addr( 
      0xFFFFFFFFFF600400ULL,
      (Addr)&VG_(amd64_linux_REDIR_FOR_vtime) 
   );

#elif defined(VGP_ppc32_linux)

   /* If we're using memcheck, use these intercepts right from
      the start, otherwise ld.so makes a lot of noise. */
   if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {

      add_redirect_sym_to_addr(
         "soname:ld.so.1", "strlen",
         (Addr)&VG_(ppc32_linux_REDIR_FOR_strlen)
      );   
      add_redirect_sym_to_addr(
         "soname:ld.so.1", "strcmp",
         (Addr)&VG_(ppc32_linux_REDIR_FOR_strcmp)
      );

   }

#else
#  error Unknown platform
#endif
}
Example #2
0
void VG_(setup_code_redirect_table) ( void )
{

   // Initialise resolved_redirs list.
   resolved_redirs = VG_(OSet_Create)(offsetof(CodeRedirect, from_addr),
                                      NULL,     // Use fast comparison
                                      symtab_alloc,
                                      symtab_free);

#if defined(VGP_x86_linux)
   /* Redirect _dl_sysinfo_int80, which is glibc's default system call
      routine, to our copy so that the special sysinfo unwind hack in
      m_stacktrace.c will kick in.  */
   add_redirect_sym_to_addr(
      "soname:ld-linux.so.2", "_dl_sysinfo_int80",
      (Addr)&VG_(x86_linux_REDIR_FOR__dl_sysinfo_int80)
   );
   /* If we're using memcheck, use this intercept right from the
      start, otherwise ld.so (glibc-2.3.5) makes a lot of noise. */
   if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
      add_redirect_sym_to_addr(
         "soname:ld-linux.so.2", "index",
         (Addr)&VG_(x86_linux_REDIR_FOR_index)
      );   
   }

#elif defined(VGP_amd64_linux)

   /* Redirect vsyscalls to local versions */
   add_redirect_addr_to_addr(
      0xFFFFFFFFFF600000ULL,
      (Addr)&VG_(amd64_linux_REDIR_FOR_vgettimeofday) 
      );
   add_redirect_addr_to_addr( 
      0xFFFFFFFFFF600400ULL,
      (Addr)&VG_(amd64_linux_REDIR_FOR_vtime) 
   );

#elif defined(VGP_ppc32_linux)

   /* If we're using memcheck, use these intercepts right from
      the start, otherwise ld.so makes a lot of noise. */
   if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {

      add_redirect_sym_to_addr(
         "soname:ld.so.1", "strlen",
         (Addr)&VG_(ppc32_linux_REDIR_FOR_strlen)
      );   
      add_redirect_sym_to_addr(
         "soname:ld.so.1", "strcmp",
         (Addr)&VG_(ppc32_linux_REDIR_FOR_strcmp)
      );

#elif defined(VGP_x86_netbsdelf2)

   /* Redirect _dl_sysinfo_int80, which is glibc's default system call
      routine, to our copy so that the special sysinfo unwind hack in
      m_stacktrace.c will kick in.  */
/*    add_redirect_sym_to_addr( */
/*       "soname:ld-linux.so.2", "_dl_sysinfo_int80", */
/*       (Addr)&VG_(x86_netbsd_REDIR_FOR__dl_sysinfo_int80) */
/*    ); */
   /* If we're using memcheck, use this intercept right from the
      start, otherwise ld.so (glibc-2.3.5) makes a lot of noise. */
/*    if (0==VG_(strcmp)("Memcheck", VG_(details).name)) { */
/*       add_redirect_sym_to_addr( */
/*          "soname:ld.elf_so", "index", */
/*          (Addr)&VG_(x86_linux_REDIR_FOR_index) */
/*       );    */
/*    } */
   // NetBSD: TODO - XXXX 
/*  add_redirect_sym_to_addr( */
/*       "soname:ld.elf_so", "_dl_sysinfo_int80", */
/*       (Addr)&VG_(x86_linux_REDIR_FOR__dl_sysinfo_int80) */
/*    ); */

#else
#  error Unknown platform
#endif
}

/* Z-decode a symbol into library:func form, eg 
  
     _vgi_libcZdsoZd6__ZdlPv  -->  libc.so.6:_ZdlPv

   Uses the Z-encoding scheme described in pub_core_redir.h.
   Returns True if demangle OK, False otherwise.
*/
static Bool Z_decode(const Char* symbol, Char* result, Int nbytes)
{
#  define EMIT(ch)                    \
      do {                            \
         if (j >= nbytes)             \
            result[j-1] = 0;          \
         else                         \
            result[j++] = ch;         \
      } while (0)

   Bool error = False;
   Int i, j = 0;
   Int len = VG_(strlen)(symbol);
   if (0) VG_(printf)("idm: %s\n", symbol);

   i = VG_REPLACE_FUNCTION_PREFIX_LEN;

   /* Chew though the Z-encoded soname part. */
   while (True) {

      if (i >= len) 
         break;

      if (symbol[i] == '_')
         /* We found the underscore following the Z-encoded soname.
            Just copy the rest literally. */
         break;

      if (symbol[i] != 'Z') {
         EMIT(symbol[i]);
         i++;
         continue;
      }

      /* We've got a Z-escape.  Act accordingly. */
      i++;
      if (i >= len) {
         /* Hmm, Z right at the end.  Something's wrong. */
         error = True;
         EMIT('Z');
         break;
      }
      switch (symbol[i]) {
         case 'a': EMIT('*'); break;
         case 'p': EMIT('+'); break;
         case 'c': EMIT(':'); break;
         case 'd': EMIT('.'); break;
         case 'u': EMIT('_'); break;
         case 'h': EMIT('-'); break;
         case 's': EMIT(' '); break;
         case 'Z': EMIT('Z'); break;
         default: error = True; EMIT('Z'); EMIT(symbol[i]); break;
      }
      i++;
   }

   if (error || i >= len || symbol[i] != '_') {
      /* Something's wrong.  Give up. */
      VG_(message)(Vg_UserMsg, "intercept: error demangling: %s", symbol);
      EMIT(0);
      return False;
   }

   /* Copy the rest of the string verbatim. */
   i++;
   EMIT(':');
   while (True) {
     if (i >= len)
        break;
     EMIT(symbol[i]);
     i++;
   }

   EMIT(0);
   if (0) VG_(printf)("%s\n", result);
   return True;

#  undef EMIT
}