summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--trunk/ChangeLog35
-rw-r--r--trunk/src/dwarf2.c74
-rw-r--r--trunk/src/dwarf2.h25
3 files changed, 112 insertions, 22 deletions
diff --git a/trunk/ChangeLog b/trunk/ChangeLog
index d743677..1cd080f 100644
--- a/trunk/ChangeLog
+++ b/trunk/ChangeLog
@@ -1,3 +1,38 @@
+2009-06-15 Jakub Jelinek <jakub@redhat.com>
+
+ * dwarf2.h (DW_TAG_condition, DW_TAG_shared_type): Define.
+ (DW_OP_form_tls_address, DW_OP_call_frame_cfa, DW_OP_bit_piece,
+ DW_OP_implicit_value, DW_OP_stack_value, DW_OP_GNU_uninit,
+ DW_OP_GNU_encoded_addr): Define.
+ (DW_ATE_packed_decimal, DW_ATE_numeric_string, DW_ATE_edited,
+ DW_ATE_signed_fixed, DW_ATE_unsigned_fixed, DW_ATE_decimal_float):
+ Define.
+ (DW_CFA_val_offset, DW_CFA_val_offset_sf, DW_CFA_val_expression):
+ Define.
+ (DW_LANG_PLI, DW_LANG_ObjC, DW_LANG_ObjC_plus_plus, DW_LANG_UPC,
+ DW_LANG_D): Define.
+ * dwarf2.c (debug_sections): Add .debug_pubtypes.
+ (DEBUG_PUBTYPES): Define.
+ (DEBUG_MACINFO, DEBUG_LOC, DEBUG_STR, DEBUG_FRAME, DEBUG_RANGES):
+ Adjust.
+ (struct cu_data): Add cu_version field.
+ (read_abbrev): Adjust error messages not to be DWARF-2 specific.
+ (adjust_location_list): Likewise. Fix up DW_OP_call_ref handling,
+ handle DW_OP_form_tls_address, DW_OP_call_frame_cfa,
+ DW_OP_GNU_uninit, DW_OP_bit_piece, DW_OP_stack_value and
+ DW_OP_implicit_value.
+ (adjust_attributes): For cu->cu_version == 2 skip ptr_size bytes
+ instead of just 4. Adjust error messages not to be DWARF-2
+ specific.
+ (adjust_dwarf2_line): Handle version 3 of .debug_line.
+ (adjust_dwarf2_frame): Just that CIE version is 1 or 3, for
+ version 1 skip just one byte instead of uleb128 for return address
+ column. Handle DW_CFA_val_offset, DW_CFA_val_offset_sf and
+ DW_CFA_val_expression.
+ (adjust_dwarf2): Handle version 3 of .debug_info, initialize
+ cu.cu_version. Adjust error messages not to be DWARF-2 specific.
+ Note that .debug_pubtypes doesn't need adjustments.
+
2009-03-11 Jakub Jelinek <jakub@redhat.com>
* src/prelink.h (PLArch): Add rtype_class_valid field.
diff --git a/trunk/src/dwarf2.c b/trunk/src/dwarf2.c
index 4c27836..8869dc3 100644
--- a/trunk/src/dwarf2.c
+++ b/trunk/src/dwarf2.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2002, 2003, 2005, 2006 Red Hat, Inc.
+/* Copyright (C) 2001, 2002, 2003, 2005, 2006, 2009 Red Hat, Inc.
Written by Jakub Jelinek <jakub@redhat.com>, 2001.
This program is free software; you can redistribute it and/or modify
@@ -155,16 +155,18 @@ static struct
#define DEBUG_LINE 2
#define DEBUG_ARANGES 3
#define DEBUG_PUBNAMES 4
-#define DEBUG_MACINFO 5
-#define DEBUG_LOC 6
-#define DEBUG_STR 7
-#define DEBUG_FRAME 8
-#define DEBUG_RANGES 9
+#define DEBUG_PUBTYPES 5
+#define DEBUG_MACINFO 6
+#define DEBUG_LOC 7
+#define DEBUG_STR 8
+#define DEBUG_FRAME 9
+#define DEBUG_RANGES 10
{ ".debug_info", NULL, 0, 0 },
{ ".debug_abbrev", NULL, 0, 0 },
{ ".debug_line", NULL, 0, 0 },
{ ".debug_aranges", NULL, 0, 0 },
{ ".debug_pubnames", NULL, 0, 0 },
+ { ".debug_pubtypes", NULL, 0, 0 },
{ ".debug_macinfo", NULL, 0, 0 },
{ ".debug_loc", NULL, 0, 0 },
{ ".debug_str", NULL, 0, 0 },
@@ -191,6 +193,7 @@ struct cu_data
{
GElf_Addr cu_entry_pc;
GElf_Addr cu_low_pc;
+ unsigned char cu_version;
};
static hashval_t
@@ -250,7 +253,7 @@ no_memory:
}
if (*slot != NULL)
{
- error (0, 0, "%s: Duplicate DWARF-2 abbreviation %d", dso->filename,
+ error (0, 0, "%s: Duplicate DWARF abbreviation %d", dso->filename,
t->entry);
free (t);
htab_delete (h);
@@ -270,7 +273,7 @@ no_memory:
form = read_uleb128 (ptr);
if (form == 2 || form > DW_FORM_indirect)
{
- error (0, 0, "%s: Unknown DWARF-2 DW_FORM_%d", dso->filename, form);
+ error (0, 0, "%s: Unknown DWARF DW_FORM_%d", dso->filename, form);
htab_delete (h);
return NULL;
}
@@ -280,7 +283,7 @@ no_memory:
}
if (read_uleb128 (ptr) != 0)
{
- error (0, 0, "%s: DWARF-2 abbreviation does not end with 2 zeros",
+ error (0, 0, "%s: DWARF abbreviation does not end with 2 zeros",
dso->filename);
htab_delete (h);
return NULL;
@@ -340,8 +343,11 @@ adjust_location_list (DSO *dso, unsigned char *ptr, size_t len,
case DW_OP_reg0 ... DW_OP_reg31:
case DW_OP_nop:
case DW_OP_push_object_address:
- case DW_OP_call_ref:
+ case DW_OP_form_tls_address:
+ case DW_OP_call_frame_cfa:
+ case DW_OP_stack_value:
case DW_OP_GNU_push_tls_address:
+ case DW_OP_GNU_uninit:
break;
case DW_OP_const1u:
case DW_OP_pick:
@@ -360,6 +366,7 @@ adjust_location_list (DSO *dso, unsigned char *ptr, size_t len,
case DW_OP_const4u:
case DW_OP_const4s:
case DW_OP_call4:
+ case DW_OP_call_ref:
ptr += 4;
break;
case DW_OP_const8u:
@@ -376,11 +383,17 @@ adjust_location_list (DSO *dso, unsigned char *ptr, size_t len,
read_uleb128 (ptr);
break;
case DW_OP_bregx:
+ case DW_OP_bit_piece:
read_uleb128 (ptr);
read_uleb128 (ptr);
break;
+ case DW_OP_implicit_value:
+ {
+ uint32_t len = read_uleb128 (ptr);
+ ptr += len;
+ }
default:
- error (0, 0, "%s: Unknown DWARF-2 DW_OP_%d", dso->filename, op);
+ error (0, 0, "%s: Unknown DWARF DW_OP_%d", dso->filename, op);
return 1;
}
}
@@ -596,6 +609,11 @@ adjust_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t,
read_uleb128 (ptr);
break;
case DW_FORM_ref_addr:
+ if (cu->cu_version == 2)
+ ptr += ptr_size;
+ else
+ ptr += 4;
+ break;
case DW_FORM_strp:
ptr += 4;
break;
@@ -622,7 +640,7 @@ adjust_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t,
assert (len < UINT_MAX);
break;
default:
- error (0, 0, "%s: Unknown DWARF-2 DW_FORM_%d", dso->filename,
+ error (0, 0, "%s: Unknown DWARF DW_FORM_%d", dso->filename,
form);
return NULL;
}
@@ -645,7 +663,7 @@ adjust_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t,
|| (t->attr[i].attr >= DW_AT_sf_names
&& t->attr[i].attr <= DW_AT_body_end))
break;
- error (0, 0, "%s: Unknown DWARF-2 DW_AT_%d with block DW_FORM",
+ error (0, 0, "%s: Unknown DWARF DW_AT_%d with block DW_FORM",
dso->filename, t->attr[i].attr);
return NULL;
}
@@ -688,7 +706,7 @@ adjust_dwarf2_line (DSO *dso, GElf_Addr start, GElf_Addr adjust)
}
value = read_16 (ptr);
- if (value != 2)
+ if (value != 2 && value != 3)
{
error (0, 0, "%s: DWARF version %d unhandled", dso->filename,
value);
@@ -836,7 +854,13 @@ adjust_dwarf2_frame (DSO *dso, GElf_Addr start, GElf_Addr adjust)
if (value == 0xffffffff)
{
/* CIE. */
- ptr++; /* Skip version. */
+ uint32_t version = *ptr++;
+ if (version != 1 && version != 3)
+ {
+ error (0, 0, "%s: unhandled .debug_frame version %d",
+ dso->filename, version);
+ return 1;
+ }
if (*ptr != '\0')
{
error (0, 0, "%s: .debug_frame unhandled augmentation \"%s\"",
@@ -846,7 +870,10 @@ adjust_dwarf2_frame (DSO *dso, GElf_Addr start, GElf_Addr adjust)
ptr++; /* Skip augmentation. */
read_uleb128 (ptr); /* Skip code_alignment factor. */
read_uleb128 (ptr); /* Skip data_alignment factor. */
- read_uleb128 (ptr); /* Skip return_address_register. */
+ if (version >= 3)
+ read_uleb128 (ptr); /* Skip return_address_register. */
+ else
+ ptr++;
}
else
{
@@ -881,6 +908,8 @@ adjust_dwarf2_frame (DSO *dso, GElf_Addr start, GElf_Addr adjust)
case DW_CFA_offset_extended_sf:
case DW_CFA_def_cfa_sf:
case DW_CFA_GNU_negative_offset_extended:
+ case DW_CFA_val_offset:
+ case DW_CFA_val_offset_sf:
read_uleb128 (ptr);
/* FALLTHROUGH */
case DW_CFA_restore_extended:
@@ -907,6 +936,7 @@ adjust_dwarf2_frame (DSO *dso, GElf_Addr start, GElf_Addr adjust)
ptr += 4;
break;
case DW_CFA_expression:
+ case DW_CFA_val_expression:
read_uleb128 (ptr);
/* FALLTHROUGH */
case DW_CFA_def_cfa_expression:
@@ -1041,12 +1071,13 @@ adjust_dwarf2 (DSO *dso, int n, GElf_Addr start, GElf_Addr adjust)
}
value = read_16 (ptr);
- if (value != 2)
+ if (value != 2 && value != 3)
{
error (0, 0, "%s: DWARF version %d unhandled", dso->filename,
value);
return 1;
}
+ cu.cu_version = value;
value = read_32 (ptr);
if (value >= debug_sections[DEBUG_ABBREV].size)
@@ -1054,7 +1085,7 @@ adjust_dwarf2 (DSO *dso, int n, GElf_Addr start, GElf_Addr adjust)
if (debug_sections[DEBUG_ABBREV].data == NULL)
error (0, 0, "%s: .debug_abbrev not present", dso->filename);
else
- error (0, 0, "%s: DWARF-2 CU abbrev offset too large",
+ error (0, 0, "%s: DWARF CU abbrev offset too large",
dso->filename);
return 1;
}
@@ -1074,14 +1105,14 @@ adjust_dwarf2 (DSO *dso, int n, GElf_Addr start, GElf_Addr adjust)
}
else
{
- error (0, 0, "%s: Invalid DWARF-2 pointer size %d",
+ error (0, 0, "%s: Invalid DWARF pointer size %d",
dso->filename, ptr_size);
return 1;
}
}
else if (read_1 (ptr) != ptr_size)
{
- error (0, 0, "%s: DWARF-2 pointer size differs between CUs",
+ error (0, 0, "%s: DWARF pointer size differs between CUs",
dso->filename);
return 1;
}
@@ -1102,7 +1133,7 @@ adjust_dwarf2 (DSO *dso, int n, GElf_Addr start, GElf_Addr adjust)
t = htab_find_with_hash (abbrev, &tag, tag.entry);
if (t == NULL)
{
- error (0, 0, "%s: Could not find DWARF-2 abbreviation %d",
+ error (0, 0, "%s: Could not find DWARF abbreviation %d",
dso->filename, tag.entry);
htab_delete (abbrev);
return 1;
@@ -1138,6 +1169,7 @@ adjust_dwarf2 (DSO *dso, int n, GElf_Addr start, GElf_Addr adjust)
/* .debug_abbrev requires no adjustement. */
/* .debug_pubnames requires no adjustement. */
+ /* .debug_pubtypes requires no adjustement. */
/* .debug_macinfo requires no adjustement. */
/* .debug_str requires no adjustement. */
/* .debug_ranges adjusted for each DW_AT_ranges pointing into it. */
diff --git a/trunk/src/dwarf2.h b/trunk/src/dwarf2.h
index 1f938f5..143a00b 100644
--- a/trunk/src/dwarf2.h
+++ b/trunk/src/dwarf2.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2002 Red Hat, Inc.
+/* Copyright (C) 2001, 2002, 2009 Red Hat, Inc.
Written by Jakub Jelinek <jakub@redhat.com>, 2001.
This program is free software; you can redistribute it and/or modify
@@ -71,6 +71,8 @@
#define DW_TAG_unspecified_type 0x3b
#define DW_TAG_partial_unit 0x3c
#define DW_TAG_imported_unit 0x3d
+#define DW_TAG_condition 0x3f
+#define DW_TAG_shared_type 0x40
#define DW_TAG_MIPS_loop 0x4081
#define DW_TAG_format_label 0x4101
#define DW_TAG_function_template 0x4102
@@ -348,7 +350,14 @@
#define DW_OP_call2 0x98
#define DW_OP_call4 0x99
#define DW_OP_call_ref 0x9a
+#define DW_OP_form_tls_address 0x9b
+#define DW_OP_call_frame_cfa 0x9c
+#define DW_OP_bit_piece 0x9d
+#define DW_OP_implicit_value 0x9e
+#define DW_OP_stack_value 0x9f
#define DW_OP_GNU_push_tls_address 0xe0
+#define DW_OP_GNU_uninit 0xf0
+#define DW_OP_GNU_encoded_addr 0xf1
#define DW_OP_lo_user 0xe0
#define DW_OP_hi_user 0xff
@@ -362,6 +371,12 @@
#define DW_ATE_unsigned 0x7
#define DW_ATE_unsigned_char 0x8
#define DW_ATE_imaginary_float 0x9
+#define DW_ATE_packed_decimal 0xa
+#define DW_ATE_numeric_string 0xb
+#define DW_ATE_edited 0xc
+#define DW_ATE_signed_fixed 0xd
+#define DW_ATE_unsigned_fixed 0xe
+#define DW_ATE_decimal_float 0xf
#define DW_ATE_lo_user 0x80
#define DW_ATE_hi_user 0xff
@@ -437,6 +452,9 @@
#define DW_CFA_offset_extended_sf 0x11
#define DW_CFA_def_cfa_sf 0x12
#define DW_CFA_def_cfa_offset_sf 0x13
+#define DW_CFA_val_offset 0x14
+#define DW_CFA_val_offset_sf 0x15
+#define DW_CFA_val_expression 0x16
#define DW_CFA_MIPS_advance_loc8 0x1d
#define DW_CFA_GNU_window_save 0x2d
#define DW_CFA_GNU_args_size 0x2e
@@ -468,6 +486,11 @@
#define DW_LANG_C99 0x000c
#define DW_LANG_Ada95 0x000d
#define DW_LANG_Fortran95 0x000e
+#define DW_LANG_PLI 0x000f
+#define DW_LANG_ObjC 0x0010
+#define DW_LANG_ObjC_plus_plus 0x0011
+#define DW_LANG_UPC 0x0012
+#define DW_LANG_D 0x0013
#define DW_LANG_Mips_Assembler 0x8001
#define DW_LANG_lo_user 0x8000
#define DW_LANG_hi_user 0xffff