78 lines
2.6 KiB
Diff
78 lines
2.6 KiB
Diff
|
[ Forward-ported context. ]
|
||
|
|
||
|
http://sourceware.org/ml/gdb-patches/2009-11/msg00170.html
|
||
|
Subject: [patch 03/15] PIE: breakpoint_address_match gdbarch_addr_bit workaround
|
||
|
|
||
|
Hi,
|
||
|
|
||
|
there are already multiple cases of CORE_ADDR being masked by the width of
|
||
|
gdbarch_addr_bit. This specific new case was required the PIE support.
|
||
|
|
||
|
Please read the C comment in attached patch.
|
||
|
|
||
|
Checked that CORE_ADDR math operations are present on 6000+ lines of code of
|
||
|
GDB sources which makes it impossible to do some general fix by replacing all
|
||
|
a->addr < b->addr
|
||
|
by
|
||
|
addr_less_than (a->addr, b->addr)
|
||
|
etc.
|
||
|
|
||
|
Even with this patch I think there are still many bugs left in the operation
|
||
|
of x86_64 gdb debugging i386 targets. Do you find the C++ way as a viable
|
||
|
one?
|
||
|
|
||
|
|
||
|
Thanks,
|
||
|
Jan
|
||
|
|
||
|
|
||
|
gdb/
|
||
|
* breakpoint.c (breakpoint_address_match): New variables addr_bit and
|
||
|
addr_mask, initialize it. Mask addresses by ADDR_MASK.
|
||
|
* defs.h (CORE_ADDR): Extend the comment.
|
||
|
|
||
|
--- a/gdb/breakpoint.c
|
||
|
+++ b/gdb/breakpoint.c
|
||
|
@@ -4559,9 +4559,15 @@ static int
|
||
|
breakpoint_address_match (struct address_space *aspace1, CORE_ADDR addr1,
|
||
|
struct address_space *aspace2, CORE_ADDR addr2)
|
||
|
{
|
||
|
+ int addr_bit = gdbarch_addr_bit (target_gdbarch);
|
||
|
+ CORE_ADDR addr_mask = CORE_ADDR_MAX;
|
||
|
+
|
||
|
+ if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT))
|
||
|
+ addr_mask = ((CORE_ADDR) 1 << addr_bit) - 1;
|
||
|
+
|
||
|
return ((gdbarch_has_global_breakpoints (target_gdbarch)
|
||
|
|| aspace1 == aspace2)
|
||
|
- && addr1 == addr2);
|
||
|
+ && (addr1 & addr_mask) == (addr2 & addr_mask));
|
||
|
}
|
||
|
|
||
|
/* Assuming LOC1 and LOC2's types' have meaningful target addresses
|
||
|
--- a/gdb/defs.h
|
||
|
+++ b/gdb/defs.h
|
||
|
@@ -98,7 +98,20 @@
|
||
|
/* A byte from the program being debugged. */
|
||
|
typedef bfd_byte gdb_byte;
|
||
|
|
||
|
-/* An address in the program being debugged. Host byte order. */
|
||
|
+/* An address in the program being debugged. Host byte order.
|
||
|
+
|
||
|
+ Its width is the maximum width of all the supported targets. That means
|
||
|
+ 32-bit target will run on such GDB using 64-bit CORE_ADDR cluttering the
|
||
|
+ bits 32...63 with random data from internal GDB calculations. GDB currently
|
||
|
+ in general truncates the address width only when it is being presented/used
|
||
|
+ externally (such as by the paddress function).
|
||
|
+
|
||
|
+ FIXME: This is still not right as any GDB internal comparisons (such as >=)
|
||
|
+ of CORE_ADDR do not use the properly truncated width. As converting all the
|
||
|
+ CORE_ADDR operations to width-aware functions is not feasible the way out
|
||
|
+ could be a width-aware C++ class CORE_ADDR referencing gdbarch as its
|
||
|
+ constructor parameter. */
|
||
|
+
|
||
|
typedef bfd_vma CORE_ADDR;
|
||
|
|
||
|
/* The largest CORE_ADDR value. */
|
||
|
|