+ HDRR *symhdr;
+ const struct ecoff_debug_swap *swap;
+ char *ext_hdr;
+
+ swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
+
+ ext_hdr = (char *) alloca (swap->external_hdr_size);
+
+ if (bfd_get_section_contents (abfd, section, ext_hdr, (file_ptr) 0,
+ swap->external_hdr_size)
+ == false)
+ return false;
+
+ symhdr = &debug->symbolic_header;
+ (*swap->swap_hdr_in) (abfd, ext_hdr, symhdr);
+
+ /* The symbolic header contains absolute file offsets and sizes to
+ read. */
+#define READ(ptr, offset, count, size, type) \
+ if (symhdr->count == 0) \
+ debug->ptr = NULL; \
+ else \
+ { \
+ debug->ptr = (type) malloc (size * symhdr->count); \
+ if (debug->ptr == NULL) \
+ { \
+ bfd_error = no_memory; \
+ return false; \
+ } \
+ if (bfd_seek (abfd, (file_ptr) symhdr->offset, SEEK_SET) != 0 \
+ || (bfd_read (debug->ptr, size, symhdr->count, \
+ abfd) != size * symhdr->count)) \
+ return false; \
+ }
+
+ READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *);
+ READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, PTR);
+ READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, PTR);
+ READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, PTR);
+ READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, PTR);
+ READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext),
+ union aux_ext *);
+ READ (ss, cbSsOffset, issMax, sizeof (char), char *);
+ READ (ssext, cbSsExtOffset, issExtMax, sizeof (char), char *);
+ READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, PTR);
+ READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, PTR);
+ READ (external_ext, cbExtOffset, iextMax, swap->external_ext_size, PTR);
+
+ return true;
+}
+
+/* Get EXTR information for a symbol. */
+
+static boolean
+mips_elf_get_extr (sym, esym)
+ asymbol *sym;
+ EXTR *esym;
+{
+ if (sym->flags & BSF_SECTION_SYM)
+ return false;
+
+ if (bfd_asymbol_flavour (sym) != bfd_target_elf_flavour
+ || ((elf_symbol_type *) sym)->tc_data.mips_extr == NULL)
+ {
+ esym->jmptbl = 0;
+ esym->cobol_main = 0;
+ esym->weakext = 0;
+ esym->reserved = 0;
+ esym->ifd = ifdNil;
+ /* FIXME: we can do better than this for st and sc. */
+ esym->asym.st = stGlobal;
+ esym->asym.sc = scAbs;
+ esym->asym.reserved = 0;
+ esym->asym.index = indexNil;
+ return true;
+ }
+
+ *esym = *((elf_symbol_type *) sym)->tc_data.mips_extr;
+
+ return true;
+}
+
+/* Set the symbol index for an external symbol. This is actually not
+ needed for ELF. */
+
+/*ARGSUSED*/
+static void
+mips_elf_set_index (sym, indx)
+ asymbol *sym;
+ bfd_size_type indx;
+{
+}
+
+/* We need to use a special link routine to handle the .reginfo and
+ the .mdebug sections. We need to merge all instances of these
+ sections together, not write them all out sequentially. */
+
+static boolean
+mips_elf_final_link (abfd, info)
+ bfd *abfd;
+ struct bfd_link_info *info;
+{
+ bfd *sub;
+ size_t outsymalloc;
+ struct generic_write_global_symbol_info wginfo;
+ asection **secpp;
+ asection *o;
+ struct bfd_link_order *p;
+ asection *reginfo_sec, *mdebug_sec;