* RFC/PATCH multi-arch SMASH_TEXT_ADDRESS
@ 2002-02-02 10:00 Richard Earnshaw
2002-02-02 13:48 ` Andrew Cagney
0 siblings, 1 reply; 4+ messages in thread
From: Richard Earnshaw @ 2002-02-02 10:00 UTC (permalink / raw)
To: gdb-patches; +Cc: Richard.Earnshaw
[-- Attachment #1: Type: text/plain, Size: 846 bytes --]
This is the first time I've multi-arched a macro, so I'd be grateful if
someone who has done all this before could give this patch a quick
once-over to ensure I've not done anything stupid.
R.
<date> Richard Earnshaw <rearnsha@arm.com>
* gdbarch.h (SMASH_TEXT_ADDRESS): Add multi-arch defines.
* gdbarch.sh (SMASH_TEXT_ADDRESS): Add rule.
* gdbarch.c (struct gdbarch): Add entry for it.
(startup_gdbarch): Likewise.
(gdbarch_alloc): Default it.
(verify_gdbarch): Skip verify of it.
(gdbarch_dump): Dump it.
(gdbarch_smash_text_address): New function.
* coffread.c: Multi-arch uses of SMASH_TEXT_ADDRESS.
* dbxread.c: Likewise.
* dwarfread.c: Likewise.
* elfread.c: Likewise.
* somread.c: Likewise.
* arm-tdep.c (arm_smash_text_address): New function.
* config/arm/tm-arm.h (SMASH_TEXT_ADDRESS): Define in terms of above.
[-- Attachment #2: gdb-smash.patch --]
[-- Type: text/x-patch , Size: 16185 bytes --]
Index: arm-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/arm-tdep.c,v
retrieving revision 1.31
diff -p -r1.31 arm-tdep.c
*** arm-tdep.c 2002/02/01 13:39:41 1.31
--- arm-tdep.c 2002/02/02 17:08:31
*************** arm_pc_is_thumb_dummy (CORE_ADDR memaddr
*** 282,287 ****
--- 282,288 ----
return 0;
}
+ /* Remove useless bits from addresses in a running program. */
CORE_ADDR
arm_addr_bits_remove (CORE_ADDR val)
{
*************** arm_addr_bits_remove (CORE_ADDR val)
*** 289,294 ****
--- 290,303 ----
return (val & (arm_apcs_32 ? 0xfffffffe : 0x03fffffe));
else
return (val & (arm_apcs_32 ? 0xfffffffc : 0x03fffffc));
+ }
+
+ /* When reading symbols, we need to zap the low bit of the address,
+ which may be set to 1 for Thumb functions. */
+ CORE_ADDR
+ arm_smash_text_address (CORE_ADDR val)
+ {
+ return val & ~1;
}
CORE_ADDR
Index: coffread.c
===================================================================
RCS file: /cvs/src/src/gdb/coffread.c,v
retrieving revision 1.23
diff -p -r1.23 coffread.c
*** coffread.c 2002/02/02 03:42:58 1.23
--- coffread.c 2002/02/02 17:08:31
*************** coff_symtab_read (long symtab_offset, un
*** 944,953 ****
cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXTFUNC
|| cs->c_sclass == C_THUMBEXT ?
mst_text : mst_file_text;
! #ifdef SMASH_TEXT_ADDRESS
! if (tmpaddr & 1) /* FIXME: delete this line */
! SMASH_TEXT_ADDRESS (tmpaddr);
! #endif
}
else if (sec == SECT_OFF_DATA (objfile))
{
--- 944,950 ----
cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXTFUNC
|| cs->c_sclass == C_THUMBEXT ?
mst_text : mst_file_text;
! tmpaddr = SMASH_TEXT_ADDRESS (tmpaddr);
}
else if (sec == SECT_OFF_DATA (objfile))
{
Index: dbxread.c
===================================================================
RCS file: /cvs/src/src/gdb/dbxread.c,v
retrieving revision 1.28
diff -p -r1.28 dbxread.c
*** dbxread.c 2001/12/02 22:38:23 1.28
--- dbxread.c 2002/02/02 17:08:31
*************** process_one_symbol (int type, int desc,
*** 2759,2767 ****
/* Relocate for dynamic loading */
valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
! #ifdef SMASH_TEXT_ADDRESS
! SMASH_TEXT_ADDRESS (valu);
! #endif
goto define_a_symbol;
case N_LBRAC:
--- 2759,2765 ----
/* Relocate for dynamic loading */
valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
! valu = SMASH_TEXT_ADDRESS (valu);
goto define_a_symbol;
case N_LBRAC:
Index: dwarfread.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarfread.c,v
retrieving revision 1.12
diff -p -r1.12 dwarfread.c
*** dwarfread.c 2002/02/02 02:28:40 1.12
--- dwarfread.c 2002/02/02 17:08:32
*************** process_dies (char *thisdie, char *enddi
*** 1952,1962 ****
{
nextdie = thisdie + di.die_length;
}
- #ifdef SMASH_TEXT_ADDRESS
/* I think that these are always text, not data, addresses. */
! SMASH_TEXT_ADDRESS (di.at_low_pc);
! SMASH_TEXT_ADDRESS (di.at_high_pc);
! #endif
switch (di.die_tag)
{
case TAG_compile_unit:
--- 1952,1960 ----
{
nextdie = thisdie + di.die_length;
}
/* I think that these are always text, not data, addresses. */
! di.at_low_pc = SMASH_TEXT_ADDRESS (di.at_low_pc);
! di.at_high_pc = SMASH_TEXT_ADDRESS (di.at_high_pc);
switch (di.die_tag)
{
case TAG_compile_unit:
Index: elfread.c
===================================================================
RCS file: /cvs/src/src/gdb/elfread.c,v
retrieving revision 1.18
diff -p -r1.18 elfread.c
*** elfread.c 2001/12/07 12:10:15 1.18
--- elfread.c 2002/02/02 17:08:32
*************** record_minimal_symbol_and_info (char *na
*** 173,182 ****
enum minimal_symbol_type ms_type, char *info, /* FIXME, is this really char *? */
asection *bfd_section, struct objfile *objfile)
{
- #ifdef SMASH_TEXT_ADDRESS
if (ms_type == mst_text || ms_type == mst_file_text)
! SMASH_TEXT_ADDRESS (address);
! #endif
return prim_record_minimal_symbol_and_info
(name, address, ms_type, info, bfd_section->index, bfd_section, objfile);
--- 173,180 ----
enum minimal_symbol_type ms_type, char *info, /* FIXME, is this really char *? */
asection *bfd_section, struct objfile *objfile)
{
if (ms_type == mst_text || ms_type == mst_file_text)
! address = SMASH_TEXT_ADDRESS (address);
return prim_record_minimal_symbol_and_info
(name, address, ms_type, info, bfd_section->index, bfd_section, objfile);
Index: gdbarch.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.c,v
retrieving revision 1.100
diff -p -r1.100 gdbarch.c
*** gdbarch.c 2002/01/20 18:05:51 1.100
--- gdbarch.c 2002/02/02 17:08:32
*************** struct gdbarch
*** 250,255 ****
--- 250,256 ----
const struct floatformat * long_double_format;
gdbarch_convert_from_func_ptr_addr_ftype *convert_from_func_ptr_addr;
gdbarch_addr_bits_remove_ftype *addr_bits_remove;
+ gdbarch_smash_text_address_ftype *smash_text_address;
gdbarch_software_single_step_ftype *software_single_step;
gdbarch_print_insn_ftype *print_insn;
gdbarch_skip_trampoline_code_ftype *skip_trampoline_code;
*************** struct gdbarch startup_gdbarch =
*** 395,400 ****
--- 396,402 ----
0,
0,
0,
+ 0,
generic_in_function_epilogue_p,
construct_inferior_arguments,
0,
*************** gdbarch_alloc (const struct gdbarch_info
*** 505,510 ****
--- 507,513 ----
current_gdbarch->extra_stack_alignment_needed = 1;
current_gdbarch->convert_from_func_ptr_addr = core_addr_identity;
current_gdbarch->addr_bits_remove = core_addr_identity;
+ current_gdbarch->smash_text_address = core_addr_identity;
current_gdbarch->print_insn = legacy_print_insn;
current_gdbarch->skip_trampoline_code = generic_skip_trampoline_code;
current_gdbarch->in_solib_call_trampoline = generic_in_solib_call_trampoline;
*************** verify_gdbarch (struct gdbarch *gdbarch)
*** 757,762 ****
--- 760,766 ----
gdbarch->long_double_format = &floatformat_unknown;
/* Skip verify of convert_from_func_ptr_addr, invalid_p == 0 */
/* Skip verify of addr_bits_remove, invalid_p == 0 */
+ /* Skip verify of smash_text_address, invalid_p == 0 */
/* Skip verify of software_single_step, has predicate */
/* Skip verify of print_insn, invalid_p == 0 */
/* Skip verify of skip_trampoline_code, invalid_p == 0 */
*************** gdbarch_dump (struct gdbarch *gdbarch, s
*** 825,830 ****
--- 829,845 ----
(long) current_gdbarch->addr_bits_remove
/*ADDR_BITS_REMOVE ()*/);
#endif
+ #ifdef SMASH_TEXT_ADDRESS
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "SMASH_TEXT_ADDRESS(addr)",
+ XSTRING (SMASH_TEXT_ADDRESS (addr)));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: SMASH_TEXT_ADDRESS = 0x%08lx\n",
+ (long) current_gdbarch->smash_text_address
+ /*SMASH_TEXT_ADDRESS ()*/);
+ #endif
#ifdef BELIEVE_PCC_PROMOTION
fprintf_unfiltered (file,
"gdbarch_dump: BELIEVE_PCC_PROMOTION # %s\n",
*************** set_gdbarch_addr_bits_remove (struct gdb
*** 4213,4218 ****
--- 4228,4251 ----
gdbarch_addr_bits_remove_ftype addr_bits_remove)
{
gdbarch->addr_bits_remove = addr_bits_remove;
+ }
+
+ CORE_ADDR
+ gdbarch_smash_text_address (struct gdbarch *gdbarch, CORE_ADDR addr)
+ {
+ if (gdbarch->smash_text_address == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_smash_text_address invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_smash_text_address called\n");
+ return gdbarch->smash_text_address (addr);
+ }
+
+ void
+ set_gdbarch_smash_text_address (struct gdbarch *gdbarch,
+ gdbarch_smash_text_address_ftype smash_text_address)
+ {
+ gdbarch->smash_text_address = smash_text_address;
}
int
Index: gdbarch.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.h,v
retrieving revision 1.75
diff -p -r1.75 gdbarch.h
*** gdbarch.h 2002/01/20 19:26:48 1.75
--- gdbarch.h 2002/02/02 17:08:32
*************** extern void set_gdbarch_addr_bits_remove
*** 2040,2045 ****
--- 2040,2064 ----
#endif
#endif
+ /* It is not at all clear why SMASH_TEXT_ADDRESS is not folded into
+ ADDR_BITS_REMOVE. */
+ /* Default (function) for non- multi-arch platforms. */
+ #if (!GDB_MULTI_ARCH) && !defined (SMASH_TEXT_ADDRESS)
+ #define SMASH_TEXT_ADDRESS(addr) (core_addr_identity (addr))
+ #endif
+
+ typedef CORE_ADDR (gdbarch_smash_text_address_ftype) (CORE_ADDR addr);
+ extern CORE_ADDR gdbarch_smash_text_address (struct gdbarch *gdbarch, CORE_ADDR addr);
+ extern void set_gdbarch_smash_text_address (struct gdbarch *gdbarch, gdbarch_smash_text_address_ftype *addr_bits_remove);
+ #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SMASH_TEXT_ADDRESS)
+ #error "Non multi-arch definition of SMASH_TEXT_ADDRESS"
+ #endif
+ #if GDB_MULTI_ARCH
+ #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (SMASH_TEXT_ADDRESS)
+ #define SMASH_TEXT_ADDRESS(addr) (gdbarch_smash_text_address (current_gdbarch, addr))
+ #endif
+ #endif
+
/* FIXME/cagney/2001-01-18: This should be split in two. A target method that indicates if
the target needs software single step. An ISA method to implement it.
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.105
diff -p -r1.105 gdbarch.sh
*** gdbarch.sh 2002/01/20 19:26:48 1.105
--- gdbarch.sh 2002/02/02 17:08:33
*************** f:2:CONVERT_FROM_FUNC_PTR_ADDR:CORE_ADDR
*** 552,557 ****
--- 552,560 ----
# sort of generic thing to handle alignment or segmentation (it's
# possible it should be in TARGET_READ_PC instead).
f:2:ADDR_BITS_REMOVE:CORE_ADDR:addr_bits_remove:CORE_ADDR addr:addr:::core_addr_identity::0
+ # It is not at all clear why SMASH_TEXT_ADDRESS is not folded into
+ # ADDR_BITS_REMOVE.
+ f:2:SMASH_TEXT_ADDRESS:CORE_ADDR:smash_text_address:CORE_ADDR addr:addr:::core_addr_identity::0
# FIXME/cagney/2001-01-18: This should be split in two. A target method that indicates if
# the target needs software single step. An ISA method to implement it.
#
Index: somread.c
===================================================================
RCS file: /cvs/src/src/gdb/somread.c,v
retrieving revision 1.13
diff -p -r1.13 somread.c
*** somread.c 2002/01/08 02:09:31 1.13
--- somread.c 2002/02/02 17:08:33
*************** som_symtab_read (bfd *abfd, struct objfi
*** 157,165 ****
symname = bufp->name.n_strx + stringtab;
ms_type = mst_text;
bufp->symbol_value += text_offset;
! #ifdef SMASH_TEXT_ADDRESS
! SMASH_TEXT_ADDRESS (bufp->symbol_value);
! #endif
break;
case ST_ENTRY:
--- 157,163 ----
symname = bufp->name.n_strx + stringtab;
ms_type = mst_text;
bufp->symbol_value += text_offset;
! bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value);
break;
case ST_ENTRY:
*************** som_symtab_read (bfd *abfd, struct objfi
*** 172,189 ****
else
ms_type = mst_text;
bufp->symbol_value += text_offset;
! #ifdef SMASH_TEXT_ADDRESS
! SMASH_TEXT_ADDRESS (bufp->symbol_value);
! #endif
break;
case ST_STUB:
symname = bufp->name.n_strx + stringtab;
ms_type = mst_solib_trampoline;
bufp->symbol_value += text_offset;
! #ifdef SMASH_TEXT_ADDRESS
! SMASH_TEXT_ADDRESS (bufp->symbol_value);
! #endif
break;
case ST_DATA:
--- 170,183 ----
else
ms_type = mst_text;
bufp->symbol_value += text_offset;
! bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value);
break;
case ST_STUB:
symname = bufp->name.n_strx + stringtab;
ms_type = mst_solib_trampoline;
bufp->symbol_value += text_offset;
! bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value);
break;
case ST_DATA:
*************** som_symtab_read (bfd *abfd, struct objfi
*** 211,219 ****
symname = bufp->name.n_strx + stringtab;
ms_type = mst_file_text;
bufp->symbol_value += text_offset;
! #ifdef SMASH_TEXT_ADDRESS
! SMASH_TEXT_ADDRESS (bufp->symbol_value);
! #endif
check_strange_names:
/* Utah GCC 2.5, FSF GCC 2.6 and later generate correct local
--- 205,211 ----
symname = bufp->name.n_strx + stringtab;
ms_type = mst_file_text;
bufp->symbol_value += text_offset;
! bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value);
check_strange_names:
/* Utah GCC 2.5, FSF GCC 2.6 and later generate correct local
*************** som_symtab_read (bfd *abfd, struct objfi
*** 243,251 ****
symname = bufp->name.n_strx + stringtab;
ms_type = mst_file_text;
bufp->symbol_value += text_offset;
! #ifdef SMASH_TEXT_ADDRESS
! SMASH_TEXT_ADDRESS (bufp->symbol_value);
! #endif
break;
case ST_ENTRY:
--- 235,241 ----
symname = bufp->name.n_strx + stringtab;
ms_type = mst_file_text;
bufp->symbol_value += text_offset;
! bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value);
break;
case ST_ENTRY:
*************** som_symtab_read (bfd *abfd, struct objfi
*** 258,275 ****
else
ms_type = mst_file_text;
bufp->symbol_value += text_offset;
! #ifdef SMASH_TEXT_ADDRESS
! SMASH_TEXT_ADDRESS (bufp->symbol_value);
! #endif
break;
case ST_STUB:
symname = bufp->name.n_strx + stringtab;
ms_type = mst_solib_trampoline;
bufp->symbol_value += text_offset;
! #ifdef SMASH_TEXT_ADDRESS
! SMASH_TEXT_ADDRESS (bufp->symbol_value);
! #endif
break;
--- 248,261 ----
else
ms_type = mst_file_text;
bufp->symbol_value += text_offset;
! bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value);
break;
case ST_STUB:
symname = bufp->name.n_strx + stringtab;
ms_type = mst_solib_trampoline;
bufp->symbol_value += text_offset;
! bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value);
break;
Index: config/arm/tm-arm.h
===================================================================
RCS file: /cvs/src/src/gdb/config/arm/tm-arm.h,v
retrieving revision 1.20
diff -p -r1.20 tm-arm.h
*** tm-arm.h 2002/02/01 13:39:43 1.20
--- tm-arm.h 2002/02/02 17:08:37
*************** struct value;
*** 34,49 ****
? &floatformat_ieee_double_big \
: &floatformat_ieee_double_littlebyte_bigword)
! /* When reading symbols, we need to zap the low bit of the address,
! which may be set to 1 for Thumb functions. */
- #define SMASH_TEXT_ADDRESS(addr) ((addr) &= ~0x1)
-
- /* Remove useless bits from addresses in a running program. */
-
CORE_ADDR arm_addr_bits_remove (CORE_ADDR);
!
! #define ADDR_BITS_REMOVE(val) (arm_addr_bits_remove (val))
/* Offset from address of function to start of its code. Zero on most
machines. */
--- 34,44 ----
? &floatformat_ieee_double_big \
: &floatformat_ieee_double_littlebyte_bigword)
! CORE_ADDR arm_smash_text_address(CORE_ADDR);
! #define SMASH_TEXT_ADDRESS(ADDR) arm_smash_text_address (ADDR)
CORE_ADDR arm_addr_bits_remove (CORE_ADDR);
! #define ADDR_BITS_REMOVE(VAL) arm_addr_bits_remove (VAL)
/* Offset from address of function to start of its code. Zero on most
machines. */
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: RFC/PATCH multi-arch SMASH_TEXT_ADDRESS 2002-02-02 10:00 RFC/PATCH multi-arch SMASH_TEXT_ADDRESS Richard Earnshaw @ 2002-02-02 13:48 ` Andrew Cagney 2002-02-03 7:24 ` Richard Earnshaw 2002-02-04 3:58 ` Richard Earnshaw 0 siblings, 2 replies; 4+ messages in thread From: Andrew Cagney @ 2002-02-02 13:48 UTC (permalink / raw) To: Richard.Earnshaw; +Cc: gdb-patches > * gdbarch.h (SMASH_TEXT_ADDRESS): Add multi-arch defines. > * gdbarch.sh (SMASH_TEXT_ADDRESS): Add rule. > * gdbarch.c (struct gdbarch): Add entry for it. > (startup_gdbarch): Likewise. > (gdbarch_alloc): Default it. > (verify_gdbarch): Skip verify of it. > (gdbarch_dump): Dump it. > (gdbarch_smash_text_address): New function. > FYI, just do this: gdbarch.sh (SMASH_TEXT_ADDRESS): Add rule. gdbarch.h, gdbarch.c: Re-generate. And then in the gdb directory run: ./gdbarch.sh It will generate new-gdbarch.[hc] which you can examine/copy into place. I noticed slight differences when running this. > ! #ifdef SMASH_TEXT_ADDRESS > ! if (tmpaddr & 1) /* FIXME: delete this line */ > ! SMASH_TEXT_ADDRESS (tmpaddr); > ! #endif I would have been more conservative with this (if (SMASH_TEXT_ADDRESS_P()) ... but as you noticed there are only two definitions and they both just mask out the bottom bits - the test is probably even bogus for HP/UX. > + # It is not at all clear why SMASH_TEXT_ADDRESS is not folded into > + # ADDR_BITS_REMOVE. > + f:2:SMASH_TEXT_ADDRESS:CORE_ADDR:smash_text_address:CORE_ADDR addr:addr:::core_addr_identity::0 I agree. Suggest creating a bug report so someone (else - me?) gets to investigate further. This one was nastier then it first looked, but yes fine. Andrew ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: RFC/PATCH multi-arch SMASH_TEXT_ADDRESS 2002-02-02 13:48 ` Andrew Cagney @ 2002-02-03 7:24 ` Richard Earnshaw 2002-02-04 3:58 ` Richard Earnshaw 1 sibling, 0 replies; 4+ messages in thread From: Richard Earnshaw @ 2002-02-03 7:24 UTC (permalink / raw) To: Andrew Cagney; +Cc: Richard.Earnshaw, gdb-patches > FYI, just do this: > > gdbarch.sh (SMASH_TEXT_ADDRESS): Add rule. > gdbarch.h, gdbarch.c: Re-generate. > > And then in the gdb directory run: > > ./gdbarch.sh But that makes it too easy :-) Programming should be hard... > > It will generate new-gdbarch.[hc] which you can examine/copy into place. > I noticed slight differences when running this. > > > ! #ifdef SMASH_TEXT_ADDRESS > > ! if (tmpaddr & 1) /* FIXME: delete this line */ > > ! SMASH_TEXT_ADDRESS (tmpaddr); > > ! #endif > > > I would have been more conservative with this (if > (SMASH_TEXT_ADDRESS_P()) ... but as you noticed there are only two > definitions and they both just mask out the bottom bits - the test is > probably even bogus for HP/UX. I think the test for "& 1" was probably bogus anyway, regardless of what other ports might want to define SMASH_TEXT_ADDRESS as. Consider a port that would incorrectly smash an address with the test removed, I think that would likely mean that the macro was incorrectly implemented, or that there is a more serious problem that needs considering. Either way, it shouldn't be done as a test of a manifest constant. > > > + # It is not at all clear why SMASH_TEXT_ADDRESS is not folded into > > + # ADDR_BITS_REMOVE. > > + f:2:SMASH_TEXT_ADDRESS:CORE_ADDR:smash_text_address:CORE_ADDR addr:addr:::core_addr_identity::0 > > > I agree. Suggest creating a bug report so someone (else - me?) gets to > investigate further. Will do. > This one was nastier then it first looked, but yes fine. I bet they nearly always are... R. ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: RFC/PATCH multi-arch SMASH_TEXT_ADDRESS 2002-02-02 13:48 ` Andrew Cagney 2002-02-03 7:24 ` Richard Earnshaw @ 2002-02-04 3:58 ` Richard Earnshaw 1 sibling, 0 replies; 4+ messages in thread From: Richard Earnshaw @ 2002-02-04 3:58 UTC (permalink / raw) To: Andrew Cagney; +Cc: Richard.Earnshaw, gdb-patches [-- Attachment #1: Type: text/plain, Size: 621 bytes --] Taking into account Andrew's suggestions, here's the patch I've just committed. I've also updated the generated copyright message that gdbarch.sh produces. 2002-02-04 Richard Earnshaw <rearnsha@arm.com> * gdbarch.sh (copyright): Update years in generated header. (SMASH_TEXT_ADDRESS): Add rule. *gdbarch.h, gdbarch.c: Re-generate. * coffread.c: Multi-arch uses of SMASH_TEXT_ADDRESS. * dbxread.c: Likewise. * dwarfread.c: Likewise. * elfread.c: Likewise. * somread.c: Likewise. * arm-tdep.c (arm_smash_text_address): New function. * config/arm/tm-arm.h (SMASH_TEXT_ADDRESS): Define in terms of above. [-- Attachment #2: gdb-smash.patch --] [-- Type: text/x-patch , Size: 20938 bytes --] Index: arm-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/arm-tdep.c,v retrieving revision 1.31 diff -p -r1.31 arm-tdep.c *** arm-tdep.c 2002/02/01 13:39:41 1.31 --- arm-tdep.c 2002/02/04 11:48:30 *************** arm_pc_is_thumb_dummy (CORE_ADDR memaddr *** 282,287 **** --- 282,288 ---- return 0; } + /* Remove useless bits from addresses in a running program. */ CORE_ADDR arm_addr_bits_remove (CORE_ADDR val) { *************** arm_addr_bits_remove (CORE_ADDR val) *** 289,294 **** --- 290,303 ---- return (val & (arm_apcs_32 ? 0xfffffffe : 0x03fffffe)); else return (val & (arm_apcs_32 ? 0xfffffffc : 0x03fffffc)); + } + + /* When reading symbols, we need to zap the low bit of the address, + which may be set to 1 for Thumb functions. */ + CORE_ADDR + arm_smash_text_address (CORE_ADDR val) + { + return val & ~1; } CORE_ADDR Index: coffread.c =================================================================== RCS file: /cvs/src/src/gdb/coffread.c,v retrieving revision 1.23 diff -p -r1.23 coffread.c *** coffread.c 2002/02/02 03:42:58 1.23 --- coffread.c 2002/02/04 11:48:31 *************** *** 1,6 **** /* Read coff symbol tables and convert to internal format, for GDB. Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, ! 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu). --- 1,6 ---- /* Read coff symbol tables and convert to internal format, for GDB. Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, ! 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu). *************** coff_symtab_read (long symtab_offset, un *** 944,953 **** cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXTFUNC || cs->c_sclass == C_THUMBEXT ? mst_text : mst_file_text; ! #ifdef SMASH_TEXT_ADDRESS ! if (tmpaddr & 1) /* FIXME: delete this line */ ! SMASH_TEXT_ADDRESS (tmpaddr); ! #endif } else if (sec == SECT_OFF_DATA (objfile)) { --- 944,950 ---- cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXTFUNC || cs->c_sclass == C_THUMBEXT ? mst_text : mst_file_text; ! tmpaddr = SMASH_TEXT_ADDRESS (tmpaddr); } else if (sec == SECT_OFF_DATA (objfile)) { Index: dbxread.c =================================================================== RCS file: /cvs/src/src/gdb/dbxread.c,v retrieving revision 1.28 diff -p -r1.28 dbxread.c *** dbxread.c 2001/12/02 22:38:23 1.28 --- dbxread.c 2002/02/04 11:48:31 *************** *** 1,6 **** /* Read dbx symbol tables and convert to internal format, for GDB. Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, ! 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This file is part of GDB. --- 1,6 ---- /* Read dbx symbol tables and convert to internal format, for GDB. Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, ! 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GDB. *************** process_one_symbol (int type, int desc, *** 2759,2767 **** /* Relocate for dynamic loading */ valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile)); ! #ifdef SMASH_TEXT_ADDRESS ! SMASH_TEXT_ADDRESS (valu); ! #endif goto define_a_symbol; case N_LBRAC: --- 2759,2765 ---- /* Relocate for dynamic loading */ valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile)); ! valu = SMASH_TEXT_ADDRESS (valu); goto define_a_symbol; case N_LBRAC: Index: dwarfread.c =================================================================== RCS file: /cvs/src/src/gdb/dwarfread.c,v retrieving revision 1.12 diff -p -r1.12 dwarfread.c *** dwarfread.c 2002/02/02 02:28:40 1.12 --- dwarfread.c 2002/02/04 11:48:31 *************** *** 1,6 **** /* DWARF debugging format support for GDB. Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, ! 2001 Free Software Foundation, Inc. Written by Fred Fish at Cygnus Support. Portions based on dbxread.c, mipsread.c, coffread.c, and dwarfread.c from a Data General SVR4 gdb port. --- 1,6 ---- /* DWARF debugging format support for GDB. Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, ! 2001, 2002 Free Software Foundation, Inc. Written by Fred Fish at Cygnus Support. Portions based on dbxread.c, mipsread.c, coffread.c, and dwarfread.c from a Data General SVR4 gdb port. *************** process_dies (char *thisdie, char *enddi *** 1952,1962 **** { nextdie = thisdie + di.die_length; } - #ifdef SMASH_TEXT_ADDRESS /* I think that these are always text, not data, addresses. */ ! SMASH_TEXT_ADDRESS (di.at_low_pc); ! SMASH_TEXT_ADDRESS (di.at_high_pc); ! #endif switch (di.die_tag) { case TAG_compile_unit: --- 1952,1960 ---- { nextdie = thisdie + di.die_length; } /* I think that these are always text, not data, addresses. */ ! di.at_low_pc = SMASH_TEXT_ADDRESS (di.at_low_pc); ! di.at_high_pc = SMASH_TEXT_ADDRESS (di.at_high_pc); switch (di.die_tag) { case TAG_compile_unit: Index: elfread.c =================================================================== RCS file: /cvs/src/src/gdb/elfread.c,v retrieving revision 1.18 diff -p -r1.18 elfread.c *** elfread.c 2001/12/07 12:10:15 1.18 --- elfread.c 2002/02/04 11:48:31 *************** *** 1,6 **** /* Read ELF (Executable and Linking Format) object files for GDB. Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, ! 2001 Free Software Foundation, Inc. Written by Fred Fish at Cygnus Support. --- 1,6 ---- /* Read ELF (Executable and Linking Format) object files for GDB. Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, ! 2001, 2002 Free Software Foundation, Inc. Written by Fred Fish at Cygnus Support. *************** record_minimal_symbol_and_info (char *na *** 173,182 **** enum minimal_symbol_type ms_type, char *info, /* FIXME, is this really char *? */ asection *bfd_section, struct objfile *objfile) { - #ifdef SMASH_TEXT_ADDRESS if (ms_type == mst_text || ms_type == mst_file_text) ! SMASH_TEXT_ADDRESS (address); ! #endif return prim_record_minimal_symbol_and_info (name, address, ms_type, info, bfd_section->index, bfd_section, objfile); --- 173,180 ---- enum minimal_symbol_type ms_type, char *info, /* FIXME, is this really char *? */ asection *bfd_section, struct objfile *objfile) { if (ms_type == mst_text || ms_type == mst_file_text) ! address = SMASH_TEXT_ADDRESS (address); return prim_record_minimal_symbol_and_info (name, address, ms_type, info, bfd_section->index, bfd_section, objfile); Index: gdbarch.c =================================================================== RCS file: /cvs/src/src/gdb/gdbarch.c,v retrieving revision 1.100 diff -p -r1.100 gdbarch.c *** gdbarch.c 2002/01/20 18:05:51 1.100 --- gdbarch.c 2002/02/04 11:48:31 *************** *** 1,7 **** /* *INDENT-OFF* */ /* THIS FILE IS GENERATED */ /* Dynamic architecture support for GDB, the GNU debugger. ! Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This file is part of GDB. --- 1,7 ---- /* *INDENT-OFF* */ /* THIS FILE IS GENERATED */ /* Dynamic architecture support for GDB, the GNU debugger. ! Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GDB. *************** struct gdbarch *** 250,255 **** --- 250,256 ---- const struct floatformat * long_double_format; gdbarch_convert_from_func_ptr_addr_ftype *convert_from_func_ptr_addr; gdbarch_addr_bits_remove_ftype *addr_bits_remove; + gdbarch_smash_text_address_ftype *smash_text_address; gdbarch_software_single_step_ftype *software_single_step; gdbarch_print_insn_ftype *print_insn; gdbarch_skip_trampoline_code_ftype *skip_trampoline_code; *************** struct gdbarch startup_gdbarch = *** 395,400 **** --- 396,402 ---- 0, 0, 0, + 0, generic_in_function_epilogue_p, construct_inferior_arguments, 0, *************** gdbarch_alloc (const struct gdbarch_info *** 505,510 **** --- 507,513 ---- current_gdbarch->extra_stack_alignment_needed = 1; current_gdbarch->convert_from_func_ptr_addr = core_addr_identity; current_gdbarch->addr_bits_remove = core_addr_identity; + current_gdbarch->smash_text_address = core_addr_identity; current_gdbarch->print_insn = legacy_print_insn; current_gdbarch->skip_trampoline_code = generic_skip_trampoline_code; current_gdbarch->in_solib_call_trampoline = generic_in_solib_call_trampoline; *************** verify_gdbarch (struct gdbarch *gdbarch) *** 757,762 **** --- 760,766 ---- gdbarch->long_double_format = &floatformat_unknown; /* Skip verify of convert_from_func_ptr_addr, invalid_p == 0 */ /* Skip verify of addr_bits_remove, invalid_p == 0 */ + /* Skip verify of smash_text_address, invalid_p == 0 */ /* Skip verify of software_single_step, has predicate */ /* Skip verify of print_insn, invalid_p == 0 */ /* Skip verify of skip_trampoline_code, invalid_p == 0 */ *************** gdbarch_dump (struct gdbarch *gdbarch, s *** 1742,1747 **** --- 1746,1762 ---- (long) current_gdbarch->skip_trampoline_code /*SKIP_TRAMPOLINE_CODE ()*/); #endif + #ifdef SMASH_TEXT_ADDRESS + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "SMASH_TEXT_ADDRESS(addr)", + XSTRING (SMASH_TEXT_ADDRESS (addr))); + if (GDB_MULTI_ARCH) + fprintf_unfiltered (file, + "gdbarch_dump: SMASH_TEXT_ADDRESS = 0x%08lx\n", + (long) current_gdbarch->smash_text_address + /*SMASH_TEXT_ADDRESS ()*/); + #endif #ifdef SOFTWARE_SINGLE_STEP #if GDB_MULTI_ARCH /* Macro might contain `[{}]' when not multi-arch */ *************** set_gdbarch_addr_bits_remove (struct gdb *** 4213,4218 **** --- 4228,4251 ---- gdbarch_addr_bits_remove_ftype addr_bits_remove) { gdbarch->addr_bits_remove = addr_bits_remove; + } + + CORE_ADDR + gdbarch_smash_text_address (struct gdbarch *gdbarch, CORE_ADDR addr) + { + if (gdbarch->smash_text_address == 0) + internal_error (__FILE__, __LINE__, + "gdbarch: gdbarch_smash_text_address invalid"); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_smash_text_address called\n"); + return gdbarch->smash_text_address (addr); + } + + void + set_gdbarch_smash_text_address (struct gdbarch *gdbarch, + gdbarch_smash_text_address_ftype smash_text_address) + { + gdbarch->smash_text_address = smash_text_address; } int Index: gdbarch.h =================================================================== RCS file: /cvs/src/src/gdb/gdbarch.h,v retrieving revision 1.75 diff -p -r1.75 gdbarch.h *** gdbarch.h 2002/01/20 19:26:48 1.75 --- gdbarch.h 2002/02/04 11:48:31 *************** *** 1,7 **** /* *INDENT-OFF* */ /* THIS FILE IS GENERATED */ /* Dynamic architecture support for GDB, the GNU debugger. ! Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This file is part of GDB. --- 1,7 ---- /* *INDENT-OFF* */ /* THIS FILE IS GENERATED */ /* Dynamic architecture support for GDB, the GNU debugger. ! Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GDB. *************** extern void set_gdbarch_addr_bits_remove *** 2037,2042 **** --- 2037,2062 ---- #if GDB_MULTI_ARCH #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (ADDR_BITS_REMOVE) #define ADDR_BITS_REMOVE(addr) (gdbarch_addr_bits_remove (current_gdbarch, addr)) + #endif + #endif + + /* It is not at all clear why SMASH_TEXT_ADDRESS is not folded into + ADDR_BITS_REMOVE. */ + + /* Default (function) for non- multi-arch platforms. */ + #if (!GDB_MULTI_ARCH) && !defined (SMASH_TEXT_ADDRESS) + #define SMASH_TEXT_ADDRESS(addr) (core_addr_identity (addr)) + #endif + + typedef CORE_ADDR (gdbarch_smash_text_address_ftype) (CORE_ADDR addr); + extern CORE_ADDR gdbarch_smash_text_address (struct gdbarch *gdbarch, CORE_ADDR addr); + extern void set_gdbarch_smash_text_address (struct gdbarch *gdbarch, gdbarch_smash_text_address_ftype *smash_text_address); + #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SMASH_TEXT_ADDRESS) + #error "Non multi-arch definition of SMASH_TEXT_ADDRESS" + #endif + #if GDB_MULTI_ARCH + #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (SMASH_TEXT_ADDRESS) + #define SMASH_TEXT_ADDRESS(addr) (gdbarch_smash_text_address (current_gdbarch, addr)) #endif #endif Index: gdbarch.sh =================================================================== RCS file: /cvs/src/src/gdb/gdbarch.sh,v retrieving revision 1.105 diff -p -r1.105 gdbarch.sh *** gdbarch.sh 2002/01/20 19:26:48 1.105 --- gdbarch.sh 2002/02/04 11:48:32 *************** *** 1,7 **** #!/bin/sh -u # Architecture commands for GDB, the GNU debugger. ! # Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc. # # This file is part of GDB. # --- 1,7 ---- #!/bin/sh -u # Architecture commands for GDB, the GNU debugger. ! # Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. # # This file is part of GDB. # *************** f:2:CONVERT_FROM_FUNC_PTR_ADDR:CORE_ADDR *** 552,557 **** --- 552,560 ---- # sort of generic thing to handle alignment or segmentation (it's # possible it should be in TARGET_READ_PC instead). f:2:ADDR_BITS_REMOVE:CORE_ADDR:addr_bits_remove:CORE_ADDR addr:addr:::core_addr_identity::0 + # It is not at all clear why SMASH_TEXT_ADDRESS is not folded into + # ADDR_BITS_REMOVE. + f:2:SMASH_TEXT_ADDRESS:CORE_ADDR:smash_text_address:CORE_ADDR addr:addr:::core_addr_identity::0 # FIXME/cagney/2001-01-18: This should be split in two. A target method that indicates if # the target needs software single step. An ISA method to implement it. # *************** cat <<EOF *** 642,648 **** /* *INDENT-OFF* */ /* THIS FILE IS GENERATED */ /* Dynamic architecture support for GDB, the GNU debugger. ! Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This file is part of GDB. --- 645,651 ---- /* *INDENT-OFF* */ /* THIS FILE IS GENERATED */ /* Dynamic architecture support for GDB, the GNU debugger. ! Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GDB. Index: somread.c =================================================================== RCS file: /cvs/src/src/gdb/somread.c,v retrieving revision 1.13 diff -p -r1.13 somread.c *** somread.c 2002/01/08 02:09:31 1.13 --- somread.c 2002/02/04 11:48:32 *************** *** 1,5 **** /* Read HP PA/Risc object files for GDB. ! Copyright 1991, 1992, 1994, 1995, 1996, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. Written by Fred Fish at Cygnus Support. --- 1,5 ---- /* Read HP PA/Risc object files for GDB. ! Copyright 1991, 1992, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. Written by Fred Fish at Cygnus Support. *************** som_symtab_read (bfd *abfd, struct objfi *** 157,165 **** symname = bufp->name.n_strx + stringtab; ms_type = mst_text; bufp->symbol_value += text_offset; ! #ifdef SMASH_TEXT_ADDRESS ! SMASH_TEXT_ADDRESS (bufp->symbol_value); ! #endif break; case ST_ENTRY: --- 157,163 ---- symname = bufp->name.n_strx + stringtab; ms_type = mst_text; bufp->symbol_value += text_offset; ! bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value); break; case ST_ENTRY: *************** som_symtab_read (bfd *abfd, struct objfi *** 172,189 **** else ms_type = mst_text; bufp->symbol_value += text_offset; ! #ifdef SMASH_TEXT_ADDRESS ! SMASH_TEXT_ADDRESS (bufp->symbol_value); ! #endif break; case ST_STUB: symname = bufp->name.n_strx + stringtab; ms_type = mst_solib_trampoline; bufp->symbol_value += text_offset; ! #ifdef SMASH_TEXT_ADDRESS ! SMASH_TEXT_ADDRESS (bufp->symbol_value); ! #endif break; case ST_DATA: --- 170,183 ---- else ms_type = mst_text; bufp->symbol_value += text_offset; ! bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value); break; case ST_STUB: symname = bufp->name.n_strx + stringtab; ms_type = mst_solib_trampoline; bufp->symbol_value += text_offset; ! bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value); break; case ST_DATA: *************** som_symtab_read (bfd *abfd, struct objfi *** 211,219 **** symname = bufp->name.n_strx + stringtab; ms_type = mst_file_text; bufp->symbol_value += text_offset; ! #ifdef SMASH_TEXT_ADDRESS ! SMASH_TEXT_ADDRESS (bufp->symbol_value); ! #endif check_strange_names: /* Utah GCC 2.5, FSF GCC 2.6 and later generate correct local --- 205,211 ---- symname = bufp->name.n_strx + stringtab; ms_type = mst_file_text; bufp->symbol_value += text_offset; ! bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value); check_strange_names: /* Utah GCC 2.5, FSF GCC 2.6 and later generate correct local *************** som_symtab_read (bfd *abfd, struct objfi *** 243,251 **** symname = bufp->name.n_strx + stringtab; ms_type = mst_file_text; bufp->symbol_value += text_offset; ! #ifdef SMASH_TEXT_ADDRESS ! SMASH_TEXT_ADDRESS (bufp->symbol_value); ! #endif break; case ST_ENTRY: --- 235,241 ---- symname = bufp->name.n_strx + stringtab; ms_type = mst_file_text; bufp->symbol_value += text_offset; ! bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value); break; case ST_ENTRY: *************** som_symtab_read (bfd *abfd, struct objfi *** 258,275 **** else ms_type = mst_file_text; bufp->symbol_value += text_offset; ! #ifdef SMASH_TEXT_ADDRESS ! SMASH_TEXT_ADDRESS (bufp->symbol_value); ! #endif break; case ST_STUB: symname = bufp->name.n_strx + stringtab; ms_type = mst_solib_trampoline; bufp->symbol_value += text_offset; ! #ifdef SMASH_TEXT_ADDRESS ! SMASH_TEXT_ADDRESS (bufp->symbol_value); ! #endif break; --- 248,261 ---- else ms_type = mst_file_text; bufp->symbol_value += text_offset; ! bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value); break; case ST_STUB: symname = bufp->name.n_strx + stringtab; ms_type = mst_solib_trampoline; bufp->symbol_value += text_offset; ! bufp->symbol_value = SMASH_TEXT_ADDRESS (bufp->symbol_value); break; Index: config/arm/tm-arm.h =================================================================== RCS file: /cvs/src/src/gdb/config/arm/tm-arm.h,v retrieving revision 1.20 diff -p -r1.20 tm-arm.h *** tm-arm.h 2002/02/01 13:39:43 1.20 --- tm-arm.h 2002/02/04 11:48:33 *************** struct value; *** 34,49 **** ? &floatformat_ieee_double_big \ : &floatformat_ieee_double_littlebyte_bigword) ! /* When reading symbols, we need to zap the low bit of the address, ! which may be set to 1 for Thumb functions. */ - #define SMASH_TEXT_ADDRESS(addr) ((addr) &= ~0x1) - - /* Remove useless bits from addresses in a running program. */ - CORE_ADDR arm_addr_bits_remove (CORE_ADDR); ! ! #define ADDR_BITS_REMOVE(val) (arm_addr_bits_remove (val)) /* Offset from address of function to start of its code. Zero on most machines. */ --- 34,44 ---- ? &floatformat_ieee_double_big \ : &floatformat_ieee_double_littlebyte_bigword) ! CORE_ADDR arm_smash_text_address(CORE_ADDR); ! #define SMASH_TEXT_ADDRESS(ADDR) arm_smash_text_address (ADDR) CORE_ADDR arm_addr_bits_remove (CORE_ADDR); ! #define ADDR_BITS_REMOVE(VAL) arm_addr_bits_remove (VAL) /* Offset from address of function to start of its code. Zero on most machines. */ ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2002-02-04 11:58 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2002-02-02 10:00 RFC/PATCH multi-arch SMASH_TEXT_ADDRESS Richard Earnshaw 2002-02-02 13:48 ` Andrew Cagney 2002-02-03 7:24 ` Richard Earnshaw 2002-02-04 3:58 ` Richard Earnshaw
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox