Home | History | Annotate | Download | only in gdb
      1 --- gdb-6.8/gdb/auxv.c.orig	Sun Aug  2 13:51:23 2009
      2 +++ gdb-6.8/gdb/auxv.c	Sun Aug  2 13:51:46 2009
      3 @@ -52,9 +52,21 @@
      4    int fd;
      5    LONGEST n;
      6  
      7 +  /*
      8 +   * Solaris pads auxv for 32 bit process out to 64 bits when being read
      9 +   * by a 64 bit process.  gdb expects a 32 bit auxv for 32 bit processes.
     10 +   * We'll remove the padding here.
     11 +   */
     12 +  int solaris_64_32 = TYPE_LENGTH (builtin_type_void_data_ptr) == 4 && sizeof (void *) == 8;
     13 +
     14    gdb_assert (object == TARGET_OBJECT_AUXV);
     15    gdb_assert (readbuf || writebuf);
     16  
     17 +  /*
     18 +   * Adjust offest for the 64/32 case.
     19 +   */
     20 +  if (solaris_64_32) offset *= 2;
     21 +
     22    pathname = xstrprintf ("/proc/%d/auxv", PIDGET (inferior_ptid));
     23    fd = open (pathname, writebuf != NULL ? O_WRONLY : O_RDONLY);
     24    xfree (pathname);
     25 @@ -64,10 +76,54 @@
     26    if (offset != (ULONGEST) 0
     27        && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
     28      n = -1;
     29 -  else if (readbuf != NULL)
     30 +  else if (readbuf != NULL) {
     31      n = read (fd, readbuf, len);
     32 -  else
     33 +    /*
     34 +     * Remove the padding for the 64/32 case.
     35 +     */
     36 +    if (solaris_64_32) {
     37 +      /*
     38 +       * Solaris pads auxv for 32 bit process out to 64 bits when being read
     39 +       * by a 64 bit process.  gdb expects a 32 bit auxv for 32 bit processes.
     40 +       */
     41 +      unsigned *from, *to;
     42 +      gdb_assert (n % 4 == 0);
     43 +      from = to = (unsigned *)readbuf;
     44 +      while (from < (unsigned *)(readbuf + n)) {
     45 +        /*
     46 +         * The type is always in the first 4 bytes followed by 4 bytes
     47 +         * of padding on both SPARC and x86.
     48 +         */
     49 +        *to++ = *from;
     50 +        from += 2;
     51 +        /*
     52 +         * The value is before the padding on Intel and after on SPARC.
     53 +         */
     54 +        switch (gdbarch_byte_order (current_gdbarch)) {
     55 +          case BFD_ENDIAN_LITTLE:
     56 +            *to++ = *from;
     57 +            gdb_assert (*(from + 1) == 0);
     58 +            break;
     59 +          case BFD_ENDIAN_BIG:
     60 +            gdb_assert (*from == 0);
     61 +            *to++ = *(from + 1);
     62 +            break;
     63 +          default: gdb_assert (0);
     64 +        }
     65 +        from += 2;
     66 +      }
     67 +      /*
     68 +       * Adjust the length for the 64/32 case.
     69 +       */
     70 +      n /= 2;
     71 +    }
     72 +  } else {
     73 +    /*
     74 +     * Does gdb ever write to auxv?
     75 +     */
     76 +    gdb_assert (!writebuf);
     77      n = write (fd, writebuf, len);
     78 +  }
     79  
     80    (void) close (fd);
     81  
     82