aboutsummaryrefslogtreecommitdiff
path: root/gas/config/obj-elf.c
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>1993-11-24 07:42:03 +0000
committerIan Lance Taylor <ian@airs.com>1993-11-24 07:42:03 +0000
commitc5953036d8466d90cff927d72fc17b179d4889ca (patch)
tree17bb2f7dc07a84001a44d0bf9cb3c819064094d6 /gas/config/obj-elf.c
parent6c35a16d6a1ebce8d60300d9d1e9e4dffb7361d2 (diff)
downloadgdb-c5953036d8466d90cff927d72fc17b179d4889ca.zip
gdb-c5953036d8466d90cff927d72fc17b179d4889ca.tar.gz
gdb-c5953036d8466d90cff927d72fc17b179d4889ca.tar.bz2
* ecoff.c (ecoff_setup_ext): Renamed from ecoff_build_ext.
Changed to not actually build the external symbol information, as that is now done by the ECOFF back end. (ecoff_build_debug): Changed accordingly. * ecoff.h (obj_ecoff_set_ext): Declare. obj-format.c function called by ecoff_setup_ext. * config/obj-ecoff.c (ecoff_frob_file): If debug_info count is 0, set corresponding pointer to NULL. Don't set raw_size and raw_syments. (obj_ecoff_set_sym_index): Removed. (obj_ecoff_set_ext): New function. * config/obj-ecoff.h (obj_set_sym_index): Don't define. (obj_ecoff_set_sym_index): Don't declare. * config/obj-elf.c (obj_ecoff_set_ext, elf_get_extr, elf_set_index): New functions used for ECOFF_DEBUGGING. (elf_frob_file): Reworked ECOFF debug generation to use new functions in bfd/ecofflink.c.
Diffstat (limited to 'gas/config/obj-elf.c')
-rw-r--r--gas/config/obj-elf.c166
1 files changed, 165 insertions, 1 deletions
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index ab46762..a0cf0ac 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -21,8 +21,17 @@
#include "subsegs.h"
#include "obstack.h"
+#ifdef ECOFF_DEBUGGING
+#include "ecoff.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));
+#endif
+
static void obj_elf_line PARAMS ((int));
void obj_elf_version PARAMS ((int));
static void obj_elf_size PARAMS ((int));
@@ -58,6 +67,43 @@ const pseudo_typeS obj_pseudo_table[] =
{"data", obj_elf_data, 0},
{"text", obj_elf_text, 0},
+#ifdef ECOFF_DEBUGGING
+ /* COFF style debugging information for ECOFF. .ln is not used; .loc
+ is used instead. */
+ { "def", ecoff_directive_def, 0 },
+ { "dim", ecoff_directive_dim, 0 },
+ { "endef", ecoff_directive_endef, 0 },
+ { "file", ecoff_directive_file, 0 },
+ { "scl", ecoff_directive_scl, 0 },
+ { "tag", ecoff_directive_tag, 0 },
+ { "val", ecoff_directive_val, 0 },
+
+ /* COFF debugging requires pseudo-ops .size and .type, but ELF
+ already has meanings for those. We use .esize and .etype
+ instead. These are only generated by gcc anyhow. */
+ { "esize", ecoff_directive_size, 0 },
+ { "etype", ecoff_directive_type, 0 },
+
+ /* ECOFF specific debugging information. */
+ { "begin", ecoff_directive_begin, 0 },
+ { "bend", ecoff_directive_bend, 0 },
+ { "end", ecoff_directive_end, 0 },
+ { "ent", ecoff_directive_ent, 0 },
+ { "fmask", ecoff_directive_fmask, 0 },
+ { "frame", ecoff_directive_frame, 0 },
+ { "loc", ecoff_directive_loc, 0 },
+ { "mask", ecoff_directive_mask, 0 },
+
+ /* These are used on Irix. I don't know how to implement them. */
+ { "alias", s_ignore, 0 },
+ { "bgnb", s_ignore, 0 },
+ { "endb", s_ignore, 0 },
+ { "lab", s_ignore, 0 },
+ { "noalias", s_ignore, 0 },
+ { "verstamp", s_ignore, 0 },
+ { "vreg", s_ignore, 0 },
+#endif /* ECOFF_DEBUGGING */
+
{NULL} /* end sentinel */
};
@@ -611,6 +657,9 @@ obj_elf_line (ignore)
void
obj_read_begin_hook ()
{
+#ifdef ECOFF_DEBUGGING
+ ecoff_read_begin_hook ();
+#endif
}
void
@@ -627,6 +676,9 @@ obj_symbol_new_hook (symbolP)
bzero ((char *) &esym->native_elf_sym, sizeof (esym->native_elf_sym));
bzero ((char *) &esym->tc_data, sizeof (esym->tc_data));
#endif
+#ifdef ECOFF_DEBUGGING
+ ecoff_symbol_new_hook (symbolP);
+#endif
}
void
@@ -823,6 +875,7 @@ obj_elf_init_stab_section (seg)
{
char *file;
char *p;
+ char *stabstr_name;
unsigned int stroff;
/* Force the section to align to a longword boundary. Without this,
@@ -831,7 +884,10 @@ obj_elf_init_stab_section (seg)
p = frag_more (12);
as_where (&file, (unsigned int *) NULL);
- stroff = get_stab_string_offset (file, segment_name (seg));
+ stabstr_name = (char *) alloca (strlen (segment_name (seg)) + 4);
+ strcpy (stabstr_name, segment_name (seg));
+ strcat (stabstr_name, "str");
+ stroff = get_stab_string_offset (file, stabstr_name);
know (stroff == 1);
md_number_to_chars (p, stroff, 4);
seg_info (seg)->stabu.p = p;
@@ -872,6 +928,50 @@ adjust_stab_sections (abfd, sec, xxx)
bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8);
}
+#ifdef ECOFF_DEBUGGING
+
+/* This function is called by the ECOFF code. It is supposed to
+ record the external symbol information so that the backend can
+ write it out correctly. The ELF backend doesn't actually handle
+ this at the moment, so we do it ourselves. We save the information
+ in the symbol. */
+
+void
+obj_ecoff_set_ext (sym, ext)
+ symbolS *sym;
+ EXTR *ext;
+{
+ sym->bsym->udata = (PTR) ext;
+}
+
+/* This function is called by bfd_ecoff_debug_externals. It is
+ supposed to *EXT to the external symbol information, and return
+ whether the symbol should be used at all. */
+
+static boolean
+elf_get_extr (sym, ext)
+ asymbol *sym;
+ EXTR *ext;
+{
+ if (sym->udata == NULL)
+ return false;
+ *ext = *(EXTR *) sym->udata;
+ return true;
+}
+
+/* This function is called by bfd_ecoff_debug_externals. It has
+ nothing to do for ELF. */
+
+/*ARGSUSED*/
+static void
+elf_set_index (sym, indx)
+ asymbol *sym;
+ bfd_size_type indx;
+{
+}
+
+#endif /* ECOFF_DEBUGGING */
+
void
elf_frob_file ()
{
@@ -896,4 +996,68 @@ elf_frob_file ()
#ifdef elf_tc_make_sections
elf_tc_make_sections (stdoutput);
#endif
+
+#ifdef ECOFF_DEBUGGING
+ /* Generate the ECOFF debugging information. */
+ {
+ const struct ecoff_debug_swap *debug_swap;
+ struct ecoff_debug_info debug;
+ char *buf;
+ asection *sec;
+
+ debug_swap
+ = get_elf_backend_data (stdoutput)->elf_backend_ecoff_debug_swap;
+ know (debug_swap != (const struct ecoff_debug_swap *) NULL);
+ ecoff_build_debug (&debug.symbolic_header, &buf, debug_swap);
+
+ /* Set up the pointers in debug. */
+#define SET(ptr, offset, type) \
+ debug.ptr = (type) (buf + debug.symbolic_header.offset)
+
+ SET (line, cbLineOffset, unsigned char *);
+ SET (external_dnr, cbDnOffset, PTR);
+ SET (external_pdr, cbPdOffset, PTR);
+ SET (external_sym, cbSymOffset, PTR);
+ SET (external_opt, cbOptOffset, PTR);
+ SET (external_aux, cbAuxOffset, union aux_ext *);
+ SET (ss, cbSsOffset, char *);
+ SET (external_fdr, cbFdOffset, PTR);
+ SET (external_rfd, cbRfdOffset, PTR);
+ /* ssext and external_ext are set up just below. */
+
+#undef SET
+
+ /* Set up the external symbols. */
+ debug.ssext = debug.ssext_end = NULL;
+ debug.external_ext = debug.external_ext_end = NULL;
+ if (! bfd_ecoff_debug_externals (stdoutput, &debug, debug_swap, true,
+ elf_get_extr, elf_set_index))
+ as_fatal ("Failed to set up debugging information: %s",
+ bfd_errmsg (bfd_error));
+
+ sec = bfd_get_section_by_name (stdoutput, ".mdebug");
+ assert (sec != NULL);
+
+ know (stdoutput->output_has_begun == false);
+
+ /* We set the size of the section, call bfd_set_section_contents
+ to force the ELF backend to allocate a file position, and then
+ write out the data. FIXME: Is this really the best way to do
+ this? */
+ sec->_raw_size = bfd_ecoff_debug_size (stdoutput, &debug, debug_swap);
+
+ if (! bfd_set_section_contents (stdoutput, sec, (PTR) NULL,
+ (file_ptr) 0, (bfd_size_type) 0))
+ as_fatal ("Can't start writing .mdebug section: %s",
+ bfd_errmsg (bfd_error));
+
+ know (stdoutput->output_has_begun == true);
+ know (sec->filepos != 0);
+
+ if (! bfd_ecoff_write_debug (stdoutput, &debug, debug_swap,
+ sec->filepos))
+ as_fatal ("Could not write .mdebug section: %s",
+ bfd_errmsg (bfd_error));
+ }
+#endif /* ECOFF_DEBUGGING */
}