(ecoff_directive_def): Set ecoff_debugging_seen.
(ecoff_stab): Likewise.
* ecoff.h: Make idempotent.
(ecoff_debugging_seen): Declare.
* config/tc-mips.c: Include ecoff.h.
(mips_debug): New static variable.
(s_stringer, s_mips_space): Remove unneeded declarations.
(md_parse_option): In case 'g', set mips_debug to debugging level.
(mips_local_label): New function.
* tc-mips.h (LOCAL_LABEL): Call mips_local_label.
(mips_local_label): Declare.
PR 6978.
+Wed Jul 5 12:01:49 1995 Ian Lance Taylor <ian@cygnus.com>
+
+ * ecoff.c (ecoff_debugging_seen): New global variable.
+ (ecoff_directive_def): Set ecoff_debugging_seen.
+ (ecoff_stab): Likewise.
+ * ecoff.h: Make idempotent.
+ (ecoff_debugging_seen): Declare.
+ * config/tc-mips.c: Include ecoff.h.
+ (mips_debug): New static variable.
+ (s_stringer, s_mips_space): Remove unneeded declarations.
+ (md_parse_option): In case 'g', set mips_debug to debugging level.
+ (mips_local_label): New function.
+ * tc-mips.h (LOCAL_LABEL): Call mips_local_label.
+ (mips_local_label): Declare.
+
Wed Jul 5 00:59:22 1995 Fred Fish (fnf@cygnus.com)
* as.c (main): Only use sbrk when HAVE_SBRK defined.
#define ECOFF_DEBUGGING 0
#endif
+#include "ecoff.h"
+
static char *mips_regmask_frag;
#define AT 1
static char *insn_error;
-static int byte_order = BYTE_ORDER;
+static int byte_order;
static int auto_align = 1;
insert NOPs. */
static int mips_optimize = 2;
+/* Debugging level. -g sets this to 2. -gN sets this to N. -g0 is
+ equivalent to seeing no -g option at all. */
+static int mips_debug = 0;
+
/* The previous instruction. */
static struct mips_cl_insn prev_insn;
static symbolS *get_symbol PARAMS ((void));
static void mips_align PARAMS ((int to, int fill, symbolS *label));
static void s_align PARAMS ((int));
-static void s_stringer PARAMS ((int));
static void s_change_sec PARAMS ((int));
static void s_cons PARAMS ((int));
static void s_err PARAMS ((int));
static void s_mips_globl PARAMS ((int));
static void s_option PARAMS ((int));
static void s_mipsset PARAMS ((int));
-static void s_mips_space PARAMS ((int));
static void s_abicalls PARAMS ((int));
static void s_cpload PARAMS ((int));
static void s_cprestore PARAMS ((int));
break;
case OPTION_EB:
- byte_order = BIG_ENDIAN;
target_big_endian = 1;
break;
case OPTION_EL:
- byte_order = LITTLE_ENDIAN;
target_big_endian = 0;
break;
break;
case 'g':
- if (arg == NULL || arg[1] == '2')
+ if (arg == NULL)
+ mips_debug = 2;
+ else
+ mips_debug = atoi (arg);
+ /* When the MIPS assembler sees -g or -g2, it does not do
+ optimizations which limit full symbolic debugging. We take
+ that to be equivalent to -O0. */
+ if (mips_debug == 2)
mips_optimize = 0;
break;
-non_shared do not generate position independent code\n");
#endif
}
+
+void
+mips_init_after_args ()
+{
+ if (target_big_endian)
+ byte_order = BIG_ENDIAN;
+ else
+ byte_order = LITTLE_ENDIAN;
+}
\f
long
md_pcrel_from (fixP)
return ((addr + (1 << align) - 1) & (-1 << align));
}
-/* Estimate the size of a frag before relaxing. We are not really
- relaxing here, and the final size is encoded in the subtype
- information. */
-
/* Utility routine, called from above as well. If called while the
input file is still being read, it's only an approximation. (For
example, a symbol may later become defined which appeared to be
undefined earlier.) */
-static int nopic_need_relax (sym)
+
+static int
+nopic_need_relax (sym)
symbolS *sym;
{
if (sym == 0)
return 1;
}
+/* Estimate the size of a frag before relaxing. We are not really
+ relaxing here, and the final size is encoded in the subtype
+ information. */
+
/*ARGSUSED*/
int
md_estimate_size_before_relax (fragp, segtype)
{
insn_label = sym;
}
+
+/* Decide whether a label is local. This is called by LOCAL_LABEL.
+ In order to work with gcc when using mips-tfile, we must keep all
+ local labels. However, in other cases, we want to discard them,
+ since they are useless. */
+
+int
+mips_local_label (name)
+ const char *name;
+{
+ if (ECOFF_DEBUGGING
+ && mips_debug != 0
+ && ! ecoff_debugging_seen)
+ {
+ /* We were called with -g, but we didn't see any debugging
+ information. That may mean that gcc is smuggling debugging
+ information through to mips-tfile, in which case we must
+ generate all local labels. */
+ return 0;
+ }
+
+ /* Here it's OK to discard local labels. */
+
+ if (name[0] == '$')
+ return 1;
+
+#ifdef TE_IRIX
+ /* gcc for the SGI generates a bunch of local labels named LM%d. I
+ don't know why they don't start with '$'. We must check specially
+ for these. */
+ if (name[0] == 'L' && name[1] == 'M')
+ return 1;
+#endif
+
+ return 0;
+}
\f
#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
along with GAS; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+#ifndef TC_MIPS
+
#define TC_MIPS
#define TARGET_ARCH bfd_arch_mips
#define MAX_RELOC_EXPANSION 3
#define LOCAL_LABELS_FB 1
-/* The MIPS assembler appears to keep all symbols. */
-#define LOCAL_LABEL(name) 0
+#define LOCAL_LABEL(name) mips_local_label (name)
+extern int mips_local_label PARAMS ((const char *));
#define md_relax_frag(fragp, stretch) (0)
#define md_undefined_symbol(name) (0)
#define USE_GLOBAL_POINTER_OPT (OUTPUT_FLAVOR == bfd_target_ecoff_flavour \
|| OUTPUT_FLAVOR == bfd_target_elf_flavour)
+
+extern void mips_pop_insert PARAMS ((void));
+#define md_pop_insert() mips_pop_insert()
+
+extern void mips_flush_pending_output PARAMS ((void));
+#define md_flush_pending_output mips_flush_pending_output
+
+extern void mips_enable_auto_align PARAMS ((void));
+#define md_elf_section_change_hook() mips_enable_auto_align()
+
+extern void mips_init_after_args PARAMS ((void));
+#define tc_init_after_args mips_init_after_args
+
+#endif /* TC_MIPS */
/* Keep track of different sized allocation requests. */
static alloc_info_t alloc_counts[ (int)alloc_type_last ];
\f
+/* Record whether we have seen any debugging information. */
+int ecoff_debugging_seen = 0;
+
/* 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 */
char *name;
char name_end;
+ ecoff_debugging_seen = 1;
+
SKIP_WHITESPACE ();
name = input_line_pointer;
{
if (tq_ptr == &coff_type.type_qualifiers[0])
{
- as_warn ("Too derived values in .type argument");
+ /* FIXME: We could handle this by setting the continued bit.
+ There would still be a limit: the .type argument can not
+ be infinite. */
+ as_warn ("The type of %s is too complex; it will be simplified",
+ coff_sym_name);
break;
}
if (ISPTR (val))
value a numeric value or an address. */
void
-ecoff_stab (what, string, type, other, desc)
+ecoff_stab (sec, what, string, type, other, desc)
+ segT sec;
int what;
const char *string;
int type;
symint_t indx;
localsym_t *hold = NULL;
+ ecoff_debugging_seen = 1;
+
/* We don't handle .stabd. */
if (what != 's' && what != 'n')
{
fil_ptr = fil_ptr->next_file)
{
cur_file_ptr = fil_ptr;
- while (cur_file_ptr->cur_scope->prev != (scope_t *) NULL)
+ while (cur_file_ptr->cur_scope != (scope_t *) NULL
+ && cur_file_ptr->cur_scope->prev != (scope_t *) NULL)
{
cur_file_ptr->cur_scope = cur_file_ptr->cur_scope->prev;
if (! end_warning)
end_warning = 1;
}
}
- (void) add_ecoff_symbol ((const char *) NULL,
- st_End, sc_Text,
- (symbolS *) NULL,
- (symint_t) 0,
- (symint_t) 0);
+ if (cur_file_ptr->cur_scope != (scope_t *) NULL)
+ (void) add_ecoff_symbol ((const char *) NULL,
+ st_End, sc_Text,
+ (symbolS *) NULL,
+ (symint_t) 0,
+ (symint_t) 0);
}
/* Build the symbolic information. */
int sz;
{
if (cur_proc_ptr == 0)
- abort ();
+ return;
cur_proc_ptr->pdr.gp_prologue = sz;
if (cur_proc_ptr->pdr.gp_prologue != sz)
void
ecoff_generate_asm_lineno (filename, lineno)
- char *filename;
- int lineno;
+ const char *filename;
+ int lineno;
{
lineno_list_t *list;
#ifdef ECOFF_DEBUGGING
+#ifndef GAS_ECOFF_H
+#define GAS_ECOFF_H
+
#include "coff/sym.h"
#include "coff/ecoff.h"
+/* Whether we have seen any ECOFF debugging information. */
+extern int ecoff_debugging_seen;
+
/* This function should be called at the start of assembly, by
obj_read_begin_hook. */
extern void ecoff_read_begin_hook PARAMS ((void));
extern void ecoff_directive_val PARAMS ((int));
/* Handle stabs. */
-extern void ecoff_stab PARAMS ((int what, const char *string,
+extern void ecoff_stab PARAMS ((segT sec, int what, const char *string,
int type, int other, int desc));
/* Set the GP prologue size. */
extern void obj_ecoff_set_ext PARAMS ((struct symbol *, EXTR *));
#endif
+/* This function is called from read.c to peek at cur_file_ptr */
+extern int ecoff_no_current_file PARAMS ((void));
+
+/* This routine is called from read.c to generate line number for .s file
+*/
+extern void ecoff_generate_asm_lineno PARAMS ((const char *, int));
+
/* This routine is called from read.c to generate line number stabs for .s file
*/
-extern void ecoff_generate_asm_line_stab PARAMS ((int));
+extern void ecoff_generate_asm_line_stab PARAMS ((char *, int));
+
+#endif /* ! GAS_ECOFF_H */
#endif /* ECOFF_DEBUGGING */