Re: [RFA] OSF/1 - "next" over prologueless function call

Joel Brobecker
2003-12-03T01:54:51Z

> Is this descriptor easily accessible? I imagine that gp_prologue is
> the byte offset into the function at which you'd jump if you're
> bypassing the GP load. So it becomes pc == func_start || ECOFF and pc
> == func_start + gp_prologue || ELF and something similar.
>
> Avoiding parsing the code would make me a lot happier.

I think it is, although not easily yet (or rather, not in a
target-independent way). Here is how I understood the code:

First, we have mdebugread.c:parse_type(), case symbol type equal
to stEnd:

else if (sh->sc == scText &&
(top_stack->blocktype == stProc ||
top_stack->blocktype == stStaticProc))
{
[...]
/* Make up special symbol to contain procedure specific info */
s = new_symbol (MIPS_EFI_SYMBOL_NAME);
[...]
e = ((struct mips_extra_func_info *)
obstack_alloc (&current_objfile->symbol_obstack,
sizeof (struct mips_extra_func_info)));
memset (e, 0, sizeof (struct mips_extra_func_info));
SYMBOL_VALUE (s) = (long) e;
[...]
add_symbol (s, top_stack->cur_block);

So for each procedure we encounter in the debugging data, we create
a virtual nested procedure with a special name, and the SYMBOL_VALUE
of this symbol is a struct mips_extra_func_info (the actual definition
for this type is achived via a #define in the tm file).

Then later on, when we convert psymtabs into symtabs, we call
mdebugread.c:parse_procedure(). For each procedure, this function
looks up the special symbol we created earlier, and then stuffes
the mips_extra_func_info data with the procedure descriptor:

static void
parse_procedure (PDR *pr, struct symtab *search_symtab,
struct partial_symtab *pst)
{
[...]
i = mylookup_symbol (MIPS_EFI_SYMBOL_NAME, b, LABEL_DOMAIN, LOC_CONST);

if (i)
{
e = (struct mips_extra_func_info *) SYMBOL_VALUE (i);
e->pdr = *pr;

And finally, I see some code in alpha-mdebug-tdep.c which uses that
symbol to dig this information out, given any PC:

static alpha_extra_func_info_t find_proc_desc (CORE_ADDR pc);

I did check with a few trivial examples the value of the gp_prologue
gd_used fields, and it "checks". gp_used is indeed set when the function
starts with the two gp load instructions, and gp_prologue is then equal
to 8. Otherwise, it is set to 0.

If you prefer to use this data rather than relying on code parsing
(which we already do for skip_prologue, btw), using this data seems
to promising. The question then becomes: how will we make this available
in a general (non-target-specific) form? Should we add an extra data
field in struct symbol for instance (I already hear some people
screaming :-)?

You may also see that we have a little hack in objfiles.c:

#ifdef MIPS_EFI_SYMBOL_NAME
/* Relocate Extra Function Info for ecoff. */

else if (SYMBOL_CLASS (sym) == LOC_CONST
&& SYMBOL_DOMAIN (sym) == LABEL_DOMAIN
&& strcmp (DEPRECATED_SYMBOL_NAME (sym), MIPS_EFI_SYMBOL_NAME) == 0)
ecoff_relocate_efi (sym, ANOFFSET (delta, s->block_line_section));
#endif

But I don't think we want to pollute more GDB code with this sort
of hack :)

--
Joel