| 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 |
| |
| |
| @@ -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 |
| |