david@CSVAX.CALTECH.EDU (David Hull) (03/16/89)
In the process of porting gdb 3.1 to the Intergraph CLIPPER, I found the following bugs in coffread.c: The function enter_linenos() fails on machines which require strict alignment of integer variables. Symbols of type C_REGPARM were treated like type C_REG in process_coff_symbol(). The CLIPPER compiler passes the first two (integer) arguments to a function in registers. If the declared argument is smaller than an int, then the function prologue copies the argument into a local variable of the local type before the program can use it. In this case, the symbol information for the argument says that it is of type C_ARG, but the symbol value is *negative*. This causes two problems, in coffread.c:process_coff_symbol() and in printcmd.c: print_frame_args(). In process_coff_symbol(), my fix is to get rid of the promotion of char and short arguments to int. I will post my fix to print_frame_args() separately. Also in this patch is the test for CLIPPERMAGIC that was necessary for gdb to work on the CLIPPER. -David --------------------------------------- David Hull TRW Inc. Redondo Beach, CA ...!{uunet,cit-vax,trwrb}!wiley!david david%wiley.uucp@csvax.caltech.edu *** orig/coffread.c Thu Feb 9 18:15:50 1989 --- coffread.c Fri Feb 17 17:37:06 1989 *************** *** 1080,1085 **** --- 1080,1088 ---- #ifdef I386MAGIC case I386MAGIC: #endif + #ifdef CLIPPERMAGIC + case CLIPPERMAGIC: + #endif return file_hdr->f_nsyms; *************** *** 1276,1282 **** register int last_line; { register char *rawptr = &linetab[file_offset - linetab_offset]; ! register struct lineno *lptr; /* skip first line entry for each function */ rawptr += LINESZ; --- 1279,1285 ---- register int last_line; { register char *rawptr = &linetab[file_offset - linetab_offset]; ! struct lineno lptr; /* skip first line entry for each function */ rawptr += LINESZ; *************** *** 1283,1293 **** /* line numbers start at one for the first line of the function */ first_line--; ! for (lptr = (struct lineno *)rawptr; ! lptr->l_lnno && lptr->l_lnno <= last_line; ! rawptr += LINESZ, lptr = (struct lineno *)rawptr) { ! record_line (first_line + lptr->l_lnno, lptr->l_addr.l_paddr); } } --- 1286,1296 ---- /* line numbers start at one for the first line of the function */ first_line--; ! for (bcopy (rawptr, &lptr, LINESZ); ! lptr.l_lnno && lptr.l_lnno <= last_line; ! rawptr += LINESZ, bcopy (rawptr, &lptr, LINESZ)) { ! record_line (first_line + lptr.l_lnno, lptr.l_addr.l_paddr); } } *************** *** 1465,1471 **** break; case C_REG: - case C_REGPARM: SYMBOL_CLASS (sym) = LOC_REGISTER; add_symbol_to_list (sym, &local_symbols); break; --- 1468,1473 ---- *************** *** 1476,1481 **** --- 1478,1484 ---- case C_ARG: SYMBOL_CLASS (sym) = LOC_ARG; add_symbol_to_list (sym, &local_symbols); + #ifndef clipper /* If PCC says a parameter is a short or a char, it is really an int. */ if (SYMBOL_TYPE (sym) == builtin_type_char *************** *** 1484,1491 **** --- 1487,1510 ---- else if (SYMBOL_TYPE (sym) == builtin_type_unsigned_char || SYMBOL_TYPE (sym) == builtin_type_unsigned_short) SYMBOL_TYPE (sym) = builtin_type_unsigned_int; + #endif break; + case C_REGPARM: + SYMBOL_CLASS (sym) = LOC_REGPARM; + add_symbol_to_list (sym, &local_symbols); + #ifndef clipper + /* If PCC says a parameter is a short or a char, + it is really an int. */ + if (SYMBOL_TYPE (sym) == builtin_type_char + || SYMBOL_TYPE (sym) == builtin_type_short) + SYMBOL_TYPE (sym) = builtin_type_int; + else if (SYMBOL_TYPE (sym) == builtin_type_unsigned_char + || SYMBOL_TYPE (sym) == builtin_type_unsigned_short) + SYMBOL_TYPE (sym) = builtin_type_unsigned_int; + #endif + break; + case C_TPDEF: SYMBOL_CLASS (sym) = LOC_TYPEDEF; SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;