This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: [RFA] patch to skip bigtoc fixup code
- To: Nicholas Duffek <nsd at redhat dot com>
- Subject: Re: [RFA] patch to skip bigtoc fixup code
- From: Elena Zannoni <ezannoni at cygnus dot com>
- Date: Tue, 1 May 2001 13:28:53 -0400 (EDT)
- Cc: gdb-patches at sourceware dot cygnus dot com, ezannoni at cygnus dot com, phdm at macqel dot be, kevinb at cygnus dot com, Peter dot Schauer at regent dot e-technik dot tu-muenchen dot de, jimb at cygnus dot com
- References: <200104301626.MAA00208@nog.bosbc.com>
Nicholas Duffek writes:
> This patch is an improvement over the one I committed a couple of weeks
> ago. With the new patch, GDB works similarly to dbx:
>
> 1. "step" silently steps through bigtoc fixup code.
>
> 2. Numeric fixup code addresses resolve to symbols @FIX*. For example,
> when debugging a cc1plus binary containing bigtoc fixup section @FIX1
> in address range 0x1001b614 through 0x1001bfc8, "x/i 0x1001b6fc"
> displays "<@FIX1+232>: addis r3,r2,1".
>
> Without the patch, "step" stops at bigtoc fixup code because GDB detects
> that it has stepped outside the current function into the middle of
> another function. A subsequent "step" would return to the original
> function.
>
> The patch uses some of the trampoline hooks in handle_inferior_event() to
> tell GDB to skip bigtoc fixup code. The hooks detect bigtoc fixup code by
> looking for "@FIX" in the first 4 bytes of the code's function name. "@"
> symbols are no longer ignored by xcoffread.c; instead, they introduduce
> new symbol tables and generate function minimal_symbols via the
> misc_func_recorded mechanism.
>
Ah, I see. AIX has separate symbol tables for each section. If you
record the '@' symbols in their own symtab you will avoid also the
problem that prompted your previous patch, correct?
Anyway, the xcoffread.c part looks good to me.
Elena
> ChangeLog:
>
> * config/rs6000/tm-rs6000.h (IN_SOLIB_RETURN_TRAMPOLINE): Define.
> (rs6000_in_solib_return_trampoline): Declare.
> * rs6000-tdep.c (rs6000_in_solib_return_trampoline): New
> function.
> (rs6000_skip_trampoline_code): Skip bigtoc fixup code.
> * xcoffread.c (read_xcoff_symtab): Perform the ISFCN function
> check after the CSECT check rather than before it. Allocate
> separate symtabs for CSECTs whose names begin with '@'.
> (scan_xcoff_symtab): Don't ignore symbols beginning with '@'.
> Activate the misc_func_recorded mechanism for whose names begin
> with '@'.
>
> Tested on powerpc-ibm-aix4.3.3.0. Okay to apply?
>
> Nicholas Duffek
> <nsd@redhat.com>
>
> [patch follows]
>
> Index: gdb/config/rs6000/tm-rs6000.h
> ===================================================================
> diff -up gdb/config/rs6000/tm-rs6000.h gdb/config/rs6000/tm-rs6000.h
> --- gdb/config/rs6000/tm-rs6000.h Fri Apr 27 13:41:03 2001
> +++ gdb/config/rs6000/tm-rs6000.h Fri Apr 27 12:09:00 2001
> @@ -36,6 +36,13 @@ extern char *pc_load_segment_name (CORE_
> #undef CPLUS_MARKER
> #define CPLUS_MARKER '.'
>
> +/* Return whether PC in function NAME is in code that should be skipped when
> + single-stepping. */
> +
> +#define IN_SOLIB_RETURN_TRAMPOLINE(pc, name) \
> + rs6000_in_solib_return_trampoline (pc, name)
> +extern int rs6000_in_solib_return_trampoline (CORE_ADDR, char *);
> +
> /* If PC is in some function-call trampoline code, return the PC
> where the function itself actually starts. If not, return NULL. */
>
> Index: gdb/rs6000-tdep.c
> ===================================================================
> diff -up gdb/rs6000-tdep.c gdb/rs6000-tdep.c
> --- gdb/rs6000-tdep.c Fri Apr 27 13:41:08 2001
> +++ gdb/rs6000-tdep.c Fri Apr 27 13:40:52 2001
> @@ -1045,19 +1045,55 @@ rs6000_extract_return_value (struct type
>
> static CORE_ADDR rs6000_struct_return_address;
>
> -/* Indirect function calls use a piece of trampoline code to do context
> - switching, i.e. to set the new TOC table. Skip such code if we are on
> - its first instruction (as when we have single-stepped to here).
> - Also skip shared library trampoline code (which is different from
> +/* Return whether handle_inferior_event() should proceed through code
> + starting at PC in function NAME when stepping.
> +
> + The AIX -bbigtoc linker option generates functions @FIX0, @FIX1, etc. to
> + handle memory references that are too distant to fit in instructions
> + generated by the compiler. For example, if 'foo' in the following
> + instruction:
> +
> + lwz r9,foo(r2)
> +
> + is greater than 32767, the linker might replace the lwz with a branch to
> + somewhere in @FIX1 that does the load in 2 instructions and then branches
> + back to where execution should continue.
> +
> + GDB should silently step over @FIX code, just like AIX dbx does.
> + Unfortunately, the linker uses the "b" instruction for the branches,
> + meaning that the link register doesn't get set. Therefore, GDB's usual
> + step_over_function() mechanism won't work.
> +
> + Instead, use the IN_SOLIB_RETURN_TRAMPOLINE and SKIP_TRAMPOLINE_CODE hooks
> + in handle_inferior_event() to skip past @FIX code. */
> +
> +int
> +rs6000_in_solib_return_trampoline (CORE_ADDR pc, char *name)
> +{
> + return name && !strncmp (name, "@FIX", 4);
> +}
> +
> +/* Skip code that the user doesn't want to see when stepping:
> +
> + 1. Indirect function calls use a piece of trampoline code to do context
> + switching, i.e. to set the new TOC table. Skip such code if we are on
> + its first instruction (as when we have single-stepped to here).
> +
> + 2. Skip shared library trampoline code (which is different from
> indirect function call trampolines).
> +
> + 3. Skip bigtoc fixup code.
> +
> Result is desired PC to step until, or NULL if we are not in
> - trampoline code. */
> + code that should be skipped. */
>
> CORE_ADDR
> rs6000_skip_trampoline_code (CORE_ADDR pc)
> {
> register unsigned int ii, op;
> + int rel;
> CORE_ADDR solib_target_pc;
> + struct minimal_symbol *msymbol;
>
> static unsigned trampoline_code[] =
> {
> @@ -1070,6 +1106,21 @@ rs6000_skip_trampoline_code (CORE_ADDR p
> 0x4e800020, /* br */
> 0
> };
> +
> + /* Check for bigtoc fixup code. */
> + msymbol = lookup_minimal_symbol_by_pc (pc);
> + if (msymbol && rs6000_in_solib_return_trampoline (pc, SYMBOL_NAME (msymbol)))
> + {
> + /* Double-check that the third instruction from PC is relative "b". */
> + op = read_memory_integer (pc + 8, 4);
> + if ((op & 0xfc000003) == 0x48000000)
> + {
> + /* Extract bits 6-29 as a signed 24-bit relative word address and
> + add it to the containing PC. */
> + rel = ((int)(op << 6) >> 6);
> + return pc + 8 + rel;
> + }
> + }
>
> /* If pc is in a shared library trampoline, return its target. */
> solib_target_pc = find_solib_trampoline_target (pc);
> Index: gdb/xcoffread.c
> ===================================================================
> diff -up gdb/xcoffread.c gdb/xcoffread.c
> --- gdb/xcoffread.c Fri Apr 27 13:41:13 2001
> +++ gdb/xcoffread.c Fri Apr 27 12:52:10 2001
> @@ -1100,14 +1100,6 @@ read_xcoff_symtab (pst)
> /* done with all files, everything from here on is globals */
> }
>
> - /* if explicitly specified as a function, treat is as one. */
> - if (ISFCN (cs->c_type) && cs->c_sclass != C_TPDEF)
> - {
> - bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
> - 0, cs->c_naux, &main_aux);
> - goto function_entry_point;
> - }
> -
> if ((cs->c_sclass == C_EXT || cs->c_sclass == C_HIDEXT)
> && cs->c_naux == 1)
> {
> @@ -1177,7 +1169,8 @@ read_xcoff_symtab (pst)
> SECT_OFF_TEXT (objfile));
> file_end_addr = file_start_addr + CSECT_LEN (&main_aux);
>
> - if (cs->c_name && cs->c_name[0] == '.')
> + if (cs->c_name && (cs->c_name[0] == '.'
> + || cs->c_name[0] == '@'))
> {
> last_csect_name = cs->c_name;
> last_csect_val = cs->c_value;
> @@ -1251,6 +1244,16 @@ read_xcoff_symtab (pst)
> }
> }
>
> + /* If explicitly specified as a function, treat is as one. This check
> + evaluates to true for @FIX* bigtoc CSECT symbols, so it must occur
> + after the above CSECT check. */
> + if (ISFCN (cs->c_type) && cs->c_sclass != C_TPDEF)
> + {
> + bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
> + 0, cs->c_naux, &main_aux);
> + goto function_entry_point;
> + }
> +
> switch (cs->c_sclass)
> {
>
> @@ -2295,14 +2298,8 @@ scan_xcoff_symtab (objfile)
> else
> csect_aux = main_aux[0];
>
> - /* If symbol name starts with ".$" or "$", ignore it.
> -
> - A symbol like "@FIX1" introduces a section for -bbigtoc jump
> - tables, which contain anonymous linker-generated code.
> - Ignore those sections to avoid "pc 0x... in read in psymtab,
> - but not in symtab" warnings from find_pc_sect_symtab. */
> -
> - if (namestring[0] == '$' || namestring[0] == '@'
> + /* If symbol name starts with ".$" or "$", ignore it. */
> + if (namestring[0] == '$'
> || (namestring[0] == '.' && namestring[1] == '$'))
> break;
>
> @@ -2348,7 +2345,11 @@ scan_xcoff_symtab (objfile)
> objfile->static_psymbols.next);
> }
> }
> - if (namestring && namestring[0] == '.')
> + /* Activate the misc_func_recorded mechanism for
> + compiler- and linker-generated CSECTs like ".strcmp"
> + and "@FIX1". */
> + if (namestring && (namestring[0] == '.'
> + || namestring[0] == '@'))
> {
> last_csect_name = namestring;
> last_csect_val = symbol.n_value;
>