diff options
Diffstat (limited to 'gdb/xcoffread.c')
-rw-r--r-- | gdb/xcoffread.c | 1214 |
1 files changed, 691 insertions, 523 deletions
diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c index 7ab1035..a7dc46b 100644 --- a/gdb/xcoffread.c +++ b/gdb/xcoffread.c @@ -54,6 +54,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "stabsread.h" #include "complaints.h" +#include "gdb-stabs.h" + /* For interface with stabsread.c. */ #include "aout/stab_gnu.h" @@ -208,6 +210,51 @@ read_xcoff_symtab PARAMS ((struct objfile *, int)); static void add_stab_to_list PARAMS ((char *, struct pending_stabs **)); + +#ifdef STATIC_NODEBUG_VARS +/* Return the section_offsets* that CS points to. */ +static int cs_to_section PARAMS ((struct coff_symbol *, struct objfile *)); + +struct find_targ_sec_arg { + int targ_index; + int *resultp; +}; + +static void find_targ_sec PARAMS ((bfd *, asection *, void *)); + +static void find_targ_sec (abfd, sect, obj) + bfd *abfd; + asection *sect; + PTR obj; +{ + struct find_targ_sec_arg *args = (struct find_targ_sec_arg *)obj; + if (sect->target_index == args->targ_index) + { + /* This is the section. Figure out what SECT_OFF_* code it is. */ + if (bfd_get_section_flags (abfd, sect) & SEC_CODE) + *args->resultp = SECT_OFF_TEXT; + else if (bfd_get_section_flags (abfd, sect) & SEC_LOAD) + *args->resultp = SECT_OFF_DATA; + else + *args->resultp = SECT_OFF_BSS; + } +} + +/* Return the section number (SECT_OFF_*) that CS points to. */ +static int +cs_to_section (cs, objfile) + struct coff_symbol *cs; + struct objfile *objfile; +{ + int off = SECT_OFF_TEXT; + struct find_targ_sec_arg args; + args.targ_index = cs->c_secnum; + args.resultp = &off; + bfd_map_over_sections (objfile->obfd, find_targ_sec, &args); + return off; +} +#endif /* STATIC_NODEBUG_VARS */ + /* add a given stab string into given stab vector. */ static void @@ -938,11 +985,11 @@ retrieve_traceback (abfd, textsec, cs, size) #define RECORD_MINIMAL_SYMBOL(NAME, ADDR, TYPE, ALLOCED, SECTION, OBJFILE) \ { \ char *namestr; \ - if (ALLOCED) \ - namestr = (NAME) + 1; \ - else { \ + namestr = (NAME); \ + if (namestr[0] == '.') ++namestr; \ + if (!(ALLOCED)) { \ (NAME) = namestr = \ - obstack_copy0 (&objfile->symbol_obstack, (NAME) + 1, strlen ((NAME)+1)); \ + obstack_copy0 (&objfile->symbol_obstack, namestr, strlen (namestr)); \ (ALLOCED) = 1; \ } \ prim_record_minimal_symbol_and_info (namestr, (ADDR), (TYPE), \ @@ -1068,7 +1115,8 @@ read_xcoff_symtab (objfile, nsyms) current_objfile = objfile; - /* Get the appropriate COFF "constants" related to the file we're handling. */ + /* Get the appropriate COFF "constants" related to the file we're + handling. */ N_TMASK = coff_data (abfd)->local_n_tmask; N_BTSHFT = coff_data (abfd)->local_n_btshft; local_symesz = coff_data (abfd)->local_symesz; @@ -1098,477 +1146,585 @@ read_xcoff_symtab (objfile, nsyms) raw_symbol = symtbl; textsec = bfd_get_section_by_name (abfd, ".text"); - if (!textsec) { - printf_unfiltered ("Unable to locate text section!\n"); - } + if (!textsec) + { + printf_unfiltered ("Unable to locate text section!\n"); + } next_symbol_text_func = xcoff_next_symbol_text; - while (symnum < nsyms) { + while (symnum < nsyms) + { - QUIT; /* make this command interruptable. */ + QUIT; /* make this command interruptable. */ - /* READ_ONE_SYMBOL (symbol, cs, symname_alloced); */ - /* read one symbol into `cs' structure. After processing the whole symbol - table, only string table will be kept in memory, symbol table and debug - section of xcoff will be freed. Thus we can mark symbols with names - in string table as `alloced'. */ - { - int ii; - - /* Swap and align the symbol into a reasonable C structure. */ - bfd_coff_swap_sym_in (abfd, raw_symbol, symbol); - - cs->c_symnum = symnum; - cs->c_naux = symbol->n_numaux; - if (symbol->n_zeroes) { - symname_alloced = 0; - /* We must use the original, unswapped, name here so the name field - pointed to by cs->c_name will persist throughout xcoffread. If - we use the new field, it gets overwritten for each symbol. */ - cs->c_name = ((struct external_syment *)raw_symbol)->e.e_name; - /* If it's exactly E_SYMNMLEN characters long it isn't - '\0'-terminated. */ - if (cs->c_name[E_SYMNMLEN - 1] != '\0') + /* READ_ONE_SYMBOL (symbol, cs, symname_alloced); */ + /* read one symbol into `cs' structure. After processing the + whole symbol table, only string table will be kept in memory, + symbol table and debug section of xcoff will be freed. Thus + we can mark symbols with names in string table as + `alloced'. */ + { + int ii; + + /* Swap and align the symbol into a reasonable C structure. */ + bfd_coff_swap_sym_in (abfd, raw_symbol, symbol); + + cs->c_symnum = symnum; + cs->c_naux = symbol->n_numaux; + if (symbol->n_zeroes) { - char *p; - p = obstack_alloc (&objfile->symbol_obstack, E_SYMNMLEN + 1); - strncpy (p, cs->c_name, E_SYMNMLEN); - p[E_SYMNMLEN] = '\0'; - cs->c_name = p; + symname_alloced = 0; + /* We must use the original, unswapped, name here so the name field + pointed to by cs->c_name will persist throughout xcoffread. If + we use the new field, it gets overwritten for each symbol. */ + cs->c_name = ((struct external_syment *)raw_symbol)->e.e_name; + /* If it's exactly E_SYMNMLEN characters long it isn't + '\0'-terminated. */ + if (cs->c_name[E_SYMNMLEN - 1] != '\0') + { + char *p; + p = obstack_alloc (&objfile->symbol_obstack, E_SYMNMLEN + 1); + strncpy (p, cs->c_name, E_SYMNMLEN); + p[E_SYMNMLEN] = '\0'; + cs->c_name = p; + symname_alloced = 1; + } + } + else if (symbol->n_sclass & 0x80) + { + cs->c_name = debugsec + symbol->n_offset; + symname_alloced = 0; + } + else + { + /* in string table */ + cs->c_name = strtbl + (int)symbol->n_offset; symname_alloced = 1; } - } else if (symbol->n_sclass & 0x80) { - cs->c_name = debugsec + symbol->n_offset; - symname_alloced = 0; - } else { /* in string table */ - cs->c_name = strtbl + (int)symbol->n_offset; - symname_alloced = 1; - } - cs->c_value = symbol->n_value; - cs->c_sclass = symbol->n_sclass; - cs->c_secnum = symbol->n_scnum; - cs->c_type = (unsigned)symbol->n_type; + cs->c_value = symbol->n_value; + cs->c_sclass = symbol->n_sclass; + cs->c_secnum = symbol->n_scnum; + cs->c_type = (unsigned)symbol->n_type; - raw_symbol += coff_data (abfd)->local_symesz; - ++symnum; + raw_symbol += coff_data (abfd)->local_symesz; + ++symnum; - raw_auxptr = raw_symbol; /* Save addr of first aux entry */ + /* Save addr of first aux entry. */ + raw_auxptr = raw_symbol; - /* Skip all the auxents associated with this symbol. */ - for (ii = symbol->n_numaux; ii; --ii ) { - raw_symbol += coff_data (abfd)->local_auxesz; - ++symnum; + /* Skip all the auxents associated with this symbol. */ + for (ii = symbol->n_numaux; ii; --ii) + { + raw_symbol += coff_data (abfd)->local_auxesz; + ++symnum; + } } - } - /* if symbol name starts with ".$" or "$", ignore it. */ - if (cs->c_name[0] == '$' || (cs->c_name[1] == '$' && cs->c_name[0] == '.')) - continue; + /* if symbol name starts with ".$" or "$", ignore it. */ + if (cs->c_name[0] == '$' + || (cs->c_name[1] == '$' && cs->c_name[0] == '.')) + continue; - if (cs->c_symnum == next_file_symnum && cs->c_sclass != C_FILE) { - if (last_source_file) + if (cs->c_symnum == next_file_symnum && cs->c_sclass != C_FILE) { - end_symtab (cur_src_end_addr, 1, 0, objfile, textsec->target_index); - end_stabs (); - } - - start_stabs (); - start_symtab ("_globals_", (char *)NULL, (CORE_ADDR)0); - cur_src_end_addr = first_object_file_end; - /* done with all files, everything from here on is globals */ - } + if (last_source_file) + { + end_symtab (cur_src_end_addr, 1, 0, objfile, + textsec->target_index); + end_stabs (); + } - /* 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; - } + start_stabs (); + start_symtab ("_globals_", (char *)NULL, (CORE_ADDR)0); + cur_src_end_addr = first_object_file_end; + /* done with all files, everything from here on is globals */ + } - if ((cs->c_sclass == C_EXT || cs->c_sclass == C_HIDEXT) && cs->c_naux == 1) - { - /* dealing with a symbol with a csect entry. */ + /* 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; + } -# define CSECT(PP) ((PP)->x_csect) -# define CSECT_LEN(PP) (CSECT(PP).x_scnlen.l) -# define CSECT_ALIGN(PP) (SMTYP_ALIGN(CSECT(PP).x_smtyp)) -# define CSECT_SMTYP(PP) (SMTYP_SMTYP(CSECT(PP).x_smtyp)) -# define CSECT_SCLAS(PP) (CSECT(PP).x_smclas) + if ((cs->c_sclass == C_EXT || cs->c_sclass == C_HIDEXT) + && cs->c_naux == 1) + { + /* Dealing with a symbol with a csect entry. */ - /* Convert the auxent to something we can access. */ - bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass, - 0, cs->c_naux, &main_aux); +#define CSECT(PP) ((PP)->x_csect) +#define CSECT_LEN(PP) (CSECT(PP).x_scnlen.l) +#define CSECT_ALIGN(PP) (SMTYP_ALIGN(CSECT(PP).x_smtyp)) +#define CSECT_SMTYP(PP) (SMTYP_SMTYP(CSECT(PP).x_smtyp)) +#define CSECT_SCLAS(PP) (CSECT(PP).x_smclas) - switch (CSECT_SMTYP (&main_aux)) { + /* Convert the auxent to something we can access. */ + bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass, + 0, cs->c_naux, &main_aux); - case XTY_ER : - continue; /* ignore all external references. */ + switch (CSECT_SMTYP (&main_aux)) + { - case XTY_SD : /* a section description. */ - { - switch (CSECT_SCLAS (&main_aux)) { + case XTY_ER: + /* Ignore all external references. */ + continue; - case XMC_PR : /* a `.text' csect. */ + case XTY_SD: + /* A section description. */ { + switch (CSECT_SCLAS (&main_aux)) + { + + case XMC_PR: + { + + /* A program csect is seen. We have to allocate one + symbol table for each program csect. Normally gdb + prefers one symtab for each source file. In case + of AIX, one source file might include more than one + [PR] csect, and they don't have to be adjacent in + terms of the space they occupy in memory. Thus, one + single source file might get fragmented in the + memory and gdb's file start and end address + approach does not work! GCC (and I think xlc) seem + to put all the code in the unnamed program csect. */ + + if (last_csect_name) + { + + /* If no misc. function recorded in the last + seen csect, enter it as a function. This + will take care of functions like strcmp() + compiled by xlc. */ + + if (!misc_func_recorded) + { + int alloced = 0; + RECORD_MINIMAL_SYMBOL + (last_csect_name, last_csect_val, + mst_text, alloced, last_csect_sec, + objfile); + } + + complete_symtab (filestring, file_start_addr); + cur_src_end_addr = file_end_addr; + end_symtab (file_end_addr, 1, 0, objfile, + textsec->target_index); + end_stabs (); + start_stabs (); + /* Give all csects for this source file the same + name. */ + start_symtab (filestring, NULL, (CORE_ADDR)0); + } + + /* If this is the very first csect seen, + basically `__start'. */ + if (just_started) + { + first_object_file_end + = cs->c_value + CSECT_LEN (&main_aux); + just_started = 0; + } + + file_start_addr = cs->c_value; + file_end_addr = cs->c_value + CSECT_LEN (&main_aux); + + if (cs->c_name && cs->c_name[0] == '.') + { + last_csect_name = cs->c_name; + last_csect_val = cs->c_value; + last_csect_sec = cs->c_secnum; + } + } + misc_func_recorded = 0; + continue; + + case XMC_RW : + break; + + /* If the section is not a data description, + ignore it. Note that uninitialized data will + show up as XTY_CM/XMC_RW pair. */ + + case XMC_TC0: + if (toc_offset) + warning ("More than one xmc_tc0 symbol found."); + toc_offset = cs->c_value; + continue; + + case XMC_TC: +#ifdef STATIC_NODEBUG_VARS + /* We need to process these symbols if they are C_HIDEXT, + for static variables in files compiled without -g. */ + if (cs->c_sclass == C_HIDEXT) + break; + else +#endif + continue; - /* A program csect is seen. We have to allocate one - symbol table for each program csect. Normally gdb - prefers one symtab for each source file. In case - of AIX, one source file might include more than one - [PR] csect, and they don't have to be adjacent in - terms of the space they occupy in memory. Thus, one - single source file might get fragmented in the - memory and gdb's file start and end address - approach does not work! GCC (and I think xlc) seem - to put all the code in the unnamed program csect. */ - - if (last_csect_name) { - - /* if no misc. function recorded in the last seen csect, enter - it as a function. This will take care of functions like - strcmp() compiled by xlc. */ - - if (!misc_func_recorded) { - int alloced = 0; - RECORD_MINIMAL_SYMBOL (last_csect_name, last_csect_val, - mst_text, alloced, last_csect_sec, - objfile); + default: + /* Ignore the symbol. */ + continue; } - - - complete_symtab (filestring, file_start_addr); - cur_src_end_addr = file_end_addr; - end_symtab (file_end_addr, 1, 0, objfile, - textsec->target_index); - end_stabs (); - start_stabs (); - /* Give all csects for this source file the same - name. */ - start_symtab (filestring, (char *)NULL, (CORE_ADDR)0); - } - - /* If this is the very first csect seen, basically `__start'. */ - if (just_started) { - first_object_file_end = cs->c_value + CSECT_LEN (&main_aux); - just_started = 0; - } - - file_start_addr = cs->c_value; - file_end_addr = cs->c_value + CSECT_LEN (&main_aux); - - if (cs->c_name && cs->c_name[0] == '.') { - last_csect_name = cs->c_name; - last_csect_val = cs->c_value; - last_csect_sec = cs->c_secnum; - } } - misc_func_recorded = 0; - continue; - - case XMC_RW : break; - /* If the section is not a data description, ignore it. Note that - uninitialized data will show up as XTY_CM/XMC_RW pair. */ - - case XMC_TC0: - if (toc_offset) - warning ("More than one xmc_tc0 symbol found."); - toc_offset = cs->c_value; - continue; + case XTY_LD: + + switch (CSECT_SCLAS (&main_aux)) + { + case XMC_PR: + /* a function entry point. */ + function_entry_point: + RECORD_MINIMAL_SYMBOL (cs->c_name, cs->c_value, mst_text, + symname_alloced, cs->c_secnum, + objfile); + + fcn_line_offset = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr; + fcn_start_addr = cs->c_value; + + /* save the function header info, which will be used + when `.bf' is seen. */ + fcn_cs_saved = *cs; + fcn_aux_saved = main_aux; + + ptb = NULL; + + /* If function has two auxent, then debugging information is + already available for it. Process traceback table for + functions with only one auxent. */ + + if (cs->c_naux == 1) + ptb = retrieve_tracebackinfo (abfd, textsec, cs); + + else if (cs->c_naux != 2) + { + static struct complaint msg = + {"Expected one or two auxents for function", 0, 0}; + complain (&msg); + } + + /* If there is traceback info, create and add parameters + for it. */ + + if (ptb && (ptb->fixedparms || ptb->floatparms)) + { + + int parmcnt = ptb->fixedparms + ptb->floatparms; + char *parmcode = (char*) &ptb->parminfo; + + /* The link area is 0x18 bytes. */ + int parmvalue = ptb->framesize + 0x18; + unsigned int ii, mask; + + for (ii=0, mask = 0x80000000; ii <parmcnt; ++ii) + { + struct symbol *parm; + + if (ptb->parminfo & mask) + { + /* float or double */ + mask = mask >> 1; + if (ptb->parminfo & mask) + { + /* double parm */ + ADD_PARM_TO_PENDING + (parm, parmvalue, builtin_type_double, + local_symbols); + parmvalue += sizeof (double); + } + else + { + /* float parm */ + ADD_PARM_TO_PENDING + (parm, parmvalue, builtin_type_float, + local_symbols); + parmvalue += sizeof (float); + } + } + else + { + /* fixed parm, use (int*) for hex rep. */ + ADD_PARM_TO_PENDING + (parm, parmvalue, + lookup_pointer_type (builtin_type_int), + local_symbols); + parmvalue += sizeof (int); + } + mask = mask >> 1; + } + + /* Fake this as a function. Needed in + process_xcoff_symbol(). */ + cs->c_type = 32; + + finish_block + (process_xcoff_symbol (cs, objfile), &local_symbols, + pending_blocks, cs->c_value, + cs->c_value + ptb->fsize, objfile); + } + continue; + + case XMC_GL: + /* shared library function trampoline code entry point. */ + + /* record trampoline code entries as + mst_solib_trampoline symbol. When we lookup mst + symbols, we will choose mst_text over + mst_solib_trampoline. */ + RECORD_MINIMAL_SYMBOL + (cs->c_name, cs->c_value, + mst_solib_trampoline, + symname_alloced, cs->c_secnum, objfile); + continue; + + case XMC_DS: + /* The symbols often have the same names as debug symbols for + functions, and confuse lookup_symbol. */ + continue; + + default: + /* xlc puts each variable in a separate csect, so we get + an XTY_SD for each variable. But gcc puts several + variables in a csect, so that each variable only gets + an XTY_LD. We still need to record them. This will + typically be XMC_RW; I suspect XMC_RO and XMC_BS might + be possible too. */ + break; + } - case XMC_TC : /* ignore toc entries */ - default : /* any other XMC_XXX */ - continue; + default: + break; } - } - break; /* switch CSECT_SCLAS() */ - - case XTY_LD : - - switch (CSECT_SCLAS (&main_aux)) - { - case XMC_PR: - /* a function entry point. */ - function_entry_point: - RECORD_MINIMAL_SYMBOL (cs->c_name, cs->c_value, mst_text, - symname_alloced, cs->c_secnum, objfile); + } - fcn_line_offset = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr; - fcn_start_addr = cs->c_value; + switch (cs->c_sclass) + { - /* save the function header info, which will be used - when `.bf' is seen. */ - fcn_cs_saved = *cs; - fcn_aux_saved = main_aux; + case C_FILE: + /* see if the last csect needs to be recorded. */ - ptb = NULL; + if (last_csect_name && !misc_func_recorded) + { - /* If function has two auxent, then debugging information is - already available for it. Process traceback table for - functions with only one auxent. */ + /* If no misc. function recorded in the last seen csect, enter + it as a function. This will take care of functions like + strcmp() compiled by xlc. */ - if (cs->c_naux == 1) - ptb = retrieve_tracebackinfo (abfd, textsec, cs); + int alloced = 0; + RECORD_MINIMAL_SYMBOL + (last_csect_name, last_csect_val, + mst_text, alloced, last_csect_sec, objfile); + } - else if (cs->c_naux != 2) - { - static struct complaint msg = - {"Expected one or two auxents for function", 0, 0}; - complain (&msg); - } + /* c_value field contains symnum of next .file entry in table + or symnum of first global after last .file. */ - /* If there is traceback info, create and add parameters for it. */ + next_file_symnum = cs->c_value; - if (ptb && (ptb->fixedparms || ptb->floatparms)) { + /* Complete symbol table for last object file containing + debugging information. */ - int parmcnt = ptb->fixedparms + ptb->floatparms; - char *parmcode = (char*) &ptb->parminfo; - int parmvalue = ptb->framesize + 0x18; /* sizeof(LINK AREA) == 0x18 */ - unsigned int ii, mask; + /* Whether or not there was a csect in the previous file, we + have to call `end_stabs' and `start_stabs' to reset + type_vector, line_vector, etc. structures. */ - for (ii=0, mask = 0x80000000; ii <parmcnt; ++ii) { - struct symbol *parm; + complete_symtab (filestring, file_start_addr); + cur_src_end_addr = file_end_addr; + end_symtab (file_end_addr, 1, 0, objfile, textsec->target_index); + end_stabs (); - if (ptb->parminfo & mask) { /* float or double */ - mask = mask >> 1; - if (ptb->parminfo & mask) { /* double parm */ - ADD_PARM_TO_PENDING - (parm, parmvalue, builtin_type_double, local_symbols); - parmvalue += sizeof (double); - } - else { /* float parm */ - ADD_PARM_TO_PENDING - (parm, parmvalue, builtin_type_float, local_symbols); - parmvalue += sizeof (float); - } - } - else { /* fixed parm, use (int*) for hex rep. */ - ADD_PARM_TO_PENDING (parm, parmvalue, - lookup_pointer_type (builtin_type_int), - local_symbols); - parmvalue += sizeof (int); - } - mask = mask >> 1; - } - - /* Fake this as a function. Needed in process_xcoff_symbol() */ - cs->c_type = 32; - - finish_block(process_xcoff_symbol (cs, objfile), &local_symbols, - pending_blocks, cs->c_value, - cs->c_value + ptb->fsize, objfile); + /* XCOFF, according to the AIX 3.2 documentation, puts the filename + in cs->c_name. But xlc 1.3.0.2 has decided to do things the + standard COFF way and put it in the auxent. We use the auxent if + the symbol is ".file" and an auxent exists, otherwise use the symbol + itself. Simple enough. */ + if (!strcmp (cs->c_name, ".file") && cs->c_naux > 0) + { + bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass, + 0, cs->c_naux, &main_aux); + filestring = coff_getfilename (&main_aux); } - continue; + else + filestring = cs->c_name; - case XMC_GL: - /* shared library function trampoline code entry point. */ + start_stabs (); + start_symtab (filestring, (char *)NULL, (CORE_ADDR)0); + last_csect_name = 0; - /* record trampoline code entries as mst_solib_trampoline symbol. - When we lookup mst symbols, we will choose mst_text over - mst_solib_trampoline. */ - RECORD_MINIMAL_SYMBOL (cs->c_name, cs->c_value, - mst_solib_trampoline, - symname_alloced, cs->c_secnum, objfile); - continue; - - case XMC_DS: - /* The symbols often have the same names as debug symbols for - functions, and confuse lookup_symbol. */ - continue; - - default: - /* xlc puts each variable in a separate csect, so we get - an XTY_SD for each variable. But gcc puts several - variables in a csect, so that each variable only gets - an XTY_LD. We still need to record them. This will - typically be XMC_RW; I suspect XMC_RO and XMC_BS might - be possible too. */ - break; - } - - default : /* all other XTY_XXXs */ + /* reset file start and end addresses. A compilation unit with no text + (only data) should have zero file boundaries. */ + file_start_addr = file_end_addr = 0; break; - } /* switch CSECT_SMTYP() */ } - - switch (cs->c_sclass) { - case C_FILE: + case C_FUN: + fcn_stab_saved = *cs; + break; - /* see if the last csect needs to be recorded. */ + case C_FCN: + if (STREQ (cs->c_name, ".bf")) + { - if (last_csect_name && !misc_func_recorded) { + bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass, + 0, cs->c_naux, &main_aux); - /* if no misc. function recorded in the last seen csect, enter - it as a function. This will take care of functions like - strcmp() compiled by xlc. */ + within_function = 1; - int alloced = 0; - RECORD_MINIMAL_SYMBOL (last_csect_name, last_csect_val, - mst_text, alloced, last_csect_sec, objfile); - } + mark_first_line (fcn_line_offset, cs->c_symnum); - /* c_value field contains symnum of next .file entry in table - or symnum of first global after last .file. */ + new = push_context (0, fcn_start_addr); - next_file_symnum = cs->c_value; - - /* complete symbol table for last object file containing - debugging information. */ + new->name = define_symbol + (fcn_cs_saved.c_value, fcn_stab_saved.c_name, 0, 0, objfile); + if (new->name != NULL) + SYMBOL_SECTION (new->name) = cs->c_secnum; + } + else if (STREQ (cs->c_name, ".ef")) + { - /* Whether or not there was a csect in the previous file, we have to call - `end_stabs' and `start_stabs' to reset type_vector, - line_vector, etc. structures. */ + bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass, + 0, cs->c_naux, &main_aux); + + /* The value of .ef is the address of epilogue code; + not useful for gdb. */ + /* { main_aux.x_sym.x_misc.x_lnsz.x_lnno + contains number of lines to '}' */ + + fcn_last_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno; + new = pop_context (); + if (context_stack_depth != 0) + error ("\ + invalid symbol data; .bf/.ef/.bb/.eb symbol mismatch, at symbol %d.", + symnum); + + finish_block (new->name, &local_symbols, new->old_blocks, + new->start_addr, + fcn_cs_saved.c_value + + fcn_aux_saved.x_sym.x_misc.x_fsize, objfile); + within_function = 0; + } + break; - complete_symtab (filestring, file_start_addr); - cur_src_end_addr = file_end_addr; - end_symtab (file_end_addr, 1, 0, objfile, textsec->target_index); - end_stabs (); + case C_BSTAT: + /* Begin static block. */ + { + struct internal_syment symbol; - /* XCOFF, according to the AIX 3.2 documentation, puts the filename - in cs->c_name. But xlc 1.3.0.2 has decided to do things the - standard COFF way and put it in the auxent. We use the auxent if - the symbol is ".file" and an auxent exists, otherwise use the symbol - itself. Simple enough. */ - if (!strcmp (cs->c_name, ".file") && cs->c_naux > 0) - { - bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass, - 0, cs->c_naux, &main_aux); - filestring = coff_getfilename (&main_aux); - } - else - filestring = cs->c_name; + read_symbol (&symbol, cs->c_value); + static_block_base = symbol.n_value; + static_block_section = symbol.n_scnum; + } + break; - start_stabs (); - start_symtab (filestring, (char *)NULL, (CORE_ADDR)0); - last_csect_name = 0; + case C_ESTAT: + /* End of static block. */ + static_block_base = 0; + static_block_section = -1; + break; - /* reset file start and end addresses. A compilation unit with no text - (only data) should have zero file boundaries. */ - file_start_addr = file_end_addr = 0; - break; + case C_ARG: + case C_REGPARM: + case C_TPDEF: + case C_STRTAG: + case C_UNTAG: + case C_ENTAG: + printf_unfiltered + ("ERROR: Unimplemented storage class: %d.\n", cs->c_sclass); + break; + case C_LABEL: + case C_NULL: + /* Ignore these. */ + break; - case C_FUN: - fcn_stab_saved = *cs; - break; - +#ifdef STATIC_NODEBUG_VARS + /* This is wrong. These symbols are XMC_TC, which means that + the value of the symbol is the address of the TOC entry, not + the address of the variable itself. */ + case C_HIDEXT: + { + /* This is the only place that static variables show up in files + compiled without -g. External variables also have a C_EXT, + so that is why we record everything as mst_file_* here. */ + enum minimal_symbol_type ms_type; + CORE_ADDR tmpaddr; + int sec; - case C_FCN: - if (STREQ (cs->c_name, ".bf")) { + sec = cs_to_section (cs, objfile); + tmpaddr = cs->c_value; - bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass, - 0, cs->c_naux, &main_aux); + switch (sec) + { + case SECT_OFF_TEXT: + case SECT_OFF_RODATA: + ms_type = mst_file_text; + break; + case SECT_OFF_DATA: + ms_type = mst_file_data; + break; + case SECT_OFF_BSS: + ms_type = mst_file_bss; + break; + default: + ms_type = mst_unknown; + break; + } + RECORD_MINIMAL_SYMBOL (cs->c_name, cs->c_value, ms_type, + symname_alloced, cs->c_secnum, objfile); + } +#endif /* STATIC_NODEBUG_VARS */ + break; - within_function = 1; + case C_BINCL: + /* beginning of include file */ + /* In xlc output, C_BINCL/C_EINCL pair doesn't show up in sorted + order. Thus, when wee see them, we might not know enough info + to process them. Thus, we'll be saving them into a table + (inclTable) and postpone their processing. */ - mark_first_line (fcn_line_offset, cs->c_symnum); + record_include_begin (cs); + break; - new = push_context (0, fcn_start_addr); + case C_EINCL: + /* End of include file. */ + /* See the comment after case C_BINCL. */ + record_include_end (cs); + break; - new->name = define_symbol - (fcn_cs_saved.c_value, fcn_stab_saved.c_name, 0, 0, objfile); - if (new->name != NULL) - SYMBOL_SECTION (new->name) = cs->c_secnum; - } - else if (STREQ (cs->c_name, ".ef")) { - - bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass, - 0, cs->c_naux, &main_aux); - - /* the value of .ef is the address of epilogue code; - not useful for gdb */ - /* { main_aux.x_sym.x_misc.x_lnsz.x_lnno - contains number of lines to '}' */ - - fcn_last_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno; - new = pop_context (); - if (context_stack_depth != 0) - error ("invalid symbol data; .bf/.ef/.bb/.eb symbol mismatch, at symbol %d.", - symnum); - - finish_block (new->name, &local_symbols, new->old_blocks, - new->start_addr, - fcn_cs_saved.c_value + - fcn_aux_saved.x_sym.x_misc.x_fsize, objfile); - within_function = 0; - } - break; + case C_BLOCK: + if (STREQ (cs->c_name, ".bb")) + { + depth++; + new = push_context (depth, cs->c_value); + } + else if (STREQ (cs->c_name, ".eb")) + { + new = pop_context (); + if (depth != new->depth) + error ("\ + Invalid symbol data: .bb/.eb symbol mismatch at symbol %d.", + symnum); + + depth--; + if (local_symbols && context_stack_depth > 0) + { + /* Make a block for the local symbols within. */ + finish_block (new->name, &local_symbols, new->old_blocks, + new->start_addr, cs->c_value, objfile); + } + local_symbols = new->locals; + } + break; - case C_BSTAT : /* begin static block */ - { - struct internal_syment symbol; - - read_symbol (&symbol, cs->c_value); - static_block_base = symbol.n_value; - static_block_section = symbol.n_scnum; - } - break; - - case C_ESTAT : /* end of static block */ - static_block_base = 0; - static_block_section = -1; - break; - - case C_ARG : /* These are not implemented. */ - case C_REGPARM : - case C_TPDEF : - case C_STRTAG : - case C_UNTAG : - case C_ENTAG : - printf_unfiltered ("ERROR: Unimplemented storage class: %d.\n", cs->c_sclass); - break; - - case C_HIDEXT : /* ignore these.. */ - case C_LABEL : - case C_NULL : - break; - - case C_BINCL : /* beginning of include file */ - - /* In xlc output, C_BINCL/C_EINCL pair doesn't show up in sorted - order. Thus, when wee see them, we might not know enough info - to process them. Thus, we'll be saving them into a table - (inclTable) and postpone their processing. */ - - record_include_begin (cs); - break; - - case C_EINCL : /* end of include file */ - /* see the comment after case C_BINCL. */ - record_include_end (cs); - break; - - case C_BLOCK : - if (STREQ (cs->c_name, ".bb")) { - depth++; - new = push_context (depth, cs->c_value); - } - else if (STREQ (cs->c_name, ".eb")) { - new = pop_context (); - if (depth != new->depth) - error ("Invalid symbol data: .bb/.eb symbol mismatch at symbol %d.", - symnum); - - depth--; - if (local_symbols && context_stack_depth > 0) { - /* Make a block for the local symbols within. */ - finish_block (new->name, &local_symbols, new->old_blocks, - new->start_addr, cs->c_value, objfile); + default: + process_xcoff_symbol (cs, objfile); + break; } - local_symbols = new->locals; - } - break; - - default : - process_xcoff_symbol (cs, objfile); - break; } - } /* while */ - if (last_source_file) { end_symtab (cur_src_end_addr, 1, 0, objfile, textsec->target_index); @@ -1597,6 +1753,9 @@ read_xcoff_symtab (objfile, nsyms) (ALLOCED) ? (NAME) : obstack_copy0 (&objfile->symbol_obstack, (NAME), strlen (NAME)); +static struct type *func_symbol_type; +static struct type *var_symbol_type; + /* process one xcoff symbol. */ static struct symbol * @@ -1623,146 +1782,148 @@ process_xcoff_symbol (cs, objfile) SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; SYMBOL_SECTION (sym) = cs->c_secnum; - if (ISFCN (cs->c_type)) { - - /* At this point, we don't know the type of the function and assume it - is int. This will be patched with the type from its stab entry later - on in patch_block_stabs () */ - - SYMBOL_NAME (sym) = SYMNAME_ALLOC (name, symname_alloced); - SYMBOL_TYPE (sym) = lookup_function_type (lookup_fundamental_type (objfile, FT_INTEGER)); - - SYMBOL_CLASS (sym) = LOC_BLOCK; - SYMBOL_DUP (sym, sym2); - - if (cs->c_sclass == C_EXT) - add_symbol_to_list (sym2, &global_symbols); - else if (cs->c_sclass == C_HIDEXT || cs->c_sclass == C_STAT) - add_symbol_to_list (sym2, &file_symbols); - } + if (ISFCN (cs->c_type)) + { + /* At this point, we don't know the type of the function. This + will be patched with the type from its stab entry later on in + patch_block_stabs (), unless the file was compiled without -g. */ - else { + SYMBOL_NAME (sym) = SYMNAME_ALLOC (name, symname_alloced); + SYMBOL_TYPE (sym) = func_symbol_type; - /* in case we can't figure out the type, default is `int'. */ - SYMBOL_TYPE (sym) = lookup_fundamental_type (objfile, FT_INTEGER); + SYMBOL_CLASS (sym) = LOC_BLOCK; + SYMBOL_DUP (sym, sym2); - switch (cs->c_sclass) + if (cs->c_sclass == C_EXT) + add_symbol_to_list (sym2, &global_symbols); + else if (cs->c_sclass == C_HIDEXT || cs->c_sclass == C_STAT) + add_symbol_to_list (sym2, &file_symbols); + } + else { + /* In case we can't figure out the type, provide default. */ + SYMBOL_TYPE (sym) = var_symbol_type; + + switch (cs->c_sclass) + { #if 0 - case C_FUN: - if (fcn_cs_saved.c_sclass == C_EXT) - add_stab_to_list (name, &global_stabs); - else - add_stab_to_list (name, &file_stabs); - break; + case C_FUN: + if (fcn_cs_saved.c_sclass == C_EXT) + add_stab_to_list (name, &global_stabs); + else + add_stab_to_list (name, &file_stabs); + break; #endif - case C_GSYM: - add_stab_to_list (name, &global_stabs); - break; + case C_GSYM: + add_stab_to_list (name, &global_stabs); + break; - case C_BCOMM: - common_block_start (cs->c_name, objfile); - break; + case C_BCOMM: + common_block_start (cs->c_name, objfile); + break; - case C_ECOMM: - common_block_end (objfile); - break; + case C_ECOMM: + common_block_end (objfile); + break; - default: - complain (&storclass_complaint, cs->c_sclass); - /* FALLTHROUGH */ + default: + complain (&storclass_complaint, cs->c_sclass); + /* FALLTHROUGH */ - case C_DECL: - case C_PSYM: - case C_RPSYM: - case C_ECOML: + case C_DECL: + case C_PSYM: + case C_RPSYM: + case C_ECOML: - sym = define_symbol (cs->c_value, cs->c_name, 0, 0, objfile); - if (sym != NULL) - { - SYMBOL_SECTION (sym) = cs->c_secnum; - } - return sym; + sym = define_symbol (cs->c_value, cs->c_name, 0, 0, objfile); + if (sym != NULL) + { + SYMBOL_SECTION (sym) = cs->c_secnum; + } + return sym; - case C_STSYM: + case C_STSYM: - /* For xlc (not GCC), the 'V' symbol descriptor is used for all - statics and we need to distinguish file-scope versus function-scope - using within_function. We do this by changing the string we pass - to define_symbol to use 'S' where we need to, which is not necessarily - super-clean, but seems workable enough. */ + /* For xlc (not GCC), the 'V' symbol descriptor is used for + all statics and we need to distinguish file-scope versus + function-scope using within_function. We do this by + changing the string we pass to define_symbol to use 'S' + where we need to, which is not necessarily super-clean, + but seems workable enough. */ - if (*name == ':' || (pp = (char *) strchr(name, ':')) == NULL) - return NULL; + if (*name == ':' || (pp = (char *) strchr(name, ':')) == NULL) + return NULL; - ++pp; - if (*pp == 'V' && !within_function) - *pp = 'S'; - sym = define_symbol (cs->c_value, cs->c_name, 0, 0, objfile); - if (sym != NULL) - { - SYMBOL_VALUE (sym) += static_block_base; - SYMBOL_SECTION (sym) = static_block_section; - } - return sym; + ++pp; + if (*pp == 'V' && !within_function) + *pp = 'S'; + sym = define_symbol (cs->c_value, cs->c_name, 0, 0, objfile); + if (sym != NULL) + { + SYMBOL_VALUE (sym) += static_block_base; + SYMBOL_SECTION (sym) = static_block_section; + } + return sym; - case C_LSYM: - sym = define_symbol (cs->c_value, cs->c_name, 0, N_LSYM, objfile); - if (sym != NULL) - { - SYMBOL_SECTION (sym) = cs->c_secnum; - } - return sym; + case C_LSYM: + sym = define_symbol (cs->c_value, cs->c_name, 0, N_LSYM, objfile); + if (sym != NULL) + { + SYMBOL_SECTION (sym) = cs->c_secnum; + } + return sym; - case C_AUTO: - SYMBOL_CLASS (sym) = LOC_LOCAL; - SYMBOL_NAME (sym) = SYMNAME_ALLOC (name, symname_alloced); - SYMBOL_SECTION (sym) = cs->c_secnum; - SYMBOL_DUP (sym, sym2); - add_symbol_to_list (sym2, &local_symbols); - break; + case C_AUTO: + SYMBOL_CLASS (sym) = LOC_LOCAL; + SYMBOL_NAME (sym) = SYMNAME_ALLOC (name, symname_alloced); + SYMBOL_SECTION (sym) = cs->c_secnum; + SYMBOL_DUP (sym, sym2); + add_symbol_to_list (sym2, &local_symbols); + break; - case C_EXT: - SYMBOL_CLASS (sym) = LOC_STATIC; - SYMBOL_NAME (sym) = SYMNAME_ALLOC (name, symname_alloced); - SYMBOL_SECTION (sym) = cs->c_secnum; - SYMBOL_DUP (sym, sym2); - add_symbol_to_list (sym2, &global_symbols); - break; + case C_EXT: + SYMBOL_CLASS (sym) = LOC_STATIC; + SYMBOL_NAME (sym) = SYMNAME_ALLOC (name, symname_alloced); + SYMBOL_SECTION (sym) = cs->c_secnum; + SYMBOL_DUP (sym, sym2); + add_symbol_to_list (sym2, &global_symbols); + break; - case C_STAT: - SYMBOL_CLASS (sym) = LOC_STATIC; - SYMBOL_NAME (sym) = SYMNAME_ALLOC (name, symname_alloced); - SYMBOL_SECTION (sym) = cs->c_secnum; - SYMBOL_DUP (sym, sym2); - add_symbol_to_list - (sym2, within_function ? &local_symbols : &file_symbols); - break; + case C_STAT: + SYMBOL_CLASS (sym) = LOC_STATIC; + SYMBOL_NAME (sym) = SYMNAME_ALLOC (name, symname_alloced); + SYMBOL_SECTION (sym) = cs->c_secnum; + SYMBOL_DUP (sym, sym2); + add_symbol_to_list + (sym2, within_function ? &local_symbols : &file_symbols); + break; - case C_REG: - printf_unfiltered ("ERROR! C_REG is not fully implemented!\n"); - SYMBOL_CLASS (sym) = LOC_REGISTER; - SYMBOL_NAME (sym) = SYMNAME_ALLOC (name, symname_alloced); - SYMBOL_SECTION (sym) = cs->c_secnum; - SYMBOL_DUP (sym, sym2); - add_symbol_to_list (sym2, &local_symbols); - break; + case C_REG: + printf_unfiltered ("ERROR! C_REG is not fully implemented!\n"); + SYMBOL_CLASS (sym) = LOC_REGISTER; + SYMBOL_NAME (sym) = SYMNAME_ALLOC (name, symname_alloced); + SYMBOL_SECTION (sym) = cs->c_secnum; + SYMBOL_DUP (sym, sym2); + add_symbol_to_list (sym2, &local_symbols); + break; - case C_RSYM: - pp = (char*) strchr (name, ':'); - if (pp) { - sym = define_symbol (cs->c_value, cs->c_name, 0, 0, objfile); - if (sym != NULL) - SYMBOL_SECTION (sym) = cs->c_secnum; - return sym; - } - else { - complain (&rsym_complaint, name); - return NULL; + case C_RSYM: + pp = (char*) strchr (name, ':'); + if (pp) + { + sym = define_symbol (cs->c_value, cs->c_name, 0, 0, objfile); + if (sym != NULL) + SYMBOL_SECTION (sym) = cs->c_secnum; + return sym; + } + else + { + complain (&rsym_complaint, name); + return NULL; + } } } - } return sym2; } @@ -2245,10 +2406,17 @@ _initialize_xcoffread () { add_symtab_fns(&xcoff_sym_fns); - /* Initialize symbol template later used for arguments. */ + /* Initialize symbol template later used for arguments. Its other + fields are zero, or are filled in later. */ SYMBOL_NAME (&parmsym) = ""; SYMBOL_INIT_LANGUAGE_SPECIFIC (&parmsym, language_c); SYMBOL_NAMESPACE (&parmsym) = VAR_NAMESPACE; SYMBOL_CLASS (&parmsym) = LOC_ARG; - /* Its other fields are zero, or are filled in later. */ + + func_symbol_type = init_type (TYPE_CODE_FUNC, 1, 0, + "<function, no debug info>", NULL); + TYPE_TARGET_TYPE (func_symbol_type) = builtin_type_int; + var_symbol_type = + init_type (TYPE_CODE_INT, TARGET_INT_BIT / HOST_CHAR_BIT, 0, + "<variable, no debug info>", NULL); } |