910 lines
39 KiB
Diff
910 lines
39 KiB
Diff
|
diff -ru valgrind-3.7.0.orig/config.h valgrind-3.7.0/config.h
|
||
|
--- valgrind-3.7.0.orig/config.h 2012-07-25 12:33:29.212949007 +0200
|
||
|
+++ valgrind-3.7.0/config.h 2012-07-25 12:44:42.847307554 +0200
|
||
|
@@ -29,7 +29,7 @@
|
||
|
/* #undef GLIBC_2_10 */
|
||
|
|
||
|
/* Define to 1 if you're using glibc 2.11.x */
|
||
|
-#define GLIBC_2_11 1
|
||
|
+/* #undef GLIBC_2_11 */
|
||
|
|
||
|
/* Define to 1 if you're using glibc 2.12.x */
|
||
|
/* #undef GLIBC_2_12 */
|
||
|
@@ -38,7 +38,10 @@
|
||
|
/* #undef GLIBC_2_13 */
|
||
|
|
||
|
/* Define to 1 if you're using glibc 2.14.x */
|
||
|
-/* #undef GLIBC_2_14 */
|
||
|
+#define GLIBC_2_14 1
|
||
|
+
|
||
|
+/* Define to 1 if you're using glibc 2.15.x */
|
||
|
+/* #undef GLIBC_2_15 */
|
||
|
|
||
|
/* Define to 1 if you're using glibc 2.2.x */
|
||
|
/* #undef GLIBC_2_2 */
|
||
|
diff -ru valgrind-3.7.0.orig/coregrind/m_debuginfo/d3basics.c valgrind-3.7.0/coregrind/m_debuginfo/d3basics.c
|
||
|
--- valgrind-3.7.0.orig/coregrind/m_debuginfo/d3basics.c 2012-07-25 12:33:29.191948686 +0200
|
||
|
+++ valgrind-3.7.0/coregrind/m_debuginfo/d3basics.c 2012-07-25 12:44:30.217112438 +0200
|
||
|
@@ -180,6 +180,8 @@
|
||
|
case DW_FORM_exprloc: return "DW_FORM_exprloc";
|
||
|
case DW_FORM_flag_present:return "DW_FORM_flag_present";
|
||
|
case DW_FORM_ref_sig8: return "DW_FORM_ref_sig8";
|
||
|
+ case DW_FORM_GNU_ref_alt:return "DW_FORM_GNU_ref_alt";
|
||
|
+ case DW_FORM_GNU_strp_alt:return "DW_FORM_GNU_strp_alt";
|
||
|
default: return "DW_FORM_???";
|
||
|
}
|
||
|
}
|
||
|
diff -ru valgrind-3.7.0.orig/coregrind/m_debuginfo/debuginfo.c valgrind-3.7.0/coregrind/m_debuginfo/debuginfo.c
|
||
|
--- valgrind-3.7.0.orig/coregrind/m_debuginfo/debuginfo.c 2012-07-25 12:33:29.191948686 +0200
|
||
|
+++ valgrind-3.7.0/coregrind/m_debuginfo/debuginfo.c 2012-07-25 12:44:30.219112468 +0200
|
||
|
@@ -859,7 +859,7 @@
|
||
|
|
||
|
/* We're only interested in mappings of object files. */
|
||
|
# if defined(VGO_linux)
|
||
|
- if (!ML_(is_elf_object_file)( buf1k, (SizeT)sr_Res(preadres) ))
|
||
|
+ if (!ML_(is_elf_object_file)( buf1k, (SizeT)sr_Res(preadres), False ))
|
||
|
return 0;
|
||
|
# elif defined(VGO_darwin)
|
||
|
if (!ML_(is_macho_object_file)( buf1k, (SizeT)sr_Res(preadres) ))
|
||
|
diff -ru valgrind-3.7.0.orig/coregrind/m_debuginfo/priv_d3basics.h valgrind-3.7.0/coregrind/m_debuginfo/priv_d3basics.h
|
||
|
--- valgrind-3.7.0.orig/coregrind/m_debuginfo/priv_d3basics.h 2012-07-25 12:33:29.192948701 +0200
|
||
|
+++ valgrind-3.7.0/coregrind/m_debuginfo/priv_d3basics.h 2012-07-25 12:44:30.235112717 +0200
|
||
|
@@ -199,7 +199,11 @@
|
||
|
DW_FORM_sec_offset = 0x17,
|
||
|
DW_FORM_exprloc = 0x18,
|
||
|
DW_FORM_flag_present = 0x19,
|
||
|
- DW_FORM_ref_sig8 = 0x20
|
||
|
+ DW_FORM_ref_sig8 = 0x20,
|
||
|
+ /* Extensions for DWZ multifile.
|
||
|
+ See http://www.dwarfstd.org/ShowIssue.php?issue=120604.1&type=open . */
|
||
|
+ DW_FORM_GNU_ref_alt = 0x1f20,
|
||
|
+ DW_FORM_GNU_strp_alt = 0x1f21
|
||
|
}
|
||
|
DW_FORM;
|
||
|
|
||
|
diff -ru valgrind-3.7.0.orig/coregrind/m_debuginfo/priv_readdwarf3.h valgrind-3.7.0/coregrind/m_debuginfo/priv_readdwarf3.h
|
||
|
--- valgrind-3.7.0.orig/coregrind/m_debuginfo/priv_readdwarf3.h 2012-07-25 12:33:29.192948701 +0200
|
||
|
+++ valgrind-3.7.0/coregrind/m_debuginfo/priv_readdwarf3.h 2012-07-25 12:44:30.237112747 +0200
|
||
|
@@ -48,7 +48,11 @@
|
||
|
UChar* debug_line_img, SizeT debug_line_sz,
|
||
|
UChar* debug_str_img, SizeT debug_str_sz,
|
||
|
UChar* debug_ranges_img, SizeT debug_ranges_sz,
|
||
|
- UChar* debug_loc_img, SizeT debug_loc_sz
|
||
|
+ UChar* debug_loc_img, SizeT debug_loc_sz,
|
||
|
+ UChar* debug_info_alt_img, SizeT debug_info_alt_sz,
|
||
|
+ UChar* debug_abbv_alt_img, SizeT debug_abbv_alt_sz,
|
||
|
+ UChar* debug_line_alt_img, SizeT debug_line_alt_sz,
|
||
|
+ UChar* debug_str_alt_img, SizeT debug_str_alt_sz
|
||
|
);
|
||
|
|
||
|
#endif /* ndef __PRIV_READDWARF3_H */
|
||
|
diff -ru valgrind-3.7.0.orig/coregrind/m_debuginfo/priv_readdwarf.h valgrind-3.7.0/coregrind/m_debuginfo/priv_readdwarf.h
|
||
|
--- valgrind-3.7.0.orig/coregrind/m_debuginfo/priv_readdwarf.h 2012-07-25 12:33:29.192948701 +0200
|
||
|
+++ valgrind-3.7.0/coregrind/m_debuginfo/priv_readdwarf.h 2012-07-25 12:44:30.238112762 +0200
|
||
|
@@ -48,7 +48,8 @@
|
||
|
UChar* debug_types_img, Word debug_types_sz, /* .debug_types */
|
||
|
UChar* debug_abbv_img, Word debug_abbv_sz, /* .debug_abbrev */
|
||
|
UChar* debug_line_img, Word debug_line_sz, /* .debug_line */
|
||
|
- UChar* debug_str_img, Word debug_str_sz ); /* .debug_str */
|
||
|
+ UChar* debug_str_img, Word debug_str_sz, /* .debug_str */
|
||
|
+ UChar* debug_str_alt_img, Word debug_str_alt_sz ); /* .debug_str */
|
||
|
|
||
|
/* --------------------
|
||
|
DWARF1 reader
|
||
|
diff -ru valgrind-3.7.0.orig/coregrind/m_debuginfo/priv_readelf.h valgrind-3.7.0/coregrind/m_debuginfo/priv_readelf.h
|
||
|
--- valgrind-3.7.0.orig/coregrind/m_debuginfo/priv_readelf.h 2012-07-25 12:33:29.192948701 +0200
|
||
|
+++ valgrind-3.7.0/coregrind/m_debuginfo/priv_readelf.h 2012-07-25 12:44:30.239112777 +0200
|
||
|
@@ -40,7 +40,7 @@
|
||
|
|
||
|
/* Identify an ELF object file by peering at the first few bytes of
|
||
|
it. */
|
||
|
-extern Bool ML_(is_elf_object_file)( void* image, SizeT n_image );
|
||
|
+extern Bool ML_(is_elf_object_file)( void* image, SizeT n_image, Bool rel_ok );
|
||
|
|
||
|
/* The central function for reading ELF debug info. For the
|
||
|
object/exe specified by the SegInfo, find ELF sections, then read
|
||
|
diff -ru valgrind-3.7.0.orig/coregrind/m_debuginfo/readdwarf3.c valgrind-3.7.0/coregrind/m_debuginfo/readdwarf3.c
|
||
|
--- valgrind-3.7.0.orig/coregrind/m_debuginfo/readdwarf3.c 2012-07-25 12:33:29.192948701 +0200
|
||
|
+++ valgrind-3.7.0/coregrind/m_debuginfo/readdwarf3.c 2012-07-25 12:44:30.240112792 +0200
|
||
|
@@ -420,6 +420,16 @@
|
||
|
/* Where is .debug_types? */
|
||
|
UChar* debug_types_img;
|
||
|
UWord debug_types_sz;
|
||
|
+ /* Where is alternate .debug_info? */
|
||
|
+ UChar* debug_info_alt_img;
|
||
|
+ UWord debug_info_alt_sz;
|
||
|
+ /* Where is alternate .debug_str ? */
|
||
|
+ UChar* debug_str_alt_img;
|
||
|
+ UWord debug_str_alt_sz;
|
||
|
+ /* How much to add to .debug_types resp. alternate .debug_info offsets
|
||
|
+ in cook_die*. */
|
||
|
+ UWord types_cuOff_bias;
|
||
|
+ UWord alt_cuOff_bias;
|
||
|
/* --- Needed so we can add stuff to the string table. --- */
|
||
|
struct _DebugInfo* di;
|
||
|
/* --- a cache for set_abbv_Cursor --- */
|
||
|
@@ -440,40 +450,58 @@
|
||
|
/* Signatured type hash; computed once and then shared by all
|
||
|
CUs. */
|
||
|
VgHashTable signature_types;
|
||
|
+
|
||
|
+ /* True if this came from alternate .debug_info; otherwise
|
||
|
+ it came from normal .debug_info or .debug_types. */
|
||
|
+ Bool is_alt_info;
|
||
|
}
|
||
|
CUConst;
|
||
|
|
||
|
|
||
|
/* Return the cooked value of DIE depending on whether CC represents a
|
||
|
- .debug_types unit. To cook a DIE, we pretend that the .debug_info
|
||
|
- and .debug_types sections form a contiguous whole, so that DIEs
|
||
|
- coming from .debug_types are numbered starting at the end of
|
||
|
- .debug_info. */
|
||
|
+ .debug_types unit. To cook a DIE, we pretend that the .debug_info,
|
||
|
+ .debug_types and optional alternate .debug_info sections form
|
||
|
+ a contiguous whole, so that DIEs coming from .debug_types are numbered
|
||
|
+ starting at the end of .debug_info and DIEs coming from alternate
|
||
|
+ .debug_info are numbered starting at the end of .debug_types. */
|
||
|
static UWord cook_die( CUConst* cc, UWord die )
|
||
|
{
|
||
|
if (cc->is_type_unit)
|
||
|
- die += cc->debug_info_sz;
|
||
|
+ die += cc->types_cuOff_bias;
|
||
|
+ else if (cc->is_alt_info)
|
||
|
+ die += cc->alt_cuOff_bias;
|
||
|
return die;
|
||
|
}
|
||
|
|
||
|
/* Like cook_die, but understand that DIEs coming from a
|
||
|
- DW_FORM_ref_sig8 reference are already cooked. */
|
||
|
+ DW_FORM_ref_sig8 reference are already cooked. Also, handle
|
||
|
+ DW_FORM_GNU_ref_alt from within primary .debug_info or .debug_types
|
||
|
+ as reference to alternate .debug_info. */
|
||
|
static UWord cook_die_using_form( CUConst *cc, UWord die, DW_FORM form)
|
||
|
{
|
||
|
if (form == DW_FORM_ref_sig8)
|
||
|
return die;
|
||
|
+ if (form == DW_FORM_GNU_ref_alt)
|
||
|
+ return die + cc->alt_cuOff_bias;
|
||
|
return cook_die( cc, die );
|
||
|
}
|
||
|
|
||
|
-/* Return the uncooked offset of DIE and set *FLAG to true if the DIE
|
||
|
- came from the .debug_types section. */
|
||
|
-static UWord uncook_die( CUConst *cc, UWord die, /*OUT*/Bool *flag )
|
||
|
+/* Return the uncooked offset of DIE and set *TYPE_FLAG to true if the DIE
|
||
|
+ came from the .debug_types section and *ALT_FLAG to true if the DIE
|
||
|
+ came from alternate .debug_info section. */
|
||
|
+static UWord uncook_die( CUConst *cc, UWord die, /*OUT*/Bool *type_flag,
|
||
|
+ Bool *alt_flag )
|
||
|
{
|
||
|
+ *alt_flag = False;
|
||
|
+ *type_flag = False;
|
||
|
if (die >= cc->debug_info_sz) {
|
||
|
- *flag = True;
|
||
|
- die -= cc->debug_info_sz;
|
||
|
- } else {
|
||
|
- *flag = False;
|
||
|
+ if (die >= cc->debug_info_sz + cc->debug_types_sz) {
|
||
|
+ *alt_flag = True;
|
||
|
+ die -= cc->debug_info_sz + cc->debug_types_sz;
|
||
|
+ } else {
|
||
|
+ *type_flag = True;
|
||
|
+ die -= cc->debug_info_sz;
|
||
|
+ }
|
||
|
}
|
||
|
return die;
|
||
|
}
|
||
|
@@ -831,7 +859,8 @@
|
||
|
Bool td3,
|
||
|
Cursor* c,
|
||
|
UChar* debug_abbv_img, UWord debug_abbv_sz,
|
||
|
- Bool type_unit )
|
||
|
+ Bool type_unit,
|
||
|
+ Bool alt_info )
|
||
|
{
|
||
|
UChar address_size;
|
||
|
UWord debug_abbrev_offset;
|
||
|
@@ -870,6 +899,7 @@
|
||
|
TRACE_D3(" Pointer Size: %d\n", (Int)address_size );
|
||
|
|
||
|
cc->is_type_unit = type_unit;
|
||
|
+ cc->is_alt_info = alt_info;
|
||
|
|
||
|
if (type_unit) {
|
||
|
cc->type_signature = get_ULong( c );
|
||
|
@@ -1289,6 +1319,37 @@
|
||
|
(DW_FORM)get_ULEB128(c));
|
||
|
return;
|
||
|
|
||
|
+ case DW_FORM_GNU_ref_alt:
|
||
|
+ *cts = get_Dwarfish_UWord(c, cc->is_dw64);
|
||
|
+ *ctsSzB = cc->is_dw64 ? sizeof(ULong) : sizeof(UInt);
|
||
|
+ TRACE_D3("0x%lx", (UWord)*cts);
|
||
|
+ if (0) VG_(printf)("DW_FORM_GNU_ref_alt 0x%lx\n", (UWord)*cts);
|
||
|
+ if (/* the following 2 are surely impossible, but ... */
|
||
|
+ cc->debug_info_alt_img == NULL || cc->debug_info_alt_sz == 0
|
||
|
+ || *cts >= (ULong)cc->debug_info_alt_sz) {
|
||
|
+ /* Hmm. Offset is nonsensical for this object's .debug_info
|
||
|
+ section. Be safe and reject it. */
|
||
|
+ cc->barf("get_Form_contents: DW_FORM_ref_addr points "
|
||
|
+ "outside alternate .debug_info");
|
||
|
+ }
|
||
|
+ break;
|
||
|
+
|
||
|
+ case DW_FORM_GNU_strp_alt: {
|
||
|
+ /* this is an offset into alternate .debug_str */
|
||
|
+ UChar* str;
|
||
|
+ UWord uw = (UWord)get_Dwarfish_UWord( c, cc->is_dw64 );
|
||
|
+ if (cc->debug_str_alt_img == NULL || uw >= cc->debug_str_alt_sz)
|
||
|
+ cc->barf("get_Form_contents: DW_FORM_GNU_strp_alt "
|
||
|
+ "points outside alternate .debug_str");
|
||
|
+ /* FIXME: check the entire string lies inside debug_str,
|
||
|
+ not just the first byte of it. */
|
||
|
+ str = (UChar*)cc->debug_str_alt_img + uw;
|
||
|
+ TRACE_D3("(indirect alt string, offset: 0x%lx): %s", uw, str);
|
||
|
+ *cts = (ULong)(UWord)str;
|
||
|
+ *ctsMemSzB = 1 + (ULong)VG_(strlen)(str);
|
||
|
+ break;
|
||
|
+ }
|
||
|
+
|
||
|
default:
|
||
|
VG_(printf)(
|
||
|
"get_Form_contents: unhandled %d (%s) at <%lx>\n",
|
||
|
@@ -1579,10 +1640,13 @@
|
||
|
UWord saved_die_c_offset = get_position_of_Cursor( c_die );
|
||
|
UWord saved_abbv_c_offset = get_position_of_Cursor( c_abbv );
|
||
|
Bool debug_types_flag;
|
||
|
+ Bool alt_flag;
|
||
|
|
||
|
varstack_preen( parser, td3, level-1 );
|
||
|
|
||
|
- if (dtag == DW_TAG_compile_unit || dtag == DW_TAG_type_unit) {
|
||
|
+ if (dtag == DW_TAG_compile_unit
|
||
|
+ || dtag == DW_TAG_type_unit
|
||
|
+ || dtag == DW_TAG_partial_unit) {
|
||
|
Bool have_lo = False;
|
||
|
Bool have_hi1 = False;
|
||
|
Bool have_range = False;
|
||
|
@@ -2028,11 +2092,14 @@
|
||
|
set_position_of_Cursor( c_die, saved_die_c_offset );
|
||
|
set_position_of_Cursor( c_abbv, saved_abbv_c_offset );
|
||
|
VG_(printf)("\nparse_var_DIE: confused by:\n");
|
||
|
- posn = uncook_die( cc, posn, &debug_types_flag );
|
||
|
+ posn = uncook_die( cc, posn, &debug_types_flag, &alt_flag );
|
||
|
VG_(printf)(" <%d><%lx>: %s", level, posn, ML_(pp_DW_TAG)( dtag ) );
|
||
|
if (debug_types_flag) {
|
||
|
VG_(printf)(" (in .debug_types)");
|
||
|
}
|
||
|
+ else if (alt_flag) {
|
||
|
+ VG_(printf)(" (in alternate .debug_info)");
|
||
|
+ }
|
||
|
VG_(printf)("\n");
|
||
|
while (True) {
|
||
|
DW_AT attr = (DW_AT) get_ULEB128( c_abbv );
|
||
|
@@ -2214,6 +2281,7 @@
|
||
|
TyEnt fieldE;
|
||
|
TyEnt boundE;
|
||
|
Bool debug_types_flag;
|
||
|
+ Bool alt_flag;
|
||
|
|
||
|
UWord saved_die_c_offset = get_position_of_Cursor( c_die );
|
||
|
UWord saved_abbv_c_offset = get_position_of_Cursor( c_abbv );
|
||
|
@@ -2228,7 +2296,9 @@
|
||
|
its children. */
|
||
|
typestack_preen( parser, td3, level-1 );
|
||
|
|
||
|
- if (dtag == DW_TAG_compile_unit || dtag == DW_TAG_type_unit) {
|
||
|
+ if (dtag == DW_TAG_compile_unit
|
||
|
+ || dtag == DW_TAG_type_unit
|
||
|
+ || dtag == DW_TAG_partial_unit) {
|
||
|
/* See if we can find DW_AT_language, since it is important for
|
||
|
establishing array bounds (see DW_TAG_subrange_type below in
|
||
|
this fn) */
|
||
|
@@ -2947,10 +3017,12 @@
|
||
|
set_position_of_Cursor( c_die, saved_die_c_offset );
|
||
|
set_position_of_Cursor( c_abbv, saved_abbv_c_offset );
|
||
|
VG_(printf)("\nparse_type_DIE: confused by:\n");
|
||
|
- posn = uncook_die( cc, posn, &debug_types_flag );
|
||
|
+ posn = uncook_die( cc, posn, &debug_types_flag, &alt_flag );
|
||
|
VG_(printf)(" <%d><%lx>: %s", level, posn, ML_(pp_DW_TAG)( dtag ) );
|
||
|
if (debug_types_flag) {
|
||
|
VG_(printf)(" (in .debug_types)");
|
||
|
+ } else if (alt_flag) {
|
||
|
+ VG_(printf)(" (in alternate .debug_info)");
|
||
|
}
|
||
|
VG_(printf)("\n");
|
||
|
while (True) {
|
||
|
@@ -3428,7 +3500,11 @@
|
||
|
UChar* debug_line_img, SizeT debug_line_sz,
|
||
|
UChar* debug_str_img, SizeT debug_str_sz,
|
||
|
UChar* debug_ranges_img, SizeT debug_ranges_sz,
|
||
|
- UChar* debug_loc_img, SizeT debug_loc_sz
|
||
|
+ UChar* debug_loc_img, SizeT debug_loc_sz,
|
||
|
+ UChar* debug_info_alt_img, SizeT debug_info_alt_sz,
|
||
|
+ UChar* debug_abbv_alt_img, SizeT debug_abbv_alt_sz,
|
||
|
+ UChar* debug_line_alt_img, SizeT debug_line_alt_sz,
|
||
|
+ UChar* debug_str_alt_img, SizeT debug_str_alt_sz
|
||
|
)
|
||
|
{
|
||
|
XArray* /* of TyEnt */ tyents;
|
||
|
@@ -3668,10 +3744,10 @@
|
||
|
(saC_cache) */
|
||
|
parse_CU_Header( &cc, td3, &info,
|
||
|
(UChar*)debug_abbv_img, debug_abbv_sz,
|
||
|
- True );
|
||
|
+ True, False );
|
||
|
|
||
|
/* Needed by cook_die. */
|
||
|
- cc.debug_info_sz = debug_info_sz;
|
||
|
+ cc.types_cuOff_bias = debug_info_sz;
|
||
|
|
||
|
record_signatured_type( signature_types, cc.type_signature,
|
||
|
cook_die( &cc, cc.type_offset ));
|
||
|
@@ -3689,15 +3765,29 @@
|
||
|
}
|
||
|
}
|
||
|
|
||
|
- /* Perform two DIE-reading passes. The first pass reads DIEs from
|
||
|
- .debug_info, and the second pass reads DIEs from .debug_types.
|
||
|
+ /* Perform three DIE-reading passes. The first pass reads DIEs from
|
||
|
+ alternate .debug_info (if any), the second pass reads DIEs from
|
||
|
+ .debug_info, and the third pass reads DIEs from .debug_types.
|
||
|
Moving the body of this loop into a separate function would
|
||
|
require a large number of arguments to be passed in, so it is
|
||
|
kept inline instead. */
|
||
|
- for (pass = 0; pass < 2; ++pass) {
|
||
|
+ for (pass = 0; pass < 3; ++pass) {
|
||
|
UWord section_size;
|
||
|
|
||
|
if (pass == 0) {
|
||
|
+ if (debug_info_alt_img == NULL)
|
||
|
+ continue;
|
||
|
+ /* Now loop over the Compilation Units listed in the alternate
|
||
|
+ .debug_info section (see D3SPEC sec 7.5) paras 1 and 2.
|
||
|
+ Each compilation unit contains a Compilation Unit Header
|
||
|
+ followed by precisely one DW_TAG_compile_unit or
|
||
|
+ DW_TAG_partial_unit DIE. */
|
||
|
+ init_Cursor( &info, debug_info_alt_img, debug_info_alt_sz, 0, barf,
|
||
|
+ "Overrun whilst reading alternate .debug_info section" );
|
||
|
+ section_size = debug_info_alt_sz;
|
||
|
+
|
||
|
+ TRACE_D3("\n------ Parsing alternate .debug_info section ------\n");
|
||
|
+ } else if (pass == 1) {
|
||
|
/* Now loop over the Compilation Units listed in the .debug_info
|
||
|
section (see D3SPEC sec 7.5) paras 1 and 2. Each compilation
|
||
|
unit contains a Compilation Unit Header followed by precisely
|
||
|
@@ -3769,21 +3859,32 @@
|
||
|
TRACE_D3(" Compilation Unit @ offset 0x%lx:\n", cu_start_offset);
|
||
|
/* parse_CU_header initialises the CU's set_abbv_Cursor cache
|
||
|
(saC_cache) */
|
||
|
- parse_CU_Header( &cc, td3, &info,
|
||
|
- (UChar*)debug_abbv_img, debug_abbv_sz,
|
||
|
- pass != 0 );
|
||
|
- cc.debug_str_img = debug_str_img;
|
||
|
- cc.debug_str_sz = debug_str_sz;
|
||
|
+ if (pass == 0)
|
||
|
+ parse_CU_Header( &cc, td3, &info,
|
||
|
+ (UChar*)debug_abbv_alt_img, debug_abbv_alt_sz,
|
||
|
+ False, True );
|
||
|
+ else
|
||
|
+ parse_CU_Header( &cc, td3, &info,
|
||
|
+ (UChar*)debug_abbv_img, debug_abbv_sz,
|
||
|
+ pass == 2, False );
|
||
|
+ cc.debug_str_img = pass == 0 ? debug_str_alt_img : debug_str_img;
|
||
|
+ cc.debug_str_sz = pass == 0 ? debug_str_alt_sz : debug_str_sz;
|
||
|
cc.debug_ranges_img = debug_ranges_img;
|
||
|
cc.debug_ranges_sz = debug_ranges_sz;
|
||
|
cc.debug_loc_img = debug_loc_img;
|
||
|
cc.debug_loc_sz = debug_loc_sz;
|
||
|
- cc.debug_line_img = debug_line_img;
|
||
|
- cc.debug_line_sz = debug_line_sz;
|
||
|
- cc.debug_info_img = debug_info_img;
|
||
|
- cc.debug_info_sz = debug_info_sz;
|
||
|
+ cc.debug_line_img = pass == 0 ? debug_line_alt_img : debug_line_img;
|
||
|
+ cc.debug_line_sz = pass == 0 ? debug_line_alt_sz : debug_line_sz;
|
||
|
+ cc.debug_info_img = pass == 0 ? debug_info_alt_img : debug_info_img;
|
||
|
+ cc.debug_info_sz = pass == 0 ? debug_info_alt_sz : debug_info_sz;
|
||
|
cc.debug_types_img = debug_types_img;
|
||
|
cc.debug_types_sz = debug_types_sz;
|
||
|
+ cc.debug_info_alt_img = debug_info_alt_img;
|
||
|
+ cc.debug_info_alt_sz = debug_info_alt_sz;
|
||
|
+ cc.debug_str_alt_img = debug_str_alt_img;
|
||
|
+ cc.debug_str_alt_sz = debug_str_alt_sz;
|
||
|
+ cc.types_cuOff_bias = debug_info_sz;
|
||
|
+ cc.alt_cuOff_bias = debug_info_sz + debug_types_sz;
|
||
|
cc.cu_start_offset = cu_start_offset;
|
||
|
cc.di = di;
|
||
|
/* The CU's svma can be deduced by looking at the AT_low_pc
|
||
|
@@ -3966,10 +4067,19 @@
|
||
|
vg_assert(dioff_lookup_tab);
|
||
|
|
||
|
n = VG_(sizeXA)( tempvars );
|
||
|
+ Word first_primary_var;
|
||
|
+ for (first_primary_var = 0;
|
||
|
+ debug_info_alt_sz && first_primary_var < n;
|
||
|
+ first_primary_var++) {
|
||
|
+ varp = *(TempVar**)VG_(indexXA)( tempvars, first_primary_var );
|
||
|
+ if (varp->dioff < debug_info_sz + debug_types_sz)
|
||
|
+ break;
|
||
|
+ }
|
||
|
for (i = 0; i < n; i++) {
|
||
|
- varp = *(TempVar**)VG_(indexXA)( tempvars, i );
|
||
|
- if (i > 0) {
|
||
|
- varp2 = *(TempVar**)VG_(indexXA)( tempvars, i-1 );
|
||
|
+ varp = *(TempVar**)VG_(indexXA)( tempvars, (i + first_primary_var) % n );
|
||
|
+ if (i > first_primary_var) {
|
||
|
+ varp2 = *(TempVar**)VG_(indexXA)( tempvars,
|
||
|
+ (i + first_primary_var - 1) % n );
|
||
|
/* why should this hold? Only, I think, because we've
|
||
|
constructed the array by reading .debug_info sequentially,
|
||
|
and so the array .dioff fields should reflect that, and be
|
||
|
@@ -4223,7 +4333,11 @@
|
||
|
UChar* debug_line_img, SizeT debug_line_sz,
|
||
|
UChar* debug_str_img, SizeT debug_str_sz,
|
||
|
UChar* debug_ranges_img, SizeT debug_ranges_sz,
|
||
|
- UChar* debug_loc_img, SizeT debug_loc_sz
|
||
|
+ UChar* debug_loc_img, SizeT debug_loc_sz,
|
||
|
+ UChar* debug_info_alt_img, SizeT debug_info_alt_sz,
|
||
|
+ UChar* debug_abbv_alt_img, SizeT debug_abbv_alt_sz,
|
||
|
+ UChar* debug_line_alt_img, SizeT debug_line_alt_sz,
|
||
|
+ UChar* debug_str_alt_img, SizeT debug_str_alt_sz
|
||
|
)
|
||
|
{
|
||
|
volatile Int jumped;
|
||
|
@@ -4247,7 +4361,11 @@
|
||
|
debug_line_img, debug_line_sz,
|
||
|
debug_str_img, debug_str_sz,
|
||
|
debug_ranges_img, debug_ranges_sz,
|
||
|
- debug_loc_img, debug_loc_sz );
|
||
|
+ debug_loc_img, debug_loc_sz,
|
||
|
+ debug_info_alt_img, debug_info_alt_sz,
|
||
|
+ debug_abbv_alt_img, debug_abbv_alt_sz,
|
||
|
+ debug_line_alt_img, debug_line_alt_sz,
|
||
|
+ debug_str_alt_img, debug_str_alt_sz);
|
||
|
d3rd_jmpbuf_valid = False;
|
||
|
TRACE_D3("\n------ .debug_info reading was successful ------\n");
|
||
|
} else {
|
||
|
diff -ru valgrind-3.7.0.orig/coregrind/m_debuginfo/readdwarf.c valgrind-3.7.0/coregrind/m_debuginfo/readdwarf.c
|
||
|
--- valgrind-3.7.0.orig/coregrind/m_debuginfo/readdwarf.c 2012-07-25 12:33:29.191948686 +0200
|
||
|
+++ valgrind-3.7.0/coregrind/m_debuginfo/readdwarf.c 2012-07-25 12:44:30.257113055 +0200
|
||
|
@@ -985,7 +985,8 @@
|
||
|
void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui,
|
||
|
UChar* unitblock_img,
|
||
|
UChar* debugabbrev_img,
|
||
|
- UChar* debugstr_img )
|
||
|
+ UChar* debugstr_img,
|
||
|
+ UChar* debugstr_alt_img )
|
||
|
{
|
||
|
UInt acode, abcode;
|
||
|
ULong atoffs, blklen;
|
||
|
@@ -1128,6 +1129,14 @@
|
||
|
case 0x18: /* FORM_exprloc */ p += read_leb128U( &p ); break;
|
||
|
case 0x19: /* FORM_flag_present */break;
|
||
|
case 0x20: /* FORM_ref_sig8 */ p += 8; break;
|
||
|
+ case 0x1f20: /* FORM_GNU_ref_alt */ p += ui->dw64 ? 8 : 4; break;
|
||
|
+ case 0x1f21: /* FORM_GNU_strp_alt */
|
||
|
+ if (debugstr_alt_img && !ui->dw64)
|
||
|
+ sval = debugstr_alt_img + ML_(read_UInt)(p);
|
||
|
+ if (debugstr_alt_img && ui->dw64)
|
||
|
+ sval = debugstr_alt_img + ML_(read_ULong)(p);
|
||
|
+ p += ui->dw64 ? 8 : 4;
|
||
|
+ break;
|
||
|
|
||
|
default:
|
||
|
VG_(printf)( "### unhandled dwarf2 abbrev form code 0x%x\n", form );
|
||
|
@@ -1169,7 +1178,8 @@
|
||
|
UChar* debug_types_img, Word debug_types_sz, /* .debug_types */
|
||
|
UChar* debug_abbv_img, Word debug_abbv_sz, /* .debug_abbrev */
|
||
|
UChar* debug_line_img, Word debug_line_sz, /* .debug_line */
|
||
|
- UChar* debug_str_img, Word debug_str_sz ) /* .debug_str */
|
||
|
+ UChar* debug_str_img, Word debug_str_sz, /* .debug_str */
|
||
|
+ UChar* debug_str_alt_img, Word debug_str_alt_sz ) /* .debug_str */
|
||
|
{
|
||
|
UnitInfo ui;
|
||
|
UShort ver;
|
||
|
@@ -1218,7 +1228,8 @@
|
||
|
VG_(printf)( "Reading UnitInfo at 0x%lx.....\n",
|
||
|
block_img - debug_info_img + 0UL );
|
||
|
read_unitinfo_dwarf2( &ui, block_img,
|
||
|
- debug_abbv_img, debug_str_img );
|
||
|
+ debug_abbv_img, debug_str_img,
|
||
|
+ debug_str_alt_img );
|
||
|
if (0)
|
||
|
VG_(printf)( " => LINES=0x%llx NAME=%s DIR=%s\n",
|
||
|
ui.stmt_list, ui.name, ui.compdir );
|
||
|
diff -ru valgrind-3.7.0.orig/coregrind/m_debuginfo/readelf.c valgrind-3.7.0/coregrind/m_debuginfo/readelf.c
|
||
|
--- valgrind-3.7.0.orig/coregrind/m_debuginfo/readelf.c 2012-07-25 12:33:29.191948686 +0200
|
||
|
+++ valgrind-3.7.0/coregrind/m_debuginfo/readelf.c 2012-07-25 12:53:09.377151832 +0200
|
||
|
@@ -111,7 +111,7 @@
|
||
|
/* Identify an ELF object file by peering at the first few bytes of
|
||
|
it. */
|
||
|
|
||
|
-Bool ML_(is_elf_object_file)( void* image, SizeT n_image )
|
||
|
+Bool ML_(is_elf_object_file)( void* image, SizeT n_image, Bool rel_ok )
|
||
|
{
|
||
|
ElfXX_Ehdr* ehdr = (ElfXX_Ehdr*)image;
|
||
|
Int ok = 1;
|
||
|
@@ -126,12 +126,14 @@
|
||
|
ok &= (ehdr->e_ident[EI_CLASS] == VG_ELF_CLASS
|
||
|
&& ehdr->e_ident[EI_DATA] == VG_ELF_DATA2XXX
|
||
|
&& ehdr->e_ident[EI_VERSION] == EV_CURRENT);
|
||
|
- ok &= (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN);
|
||
|
+ ok &= (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN
|
||
|
+ || (rel_ok && ehdr->e_type == ET_REL));
|
||
|
ok &= (ehdr->e_machine == VG_ELF_MACHINE);
|
||
|
ok &= (ehdr->e_version == EV_CURRENT);
|
||
|
ok &= (ehdr->e_shstrndx != SHN_UNDEF);
|
||
|
ok &= (ehdr->e_shoff != 0 && ehdr->e_shnum != 0);
|
||
|
- ok &= (ehdr->e_phoff != 0 && ehdr->e_phnum != 0);
|
||
|
+ ok &= ((ehdr->e_phoff != 0 && ehdr->e_phnum != 0)
|
||
|
+ || ehdr->e_type == ET_REL);
|
||
|
|
||
|
if (ok)
|
||
|
return True;
|
||
|
@@ -887,7 +889,7 @@
|
||
|
* http://fedoraproject.org/wiki/RolandMcGrath/BuildID
|
||
|
*/
|
||
|
static
|
||
|
-Char *find_buildid(Addr image, UWord n_image)
|
||
|
+Char *find_buildid(Addr image, UWord n_image, Bool rel_ok)
|
||
|
{
|
||
|
Char* buildid = NULL;
|
||
|
__attribute__((unused)) /* on Android, at least */
|
||
|
@@ -895,7 +897,7 @@
|
||
|
|
||
|
#ifdef NT_GNU_BUILD_ID
|
||
|
if (n_image >= sizeof(ElfXX_Ehdr) &&
|
||
|
- ML_(is_elf_object_file)(ehdr, n_image)) {
|
||
|
+ ML_(is_elf_object_file)(ehdr, n_image, rel_ok)) {
|
||
|
Word i;
|
||
|
|
||
|
for (i = 0; i < ehdr->e_phnum; i++) {
|
||
|
@@ -927,7 +929,41 @@
|
||
|
+ ((note->n_descsz + 3) & ~3);
|
||
|
}
|
||
|
}
|
||
|
- }
|
||
|
+ }
|
||
|
+
|
||
|
+ if (buildid || !rel_ok)
|
||
|
+ return buildid;
|
||
|
+
|
||
|
+ for (i = 0; i < ehdr->e_shnum; i++) {
|
||
|
+ ElfXX_Shdr* shdr
|
||
|
+ = (ElfXX_Shdr*)(image + ehdr->e_shoff + i * ehdr->e_shentsize);
|
||
|
+
|
||
|
+ if (shdr->sh_type == SHT_NOTE) {
|
||
|
+ ElfXX_Off offset = shdr->sh_offset;
|
||
|
+
|
||
|
+ while (offset < shdr->sh_offset + shdr->sh_size) {
|
||
|
+ ElfXX_Nhdr* note = (ElfXX_Nhdr*)(image + offset);
|
||
|
+ Char* name = (Char *)note + sizeof(ElfXX_Nhdr);
|
||
|
+ UChar *desc = (UChar *)name + ((note->n_namesz + 3) & ~3);
|
||
|
+ Word j;
|
||
|
+
|
||
|
+ if (VG_(strcmp)(name, ELF_NOTE_GNU) == 0 &&
|
||
|
+ note->n_type == NT_GNU_BUILD_ID) {
|
||
|
+ buildid = ML_(dinfo_zalloc)("di.fbi.1",
|
||
|
+ note->n_descsz * 2 + 1);
|
||
|
+
|
||
|
+ for (j = 0; j < note->n_descsz; j++) {
|
||
|
+ VG_(sprintf)(buildid + VG_(strlen)(buildid),
|
||
|
+ "%02x", desc[j]);
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ offset = offset + sizeof(ElfXX_Nhdr)
|
||
|
+ + ((note->n_namesz + 3) & ~3)
|
||
|
+ + ((note->n_descsz + 3) & ~3);
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
@@ -1009,7 +1045,8 @@
|
||
|
* not match the value from the main object file.
|
||
|
*/
|
||
|
static
|
||
|
-Addr open_debug_file( Char* name, Char* buildid, UInt crc, /*OUT*/UWord* size )
|
||
|
+Addr open_debug_file( Char* name, Char* buildid, UInt crc, Bool rel_ok,
|
||
|
+ /*OUT*/UWord* size )
|
||
|
{
|
||
|
SysRes fd, sres;
|
||
|
struct vg_stat stat_buf;
|
||
|
@@ -1038,7 +1075,7 @@
|
||
|
return 0;
|
||
|
|
||
|
if (buildid) {
|
||
|
- Char* debug_buildid = find_buildid(sr_Res(sres), *size);
|
||
|
+ Char* debug_buildid = find_buildid(sr_Res(sres), *size, rel_ok);
|
||
|
if (debug_buildid == NULL || VG_(strcmp)(buildid, debug_buildid) != 0) {
|
||
|
SysRes res = VG_(am_munmap_valgrind)(sr_Res(sres), *size);
|
||
|
vg_assert(!sr_isError(res));
|
||
|
@@ -1157,7 +1194,7 @@
|
||
|
static
|
||
|
void find_debug_file( struct _DebugInfo* di,
|
||
|
Char* objpath, Char* buildid,
|
||
|
- Char* debugname, UInt crc,
|
||
|
+ Char* debugname, UInt crc, Bool rel_ok,
|
||
|
/*OUT*/Addr* dimage,
|
||
|
/*OUT*/SizeT* n_dimage )
|
||
|
{
|
||
|
@@ -1175,13 +1212,14 @@
|
||
|
VG_(sprintf)(debugpath, "/usr/lib/debug/.build-id/%c%c/%s.debug",
|
||
|
buildid[0], buildid[1], buildid + 2);
|
||
|
|
||
|
- if ((addr = open_debug_file(debugpath, buildid, 0, &size)) == 0) {
|
||
|
+ if ((addr = open_debug_file(debugpath, buildid, 0,
|
||
|
+ rel_ok, &size)) == 0) {
|
||
|
ML_(dinfo_free)(debugpath);
|
||
|
debugpath = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
- if (addr == 0 && debugname != NULL) {
|
||
|
+ if (addr == 0 && debugname != NULL && !rel_ok) {
|
||
|
Char *objdir = ML_(dinfo_strdup)("di.fdf.2", objpath);
|
||
|
Char *objdirptr;
|
||
|
|
||
|
@@ -1194,11 +1232,11 @@
|
||
|
|
||
|
VG_(sprintf)(debugpath, "%s/%s", objdir, debugname);
|
||
|
|
||
|
- if ((addr = open_debug_file(debugpath, NULL, crc, &size)) == 0) {
|
||
|
+ if ((addr = open_debug_file(debugpath, NULL, crc, rel_ok, &size)) == 0) {
|
||
|
VG_(sprintf)(debugpath, "%s/.debug/%s", objdir, debugname);
|
||
|
- if ((addr = open_debug_file(debugpath, NULL, crc, &size)) == 0) {
|
||
|
+ if ((addr = open_debug_file(debugpath, NULL, crc, rel_ok, &size)) == 0) {
|
||
|
VG_(sprintf)(debugpath, "/usr/lib/debug%s/%s", objdir, debugname);
|
||
|
- addr = open_debug_file(debugpath, NULL, crc, &size);
|
||
|
+ addr = open_debug_file(debugpath, NULL, crc, rel_ok, &size);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@@ -1283,7 +1321,7 @@
|
||
|
/* TOPLEVEL */
|
||
|
Bool res, ok;
|
||
|
SysRes fd, sres;
|
||
|
- Word i;
|
||
|
+ Word i, j;
|
||
|
Bool dynbss_present = False;
|
||
|
Bool sdynbss_present = False;
|
||
|
|
||
|
@@ -1295,6 +1333,10 @@
|
||
|
Addr dimage = 0;
|
||
|
UWord n_dimage = 0;
|
||
|
|
||
|
+ /* Ditto for alternate ELF debuginfo file that we might happen to load. */
|
||
|
+ Addr aimage = 0;
|
||
|
+ UWord n_aimage = 0;
|
||
|
+
|
||
|
/* ELF header for the main file. Should == oimage since is at
|
||
|
start of file. */
|
||
|
ElfXX_Ehdr* ehdr_img = NULL;
|
||
|
@@ -1417,7 +1459,7 @@
|
||
|
ehdr_img = (ElfXX_Ehdr*)oimage;
|
||
|
|
||
|
if (ok)
|
||
|
- ok &= ML_(is_elf_object_file)(ehdr_img, n_oimage);
|
||
|
+ ok &= ML_(is_elf_object_file)(ehdr_img, n_oimage, False);
|
||
|
|
||
|
if (!ok) {
|
||
|
ML_(symerr)(di, True, "Invalid ELF Header");
|
||
|
@@ -2068,6 +2110,7 @@
|
||
|
UChar* dynstr_img = NULL; /* .dynstr */
|
||
|
ElfXX_Sym* dynsym_img = NULL; /* .dynsym */
|
||
|
UChar* debuglink_img = NULL; /* .gnu_debuglink */
|
||
|
+ UChar* debugaltlink_img = NULL; /* .gnu_debugaltlink */
|
||
|
UChar* stab_img = NULL; /* .stab (stabs) */
|
||
|
UChar* stabstr_img = NULL; /* .stabstr (stabs) */
|
||
|
UChar* debug_line_img = NULL; /* .debug_line (dwarf2) */
|
||
|
@@ -2078,6 +2121,10 @@
|
||
|
UChar* debug_ranges_img = NULL; /* .debug_ranges (dwarf2) */
|
||
|
UChar* debug_loc_img = NULL; /* .debug_loc (dwarf2) */
|
||
|
UChar* debug_frame_img = NULL; /* .debug_frame (dwarf2) */
|
||
|
+ UChar* debug_line_alt_img = NULL; /* .debug_line (alternate) */
|
||
|
+ UChar* debug_info_alt_img = NULL; /* .debug_info (alternate) */
|
||
|
+ UChar* debug_abbv_alt_img = NULL; /* .debug_abbrev (alternate) */
|
||
|
+ UChar* debug_str_alt_img = NULL; /* .debug_str (alternate) */
|
||
|
UChar* dwarf1d_img = NULL; /* .debug (dwarf1) */
|
||
|
UChar* dwarf1l_img = NULL; /* .line (dwarf1) */
|
||
|
UChar* opd_img = NULL; /* .opd (dwarf2,
|
||
|
@@ -2090,16 +2137,21 @@
|
||
|
SizeT dynstr_sz = 0;
|
||
|
SizeT dynsym_sz = 0;
|
||
|
SizeT debuglink_sz = 0;
|
||
|
+ SizeT debugaltlink_sz = 0;
|
||
|
SizeT stab_sz = 0;
|
||
|
SizeT stabstr_sz = 0;
|
||
|
SizeT debug_line_sz = 0;
|
||
|
SizeT debug_info_sz = 0;
|
||
|
- SizeT debug_types_sz = 0;
|
||
|
+ SizeT debug_types_sz = 0;
|
||
|
SizeT debug_abbv_sz = 0;
|
||
|
SizeT debug_str_sz = 0;
|
||
|
SizeT debug_ranges_sz = 0;
|
||
|
SizeT debug_loc_sz = 0;
|
||
|
SizeT debug_frame_sz = 0;
|
||
|
+ SizeT debug_line_alt_sz = 0;
|
||
|
+ SizeT debug_info_alt_sz = 0;
|
||
|
+ SizeT debug_abbv_alt_sz = 0;
|
||
|
+ SizeT debug_str_alt_sz = 0;
|
||
|
SizeT dwarf1d_sz = 0;
|
||
|
SizeT dwarf1l_sz = 0;
|
||
|
SizeT opd_sz_unused = 0;
|
||
|
@@ -2164,6 +2216,7 @@
|
||
|
FIND(".strtab", strtab_sz, strtab_img)
|
||
|
|
||
|
FIND(".gnu_debuglink", debuglink_sz, debuglink_img)
|
||
|
+ FIND(".gnu_debugaltlink", debugaltlink_sz, debugaltlink_img)
|
||
|
|
||
|
FIND(".stab", stab_sz, stab_img)
|
||
|
FIND(".stabstr", stabstr_sz, stabstr_img)
|
||
|
@@ -2209,7 +2262,7 @@
|
||
|
vg_assert(dimage == 0 && n_dimage == 0);
|
||
|
|
||
|
/* Look for a build-id */
|
||
|
- buildid = find_buildid(oimage, n_oimage);
|
||
|
+ buildid = find_buildid(oimage, n_oimage, False);
|
||
|
|
||
|
/* Look for a debug image */
|
||
|
if (buildid != NULL || debuglink_img != NULL) {
|
||
|
@@ -2225,11 +2278,11 @@
|
||
|
|
||
|
/* See if we can find a matching debug file */
|
||
|
find_debug_file( di, di->fsm.filename, buildid,
|
||
|
- debuglink_img, crc, &dimage, &n_dimage );
|
||
|
+ debuglink_img, crc, False, &dimage, &n_dimage );
|
||
|
} else {
|
||
|
/* See if we can find a matching debug file */
|
||
|
find_debug_file( di, di->fsm.filename, buildid,
|
||
|
- NULL, 0, &dimage, &n_dimage );
|
||
|
+ NULL, 0, False, &dimage, &n_dimage );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@@ -2252,7 +2305,7 @@
|
||
|
SVMA/bias/size and image addresses out of it. */
|
||
|
if (dimage != 0
|
||
|
&& n_dimage >= sizeof(ElfXX_Ehdr)
|
||
|
- && ML_(is_elf_object_file)((void*)dimage, n_dimage)) {
|
||
|
+ && ML_(is_elf_object_file)((void*)dimage, n_dimage, False)) {
|
||
|
|
||
|
/* Pull out and validate program header and section header info */
|
||
|
ElfXX_Ehdr* ehdr_dimg = (ElfXX_Ehdr*)dimage;
|
||
|
@@ -2437,6 +2490,8 @@
|
||
|
FIND(need_dwarf2, ".debug_loc", debug_loc_sz, debug_loc_img)
|
||
|
FIND(need_dwarf2, ".debug_frame", debug_frame_sz,
|
||
|
debug_frame_img)
|
||
|
+ FIND(need_dwarf2, ".gnu_debugaltlink", debugaltlink_sz,
|
||
|
+ debugaltlink_img)
|
||
|
FIND(need_dwarf1, ".debug", dwarf1d_sz, dwarf1d_img)
|
||
|
FIND(need_dwarf1, ".line", dwarf1l_sz, dwarf1l_img)
|
||
|
|
||
|
@@ -2444,6 +2499,100 @@
|
||
|
} /* Find all interesting sections */
|
||
|
} /* do we have a debug image? */
|
||
|
|
||
|
+ /* Look for alternate debug image */
|
||
|
+ if (debugaltlink_img != NULL) {
|
||
|
+ UInt buildid_offset = VG_(strlen)(debugaltlink_img)+1;
|
||
|
+
|
||
|
+ vg_assert(buildid_offset < debugaltlink_sz);
|
||
|
+
|
||
|
+ Char *altbuildid
|
||
|
+ = ML_(dinfo_zalloc)("di.fbi.4",
|
||
|
+ (debugaltlink_sz - buildid_offset)
|
||
|
+ * 2 + 1);
|
||
|
+
|
||
|
+ for (j = 0; j < debugaltlink_sz - buildid_offset; j++)
|
||
|
+ VG_(sprintf)(altbuildid + 2 * j,
|
||
|
+ "%02x", debugaltlink_img[buildid_offset + j]);
|
||
|
+
|
||
|
+ /* See if we can find a matching debug file */
|
||
|
+ find_debug_file( di, di->fsm.filename, altbuildid,
|
||
|
+ NULL, 0, True, &aimage, &n_aimage );
|
||
|
+
|
||
|
+ ML_(dinfo_free)(altbuildid);
|
||
|
+ }
|
||
|
+
|
||
|
+ /* TOPLEVEL */
|
||
|
+ /* If we were successful in finding alternate debug image, pull various
|
||
|
+ size and image addresses out of it. */
|
||
|
+ if (aimage != 0
|
||
|
+ && n_aimage >= sizeof(ElfXX_Ehdr)
|
||
|
+ && ML_(is_elf_object_file)((void*)aimage, n_aimage, True)) {
|
||
|
+
|
||
|
+ /* Pull out and validate program header and section header info */
|
||
|
+ ElfXX_Ehdr* ehdr_aimg = (ElfXX_Ehdr*)aimage;
|
||
|
+ ElfXX_Shdr* shdr_aimg = (ElfXX_Shdr*)( ((UChar*)ehdr_aimg)
|
||
|
+ + ehdr_aimg->e_shoff );
|
||
|
+ UWord shdr_dnent = ehdr_aimg->e_shnum;
|
||
|
+ UWord shdr_dent_szB = ehdr_aimg->e_shentsize;
|
||
|
+ UChar* shdr_strtab_aimg = NULL;
|
||
|
+
|
||
|
+ if (shdr_dnent == 0
|
||
|
+ || !contained_within(
|
||
|
+ aimage, n_aimage,
|
||
|
+ (Addr)shdr_aimg, shdr_dnent * shdr_dent_szB)) {
|
||
|
+ ML_(symerr)(di, True,
|
||
|
+ "Missing or invalid ELF Section Header Table"
|
||
|
+ " (alternate debuginfo file)");
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Also find the section header's string table, and validate. */
|
||
|
+ /* checked previously by is_elf_object_file: */
|
||
|
+ vg_assert( ehdr_aimg->e_shstrndx != SHN_UNDEF );
|
||
|
+
|
||
|
+ shdr_strtab_aimg
|
||
|
+ = (UChar*)( ((UChar*)ehdr_aimg)
|
||
|
+ + shdr_aimg[ehdr_aimg->e_shstrndx].sh_offset);
|
||
|
+ if (!contained_within(
|
||
|
+ aimage, n_aimage,
|
||
|
+ (Addr)shdr_strtab_aimg,
|
||
|
+ 1/*bogus, but we don't know the real size*/ )) {
|
||
|
+ ML_(symerr)(di, True,
|
||
|
+ "Invalid ELF Section Header String Table"
|
||
|
+ " (alternate debuginfo file)");
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Find all interesting sections */
|
||
|
+ for (i = 0; i < ehdr_aimg->e_shnum; i++) {
|
||
|
+
|
||
|
+# define FIND(sec_name, sec_size, sec_img) \
|
||
|
+ do { ElfXX_Shdr* shdr \
|
||
|
+ = INDEX_BIS( shdr_aimg, i, shdr_dent_szB ); \
|
||
|
+ if (0 == VG_(strcmp)(sec_name, \
|
||
|
+ shdr_strtab_aimg + shdr->sh_name)) { \
|
||
|
+ if (0 != sec_img) \
|
||
|
+ VG_(core_panic)("repeated section!\n"); \
|
||
|
+ sec_img = (void*)(aimage + shdr->sh_offset); \
|
||
|
+ sec_size = shdr->sh_size; \
|
||
|
+ TRACE_SYMTAB( "%18s: aimg %p .. %p\n", \
|
||
|
+ sec_name, \
|
||
|
+ (UChar*)sec_img, \
|
||
|
+ ((UChar*)sec_img) + sec_size - 1); \
|
||
|
+ } \
|
||
|
+ } while (0);
|
||
|
+
|
||
|
+ /* NAME SIZE IMAGE addr */
|
||
|
+ FIND(".debug_line", debug_line_alt_sz, debug_line_alt_img)
|
||
|
+ FIND(".debug_info", debug_info_alt_sz, debug_info_alt_img)
|
||
|
+ FIND(".debug_abbrev", debug_abbv_alt_sz, debug_abbv_alt_img)
|
||
|
+ FIND(".debug_str", debug_str_alt_sz, debug_str_alt_img)
|
||
|
+
|
||
|
+# undef FIND
|
||
|
+ } /* Find all interesting sections */
|
||
|
+ } /* do we have a debug image? */
|
||
|
+
|
||
|
+
|
||
|
/* TOPLEVEL */
|
||
|
/* Check some sizes */
|
||
|
vg_assert((dynsym_sz % sizeof(ElfXX_Sym)) == 0);
|
||
|
@@ -2524,7 +2673,8 @@
|
||
|
debug_types_img, debug_types_sz,
|
||
|
debug_abbv_img, debug_abbv_sz,
|
||
|
debug_line_img, debug_line_sz,
|
||
|
- debug_str_img, debug_str_sz );
|
||
|
+ debug_str_img, debug_str_sz,
|
||
|
+ debug_str_alt_img, debug_str_alt_sz );
|
||
|
|
||
|
/* The new reader: read the DIEs in .debug_info to acquire
|
||
|
information on variable types and locations. But only if
|
||
|
@@ -2539,7 +2689,11 @@
|
||
|
debug_line_img, debug_line_sz,
|
||
|
debug_str_img, debug_str_sz,
|
||
|
debug_ranges_img, debug_ranges_sz,
|
||
|
- debug_loc_img, debug_loc_sz
|
||
|
+ debug_loc_img, debug_loc_sz,
|
||
|
+ debug_info_alt_img, debug_info_alt_sz,
|
||
|
+ debug_abbv_alt_img, debug_abbv_alt_sz,
|
||
|
+ debug_line_alt_img, debug_line_alt_sz,
|
||
|
+ debug_str_alt_img, debug_str_alt_sz
|
||
|
);
|
||
|
}
|
||
|
}
|