You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
753 lines
22 KiB
753 lines
22 KiB
From de119ea9797f3ccfa3842e3926b6ea8198607207 Mon Sep 17 00:00:00 2001 |
|
From: Jan Kratochvil <jan.kratochvil@redhat.com> |
|
Date: Sat, 1 Aug 2020 10:43:12 +0200 |
|
Subject: [PATCH 2/6] [NFC] debugedit: Move code from edit_dwarf2() to |
|
edit_info(). |
|
|
|
--- |
|
tools/debugedit.c | 672 +++++++++++++++++++++++----------------------- |
|
1 file changed, 343 insertions(+), 329 deletions(-) |
|
|
|
diff --git a/tools/debugedit.c b/tools/debugedit.c |
|
index a351adec8..cad0cc349 100644 |
|
--- a/tools/debugedit.c |
|
+++ b/tools/debugedit.c |
|
@@ -1964,6 +1964,106 @@ line_rel_cmp (const void *a, const void *b) |
|
return 0; |
|
} |
|
|
|
+static int |
|
+edit_info (DSO *dso, int phase) |
|
+{ |
|
+ unsigned char *ptr, *endcu, *endsec; |
|
+ uint32_t value; |
|
+ htab_t abbrev; |
|
+ struct abbrev_tag tag, *t; |
|
+ |
|
+ ptr = debug_sections[DEBUG_INFO].data; |
|
+ setup_relbuf(dso, &debug_sections[DEBUG_INFO], &reltype); |
|
+ endsec = ptr + debug_sections[DEBUG_INFO].size; |
|
+ while (ptr < endsec) |
|
+ { |
|
+ if (ptr + 11 > endsec) |
|
+ { |
|
+ error (0, 0, "%s: .debug_info CU header too small", |
|
+ dso->filename); |
|
+ return 1; |
|
+ } |
|
+ |
|
+ endcu = ptr + 4; |
|
+ endcu += read_32 (ptr); |
|
+ if (endcu == ptr + 0xffffffff) |
|
+ { |
|
+ error (0, 0, "%s: 64-bit DWARF not supported", dso->filename); |
|
+ return 1; |
|
+ } |
|
+ |
|
+ if (endcu > endsec) |
|
+ { |
|
+ error (0, 0, "%s: .debug_info too small", dso->filename); |
|
+ return 1; |
|
+ } |
|
+ |
|
+ cu_version = read_16 (ptr); |
|
+ if (cu_version != 2 && cu_version != 3 && cu_version != 4) |
|
+ { |
|
+ error (0, 0, "%s: DWARF version %d unhandled", dso->filename, |
|
+ cu_version); |
|
+ return 1; |
|
+ } |
|
+ |
|
+ value = read_32_relocated (ptr); |
|
+ if (value >= debug_sections[DEBUG_ABBREV].size) |
|
+ { |
|
+ if (debug_sections[DEBUG_ABBREV].data == NULL) |
|
+ error (0, 0, "%s: .debug_abbrev not present", dso->filename); |
|
+ else |
|
+ error (0, 0, "%s: DWARF CU abbrev offset too large", |
|
+ dso->filename); |
|
+ return 1; |
|
+ } |
|
+ |
|
+ if (ptr_size == 0) |
|
+ { |
|
+ ptr_size = read_8 (ptr); |
|
+ if (ptr_size != 4 && ptr_size != 8) |
|
+ { |
|
+ error (0, 0, "%s: Invalid DWARF pointer size %d", |
|
+ dso->filename, ptr_size); |
|
+ return 1; |
|
+ } |
|
+ } |
|
+ else if (read_8 (ptr) != ptr_size) |
|
+ { |
|
+ error (0, 0, "%s: DWARF pointer size differs between CUs", |
|
+ dso->filename); |
|
+ return 1; |
|
+ } |
|
+ |
|
+ abbrev = read_abbrev (dso, |
|
+ debug_sections[DEBUG_ABBREV].data + value); |
|
+ if (abbrev == NULL) |
|
+ return 1; |
|
+ |
|
+ while (ptr < endcu) |
|
+ { |
|
+ tag.entry = read_uleb128 (ptr); |
|
+ if (tag.entry == 0) |
|
+ continue; |
|
+ t = htab_find_with_hash (abbrev, &tag, tag.entry); |
|
+ if (t == NULL) |
|
+ { |
|
+ error (0, 0, "%s: Could not find DWARF abbreviation %d", |
|
+ dso->filename, tag.entry); |
|
+ htab_delete (abbrev); |
|
+ return 1; |
|
+ } |
|
+ |
|
+ ptr = edit_attributes (dso, ptr, t, phase); |
|
+ if (ptr == NULL) |
|
+ break; |
|
+ } |
|
+ |
|
+ htab_delete (abbrev); |
|
+ } |
|
+ |
|
+ return 0; |
|
+} |
|
+ |
|
static int |
|
edit_dwarf2 (DSO *dso) |
|
{ |
|
@@ -2100,385 +2200,299 @@ edit_dwarf2 (DSO *dso) |
|
return 1; |
|
} |
|
|
|
- if (debug_sections[DEBUG_INFO].data != NULL) |
|
+ if (debug_sections[DEBUG_INFO].data == NULL) |
|
+ return 0; |
|
+ |
|
+ unsigned char *ptr, *endcu, *endsec; |
|
+ uint32_t value; |
|
+ htab_t abbrev; |
|
+ struct abbrev_tag tag, *t; |
|
+ int phase; |
|
+ bool info_rel_updated = false; |
|
+ bool macro_rel_updated = false; |
|
+ |
|
+ for (phase = 0; phase < 2; phase++) |
|
{ |
|
- unsigned char *ptr, *endcu, *endsec; |
|
- uint32_t value; |
|
- htab_t abbrev; |
|
- struct abbrev_tag tag, *t; |
|
- int phase; |
|
- bool info_rel_updated = false; |
|
- bool macro_rel_updated = false; |
|
+ /* If we don't need to update anyhing, skip phase 1. */ |
|
+ if (phase == 1 |
|
+ && !need_strp_update |
|
+ && !need_string_replacement |
|
+ && !need_stmt_update) |
|
+ break; |
|
|
|
- for (phase = 0; phase < 2; phase++) |
|
+ rel_updated = false; |
|
+ if (edit_info (dso, phase)) |
|
+ return 1; |
|
+ |
|
+ /* Remember whether any .debug_info relocations might need |
|
+ to be updated. */ |
|
+ info_rel_updated = rel_updated; |
|
+ |
|
+ /* We might have to recalculate/rewrite the debug_line |
|
+ section. We need to do that before going into phase one |
|
+ so we have all new offsets. We do this separately from |
|
+ scanning the dirs/file names because the DW_AT_stmt_lists |
|
+ might not be in order or skip some padding we might have |
|
+ to (re)move. */ |
|
+ if (phase == 0 && need_stmt_update) |
|
{ |
|
- /* If we don't need to update anyhing, skip phase 1. */ |
|
- if (phase == 1 |
|
- && !need_strp_update |
|
- && !need_string_replacement |
|
- && !need_stmt_update) |
|
- break; |
|
+ edit_dwarf2_line (dso); |
|
|
|
- ptr = debug_sections[DEBUG_INFO].data; |
|
- setup_relbuf(dso, &debug_sections[DEBUG_INFO], &reltype); |
|
- rel_updated = false; |
|
- endsec = ptr + debug_sections[DEBUG_INFO].size; |
|
- while (ptr < endsec) |
|
+ /* The line table programs will be moved |
|
+ forward/backwards a bit in the new data. Update the |
|
+ debug_line relocations to the new offsets. */ |
|
+ int rndx = debug_sections[DEBUG_LINE].relsec; |
|
+ if (rndx != 0) |
|
{ |
|
- if (ptr + 11 > endsec) |
|
- { |
|
- error (0, 0, "%s: .debug_info CU header too small", |
|
- dso->filename); |
|
- return 1; |
|
- } |
|
- |
|
- endcu = ptr + 4; |
|
- endcu += read_32 (ptr); |
|
- if (endcu == ptr + 0xffffffff) |
|
- { |
|
- error (0, 0, "%s: 64-bit DWARF not supported", dso->filename); |
|
- return 1; |
|
- } |
|
- |
|
- if (endcu > endsec) |
|
- { |
|
- error (0, 0, "%s: .debug_info too small", dso->filename); |
|
- return 1; |
|
- } |
|
- |
|
- cu_version = read_16 (ptr); |
|
- if (cu_version != 2 && cu_version != 3 && cu_version != 4) |
|
- { |
|
- error (0, 0, "%s: DWARF version %d unhandled", dso->filename, |
|
- cu_version); |
|
- return 1; |
|
- } |
|
- |
|
- value = read_32_relocated (ptr); |
|
- if (value >= debug_sections[DEBUG_ABBREV].size) |
|
+ LINE_REL *rbuf; |
|
+ size_t rels; |
|
+ Elf_Data *rdata = elf_getdata (dso->scn[rndx], NULL); |
|
+ int rtype = dso->shdr[rndx].sh_type; |
|
+ rels = dso->shdr[rndx].sh_size / dso->shdr[rndx].sh_entsize; |
|
+ rbuf = malloc (rels * sizeof (LINE_REL)); |
|
+ if (rbuf == NULL) |
|
+ error (1, errno, "%s: Could not allocate line relocations", |
|
+ dso->filename); |
|
+ |
|
+ /* Sort them by offset into section. */ |
|
+ for (size_t i = 0; i < rels; i++) |
|
{ |
|
- if (debug_sections[DEBUG_ABBREV].data == NULL) |
|
- error (0, 0, "%s: .debug_abbrev not present", dso->filename); |
|
+ if (rtype == SHT_RELA) |
|
+ { |
|
+ GElf_Rela rela; |
|
+ if (gelf_getrela (rdata, i, &rela) == NULL) |
|
+ error (1, 0, "Couldn't get relocation: %s", |
|
+ elf_errmsg (-1)); |
|
+ rbuf[i].r_offset = rela.r_offset; |
|
+ rbuf[i].ndx = i; |
|
+ } |
|
else |
|
- error (0, 0, "%s: DWARF CU abbrev offset too large", |
|
- dso->filename); |
|
- return 1; |
|
- } |
|
- |
|
- if (ptr_size == 0) |
|
- { |
|
- ptr_size = read_8 (ptr); |
|
- if (ptr_size != 4 && ptr_size != 8) |
|
{ |
|
- error (0, 0, "%s: Invalid DWARF pointer size %d", |
|
- dso->filename, ptr_size); |
|
- return 1; |
|
+ GElf_Rel rel; |
|
+ if (gelf_getrel (rdata, i, &rel) == NULL) |
|
+ error (1, 0, "Couldn't get relocation: %s", |
|
+ elf_errmsg (-1)); |
|
+ rbuf[i].r_offset = rel.r_offset; |
|
+ rbuf[i].ndx = i; |
|
} |
|
} |
|
- else if (read_8 (ptr) != ptr_size) |
|
- { |
|
- error (0, 0, "%s: DWARF pointer size differs between CUs", |
|
- dso->filename); |
|
- return 1; |
|
- } |
|
+ qsort (rbuf, rels, sizeof (LINE_REL), line_rel_cmp); |
|
|
|
- abbrev = read_abbrev (dso, |
|
- debug_sections[DEBUG_ABBREV].data + value); |
|
- if (abbrev == NULL) |
|
- return 1; |
|
- |
|
- while (ptr < endcu) |
|
+ size_t lndx = 0; |
|
+ for (size_t i = 0; i < rels; i++) |
|
{ |
|
- tag.entry = read_uleb128 (ptr); |
|
- if (tag.entry == 0) |
|
- continue; |
|
- t = htab_find_with_hash (abbrev, &tag, tag.entry); |
|
- if (t == NULL) |
|
+ /* These relocations only happen in ET_REL files |
|
+ and are section offsets. */ |
|
+ GElf_Addr r_offset; |
|
+ size_t ndx = rbuf[i].ndx; |
|
+ |
|
+ GElf_Rel rel; |
|
+ GElf_Rela rela; |
|
+ if (rtype == SHT_RELA) |
|
{ |
|
- error (0, 0, "%s: Could not find DWARF abbreviation %d", |
|
- dso->filename, tag.entry); |
|
- htab_delete (abbrev); |
|
- return 1; |
|
+ if (gelf_getrela (rdata, ndx, &rela) == NULL) |
|
+ error (1, 0, "Couldn't get relocation: %s", |
|
+ elf_errmsg (-1)); |
|
+ r_offset = rela.r_offset; |
|
+ } |
|
+ else |
|
+ { |
|
+ if (gelf_getrel (rdata, ndx, &rel) == NULL) |
|
+ error (1, 0, "Couldn't get relocation: %s", |
|
+ elf_errmsg (-1)); |
|
+ r_offset = rel.r_offset; |
|
} |
|
|
|
- ptr = edit_attributes (dso, ptr, t, phase); |
|
- if (ptr == NULL) |
|
- break; |
|
- } |
|
+ while (lndx < dso->lines.used |
|
+ && r_offset > (dso->lines.table[lndx].old_idx |
|
+ + 4 |
|
+ + dso->lines.table[lndx].unit_length)) |
|
+ lndx++; |
|
|
|
- htab_delete (abbrev); |
|
- } |
|
+ if (lndx >= dso->lines.used) |
|
+ error (1, 0, |
|
+ ".debug_line relocation offset out of range"); |
|
|
|
- /* Remember whether any .debug_info relocations might need |
|
- to be updated. */ |
|
- info_rel_updated = rel_updated; |
|
- |
|
- /* We might have to recalculate/rewrite the debug_line |
|
- section. We need to do that before going into phase one |
|
- so we have all new offsets. We do this separately from |
|
- scanning the dirs/file names because the DW_AT_stmt_lists |
|
- might not be in order or skip some padding we might have |
|
- to (re)move. */ |
|
- if (phase == 0 && need_stmt_update) |
|
- { |
|
- edit_dwarf2_line (dso); |
|
+ /* Offset (pointing into the line program) moves |
|
+ from old to new index including the header |
|
+ size diff. */ |
|
+ r_offset += (ssize_t)((dso->lines.table[lndx].new_idx |
|
+ - dso->lines.table[lndx].old_idx) |
|
+ + dso->lines.table[lndx].size_diff); |
|
|
|
- /* The line table programs will be moved |
|
- forward/backwards a bit in the new data. Update the |
|
- debug_line relocations to the new offsets. */ |
|
- int rndx = debug_sections[DEBUG_LINE].relsec; |
|
- if (rndx != 0) |
|
- { |
|
- LINE_REL *rbuf; |
|
- size_t rels; |
|
- Elf_Data *rdata = elf_getdata (dso->scn[rndx], NULL); |
|
- int rtype = dso->shdr[rndx].sh_type; |
|
- rels = dso->shdr[rndx].sh_size / dso->shdr[rndx].sh_entsize; |
|
- rbuf = malloc (rels * sizeof (LINE_REL)); |
|
- if (rbuf == NULL) |
|
- error (1, errno, "%s: Could not allocate line relocations", |
|
- dso->filename); |
|
- |
|
- /* Sort them by offset into section. */ |
|
- for (size_t i = 0; i < rels; i++) |
|
+ if (rtype == SHT_RELA) |
|
{ |
|
- if (rtype == SHT_RELA) |
|
- { |
|
- GElf_Rela rela; |
|
- if (gelf_getrela (rdata, i, &rela) == NULL) |
|
- error (1, 0, "Couldn't get relocation: %s", |
|
- elf_errmsg (-1)); |
|
- rbuf[i].r_offset = rela.r_offset; |
|
- rbuf[i].ndx = i; |
|
- } |
|
- else |
|
- { |
|
- GElf_Rel rel; |
|
- if (gelf_getrel (rdata, i, &rel) == NULL) |
|
- error (1, 0, "Couldn't get relocation: %s", |
|
- elf_errmsg (-1)); |
|
- rbuf[i].r_offset = rel.r_offset; |
|
- rbuf[i].ndx = i; |
|
- } |
|
+ rela.r_offset = r_offset; |
|
+ if (gelf_update_rela (rdata, ndx, &rela) == 0) |
|
+ error (1, 0, "Couldn't update relocation: %s", |
|
+ elf_errmsg (-1)); |
|
} |
|
- qsort (rbuf, rels, sizeof (LINE_REL), line_rel_cmp); |
|
- |
|
- size_t lndx = 0; |
|
- for (size_t i = 0; i < rels; i++) |
|
+ else |
|
{ |
|
- /* These relocations only happen in ET_REL files |
|
- and are section offsets. */ |
|
- GElf_Addr r_offset; |
|
- size_t ndx = rbuf[i].ndx; |
|
- |
|
- GElf_Rel rel; |
|
- GElf_Rela rela; |
|
- if (rtype == SHT_RELA) |
|
- { |
|
- if (gelf_getrela (rdata, ndx, &rela) == NULL) |
|
- error (1, 0, "Couldn't get relocation: %s", |
|
- elf_errmsg (-1)); |
|
- r_offset = rela.r_offset; |
|
- } |
|
- else |
|
- { |
|
- if (gelf_getrel (rdata, ndx, &rel) == NULL) |
|
- error (1, 0, "Couldn't get relocation: %s", |
|
- elf_errmsg (-1)); |
|
- r_offset = rel.r_offset; |
|
- } |
|
- |
|
- while (lndx < dso->lines.used |
|
- && r_offset > (dso->lines.table[lndx].old_idx |
|
- + 4 |
|
- + dso->lines.table[lndx].unit_length)) |
|
- lndx++; |
|
- |
|
- if (lndx >= dso->lines.used) |
|
- error (1, 0, |
|
- ".debug_line relocation offset out of range"); |
|
- |
|
- /* Offset (pointing into the line program) moves |
|
- from old to new index including the header |
|
- size diff. */ |
|
- r_offset += (ssize_t)((dso->lines.table[lndx].new_idx |
|
- - dso->lines.table[lndx].old_idx) |
|
- + dso->lines.table[lndx].size_diff); |
|
- |
|
- if (rtype == SHT_RELA) |
|
- { |
|
- rela.r_offset = r_offset; |
|
- if (gelf_update_rela (rdata, ndx, &rela) == 0) |
|
- error (1, 0, "Couldn't update relocation: %s", |
|
- elf_errmsg (-1)); |
|
- } |
|
- else |
|
- { |
|
- rel.r_offset = r_offset; |
|
- if (gelf_update_rel (rdata, ndx, &rel) == 0) |
|
- error (1, 0, "Couldn't update relocation: %s", |
|
- elf_errmsg (-1)); |
|
- } |
|
+ rel.r_offset = r_offset; |
|
+ if (gelf_update_rel (rdata, ndx, &rel) == 0) |
|
+ error (1, 0, "Couldn't update relocation: %s", |
|
+ elf_errmsg (-1)); |
|
} |
|
- |
|
- elf_flagdata (rdata, ELF_C_SET, ELF_F_DIRTY); |
|
- free (rbuf); |
|
} |
|
+ |
|
+ elf_flagdata (rdata, ELF_C_SET, ELF_F_DIRTY); |
|
+ free (rbuf); |
|
} |
|
+ } |
|
|
|
- /* The .debug_macro section also contains offsets into the |
|
- .debug_str section and references to the .debug_line |
|
- tables, so we need to update those as well if we update |
|
- the strings or the stmts. */ |
|
- if ((need_strp_update || need_stmt_update) |
|
- && debug_sections[DEBUG_MACRO].data) |
|
+ /* The .debug_macro section also contains offsets into the |
|
+ .debug_str section and references to the .debug_line |
|
+ tables, so we need to update those as well if we update |
|
+ the strings or the stmts. */ |
|
+ if ((need_strp_update || need_stmt_update) |
|
+ && debug_sections[DEBUG_MACRO].data) |
|
+ { |
|
+ /* There might be multiple (COMDAT) .debug_macro sections. */ |
|
+ struct debug_section *macro_sec = &debug_sections[DEBUG_MACRO]; |
|
+ while (macro_sec != NULL) |
|
{ |
|
- /* There might be multiple (COMDAT) .debug_macro sections. */ |
|
- struct debug_section *macro_sec = &debug_sections[DEBUG_MACRO]; |
|
- while (macro_sec != NULL) |
|
- { |
|
- setup_relbuf(dso, macro_sec, &reltype); |
|
- rel_updated = false; |
|
+ setup_relbuf(dso, macro_sec, &reltype); |
|
+ rel_updated = false; |
|
|
|
- ptr = macro_sec->data; |
|
- endsec = ptr + macro_sec->size; |
|
- int op = 0, macro_version, macro_flags; |
|
- int offset_len = 4, line_offset = 0; |
|
+ ptr = macro_sec->data; |
|
+ endsec = ptr + macro_sec->size; |
|
+ int op = 0, macro_version, macro_flags; |
|
+ int offset_len = 4, line_offset = 0; |
|
|
|
- while (ptr < endsec) |
|
+ while (ptr < endsec) |
|
+ { |
|
+ if (!op) |
|
{ |
|
- if (!op) |
|
- { |
|
- macro_version = read_16 (ptr); |
|
- macro_flags = read_8 (ptr); |
|
- if (macro_version < 4 || macro_version > 5) |
|
- error (1, 0, "unhandled .debug_macro version: %d", |
|
- macro_version); |
|
- if ((macro_flags & ~2) != 0) |
|
- error (1, 0, "unhandled .debug_macro flags: 0x%x", |
|
- macro_flags); |
|
- |
|
- offset_len = (macro_flags & 0x01) ? 8 : 4; |
|
- line_offset = (macro_flags & 0x02) ? 1 : 0; |
|
- |
|
- if (offset_len != 4) |
|
- error (0, 1, |
|
- "Cannot handle 8 byte macro offsets: %s", |
|
- dso->filename); |
|
- |
|
- /* Update the line_offset if it is there. */ |
|
- if (line_offset) |
|
- { |
|
- if (phase == 0) |
|
- ptr += offset_len; |
|
- else |
|
- { |
|
- size_t idx, new_idx; |
|
- idx = do_read_32_relocated (ptr); |
|
- new_idx = find_new_list_offs (&dso->lines, |
|
- idx); |
|
- write_32_relocated (ptr, new_idx); |
|
- } |
|
- } |
|
- } |
|
+ macro_version = read_16 (ptr); |
|
+ macro_flags = read_8 (ptr); |
|
+ if (macro_version < 4 || macro_version > 5) |
|
+ error (1, 0, "unhandled .debug_macro version: %d", |
|
+ macro_version); |
|
+ if ((macro_flags & ~2) != 0) |
|
+ error (1, 0, "unhandled .debug_macro flags: 0x%x", |
|
+ macro_flags); |
|
+ |
|
+ offset_len = (macro_flags & 0x01) ? 8 : 4; |
|
+ line_offset = (macro_flags & 0x02) ? 1 : 0; |
|
+ |
|
+ if (offset_len != 4) |
|
+ error (0, 1, |
|
+ "Cannot handle 8 byte macro offsets: %s", |
|
+ dso->filename); |
|
|
|
- op = read_8 (ptr); |
|
- if (!op) |
|
- continue; |
|
- switch(op) |
|
+ /* Update the line_offset if it is there. */ |
|
+ if (line_offset) |
|
{ |
|
- case DW_MACRO_GNU_define: |
|
- case DW_MACRO_GNU_undef: |
|
- read_uleb128 (ptr); |
|
- ptr = ((unsigned char *) strchr ((char *) ptr, '\0') |
|
- + 1); |
|
- break; |
|
- case DW_MACRO_GNU_start_file: |
|
- read_uleb128 (ptr); |
|
- read_uleb128 (ptr); |
|
- break; |
|
- case DW_MACRO_GNU_end_file: |
|
- break; |
|
- case DW_MACRO_GNU_define_indirect: |
|
- case DW_MACRO_GNU_undef_indirect: |
|
- read_uleb128 (ptr); |
|
if (phase == 0) |
|
- { |
|
- size_t idx = read_32_relocated (ptr); |
|
- record_existing_string_entry_idx (&dso->strings, |
|
- idx); |
|
- } |
|
+ ptr += offset_len; |
|
else |
|
{ |
|
- struct stridxentry *entry; |
|
size_t idx, new_idx; |
|
idx = do_read_32_relocated (ptr); |
|
- entry = string_find_entry (&dso->strings, idx); |
|
- new_idx = strent_offset (entry->entry); |
|
+ new_idx = find_new_list_offs (&dso->lines, |
|
+ idx); |
|
write_32_relocated (ptr, new_idx); |
|
} |
|
- break; |
|
- case DW_MACRO_GNU_transparent_include: |
|
- ptr += offset_len; |
|
- break; |
|
- default: |
|
- error (1, 0, "Unhandled DW_MACRO op 0x%x", op); |
|
- break; |
|
} |
|
} |
|
|
|
- if (rel_updated) |
|
- macro_rel_updated = true; |
|
- macro_sec = macro_sec->next; |
|
+ op = read_8 (ptr); |
|
+ if (!op) |
|
+ continue; |
|
+ switch(op) |
|
+ { |
|
+ case DW_MACRO_GNU_define: |
|
+ case DW_MACRO_GNU_undef: |
|
+ read_uleb128 (ptr); |
|
+ ptr = ((unsigned char *) strchr ((char *) ptr, '\0') |
|
+ + 1); |
|
+ break; |
|
+ case DW_MACRO_GNU_start_file: |
|
+ read_uleb128 (ptr); |
|
+ read_uleb128 (ptr); |
|
+ break; |
|
+ case DW_MACRO_GNU_end_file: |
|
+ break; |
|
+ case DW_MACRO_GNU_define_indirect: |
|
+ case DW_MACRO_GNU_undef_indirect: |
|
+ read_uleb128 (ptr); |
|
+ if (phase == 0) |
|
+ { |
|
+ size_t idx = read_32_relocated (ptr); |
|
+ record_existing_string_entry_idx (&dso->strings, |
|
+ idx); |
|
+ } |
|
+ else |
|
+ { |
|
+ struct stridxentry *entry; |
|
+ size_t idx, new_idx; |
|
+ idx = do_read_32_relocated (ptr); |
|
+ entry = string_find_entry (&dso->strings, idx); |
|
+ new_idx = strent_offset (entry->entry); |
|
+ write_32_relocated (ptr, new_idx); |
|
+ } |
|
+ break; |
|
+ case DW_MACRO_GNU_transparent_include: |
|
+ ptr += offset_len; |
|
+ break; |
|
+ default: |
|
+ error (1, 0, "Unhandled DW_MACRO op 0x%x", op); |
|
+ break; |
|
+ } |
|
} |
|
- } |
|
|
|
- /* Same for the debug_str section. Make sure everything is |
|
- in place for phase 1 updating of debug_info |
|
- references. */ |
|
- if (phase == 0 && need_strp_update) |
|
- { |
|
- Strtab *strtab = dso->strings.str_tab; |
|
- Elf_Data *strdata = debug_sections[DEBUG_STR].elf_data; |
|
- int strndx = debug_sections[DEBUG_STR].sec; |
|
- Elf_Scn *strscn = dso->scn[strndx]; |
|
- |
|
- /* Out with the old. */ |
|
- strdata->d_size = 0; |
|
- /* In with the new. */ |
|
- strdata = elf_newdata (strscn); |
|
- |
|
- /* We really should check whether we had enough memory, |
|
- but the old ebl version will just abort on out of |
|
- memory... */ |
|
- strtab_finalize (strtab, strdata); |
|
- debug_sections[DEBUG_STR].size = strdata->d_size; |
|
- dso->strings.str_buf = strdata->d_buf; |
|
+ if (rel_updated) |
|
+ macro_rel_updated = true; |
|
+ macro_sec = macro_sec->next; |
|
} |
|
+ } |
|
|
|
+ /* Same for the debug_str section. Make sure everything is |
|
+ in place for phase 1 updating of debug_info |
|
+ references. */ |
|
+ if (phase == 0 && need_strp_update) |
|
+ { |
|
+ Strtab *strtab = dso->strings.str_tab; |
|
+ Elf_Data *strdata = debug_sections[DEBUG_STR].elf_data; |
|
+ int strndx = debug_sections[DEBUG_STR].sec; |
|
+ Elf_Scn *strscn = dso->scn[strndx]; |
|
+ |
|
+ /* Out with the old. */ |
|
+ strdata->d_size = 0; |
|
+ /* In with the new. */ |
|
+ strdata = elf_newdata (strscn); |
|
+ |
|
+ /* We really should check whether we had enough memory, |
|
+ but the old ebl version will just abort on out of |
|
+ memory... */ |
|
+ strtab_finalize (strtab, strdata); |
|
+ debug_sections[DEBUG_STR].size = strdata->d_size; |
|
+ dso->strings.str_buf = strdata->d_buf; |
|
} |
|
|
|
- /* After phase 1 we might have rewritten the debug_info with |
|
- new strp, strings and/or linep offsets. */ |
|
- if (need_strp_update || need_string_replacement || need_stmt_update) |
|
- dirty_section (DEBUG_INFO); |
|
- if (need_strp_update || need_stmt_update) |
|
- dirty_section (DEBUG_MACRO); |
|
- if (need_stmt_update) |
|
- dirty_section (DEBUG_LINE); |
|
+ } |
|
+ |
|
+ /* After phase 1 we might have rewritten the debug_info with |
|
+ new strp, strings and/or linep offsets. */ |
|
+ if (need_strp_update || need_string_replacement || need_stmt_update) |
|
+ dirty_section (DEBUG_INFO); |
|
+ if (need_strp_update || need_stmt_update) |
|
+ dirty_section (DEBUG_MACRO); |
|
+ if (need_stmt_update) |
|
+ dirty_section (DEBUG_LINE); |
|
|
|
- /* Update any relocations addends we might have touched. */ |
|
- if (info_rel_updated) |
|
- update_rela_data (dso, &debug_sections[DEBUG_INFO]); |
|
+ /* Update any relocations addends we might have touched. */ |
|
+ if (info_rel_updated) |
|
+ update_rela_data (dso, &debug_sections[DEBUG_INFO]); |
|
|
|
- if (macro_rel_updated) |
|
+ if (macro_rel_updated) |
|
+ { |
|
+ struct debug_section *macro_sec = &debug_sections[DEBUG_MACRO]; |
|
+ while (macro_sec != NULL) |
|
{ |
|
- struct debug_section *macro_sec = &debug_sections[DEBUG_MACRO]; |
|
- while (macro_sec != NULL) |
|
- { |
|
- update_rela_data (dso, macro_sec); |
|
- macro_sec = macro_sec->next; |
|
- } |
|
+ update_rela_data (dso, macro_sec); |
|
+ macro_sec = macro_sec->next; |
|
} |
|
} |
|
|
|
-- |
|
2.18.4 |
|
|
|
|