* [PATCH] Make relocation reading explicit
@ 2024-05-15 20:40 Mark Wielaard
2024-05-19 13:23 ` Mark Wielaard
0 siblings, 1 reply; 2+ messages in thread
From: Mark Wielaard @ 2024-05-15 20:40 UTC (permalink / raw)
To: debugedit; +Cc: Mark Wielaard
Relocation handling used to be linear per section. But since handling
.debug_str_offsets (which can have relocations itself) we had to
"reset" the relocation handling when switching between reading
sections. This caused a lnear search from the start of the relocation
table each time section reading was switched. Since this was slow
do_read_32_relocated needed to be optimized using a binary search
(commit fbad879eb).
Since we do a binary search now, resetting the relocation
datastructure isn't really needed. It is also a little confusing and
fragile. Rewrite the relocation code so it works per section and
doesn't need "switching".
Make the relocation related data structures part of struct
debug_section. And change do_read_32_relocated to take a struct
debug_section. This way we make explicit from which section we are
reading.
Signed-off-by: Mark Wielaard <mark@klomp.org>
---
tools/debugedit.c | 331 ++++++++++++++++++++++------------------------
1 file changed, 161 insertions(+), 170 deletions(-)
diff --git a/tools/debugedit.c b/tools/debugedit.c
index ae8e38fa58da..1a46c13dee47 100644
--- a/tools/debugedit.c
+++ b/tools/debugedit.c
@@ -1,5 +1,5 @@
/* Copyright (C) 2001-2003, 2005, 2007, 2009-2011, 2016, 2017 Red Hat, Inc.
- Copyright (C) 2022, 2023 Mark J. Wielaard <mark@klomp.org>
+ Copyright (C) 2022, 2023, 2024 Mark J. Wielaard <mark@klomp.org>
Written by Alexander Larsson <alexl@redhat.com>, 2002
Based on code by Jakub Jelinek <jakub@redhat.com>, 2001.
String/Line table rewriting by Mark Wielaard <mjw@redhat.com>, 2017.
@@ -204,6 +204,77 @@ typedef struct
GElf_Shdr shdr[0];
} DSO;
+typedef struct
+{
+ unsigned char *ptr;
+ uint32_t addend;
+ int ndx;
+} REL;
+
+typedef struct
+{
+ Elf64_Addr r_offset;
+ int ndx;
+} LINE_REL;
+
+typedef struct debug_section
+ {
+ const char *name;
+ unsigned char *data;
+ Elf_Data *elf_data;
+ size_t size;
+ int sec, relsec;
+ int reltype;
+ REL *relbuf;
+ REL *relend;
+ bool rel_updated;
+ /* Only happens for COMDAT .debug_macro and .debug_types. */
+ struct debug_section *next;
+ } debug_section;
+
+static debug_section debug_sections[] =
+ {
+#define DEBUG_INFO 0
+#define DEBUG_ABBREV 1
+#define DEBUG_LINE 2
+#define DEBUG_ARANGES 3
+#define DEBUG_PUBNAMES 4
+#define DEBUG_PUBTYPES 5
+#define DEBUG_MACINFO 6
+#define DEBUG_LOC 7
+#define DEBUG_STR 8
+#define DEBUG_FRAME 9
+#define DEBUG_RANGES 10
+#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", },
+ { ".debug_abbrev", },
+ { ".debug_line", },
+ { ".debug_aranges", },
+ { ".debug_pubnames", },
+ { ".debug_pubtypes", },
+ { ".debug_macinfo", },
+ { ".debug_loc", },
+ { ".debug_str", },
+ { ".debug_frame", },
+ { ".debug_ranges", },
+ { ".debug_types", },
+ { ".debug_macro", },
+ { ".debug_gdb_scripts", },
+ { ".debug_rnglists", },
+ { ".debug_line_str", },
+ { ".debug_addr", },
+ { ".debug_str_offsets", },
+ { ".debug_loclists", },
+ { NULL, }
+ };
+
static void
setup_lines (struct debug_lines *lines)
{
@@ -221,19 +292,6 @@ destroy_lines (struct debug_lines *lines)
free (lines->line_buf);
}
-typedef struct
-{
- unsigned char *ptr;
- uint32_t addend;
- int ndx;
-} REL;
-
-typedef struct
-{
- Elf64_Addr r_offset;
- int ndx;
-} LINE_REL;
-
#define read_uleb128(ptr) ({ \
unsigned int ret = 0; \
unsigned int c; \
@@ -332,12 +390,18 @@ strptr (DSO *dso, size_t sec, size_t offset)
ret; \
})
-REL *relptr, *relend;
-int reltype;
+/* Used for do_write_32_relocated, which can only be called
+ immediately following do_read_32_relocated. */
+REL *last_relptr;
+REL *last_relend;
+int last_reltype;
+struct debug_section *last_sec;
static inline REL *
-find_rel_for_ptr (unsigned char *xptr)
+find_rel_for_ptr (unsigned char *xptr, struct debug_section *sec)
{
+ REL *relptr = sec->relbuf;
+ REL *relend = sec->relend;
size_t l = 0, r = relend - relptr;
while (l < r)
{
@@ -352,11 +416,14 @@ find_rel_for_ptr (unsigned char *xptr)
return relend;
}
-#define do_read_32_relocated(xptr) ({ \
+#define do_read_32_relocated(xptr, xsec) ({ \
uint32_t dret = do_read_32 (xptr); \
+ REL *relptr = xsec->relbuf; \
+ REL *relend = xsec->relend; \
+ int reltype = xsec->reltype; \
if (relptr) \
{ \
- relptr = find_rel_for_ptr (xptr); \
+ relptr = find_rel_for_ptr (xptr, xsec); \
if (relptr < relend && relptr->ptr == (xptr)) \
{ \
if (reltype == SHT_REL) \
@@ -365,11 +432,15 @@ find_rel_for_ptr (unsigned char *xptr)
dret = relptr->addend; \
} \
} \
+ last_relptr = relptr; \
+ last_relend = relend; \
+ last_reltype = reltype; \
+ last_sec = xsec; \
dret; \
})
-#define read_32_relocated(ptr) ({ \
- uint32_t ret = do_read_32_relocated (ptr); \
+#define read_32_relocated(ptr,sec) ({ \
+ uint32_t ret = do_read_32_relocated (ptr,sec); \
ptr += 4; \
ret; \
})
@@ -425,17 +496,16 @@ dwarf2_write_be32 (unsigned char *p, uint32_t v)
relend). Might just update the addend. So relocations need to be
updated at the end. */
-static bool rel_updated;
-
-#define do_write_32_relocated(ptr,val) ({ \
- if (relptr && relptr < relend && relptr->ptr == ptr) \
+#define do_write_32_relocated(ptr,val) ({ \
+ if (last_relptr && last_relptr < last_relend \
+ && last_relptr->ptr == ptr) \
{ \
- if (reltype == SHT_REL) \
- do_write_32 (ptr, val - relptr->addend); \
+ if (last_reltype == SHT_REL) \
+ do_write_32 (ptr, val - last_relptr->addend); \
else \
{ \
- relptr->addend = val; \
- rel_updated = true; \
+ last_relptr->addend = val; \
+ last_sec->rel_updated = true; \
} \
} \
else \
@@ -447,62 +517,6 @@ static bool rel_updated;
ptr += 4; \
})
-typedef struct debug_section
- {
- const char *name;
- unsigned char *data;
- Elf_Data *elf_data;
- size_t size;
- int sec, relsec;
- REL *relbuf;
- REL *relend;
- /* Only happens for COMDAT .debug_macro and .debug_types. */
- struct debug_section *next;
- } debug_section;
-
-static debug_section debug_sections[] =
- {
-#define DEBUG_INFO 0
-#define DEBUG_ABBREV 1
-#define DEBUG_LINE 2
-#define DEBUG_ARANGES 3
-#define DEBUG_PUBNAMES 4
-#define DEBUG_PUBTYPES 5
-#define DEBUG_MACINFO 6
-#define DEBUG_LOC 7
-#define DEBUG_STR 8
-#define DEBUG_FRAME 9
-#define DEBUG_RANGES 10
-#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 },
- { ".debug_aranges", NULL, NULL, 0, 0, 0 },
- { ".debug_pubnames", NULL, NULL, 0, 0, 0 },
- { ".debug_pubtypes", NULL, NULL, 0, 0, 0 },
- { ".debug_macinfo", NULL, NULL, 0, 0, 0 },
- { ".debug_loc", NULL, NULL, 0, 0, 0 },
- { ".debug_str", NULL, NULL, 0, 0, 0 },
- { ".debug_frame", NULL, NULL, 0, 0, 0 },
- { ".debug_ranges", NULL, NULL, 0, 0, 0 },
- { ".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 }
- };
-
static int
rel_cmp (const void *a, const void *b)
{
@@ -521,7 +535,7 @@ rel_cmp (const void *a, const void *b)
for this section. When there are relocations, will setup relend,
as the last REL, and reltype, as SHT_REL or SHT_RELA. */
static void
-setup_relbuf (DSO *dso, debug_section *sec, int *reltype)
+setup_relbuf (DSO *dso, debug_section *sec)
{
int ndx, maxndx;
GElf_Rel rel;
@@ -531,6 +545,7 @@ setup_relbuf (DSO *dso, debug_section *sec, int *reltype)
Elf_Data *symdata = NULL;
int rtype;
REL *relbuf;
+ REL *relend;
Elf_Scn *scn;
Elf_Data *data;
int i = sec->relsec;
@@ -538,8 +553,10 @@ setup_relbuf (DSO *dso, debug_section *sec, int *reltype)
/* No relocations, or did we do this already? */
if (i == 0 || sec->relbuf != NULL)
{
- relptr = sec->relbuf;
- relend = sec->relend;
+ last_relptr = NULL;
+ last_relend = NULL;
+ last_reltype = 0;
+ last_sec = NULL;
return;
}
@@ -551,7 +568,7 @@ setup_relbuf (DSO *dso, debug_section *sec, int *reltype)
assert (data->d_size == dso->shdr[i].sh_size);
maxndx = dso->shdr[i].sh_size / dso->shdr[i].sh_entsize;
relbuf = malloc (maxndx * sizeof (REL));
- *reltype = dso->shdr[i].sh_type;
+ sec->reltype = dso->shdr[i].sh_type;
if (relbuf == NULL)
error (1, errno, "%s: Could not allocate memory", dso->filename);
@@ -675,7 +692,7 @@ setup_relbuf (DSO *dso, debug_section *sec, int *reltype)
sec->relbuf = relbuf;
sec->relend = relend;
- relptr = relbuf;
+ last_relptr = NULL;
}
/* Updates SHT_RELA section associated with the given section based on
@@ -689,8 +706,8 @@ update_rela_data (DSO *dso, struct debug_section *sec)
symdata = elf_getdata (dso->scn[dso->shdr[relsec_ndx].sh_link],
NULL);
- relptr = sec->relbuf;
- relend = sec->relend;
+ REL *relptr = sec->relbuf;
+ REL *relend = sec->relend;
while (relptr < relend)
{
GElf_Sym sym;
@@ -726,14 +743,15 @@ do_read_uleb128 (unsigned char *ptr)
}
static inline uint32_t
-do_read_str_form_relocated (DSO *dso, uint32_t form, unsigned char *ptr)
+do_read_str_form_relocated (DSO *dso, uint32_t form, unsigned char *ptr,
+ struct debug_section *sec)
{
uint32_t idx;
switch (form)
{
case DW_FORM_strp:
case DW_FORM_line_strp:
- return do_read_32_relocated (ptr);
+ return do_read_32_relocated (ptr, sec);
case DW_FORM_strx1:
idx = *ptr;
@@ -759,15 +777,11 @@ do_read_str_form_relocated (DSO *dso, uint32_t form, unsigned char *ptr)
str_off_ptr += str_offsets_base;
str_off_ptr += idx * 4;
- /* Switch rel reading... */
- REL *old_relptr = relptr;
- REL *old_relend = relend;
- setup_relbuf(dso, &debug_sections[DEBUG_STR_OFFSETS], &reltype);
+ struct debug_section *str_offsets_sec = &debug_sections[DEBUG_STR_OFFSETS];
+ setup_relbuf(dso, str_offsets_sec);
- uint32_t str_off = do_read_32_relocated (str_off_ptr);
+ uint32_t str_off = do_read_32_relocated (str_off_ptr, str_offsets_sec);
- relptr = old_relptr;
- relend = old_relend;
return str_off;
}
@@ -1616,7 +1630,7 @@ edit_dwarf2_line (DSO *dso)
Also handles DW_FORM_strx, but just for recording the (indexed) string. */
static void
edit_strp (DSO *dso, uint32_t form, unsigned char *ptr, int phase,
- bool handled_strp)
+ bool handled_strp, struct debug_section *sec)
{
unsigned char *ptr_orig = ptr;
@@ -1630,7 +1644,7 @@ edit_strp (DSO *dso, uint32_t form, unsigned char *ptr, int phase,
recorded. */
if (! handled_strp)
{
- size_t idx = do_read_str_form_relocated (dso, form, ptr);
+ size_t idx = do_read_str_form_relocated (dso, form, ptr, sec);
record_existing_string_entry_idx (form == DW_FORM_line_strp,
dso, idx);
}
@@ -1644,7 +1658,7 @@ edit_strp (DSO *dso, uint32_t form, unsigned char *ptr, int phase,
size_t idx, new_idx;
struct strings *strings = (form == DW_FORM_line_strp
? &dso->debug_line_str : &dso->debug_str);
- idx = do_read_32_relocated (ptr);
+ idx = do_read_32_relocated (ptr, sec);
entry = string_find_entry (strings, idx);
new_idx = strent_offset (entry->entry);
do_write_32_relocated (ptr, new_idx);
@@ -1955,7 +1969,8 @@ read_dwarf5_line_entries (DSO *dso, unsigned char **ptrp,
case DW_FORM_line_strp:
if (phase == 0)
{
- size_t idx = do_read_32_relocated (*ptrp);
+ debug_section *debug_sec = &debug_sections[DEBUG_LINE];
+ size_t idx = do_read_32_relocated (*ptrp, debug_sec);
if (dest_dir)
{
if (record_file_string_entry_idx (line_strp, dso,
@@ -2025,7 +2040,8 @@ read_dwarf5_line_entries (DSO *dso, unsigned char **ptrp,
/* Note we don't expect DW_FORM_strx in the line table. */
case DW_FORM_strp:
case DW_FORM_line_strp:
- edit_strp (dso, form, *ptrp, phase, handled_strp);
+ edit_strp (dso, form, *ptrp, phase, handled_strp,
+ &debug_sections[DEBUG_LINE]);
break;
}
@@ -2208,10 +2224,11 @@ find_new_list_offs (struct debug_lines *lines, size_t idx)
/* Read DW_FORM_strp or DW_FORM_line_strp collecting compilation directory. */
static void
edit_attributes_str_comp_dir (uint32_t form, DSO *dso, unsigned char **ptrp,
- int phase, char **comp_dirp, bool *handled_strpp)
+ int phase, char **comp_dirp, bool *handled_strpp,
+ struct debug_section *debug_sec)
{
const char *dir;
- size_t idx = do_read_str_form_relocated (dso, form, *ptrp);
+ size_t idx = do_read_str_form_relocated (dso, form, *ptrp, debug_sec);
bool line_strp = form == DW_FORM_line_strp;
/* In phase zero we collect the comp_dir. */
if (phase == 0)
@@ -2245,7 +2262,8 @@ edit_attributes_str_comp_dir (uint32_t form, DSO *dso, unsigned char **ptrp,
abbrev data is consumed. In phase zero data is collected, in phase one
data might be replaced/updated. */
static unsigned char *
-edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
+edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase,
+ struct debug_section *debug_sec)
{
int i;
uint32_t list_offs;
@@ -2274,13 +2292,13 @@ edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
if (form == DW_FORM_data4
|| form == DW_FORM_sec_offset)
{
- list_offs = do_read_32_relocated (ptr);
+ list_offs = do_read_32_relocated (ptr, debug_sec);
if (phase == 0)
found_list_offs = 1;
else if (need_stmt_update) /* phase one */
{
size_t idx, new_idx;
- idx = do_read_32_relocated (ptr);
+ idx = do_read_32_relocated (ptr, debug_sec);
new_idx = find_new_list_offs (&dso->lines, idx);
do_write_32_relocated (ptr, new_idx);
}
@@ -2352,7 +2370,7 @@ edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
|| form == DW_FORM_strx4)
edit_attributes_str_comp_dir (form, dso,
&ptr, phase, &comp_dir,
- &handled_strp);
+ &handled_strp, debug_sec);
}
else if ((t->tag == DW_TAG_compile_unit
|| t->tag == DW_TAG_partial_unit)
@@ -2374,7 +2392,8 @@ edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
unit. If starting with / it is a full path name.
Note that we don't handle DW_FORM_string in this
case. */
- size_t idx = do_read_str_form_relocated (dso, form, ptr);
+ size_t idx = do_read_str_form_relocated (dso, form, ptr,
+ debug_sec);
/* In phase zero we will look for a comp_dir to use. */
if (phase == 0)
@@ -2427,7 +2446,7 @@ edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
case DW_FORM_strx2:
case DW_FORM_strx3:
case DW_FORM_strx4:
- edit_strp (dso, form, ptr, phase, handled_strp);
+ edit_strp (dso, form, ptr, phase, handled_strp, debug_sec);
break;
}
@@ -2521,7 +2540,7 @@ edit_info (DSO *dso, int phase, struct debug_section *sec)
if (ptr == NULL)
return 0;
- setup_relbuf(dso, sec, &reltype);
+ setup_relbuf(dso, sec);
endsec = ptr + sec->size;
while (ptr < endsec)
{
@@ -2580,7 +2599,7 @@ edit_info (DSO *dso, int phase, struct debug_section *sec)
return 1;
}
- value = read_32_relocated (ptr);
+ value = read_32_relocated (ptr, sec);
if (value >= debug_sections[DEBUG_ABBREV].size)
{
if (debug_sections[DEBUG_ABBREV].data == NULL)
@@ -2643,23 +2662,19 @@ edit_info (DSO *dso, int phase, struct debug_section *sec)
{
uint32_t form;
unsigned char *fptr = ptr;
- // We will read this DIE again, save and reset rel reading
- REL *old_relptr = relptr;
for (i = 0; i < t->nattr; ++i)
{
form = t->attr[i].form;
if (t->attr[i].attr == DW_AT_str_offsets_base)
{
- str_offsets_base = do_read_32_relocated (fptr);
+ str_offsets_base = do_read_32_relocated (fptr, sec);
break;
}
skip_form (dso, &form, &fptr);
}
- // Reset the rel reading...
- relptr = old_relptr;
}
}
- ptr = edit_attributes (dso, ptr, t, phase);
+ ptr = edit_attributes (dso, ptr, t, phase, sec);
if (ptr == NULL)
break;
}
@@ -2696,8 +2711,9 @@ edit_dwarf2_any_str (DSO *dso, struct strings *strings, debug_section *secp)
static void
update_str_offsets (DSO *dso)
{
- unsigned char *ptr = debug_sections[DEBUG_STR_OFFSETS].data;
- unsigned char *endp = ptr + debug_sections[DEBUG_STR_OFFSETS].size;
+ struct debug_section *str_off_sec = &debug_sections[DEBUG_STR_OFFSETS];
+ unsigned char *ptr = str_off_sec->data;
+ unsigned char *endp = ptr + str_off_sec->size;
while (ptr < endp)
{
@@ -2719,7 +2735,7 @@ update_str_offsets (DSO *dso)
{
struct stridxentry *entry;
size_t idx, new_idx;
- idx = do_read_32_relocated (ptr);
+ idx = do_read_32_relocated (ptr, str_off_sec);
entry = string_find_entry (&dso->debug_str, idx);
new_idx = strent_offset (entry->entry);
write_32_relocated (ptr, new_idx);
@@ -2872,11 +2888,6 @@ edit_dwarf2 (DSO *dso)
unsigned char *ptr, *endsec;
int phase;
- bool info_rel_updated = false;
- bool types_rel_updated = false;
- bool macro_rel_updated = false;
- bool line_rel_updated = false;
-
for (phase = 0; phase < 2; phase++)
{
/* If we don't need to update anyhing, skip phase 1. */
@@ -2887,15 +2898,9 @@ edit_dwarf2 (DSO *dso)
&& !need_stmt_update)
break;
- rel_updated = false;
if (edit_info (dso, phase, &debug_sections[DEBUG_INFO]))
return 1;
- /* Remember whether any .debug_info relocations might need
- to be updated. */
- info_rel_updated = rel_updated;
-
- rel_updated = false;
struct debug_section *types_sec = &debug_sections[DEBUG_TYPES];
while (types_sec != NULL)
{
@@ -2904,10 +2909,6 @@ edit_dwarf2 (DSO *dso)
types_sec = types_sec->next;
}
- /* Remember whether any .debug_types relocations might need
- to be updated. */
- types_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
@@ -3032,8 +3033,7 @@ edit_dwarf2 (DSO *dso)
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);
ptr = macro_sec->data;
endsec = ptr + macro_sec->size;
@@ -3069,7 +3069,7 @@ edit_dwarf2 (DSO *dso)
else
{
size_t idx, new_idx;
- idx = do_read_32_relocated (ptr);
+ idx = do_read_32_relocated (ptr, macro_sec);
new_idx = find_new_list_offs (&dso->lines,
idx);
write_32_relocated (ptr, new_idx);
@@ -3099,14 +3099,14 @@ edit_dwarf2 (DSO *dso)
read_uleb128 (ptr);
if (phase == 0)
{
- size_t idx = read_32_relocated (ptr);
+ size_t idx = read_32_relocated (ptr, macro_sec);
record_existing_string_entry_idx (false, dso, idx);
}
else
{
struct stridxentry *entry;
size_t idx, new_idx;
- idx = do_read_32_relocated (ptr);
+ idx = do_read_32_relocated (ptr, macro_sec);
entry = string_find_entry (&dso->debug_str, idx);
new_idx = strent_offset (entry->entry);
write_32_relocated (ptr, new_idx);
@@ -3121,8 +3121,6 @@ edit_dwarf2 (DSO *dso)
}
}
- if (rel_updated)
- macro_rel_updated = true;
macro_sec = macro_sec->next;
}
}
@@ -3130,8 +3128,7 @@ edit_dwarf2 (DSO *dso)
/* Now handle all the DWARF5 line tables, they contain strp
and/or line_strp entries that need to be registered/rewritten. */
- setup_relbuf(dso, &debug_sections[DEBUG_LINE], &reltype);
- rel_updated = false;
+ setup_relbuf(dso, &debug_sections[DEBUG_LINE]);
/* edit_dwarf2_line will have set this up, unless there are no
moved/resized (DWARF4) lines. In which case we can just use
@@ -3146,8 +3143,6 @@ edit_dwarf2 (DSO *dso)
if (t->version >= 5)
read_dwarf5_line (dso, line_buf + t->new_idx, t, phase);
}
- if (rel_updated)
- line_rel_updated = true;
/* Same for the debug_str and debug_line_str sections.
Make sure everything is in place for phase 1 updating of debug_info
@@ -3174,38 +3169,34 @@ edit_dwarf2 (DSO *dso)
dirty_section (DEBUG_LINE);
if (need_strp_update && debug_sections[DEBUG_STR_OFFSETS].data != NULL)
{
- setup_relbuf(dso, &debug_sections[DEBUG_STR_OFFSETS], &reltype);
- rel_updated = false;
+ setup_relbuf(dso, &debug_sections[DEBUG_STR_OFFSETS]);
update_str_offsets (dso);
dirty_section (DEBUG_STR_OFFSETS);
- if (rel_updated)
+ if (debug_sections[DEBUG_STR_OFFSETS].rel_updated)
update_rela_data (dso, &debug_sections[DEBUG_STR_OFFSETS]);
}
/* Update any relocations addends we might have touched. */
- if (info_rel_updated)
+ if (debug_sections[DEBUG_INFO].rel_updated)
update_rela_data (dso, &debug_sections[DEBUG_INFO]);
- if (types_rel_updated)
+
+ struct debug_section *types_sec = &debug_sections[DEBUG_TYPES];
+ while (types_sec != NULL)
{
- struct debug_section *types_sec = &debug_sections[DEBUG_TYPES];
- while (types_sec != NULL)
- {
- update_rela_data (dso, types_sec);
- types_sec = types_sec->next;
- }
+ if (types_sec->rel_updated)
+ update_rela_data (dso, types_sec);
+ types_sec = types_sec->next;
}
- 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;
- }
+ if (macro_sec->rel_updated)
+ update_rela_data (dso, macro_sec);
+ macro_sec = macro_sec->next;
}
- if (line_rel_updated)
+ if (debug_sections[DEBUG_LINE].rel_updated)
update_rela_data (dso, &debug_sections[DEBUG_LINE]);
return 0;
--
2.39.3
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] Make relocation reading explicit
2024-05-15 20:40 [PATCH] Make relocation reading explicit Mark Wielaard
@ 2024-05-19 13:23 ` Mark Wielaard
0 siblings, 0 replies; 2+ messages in thread
From: Mark Wielaard @ 2024-05-19 13:23 UTC (permalink / raw)
To: debugedit
Hi,
On Wed, May 15, 2024 at 10:40:12PM +0200, Mark Wielaard wrote:
> Relocation handling used to be linear per section. But since handling
> .debug_str_offsets (which can have relocations itself) we had to
> "reset" the relocation handling when switching between reading
> sections. This caused a lnear search from the start of the relocation
> table each time section reading was switched. Since this was slow
> do_read_32_relocated needed to be optimized using a binary search
> (commit fbad879eb).
>
> Since we do a binary search now, resetting the relocation
> datastructure isn't really needed. It is also a little confusing and
> fragile. Rewrite the relocation code so it works per section and
> doesn't need "switching".
>
> Make the relocation related data structures part of struct
> debug_section. And change do_read_32_relocated to take a struct
> debug_section. This way we make explicit from which section we are
> reading.
I pushed this to main.
Cheers,
Mark
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2024-05-19 13:23 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-05-15 20:40 [PATCH] Make relocation reading explicit Mark Wielaard
2024-05-19 13:23 ` Mark Wielaard
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).