--- /dev/null
+/* ECOFF object file format header file.
+ Copyright (C) 1993 Free Software Foundation, Inc.
+ Contributed by Cygnus Support.
+ Written by Ian Lance Taylor <ian@cygnus.com>.
+
+ This file is part of GAS.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GAS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#define OBJ_ECOFF 1
+
+/* Use the generic ECOFF debugging code. */
+#define ECOFF_DEBUGGING
+
+#include "targ-cpu.h"
+
+#include "ecoff.h"
+
+/* For each gas symbol we keep track of which file it came from, of
+ whether we have generated an ECOFF symbol for it, and whether the
+ symbols is undefined (this last is needed to distinguish a .extern
+ symbols from a .comm symbol). */
+
+#define TARGET_SYMBOL_FIELDS \
+ struct efdr *ecoff_file; \
+ struct localsym *ecoff_symbol; \
+ char ecoff_undefined;
+
+/* Modify the ECOFF symbol. */
+#define obj_frob_symbol(symp, punt) ecoff_frob_symbol (symp)
+
+/* This is used to write the symbolic data in the format that BFD
+ expects it. */
+extern void ecoff_frob_file PARAMS ((void));
+#define obj_frob_file() ecoff_frob_file ()
+
+/* We use the ECOFF functions as our hooks. */
+#define obj_read_begin_hook ecoff_read_begin_hook
+#define obj_symbol_new_hook ecoff_symbol_new_hook
+
+/* At the moment we don't want to do any stabs processing in read.c. */
+#define OBJ_PROCESS_STAB(what, string, type, other, desc) \
+ ecoff_stab ((what), (string), (type), (other), (desc))
#include "elf/mips.h"
#endif
-static int obj_elf_write_symbol_p PARAMS ((symbolS *sym));
-
#ifdef ECOFF_DEBUGGING
static boolean elf_get_extr PARAMS ((asymbol *, EXTR *));
static void elf_set_index PARAMS ((asymbol *, bfd_size_type));
previous_section = 0;
}
-static int
-obj_elf_write_symbol_p (sym)
- symbolS *sym;
-{
- /* If this is a local symbol, are there any relocations for which
- need this symbol? */
-
- /* To find this out, we examine all relocations in all bfd sections
- that have relocations. If there is one that references this
- symbol, we need to keep this symbol. In this case, we return a
- true status. In all other cases, we return a false status. */
-
- if (S_IS_LOCAL (sym))
- {
- asymbol *bsym = sym->bsym;
- bfd *abfd = bsym->the_bfd;
- asection *bsec;
-
- for (bsec = abfd->sections; bsec; bsec = bsec->next)
- {
- struct reloc_cache_entry **rlocs = bsec->orelocation;
- int rcnt = bsec->reloc_count;
-
- if (rlocs)
- {
- int i;
-
- for (i = 0; i < rcnt; i++)
- if (rlocs[i]->sym_ptr_ptr
- && rlocs[i]->sym_ptr_ptr[0] == bsym)
- return 1;
- }
- else
- {
- /* No relocations for this section. Check the seg_info
- structure to see if there are any fixups for this
- section. */
- segment_info_type *seginfo = seg_info (bsec);
- fixS *fixp;
-
- for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
- if ((fixp->fx_addsy && fixp->fx_addsy->bsym == bsym)
- || (fixp->fx_subsy && fixp->fx_subsy->bsym == bsym))
- return 1;
- }
- }
- }
- return 0;
-}
-
-int
-obj_elf_write_symbol (sym)
- symbolS *sym;
-{
- return /* obj_elf_write_symbol_p (sym) || */ !S_IS_LOCAL (sym);
-}
-
-int
-obj_elf_frob_symbol (sym, punt)
- symbolS *sym;
- int *punt;
-{
-#if 0 /* ?? The return value is ignored. Only the value of *punt is
- relevant. */
- return obj_elf_write_symbol_p (sym);
-#endif
- /* FIXME: Just return 0 until is fixed. */
- return 0;
-}
-
static void
obj_elf_line (ignore)
int ignore;
#define BYTES_IN_WORD 4 /* for now */
#include "../bfd/libelf.h"
-#define TARGET_SYMBOL_FIELDS int local:1; unsigned long sy_name_offset;
+/* Symbol fields used by the ELF back end. */
+#define ELF_TARGET_SYMBOL_FIELDS int local:1; unsigned long sy_name_offset;
+
+/* Don't change this; change ELF_TARGET_SYMBOL_FIELDS instead. */
+#define TARGET_SYMBOL_FIELDS ELF_TARGET_SYMBOL_FIELDS
#include "targ-cpu.h"
extern asection *gdb_section;
-#if 0 /* This should not reference i!!
- If it's really needed, fix it, and the call site if necessary. */
-#define obj_frob_symbol(S,PUNT) if ( obj_elf_frob_symbol (S, &PUNT) ) { i++; continue; }
-#endif
-
/* Copy over the function bit and size of a forwarded symbol. */
#define obj_frob_forward_symbol(sym) \
(((sym)->bsym->flags |= \
((sym)->sy_value.X_add_symbol->bsym->flags & BSF_FUNCTION)), \
S_SET_SIZE ((sym), S_GET_SIZE ((sym)->sy_value.X_add_symbol)))
-#define obj_write_symbol(S) obj_elf_write_symbol (S)
-
#define obj_frob_file() elf_frob_file()
-extern int obj_elf_frob_symbol PARAMS ((struct symbol *, int *));
extern void elf_frob_file PARAMS ((void));
extern void elf_file_symbol PARAMS ((char *));
-extern int obj_elf_write_symbol PARAMS ((struct symbol *));
-
extern void obj_elf_section PARAMS ((int));
extern void obj_elf_previous PARAMS ((int));
+extern void obj_elf_version PARAMS ((int));
/* Stabs go in a separate section. */
#define SEPARATE_STAB_SECTIONS
/* We need 12 bytes at the start of the section to hold some initial
information. */
-#define INIT_STAB_SECTION(seg) (seg_info (seg)->stabu.p = frag_more (12))
-
-/* Set the filename offset. */
-#define OBJ_PROCESS_STAB(seg, string, stroff, type, other, desc) \
- ((type) == N_SO \
- ? (md_number_to_chars (seg_info (seg)->stabu.p, \
- (valueT) (stroff), \
- 4), \
- 0) \
- : 0)
+extern void obj_elf_init_stab_section PARAMS ((segT));
+#define INIT_STAB_SECTION(seg) obj_elf_init_stab_section (seg)
+
+/* For now, always set ECOFF_DEBUGGING for a MIPS target. */
+#ifdef TC_MIPS
+#define ECOFF_DEBUGGING
+#endif
+
+#ifdef ECOFF_DEBUGGING
+
+/* If we are generating ECOFF debugging information, we need some
+ additional fields for each symbol. */
+#undef TARGET_SYMBOL_FIELDS
+#define TARGET_SYMBOL_FIELDS \
+ ELF_TARGET_SYMBOL_FIELDS \
+ struct efdr *ecoff_file; \
+ struct localsym *ecoff_symbol; \
+ char ecoff_undefined;
+
+/* We smuggle stabs in ECOFF rather than using a separate section.
+ The Irix linker can not handle a separate stabs section. */
+#undef SEPARATE_STAB_SECTIONS
+#undef INIT_STAB_SECTION
+#define OBJ_PROCESS_STAB(what, string, type, other, desc) \
+ ecoff_stab ((what), (string), (type), (other), (desc))
+
+/* ECOFF requires that we call the ecoff_frob_symbol hook. */
+#define obj_frob_symbol(symp, punt) ecoff_frob_symbol (symp)
+
+#endif /* ECOFF_DEBUGGING */
#endif /* _OBJ_ELF_H */
cur_file_ptr = save_file_ptr;
}
\f
+/* Frob an ECOFF symbol. A .extern symbol will have a value, but is
+ not common. Small common symbols go into a special .scommon
+ section rather than bfd_com_section. */
+
+void
+ecoff_frob_symbol (sym)
+ symbolS *sym;
+{
+ if (sym->ecoff_undefined)
+ S_SET_SEGMENT (sym, undefined_section);
+ else if (S_IS_COMMON (sym)
+ && S_GET_VALUE (sym) > 0
+ && S_GET_VALUE (sym) < bfd_get_gp_size (stdoutput))
+ {
+ static asection scom_section;
+ static asymbol scom_symbol;
+
+ /* We must construct a fake section similar to bfd_com_section
+ but with the name .scommon. */
+ if (scom_section.name == NULL)
+ {
+ scom_section = bfd_com_section;
+ scom_section.name = ".scommon";
+ scom_section.output_section = &scom_section;
+ scom_section.symbol = &scom_symbol;
+ scom_section.symbol_ptr_ptr = &scom_section.symbol;
+ scom_symbol = *bfd_com_section.symbol;
+ scom_symbol.name = ".scommon";
+ scom_symbol.section = &scom_section;
+ }
+ S_SET_SEGMENT (sym, &scom_section);
+ }
+}
+\f
/* Add bytes to the symbolic information buffer. */
static char *