rpm/0005-debugedit-Implement-DWARF-5-unit-header-and-new-form.patch
DistroBaker 6ff1afd362 Merged update from upstream sources
This is an automated DistroBaker update from upstream sources.
If you do not know what this is about or would like to opt out,
contact the OSCI team.

Source: https://src.fedoraproject.org/rpms/rpm.git#ff02e06b27ca4f7483f79d49f229310646364496
2021-01-20 13:04:28 +00:00

218 lines
6.5 KiB
Diff

From 8b5dcb4c2175ac706a4e1c34ce83301213800689 Mon Sep 17 00:00:00 2001
From: Jan Kratochvil <jan.kratochvil@redhat.com>
Date: Mon, 18 Jan 2021 22:56:53 +0100
Subject: [PATCH 5/6] debugedit: Implement DWARF-5 unit header and new forms
parsing.
Recognize the various new DWARF5 .debug sections.
Parse and skip new DWARF5 forms in read_abbrev and skip_form.
Read DWARF5 unit headers for compile and partial units in edit_info.
This is enough to be able to process gcc -gdwarf-5 produced binaries
without the new DWARF5 .debug_line format (which isn't produced with
binutils < 2.36).
Patches slightly edited/merged by Mark Wielaard <mark@klomp.org>
---
tools/debugedit.c | 88 +++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 81 insertions(+), 7 deletions(-)
diff --git a/tools/debugedit.c b/tools/debugedit.c
index 7464883c5..be5fee85b 100644
--- a/tools/debugedit.c
+++ b/tools/debugedit.c
@@ -453,6 +453,11 @@ static debug_section debug_sections[] =
#define DEBUG_TYPES 11
#define DEBUG_MACRO 12
#define DEBUG_GDB_SCRIPT 13
+#define DEBUG_RNGLISTS 14
+#define DEBUG_LINE_STR 15
+#define DEBUG_ADDR 16
+#define DEBUG_STR_OFFSETS 17
+#define DEBUG_LOCLISTS 18
{ ".debug_info", NULL, NULL, 0, 0, 0 },
{ ".debug_abbrev", NULL, NULL, 0, 0, 0 },
{ ".debug_line", NULL, NULL, 0, 0, 0 },
@@ -467,6 +472,11 @@ static debug_section debug_sections[] =
{ ".debug_types", NULL, NULL, 0, 0, 0 },
{ ".debug_macro", NULL, NULL, 0, 0, 0 },
{ ".debug_gdb_scripts", NULL, NULL, 0, 0, 0 },
+ { ".debug_rnglists", NULL, NULL, 0, 0, 0 },
+ { ".debug_line_str", NULL, NULL, 0, 0, 0 },
+ { ".debug_addr", NULL, NULL, 0, 0, 0 },
+ { ".debug_str_offsets", NULL, NULL, 0, 0, 0 },
+ { ".debug_loclists", NULL, NULL, 0, 0, 0 },
{ NULL, NULL, NULL, 0, 0, 0 }
};
@@ -755,12 +765,28 @@ no_memory:
}
form = read_uleb128 (ptr);
if (form == 2
- || (form > DW_FORM_flag_present && form != DW_FORM_ref_sig8))
+ || (form > DW_FORM_flag_present
+ && !(form == DW_FORM_ref_sig8
+ || form == DW_FORM_data16
+ || form == DW_FORM_implicit_const
+ || form == DW_FORM_addrx
+ || form == DW_FORM_loclistx
+ || form == DW_FORM_rnglistx
+ || form == DW_FORM_addrx1
+ || form == DW_FORM_addrx2
+ || form == DW_FORM_addrx3
+ || form == DW_FORM_addrx4)))
{
- error (0, 0, "%s: Unknown DWARF DW_FORM_%d", dso->filename, form);
+ error (0, 0, "%s: Unknown DWARF DW_FORM_0x%x", dso->filename,
+ form);
htab_delete (h);
return NULL;
}
+ if (form == DW_FORM_implicit_const)
+ {
+ /* It is SLEB128 but the value is dropped anyway. */
+ read_uleb128 (ptr);
+ }
t->attr[t->nattr].attr = attr;
t->attr[t->nattr++].form = form;
@@ -1505,6 +1531,7 @@ skip_form (DSO *dso, uint32_t *formp, unsigned char **ptrp)
*ptrp += 4;
break;
case DW_FORM_flag_present:
+ case DW_FORM_implicit_const:
break;
case DW_FORM_addr:
*ptrp += ptr_size;
@@ -1512,14 +1539,24 @@ skip_form (DSO *dso, uint32_t *formp, unsigned char **ptrp)
case DW_FORM_ref1:
case DW_FORM_flag:
case DW_FORM_data1:
+ case DW_FORM_strx1:
+ case DW_FORM_addrx1:
++*ptrp;
break;
case DW_FORM_ref2:
case DW_FORM_data2:
+ case DW_FORM_strx2:
+ case DW_FORM_addrx2:
*ptrp += 2;
break;
+ case DW_FORM_strx3:
+ case DW_FORM_addrx3:
+ *ptrp += 3;
+ break;
case DW_FORM_ref4:
case DW_FORM_data4:
+ case DW_FORM_strx4:
+ case DW_FORM_addrx4:
case DW_FORM_sec_offset:
*ptrp += 4;
break;
@@ -1528,12 +1565,20 @@ skip_form (DSO *dso, uint32_t *formp, unsigned char **ptrp)
case DW_FORM_ref_sig8:
*ptrp += 8;
break;
+ case DW_FORM_data16:
+ *ptrp += 16;
+ break;
case DW_FORM_sdata:
case DW_FORM_ref_udata:
case DW_FORM_udata:
+ case DW_FORM_strx:
+ case DW_FORM_loclistx:
+ case DW_FORM_rnglistx:
+ case DW_FORM_addrx:
read_uleb128 (*ptrp);
break;
case DW_FORM_strp:
+ case DW_FORM_line_strp:
*ptrp += 4;
break;
case DW_FORM_string:
@@ -1560,7 +1605,7 @@ skip_form (DSO *dso, uint32_t *formp, unsigned char **ptrp)
assert (len < UINT_MAX);
break;
default:
- error (0, 0, "%s: Unknown DWARF DW_FORM_%d", dso->filename, *formp);
+ error (0, 0, "%s: Unknown DWARF DW_FORM_0x%x", dso->filename, *formp);
return FORM_ERROR;
}
@@ -2030,7 +2075,10 @@ edit_info (DSO *dso, int phase, struct debug_section *sec)
endsec = ptr + sec->size;
while (ptr < endsec)
{
- if (ptr + (sec == &debug_sections[DEBUG_INFO] ? 11 : 23) > endsec)
+ unsigned char *cu_start = ptr;
+
+ /* header size, version, unit_type, ptr_size. */
+ if (ptr + 4 + 2 + 1 + 1 > endsec)
{
error (0, 0, "%s: %s CU header too small",
dso->filename, sec->name);
@@ -2052,13 +2100,36 @@ edit_info (DSO *dso, int phase, struct debug_section *sec)
}
cu_version = read_16 (ptr);
- if (cu_version != 2 && cu_version != 3 && cu_version != 4)
+ if (cu_version != 2 && cu_version != 3 && cu_version != 4
+ && cu_version != 5)
{
error (0, 0, "%s: DWARF version %d unhandled", dso->filename,
cu_version);
return 1;
}
+ int cu_ptr_size = 0;
+
+ if (cu_version >= 5)
+ {
+ uint8_t unit_type = read_8 (ptr);
+ if (unit_type != DW_UT_compile && unit_type != DW_UT_partial)
+ {
+ error (0, 0, "%s: Unit type %u unhandled", dso->filename,
+ unit_type);
+ return 1;
+ }
+
+ cu_ptr_size = read_8 (ptr);
+ }
+
+ unsigned char *header_end = (cu_start + 23 + (cu_version < 5 ? 0 : 1));
+ if (header_end > endsec)
+ {
+ error (0, 0, "%s: %s CU header too small", dso->filename, sec->name);
+ return 1;
+ }
+
value = read_32_relocated (ptr);
if (value >= debug_sections[DEBUG_ABBREV].size)
{
@@ -2070,9 +2141,12 @@ edit_info (DSO *dso, int phase, struct debug_section *sec)
return 1;
}
+ if (cu_version < 5)
+ cu_ptr_size = read_8 (ptr);
+
if (ptr_size == 0)
{
- ptr_size = read_8 (ptr);
+ ptr_size = cu_ptr_size;
if (ptr_size != 4 && ptr_size != 8)
{
error (0, 0, "%s: Invalid DWARF pointer size %d",
@@ -2080,7 +2154,7 @@ edit_info (DSO *dso, int phase, struct debug_section *sec)
return 1;
}
}
- else if (read_8 (ptr) != ptr_size)
+ else if (cu_ptr_size != ptr_size)
{
error (0, 0, "%s: DWARF pointer size differs between CUs",
dso->filename);
--
2.18.4