|
From: <sv...@va...> - 2007-11-29 03:07:24
|
Author: sewardj
Date: 2007-11-29 03:06:25 +0000 (Thu, 29 Nov 2007)
New Revision: 7248
Log:
Don't be confused by archive (.a) files which contain both a 32-bit
and a 64-bit version of the same object (with the same name). Prior
to this, it would sometimes attempt to read debug info from the wrong
version of the object, complain that the magic number wasn't right,
and so end up reading nothing at all for that object.
Modified:
trunk/coregrind/m_debuginfo/readxcoff.c
Modified: trunk/coregrind/m_debuginfo/readxcoff.c
===================================================================
--- trunk/coregrind/m_debuginfo/readxcoff.c 2007-11-28 01:55:29 UTC (rev 7247)
+++ trunk/coregrind/m_debuginfo/readxcoff.c 2007-11-29 03:06:25 UTC (rev 7248)
@@ -1708,7 +1708,7 @@
# endif
if (n_oimage < sizeof(FILHDR))
- BAD("readxcoff.c: XCOFF object file header is implausibly small");
+ BAD("readxcoff.c: XCOFF object file header is implausibly small (2)");
FILHDR* t_filehdr = (FILHDR*)cursor;
cursor += sizeof(FILHDR);
@@ -2233,7 +2233,7 @@
peer at the archive's fixed header. */
if (n_image < sizeof(FL_HDR)) {
- ML_(symerr)("XCOFF archive to small for fixed header");
+ ML_(symerr)("XCOFF archive too small for fixed header");
goto done;
}
@@ -2269,7 +2269,7 @@
/* should be: backquote newline */
if (mt_hdr->_ar_name.ar_name[0] != 0x60 /* backquote */
|| mt_hdr->_ar_name.ar_name[1] != 0x0A /* \n */) {
- ML_(symerr)("XCOFF archive member table header is invalid");
+ ML_(symerr)("XCOFF archive member table header is invalid");
goto done;
}
@@ -2304,61 +2304,89 @@
i, (Int)ascii_to_ULong(data + 20 + 20*i, 20));
}
- UInt objoff = 0; /* none of the archive members can have zero
- offset, since the fixed header is at the
- start of the file. */
+ UChar* p = data + 20 + 20*nmembers;
- UChar* p = data + 20 + 20*nmembers;
for (i = 0; i < nmembers; i++) {
- if (0 == VG_(strcmp)(p, o_name)) {
- objoff = ascii_to_ULong(data + 20 + 20*i, 20);
- if (SHOW && SHOW_AR_DETAILS)
- VG_(printf)("got offset = %u\n", objoff);
- }
- while (*p) {
- if (SHOW && SHOW_AR_DETAILS)
- VG_(printf)("%c", *p);
- p++;
- }
+
+ if (0 != VG_(strcmp)(p, o_name))
+ goto move_on;
+
+ UInt objoff = ascii_to_ULong(data + 20 + 20*i, 20);
+
if (SHOW && SHOW_AR_DETAILS)
- VG_(printf)("\n");
- p++;
- }
+ VG_(printf)("got offset = %u\n", objoff);
- vg_assert(ok == False);
+ vg_assert(ok == False);
- if (objoff == 0) {
- ML_(symerr)("can't find object in XCOFF archive file");
- goto done;
- }
+ /* Sanity check the selected member */
+ UChar* o_hdrC = image + objoff;
+ if (o_hdrC + sizeof(AR_HDR) >= image + n_image) {
+ ML_(symerr)("XCOFF archive member header exceeds image");
+ goto done;
+ }
+ AR_HDR* o_hdr = (AR_HDR*)o_hdrC;
+ UWord o_size = (UWord)ascii_to_ULong(&o_hdr->ar_size, 20);
+ UChar* o_data = o_hdrC + sizeof(AR_HDR)
+ + (UWord)ascii_to_ULong(&o_hdr->ar_namlen,4);
- /* Sanity check the selected member */
- UChar* o_hdrC = image + objoff;
- if (o_hdrC + sizeof(AR_HDR) >= image + n_image) {
- ML_(symerr)("XCOFF archive member header exceeds image");
- goto done;
- }
- AR_HDR* o_hdr = (AR_HDR*)o_hdrC;
- UWord o_size = (UWord)ascii_to_ULong(&o_hdr->ar_size, 20);
- UChar* o_data = o_hdrC + sizeof(AR_HDR)
- + (UWord)ascii_to_ULong(&o_hdr->ar_namlen,4);
+ /* ALIGN */
+ if ( ((UWord)o_data) & 1 ) o_data++;
- /* ALIGN */
- if ( ((UWord)o_data) & 1 ) o_data++;
+ if (SHOW)
+ VG_(printf)("member data = %p, size = %ld\n", o_data, o_size);
- if (SHOW)
- VG_(printf)("member data = %p, size = %ld\n", o_data, o_size);
+ if (!(o_data >= image && o_data + o_size <= image + n_image)) {
+ ML_(symerr)("XCOFF archive member exceeds image");
+ goto done;
+ }
- if (o_data >= image && o_data + o_size <= image + n_image) {
+ if (o_size < sizeof(FILHDR)) {
+ ML_(symerr)("XCOFF object file header is implausibly small (1)");
+ goto done;
+ }
+
+ /* It's the right name, but need to also check the magic
+ number, since some archives contain both a 32-bit and
+ 64-bit version of the same object. */
+ FILHDR* t_filhdr = (FILHDR*)o_data;
+# if defined(VGP_ppc32_aix5)
+ if (t_filhdr->f_magic == 0x01F7 /* XCOFF64 */) {
+ if (0)
+ VG_(printf)("Skipping 64-bit archive on 32-bit platform\n");
+ goto move_on;
+ }
+# elif defined(VGP_ppc64_aix5)
+ if (t_filhdr->f_magic == 0x01DF /* XCOFF32 */) {
+ if (0)
+ VG_(printf)("Skipping 32-bit archive on 64-bit platform\n");
+ goto move_on;
+ }
+# endif
+
if (SHOW && SHOW_AR_DETAILS)
VG_(printf)("\nimage: %p-%p object: %p-%p\n\n",
image, image+n_image-1, o_data, o_data+o_size-1);
ok = read_xcoff_mapped_object( si, o_data, o_size,
data_avma, data_alen );
- } else {
- ML_(symerr)("XCOFF archive member exceeds image");
+ goto done;
+
+ vg_assert(0);
+ /* NOTREACHED */
+
+ move_on:
+ while (*p) {
+ if (SHOW && SHOW_AR_DETAILS)
+ VG_(printf)("%c", *p);
+ p++;
+ }
+ if (SHOW && SHOW_AR_DETAILS)
+ VG_(printf)("\n");
+ p++;
}
+ vg_assert(i == nmembers);
+ ML_(symerr)("can't find object in XCOFF archive file");
+
done:
if (image) {
VG_(am_munmap_valgrind)( (Addr)image, n_image );
|