Exemplo n.º 1
0
// Reads a signed integer out of the string starting at i, stores it
// in v, and returns the next index to start at.  Zero-length
// decimal numbers are allowed, and are returned as zero.
static int readsigned(unsigned char* s, int len, int i, double* v)
{
    int i0 = i, i2;
    double sgn=1, val;
    if(i >= len) { *v = 0; return len; }
    if(s[i] == '+')      { i++; }
    else if(s[i] == '-') { i++; sgn = -1; }
    i2 = readdec(s, len, i, &val);
    if(i0 == i && i2 == i) {
        *v = 0;
        return i0; // don't successfully parse bare "+" or "-"
    }
    *v = sgn*val;
    return i2;
}
Exemplo n.º 2
0
static int tonum(unsigned char* s, int len, double* result)
{
    int i=0, fraclen=0;
    double sgn=1, val, frac=0, exp=0;

    // Special case, "." is not a number, even though "1." and ".0" are.
    if(len == 1 && s[0] == '.')
        return 0;

    // Strip off the leading negative sign first, so we can correctly
    // parse things like -.xxx which would otherwise confuse
    // readsigned.
    if(len > 1 && s[0] == '-' && s[1] != '-') {
        sgn = -1; s++; len--;
    }

    // Read the integer part
    i = readsigned(s, len, i, &val);
    if(val < 0) { sgn = -1; val = -val; }

    // Read the fractional part, if any
    if(i < len && s[i] == '.') {
        i++;
        fraclen = readdec(s, len, i, &frac) - i;
        i += fraclen;
    }

    // Nothing so far?  Then the parse failed.
    if(i == 0) return 0;

    // Read the exponent, if any
    if(i < len && (s[i] == 'e' || s[i] == 'E')) {
        int i0 = i+1;
        i = readsigned(s, len, i+1, &exp);
        if(i == i0) return 0; // Must have a number after the "e"
    }
    
    // compute the result
    *result = sgn * (val + frac * decpow(-fraclen)) * decpow(exp);

    // if we didn't use the whole string, return failure
    if(i < len) return 0;
    return 1;
}
/* Parse /proc/self/maps.  For each map entry, call
   record_mapping, passing it, in this order:

      start address in memory
      length
      page protections (using the VKI_PROT_* flags)
      mapped file device and inode
      offset in file, or zero if no file
      filename, zero terminated, or NULL if no file

   So the sig of the called fn might be

      void (*record_mapping)( Addr start, SizeT size, UInt prot,
			      UInt dev, UInt info,
                              ULong foffset, UChar* filename )

   Note that the supplied filename is transiently stored; record_mapping 
   should make a copy if it wants to keep it.

   Nb: it is important that this function does not alter the contents of
       procmap_buf!
*/
void VG_(parse_procselfmaps) (
   void (*record_mapping)( Addr addr, SizeT len, UInt prot,
			   UInt dev, UInt ino, ULong foff, const UChar* filename )
   )
{
   Int    i, j, i_eol;
   Addr   start, endPlusOne;
   UChar* filename;
   UChar  rr, ww, xx, pp, ch, tmp;
   UInt	  ino, prot;
   UWord  foffset, maj, min;

   read_procselfmaps();

   tl_assert( '\0' != procmap_buf[0] && 0 != buf_n_tot);

   if (0)
      VG_(message)(Vg_DebugMsg, "raw:\n%s", procmap_buf );

   /* Ok, it's safely aboard.  Parse the entries. */
   i = 0;
   while (True) {
      if (i >= buf_n_tot) break;

      /* Read (without fscanf :) the pattern %16x-%16x %c%c%c%c %16x %2x:%2x %d */
      j = readhex(&procmap_buf[i], &start);
      if (j > 0) i += j; else goto syntaxerror;
      j = readchar(&procmap_buf[i], &ch);
      if (j == 1 && ch == '-') i += j; else goto syntaxerror;
      j = readhex(&procmap_buf[i], &endPlusOne);
      if (j > 0) i += j; else goto syntaxerror;

      j = readchar(&procmap_buf[i], &ch);
      if (j == 1 && ch == ' ') i += j; else goto syntaxerror;

      j = readchar(&procmap_buf[i], &rr);
      if (j == 1 && (rr == 'r' || rr == '-')) i += j; else goto syntaxerror;
      j = readchar(&procmap_buf[i], &ww);
      if (j == 1 && (ww == 'w' || ww == '-')) i += j; else goto syntaxerror;
      j = readchar(&procmap_buf[i], &xx);
      if (j == 1 && (xx == 'x' || xx == '-')) i += j; else goto syntaxerror;
      /* This field is the shared/private flag */
      j = readchar(&procmap_buf[i], &pp);
      if (j == 1 && (pp == 'p' || pp == '-' || pp == 's')) 
                                              i += j; else goto syntaxerror;

      j = readchar(&procmap_buf[i], &ch);
      if (j == 1 && ch == ' ') i += j; else goto syntaxerror;

      j = readhex(&procmap_buf[i], &foffset);
      if (j > 0) i += j; else goto syntaxerror;

      j = readchar(&procmap_buf[i], &ch);
      if (j == 1 && ch == ' ') i += j; else goto syntaxerror;

      j = readhex(&procmap_buf[i], &maj);
      if (j > 0) i += j; else goto syntaxerror;
      j = readchar(&procmap_buf[i], &ch);
      if (j == 1 && ch == ':') i += j; else goto syntaxerror;
      j = readhex(&procmap_buf[i], &min);
      if (j > 0) i += j; else goto syntaxerror;

      j = readchar(&procmap_buf[i], &ch);
      if (j == 1 && ch == ' ') i += j; else goto syntaxerror;

      j = readdec(&procmap_buf[i], &ino);
      if (j > 0) i += j; else goto syntaxerror;
 
      goto read_line_ok;

    syntaxerror:
      VG_(message)(Vg_UserMsg, "FATAL: syntax error reading /proc/self/maps");
      { Int k;
        VG_(printf)("last 50 chars: '");
        for (k = i-50; k <= i; k++) VG_(printf)("%c", procmap_buf[k]);
        VG_(printf)("'\n");
      }
      VG_(exit)(1);

    read_line_ok:

      /* Try and find the name of the file mapped to this segment, if
         it exists. */
      while (procmap_buf[i] != '\n' && i < buf_n_tot-1) i++;
      i_eol = i;
      i--;
      while (!VG_(isspace)(procmap_buf[i]) && i >= 0) i--;
      i++;
      if (i < i_eol-1 && procmap_buf[i] == '/') {
         /* Minor hack: put a '\0' at the filename end for the call to
            'record_mapping', then restore the old char with 'tmp'. */
         filename = &procmap_buf[i];
         tmp = filename[i_eol - i];
         filename[i_eol - i] = '\0';
      } else {
	 tmp = 0;
         filename = NULL;
         foffset = 0;
      }

      prot = 0;
      if (rr == 'r') prot |= VKI_PROT_READ;
      if (ww == 'w') prot |= VKI_PROT_WRITE;
      if (xx == 'x') prot |= VKI_PROT_EXEC;

      //if (start < VG_(valgrind_last))
      (*record_mapping) ( start, endPlusOne-start, 
                          prot, maj * 256 + min, ino,
                          foffset, filename );

      if ('\0' != tmp) {
         filename[i_eol - i] = tmp;
      }

      i = i_eol + 1;
   }
}