|
DistroBaker |
6ff1af |
From bab443ab4f756ef80f814af0353143f41e90e6a6 Mon Sep 17 00:00:00 2001
|
|
DistroBaker |
6ff1af |
From: Jan Kratochvil <jan.kratochvil@redhat.com>
|
|
DistroBaker |
6ff1af |
Date: Mon, 17 Aug 2020 21:58:19 +0200
|
|
DistroBaker |
6ff1af |
Subject: [PATCH 4/6] [NFC] debugedit: Move code to separate functions.
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
New functions edit_strp, skip_form and edit_attributes_str_comp_dir
|
|
DistroBaker |
6ff1af |
called by edit_attributes.
|
|
DistroBaker |
6ff1af |
Split part of read_dwarf2_line into a read_dwarf4_line function.
|
|
DistroBaker |
6ff1af |
New function edit_dwarf2_any_str called by edit_dwarf2 at the end of
|
|
DistroBaker |
6ff1af |
phase 0 to rebuild .debug_str.
|
|
DistroBaker |
6ff1af |
---
|
|
DistroBaker |
6ff1af |
tools/debugedit.c | 367 ++++++++++++++++++++++++++--------------------
|
|
DistroBaker |
6ff1af |
1 file changed, 212 insertions(+), 155 deletions(-)
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
diff --git a/tools/debugedit.c b/tools/debugedit.c
|
|
DistroBaker |
6ff1af |
index 87c1cd622..7464883c5 100644
|
|
DistroBaker |
6ff1af |
--- a/tools/debugedit.c
|
|
DistroBaker |
6ff1af |
+++ b/tools/debugedit.c
|
|
DistroBaker |
6ff1af |
@@ -1457,37 +1457,128 @@ edit_dwarf2_line (DSO *dso)
|
|
DistroBaker |
6ff1af |
}
|
|
DistroBaker |
6ff1af |
}
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
-/* Called during phase zero for each debug_line table referenced from
|
|
DistroBaker |
6ff1af |
- .debug_info. Outputs all source files seen and records any
|
|
DistroBaker |
6ff1af |
- adjustments needed in the debug_list data structures. Returns true
|
|
DistroBaker |
6ff1af |
- if line_table needs to be rewrite either the dir or file paths. */
|
|
DistroBaker |
6ff1af |
+/* Record or adjust (according to phase) DW_FORM_strp. */
|
|
DistroBaker |
6ff1af |
+static void
|
|
DistroBaker |
6ff1af |
+edit_strp (DSO *dso, unsigned char *ptr, int phase, bool handled_strp)
|
|
DistroBaker |
6ff1af |
+{
|
|
DistroBaker |
6ff1af |
+ unsigned char *ptr_orig = ptr;
|
|
DistroBaker |
6ff1af |
+
|
|
DistroBaker |
6ff1af |
+ /* In the first pass we collect all strings, in the
|
|
DistroBaker |
6ff1af |
+ second we put the new references back (if there are
|
|
DistroBaker |
6ff1af |
+ any changes). */
|
|
DistroBaker |
6ff1af |
+ if (phase == 0)
|
|
DistroBaker |
6ff1af |
+ {
|
|
DistroBaker |
6ff1af |
+ /* handled_strp is set for attributes referring to
|
|
DistroBaker |
6ff1af |
+ files. If it is set the string is already
|
|
DistroBaker |
6ff1af |
+ recorded. */
|
|
DistroBaker |
6ff1af |
+ if (! handled_strp)
|
|
DistroBaker |
6ff1af |
+ {
|
|
DistroBaker |
6ff1af |
+ size_t idx = do_read_32_relocated (ptr);
|
|
DistroBaker |
6ff1af |
+ record_existing_string_entry_idx (&dso->strings, idx);
|
|
DistroBaker |
6ff1af |
+ }
|
|
DistroBaker |
6ff1af |
+ }
|
|
DistroBaker |
6ff1af |
+ else if (need_strp_update) /* && phase == 1 */
|
|
DistroBaker |
6ff1af |
+ {
|
|
DistroBaker |
6ff1af |
+ struct stridxentry *entry;
|
|
DistroBaker |
6ff1af |
+ size_t idx, new_idx;
|
|
DistroBaker |
6ff1af |
+ idx = do_read_32_relocated (ptr);
|
|
DistroBaker |
6ff1af |
+ entry = string_find_entry (&dso->strings, idx);
|
|
DistroBaker |
6ff1af |
+ new_idx = strent_offset (entry->entry);
|
|
DistroBaker |
6ff1af |
+ do_write_32_relocated (ptr, new_idx);
|
|
DistroBaker |
6ff1af |
+ }
|
|
DistroBaker |
6ff1af |
+
|
|
DistroBaker |
6ff1af |
+ assert (ptr == ptr_orig);
|
|
DistroBaker |
6ff1af |
+}
|
|
DistroBaker |
6ff1af |
+
|
|
DistroBaker |
6ff1af |
+/* Adjust *PTRP after the current *FORMP, update *FORMP for FORM_INDIRECT. */
|
|
DistroBaker |
6ff1af |
+static enum { FORM_OK, FORM_ERROR, FORM_INDIRECT }
|
|
DistroBaker |
6ff1af |
+skip_form (DSO *dso, uint32_t *formp, unsigned char **ptrp)
|
|
DistroBaker |
6ff1af |
+{
|
|
DistroBaker |
6ff1af |
+ size_t len = 0;
|
|
DistroBaker |
6ff1af |
+
|
|
DistroBaker |
6ff1af |
+ switch (*formp)
|
|
DistroBaker |
6ff1af |
+ {
|
|
DistroBaker |
6ff1af |
+ case DW_FORM_ref_addr:
|
|
DistroBaker |
6ff1af |
+ if (cu_version == 2)
|
|
DistroBaker |
6ff1af |
+ *ptrp += ptr_size;
|
|
DistroBaker |
6ff1af |
+ else
|
|
DistroBaker |
6ff1af |
+ *ptrp += 4;
|
|
DistroBaker |
6ff1af |
+ break;
|
|
DistroBaker |
6ff1af |
+ case DW_FORM_flag_present:
|
|
DistroBaker |
6ff1af |
+ break;
|
|
DistroBaker |
6ff1af |
+ case DW_FORM_addr:
|
|
DistroBaker |
6ff1af |
+ *ptrp += ptr_size;
|
|
DistroBaker |
6ff1af |
+ break;
|
|
DistroBaker |
6ff1af |
+ case DW_FORM_ref1:
|
|
DistroBaker |
6ff1af |
+ case DW_FORM_flag:
|
|
DistroBaker |
6ff1af |
+ case DW_FORM_data1:
|
|
DistroBaker |
6ff1af |
+ ++*ptrp;
|
|
DistroBaker |
6ff1af |
+ break;
|
|
DistroBaker |
6ff1af |
+ case DW_FORM_ref2:
|
|
DistroBaker |
6ff1af |
+ case DW_FORM_data2:
|
|
DistroBaker |
6ff1af |
+ *ptrp += 2;
|
|
DistroBaker |
6ff1af |
+ break;
|
|
DistroBaker |
6ff1af |
+ case DW_FORM_ref4:
|
|
DistroBaker |
6ff1af |
+ case DW_FORM_data4:
|
|
DistroBaker |
6ff1af |
+ case DW_FORM_sec_offset:
|
|
DistroBaker |
6ff1af |
+ *ptrp += 4;
|
|
DistroBaker |
6ff1af |
+ break;
|
|
DistroBaker |
6ff1af |
+ case DW_FORM_ref8:
|
|
DistroBaker |
6ff1af |
+ case DW_FORM_data8:
|
|
DistroBaker |
6ff1af |
+ case DW_FORM_ref_sig8:
|
|
DistroBaker |
6ff1af |
+ *ptrp += 8;
|
|
DistroBaker |
6ff1af |
+ break;
|
|
DistroBaker |
6ff1af |
+ case DW_FORM_sdata:
|
|
DistroBaker |
6ff1af |
+ case DW_FORM_ref_udata:
|
|
DistroBaker |
6ff1af |
+ case DW_FORM_udata:
|
|
DistroBaker |
6ff1af |
+ read_uleb128 (*ptrp);
|
|
DistroBaker |
6ff1af |
+ break;
|
|
DistroBaker |
6ff1af |
+ case DW_FORM_strp:
|
|
DistroBaker |
6ff1af |
+ *ptrp += 4;
|
|
DistroBaker |
6ff1af |
+ break;
|
|
DistroBaker |
6ff1af |
+ case DW_FORM_string:
|
|
DistroBaker |
6ff1af |
+ *ptrp = (unsigned char *) strchr ((char *)*ptrp, '\0') + 1;
|
|
DistroBaker |
6ff1af |
+ break;
|
|
DistroBaker |
6ff1af |
+ case DW_FORM_indirect:
|
|
DistroBaker |
6ff1af |
+ *formp = read_uleb128 (*ptrp);
|
|
DistroBaker |
6ff1af |
+ return FORM_INDIRECT;
|
|
DistroBaker |
6ff1af |
+ case DW_FORM_block1:
|
|
DistroBaker |
6ff1af |
+ len = *(*ptrp)++;
|
|
DistroBaker |
6ff1af |
+ break;
|
|
DistroBaker |
6ff1af |
+ case DW_FORM_block2:
|
|
DistroBaker |
6ff1af |
+ len = read_16 (*ptrp);
|
|
DistroBaker |
6ff1af |
+ *formp = DW_FORM_block1;
|
|
DistroBaker |
6ff1af |
+ break;
|
|
DistroBaker |
6ff1af |
+ case DW_FORM_block4:
|
|
DistroBaker |
6ff1af |
+ len = read_32 (*ptrp);
|
|
DistroBaker |
6ff1af |
+ *formp = DW_FORM_block1;
|
|
DistroBaker |
6ff1af |
+ break;
|
|
DistroBaker |
6ff1af |
+ case DW_FORM_block:
|
|
DistroBaker |
6ff1af |
+ case DW_FORM_exprloc:
|
|
DistroBaker |
6ff1af |
+ len = read_uleb128 (*ptrp);
|
|
DistroBaker |
6ff1af |
+ *formp = DW_FORM_block1;
|
|
DistroBaker |
6ff1af |
+ assert (len < UINT_MAX);
|
|
DistroBaker |
6ff1af |
+ break;
|
|
DistroBaker |
6ff1af |
+ default:
|
|
DistroBaker |
6ff1af |
+ error (0, 0, "%s: Unknown DWARF DW_FORM_%d", dso->filename, *formp);
|
|
DistroBaker |
6ff1af |
+ return FORM_ERROR;
|
|
DistroBaker |
6ff1af |
+ }
|
|
DistroBaker |
6ff1af |
+
|
|
DistroBaker |
6ff1af |
+ if (*formp == DW_FORM_block1)
|
|
DistroBaker |
6ff1af |
+ *ptrp += len;
|
|
DistroBaker |
6ff1af |
+
|
|
DistroBaker |
6ff1af |
+ return FORM_OK;
|
|
DistroBaker |
6ff1af |
+}
|
|
DistroBaker |
6ff1af |
+
|
|
DistroBaker |
6ff1af |
+/* Part of read_dwarf2_line processing DWARF-4. */
|
|
DistroBaker |
6ff1af |
static bool
|
|
DistroBaker |
6ff1af |
-read_dwarf2_line (DSO *dso, uint32_t off, char *comp_dir)
|
|
DistroBaker |
6ff1af |
+read_dwarf4_line (DSO *dso, unsigned char *ptr, char *comp_dir,
|
|
DistroBaker |
6ff1af |
+ struct line_table *table)
|
|
DistroBaker |
6ff1af |
{
|
|
DistroBaker |
6ff1af |
- unsigned char *ptr, *dir;
|
|
DistroBaker |
6ff1af |
unsigned char **dirt;
|
|
DistroBaker |
6ff1af |
uint32_t value, dirt_cnt;
|
|
DistroBaker |
6ff1af |
size_t comp_dir_len = !comp_dir ? 0 : strlen (comp_dir);
|
|
DistroBaker |
6ff1af |
- struct line_table *table;
|
|
DistroBaker |
6ff1af |
-
|
|
DistroBaker |
6ff1af |
- if (get_line_table (dso, off, &table) == false
|
|
DistroBaker |
6ff1af |
- || table == NULL)
|
|
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 |
- ptr = debug_sections[DEBUG_LINE].data + off;
|
|
DistroBaker |
6ff1af |
- ptr += (4 /* unit len */
|
|
DistroBaker |
6ff1af |
- + 2 /* version */
|
|
DistroBaker |
6ff1af |
- + 4 /* header len */
|
|
DistroBaker |
6ff1af |
- + 1 /* min instr len */
|
|
DistroBaker |
6ff1af |
- + (table->version >= 4) /* max op per instr, if version >= 4 */
|
|
DistroBaker |
6ff1af |
- + 1 /* default is stmt */
|
|
DistroBaker |
6ff1af |
- + 1 /* line base */
|
|
DistroBaker |
6ff1af |
- + 1 /* line range */
|
|
DistroBaker |
6ff1af |
- + 1 /* opcode base */
|
|
DistroBaker |
6ff1af |
- + table->opcode_base - 1); /* opcode len table */
|
|
DistroBaker |
6ff1af |
- dir = ptr;
|
|
DistroBaker |
6ff1af |
+ unsigned char *dir = ptr;
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
/* dir table: */
|
|
DistroBaker |
6ff1af |
value = 1;
|
|
DistroBaker |
6ff1af |
@@ -1620,6 +1711,40 @@ read_dwarf2_line (DSO *dso, uint32_t off, char *comp_dir)
|
|
DistroBaker |
6ff1af |
read_uleb128 (ptr);
|
|
DistroBaker |
6ff1af |
}
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
+ return true;
|
|
DistroBaker |
6ff1af |
+}
|
|
DistroBaker |
6ff1af |
+
|
|
DistroBaker |
6ff1af |
+/* Called during phase zero for each debug_line table referenced from
|
|
DistroBaker |
6ff1af |
+ .debug_info. Outputs all source files seen and records any
|
|
DistroBaker |
6ff1af |
+ adjustments needed in the debug_list data structures. Returns true
|
|
DistroBaker |
6ff1af |
+ if line_table needs to be rewrite either the dir or file paths. */
|
|
DistroBaker |
6ff1af |
+static bool
|
|
DistroBaker |
6ff1af |
+read_dwarf2_line (DSO *dso, uint32_t off, char *comp_dir)
|
|
DistroBaker |
6ff1af |
+{
|
|
DistroBaker |
6ff1af |
+ unsigned char *ptr;
|
|
DistroBaker |
6ff1af |
+ struct line_table *table;
|
|
DistroBaker |
6ff1af |
+
|
|
DistroBaker |
6ff1af |
+ if (get_line_table (dso, off, &table) == false
|
|
DistroBaker |
6ff1af |
+ || table == NULL)
|
|
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 |
+ ptr = debug_sections[DEBUG_LINE].data + off;
|
|
DistroBaker |
6ff1af |
+ ptr += (4 /* unit len */
|
|
DistroBaker |
6ff1af |
+ + 2 /* version */
|
|
DistroBaker |
6ff1af |
+ + 4 /* header len */
|
|
DistroBaker |
6ff1af |
+ + 1 /* min instr len */
|
|
DistroBaker |
6ff1af |
+ + (table->version >= 4) /* max op per instr, if version >= 4 */
|
|
DistroBaker |
6ff1af |
+ + 1 /* default is stmt */
|
|
DistroBaker |
6ff1af |
+ + 1 /* line base */
|
|
DistroBaker |
6ff1af |
+ + 1 /* line range */
|
|
DistroBaker |
6ff1af |
+ + 1 /* opcode base */
|
|
DistroBaker |
6ff1af |
+ + table->opcode_base - 1); /* opcode len table */
|
|
DistroBaker |
6ff1af |
+
|
|
DistroBaker |
6ff1af |
+ if (! read_dwarf4_line (dso, ptr, comp_dir, table))
|
|
DistroBaker |
6ff1af |
+ return false;
|
|
DistroBaker |
6ff1af |
+
|
|
DistroBaker |
6ff1af |
dso->lines.debug_lines_len += 4 + table->unit_length + table->size_diff;
|
|
DistroBaker |
6ff1af |
return table->replace_dirs || table->replace_files;
|
|
DistroBaker |
6ff1af |
}
|
|
DistroBaker |
6ff1af |
@@ -1637,6 +1762,33 @@ find_new_list_offs (struct debug_lines *lines, size_t idx)
|
|
DistroBaker |
6ff1af |
return table->new_idx;
|
|
DistroBaker |
6ff1af |
}
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
+/* Read DW_FORM_strp collecting compilation directory. */
|
|
DistroBaker |
6ff1af |
+static void
|
|
DistroBaker |
6ff1af |
+edit_attributes_str_comp_dir (DSO *dso, unsigned char **ptrp, int phase,
|
|
DistroBaker |
6ff1af |
+ char **comp_dirp, bool *handled_strpp)
|
|
DistroBaker |
6ff1af |
+{
|
|
DistroBaker |
6ff1af |
+ const char *dir;
|
|
DistroBaker |
6ff1af |
+ size_t idx = do_read_32_relocated (*ptrp);
|
|
DistroBaker |
6ff1af |
+ /* In phase zero we collect the comp_dir. */
|
|
DistroBaker |
6ff1af |
+ if (phase == 0)
|
|
DistroBaker |
6ff1af |
+ {
|
|
DistroBaker |
6ff1af |
+ if (idx >= debug_sections[DEBUG_STR].size)
|
|
DistroBaker |
6ff1af |
+ error (1, 0, "%s: Bad string pointer index %zd for comp_dir",
|
|
DistroBaker |
6ff1af |
+ dso->filename, idx);
|
|
DistroBaker |
6ff1af |
+ dir = (char *) debug_sections[DEBUG_STR].data + idx;
|
|
DistroBaker |
6ff1af |
+
|
|
DistroBaker |
6ff1af |
+ free (*comp_dirp);
|
|
DistroBaker |
6ff1af |
+ *comp_dirp = strdup (dir);
|
|
DistroBaker |
6ff1af |
+ }
|
|
DistroBaker |
6ff1af |
+
|
|
DistroBaker |
6ff1af |
+ if (dest_dir != NULL && phase == 0)
|
|
DistroBaker |
6ff1af |
+ {
|
|
DistroBaker |
6ff1af |
+ if (record_file_string_entry_idx (&dso->strings, idx))
|
|
DistroBaker |
6ff1af |
+ need_strp_update = true;
|
|
DistroBaker |
6ff1af |
+ *handled_strpp = true;
|
|
DistroBaker |
6ff1af |
+ }
|
|
DistroBaker |
6ff1af |
+}
|
|
DistroBaker |
6ff1af |
+
|
|
DistroBaker |
6ff1af |
/* This scans the attributes of one DIE described by the given abbrev_tag.
|
|
DistroBaker |
6ff1af |
PTR points to the data in the debug_info. It will be advanced till all
|
|
DistroBaker |
6ff1af |
abbrev data is consumed. In phase zero data is collected, in phase one
|
|
DistroBaker |
6ff1af |
@@ -1655,7 +1807,6 @@ edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
|
|
DistroBaker |
6ff1af |
for (i = 0; i < t->nattr; ++i)
|
|
DistroBaker |
6ff1af |
{
|
|
DistroBaker |
6ff1af |
uint32_t form = t->attr[i].form;
|
|
DistroBaker |
6ff1af |
- size_t len = 0;
|
|
DistroBaker |
6ff1af |
while (1)
|
|
DistroBaker |
6ff1af |
{
|
|
DistroBaker |
6ff1af |
/* Whether we already handled a string as file for this
|
|
DistroBaker |
6ff1af |
@@ -1743,29 +1894,8 @@ edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
|
|
DistroBaker |
6ff1af |
}
|
|
DistroBaker |
6ff1af |
else if (form == DW_FORM_strp &&
|
|
DistroBaker |
6ff1af |
debug_sections[DEBUG_STR].data)
|
|
DistroBaker |
6ff1af |
- {
|
|
DistroBaker |
6ff1af |
- const char *dir;
|
|
DistroBaker |
6ff1af |
- size_t idx = do_read_32_relocated (ptr);
|
|
DistroBaker |
6ff1af |
- /* In phase zero we collect the comp_dir. */
|
|
DistroBaker |
6ff1af |
- if (phase == 0)
|
|
DistroBaker |
6ff1af |
- {
|
|
DistroBaker |
6ff1af |
- if (idx >= debug_sections[DEBUG_STR].size)
|
|
DistroBaker |
6ff1af |
- error (1, 0,
|
|
DistroBaker |
6ff1af |
- "%s: Bad string pointer index %zd for comp_dir",
|
|
DistroBaker |
6ff1af |
- dso->filename, idx);
|
|
DistroBaker |
6ff1af |
- dir = (char *) debug_sections[DEBUG_STR].data + idx;
|
|
DistroBaker |
6ff1af |
-
|
|
DistroBaker |
6ff1af |
- free (comp_dir);
|
|
DistroBaker |
6ff1af |
- comp_dir = strdup (dir);
|
|
DistroBaker |
6ff1af |
- }
|
|
DistroBaker |
6ff1af |
-
|
|
DistroBaker |
6ff1af |
- if (dest_dir != NULL && phase == 0)
|
|
DistroBaker |
6ff1af |
- {
|
|
DistroBaker |
6ff1af |
- if (record_file_string_entry_idx (&dso->strings, idx))
|
|
DistroBaker |
6ff1af |
- need_strp_update = true;
|
|
DistroBaker |
6ff1af |
- handled_strp = true;
|
|
DistroBaker |
6ff1af |
- }
|
|
DistroBaker |
6ff1af |
- }
|
|
DistroBaker |
6ff1af |
+ edit_attributes_str_comp_dir (dso, &ptr, phase, &comp_dir,
|
|
DistroBaker |
6ff1af |
+ &handled_strp);
|
|
DistroBaker |
6ff1af |
}
|
|
DistroBaker |
6ff1af |
else if ((t->tag == DW_TAG_compile_unit
|
|
DistroBaker |
6ff1af |
|| t->tag == DW_TAG_partial_unit)
|
|
DistroBaker |
6ff1af |
@@ -1815,99 +1945,21 @@ edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
switch (form)
|
|
DistroBaker |
6ff1af |
{
|
|
DistroBaker |
6ff1af |
- case DW_FORM_ref_addr:
|
|
DistroBaker |
6ff1af |
- if (cu_version == 2)
|
|
DistroBaker |
6ff1af |
- ptr += ptr_size;
|
|
DistroBaker |
6ff1af |
- else
|
|
DistroBaker |
6ff1af |
- ptr += 4;
|
|
DistroBaker |
6ff1af |
- break;
|
|
DistroBaker |
6ff1af |
- case DW_FORM_flag_present:
|
|
DistroBaker |
6ff1af |
- break;
|
|
DistroBaker |
6ff1af |
- case DW_FORM_addr:
|
|
DistroBaker |
6ff1af |
- ptr += ptr_size;
|
|
DistroBaker |
6ff1af |
- break;
|
|
DistroBaker |
6ff1af |
- case DW_FORM_ref1:
|
|
DistroBaker |
6ff1af |
- case DW_FORM_flag:
|
|
DistroBaker |
6ff1af |
- case DW_FORM_data1:
|
|
DistroBaker |
6ff1af |
- ++ptr;
|
|
DistroBaker |
6ff1af |
- break;
|
|
DistroBaker |
6ff1af |
- case DW_FORM_ref2:
|
|
DistroBaker |
6ff1af |
- case DW_FORM_data2:
|
|
DistroBaker |
6ff1af |
- ptr += 2;
|
|
DistroBaker |
6ff1af |
- break;
|
|
DistroBaker |
6ff1af |
- case DW_FORM_ref4:
|
|
DistroBaker |
6ff1af |
- case DW_FORM_data4:
|
|
DistroBaker |
6ff1af |
- case DW_FORM_sec_offset:
|
|
DistroBaker |
6ff1af |
- ptr += 4;
|
|
DistroBaker |
6ff1af |
- break;
|
|
DistroBaker |
6ff1af |
- case DW_FORM_ref8:
|
|
DistroBaker |
6ff1af |
- case DW_FORM_data8:
|
|
DistroBaker |
6ff1af |
- case DW_FORM_ref_sig8:
|
|
DistroBaker |
6ff1af |
- ptr += 8;
|
|
DistroBaker |
6ff1af |
- break;
|
|
DistroBaker |
6ff1af |
- case DW_FORM_sdata:
|
|
DistroBaker |
6ff1af |
- case DW_FORM_ref_udata:
|
|
DistroBaker |
6ff1af |
- case DW_FORM_udata:
|
|
DistroBaker |
6ff1af |
- read_uleb128 (ptr);
|
|
DistroBaker |
6ff1af |
- break;
|
|
DistroBaker |
6ff1af |
case DW_FORM_strp:
|
|
DistroBaker |
6ff1af |
- /* In the first pass we collect all strings, in the
|
|
DistroBaker |
6ff1af |
- second we put the new references back (if there are
|
|
DistroBaker |
6ff1af |
- any changes). */
|
|
DistroBaker |
6ff1af |
- if (phase == 0)
|
|
DistroBaker |
6ff1af |
- {
|
|
DistroBaker |
6ff1af |
- /* handled_strp is set for attributes referring to
|
|
DistroBaker |
6ff1af |
- files. If it is set the string is already
|
|
DistroBaker |
6ff1af |
- recorded. */
|
|
DistroBaker |
6ff1af |
- if (! handled_strp)
|
|
DistroBaker |
6ff1af |
- {
|
|
DistroBaker |
6ff1af |
- size_t idx = do_read_32_relocated (ptr);
|
|
DistroBaker |
6ff1af |
- record_existing_string_entry_idx (&dso->strings, idx);
|
|
DistroBaker |
6ff1af |
- }
|
|
DistroBaker |
6ff1af |
- }
|
|
DistroBaker |
6ff1af |
- else if (need_strp_update) /* && phase == 1 */
|
|
DistroBaker |
6ff1af |
- {
|
|
DistroBaker |
6ff1af |
- struct stridxentry *entry;
|
|
DistroBaker |
6ff1af |
- size_t idx, new_idx;
|
|
DistroBaker |
6ff1af |
- idx = do_read_32_relocated (ptr);
|
|
DistroBaker |
6ff1af |
- entry = string_find_entry (&dso->strings, idx);
|
|
DistroBaker |
6ff1af |
- new_idx = strent_offset (entry->entry);
|
|
DistroBaker |
6ff1af |
- do_write_32_relocated (ptr, new_idx);
|
|
DistroBaker |
6ff1af |
- }
|
|
DistroBaker |
6ff1af |
- ptr += 4;
|
|
DistroBaker |
6ff1af |
- break;
|
|
DistroBaker |
6ff1af |
- case DW_FORM_string:
|
|
DistroBaker |
6ff1af |
- ptr = (unsigned char *) strchr ((char *)ptr, '\0') + 1;
|
|
DistroBaker |
6ff1af |
- break;
|
|
DistroBaker |
6ff1af |
- case DW_FORM_indirect:
|
|
DistroBaker |
6ff1af |
- form = read_uleb128 (ptr);
|
|
DistroBaker |
6ff1af |
- continue;
|
|
DistroBaker |
6ff1af |
- case DW_FORM_block1:
|
|
DistroBaker |
6ff1af |
- len = *ptr++;
|
|
DistroBaker |
6ff1af |
- break;
|
|
DistroBaker |
6ff1af |
- case DW_FORM_block2:
|
|
DistroBaker |
6ff1af |
- len = read_16 (ptr);
|
|
DistroBaker |
6ff1af |
- form = DW_FORM_block1;
|
|
DistroBaker |
6ff1af |
+ edit_strp (dso, ptr, phase, handled_strp);
|
|
DistroBaker |
6ff1af |
break;
|
|
DistroBaker |
6ff1af |
- case DW_FORM_block4:
|
|
DistroBaker |
6ff1af |
- len = read_32 (ptr);
|
|
DistroBaker |
6ff1af |
- form = DW_FORM_block1;
|
|
DistroBaker |
6ff1af |
- break;
|
|
DistroBaker |
6ff1af |
- case DW_FORM_block:
|
|
DistroBaker |
6ff1af |
- case DW_FORM_exprloc:
|
|
DistroBaker |
6ff1af |
- len = read_uleb128 (ptr);
|
|
DistroBaker |
6ff1af |
- form = DW_FORM_block1;
|
|
DistroBaker |
6ff1af |
- assert (len < UINT_MAX);
|
|
DistroBaker |
6ff1af |
+ }
|
|
DistroBaker |
6ff1af |
+
|
|
DistroBaker |
6ff1af |
+ switch (skip_form (dso, &form, &ptr))
|
|
DistroBaker |
6ff1af |
+ {
|
|
DistroBaker |
6ff1af |
+ case FORM_OK:
|
|
DistroBaker |
6ff1af |
break;
|
|
DistroBaker |
6ff1af |
- default:
|
|
DistroBaker |
6ff1af |
- error (0, 0, "%s: Unknown DWARF DW_FORM_%d", dso->filename,
|
|
DistroBaker |
6ff1af |
- form);
|
|
DistroBaker |
6ff1af |
+ case FORM_ERROR:
|
|
DistroBaker |
6ff1af |
return NULL;
|
|
DistroBaker |
6ff1af |
+ case FORM_INDIRECT:
|
|
DistroBaker |
6ff1af |
+ continue;
|
|
DistroBaker |
6ff1af |
}
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
- if (form == DW_FORM_block1)
|
|
DistroBaker |
6ff1af |
- ptr += len;
|
|
DistroBaker |
6ff1af |
-
|
|
DistroBaker |
6ff1af |
break;
|
|
DistroBaker |
6ff1af |
}
|
|
DistroBaker |
6ff1af |
}
|
|
DistroBaker |
6ff1af |
@@ -2068,6 +2120,28 @@ edit_info (DSO *dso, int phase, struct debug_section *sec)
|
|
DistroBaker |
6ff1af |
return 0;
|
|
DistroBaker |
6ff1af |
}
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
+/* Rebuild .debug_str. */
|
|
DistroBaker |
6ff1af |
+static void
|
|
DistroBaker |
6ff1af |
+edit_dwarf2_any_str (DSO *dso)
|
|
DistroBaker |
6ff1af |
+{
|
|
DistroBaker |
6ff1af |
+ Strtab *strtab = dso->strings.str_tab;
|
|
DistroBaker |
6ff1af |
+ Elf_Data *strdata = debug_sections[DEBUG_STR].elf_data;
|
|
DistroBaker |
6ff1af |
+ int strndx = debug_sections[DEBUG_STR].sec;
|
|
DistroBaker |
6ff1af |
+ Elf_Scn *strscn = dso->scn[strndx];
|
|
DistroBaker |
6ff1af |
+
|
|
DistroBaker |
6ff1af |
+ /* Out with the old. */
|
|
DistroBaker |
6ff1af |
+ strdata->d_size = 0;
|
|
DistroBaker |
6ff1af |
+ /* In with the new. */
|
|
DistroBaker |
6ff1af |
+ strdata = elf_newdata (strscn);
|
|
DistroBaker |
6ff1af |
+
|
|
DistroBaker |
6ff1af |
+ /* We really should check whether we had enough memory,
|
|
DistroBaker |
6ff1af |
+ but the old ebl version will just abort on out of
|
|
DistroBaker |
6ff1af |
+ memory... */
|
|
DistroBaker |
6ff1af |
+ strtab_finalize (strtab, strdata);
|
|
DistroBaker |
6ff1af |
+ debug_sections[DEBUG_STR].size = strdata->d_size;
|
|
DistroBaker |
6ff1af |
+ dso->strings.str_buf = strdata->d_buf;
|
|
DistroBaker |
6ff1af |
+}
|
|
DistroBaker |
6ff1af |
+
|
|
DistroBaker |
6ff1af |
static int
|
|
DistroBaker |
6ff1af |
edit_dwarf2 (DSO *dso)
|
|
DistroBaker |
6ff1af |
{
|
|
DistroBaker |
6ff1af |
@@ -2466,24 +2540,7 @@ edit_dwarf2 (DSO *dso)
|
|
DistroBaker |
6ff1af |
in place for phase 1 updating of debug_info
|
|
DistroBaker |
6ff1af |
references. */
|
|
DistroBaker |
6ff1af |
if (phase == 0 && need_strp_update)
|
|
DistroBaker |
6ff1af |
- {
|
|
DistroBaker |
6ff1af |
- Strtab *strtab = dso->strings.str_tab;
|
|
DistroBaker |
6ff1af |
- Elf_Data *strdata = debug_sections[DEBUG_STR].elf_data;
|
|
DistroBaker |
6ff1af |
- int strndx = debug_sections[DEBUG_STR].sec;
|
|
DistroBaker |
6ff1af |
- Elf_Scn *strscn = dso->scn[strndx];
|
|
DistroBaker |
6ff1af |
-
|
|
DistroBaker |
6ff1af |
- /* Out with the old. */
|
|
DistroBaker |
6ff1af |
- strdata->d_size = 0;
|
|
DistroBaker |
6ff1af |
- /* In with the new. */
|
|
DistroBaker |
6ff1af |
- strdata = elf_newdata (strscn);
|
|
DistroBaker |
6ff1af |
-
|
|
DistroBaker |
6ff1af |
- /* We really should check whether we had enough memory,
|
|
DistroBaker |
6ff1af |
- but the old ebl version will just abort on out of
|
|
DistroBaker |
6ff1af |
- memory... */
|
|
DistroBaker |
6ff1af |
- strtab_finalize (strtab, strdata);
|
|
DistroBaker |
6ff1af |
- debug_sections[DEBUG_STR].size = strdata->d_size;
|
|
DistroBaker |
6ff1af |
- dso->strings.str_buf = strdata->d_buf;
|
|
DistroBaker |
6ff1af |
- }
|
|
DistroBaker |
6ff1af |
+ edit_dwarf2_any_str (dso);
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
}
|
|
DistroBaker |
6ff1af |
|
|
DistroBaker |
6ff1af |
--
|
|
DistroBaker |
6ff1af |
2.18.4
|
|
DistroBaker |
6ff1af |
|