diff options
author | Tom Tromey <tom@tromey.com> | 2023-03-16 14:41:31 -0600 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2023-03-17 16:17:43 -0600 |
commit | 48e0f38c30a153855e1adc9dc76614f3f88d686a (patch) | |
tree | fd93b0e93df5852cd5bfcb81e7854fa418234ffb /gdb/disasm.c | |
parent | 152d9c48a29685752ce06a0248a3f0f490c5660a (diff) | |
download | gdb-48e0f38c30a153855e1adc9dc76614f3f88d686a.zip gdb-48e0f38c30a153855e1adc9dc76614f3f88d686a.tar.gz gdb-48e0f38c30a153855e1adc9dc76614f3f88d686a.tar.bz2 |
Fix line table regression
Simon pointed out a line table regression, and after a couple of false
starts, I was able to reproduce it by hand using his instructions.
The bug is that most of the code in do_mixed_source_and_assembly uses
unrelocated addresses, but one spot does:
pc = low;
... after the text offset has been removed.
This patch fixes the problem by introducing a new type to represent
unrelocated addresses in the line table. This prevents this sort of
bug to some degree (it's still possible to manipulate a CORE_ADDR in a
bad way, this is unavoidable).
However, this did let the compiler flag a few spots in that function,
and now it's not possible to compare an unrelocated address from a
line table with an ordinary CORE_ADDR.
Regression tested on x86-64 Fedora 36, though note this setup never
reproduced the bug in the first place. I also tested it by hand on
the disasm-optim test program.
Diffstat (limited to 'gdb/disasm.c')
-rw-r--r-- | gdb/disasm.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/gdb/disasm.c b/gdb/disasm.c index 71d3b97..03cd4b7 100644 --- a/gdb/disasm.c +++ b/gdb/disasm.c @@ -594,8 +594,11 @@ do_mixed_source_and_assembly_deprecated alloca (nlines * sizeof (struct deprecated_dis_line_entry)); struct objfile *objfile = symtab->compunit ()->objfile (); - low -= objfile->text_section_offset (); - high -= objfile->text_section_offset (); + + unrelocated_addr unrel_low + = unrelocated_addr (low - objfile->text_section_offset ()); + unrelocated_addr unrel_high + = unrelocated_addr (high - objfile->text_section_offset ()); /* Copy linetable entries for this function into our data structure, creating end_pc's and setting out_of_order as @@ -603,11 +606,11 @@ do_mixed_source_and_assembly_deprecated /* First, skip all the preceding functions. */ - for (i = 0; i < nlines - 1 && le[i].raw_pc () < low; i++); + for (i = 0; i < nlines - 1 && le[i].raw_pc () < unrel_low; i++); /* Now, copy all entries before the end of this function. */ - for (; i < nlines - 1 && le[i].raw_pc () < high; i++) + for (; i < nlines - 1 && le[i].raw_pc () < unrel_high; i++) { if (le[i] == le[i + 1]) continue; /* Ignore duplicates. */ @@ -627,7 +630,7 @@ do_mixed_source_and_assembly_deprecated /* If we're on the last line, and it's part of the function, then we need to get the end pc in a special way. */ - if (i == nlines - 1 && le[i].raw_pc () < high) + if (i == nlines - 1 && le[i].raw_pc () < unrel_high) { mle[newlines].line = le[i].line; mle[newlines].start_pc = le[i].pc (objfile); @@ -739,8 +742,11 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, htab_up dis_line_table (allocate_dis_line_table ()); struct objfile *objfile = main_symtab->compunit ()->objfile (); - low -= objfile->text_section_offset (); - high -= objfile->text_section_offset (); + + unrelocated_addr unrel_low + = unrelocated_addr (low - objfile->text_section_offset ()); + unrelocated_addr unrel_high + = unrelocated_addr (high - objfile->text_section_offset ()); pc = low; @@ -755,10 +761,10 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, first_le = NULL; /* Skip all the preceding functions. */ - for (i = 0; i < nlines && le[i].raw_pc () < low; i++) + for (i = 0; i < nlines && le[i].raw_pc () < unrel_low; i++) continue; - if (i < nlines && le[i].raw_pc () < high) + if (i < nlines && le[i].raw_pc () < unrel_high) first_le = &le[i]; /* Add lines for every pc value. */ |