[PATCH] DW_AT_calling_convention support REV 2

Petr Sorfa petrs@caldera.com
Wed Jul 10 11:41:00 GMT 2002


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.
-------------- next part --------------
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)
  	{


More information about the Gdb-patches mailing list