[PATCH] DW_AT_calling_convention support REV 2

Petr Sorfa
2002-07-10T18:32:44Z

[-- Attachment #1: Type: text/plain, Size: 1507 bytes --]

Hi,

Revised patch for supporting DW_AT_calling_convention. This helps GDB
identify the "main" program for languages that do not have a starting
subroutine called "main". It adds a new API set for keeping track of the
symbol associated with "main". Note that there are 3 checks for
DW_AT_calling_convention. They are all necessary as they are detected at
different times when processing program debug information.

2002-07-10 Petr Sorfa (petrs@caldera.com)

* dwarf2read.c (read_subroutine_type): Expanded to recognize
the DW_AT_calling_convention DWARF attribute and for
DW_CC_program and calls set_main_name ().
(read_partial_die): Now recognizes the
DW_AT_calling_convention attribute and calls set_main_name().
(new_symbol): Checks whether the new symbol has a die entry
for DW_AT_calling_convention and calls set_main_symbol() for
DW_CC_program.

* symtab.h (set_main_symbol):
(get_main_symbol):
(is_main_symbol): Added extern prototypes for these dealing
with setting the ``main'' symbol.

* symtab.c (symbol_of_main): New static variable that points to
the current ``main'' symbol.
(set_main_symbol): New function that assigns a value to
symbol_of_main.
(get_main_symbol): Returns the value of symbol_of_main.
(is_main_symbol): Determines whether a given symbol is
equivalent to the "main" symbol.

[-- Attachment #2: calling_convention_rev2.patch --]
[-- Type: text/plain, Size: 5905 bytes --]

Index: symtab.h
===================================================================
RCS file: /cvs/src/src/gdb/symtab.h,v
retrieving revision 1.33
diff -c -p -r1.33 symtab.h
*** symtab.h 28 Jun 2002 22:09:11 -0000 1.33
--- symtab.h 10 Jul 2002 17:56:00 -0000
*************** extern struct cleanup *make_cleanup_free
*** 1392,1395 ****
--- 1392,1403 ----
extern void set_main_name (const char *name);
extern /*const*/ char *main_name (void);

+ /* The symbol associated with the ``main'' function. The return
+ value of get_main_symbol() can be NULL.
+ is_main_symbol() returns a non-zero value if the checked symbol
+ is equivalent to the ``main'' symbol */
+ extern void set_main_symbol (struct symbol *main_symbol);
+ extern struct symbol *get_main_symbol (void);
+ extern int is_main_symbol (struct symbol *check_symbol);
+
#endif /* !defined(SYMTAB_H) */
Index: symtab.c
===================================================================
RCS file: /cvs/src/src/gdb/symtab.c,v
retrieving revision 1.64
diff -c -p -r1.64 symtab.c
*** symtab.c 4 Jul 2002 15:22:42 -0000 1.64
--- symtab.c 10 Jul 2002 17:56:00 -0000
*************** decode_line_spec (char *string, int funf
*** 3954,3959 ****
--- 3954,3960 ----

/* Track MAIN */
static char *name_of_main;
+ static struct symbol *symbol_of_main = NULL;

void
set_main_name (const char *name)
*************** main_name (void)
*** 3978,3983 ****
--- 3979,4007 ----
return "main";
}

+ /* Set the symbol associated with the ``main'' function */
+ void
+ set_main_symbol (struct symbol *main_symbol)
+ {
+ symbol_of_main = main_symbol;
+ }
+
+ /* Retrieve the symbol associated with the ``main'' function.
+ Note that the return value can be NULL unlike main_name() */
+ struct symbol *
+ get_main_symbol (void)
+ {
+ return symbol_of_main;
+ }
+
+ /* Determine whether the symbol passed is equivalent to
+ the ``main'' symbol. Returns 0 if not or if there is no ``main''
+ symbol set. */
+ int
+ is_main_symbol (struct symbol *check_symbol)
+ {
+ return (check_symbol == NULL ? 0 : symbol_of_main == check_symbol);
+ }

void
_initialize_symtab (void)
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.60
diff -c -p -r1.60 dwarf2read.c
*** dwarf2read.c 22 Jun 2002 00:05:59 -0000 1.60
--- dwarf2read.c 10 Jul 2002 17:56:02 -0000
*************** read_subroutine_type (struct die_info *d
*** 3026,3031 ****
--- 3026,3052 ----
|| cu_language == language_cplus)
TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED;

+ /* Check for the calling convention. A DW_CC_program indicates that
+ the subroutine is the the "main" of the program. This needs
+ to be set for languages that don't have a predefined name
+ for the starting subroutines, such as FORTRAN. */
+ attr = dwarf_attr (die, DW_AT_calling_convention);
+ if (attr && (DW_UNSND (attr) != 0))
+ {
+ switch (DW_UNSND (attr))
+ {
+ case DW_CC_program:
+ /* Set this subroutine as the "main" subroutine
+ for the program. */
+ set_main_name (TYPE_NAME (ftype));
+ break;
+ case DW_CC_normal:
+ case DW_CC_nocall:
+ default:
+ break;
+ }
+ }
+
if (die->has_children)
{
struct die_info *child_die;
*************** read_partial_die (struct partial_die_inf
*** 3414,3419 ****
--- 3435,3441 ----
int found_spec_attr = 0;
int has_low_pc_attr = 0;
int has_high_pc_attr = 0;
+ int is_main_program = 0;

*part_die = zeroed_partial_die;
abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
*************** read_partial_die (struct partial_die_inf
*** 3446,3451 ****
--- 3468,3485 ----
if (part_die->name == NULL)
part_die->name = DW_STRING (&attr);
break;
+ case DW_AT_calling_convention:
+ switch (DW_UNSND (&attr))
+ {
+ case DW_CC_program:
+ is_main_program = 1;
+ break;
+ case DW_CC_normal:
+ case DW_CC_nocall:
+ default:
+ break;
+ }
+ break;
case DW_AT_MIPS_linkage_name:
part_die->name = DW_STRING (&attr);
break;
*************** read_partial_die (struct partial_die_inf
*** 3491,3496 ****
--- 3525,3537 ----
}
}

+ /* Set the ``main'' name after attribs have been processed as the
+ ordering of attributes is not guaranteed. */
+ if (is_main_program)
+ {
+ set_main_name (part_die->name);
+ }
+
/* If we found a reference attribute and the die has no name, try
to find a name in the referred to die. */

*************** new_symbol (struct die_info *die, struct
*** 4542,4547 ****
--- 4583,4611 ----
SYMBOL_TYPE (sym) = type;
else
SYMBOL_TYPE (sym) = die_type (die, objfile, cu_header);
+
+ /* Check for the calling convention. A DW_CC_program indicates that
+ the subroutine is the the "main" of the program. This needs
+ to be set for languages that don't have a predefined name
+ for the starting subroutines, such as FORTRAN. */
+ attr = dwarf_attr (die, DW_AT_calling_convention);
+ if (attr && (DW_UNSND (attr) != 0))
+ {
+ switch (DW_UNSND (attr))
+ {
+ case DW_CC_program:
+ /* Set this subroutine as the "main" subroutine
+ for the program. */
+ set_main_name (name);
+ set_main_symbol (sym);
+ break;
+ case DW_CC_normal:
+ case DW_CC_nocall:
+ default:
+ break;
+ }
+ }
+
attr = dwarf_attr (die, DW_AT_decl_line);
if (attr)
{