From daad3bbf95c29995c3ed516fe0da0f627eff8c72 Mon Sep 17 00:00:00 2001 From: Kung Hsu Date: Fri, 8 Jul 1994 19:38:18 +0000 Subject: [PATCH] Modified Files: read.c read.h ecoff.c ecoff.h ChangeLog * read.c (read_a_source_file): generate line stabs for asm file. * read.h: add extern generate_asm_line_stab. * ecoff.h : add prototype for ecoff_generate_asm_line_stab(). * ecoff.c (add_file): if there's no filename provided, set switch to generate line stabs for .s file. * ecoff.c (add_procedure): add stabs symbol for .ent directive. * ecoff.c (generate_ecoff_stab): creates an artificial stabs. * ecoff.c (generate_asm_line_stab): generate a artifitial label for each line and generate a stabn for the line. --- gas/ChangeLog | 14 ++++ gas/ecoff.c | 194 +++++++++++++++++++++++++++++++++++++++++++++++--- gas/ecoff.h | 6 ++ gas/read.c | 23 ++++-- 4 files changed, 222 insertions(+), 15 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 386c55e0172..5d1efcedfc8 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,17 @@ +Fri Jul 8 12:23:44 1994 Kung Hsu (kung@mexican.cygnus.com) + + * config/obj-ecoff.h: define macro OBJ_GENERATE_ASM_LINE_STAB. + * config/obj-elf.h: ditto. + * read.c (read_a_source_file): generate line stabs for asm file. + * read.h: add extern generate_asm_line_stab. + * ecoff.h : add prototype for ecoff_generate_asm_line_stab(). + * ecoff.c (add_file): if there's no filename provided, set switch + to generate line stabs for .s file. + * ecoff.c (add_procedure): add stabs symbol for .ent directive. + * ecoff.c (generate_ecoff_stab): creates an artificial stabs. + * ecoff.c (generate_asm_line_stab): generate a artifitial label + for each line and generate a stabn for the line. + Thu Jul 7 17:04:03 1994 Steve Chamberlain (sac@jonny.cygnus.com) * gasp.c (get_any_string): Cope with getting a string with an diff --git a/gas/ecoff.c b/gas/ecoff.c index 7a72cf7e1ba..e52bf43fe15 100644 --- a/gas/ecoff.c +++ b/gas/ecoff.c @@ -778,7 +778,6 @@ enum aux_type { #define MAX_CLUSTER_PAGES 63 #endif - /* Linked list connecting separate page allocations. */ typedef struct vlinks { struct vlinks *prev; /* previous set of pages */ @@ -1394,6 +1393,7 @@ static alloc_info_t alloc_counts[ (int)alloc_type_last ]; /* Various statics. */ static efdr_t *cur_file_ptr = (efdr_t *) 0; /* current file desc. header */ static proc_t *cur_proc_ptr = (proc_t *) 0; /* current procedure header */ +static proc_t *first_proc_ptr = (proc_t *) 0; /* first procedure header */ static thead_t *top_tag_head = (thead_t *) 0; /* top level tag head */ static thead_t *cur_tag_head = (thead_t *) 0; /* current tag head */ #ifdef ECOFF_DEBUG @@ -1477,6 +1477,7 @@ static forward_t *allocate_forward PARAMS ((void)); static thead_t *allocate_thead PARAMS ((void)); static void free_thead PARAMS ((thead_t *ptr)); static lineno_list_t *allocate_lineno_list PARAMS ((void)); +static void generate_ecoff_stab PARAMS ((int, const char *, int, int, int)); /* This function should be called when the assembler starts up. */ @@ -2131,6 +2132,9 @@ add_procedure (func) cur_proc_ptr = new_proc_ptr = &vp->last->datum->proc[vp->objects_last_page++]; + if (first_proc_ptr == (proc_t *) NULL) + first_proc_ptr = new_proc_ptr; + vp->num_allocated++; new_proc_ptr->pdr.isym = -1; @@ -2186,7 +2190,10 @@ add_file (file_name, indx) as_fatal ("fake .file after real one"); as_where (&file, (unsigned int *) NULL); file_name = (const char *) file; + generate_asm_line_stab = 1; } + else + generate_asm_line_stab = 0; #ifndef NO_LISTING if (listing) @@ -2266,6 +2273,18 @@ add_file (file_name, indx) fil_ptr->int_type = add_aux_sym_tir (&int_type_info, hash_yes, &cur_file_ptr->thash_head[0]); + if (generate_asm_line_stab) + { + static char itstr[] = "int:t1=r1;-2147483648;2147483647;"; + mark_stabs (0); + (void) add_ecoff_symbol (file_name, st_Nil, sc_Nil, + symbol_new ("L0\001", now_seg, + (valueT) frag_now_fix (), + frag_now), + 0, ECOFF_MARK_STAB (N_SO)); + (void) add_ecoff_symbol (itstr, st_Nil, sc_Nil, + (symbolS *)NULL, 0, ECOFF_MARK_STAB (N_LSYM)); + } } } @@ -2967,11 +2986,23 @@ ecoff_directive_end (ignore) if (ent == (symbolS *) NULL) as_warn (".end directive names unknown symbol"); else - (void) add_ecoff_symbol ((const char *) NULL, st_End, sc_Text, + { + (void) add_ecoff_symbol ((const char *) NULL, st_End, sc_Text, symbol_new ("L0\001", now_seg, (valueT) frag_now_fix (), frag_now), (symint_t) 0, (symint_t) 0); + if (generate_asm_line_stab) + { + char *n; + + n = xmalloc (strlen (name) + 4); + strcpy (n, name); + strcat (n, ":F1"); + (void) add_ecoff_symbol ((const char *) n, stGlobal, scText, + ent, 0, ECOFF_MARK_STAB (N_FUN)); + } + } cur_proc_ptr = (proc_t *) NULL; @@ -3522,6 +3553,7 @@ ecoff_build_lineno (backend, buf, bufend, offset, linecntptr) unsigned long c; long iline; long totcount; + lineno_list_t first; if (linecntptr != (long *) NULL) *linecntptr = 0; @@ -3534,6 +3566,31 @@ ecoff_build_lineno (backend, buf, bufend, offset, linecntptr) c = offset; iline = 0; totcount = 0; + + /* For some reason the address of the first procedure is ignored + when reading line numbers. This doesn't matter if the address of + the first procedure is 0, but when gcc is generating MIPS + embedded PIC code, it will put strings in the .text section + before the first procedure. We cope by inserting a dummy line if + the address of the first procedure is not 0. Hopefully this + won't screw things up too badly. */ + if (first_proc_ptr != (proc_t *) NULL + && first_lineno != (lineno_list_t *) NULL + && ((S_GET_VALUE (first_proc_ptr->sym->as_sym) + + bfd_get_section_vma (stdoutput, + S_GET_SEGMENT (first_proc_ptr->sym->as_sym))) + != 0)) + { + first.file = first_lineno->file; + first.proc = first_lineno->proc; + first.frag = &zero_address_frag; + first.paddr = 0; + first.lineno = 0; + + first.next = first_lineno; + first_lineno = &first; + } + for (l = first_lineno; l != (lineno_list_t *) NULL; l = l->next) { long count; @@ -4180,12 +4237,14 @@ ecoff_build_aux (backend, buf, bufend, offset) switch (aux_ptr->type) { case aux_tir: - ecoff_swap_tir_out (bigendian, &aux_ptr->data.ti, - &aux_out->a_ti); + (*backend->swap_tir_out) (bigendian, + &aux_ptr->data.ti, + &aux_out->a_ti); break; case aux_rndx: - ecoff_swap_rndx_out (bigendian, &aux_ptr->data.rndx, - &aux_out->a_rndx); + (*backend->swap_rndx_out) (bigendian, + &aux_ptr->data.rndx, + &aux_out->a_rndx); break; case aux_dnLow: AUX_PUT_DNLOW (bigendian, aux_ptr->data.dnLow, @@ -4536,9 +4595,13 @@ ecoff_build_debug (hdr, bufp, backend) know ((offset & (backend->debug_align - 1)) == 0); - hdr->magic = backend->sym_magic; - /* FIXME: what should hdr->vstamp be? */ + /* FIXME: This value should be determined from the .verstamp directive, + with reasonable defaults in config files. */ +#ifdef TC_ALPHA + hdr->vstamp = 0x030b; +#else hdr->vstamp = 0x020b; +#endif *bufp = buf; return offset; @@ -4950,4 +5013,119 @@ ecoff_set_gp_prolog_size (sz) cur_proc_ptr->pdr.gp_used = 1; } +static void +generate_ecoff_stab (what, string, type, other, desc) + int what; + const char *string; + int type; + int other; + int desc; +{ + efdr_t *save_file_ptr = cur_file_ptr; + symbolS *sym; + symint_t value; + st_t st; + sc_t sc; + symint_t indx; + localsym_t *hold = NULL; + + /* We don't handle .stabd. */ + if (what != 's' && what != 'n') + { + as_bad (".stab%c is not supported", what); + return; + } + + /* We ignore the other field. */ + if (other != 0) + as_warn (".stab%c: ignoring non-zero other field", what); + + /* Make sure we have a current file. */ + if (cur_file_ptr == (efdr_t *) NULL) + { + add_file ((const char *) NULL, 0); + save_file_ptr = cur_file_ptr; + } + + /* For stabs in ECOFF, the first symbol must be @stabs. This is a + signal to gdb. */ + if (stabs_seen == 0) + mark_stabs (0); + + /* Line number stabs are handled differently, since they have two + values, the line number and the address of the label. We use the + index field (aka desc) to hold the line number, and the value + field to hold the address. The symbol type is st_Label, which + should be different from the other stabs, so that gdb can + recognize it. */ + if (type == N_SLINE) + { + SYMR dummy_symr; + +#ifndef NO_LISTING + if (listing) + listing_source_line ((unsigned int) desc); +#endif + + dummy_symr.index = desc; + if (dummy_symr.index != desc) + { + as_warn ("Line number (%d) for .stab%c directive cannot fit in index field (20 bits)", + desc, what); + return; + } + + sym = symbol_find_or_make ((char *)string); + value = 0; + st = st_Label; + sc = sc_Text; + indx = desc; + } + else + { +#ifndef NO_LISTING + if (listing && (type == N_SO || type == N_SOL)) + listing_source_file (string); +#endif + + sym = symbol_find_or_make ((char *)string); + sc = sc_Nil; + st = st_Nil; + value = 0; + indx = ECOFF_MARK_STAB (type); + } + + /* Don't store the stabs symbol we are creating as the type of the + ECOFF symbol. We want to compute the type of the ECOFF symbol + independently. */ + if (sym != (symbolS *) NULL) + hold = sym->ecoff_symbol; + + (void) add_ecoff_symbol (string, st, sc, sym, value, indx); + + if (sym != (symbolS *) NULL) + sym->ecoff_symbol = hold; + + /* Restore normal file type. */ + cur_file_ptr = save_file_ptr; +} + +static int line_label_cnt = 0; +void +ecoff_generate_asm_line_stab (lineno) + int lineno; +{ + char *ll; + + line_label_cnt++; + /* generate local label $LMnn */ + ll = xmalloc(10); + sprintf(ll, "$LM%d", line_label_cnt); + colon (ll); + + /* generate stab for the line */ + generate_ecoff_stab ('n', ll, N_SLINE, 0, lineno); + +} + #endif /* ECOFF_DEBUGGING */ diff --git a/gas/ecoff.h b/gas/ecoff.h index a77d14eee5b..2e94081394d 100644 --- a/gas/ecoff.h +++ b/gas/ecoff.h @@ -32,6 +32,9 @@ extern void ecoff_read_begin_hook PARAMS ((void)); obj_symbol_new_hook. */ extern void ecoff_symbol_new_hook PARAMS ((struct symbol *)); +/* This function should be called by the obj_frob_symbol hook. */ +extern void ecoff_frob_symbol PARAMS ((struct symbol *)); + /* Build the ECOFF debugging information. This should be called by obj_frob_file. This fills in the counts in *HDR; the offsets are filled in relative to the start of the *BUFP. It sets *BUFP to a @@ -74,4 +77,7 @@ extern void ecoff_set_gp_prolog_size PARAMS ((int sz)); extern void obj_ecoff_set_ext PARAMS ((struct symbol *, EXTR *)); #endif +/* This routine is called from read.c to generate line number stabs for .s file +*/ +extern void ecoff_generate_asm_line_stab PARAMS ((int)); #endif /* ECOFF_DEBUGGING */ diff --git a/gas/read.c b/gas/read.c index 2aaeae02f75..ce5dfe13919 100644 --- a/gas/read.c +++ b/gas/read.c @@ -60,6 +60,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ char *input_line_pointer; /*->next char of source file to parse. */ +int generate_asm_line_stab = 0; /* flag to generate line stab for .s file */ + #if BITS_PER_CHAR != 8 /* The following table is indexed by[(char)] and will break if a char does not have exactly 256 states (hopefully 0:255!)! */ @@ -544,6 +546,16 @@ read_a_source_file (name) c = *input_line_pointer; *input_line_pointer = '\0'; +#ifdef OBJ_GENERATE_ASM_LINE_STAB + if (generate_asm_line_stab) + { + int lineno; + char *s; + as_where (&s, &lineno); + OBJ_GENERATE_ASM_LINE_STAB (lineno); + } +#endif + md_assemble (s); /* Assemble 1 instruction. */ *input_line_pointer++ = c; @@ -1503,13 +1515,12 @@ pseudo_set (symbolP) symbolS *symbolP; { expressionS exp; -#if defined(OBJ_AOUT) | defined(OBJ_BOUT) +#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER) int ext; #endif /* OBJ_AOUT or OBJ_BOUT */ know (symbolP); /* NULL pointer is logic error. */ -#if defined(OBJ_AOUT) | defined(OBJ_BOUT) - /* @@ Fix this right for BFD. */ +#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER) ext = S_IS_EXTERNAL (symbolP); #endif /* OBJ_AOUT or OBJ_BOUT */ @@ -1542,8 +1553,7 @@ pseudo_set (symbolP) /* Fall through. */ case O_constant: S_SET_SEGMENT (symbolP, absolute_section); -#if defined(OBJ_AOUT) | defined(OBJ_BOUT) - /* @@ Fix this right for BFD. */ +#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER) if (ext) S_SET_EXTERNAL (symbolP); else @@ -1565,8 +1575,7 @@ pseudo_set (symbolP) else { S_SET_SEGMENT (symbolP, S_GET_SEGMENT (exp.X_add_symbol)); -#if defined(OBJ_AOUT) | defined(OBJ_BOUT) - /* @@ Fix this right for BFD! */ +#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER) if (ext) S_SET_EXTERNAL (symbolP); else -- 2.30.2