|
DistroBaker |
6ff1af |
From 8cd4d5046d7cb1bc16f01e77a5ff50eca8d9da3d Mon Sep 17 00:00:00 2001
|
|
DistroBaker |
6ff1af |
From: Jan Kratochvil <jan.kratochvil@redhat.com>
|
|
DistroBaker |
6ff1af |
Date: Sat, 1 Aug 2020 10:45:47 +0200
|
|
DistroBaker |
6ff1af |
Subject: [PATCH 3/6] debugedit: Fix missing relocation of .debug_types
|
|
DistroBaker |
6ff1af |
section.
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
---
|
|
DistroBaker |
6ff1af |
tools/debugedit.c | 123 ++++++++++++++++++++++++++++++----------------
|
|
DistroBaker |
6ff1af |
1 file changed, 80 insertions(+), 43 deletions(-)
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
diff --git a/tools/debugedit.c b/tools/debugedit.c
|
|
DistroBaker |
6ff1af |
index cad0cc349..87c1cd622 100644
|
|
DistroBaker |
6ff1af |
--- a/tools/debugedit.c
|
|
DistroBaker |
6ff1af |
+++ b/tools/debugedit.c
|
|
DistroBaker |
6ff1af |
@@ -433,7 +433,8 @@ typedef struct debug_section
|
|
DistroBaker |
6ff1af |
int sec, relsec;
|
|
DistroBaker |
6ff1af |
REL *relbuf;
|
|
DistroBaker |
6ff1af |
REL *relend;
|
|
DistroBaker |
6ff1af |
- struct debug_section *next; /* Only happens for COMDAT .debug_macro. */
|
|
DistroBaker |
6ff1af |
+ /* Only happens for COMDAT .debug_macro and .debug_types. */
|
|
DistroBaker |
6ff1af |
+ struct debug_section *next;
|
|
DistroBaker |
6ff1af |
} debug_section;
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
static debug_section debug_sections[] =
|
|
DistroBaker |
6ff1af |
@@ -1269,7 +1270,9 @@ static int dirty_elf;
|
|
DistroBaker |
6ff1af |
static void
|
|
DistroBaker |
6ff1af |
dirty_section (unsigned int sec)
|
|
DistroBaker |
6ff1af |
{
|
|
DistroBaker |
6ff1af |
- elf_flagdata (debug_sections[sec].elf_data, ELF_C_SET, ELF_F_DIRTY);
|
|
DistroBaker |
6ff1af |
+ for (struct debug_section *secp = &debug_sections[sec]; secp != NULL;
|
|
DistroBaker |
6ff1af |
+ secp = secp->next)
|
|
DistroBaker |
6ff1af |
+ elf_flagdata (secp->elf_data, ELF_C_SET, ELF_F_DIRTY);
|
|
DistroBaker |
6ff1af |
dirty_elf = 1;
|
|
DistroBaker |
6ff1af |
}
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
@@ -1469,12 +1472,7 @@ read_dwarf2_line (DSO *dso, uint32_t off, char *comp_dir)
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
if (get_line_table (dso, off, &table) == false
|
|
DistroBaker |
6ff1af |
|| table == NULL)
|
|
DistroBaker |
6ff1af |
- {
|
|
DistroBaker |
6ff1af |
- if (table != NULL)
|
|
DistroBaker |
6ff1af |
- error (0, 0, ".debug_line offset 0x%x referenced multiple times",
|
|
DistroBaker |
6ff1af |
- off);
|
|
DistroBaker |
6ff1af |
- return false;
|
|
DistroBaker |
6ff1af |
- }
|
|
DistroBaker |
6ff1af |
+ return false;
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
/* Skip to the directory table. The rest of the header has already
|
|
DistroBaker |
6ff1af |
been read and checked by get_line_table. */
|
|
DistroBaker |
6ff1af |
@@ -1965,22 +1963,25 @@ line_rel_cmp (const void *a, const void *b)
|
|
DistroBaker |
6ff1af |
}
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
static int
|
|
DistroBaker |
6ff1af |
-edit_info (DSO *dso, int phase)
|
|
DistroBaker |
6ff1af |
+edit_info (DSO *dso, int phase, struct debug_section *sec)
|
|
DistroBaker |
6ff1af |
{
|
|
DistroBaker |
6ff1af |
unsigned char *ptr, *endcu, *endsec;
|
|
DistroBaker |
6ff1af |
uint32_t value;
|
|
DistroBaker |
6ff1af |
htab_t abbrev;
|
|
DistroBaker |
6ff1af |
struct abbrev_tag tag, *t;
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
- ptr = debug_sections[DEBUG_INFO].data;
|
|
DistroBaker |
6ff1af |
- setup_relbuf(dso, &debug_sections[DEBUG_INFO], &reltype);
|
|
DistroBaker |
6ff1af |
- endsec = ptr + debug_sections[DEBUG_INFO].size;
|
|
DistroBaker |
6ff1af |
+ ptr = sec->data;
|
|
DistroBaker |
6ff1af |
+ if (ptr == NULL)
|
|
DistroBaker |
6ff1af |
+ return 0;
|
|
DistroBaker |
6ff1af |
+
|
|
DistroBaker |
6ff1af |
+ setup_relbuf(dso, sec, &reltype);
|
|
DistroBaker |
6ff1af |
+ endsec = ptr + sec->size;
|
|
DistroBaker |
6ff1af |
while (ptr < endsec)
|
|
DistroBaker |
6ff1af |
{
|
|
DistroBaker |
6ff1af |
- if (ptr + 11 > endsec)
|
|
DistroBaker |
6ff1af |
+ if (ptr + (sec == &debug_sections[DEBUG_INFO] ? 11 : 23) > endsec)
|
|
DistroBaker |
6ff1af |
{
|
|
DistroBaker |
6ff1af |
- error (0, 0, "%s: .debug_info CU header too small",
|
|
DistroBaker |
6ff1af |
- dso->filename);
|
|
DistroBaker |
6ff1af |
+ error (0, 0, "%s: %s CU header too small",
|
|
DistroBaker |
6ff1af |
+ dso->filename, sec->name);
|
|
DistroBaker |
6ff1af |
return 1;
|
|
DistroBaker |
6ff1af |
}
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
@@ -1994,7 +1995,7 @@ edit_info (DSO *dso, int phase)
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
if (endcu > endsec)
|
|
DistroBaker |
6ff1af |
{
|
|
DistroBaker |
6ff1af |
- error (0, 0, "%s: .debug_info too small", dso->filename);
|
|
DistroBaker |
6ff1af |
+ error (0, 0, "%s: %s too small", dso->filename, sec->name);
|
|
DistroBaker |
6ff1af |
return 1;
|
|
DistroBaker |
6ff1af |
}
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
@@ -2034,6 +2035,9 @@ edit_info (DSO *dso, int phase)
|
|
DistroBaker |
6ff1af |
return 1;
|
|
DistroBaker |
6ff1af |
}
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
+ if (sec != &debug_sections[DEBUG_INFO])
|
|
DistroBaker |
6ff1af |
+ ptr += 12; /* Skip type_signature and type_offset. */
|
|
DistroBaker |
6ff1af |
+
|
|
DistroBaker |
6ff1af |
abbrev = read_abbrev (dso,
|
|
DistroBaker |
6ff1af |
debug_sections[DEBUG_ABBREV].data + value);
|
|
DistroBaker |
6ff1af |
if (abbrev == NULL)
|
|
DistroBaker |
6ff1af |
@@ -2095,7 +2099,7 @@ edit_dwarf2 (DSO *dso)
|
|
DistroBaker |
6ff1af |
struct debug_section *debug_sec = &debug_sections[j];
|
|
DistroBaker |
6ff1af |
if (debug_sections[j].data)
|
|
DistroBaker |
6ff1af |
{
|
|
DistroBaker |
6ff1af |
- if (j != DEBUG_MACRO)
|
|
DistroBaker |
6ff1af |
+ if (j != DEBUG_MACRO && j != DEBUG_TYPES)
|
|
DistroBaker |
6ff1af |
{
|
|
DistroBaker |
6ff1af |
error (0, 0, "%s: Found two copies of %s section",
|
|
DistroBaker |
6ff1af |
dso->filename, name);
|
|
DistroBaker |
6ff1af |
@@ -2103,22 +2107,21 @@ edit_dwarf2 (DSO *dso)
|
|
DistroBaker |
6ff1af |
}
|
|
DistroBaker |
6ff1af |
else
|
|
DistroBaker |
6ff1af |
{
|
|
DistroBaker |
6ff1af |
- /* In relocatable files .debug_macro might
|
|
DistroBaker |
6ff1af |
- appear multiple times as COMDAT
|
|
DistroBaker |
6ff1af |
- section. */
|
|
DistroBaker |
6ff1af |
+ /* In relocatable files .debug_macro and .debug_types
|
|
DistroBaker |
6ff1af |
+ might appear multiple times as COMDAT section. */
|
|
DistroBaker |
6ff1af |
struct debug_section *sec;
|
|
DistroBaker |
6ff1af |
sec = calloc (sizeof (struct debug_section), 1);
|
|
DistroBaker |
6ff1af |
if (sec == NULL)
|
|
DistroBaker |
6ff1af |
error (1, errno,
|
|
DistroBaker |
6ff1af |
- "%s: Could not allocate more macro sections",
|
|
DistroBaker |
6ff1af |
- dso->filename);
|
|
DistroBaker |
6ff1af |
- sec->name = ".debug_macro";
|
|
DistroBaker |
6ff1af |
+ "%s: Could not allocate more %s sections",
|
|
DistroBaker |
6ff1af |
+ dso->filename, name);
|
|
DistroBaker |
6ff1af |
+ sec->name = name;
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
- struct debug_section *macro_sec = debug_sec;
|
|
DistroBaker |
6ff1af |
- while (macro_sec->next != NULL)
|
|
DistroBaker |
6ff1af |
- macro_sec = macro_sec->next;
|
|
DistroBaker |
6ff1af |
+ struct debug_section *multi_sec = debug_sec;
|
|
DistroBaker |
6ff1af |
+ while (multi_sec->next != NULL)
|
|
DistroBaker |
6ff1af |
+ multi_sec = multi_sec->next;
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
- macro_sec->next = sec;
|
|
DistroBaker |
6ff1af |
+ multi_sec->next = sec;
|
|
DistroBaker |
6ff1af |
debug_sec = sec;
|
|
DistroBaker |
6ff1af |
}
|
|
DistroBaker |
6ff1af |
}
|
|
DistroBaker |
6ff1af |
@@ -2155,23 +2158,23 @@ edit_dwarf2 (DSO *dso)
|
|
DistroBaker |
6ff1af |
+ (dso->shdr[i].sh_type == SHT_RELA),
|
|
DistroBaker |
6ff1af |
debug_sections[j].name) == 0)
|
|
DistroBaker |
6ff1af |
{
|
|
DistroBaker |
6ff1af |
- if (j == DEBUG_MACRO)
|
|
DistroBaker |
6ff1af |
+ if (j == DEBUG_MACRO || j == DEBUG_TYPES)
|
|
DistroBaker |
6ff1af |
{
|
|
DistroBaker |
6ff1af |
/* Pick the correct one. */
|
|
DistroBaker |
6ff1af |
int rel_target = dso->shdr[i].sh_info;
|
|
DistroBaker |
6ff1af |
- struct debug_section *macro_sec = &debug_sections[j];
|
|
DistroBaker |
6ff1af |
- while (macro_sec != NULL)
|
|
DistroBaker |
6ff1af |
+ struct debug_section *multi_sec = &debug_sections[j];
|
|
DistroBaker |
6ff1af |
+ while (multi_sec != NULL)
|
|
DistroBaker |
6ff1af |
{
|
|
DistroBaker |
6ff1af |
- if (macro_sec->sec == rel_target)
|
|
DistroBaker |
6ff1af |
+ if (multi_sec->sec == rel_target)
|
|
DistroBaker |
6ff1af |
{
|
|
DistroBaker |
6ff1af |
- macro_sec->relsec = i;
|
|
DistroBaker |
6ff1af |
+ multi_sec->relsec = i;
|
|
DistroBaker |
6ff1af |
break;
|
|
DistroBaker |
6ff1af |
}
|
|
DistroBaker |
6ff1af |
- macro_sec = macro_sec->next;
|
|
DistroBaker |
6ff1af |
+ multi_sec = multi_sec->next;
|
|
DistroBaker |
6ff1af |
}
|
|
DistroBaker |
6ff1af |
- if (macro_sec == NULL)
|
|
DistroBaker |
6ff1af |
- error (0, 1, "No .debug_macro reloc section: %s",
|
|
DistroBaker |
6ff1af |
- dso->filename);
|
|
DistroBaker |
6ff1af |
+ if (multi_sec == NULL)
|
|
DistroBaker |
6ff1af |
+ error (0, 1, "No %s reloc section: %s",
|
|
DistroBaker |
6ff1af |
+ debug_sections[j].name, dso->filename);
|
|
DistroBaker |
6ff1af |
}
|
|
DistroBaker |
6ff1af |
else
|
|
DistroBaker |
6ff1af |
debug_sections[j].relsec = i;
|
|
DistroBaker |
6ff1af |
@@ -2203,12 +2206,10 @@ edit_dwarf2 (DSO *dso)
|
|
DistroBaker |
6ff1af |
if (debug_sections[DEBUG_INFO].data == NULL)
|
|
DistroBaker |
6ff1af |
return 0;
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
- unsigned char *ptr, *endcu, *endsec;
|
|
DistroBaker |
6ff1af |
- uint32_t value;
|
|
DistroBaker |
6ff1af |
- htab_t abbrev;
|
|
DistroBaker |
6ff1af |
- struct abbrev_tag tag, *t;
|
|
DistroBaker |
6ff1af |
+ unsigned char *ptr, *endsec;
|
|
DistroBaker |
6ff1af |
int phase;
|
|
DistroBaker |
6ff1af |
bool info_rel_updated = false;
|
|
DistroBaker |
6ff1af |
+ bool types_rel_updated = false;
|
|
DistroBaker |
6ff1af |
bool macro_rel_updated = false;
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
for (phase = 0; phase < 2; phase++)
|
|
DistroBaker |
6ff1af |
@@ -2221,13 +2222,26 @@ edit_dwarf2 (DSO *dso)
|
|
DistroBaker |
6ff1af |
break;
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
rel_updated = false;
|
|
DistroBaker |
6ff1af |
- if (edit_info (dso, phase))
|
|
DistroBaker |
6ff1af |
- return 1;
|
|
DistroBaker |
6ff1af |
+ if (edit_info (dso, phase, &debug_sections[DEBUG_INFO]))
|
|
DistroBaker |
6ff1af |
+ return 1;
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
/* Remember whether any .debug_info relocations might need
|
|
DistroBaker |
6ff1af |
to be updated. */
|
|
DistroBaker |
6ff1af |
info_rel_updated = rel_updated;
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
+ rel_updated = false;
|
|
DistroBaker |
6ff1af |
+ struct debug_section *types_sec = &debug_sections[DEBUG_TYPES];
|
|
DistroBaker |
6ff1af |
+ while (types_sec != NULL)
|
|
DistroBaker |
6ff1af |
+ {
|
|
DistroBaker |
6ff1af |
+ if (edit_info (dso, phase, types_sec))
|
|
DistroBaker |
6ff1af |
+ return 1;
|
|
DistroBaker |
6ff1af |
+ types_sec = types_sec->next;
|
|
DistroBaker |
6ff1af |
+ }
|
|
DistroBaker |
6ff1af |
+
|
|
DistroBaker |
6ff1af |
+ /* Remember whether any .debug_types relocations might need
|
|
DistroBaker |
6ff1af |
+ to be updated. */
|
|
DistroBaker |
6ff1af |
+ types_rel_updated = rel_updated;
|
|
DistroBaker |
6ff1af |
+
|
|
DistroBaker |
6ff1af |
/* We might have to recalculate/rewrite the debug_line
|
|
DistroBaker |
6ff1af |
section. We need to do that before going into phase one
|
|
DistroBaker |
6ff1af |
so we have all new offsets. We do this separately from
|
|
DistroBaker |
6ff1af |
@@ -2475,8 +2489,11 @@ edit_dwarf2 (DSO *dso)
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
/* After phase 1 we might have rewritten the debug_info with
|
|
DistroBaker |
6ff1af |
new strp, strings and/or linep offsets. */
|
|
DistroBaker |
6ff1af |
- if (need_strp_update || need_string_replacement || need_stmt_update)
|
|
DistroBaker |
6ff1af |
+ if (need_strp_update || need_string_replacement || need_stmt_update) {
|
|
DistroBaker |
6ff1af |
dirty_section (DEBUG_INFO);
|
|
DistroBaker |
6ff1af |
+ if (debug_sections[DEBUG_TYPES].data != NULL)
|
|
DistroBaker |
6ff1af |
+ dirty_section (DEBUG_TYPES);
|
|
DistroBaker |
6ff1af |
+ }
|
|
DistroBaker |
6ff1af |
if (need_strp_update || need_stmt_update)
|
|
DistroBaker |
6ff1af |
dirty_section (DEBUG_MACRO);
|
|
DistroBaker |
6ff1af |
if (need_stmt_update)
|
|
DistroBaker |
6ff1af |
@@ -2485,6 +2502,15 @@ edit_dwarf2 (DSO *dso)
|
|
DistroBaker |
6ff1af |
/* Update any relocations addends we might have touched. */
|
|
DistroBaker |
6ff1af |
if (info_rel_updated)
|
|
DistroBaker |
6ff1af |
update_rela_data (dso, &debug_sections[DEBUG_INFO]);
|
|
DistroBaker |
6ff1af |
+ if (types_rel_updated)
|
|
DistroBaker |
6ff1af |
+ {
|
|
DistroBaker |
6ff1af |
+ struct debug_section *types_sec = &debug_sections[DEBUG_TYPES];
|
|
DistroBaker |
6ff1af |
+ while (types_sec != NULL)
|
|
DistroBaker |
6ff1af |
+ {
|
|
DistroBaker |
6ff1af |
+ update_rela_data (dso, types_sec);
|
|
DistroBaker |
6ff1af |
+ types_sec = types_sec->next;
|
|
DistroBaker |
6ff1af |
+ }
|
|
DistroBaker |
6ff1af |
+ }
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
if (macro_rel_updated)
|
|
DistroBaker |
6ff1af |
{
|
|
DistroBaker |
6ff1af |
@@ -3037,6 +3063,17 @@ main (int argc, char *argv[])
|
|
DistroBaker |
6ff1af |
macro_sec = next;
|
|
DistroBaker |
6ff1af |
}
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
+ /* In case there were multiple (COMDAT) .debug_types sections,
|
|
DistroBaker |
6ff1af |
+ free them. */
|
|
DistroBaker |
6ff1af |
+ struct debug_section *types_sec = &debug_sections[DEBUG_TYPES];
|
|
DistroBaker |
6ff1af |
+ types_sec = types_sec->next;
|
|
DistroBaker |
6ff1af |
+ while (types_sec != NULL)
|
|
DistroBaker |
6ff1af |
+ {
|
|
DistroBaker |
6ff1af |
+ struct debug_section *next = types_sec->next;
|
|
DistroBaker |
6ff1af |
+ free (types_sec);
|
|
DistroBaker |
6ff1af |
+ types_sec = next;
|
|
DistroBaker |
6ff1af |
+ }
|
|
DistroBaker |
6ff1af |
+
|
|
DistroBaker |
6ff1af |
poptFreeContext (optCon);
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
return 0;
|
|
DistroBaker |
6ff1af |
--
|
|
DistroBaker |
6ff1af |
2.18.4
|
|
DistroBaker |
6ff1af |
|