+/* It is required that we let write_relocs have the opportunity to
+ optimize away fixups before output has begun, since it is possible
+ to eliminate all fixups for a section and thus we never should
+ have generated the relocation section. */
+
+void
+elf_frob_file_after_relocs ()
+{
+#ifdef NEED_ECOFF_DEBUG
+ if (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_get_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_get_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_get_error ()));
+ }
+#endif /* NEED_ECOFF_DEBUG */
+}
+
+#ifdef SCO_ELF
+
+/* Heavily plagarized from obj_elf_version. The idea is to emit the
+ SCO specific identifier in the .notes section to satisfy the SCO
+ linker.
+
+ This looks more complicated than it really is. As opposed to the
+ "obvious" solution, this should handle the cross dev cases
+ correctly. (i.e, hosting on a 64 bit big endian processor, but
+ generating SCO Elf code) Efficiency isn't a concern, as there
+ should be exactly one of these sections per object module.
+
+ SCO OpenServer 5 identifies it's ELF modules with a standard ELF
+ .note section.
+
+ int_32 namesz = 4 ; Name size
+ int_32 descsz = 12 ; Descriptive information
+ int_32 type = 1 ;
+ char name[4] = "SCO" ; Originator name ALWAYS SCO + NULL
+ int_32 version = (major ver # << 16) | version of tools ;
+ int_32 source = (tool_id << 16 ) | 1 ;
+ int_32 info = 0 ; These are set by the SCO tools, but we
+ don't know enough about the source
+ environment to set them. SCO ld currently
+ ignores them, and recommends we set them
+ to zero. */
+
+#define SCO_MAJOR_VERSION 0x1
+#define SCO_MINOR_VERSION 0x1
+
+void
+sco_id ()
+{
+
+ char *name;
+ unsigned int c;
+ char ch;
+ char *p;
+ asection *seg = now_seg;
+ subsegT subseg = now_subseg;
+ Elf_Internal_Note i_note;
+ Elf_External_Note e_note;
+ asection *note_secp = (asection *) NULL;
+ int i, len;
+
+ /* create the .note section */
+
+ note_secp = subseg_new (".note", 0);
+ bfd_set_section_flags (stdoutput,
+ note_secp,
+ SEC_HAS_CONTENTS | SEC_READONLY);
+
+ /* process the version string */
+
+ i_note.namesz = 4;
+ i_note.descsz = 12; /* 12 descriptive bytes */
+ i_note.type = NT_VERSION; /* Contains a version string */
+
+ p = frag_more (sizeof (i_note.namesz));
+ md_number_to_chars (p, (valueT) i_note.namesz, 4);
+
+ p = frag_more (sizeof (i_note.descsz));
+ md_number_to_chars (p, (valueT) i_note.descsz, 4);
+
+ p = frag_more (sizeof (i_note.type));
+ md_number_to_chars (p, (valueT) i_note.type, 4);
+
+ p = frag_more (4);
+ strcpy (p, "SCO");
+
+ /* Note: this is the version number of the ELF we're representing */
+ p = frag_more (4);
+ md_number_to_chars (p, (SCO_MAJOR_VERSION << 16) | (SCO_MINOR_VERSION), 4);
+
+ /* Here, we pick a magic number for ourselves (yes, I "registered"
+ it with SCO. The bottom bit shows that we are compat with the
+ SCO ABI. */
+ p = frag_more (4);
+ md_number_to_chars (p, 0x4c520000 | 0x0001, 4);
+
+ /* If we knew (or cared) what the source language options were, we'd
+ fill them in here. SCO has given us permission to ignore these
+ and just set them to zero. */
+ p = frag_more (4);
+ md_number_to_chars (p, 0x0000, 4);
+
+ frag_align (2, 0, 0);
+
+ /* We probably can't restore the current segment, for there likely
+ isn't one yet... */
+ if (seg && subseg)
+ subseg_set (seg, subseg);