*** /tmp/jhh/binutils/ld.c	Thu Jun 21 14:52:49 1990
--- ld.original	Thu Oct 25 22:09:56 1990
***************
*** 23,60 ****
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <sys/file.h>
- #ifndef USG
- #include <sys/time.h>
- #include <sys/resource.h>
- #endif
  #ifndef sony_news
  #include <fcntl.h>
  #endif
  
- #if !defined(A_OUT) && !defined(MACH_O)
- #define A_OUT
- #endif
- 
- #ifdef A_OUT
  #ifdef COFF_ENCAPSULATE
  #include "a.out.encap.h"
  #else
  #include <a.out.h>
  #endif
- #endif
- 
- #ifdef MACH_O
- #ifndef A_OUT
- #include <nlist.h>
- #include <reloc.h>
- #endif
- #ifndef N_TEXT
- #define N_TEXT 0x04
- #define N_DATA 0x06
- #define N_BSS 0x08
- #endif
- #include <sys/loader.h>
- #endif
  
  #ifndef N_SET_MAGIC
  #define N_SET_MAGIC(exec, val)  ((exec).a_magic = val)
--- 23,37 ----
***************
*** 62,78 ****
  
  /* If compiled with GNU C, use the built-in alloca */
  #ifdef __GNUC__
! # define alloca __builtin_alloca
! #else
! # if defined(sun) && defined(sparc)
! #  include "alloca.h"
! # else
! char *alloca ();
! # endif
  #endif
  
- #include "getopt.h"
- 
  /* Always use the GNU version of debugging symbol type codes, if possible.  */
  
  #include "stab.h"
--- 39,47 ----
  
  /* If compiled with GNU C, use the built-in alloca */
  #ifdef __GNUC__
! #define alloca __builtin_alloca
  #endif
  
  /* Always use the GNU version of debugging symbol type codes, if possible.  */
  
  #include "stab.h"
***************
*** 117,129 ****
  /* Define this to specify the default executable format.  */
  
  #ifdef hpux
! #define DEFAULT_OUTPUT_STYLE OUTPUT_READONLY_TEXT
  #endif
  
  /* Ordinary 4.3bsd lacks these macros in a.out.h.  */
  
  #ifndef N_TXTADDR
! #if defined(vax) || defined(sony_news) || defined(hp300) || defined(pyr)
  #define N_TXTADDR(X) 0
  #endif
  #ifdef is68k
--- 86,102 ----
  /* Define this to specify the default executable format.  */
  
  #ifdef hpux
! #define DEFAULT_MAGIC NMAGIC  /* hpux bugs screw ZMAGIC */
  #endif
  
+ #ifndef DEFAULT_MAGIC
+ #define DEFAULT_MAGIC ZMAGIC
+ #endif
+ 
  /* Ordinary 4.3bsd lacks these macros in a.out.h.  */
  
  #ifndef N_TXTADDR
! #if defined(vax) || defined(sony_news)
  #define N_TXTADDR(X) 0
  #endif
  #ifdef is68k
***************
*** 132,144 ****
  #ifdef sequent
  #define	N_TXTADDR(x) (N_ADDRADJ(x))
  #endif
- #ifdef NeXT
- #define N_TXTADDR(X) ((X).a_magic == ZMAGIC ? page_size : 0)
- #endif
  #endif
  
  #ifndef N_DATADDR
! #if defined(vax) || defined(sony_news) || defined(hp300) || defined(pyr)
  #define N_DATADDR(x) \
  	(((x).a_magic==OMAGIC)? (N_TXTADDR(x)+(x).a_text) \
  	: (page_size+((N_TXTADDR(x)+(x).a_text-1) & ~(page_size-1))))
--- 105,114 ----
  #ifdef sequent
  #define	N_TXTADDR(x) (N_ADDRADJ(x))
  #endif
  #endif
  
  #ifndef N_DATADDR
! #if defined(vax) || defined(sony_news)
  #define N_DATADDR(x) \
  	(((x).a_magic==OMAGIC)? (N_TXTADDR(x)+(x).a_text) \
  	: (page_size+((N_TXTADDR(x)+(x).a_text-1) & ~(page_size-1))))
***************
*** 154,172 ****
  	(((x).a_magic==OMAGIC)? (N_TXTADDR(x)+(x).a_text) \
  	: (page_size+(((x).a_text-1) & ~(page_size-1))))
  #endif
- #ifdef NeXT
- #define N_DATADDR(X) \
- 	(((X).a_magic==ZMAGIC)?(N_TXTADDR(X)+(X).a_text+0xFFFF)&~0xFFFF \
- 	 :N_TXTADDR(X)+(X).a_text)
  #endif
- #endif
- 
- /* The "address" of the data segment in a relocatable file.
-    The text address of a relocatable file is always
-    considered to be zero (instead of the value of N_TXTADDR, which
-    is what the address is in an executable), so we need to subtract
-    N_TXTADDR from N_DATADDR to get the "address" for the input file.  */
- #define DATA_ADDR_DOT_O(hdr) (N_DATADDR(hdr) - N_TXTADDR(hdr))
  
  /* Define how to initialize system-dependent header fields.  */
  #ifdef sun
--- 124,130 ----
***************
*** 173,195 ****
  #ifdef sparc
  #define INITIALIZE_HEADER \
    {outheader.a_machtype = M_SPARC; outheader.a_toolversion = 1;}
! #endif /* sparc.  */
! #if defined(mc68000)
! /* Set the machine type according to the machine type of the .o files.
!    If they are all sun2 (68010), then the type of the executable is sun2.
!    If any is sun3 (68020), then the type of the executable is sun3.
!    This is consistent with the Sun loader and more useful than having
!    it depend on which machine you are on when you run ld.  */
! static int sun_machtype = M_68010;
! #define INITIALIZE_HEADER outheader.a_machtype = sun_machtype
! #define READ_HEADER_HOOK(machtype) \
!   if (machtype == M_68020)           \
!     {				     \
!       sun_machtype = M_68020;	     \
!     }
! #endif /* mc68000.  */
! #endif /* Sun.  */
! 
  #ifdef ALTOS
  #define INITIALIZE_HEADER N_SET_MACHTYPE (outheader, M_68020)
  #endif
--- 131,144 ----
  #ifdef sparc
  #define INITIALIZE_HEADER \
    {outheader.a_machtype = M_SPARC; outheader.a_toolversion = 1;}
! #endif
! #if defined(mc68010) || defined(m68010)
! #define INITIALIZE_HEADER outheader.a_machtype = M_68010
! #endif
! #ifndef INITIALIZE_HEADER
! #define INITIALIZE_HEADER outheader.a_machtype = M_68020
! #endif
! #endif
  #ifdef ALTOS
  #define INITIALIZE_HEADER N_SET_MACHTYPE (outheader, M_68020)
  #endif
***************
*** 206,218 ****
  #endif
  #if defined(i386) && !defined(sequent)
  #define INITIALIZE_HEADER N_SET_MACHTYPE (outheader, M_386)
! #endif /* Sequent symmetry.  */
! #if defined(hp300)
! #define INITIALIZE_HEADER outheader.a_mid = MID_HP300
! #endif /* hp300.  */
! #ifdef pyr
! #define INITIALIZE_HEADER outheader.a_machid = PYR90X
! #endif /* Pyramid.  */
  
  #ifdef is68k
  /* This enables code to take care of an ugly hack in the ISI OS.
--- 155,161 ----
  #endif
  #if defined(i386) && !defined(sequent)
  #define INITIALIZE_HEADER N_SET_MACHTYPE (outheader, M_386)
! #endif
  
  #ifdef is68k
  /* This enables code to take care of an ugly hack in the ISI OS.
***************
*** 221,234 ****
  #define DOLLAR_KLUDGE
  #endif
  
! /* Values for 3rd argument to lseek().  */
  #ifndef L_SET
  #define L_SET 0
  #endif
- /* This is called L_INCR in BSD, but SEEK_CUR in POSIX.  */
- #ifndef SEEK_CUR
- #define SEEK_CUR 1
- #endif
  
  /*
   * Ok.  Following are the relocation information macros.  If your
--- 164,179 ----
  #define DOLLAR_KLUDGE
  #endif
  
! /*
!  * Alloca include.
!  */
! #if defined(sun) && defined(sparc) && !defined(__GNUC__)
! #include "alloca.h"
! #endif
! 
  #ifndef L_SET
  #define L_SET 0
  #endif
  
  /*
   * Ok.  Following are the relocation information macros.  If your
***************
*** 248,254 ****
   * what the value of the relocation actually was.  *Must be an lvalue*.
   *
   *   RELOC_TYPE (rval): For a non-external relocation, this is the
!  * segment to relocate for.  *Must be an lvalue.*
   *
   *   RELOC_SYMBOL (rval): For an external relocation, this is the
   * index of its symbol in the symbol table.  *Must be an lvalue*.
--- 193,199 ----
   * what the value of the relocation actually was.  *Must be an lvalue*.
   *
   *   RELOC_TYPE (rval): For a non-external relocation, this is the
!  * segment to relocate for.
   *
   *   RELOC_SYMBOL (rval): For an external relocation, this is the
   * index of its symbol in the symbol table.  *Must be an lvalue*.
***************
*** 312,324 ****
  /* Sparc (Sun 4) macros */
  #undef relocation_info
  #define relocation_info	                reloc_info_sparc
! #define RELOC_ADDRESS(r)		((r)->r_address)
! #define RELOC_EXTERN_P(r)               ((r)->r_extern)
! #define RELOC_TYPE(r)                   ((r)->r_index)
! #define RELOC_SYMBOL(r)                 ((r)->r_index)
  #define RELOC_MEMORY_SUB_P(r)		0
  #define RELOC_MEMORY_ADD_P(r)           0
! #define RELOC_ADD_EXTRA(r)              ((r)->r_addend)
  #define RELOC_PCREL_P(r)             \
          ((r)->r_type >= RELOC_DISP8 && (r)->r_type <= RELOC_WDISP22)
  #define RELOC_VALUE_RIGHTSHIFT(r)       (reloc_target_rightshift[(r)->r_type])
--- 257,269 ----
  /* Sparc (Sun 4) macros */
  #undef relocation_info
  #define relocation_info	                reloc_info_sparc
! #define RELOC_ADDRESS(r)		((r)->r_address)                 
! #define RELOC_EXTERN_P(r)               ((r)->r_extern)      
! #define RELOC_TYPE(r)                   ((r)->r_index)  
! #define RELOC_SYMBOL(r)                 ((r)->r_index)   
  #define RELOC_MEMORY_SUB_P(r)		0
  #define RELOC_MEMORY_ADD_P(r)           0
! #define RELOC_ADD_EXTRA(r)              ((r)->r_addend)       
  #define RELOC_PCREL_P(r)             \
          ((r)->r_type >= RELOC_DISP8 && (r)->r_type <= RELOC_WDISP22)
  #define RELOC_VALUE_RIGHTSHIFT(r)       (reloc_target_rightshift[(r)->r_type])
***************
*** 399,405 ****
     So, for example, the following two lines placed in an assembler
     input file would result in an object file which would direct gnu ld
     to resolve all references to symbol "foo" as references to symbol
!    "bar".
  
  	.stabs "_foo",11,0,0,0
  	.stabs "_bar",1,0,0,0
--- 344,350 ----
     So, for example, the following two lines placed in an assembler
     input file would result in an object file which would direct gnu ld
     to resolve all references to symbol "foo" as references to symbol
!    "bar". 
  
  	.stabs "_foo",11,0,0,0
  	.stabs "_bar",1,0,0,0
***************
*** 495,501 ****
  
  /* If a this type of symbol is encountered, its name is a warning
     message to print each time the symbol referenced by the next symbol
!    table entry is referenced.
  
     This feature may be used to allow backwards compatibility with
     certain functions (eg. gets) but to discourage programmers from
--- 440,446 ----
  
  /* If a this type of symbol is encountered, its name is a warning
     message to print each time the symbol referenced by the next symbol
!    table entry is referenced.   
  
     This feature may be used to allow backwards compatibility with
     certain functions (eg. gets) but to discourage programmers from
***************
*** 557,563 ****
        /* Nonzero means definitions of this symbol as common have been seen,
  	 and the value here is the largest size specified by any of them.  */
        int max_common_size;
!       /* For OUTPUT_RELOCATABLE, records the index of this global sym in the
  	 symbol table to be written, with the first global sym given index 0.*/
        int def_count;
        /* Nonzero means a definition of this global symbol is known to exist.
--- 502,508 ----
        /* Nonzero means definitions of this symbol as common have been seen,
  	 and the value here is the largest size specified by any of them.  */
        int max_common_size;
!       /* For relocatable_output, records the index of this global sym in the
  	 symbol table to be written, with the first global sym given index 0.*/
        int def_count;
        /* Nonzero means a definition of this global symbol is known to exist.
***************
*** 585,599 ****
      }
    symbol;
  
- /* Demangler for C++.  */
- extern char *cplus_demangle ();
- 
- /* Demangler function to use.  We unconditionally enable the C++ demangler
-    because we assume any name it successfully demangles was probably produced
-    by the C++ compiler.  Enabling it only if -lg++ was specified seems too
-    much of a kludge.  */
- char *(*demangler)() = cplus_demangle;
- 
  /* Number of buckets in symbol hash table */
  #define	TABSIZE	1009
  
--- 530,535 ----
***************
*** 675,694 ****
     -e sets this.  */
  symbol *entry_symbol;
  
- /* These can be NULL if we don't actually have such a symbol.  */
  symbol *edata_symbol;   /* the symbol _edata */
  symbol *etext_symbol;   /* the symbol _etext */
  symbol *end_symbol;	/* the symbol _end */
- /* We also need __{edata,etext,end} so that they can safely
-    be used from an ANSI library.  */
- symbol *edata_symbol_alt;
- symbol *etext_symbol_alt;
- symbol *end_symbol_alt;
  
- /* Kinds of files potentially understood by the linker. */
- 
- enum file_type { IS_UNKNOWN, IS_ARCHIVE, IS_A_OUT, IS_MACH_O };
- 
  /* Each input file, and each library member ("subfile") being loaded,
     has a `file_entry' structure for it.
  
--- 611,620 ----
***************
*** 704,771 ****
  struct file_entry {
    /* Name of this file.  */
    char *filename;
- 
-   /* What kind of file this is. */
-   enum file_type file_type;
- 
    /* Name to use for the symbol giving address of text start */
    /* Usually the same as filename, but for a file spec'd with -l
       this is the -l switch itself rather than the filename.  */
    char *local_sym_name;
  
!   /* Describe the layout of the contents of the file.  */
  
!   /* The text section. */
!   unsigned long int orig_text_address;
!   unsigned long int text_size;
!   long int text_offset;
! 
!   /* Text relocation. */
!   unsigned long int text_reloc_size;
!   long int text_reloc_offset;
! 
!   /* The data section. */
!   unsigned long int orig_data_address;
!   unsigned long int data_size;
!   long int data_offset;
! 
!   /* Data relocation. */
!   unsigned long int data_reloc_size;
!   long int data_reloc_offset;
! 
!   /* The bss section. */
!   unsigned long int orig_bss_address;
!   unsigned long int bss_size;
! 
!   /* The symbol and string tables. */
!   unsigned long int syms_size;
!   long int syms_offset;
!   unsigned long int strs_size;
!   long int strs_offset;
! 
!   /* The GDB symbol segment, if any. */
!   unsigned long int symseg_size;
!   long int symseg_offset;
! 
! #ifdef MACH_O
!   /* Section ordinals from the Mach-O load commands.  These
!      are compared with the n_sect fields of symbols.  */
!   int text_ordinal;
!   int data_ordinal;
!   int bss_ordinal;
! #endif
  
    /* Describe data from the file loaded into core */
  
    /* Symbol table of the file.  */
    struct nlist *symbols;
! 
    /* Pointer to the string table.
       The string table is not kept in core all the time,
       but when it is in core, its address is here.  */
    char *strings;
  
!   /* Next two used only if OUTPUT_RELOCATABLE or if needed for */
    /* output of undefined reference line numbers. */
  
    /* Text reloc info saved by `write_text' for `coptxtrel'.  */
--- 630,659 ----
  struct file_entry {
    /* Name of this file.  */
    char *filename;
    /* Name to use for the symbol giving address of text start */
    /* Usually the same as filename, but for a file spec'd with -l
       this is the -l switch itself rather than the filename.  */
    char *local_sym_name;
  
!   /* Describe the layout of the contents of the file */
  
!   /* The file's a.out header.  */
!   struct exec header;
!   /* Offset in file of GDB symbol segment, or 0 if there is none.  */
!   int symseg_offset;
  
    /* Describe data from the file loaded into core */
  
    /* Symbol table of the file.  */
    struct nlist *symbols;
!   /* Size in bytes of string table.  */
!   int string_size;
    /* Pointer to the string table.
       The string table is not kept in core all the time,
       but when it is in core, its address is here.  */
    char *strings;
  
!   /* Next two used only if `relocatable_output' or if needed for */
    /* output of undefined reference line numbers. */
  
    /* Text reloc info saved by `write_text' for `coptxtrel'.  */
***************
*** 836,905 ****
  
  char *output_filename;
  
! /* What kind of output file to write.  */
  
! enum file_type output_file_type;
  
! #ifndef DEFAULT_OUTPUT_FILE_TYPE
! #ifdef MACH_O
! #define DEFAULT_OUTPUT_FILE_TYPE IS_MACH_O
! #else
! #define DEFAULT_OUTPUT_FILE_TYPE IS_A_OUT
! #endif
! #endif
! 
! /* What `style' of output file to write.  For BSD a.out files
!    this specifies OMAGIC, NMAGIC, or ZMAGIC.  For Mach-O files
!    this switches between MH_OBJECT and two flavors of MH_EXECUTE.  */
  
! enum output_style
!   {
!     OUTPUT_UNSPECIFIED,
!     OUTPUT_RELOCATABLE,		/* -r */
!     OUTPUT_WRITABLE_TEXT,	/* -N */
!     OUTPUT_READONLY_TEXT,	/* -n */
!     OUTPUT_DEMAND_PAGED		/* -Z (default) */
!   };
! 
! enum output_style output_style;
  
! #ifndef DEFAULT_OUTPUT_STYLE
! #define DEFAULT_OUTPUT_STYLE OUTPUT_DEMAND_PAGED
  #endif
  
- /* Descriptor for writing that file with `mywrite'.  */
- 
- int outdesc;
- 
  /* The following are computed by `digest_symbols'.  */
  
! int text_size;			/* total size of text of all input files.  */
! int text_header_size;		/* size of the file header if included in the
! 				   text size.  */
! int data_size;			/* total size of data of all input files.  */
! int bss_size;			/* total size of bss of all input files.  */
! int text_reloc_size;		/* total size of text relocation of all input files.  */
! int data_reloc_size;		/* total size of data relocation of all input
! 				   files.  */
!   
! /* The following are computed by write_header().  */
! long int output_text_offset;	/* file offset of the text section.  */
! long int output_data_offset;	/* file offset of the data section.  */
! long int output_trel_offset;	/* file offset of the text relocation info.  */
! long int output_drel_offset;	/* file offset of the data relocation info.  */
! long int output_syms_offset;	/* file offset of the symbol table.  */
! long int output_strs_offset;	/* file offset of the string table.  */
! 
! /* The following are incrementally computed by write_syms(); we keep
!    them here so we can examine their values afterwards.  */
! unsigned int output_syms_size;	/* total bytes of symbol table output. */
! unsigned int output_strs_size;	/* total bytes of string table output. */
! 
! /* This can only be computed after the size of the string table is known.  */
! long int output_symseg_offset;	/* file offset of the symbol segment (if any).  */
! 
! /* Incrementally computed by write_file_symseg().  */
! unsigned int output_symseg_size;
  
  /* Specifications of start and length of the area reserved at the end
     of the text segment for the set vectors.  Computed in 'digest_symbols' */
--- 724,750 ----
  
  char *output_filename;
  
! /* Descriptor for writing that file with `mywrite'.  */
  
! int outdesc;
  
! /* Header for that file (filled in by `write_header').  */
  
! struct exec outheader;
  
! #ifdef COFF_ENCAPSULATE
! struct coffheader coffheader;
! int need_coff_header;
  #endif
  
  /* The following are computed by `digest_symbols'.  */
  
! int text_size;		/* total size of text of all input files.  */
! int data_size;		/* total size of data of all input files.  */
! int bss_size;		/* total size of bss of all input files.  */
! int text_reloc_size;	/* total size of text relocation of all input files.  */
! int data_reloc_size;	/* total size of data relocation of all input */
! 			/* files.  */
  
  /* Specifications of start and length of the area reserved at the end
     of the text segment for the set vectors.  Computed in 'digest_symbols' */
***************
*** 910,922 ****
     written. */
  unsigned long *set_vectors;
  
! /* Amount of cleared space to leave at the end of the text segment.  */
  
  int text_pad;
  
! /* Amount of padding at end of data segment.  This has two parts:
!    That which is before the bss segment, and that which overlaps
!    with the bss segment.  */
  int data_pad;
  
  /* Format of __.SYMDEF:
--- 755,766 ----
     written. */
  unsigned long *set_vectors;
  
! /* Amount of cleared space to leave between the text and data segments.  */
  
  int text_pad;
  
! /* Amount of bss segment to include as part of the data segment.  */
! 
  int data_pad;
  
  /* Format of __.SYMDEF:
***************
*** 937,945 ****
--- 781,796 ----
     write any padding in the output file for it.  */
  int text_start;
  
+ /* Offset of default entry-pc within the text section.  */
+ int entry_offset;
+ 
  /* Address we decide the data section will be loaded at.  */
  int data_start;
  
+ /* `text-start' address is normally this much plus a page boundary.
+    This is not a user option; it is fixed for each system.  */
+ int text_start_alignment;
+ 
  /* Nonzero if -T was specified in the command line.
     This prevents text_start from being set later to default values.  */
  int T_flag_specified;
***************
*** 953,958 ****
--- 804,812 ----
     and reduce the size of the bss section to match.  */
  int specified_data_size;
  
+ /* Magic number to use for the output file, set by switch.  */
+ int magic;
+ 
  /* Nonzero means print names of input files as processed.  */
  int trace_files;
  
***************
*** 968,974 ****
  /* 1 => write load map.  */
  int write_map;
  
! /* 1 => assign space to common symbols even if OUTPUT_RELOCATABLE. */
  int force_common_definition;
  
  /* Standard directories to search for files specified by -l.  */
--- 822,831 ----
  /* 1 => write load map.  */
  int write_map;
  
! /* 1 => write relocation into output file so can re-input it later.  */
! int relocatable_output;
! 
! /* 1 => assign space to common symbols even if `relocatable_output'.  */
  int force_common_definition;
  
  /* Standard directories to search for files specified by -l.  */
***************
*** 983,991 ****
  #endif
  #endif
  
- /* If set STANDARD_SEARCH_DIRS is not searched.  */
- int no_standard_dirs;
- 
  /* Actual vector of directories to search;
     this contains those specified with -L plus the standard ones.  */
  char **search_dirs;
--- 840,845 ----
***************
*** 993,1000 ****
  /* Length of the vector `search_dirs'.  */
  int n_search_dirs;
  
! /* Non zero means to create the output executable.
!    Cleared by nonfatal errors.  */
  int make_executable;
  
  /* Force the executable to be output, even if there are non-fatal
--- 847,854 ----
  /* Length of the vector `search_dirs'.  */
  int n_search_dirs;
  
! /* Non zero means to create the output executable. */
! /* Cleared by nonfatal errors.  */
  int make_executable;
  
  /* Force the executable to be output, even if there are non-fatal
***************
*** 1007,1021 ****
  struct glosym **cmdline_references;
  int cl_refs_allocated;
  
- #ifndef bcopy
  void bcopy (), bzero ();
  #endif
! char *malloc (), *realloc ();
! void free ();
  
! char *xmalloc ();
! char *xrealloc ();
! void usage ();
  void fatal ();
  void fatal_with_file ();
  void perror_name ();
--- 861,875 ----
  struct glosym **cmdline_references;
  int cl_refs_allocated;
  
  void bcopy (), bzero ();
+ int malloc (), realloc ();
+ #ifndef alloca
+ int alloca ();
  #endif
! int free ();
  
! int xmalloc ();
! int xrealloc ();
  void fatal ();
  void fatal_with_file ();
  void perror_name ();
***************
*** 1022,1030 ****
  void perror_file ();
  void error ();
  
- int parse ();
- void initialize_text_start ();
- void initialize_data_start ();
  void digest_symbols ();
  void print_symbols ();
  void load_symbols ();
--- 876,881 ----
***************
*** 1054,1070 ****
    page_size = getpagesize ();
    progname = argv[0];
  
- #ifdef RLIMIT_STACK
-   /* Avoid dumping core on large .o files.  */
-   {
-     struct rlimit rl;
- 
-     getrlimit (RLIMIT_STACK, &rl);
-     rl.rlim_cur = rl.rlim_max;
-     setrlimit (RLIMIT_STACK, &rl);
-   }
- #endif
- 
    /* Clear the cumulative info on the output file.  */
  
    text_size = 0;
--- 905,910 ----
***************
*** 1084,1092 ****
--- 924,934 ----
    discard_locals = DISCARD_NONE;
    entry_symbol = 0;
    write_map = 0;
+   relocatable_output = 0;
    force_common_definition = 0;
    T_flag_specified = 0;
    Tdata_flag_specified = 0;
+   magic = DEFAULT_MAGIC;
    make_executable = 1;
    force_executable = 0;
    set_element_prefixes = 0;
***************
*** 1105,1111 ****
    common_defined_global_count = 0;
  
    /* Keep a list of symbols referenced from the command line */
- 
    cl_refs_allocated = 10;
    cmdline_references
      = (struct glosym **) xmalloc (cl_refs_allocated
--- 947,952 ----
***************
*** 1116,1133 ****
  
    decode_command (argc, argv);
  
    /* Load symbols of all input files.
       Also search all libraries and decide which library members to load.  */
  
    load_symbols ();
  
-   /* Create various built-in symbols.  This must occur after
-      all input files are loaded so that a user program can have a
-      symbol named etext (for example).  */
- 
-   if (output_style != OUTPUT_RELOCATABLE)
-     symtab_init ();
- 
    /* Compute where each file's sections go, and relocate symbols.  */
  
    digest_symbols ();
--- 957,1004 ----
  
    decode_command (argc, argv);
  
+   /* Create the symbols `etext', `edata' and `end'.  */
+ 
+   if (!relocatable_output)
+     symtab_init ();
+ 
+   /* Determine whether to count the header as part of
+      the text size, and initialize the text size accordingly.
+      This depends on the kind of system and on the output format selected.  */
+ 
+   N_SET_MAGIC (outheader, magic);
+ #ifdef INITIALIZE_HEADER
+   INITIALIZE_HEADER;
+ #endif
+ 
+   text_size = sizeof (struct exec);
+ #ifdef COFF_ENCAPSULATE
+   if (relocatable_output == 0)
+     {
+       need_coff_header = 1;
+       /* set this flag now, since it will change the values of N_TXTOFF, etc */
+       N_SET_FLAGS (outheader, N_FLAGS_COFF_ENCAPSULATE);
+       text_size += sizeof (struct coffheader);
+     }
+ #endif
+ 
+   text_size -= N_TXTOFF (outheader);
+ 
+   if (text_size < 0)
+     text_size = 0;
+   entry_offset = text_size;
+ 
+   if (!T_flag_specified && !relocatable_output)
+     text_start = N_TXTADDR (outheader);
+ 
+   /* The text-start address is normally this far past a page boundary.  */
+   text_start_alignment = text_start % page_size;
+ 
    /* Load symbols of all input files.
       Also search all libraries and decide which library members to load.  */
  
    load_symbols ();
  
    /* Compute where each file's sections go, and relocate symbols.  */
  
    digest_symbols ();
***************
*** 1149,1191 ****
    exit (!make_executable);
  }
  
! void add_cmdline_ref ();
  
! static struct option longopts[] =
! {
!   {"d", 0, 0, 'd'},
!   {"dc", 0, 0, 'd'},		/* For Sun compatibility. */
!   {"dp", 0, 0, 'd'},		/* For Sun compatibility. */
!   {"e", 1, 0, 'e'},
!   {"n", 0, 0, 'n'},
!   {"noinhibit-exec", 0, 0, 130},
!   {"nostdlib", 0, 0, 133},
!   {"o", 1, 0, 'o'},
!   {"r", 0, 0, 'r'},
!   {"s", 0, 0, 's'},
!   {"t", 0, 0, 't'},
!   {"u", 1, 0, 'u'},
!   {"x", 0, 0, 'x'},
!   {"z", 0, 0, 'z'},
!   {"A", 1, 0, 'A'},
!   {"Bstatic", 0, 0, 129},	/* For Sun compatibility. */
!   {"D", 1, 0, 'D'},
!   {"M", 0, 0, 'M'},
!   {"N", 0, 0, 'N'},
!   {"S", 0, 0, 'S'},
!   {"T", 1, 0, 'T'},
!   {"Ttext", 1, 0, 'T'},
!   {"Tdata", 1, 0, 132},
!   {"V", 1, 0, 'V'},
!   {"X", 0, 0, 'X'},
!   {0, 0, 0, 0}
! };
! 
! /* Since the Unix ld accepts -lfoo, -Lfoo, and -yfoo, we must also.
!    This effectively prevents any long options from starting with
!    one of these letters. */
! #define SHORTOPTS "-l:y:L:"
  
  /* Process the command arguments,
     setting up file_table with an entry for each input file,
     and setting variables according to the options.  */
--- 1020,1072 ----
    exit (!make_executable);
  }
  
! void decode_option ();
  
! /* Analyze a command line argument.
!    Return 0 if the argument is a filename.
!    Return 1 if the argument is a option complete in itself.
!    Return 2 if the argument is a option which uses an argument.
! 
!    Thus, the value is the number of consecutive arguments
!    that are part of options.  */
! 
! int
! classify_arg (arg)
!      register char *arg;
! {
!   if (*arg != '-') return 0;
!   switch (arg[1])
!     {
!     case 'A':
!     case 'D':
!     case 'e':
!     case 'L':
!     case 'l':
!     case 'o':
!     case 'u':
!     case 'V':
!     case 'y':
!       if (arg[2])
! 	return 1;
!       return 2;
! 
!     case 'B':
!       if (! strcmp (&arg[2], "static"))
! 	return 1;
! 
!     case 'T':
!       if (arg[2] == 0)
! 	return 2;
!       if (! strcmp (&arg[2], "text"))
! 	return 2;
!       if (! strcmp (&arg[2], "data"))
! 	return 2;
!       return 1;
!     }
  
+   return 1;
+ }
+ 
  /* Process the command arguments,
     setting up file_table with an entry for each input file,
     and setting variables according to the options.  */
***************
*** 1195,1201 ****
       char **argv;
       int argc;
  {
!   int optc, longind;
    register struct file_entry *p;
  
    number_of_files = 0;
--- 1076,1082 ----
       char **argv;
       int argc;
  {
!   register int i;
    register struct file_entry *p;
  
    number_of_files = 0;
***************
*** 1204,1437 ****
    n_search_dirs = 0;
    search_dirs = (char **) xmalloc (sizeof (char *));
  
!   /* First compute number_of_files so we know how long to make file_table.
!      Also process most options completely.  */
! 
!   while ((optc = getopt_long_only (argc, argv, SHORTOPTS, longopts, &longind))
! 	 != EOF)
!     {
!       if (optc == 0)
! 	optc = longopts[longind].val;
! 
!       switch (optc)
! 	{
! 	case '?':
! 	  usage (0, 0);
! 	  break;
! 
! 	case 1:
! 	  /* Non-option argument. */
! 	  number_of_files++;
! 	  break;
! 
! 	case 'd':
! 	  force_common_definition = 1;
! 	  break;
! 
! 	case 'e':
! 	  entry_symbol = getsym (optarg);
! 	  if (!entry_symbol->defined && !entry_symbol->referenced)
! 	    undefined_global_sym_count++;
! 	  entry_symbol->referenced = 1;
! 	  add_cmdline_ref (entry_symbol);
! 	  break;
! 
! 	case 'l':
! 	  number_of_files++;
! 	  break;
! 
! 	case 'n':
! 	  if (output_style && output_style != OUTPUT_READONLY_TEXT)
! 	    fatal ("illegal combination of -n with -N, -r, or -z", (char *) 0);
! 	  output_style = OUTPUT_READONLY_TEXT;
! 	  break;
! 
! 	case 130:		/* -noinhibit-exec */
! 	  force_executable = 1;
! 	  break;
! 
! 	case 133:		/* -nostdlib */
! 	  no_standard_dirs = 1;
! 	  break;
! 
! 	case 'o':
! 	  output_filename = optarg;
! 	  break;
! 
! 	case 'r':
! 	  if (output_style && output_style != OUTPUT_RELOCATABLE)
! 	    fatal ("illegal combination of -r with -N, -n, or -z", (char *) 0);
! 	  output_style = OUTPUT_RELOCATABLE;
! 	  text_start = 0;
! 	  break;
! 
! 	case 's':
! 	  strip_symbols = STRIP_ALL;
! 	  break;
! 
! 	case 't':
! 	  trace_files = 1;
! 	  break;
! 
! 	case 'u':
! 	  {
! 	    register symbol *sp = getsym (optarg);
! 
! 	    if (!sp->defined && !sp->referenced)
! 	      undefined_global_sym_count++;
! 	    sp->referenced = 1;
! 	    add_cmdline_ref (sp);
! 	  }
! 	  break;
! 
! 	case 'x':
! 	  discard_locals = DISCARD_ALL;
! 	  break;
! 	  
! 	case 'y':
! 	  {
! 	    register symbol *sp = getsym (optarg);
! 
! 	    sp->trace = 1;
! 	  }
! 	  break;
! 
! 	case 'z':
! 	  if (output_style && output_style != OUTPUT_DEMAND_PAGED)
! 	    fatal ("illegal combination of -z with -N, -n, or -r", (char *) 0);
! 	  output_style = OUTPUT_DEMAND_PAGED;
! 	  break;
! 
! 	case 'A':
! 	  number_of_files++;
! 	  break;
! 
! 	case 129:		/* -Bstatic. */
! 	  /* Ignore. */
! 	  break;
! 
! 	case 'D':
! 	  specified_data_size = parse (optarg, "%x", "invalid argument to -D");
! 	  break;
! 
! 	case 'L':
! 	  n_search_dirs++;
! 	  search_dirs = (char **)
! 	    xrealloc (search_dirs, n_search_dirs * sizeof (char *));
! 	  search_dirs[n_search_dirs - 1] = optarg;
! 	  break;
! 	  
! 	case 'M':
! 	  write_map = 1;
! 	  break;
! 
! 	case 'N':
! 	  if (output_style && output_style != OUTPUT_WRITABLE_TEXT)
! 	    fatal ("illegal combination of -N with -n, -r, or -z", (char *) 0);
! 	  output_style = OUTPUT_WRITABLE_TEXT;
! 	  break;
! 
! 	case 'S':
! 	  strip_symbols = STRIP_DEBUGGER;
! 	  break;
! 
! 	case 'T':
! 	  text_start = parse (optarg, "%x", "invalid argument to -Ttext");
! 	  T_flag_specified = 1;
! 	  break;
! 
! 	case 132:		/* -Tdata addr */
! 	  data_start = parse (optarg, "%x", "invalid argument to -Tdata");
! 	  Tdata_flag_specified = 1;
! 	  break;
! 
! 	case 'V':
! 	  {
! 	    struct string_list_element *new
! 	      = (struct string_list_element *)
! 		xmalloc (sizeof (struct string_list_element));
! 	    
! 	    new->str = optarg;
! 	    new->next = set_element_prefixes;
! 	    set_element_prefixes = new;
! 	  }
! 	  break;
  
! 	case 'X':
! 	  discard_locals = DISCARD_L;
! 	  break;
  	}
      }
  
    if (!number_of_files)
!     usage ("no input files", 0);
  
    p = file_table
      = (struct file_entry *) xmalloc (number_of_files * sizeof (struct file_entry));
    bzero (p, number_of_files * sizeof (struct file_entry));
  
!   /* Now scan again and fill in file_table.
!      All options except -A and -l are ignored here.  */
  
!   optind = 0;			/* Reset getopt. */
!   while ((optc = getopt_long_only (argc, argv, SHORTOPTS, longopts, &longind))
! 	 != EOF)
!     {
!       if (optc == 0)
! 	optc = longopts[longind].val;
! 
!       switch (optc)
  	{
! 	case 1:
! 	  /* Non-option argument. */
! 	  p->filename = optarg;
! 	  p->local_sym_name = optarg;
! 	  p++;
! 	  break;
! 
! 	case 'A':
! 	  if (p != file_table)
! 	    usage ("-A specified before an input file other than the first");
! 	  p->filename = optarg;
! 	  p->local_sym_name = optarg;
! 	  p->just_syms_flag = 1;
! 	  p++;
! 	  break;
! 
! 	case 'l':
! 	  p->filename = concat ("lib", optarg, ".a");
! 	  p->local_sym_name = concat ("-l", optarg, "");
! 	  p->search_dirs_flag = 1;
  	  p++;
- 	  break;
  	}
      }
  
-   if (!output_file_type)
-     output_file_type = DEFAULT_OUTPUT_FILE_TYPE;
- 
-   if (!output_style)
-     output_style = DEFAULT_OUTPUT_STYLE;
- 
- #if 0
-   /* THIS CONSISTENCY CHECK BELONGS SOMEWHERE ELSE.  */
    /* Now check some option settings for consistency.  */
  
!   if ((output_style == OUTPUT_READONLY_TEXT || output_style == OUTPUT_DEMAND_PAGED)
!       && (text_start - text_start_alignment) & (page_size - 1))
!     usage ("-T argument not multiple of page size, with sharable output", 0);
  #endif
  
    /* Append the standard search directories to the user-specified ones.  */
!   if (!no_standard_dirs)
!     {
!       int n = sizeof standard_search_dirs / sizeof standard_search_dirs[0];
!       n_search_dirs += n;
!       search_dirs
! 	= (char **) xrealloc (search_dirs, n_search_dirs * sizeof (char *));
!       bcopy (standard_search_dirs, &search_dirs[n_search_dirs - n],
! 	     n * sizeof (char *));
!     }
  }
  
  
--- 1085,1180 ----
    n_search_dirs = 0;
    search_dirs = (char **) xmalloc (sizeof (char *));
  
!   /* First compute number_of_files so we know how long to make file_table.  */
!   /* Also process most options completely.  */
  
!   for (i = 1; i < argc; i++)
!     {
!       register int code = classify_arg (argv[i]);
!       if (code)
! 	{
! 	  if (i + code > argc)
! 	    fatal ("no argument following %s\n", argv[i]);
! 
! 	  decode_option (argv[i], argv[i+1]);
! 
! 	  if (argv[i][1] == 'l' || argv[i][1] == 'A')
! 	    number_of_files++;
! 
! 	  i += code - 1;
  	}
+       else
+ 	number_of_files++;
      }
  
    if (!number_of_files)
!     fatal ("no input files", 0);
  
    p = file_table
      = (struct file_entry *) xmalloc (number_of_files * sizeof (struct file_entry));
    bzero (p, number_of_files * sizeof (struct file_entry));
  
!   /* Now scan again and fill in file_table.  */
!   /* All options except -A and -l are ignored here.  */
  
!   for (i = 1; i < argc; i++)
!     {
!       register int code = classify_arg (argv[i]);
! 
!       if (code)
! 	{
! 	  char *string;
! 	  if (code == 2)
! 	    string = argv[i+1];
! 	  else
! 	    string = &argv[i][2];
! 
! 	  if (argv[i][1] == 'A')
! 	    {
! 	      if (p != file_table)
! 		fatal ("-A specified before an input file other than the first");
! 
! 	      p->filename = string;
! 	      p->local_sym_name = string;
! 	      p->just_syms_flag = 1;
! 	      p++;
! 	    }
! 	  if (argv[i][1] == 'l')
! 	    {
! 	      p->filename = concat ("lib", string, ".a");
! 	      p->local_sym_name = concat ("-l", string, "");
! 	      p->search_dirs_flag = 1;
! 	      p++;
! 	    }
! 	  i += code - 1;
! 	}
!       else
  	{
! 	  p->filename = argv[i];
! 	  p->local_sym_name = argv[i];
  	  p++;
  	}
      }
  
    /* Now check some option settings for consistency.  */
  
! #ifdef NMAGIC
!   if ((magic == ZMAGIC || magic == NMAGIC)
! #else
!   if ((magic == ZMAGIC)
  #endif
+       && (text_start - text_start_alignment) & (page_size - 1))
+     fatal ("-T argument not multiple of page size, with sharable output", 0);
  
    /* Append the standard search directories to the user-specified ones.  */
!   {
!     int n = sizeof standard_search_dirs / sizeof standard_search_dirs[0];
!     n_search_dirs += n;
!     search_dirs
!       = (char **) xrealloc (search_dirs, n_search_dirs * sizeof (char *));
!     bcopy (standard_search_dirs, &search_dirs[n_search_dirs - n],
! 	   n * sizeof (char *));
!   }
  }
  
  
***************
*** 1449,1455 ****
    if (ptr >= cmdline_references + cl_refs_allocated - 1)
      {
        int diff = ptr - cmdline_references;
! 
        cl_refs_allocated *= 2;
        cmdline_references = (struct glosym **)
  	xrealloc (cmdline_references,
--- 1192,1198 ----
    if (ptr >= cmdline_references + cl_refs_allocated - 1)
      {
        int diff = ptr - cmdline_references;
!       
        cl_refs_allocated *= 2;
        cmdline_references = (struct glosym **)
  	xrealloc (cmdline_references,
***************
*** 1456,1466 ****
  		 cl_refs_allocated * sizeof (struct glosym *));
        ptr = cmdline_references + diff;
      }
! 
    *ptr++ = sp;
    *ptr = (struct glosym *) 0;
  }
! 
  int
  set_element_prefixed_p (name)
       char *name;
--- 1199,1209 ----
  		 cl_refs_allocated * sizeof (struct glosym *));
        ptr = cmdline_references + diff;
      }
!   
    *ptr++ = sp;
    *ptr = (struct glosym *) 0;
  }
!     
  int
  set_element_prefixed_p (name)
       char *name;
***************
*** 1478,1486 ****
      }
    return 0;
  }
  
! /* Convenient functions for operating on one or all files being
!    loaded.  */
  void print_file_name ();
  
  /* Call FUNCTION on each input file entry.
--- 1221,1384 ----
      }
    return 0;
  }
+ 
+ int parse ();
+ 
+ /* Record an option and arrange to act on it later.
+    ARG should be the following command argument,
+    which may or may not be used by this option.
+ 
+    The `l' and `A' options are ignored here since they actually
+    specify input files.  */
+ 
+ void
+ decode_option (swt, arg)
+      register char *swt, *arg;
+ {
+   /* We get Bstatic from gcc on suns.  */
+   if (! strcmp (swt + 1, "Bstatic"))
+     return;
+   if (! strcmp (swt + 1, "Ttext"))
+     {
+       text_start = parse (arg, "%x", "invalid argument to -Ttext");
+       T_flag_specified = 1;
+       return;
+     }
+   if (! strcmp (swt + 1, "Tdata"))
+     {
+       data_start = parse (arg, "%x", "invalid argument to -Tdata");
+       Tdata_flag_specified = 1;
+       return;
+     }
+   if (! strcmp (swt + 1, "noinhibit-exec"))
+     {
+       force_executable = 1;
+       return;
+     }
+ 
+   if (swt[2] != 0)
+     arg = &swt[2];
+ 
+   switch (swt[1])
+     {
+     case 'A':
+       return;
+ 
+     case 'D':
+       specified_data_size = parse (arg, "%x", "invalid argument to -D");
+       return;
+ 
+     case 'd':
+       force_common_definition = 1;
+       return;
+ 
+     case 'e':
+       entry_symbol = getsym (arg);
+       if (!entry_symbol->defined && !entry_symbol->referenced)
+ 	undefined_global_sym_count++;
+       entry_symbol->referenced = 1;
+       add_cmdline_ref (entry_symbol);
+       return;
+ 
+     case 'l':
+       return;
+ 
+     case 'L':
+       n_search_dirs++;
+       search_dirs
+ 	= (char **) xrealloc (search_dirs, n_search_dirs * sizeof (char *));
+       search_dirs[n_search_dirs - 1] = arg;
+       return;
+ 
+     case 'M':
+       write_map = 1;
+       return;
+ 
+     case 'N':
+       magic = OMAGIC;
+       return;
+ 
+ #ifdef NMAGIC
+     case 'n':
+       magic = NMAGIC;
+       return;
+ #endif
+ 
+     case 'o':
+       output_filename = arg;
+       return;
+ 
+     case 'r':
+       relocatable_output = 1;
+       magic = OMAGIC;
+       text_start = 0;
+       return;
+ 
+     case 'S':
+       strip_symbols = STRIP_DEBUGGER;
+       return;
+ 
+     case 's':
+       strip_symbols = STRIP_ALL;
+       return;
+ 
+     case 'T':
+       text_start = parse (arg, "%x", "invalid argument to -T");
+       T_flag_specified = 1;
+       return;
+ 
+     case 't':
+       trace_files = 1;
+       return;
+ 
+     case 'u':
+       {
+ 	register symbol *sp = getsym (arg);
+ 	if (!sp->defined && !sp->referenced)
+ 	  undefined_global_sym_count++;
+ 	sp->referenced = 1;
+ 	add_cmdline_ref (sp);
+       }
+       return;
+ 
+     case 'V':
+       {
+ 	struct string_list_element *new
+ 	  = (struct string_list_element *)
+ 	    xmalloc (sizeof (struct string_list_element));
+ 
+ 	new->str = arg;
+ 	new->next = set_element_prefixes;
+ 	set_element_prefixes = new;
+ 	return;
+       }
+ 
+     case 'X':
+       discard_locals = DISCARD_L;
+       return;
+ 
+     case 'x':
+       discard_locals = DISCARD_ALL;
+       return;
+ 
+     case 'y':
+       {
+ 	register symbol *sp = getsym (&swt[2]);
+ 	sp->trace = 1;
+       }
+       return;
+ 
+     case 'z':
+       magic = ZMAGIC;
+       return;
+ 
+     default:
+       fatal ("invalid command option `%s'", swt);
+     }
+ }
  
! /** Convenient functions for operating on one or all files being */
!  /** loaded.  */
  void print_file_name ();
  
  /* Call FUNCTION on each input file entry.
***************
*** 1596,1603 ****
  
    if (input_file) file_close ();
  
!   if (entry->search_dirs_flag && n_search_dirs)
      {
        int i;
  
        for (i = 0; i < n_search_dirs; i++)
--- 1494,1502 ----
  
    if (input_file) file_close ();
  
!   if (entry->search_dirs_flag)
      {
+       register char **p = search_dirs;
        int i;
  
        for (i = 0; i < n_search_dirs; i++)
***************
*** 1681,1971 ****
  
  /* Medium-level input routines for rel files.  */
  
! /* Determine whether the given ENTRY is an archive, a BSD a.out file,
!    a Mach-O file, or whatever.  DESC is the descriptor on which the
!    file is open.  */
! void
! deduce_file_type(desc, entry)
!      int desc;
!      struct file_entry *entry;
! {
!   int len;
! 
!   {
!     char magic[SARMAG];
!     
!     lseek (desc, entry->starting_offset, 0);
!     len = read (desc, magic, SARMAG);
!     if (len == SARMAG && !strncmp(magic, ARMAG, SARMAG))
!       {
! 	entry->file_type = IS_ARCHIVE;
! 	return;
!       }
!   }
! 
! #ifdef A_OUT
!   {
!     struct exec hdr;
! 
!     lseek (desc, entry->starting_offset, 0);
! #ifdef COFF_ENCAPSULATE
!     if (entry->just_syms_flag)
!       /* Since a file given with -A will have a coff header, unlike normal
! 	input files, we need to skip over it.  */
!       lseek (desc, sizeof (coffheader), SEEK_CUR);
! #endif
!     len = read (desc, (char *) &hdr, sizeof (struct exec));
!     if (len == sizeof (struct exec) && !N_BADMAG (hdr))
!       {
! 	entry->file_type = IS_A_OUT;
! 	return;
!       }
!   }
! #endif
! 
! #ifdef MACH_O
!   {
!     struct mach_header hdr;
! 
!     lseek (desc, entry->starting_offset, 0);
!     len = read (desc, (char *) &hdr, sizeof (struct mach_header));
!     if (len == sizeof (struct mach_header) && hdr.magic == MH_MAGIC)
!       {
! 	entry->file_type = IS_MACH_O;
! 	return;
!       }
!   }
! #endif
! 
!   fatal_with_file ("malformed input file (not rel or archive) ", entry);
! }
! 
! #ifdef A_OUT
! /* Read an a.out file's header and set up the fields of
!    the ENTRY accordingly.  DESC is the descriptor on which
!    the file is open.  */
! void
! read_a_out_header (desc, entry)
!      int desc;
!      struct file_entry *entry;
! {
!   register int len;
!   struct exec hdr;
!   struct stat st;
! 
!   lseek (desc, entry->starting_offset, 0);
! 
! #ifdef COFF_ENCAPSULATE
!   if (entry->just_syms_flag)
!     /* Since a file given with -A will have a coff header, unlike normal
!        input files, we need to skip over it.  */
!     lseek (desc, sizeof (coffheader), SEEK_CUR);
! #endif
! 
!   read (desc, (char *) &hdr, sizeof (struct exec));
! 
! #ifdef READ_HEADER_HOOK
!   READ_HEADER_HOOK(hdr.a_machtype);
! #endif
! 
!   if (entry->just_syms_flag)
!     entry->orig_text_address = N_TXTADDR(hdr);
!   else
!     entry->orig_text_address = 0;
!   entry->text_size = hdr.a_text;
!   entry->text_offset = N_TXTOFF(hdr);
! 
!   entry->text_reloc_size = hdr.a_trsize;
! #ifdef N_TRELOFF
!   entry->text_reloc_offset = N_TRELOFF(hdr);
! #else
! #ifdef N_DATOFF
!   entry->text_reloc_offset = N_DATOFF(hdr) + hdr.a_data;
! #else
!   entry->text_reloc_offset = N_TXTOFF(hdr) + hdr.a_text + hdr.a_data;
! #endif
! #endif
! 
!   if (entry->just_syms_flag)
!     entry->orig_data_address = N_DATADDR(hdr);
!   else
!     entry->orig_data_address = entry->text_size;
!   entry->data_size = hdr.a_data;
! #ifdef N_DATOFF
!   entry->data_offset = N_DATOFF(hdr);
! #else
!   entry->data_offset = N_TXTOFF(hdr) + hdr.a_text;
! #endif
! 
!   entry->data_reloc_size = hdr.a_drsize;
! #ifdef N_DRELOFF
!   entry->data_reloc_offset = N_DRELOFF(hdr);
! #else
!   entry->data_reloc_offset = entry->text_reloc_offset + entry->text_reloc_size;
! #endif
! 
! #ifdef N_BSSADDR
!   if (entry->just_syms_flag)
!     entry->orig_bss_address = N_BSSADDR(hdr);
!   else
! #endif
!   entry->orig_bss_address = entry->orig_data_address + entry->data_size;
!   entry->bss_size = hdr.a_bss;
! 
!   entry->syms_size = hdr.a_syms;
!   entry->syms_offset = N_SYMOFF(hdr);
!   entry->strs_offset = N_STROFF(hdr);
!   lseek(desc, entry->starting_offset + entry->strs_offset, 0);
!   if (read(desc, (char *) &entry->strs_size, sizeof (unsigned long int))
!       != sizeof (unsigned long int))
!     fatal_with_file ("failure reading string table size of ", entry);
! 
!   if (!entry->superfile)
!     {
!       fstat(desc, &st);
!       if (st.st_size > entry->strs_offset + entry->strs_size)
! 	{
! 	  entry->symseg_size = st.st_size - (entry->strs_offset + entry->strs_size);
! 	  entry->symseg_offset = entry->strs_offset + entry->strs_size;
! 	}
!     }
!   else
!     if (entry->total_size > entry->strs_offset + entry->strs_size)
!       {
! 	entry->symseg_size = entry->total_size - (entry->strs_offset + entry->strs_size);
! 	entry->symseg_offset = entry->strs_offset + entry->strs_size;
!       }
! }
! #endif
! 
! #ifdef MACH_O
! /* Read a Mach-O file's header.  DESC is the descriptor on which the
!    file is open, and ENTRY is the file's entry.  */
! void
! read_mach_o_header (desc, entry)
!      int desc;
!      struct file_entry *entry;
! {
!   struct mach_header mach_header;
!   char *hdrbuf;
!   struct load_command *load_command;
!   struct segment_command *segment_command;
!   struct section *section;
!   struct symtab_command *symtab_command;
! #ifdef LC_SYMSEG
!   struct symseg_command *symseg_command;
! #endif;
!   int ordinal;
!   int symtab_seen, symseg_seen;
!   int len, cmd, seg;
! 
!   entry->text_ordinal = entry->data_ordinal = entry->bss_ordinal = 0;
!   symtab_seen = symseg_seen = 0;
!   ordinal = 1;
! 
!   lseek (desc, entry->starting_offset, 0);
!   len = read (desc, (char *) &mach_header, sizeof (struct mach_header));
!   if (len != sizeof (struct mach_header))
!     fatal_with_file ("failure reading Mach-O header of ", entry);
!   if (mach_header.filetype != MH_OBJECT && mach_header.filetype != MH_EXECUTE)
!     fatal_with_file ("unsupported Mach-O file type (not MH_OBJECT or MH_EXECUTE) in ", entry);
!   hdrbuf = xmalloc (mach_header.sizeofcmds);
!   len = read (desc, hdrbuf, mach_header.sizeofcmds);
!   if (len != mach_header.sizeofcmds)
!     fatal_with_file ("failure reading Mach-O load commands of ", entry);
!   load_command = (struct load_command *) hdrbuf;
!   for (cmd = 0; cmd < mach_header.ncmds; ++cmd)
!     {
!       switch (load_command->cmd)
! 	{
! 	case LC_SEGMENT:
! 	  segment_command = (struct segment_command *) load_command;
! 	  section = (struct section *) ((char *) (segment_command + 1));
! 	  for (seg = 0; seg < segment_command->nsects; ++seg, ++section, ++ordinal)
! 	    {
! 	      if (!strncmp(SECT_TEXT, section->sectname, sizeof section->sectname))
! 		if (entry->text_ordinal)
! 		  fatal_with_file ("more than one __text section in ", entry);
! 		else
! 		  {
! 		    entry->text_ordinal = ordinal;
! 		    entry->orig_text_address = section->addr;
! 		    entry->text_size = section->size;
! 		    entry->text_offset = section->offset;
! 		    entry->text_reloc_size = section->nreloc * sizeof (struct relocation_info);
! 		    entry->text_reloc_offset = section->reloff;
! 		  }
! 	      else if (!strncmp(SECT_DATA, section->sectname, sizeof section->sectname))
! 		if (entry->data_ordinal)
! 		  fatal_with_file ("more than one __data section in ", entry);
! 		else
! 		  {
! 		    entry->data_ordinal = ordinal;
! 		    entry->orig_data_address = section->addr;
! 		    entry->data_size = section->size;
! 		    entry->data_offset = section->offset;
! 		    entry->data_reloc_size = section->nreloc * sizeof (struct relocation_info);
! 		    entry->data_reloc_offset = section->reloff;
! 		  }
! 	      else if (!strncmp(SECT_BSS, section->sectname, sizeof section->sectname))
! 		if (entry->bss_ordinal)
! 		  fatal_with_file ("more than one __bss section in ", entry);
! 		else
! 		  {
! 		    entry->bss_ordinal = ordinal;
! 		    entry->orig_bss_address = section->addr;
! 		    entry->bss_size = section->size;
! 		  }
! 	      else
! 		if (section->size != 0)
! 		  fprintf (stderr, "%s: warning: unknown section `%.*s' in %s\n",
! 			   progname, sizeof section->sectname, section->sectname,
! 			   entry->filename);
! 	    }
! 	  break;
! 	case LC_SYMTAB:
! 	  if (symtab_seen)
! 	      fatal_with_file ("more than one LC_SYMTAB in ", entry);
! 	  else
! 	    {
! 	      symtab_seen = 1;
! 	      symtab_command = (struct symtab_command *) load_command;
! 	      entry->syms_size = symtab_command->nsyms * sizeof (struct nlist);
! 	      entry->syms_offset = symtab_command->symoff;
! 	      entry->strs_size = symtab_command->strsize;
! 	      entry->strs_offset = symtab_command->stroff;
! 	    }
! 	  break;
! #ifdef LC_SYMSEG
! 	case LC_SYMSEG:
! 	  if (symseg_seen)
! 	    fatal_with_file ("more than one LC_SYMSEG in ", entry);
! 	  else
! 	    {
! 	      symseg_seen = 1;
! 	      symseg_command = (struct symseg_command *) load_command;
! 	      entry->symseg_size = symseg_command->size;
! 	      entry->symseg_offset = symseg_command->offset;
! 	    }
! 	  break;
! #endif
! 	}
!       load_command = (struct load_command *)
! 	((char *) load_command + load_command->cmdsize);
!     }
! 
!   free (hdrbuf);
! 
!   if (!symtab_seen)
!     fprintf (stderr, "%s: no symbol table in %s\n", progname, entry->filename);
! }
! #endif
! 
! /* Read a file's header info into the proper place in the file_entry.
     DESC is the descriptor on which the file is open.
!    ENTRY is the file's entry.
!    Switch in the file_type to determine the appropriate actual
!    header reading routine to call.  */
  
  void
  read_header (desc, entry)
--- 1580,1588 ----
  
  /* Medium-level input routines for rel files.  */
  
! /* Read a file's header into the proper place in the file_entry.
     DESC is the descriptor on which the file is open.
!    ENTRY is the file's entry.  */
  
  void
  read_header (desc, entry)
***************
*** 1972,2009 ****
       int desc;
       register struct file_entry *entry;
  {
!   if (!entry->file_type)
!     deduce_file_type (desc, entry);
! 
!   switch (entry->file_type)
!     {
!     case IS_ARCHIVE:
!     default:
!       /* Should never happen. */
!       abort ();
! 
! #ifdef A_OUT
!     case IS_A_OUT:
!       read_a_out_header (desc, entry);
!       break;
! #endif
  
! #ifdef MACH_O
!     case IS_MACH_O:
!       read_mach_o_header (desc, entry);
!       break;
! #endif
!     }
  
    entry->header_read_flag = 1;
  }
  
- #ifdef MACH_O
- void translate_mach_o_symbols ();
- #endif
- 
  /* Read the symbols of file ENTRY into core.
!    Assume it is already open, on descriptor DESC.  */
  
  void
  read_entry_symbols (desc, entry)
--- 1589,1611 ----
       int desc;
       register struct file_entry *entry;
  {
!   register int len;
!   struct exec *loc = (struct exec *) &entry->header;
  
!   lseek (desc, entry->starting_offset, 0);
!   len = read (desc, loc, sizeof (struct exec));
!   if (len != sizeof (struct exec))
!     fatal_with_file ("failure reading header of ", entry);
!   if (N_BADMAG (*loc))
!     fatal_with_file ("bad magic number in ", entry);
  
    entry->header_read_flag = 1;
  }
  
  /* Read the symbols of file ENTRY into core.
!    Assume it is already open, on descriptor DESC.
!    Also read the length of the string table, which follows the symbol table,
!    but don't read the contents of the string table.  */
  
  void
  read_entry_symbols (desc, entry)
***************
*** 2015,2034 ****
    if (!entry->header_read_flag)
      read_header (desc, entry);
  
!   entry->symbols = (struct nlist *) xmalloc (entry->syms_size);
  
!   lseek (desc, entry->syms_offset + entry->starting_offset, 0);
!   if (entry->syms_size != read (desc, entry->symbols, entry->syms_size))
      fatal_with_file ("premature end of file in symbols of ", entry);
  
! #ifdef MACH_O
!   if (entry->file_type == IS_MACH_O)
!     translate_mach_o_symbols (entry);
! #endif
  }
  
  /* Read the string table of file ENTRY into core.
!    Assume it is already open, on descriptor DESC.  */
  
  void
  read_entry_strings (desc, entry)
--- 1617,1638 ----
    if (!entry->header_read_flag)
      read_header (desc, entry);
  
!   entry->symbols = (struct nlist *) xmalloc (entry->header.a_syms);
  
!   lseek (desc, N_SYMOFF (entry->header) + entry->starting_offset, 0);
!   if (entry->header.a_syms != read (desc, entry->symbols, entry->header.a_syms))
      fatal_with_file ("premature end of file in symbols of ", entry);
  
!   lseek (desc, N_STROFF (entry->header) + entry->starting_offset, 0);
!   if (sizeof str_size != read (desc, &str_size, sizeof str_size))
!     fatal_with_file ("bad string table size in ", entry);
! 
!   entry->string_size = str_size;
  }
  
  /* Read the string table of file ENTRY into core.
!    Assume it is already open, on descriptor DESC.
!    Also record whether a GDB symbol segment follows the string table.  */
  
  void
  read_entry_strings (desc, entry)
***************
*** 2040,2048 ****
    if (!entry->header_read_flag)
      read_header (desc, entry);
  
!   lseek (desc, entry->strs_offset + entry->starting_offset, 0);
!   if (entry->strs_size != read (desc, entry->strings, entry->strs_size))
      fatal_with_file ("premature end of file in strings of ", entry);
  }
  
  /* Read in the symbols of all input files.  */
--- 1644,1671 ----
    if (!entry->header_read_flag)
      read_header (desc, entry);
  
!   lseek (desc, N_STROFF (entry->header) + entry->starting_offset, 0);
!   if (entry->string_size != read (desc, entry->strings, entry->string_size))
      fatal_with_file ("premature end of file in strings of ", entry);
+ 
+   /* While we are here, see if the file has a symbol segment at the end.
+      For a separate file, just try reading some more.
+      For a library member, compare current pos against total size.  */
+   if (entry->superfile)
+     {
+       if (entry->total_size == N_STROFF (entry->header) + entry->string_size)
+ 	return;
+     }
+   else
+     {
+       buffer = read (desc, &buffer, sizeof buffer);
+       if (buffer == 0)
+ 	return;
+       if (buffer != sizeof buffer)
+ 	fatal_with_file ("premature end of file in GDB symbol segment of ", entry);
+     }
+ 
+   entry->symseg_offset = N_STROFF (entry->header) + entry->string_size;
  }
  
  /* Read in the symbols of all input files.  */
***************
*** 2075,2099 ****
       register struct file_entry *entry;
  {
    register int desc;
  
    desc = file_open (entry);
  
!   if (!entry->file_type)
!     deduce_file_type (desc, entry);
  
!   if (entry->file_type == IS_ARCHIVE)
!     {
!       entry->library_flag = 1;
!       search_library (desc, entry);
!     }
!   else
      {
        read_entry_symbols (desc, entry);
!       entry->strings = (char *) alloca (entry->strs_size);
        read_entry_strings (desc, entry);
        enter_file_symbols (entry);
        entry->strings = 0;
      }
  
    file_close ();
  }
--- 1698,1730 ----
       register struct file_entry *entry;
  {
    register int desc;
+   register int len;
+   struct exec hdr;
  
    desc = file_open (entry);
  
!   len = read (desc, &hdr, sizeof hdr);
!   if (len != sizeof hdr)
!     fatal_with_file ("failure reading header of ", entry);
  
!   if (!N_BADMAG (hdr))
      {
        read_entry_symbols (desc, entry);
!       entry->strings = (char *) alloca (entry->string_size);
        read_entry_strings (desc, entry);
        enter_file_symbols (entry);
        entry->strings = 0;
      }
+   else
+     {
+       char armag[SARMAG];
+ 
+       lseek (desc, 0, 0);
+       if (SARMAG != read (desc, armag, SARMAG) || strncmp (armag, ARMAG, SARMAG))
+ 	fatal_with_file ("malformed input file (not rel or archive) ", entry);
+       entry->library_flag = 1;
+       search_library (desc, entry);
+     }
  
    file_close ();
  }
***************
*** 2106,2112 ****
  {
    register struct nlist
      *p,
!     *end = entry->symbols + entry->syms_size / sizeof (struct nlist);
  
    if (trace_files) prline_file_name (entry, stderr);
  
--- 1737,1744 ----
  {
    register struct nlist
      *p,
!     *end = entry->symbols + entry->header.a_syms / sizeof (struct nlist);
!   int lowest_set_vector = -1;
  
    if (trace_files) prline_file_name (entry, stderr);
  
***************
*** 2120,2126 ****
        if (SET_ELEMENT_P (p->n_type))
  	{
  	  set_symbol_count++;
! 	  if (output_style != OUTPUT_RELOCATABLE)
  	    enter_global_ref (p, p->n_un.n_strx + entry->strings, entry);
  	}
        else if (p->n_type == N_WARNING)
--- 1752,1758 ----
        if (SET_ELEMENT_P (p->n_type))
  	{
  	  set_symbol_count++;
! 	  if (!relocatable_output)
  	    enter_global_ref (p, p->n_un.n_strx + entry->strings, entry);
  	}
        else if (p->n_type == N_WARNING)
***************
*** 2139,2145 ****
  	  else
  	    {
  	      symbol *sp;
! 	      char *sname = p->n_un.n_strx + entry->strings;
  	      /* Deal with the warning symbol.  */
  	      enter_global_ref (p, p->n_un.n_strx + entry->strings, entry);
  	      sp = getsym (sname);
--- 1771,1777 ----
  	  else
  	    {
  	      symbol *sp;
! 	      char *sname = p->n_un.n_strx + entry->strings; 
  	      /* Deal with the warning symbol.  */
  	      enter_global_ref (p, p->n_un.n_strx + entry->strings, entry);
  	      sp = getsym (sname);
***************
*** 2230,2242 ****
  	  /* Indirect symbols value should be modified to point
  	     a symbol being equivalenced to. */
  	  nlist_p->n_value
- #ifndef NeXT
  	    = (unsigned int) getsym ((nlist_p + 1)->n_un.n_strx
  				     + entry->strings);
- #else
- 	    /* NeXT also has indirection but they do it weirdly. */
- 	    = (unsigned int) getsym (nlist_p->n_value + entry->strings);
- #endif
  	  if ((symbol *) nlist_p->n_value == sp)
  	    {
  	      /* Somebody redefined a symbol to be itself.  */
--- 1862,1869 ----
***************
*** 2282,2288 ****
    if (sp->trace)
      {
        register char *reftype;
!       switch (type & ~N_EXT)
  	{
  	case N_UNDF:
  	  if (nlist_p->n_value)
--- 1909,1915 ----
    if (sp->trace)
      {
        register char *reftype;
!       switch (type & N_TYPE)
  	{
  	case N_UNDF:
  	  if (nlist_p->n_value)
***************
*** 2327,2335 ****
  	  break;
  
  	case N_INDR:
! 	  reftype = (char *) alloca (23 + strlen (((symbol *) nlist_p->n_value)->name));
  	  sprintf (reftype, "defined equivalent to %s",
! 		   ((symbol *) nlist_p->n_value)->name);
  	  break;
  
  #ifdef sequent
--- 1954,1964 ----
  	  break;
  
  	case N_INDR:
! 	  reftype = (char *) alloca (23
! 				     + strlen ((nlist_p + 1)->n_un.n_strx
! 					       + entry->strings));
  	  sprintf (reftype, "defined equivalent to %s",
! 		   (nlist_p + 1)->n_un.n_strx + entry->strings);
  	  break;
  
  #ifdef sequent
***************
*** 2346,2356 ****
  	  reftype = "shared BSS";
  	  break;
  */
- #endif
- 
  	default:
  	  reftype = "I don't know this type";
  	  break;
  	}
  
        fprintf (stderr, "symbol %s %s in ", sp->name, reftype);
--- 1975,1984 ----
  	  reftype = "shared BSS";
  	  break;
  */
  	default:
  	  reftype = "I don't know this type";
  	  break;
+ #endif
  	}
  
        fprintf (stderr, "symbol %s %s in ", sp->name, reftype);
***************
*** 2370,2376 ****
  {
    if (n_ptr >= entry->symbols &&
        n_ptr < (entry->symbols
! 	       + (entry->syms_size / sizeof (struct nlist))))
      return (unsigned long) entry;
    return 0;
  }
--- 1998,2004 ----
  {
    if (n_ptr >= entry->symbols &&
        n_ptr < (entry->symbols
! 	       + (entry->header.a_syms / sizeof (struct nlist))))
      return (unsigned long) entry;
    return 0;
  }
***************
*** 2577,2583 ****
  			 + symdef_base[i].symbol_name_string_index,
  			 entry->filename);
  		read_entry_symbols (desc, subentry);
! 		subentry->strings = xmalloc (subentry->strs_size);
  		read_entry_strings (desc, subentry);
  
  		/* Now scan the symbol table and decide whether to load.  */
--- 2205,2211 ----
  			 + symdef_base[i].symbol_name_string_index,
  			 entry->filename);
  		read_entry_symbols (desc, subentry);
! 		subentry->strings = (char *) malloc (subentry->string_size);
  		read_entry_strings (desc, subentry);
  
  		/* Now scan the symbol table and decide whether to load.  */
***************
*** 2585,2591 ****
  		if (!subfile_wanted_p (subentry))
  		  {
  		    free (subentry->symbols);
- 		    free (subentry->strings);
  		    free (subentry);
  		  }
  		else
--- 2213,2218 ----
***************
*** 2611,2621 ****
  			if (symdef_base[j].library_member_offset == offset)
  			  symdef_base[j].symbol_name_string_index = -1;
  		      }
- 
- 		    /* We'll read the strings again if we need them again.  */
- 		    free (subentry->strings);
- 		    subentry->strings = 0;
  		  }
  	      }
  	  }
      }
--- 2238,2248 ----
  			if (symdef_base[j].library_member_offset == offset)
  			  symdef_base[j].symbol_name_string_index = -1;
  		      }
  		  }
+ 
+ 		/* We'll read the strings again if we need them again.  */
+ 		free (subentry->strings);
+ 		subentry->strings = 0;
  	      }
  	  }
      }
***************
*** 2631,2638 ****
       register struct file_entry *subentry;
       struct file_entry **prev_addr, *entry;
  {
    read_entry_symbols (desc, subentry);
!   subentry->strings = (char *) alloca (subentry->strs_size);
    read_entry_strings (desc, subentry);
  
    if (!subfile_wanted_p (subentry))
--- 2258,2267 ----
       register struct file_entry *subentry;
       struct file_entry **prev_addr, *entry;
  {
+   register struct file_entry *prev = *prev_addr;
+ 
    read_entry_symbols (desc, subentry);
!   subentry->strings = (char *) alloca (subentry->string_size);
    read_entry_strings (desc, subentry);
  
    if (!subfile_wanted_p (subentry))
***************
*** 2644,2654 ****
      {
        enter_file_symbols (subentry);
  
!       if (*prev_addr)
! 	(*prev_addr)->chain = subentry;
        else
  	entry->subfiles = subentry;
!       *prev_addr = subentry;
        subentry->strings = 0; /* Since space will dissapear on return */
      }
  }
--- 2273,2283 ----
      {
        enter_file_symbols (subentry);
  
!       if (prev)
! 	prev->chain = subentry;
        else
  	entry->subfiles = subentry;
!       prev = subentry;
        subentry->strings = 0; /* Since space will dissapear on return */
      }
  }
***************
*** 2690,2696 ****
  {
    register struct nlist *p;
    register struct nlist *end
!     = entry->symbols + entry->syms_size / sizeof (struct nlist);
  #ifdef DOLLAR_KLUDGE
    register int dollar_cond = 0;
  #endif
--- 2319,2325 ----
  {
    register struct nlist *p;
    register struct nlist *end
!     = entry->symbols + entry->header.a_syms / sizeof (struct nlist);
  #ifdef DOLLAR_KLUDGE
    register int dollar_cond = 0;
  #endif
***************
*** 2704,2710 ****
  	 potentially want it.  */
        if (type & N_EXT
  	  && (type != (N_UNDF | N_EXT) || p->n_value
! 
  #ifdef DOLLAR_KLUDGE
  	       || name[1] == '$'
  #endif
--- 2333,2339 ----
  	 potentially want it.  */
        if (type & N_EXT
  	  && (type != (N_UNDF | N_EXT) || p->n_value
! 	      
  #ifdef DOLLAR_KLUDGE
  	       || name[1] == '$'
  #endif
***************
*** 2738,2745 ****
  	  if (!sp) continue;
  
  	  if ((sp->referenced && !sp->defined)
- 	      /* NB.  This needs to be changed so that, e.g., "int pipe;" won't import
- 		 pipe() from the library.  But the bug fix kingdon made was wrong.  */
  	      || (sp->defined && sp->max_common_size))
  	    {
  	      /* This is a symbol we are looking for.  It is either
--- 2367,2372 ----
***************
*** 2796,2807 ****
    if (trace_files)
      fprintf (stderr, "Digesting symbol information:\n\n");
  
-   /* Initialize the text_start address; this depends on the output file formats.  */
- 
-   initialize_text_start ();
- 
-   text_size = text_header_size;
- 
    /* Compute total size of sections */
  
    each_file (consider_file_section_lengths, 0);
--- 2423,2428 ----
***************
*** 2809,2836 ****
    /* If necessary, pad text section to full page in the file.
       Include the padding in the text segment size.  */
  
!   if (output_style == OUTPUT_READONLY_TEXT || output_style == OUTPUT_DEMAND_PAGED)
      {
!       text_pad = ((text_size + page_size - 1) & (- page_size)) - text_size;
        text_size += text_pad;
      }
  
!   /* Now that the text_size is known, initialize the data start address;
!      this depends on text_size as well as the output file format.  */
  
!   initialize_data_start ();
  
    /* Make sure bss starts out aligned as much as anyone can want.  */
-   {
-     int new_data_size = (data_size + sizeof(double) - 1) & ~(sizeof(double)-1);
  
!     data_pad += new_data_size - data_size;
!     data_size = new_data_size;
!   }
  
    /* Set up the set element vector */
  
!   if (output_style != OUTPUT_RELOCATABLE)
      {
        /* The set sector size is the number of set elements + a word
           for each symbol for the length word at the beginning of the
--- 2430,2463 ----
    /* If necessary, pad text section to full page in the file.
       Include the padding in the text segment size.  */
  
! #ifdef NMAGIC
!   if (magic == ZMAGIC || magic == NMAGIC)
! #else
!   if (magic == ZMAGIC)
! #endif
      {
!       int text_end = text_size + N_TXTOFF (outheader);
!       text_pad = ((text_end + page_size - 1) & (- page_size)) - text_end;
        text_size += text_pad;
      }
  
!   outheader.a_text = text_size;
! #ifdef sequent
!   outheader.a_text += N_ADDRADJ (outheader);
! #endif
! 
!   /* Make the data segment address start in memory on a suitable boundary.  */
  
!   if (! Tdata_flag_specified)
!     data_start = N_DATADDR (outheader) + text_start - N_TXTADDR (outheader);
  
    /* Make sure bss starts out aligned as much as anyone can want.  */
  
!   data_size = (data_size + sizeof(double) - 1) & ~(sizeof(double)-1);
  
    /* Set up the set element vector */
  
!   if (!relocatable_output)
      {
        /* The set sector size is the number of set elements + a word
           for each symbol for the length word at the beginning of the
***************
*** 2866,2872 ****
  	{
  	  /* For each symbol */
  	  register struct nlist *p, *next;
! 	  int defs = 0, com = sp->max_common_size;
  	  struct nlist *first_definition;
  	  for (p = sp->refs; p; p = next)
  	    {
--- 2493,2499 ----
  	{
  	  /* For each symbol */
  	  register struct nlist *p, *next;
! 	  int defs = 0, com = sp->max_common_size, erred = 0;
  	  struct nlist *first_definition;
  	  for (p = sp->refs; p; p = next)
  	    {
***************
*** 2874,2880 ****
  
  	      if (SET_ELEMENT_P (type))
  		{
! 		  if (output_style == OUTPUT_RELOCATABLE)
  		    fatal ("internal: global ref to set element with -r");
  		  if (!defs++)
  		    {
--- 2501,2507 ----
  
  	      if (SET_ELEMENT_P (type))
  		{
! 		  if (relocatable_output)
  		    fatal ("internal: global ref to set element with -r");
  		  if (!defs++)
  		    {
***************
*** 2908,2914 ****
  	  /* Allocate as common if defined as common and not defined for real */
  	  if (com && !defs)
  	    {
! 	      if (output_style != OUTPUT_RELOCATABLE || force_common_definition)
  		{
  		  int align = sizeof (int);
  
--- 2535,2541 ----
  	  /* Allocate as common if defined as common and not defined for real */
  	  if (com && !defs)
  	    {
! 	      if (!relocatable_output || force_common_definition)
  		{
  		  int align = sizeof (int);
  
***************
*** 2919,2925 ****
  		     this size alignment is ever removed, ALIGN above
  		     will have to be initialized to 1 instead of
  		     sizeof (int).  */
! 
  		  com = (com + sizeof (int) - 1) & (- sizeof (int));
  
  		  while (!(com & align))
--- 2546,2552 ----
  		     this size alignment is ever removed, ALIGN above
  		     will have to be initialized to 1 instead of
  		     sizeof (int).  */
! 		  
  		  com = (com + sizeof (int) - 1) & (- sizeof (int));
  
  		  while (!(com & align))
***************
*** 2977,3029 ****
  
    bss_size = (bss_size + sizeof(double) - 1) & ~(sizeof(double)-1);
  
!   /* Give values to _end and friends.  */
!   {
!     int end_value = data_start + data_size + bss_size;
!     if (end_symbol)
!       end_symbol->value = end_value;
!     if (end_symbol_alt)
!       end_symbol_alt->value = end_value;
!   }
! 
!   {
!     int etext_value = text_size + text_start;
!     if (etext_symbol)
!       etext_symbol->value = etext_value;
!     if (etext_symbol_alt)
!       etext_symbol_alt->value = etext_value;
!   }
! 
!   {
!     int edata_value = data_start + data_size;
!     if (edata_symbol)
!       edata_symbol->value = edata_value;
!     if (edata_symbol_alt)
!       edata_symbol_alt->value = edata_value;
!   }
  
    /* Figure the data_pad now, so that it overlaps with the bss addresses.  */
  
!   {
!     /* The amount of data_pad that we are computing now.  This is the
!        part which overlaps with bss.  What was computed previously
!        goes before bss.  */
!     int data_pad_additional = 0;
!     
!     if (specified_data_size && specified_data_size > data_size)
!       data_pad_additional = specified_data_size - data_size;
! 
!     if (output_style == OUTPUT_DEMAND_PAGED)
!       data_pad_additional =
! 	((data_pad_additional + data_size + page_size - 1) & (- page_size)) - data_size;
! 
!     bss_size -= data_pad_additional;
!     if (bss_size < 0) bss_size = 0;
  
!     data_size += data_pad_additional;
  
!     data_pad += data_pad_additional;
!   }
  }
  
  /* Accumulate the section sizes of input file ENTRY
--- 2604,2629 ----
  
    bss_size = (bss_size + sizeof(double) - 1) & ~(sizeof(double)-1);
  
!   if (end_symbol)		/* These are null if -r.  */
!     {
!       etext_symbol->value = text_size + text_start;
!       edata_symbol->value = data_start + data_size;
!       end_symbol->value = data_start + data_size + bss_size;
!     }
  
    /* Figure the data_pad now, so that it overlaps with the bss addresses.  */
  
!   if (specified_data_size && specified_data_size > data_size)
!     data_pad = specified_data_size - data_size;
  
!   if (magic == ZMAGIC)
!     data_pad = ((data_pad + data_size + page_size - 1) & (- page_size))
!                - data_size;
! 
!   bss_size -= data_pad;
!   if (bss_size < 0) bss_size = 0;
  
!   data_size += data_pad;
  }
  
  /* Accumulate the section sizes of input file ENTRY
***************
*** 3038,3051 ****
  
    entry->text_start_address = text_size;
    /* If there were any vectors, we need to chop them off */
!   text_size += entry->text_size;
    entry->data_start_address = data_size;
!   data_size += entry->data_size;
    entry->bss_start_address = bss_size;
!   bss_size += entry->bss_size;
  
!   text_reloc_size += entry->text_reloc_size;
!   data_reloc_size += entry->data_reloc_size;
  }
  
  /* Determine where the sections of ENTRY go into the output file,
--- 2638,2651 ----
  
    entry->text_start_address = text_size;
    /* If there were any vectors, we need to chop them off */
!   text_size += entry->header.a_text;
    entry->data_start_address = data_size;
!   data_size += entry->header.a_data;
    entry->bss_start_address = bss_size;
!   bss_size += entry->header.a_bss;
  
!   text_reloc_size += entry->header.a_trsize;
!   data_reloc_size += entry->header.a_drsize;
  }
  
  /* Determine where the sections of ENTRY go into the output file,
***************
*** 3057,3066 ****
       register struct file_entry *entry;
  {
    entry->text_start_address += text_start;
! 
!   /* Note that `data_start' and `data_size' have not yet been adjusted
!      for the portion of data_pad which overlaps with bss.  If they had
!      been, we would get the wrong results here.  */
    entry->data_start_address += data_start;
    entry->bss_start_address += data_start + data_size;
  
--- 2657,2665 ----
       register struct file_entry *entry;
  {
    entry->text_start_address += text_start;
!   /* Note that `data_start' and `data_size' have not yet been
!      adjusted for `data_pad'.  If they had been, we would get the wrong
!      results here.  */
    entry->data_start_address += data_start;
    entry->bss_start_address += data_start + data_size;
  
***************
*** 3067,3098 ****
    {
      register struct nlist *p;
      register struct nlist *end
!       = entry->symbols + entry->syms_size / sizeof (struct nlist);
  
      for (p = entry->symbols; p < end; p++)
        {
  	/* If this belongs to a section, update it by the section's start address */
! 	register int type = p->n_type & ~N_EXT;
  
  	switch (type)
  	  {
  	  case N_TEXT:
  	  case N_SETT:
! 	    p->n_value += entry->text_start_address - entry->orig_text_address;
  	    break;
  	  case N_DATA:
  	  case N_SETV:
  	  case N_SETD:
! 	    /* Data segment symbol.  Subtract the address of the
! 	       data segment in the input file, and add the address
! 	       of this input file's data segment in the output file.  */
! 	    p->n_value +=
! 	      entry->data_start_address - entry->orig_data_address;
  	    break;
  	  case N_BSS:
  	  case N_SETB:
  	    /* likewise for symbols with value in BSS.  */
! 	    p->n_value += entry->bss_start_address - entry->orig_bss_address;
  	    break;
  	  }
        }
--- 2666,2697 ----
    {
      register struct nlist *p;
      register struct nlist *end
!       = entry->symbols + entry->header.a_syms / sizeof (struct nlist);
  
      for (p = entry->symbols; p < end; p++)
        {
  	/* If this belongs to a section, update it by the section's start address */
! 	register int type = p->n_type & N_TYPE;
  
  	switch (type)
  	  {
  	  case N_TEXT:
  	  case N_SETT:
! 	    p->n_value += entry->text_start_address;
  	    break;
  	  case N_DATA:
  	  case N_SETV:
  	  case N_SETD:
! 	    /* A symbol whose value is in the data section
! 	       is present in the input file as if the data section
! 	       started at an address equal to the length of the file's text.  */
! 	    p->n_value += entry->data_start_address - entry->header.a_text;
  	    break;
  	  case N_BSS:
  	  case N_SETB:
  	    /* likewise for symbols with value in BSS.  */
! 	    p->n_value += entry->bss_start_address
! 	      - entry->header.a_text - entry->header.a_data;
  	    break;
  	  }
        }
***************
*** 3143,3151 ****
      fprintf (outfile, " symbols only\n", 0);
    else
      fprintf (outfile, " text %x(%x), data %x(%x), bss %x(%x) hex\n",
! 	     entry->text_start_address, entry->text_size,
! 	     entry->data_start_address, entry->data_size,
! 	     entry->bss_start_address, entry->bss_size);
  }
  
  void
--- 2742,2750 ----
      fprintf (outfile, " symbols only\n", 0);
    else
      fprintf (outfile, " text %x(%x), data %x(%x), bss %x(%x) hex\n",
! 	     entry->text_start_address, entry->header.a_text,
! 	     entry->data_start_address, entry->header.a_data,
! 	     entry->bss_start_address, entry->header.a_bss);
  }
  
  void
***************
*** 3155,3163 ****
  {
    register struct nlist
      *p,
!     *end = entry->symbols + entry->syms_size / sizeof (struct nlist);
  
!   entry->strings = (char *) alloca (entry->strs_size);
    read_entry_strings (file_open (entry), entry);
  
    fprintf (outfile, "\nLocal symbols of ");
--- 2754,2762 ----
  {
    register struct nlist
      *p,
!     *end = entry->symbols + entry->header.a_syms / sizeof (struct nlist);
  
!   entry->strings = (char *) alloca (entry->string_size);
    read_entry_strings (file_open (entry), entry);
  
    fprintf (outfile, "\nLocal symbols of ");
***************
*** 3232,3243 ****
    current->filename = next->filename;
  
    while (++(next->sym) < (entry->symbols
! 			  + entry->syms_size/sizeof (struct nlist)))
      {
        /* n_type is a char, and N_SOL, N_EINCL and N_BINCL are > 0x80, so
         * may look negative...therefore, must mask to low bits
         */
!       switch (next->sym->n_type & 0xff)
  	{
  	case N_SLINE:
  	  if (use_data_symbols) continue;
--- 2831,2842 ----
    current->filename = next->filename;
  
    while (++(next->sym) < (entry->symbols
! 			  + entry->header.a_syms/sizeof (struct nlist)))
      {
        /* n_type is a char, and N_SOL, N_EINCL and N_BINCL are > 0x80, so
         * may look negative...therefore, must mask to low bits
         */
!       switch (next->sym->n_type & 0xff) 
  	{
  	case N_SLINE:
  	  if (use_data_symbols) continue;
***************
*** 3292,3304 ****
  
    for (tmp = entry->symbols;
         tmp < (entry->symbols
! 	      + entry->syms_size/sizeof (struct nlist));
         tmp++)
      if (tmp->n_type == (int) N_SO)
        break;
  
    if (tmp >= (entry->symbols
! 	      + entry->syms_size/sizeof (struct nlist)))
      {
        /* I believe this translates to "We lose" */
        current->filename = next->filename = entry->filename;
--- 2891,2903 ----
  
    for (tmp = entry->symbols;
         tmp < (entry->symbols
! 	      + entry->header.a_syms/sizeof (struct nlist));
         tmp++)
      if (tmp->n_type == (int) N_SO)
        break;
  
    if (tmp >= (entry->symbols
! 	      + entry->header.a_syms/sizeof (struct nlist)))
      {
        /* I believe this translates to "We lose" */
        current->filename = next->filename = entry->filename;
***************
*** 3341,3347 ****
     which describes the current location in the implied scan through
     the debug symbols within the file which ADDRESS is within, and
     returns the source line number which corresponds to ADDRESS.  */
! 
  int
  address_to_line (address, state_pointer)
       unsigned long address;
--- 2940,2946 ----
     which describes the current location in the implied scan through
     the debug symbols within the file which ADDRESS is within, and
     returns the source line number which corresponds to ADDRESS.  */
!   
  int
  address_to_line (address, state_pointer)
       unsigned long address;
***************
*** 3356,3362 ****
    int use_data_symbols;
  
    if (next->sym)
!     use_data_symbols = (next->sym->n_type & ~N_EXT) == N_DATA;
    else
      return current->line;
  
--- 2955,2961 ----
    int use_data_symbols;
  
    if (next->sym)
!     use_data_symbols = (next->sym->n_type & N_TYPE) == N_DATA;
    else
      return current->line;
  
***************
*** 3408,3414 ****
      *reloc_start = data_segment ? entry->datarel : entry->textrel,
      *reloc;
    int reloc_size
!     = ((data_segment ? entry->data_reloc_size : entry->text_reloc_size)
         / sizeof (struct relocation_info));
    int start_of_segment
      = (data_segment ? entry->data_start_address : entry->text_start_address);
--- 3007,3013 ----
      *reloc_start = data_segment ? entry->datarel : entry->textrel,
      *reloc;
    int reloc_size
!     = ((data_segment ? entry->header.a_drsize : entry->header.a_trsize)
         / sizeof (struct relocation_info));
    int start_of_segment
      = (data_segment ? entry->data_start_address : entry->text_start_address);
***************
*** 3415,3421 ****
    struct nlist *start_of_syms = entry->symbols;
    struct line_debug_entry *state_pointer
      = init_debug_scan (data_segment != 0, entry);
!   register struct line_debug_entry *current = state_pointer;
    /* Assigned to generally static values; should not be written into.  */
    char *errfmt;
    /* Assigned to alloca'd values cand copied into; should be freed
--- 3014,3023 ----
    struct nlist *start_of_syms = entry->symbols;
    struct line_debug_entry *state_pointer
      = init_debug_scan (data_segment != 0, entry);
!   register struct line_debug_entry
!     *current = state_pointer,
!     *next = state_pointer + 1,
!     *source = state_pointer + 2;
    /* Assigned to generally static values; should not be written into.  */
    char *errfmt;
    /* Assigned to alloca'd values cand copied into; should be freed
***************
*** 3459,3465 ****
  	{
  	  /* Mark as being noted by relocation warning pass.  */
  	  SET_BIT (nlist_bitvector, s - start_of_syms);
! 
  	  if (g->undef_refs >= MAX_UREFS_PRINTED)    /* Listed too many */
  	    continue;
  
--- 3061,3067 ----
  	{
  	  /* Mark as being noted by relocation warning pass.  */
  	  SET_BIT (nlist_bitvector, s - start_of_syms);
! 	  
  	  if (g->undef_refs >= MAX_UREFS_PRINTED)    /* Listed too many */
  	    continue;
  
***************
*** 3483,3506 ****
  
  	  /* Mark as being noted by relocation warning pass.  */
  	  SET_BIT (nlist_bitvector, s - start_of_syms);
! 
  	  errfmt = 0;
  	  errmsg = g->warning;
  	  invalidate_line_number = 0;
  	}
! 
  
        /* If errfmt == 0, errmsg has already been defined.  */
        if (errfmt != 0)
  	{
! 	  char *nm;
! 
! 	  if (!demangler || !(nm = (*demangler)(g->name)))
! 	    nm = g->name;
! 	  errmsg = xmalloc (strlen (errfmt) + strlen (nm) + 1);
! 	  sprintf (errmsg, errfmt, nm, data_segment ? "data" : "text");
! 	  if (nm != g->name)
! 	    free (nm);
  	}
  
        address_to_line (RELOC_ADDRESS (reloc) + start_of_segment,
--- 3085,3102 ----
  
  	  /* Mark as being noted by relocation warning pass.  */
  	  SET_BIT (nlist_bitvector, s - start_of_syms);
! 	  
  	  errfmt = 0;
  	  errmsg = g->warning;
  	  invalidate_line_number = 0;
  	}
!       
  
        /* If errfmt == 0, errmsg has already been defined.  */
        if (errfmt != 0)
  	{
! 	  errmsg = (char *) xmalloc (strlen (errfmt) + strlen (g->name) + 1);
! 	  sprintf (errmsg, errfmt, g->name, data_segment ? "data" : "text");
  	}
  
        address_to_line (RELOC_ADDRESS (reloc) + start_of_segment,
***************
*** 3507,3523 ****
  		       state_pointer);
  
        if (current->line >=0)
! 	{
! 	  fprintf (outfile, "%s:%d (", current->filename,
! 		   invalidate_line_number ? 0 : current->line);
! 	  print_file_name (entry, outfile);
! 	  fprintf (outfile, "): %s\n", errmsg);
! 	}
!       else
! 	{
! 	  print_file_name(entry, outfile);
! 	  fprintf(outfile, ": %s\n", errmsg);
! 	}
  
        if (errfmt != 0)
  	free (errmsg);
--- 3103,3112 ----
  		       state_pointer);
  
        if (current->line >=0)
! 	fprintf (outfile, "%s:%d: %s\n", current->filename,
! 		 invalidate_line_number ? 0 : current->line, errmsg);
!       else
! 	fprintf (outfile, "%s: %s\n", current->filename, errmsg);
  
        if (errfmt != 0)
  	free (errmsg);
***************
*** 3535,3541 ****
       struct file_entry *entry;
       FILE *outfile;
  {
!   int number_of_syms = entry->syms_size / sizeof (struct nlist);
    unsigned char *nlist_bitvector
      = (unsigned char *) alloca ((number_of_syms >> 3) + 1);
    struct line_debug_entry *text_scan, *data_scan;
--- 3124,3130 ----
       struct file_entry *entry;
       FILE *outfile;
  {
!   int number_of_syms = entry->header.a_syms / sizeof (struct nlist);
    unsigned char *nlist_bitvector
      = (unsigned char *) alloca ((number_of_syms >> 3) + 1);
    struct line_debug_entry *text_scan, *data_scan;
***************
*** 3551,3557 ****
      {
        int desc;
  
!       entry->strings = (char *) alloca (entry->strs_size);
        desc = file_open (entry);
        read_entry_strings (desc, entry);
      }
--- 3140,3146 ----
      {
        int desc;
  
!       entry->strings = (char *) alloca (entry->string_size);
        desc = file_open (entry);
        read_entry_strings (desc, entry);
      }
***************
*** 3615,3621 ****
  	{
  	  if (g->undef_refs >= MAX_UREFS_PRINTED)
  	    continue;
! 
  	  if (++(g->undef_refs) == MAX_UREFS_PRINTED)
  	    errfmt = "More undefined \"%s\" refs follow";
  	  else
--- 3204,3210 ----
  	{
  	  if (g->undef_refs >= MAX_UREFS_PRINTED)
  	    continue;
! 	  
  	  if (++(g->undef_refs) == MAX_UREFS_PRINTED)
  	    errfmt = "More undefined \"%s\" refs follow";
  	  else
***************
*** 3638,3670 ****
  	}
        else
  	continue;
! 
        if (line_number == -1)
! 	{
! 	  print_file_name (entry, outfile);
! 	  fprintf (outfile, ": ");
! 	}
        else
! 	{
! 	  fprintf (outfile, "%s:%d (", file_name, line_number);
! 	  print_file_name (entry, outfile);
! 	  fprintf (outfile, "): ");
! 	}
  
        if (dont_allow_symbol_name)
  	fprintf (outfile, "%s", errfmt);
        else
! 	{
! 	  char *nm;
! 
! 	  if (!demangler || !(nm = (*demangler)(g->name)))
! 	    fprintf (outfile, errfmt, g->name);
! 	  else
! 	    {
! 	      fprintf (outfile, errfmt, nm);
! 	      free (nm);
! 	    }
! 	}
  
        fputc ('\n', outfile);
      }
--- 3227,3242 ----
  	}
        else
  	continue;
!       
        if (line_number == -1)
! 	fprintf (outfile, "%s: ", entry->filename);
        else
! 	fprintf (outfile, "%s:%d: ", file_name, line_number);
  
        if (dont_allow_symbol_name)
  	fprintf (outfile, "%s", errfmt);
        else
! 	fprintf (outfile, errfmt, g->name);
  
        fputc ('\n', outfile);
      }
***************
*** 3676,3682 ****
  do_warnings (outfile)
       FILE *outfile;
  {
!   list_unresolved_refs = output_style != OUTPUT_RELOCATABLE && undefined_global_sym_count;
    list_warning_symbols = warning_count;
    list_multiple_defs = multiple_def_count != 0;
  
--- 3248,3256 ----
  do_warnings (outfile)
       FILE *outfile;
  {
!   int i;
! 
!   list_unresolved_refs = !relocatable_output && undefined_global_sym_count;
    list_warning_symbols = warning_count;
    list_multiple_defs = multiple_def_count != 0;
  
***************
*** 3692,3795 ****
      make_executable = 0;
  }
  
! #ifdef A_OUT
  
! /* Stuff pertaining to creating a.out files. */
  
! /* The a.out header. */
  
! struct exec outheader;
  
! #ifdef COFF_ENCAPSULATE
! int need_coff_header;
! struct coffheader coffheader;
! #endif
  
! /* Compute text_start and text_header_size for an a.out file.  */
  
! void
! initialize_a_out_text_start ()
! {
!   int magic;
  
!   switch (output_style)
!     {
!     case OUTPUT_RELOCATABLE:
!     case OUTPUT_WRITABLE_TEXT:
!       magic = OMAGIC;
!       break;
!     case OUTPUT_READONLY_TEXT:
! #ifdef NMAGIC
!       magic = NMAGIC;
!       break;
! #endif
!     case OUTPUT_DEMAND_PAGED:
!       magic = ZMAGIC;
!       break;
!     default:
!       fatal ("unknown output style found (bug in ld)", (char *) 0);
!       break;
!     }
  
!   /* Determine whether to count the header as part of
!      the text size, and initialize the text size accordingly.
!      This depends on the kind of system and on the output format selected.  */
!   N_SET_MAGIC (outheader, magic);
! #ifdef INITIALIZE_HEADER
!   INITIALIZE_HEADER;
! #endif
  
!   text_header_size = sizeof (struct exec);
! #ifdef COFF_ENCAPSULATE
!   /* Don't write the coff header for the output of ld -A (since
!      it is not executable by the kernel anyway).  */
!   if (output_style != OUTPUT_RELOCATABLE && !file_table[0].just_syms_flag)
!     {
!       need_coff_header = 1;
!       /* set this flag now, since it will change the values of N_TXTOFF, etc */
!       N_SET_FLAGS (outheader, N_FLAGS_COFF_ENCAPSULATE);
!       text_header_size += sizeof (struct coffheader);
!     }
! #endif
!   if (text_header_size <= N_TXTOFF (outheader))
!     text_header_size = 0;
!   else
!     text_header_size -= N_TXTOFF (outheader);
! 
! #ifdef _N_BASEADDR
!   /* SunOS 4.1 N_TXTADDR depends on the value of outheader.a_entry. */
!   outheader.a_entry = N_PAGSIZ(outheader);
! #endif
  
!   if (!T_flag_specified && output_style != OUTPUT_RELOCATABLE)
!     text_start = N_TXTADDR (outheader);
! }
  
! /* Compute data_start once text_size is known. */
  
  void
! initialize_a_out_data_start ()
  {
    outheader.a_text = text_size;
  #ifdef sequent
    outheader.a_text += N_ADDRADJ (outheader);
-   if (entry_symbol == 0)
-     entry_symbol = getsym ("start");
  #endif
-   if (! Tdata_flag_specified)
-     data_start = N_DATADDR (outheader) + text_start - N_TXTADDR (outheader);
- }
- 
- /* Compute offsets of various pieces of the a.out output file.  */
- 
- void
- compute_a_out_section_offsets ()
- {
    outheader.a_data = data_size;
    outheader.a_bss = bss_size;
    outheader.a_entry = (entry_symbol ? entry_symbol->value
! 		       : text_start + text_header_size);
! 
  #ifdef COFF_ENCAPSULATE
    if (need_coff_header)
      {
--- 3266,3326 ----
      make_executable = 0;
  }
  
! /* Write the output file */
! 
! void
! write_output ()
! {
!   struct stat statbuf;
!   int filemode;
  
!   outdesc = open (output_filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
!   if (outdesc < 0) perror_name (output_filename);
  
!   if (fstat (outdesc, &statbuf) < 0)
!     perror_name (output_filename);
  
!   filemode = statbuf.st_mode;
  
!   chmod (output_filename, filemode & ~0111);
  
!   /* Output the a.out header.  */
!   write_header ();
  
!   /* Output the text and data segments, relocating as we go.  */
!   write_text ();
!   write_data ();
  
!   /* Output the merged relocation info, if requested with `-r'.  */
!   if (relocatable_output)
!     write_rel ();
  
!   /* Output the symbol table (both globals and locals).  */
!   write_syms ();
  
!   /* Copy any GDB symbol segments from input files.  */
!   write_symsegs ();
  
!   close (outdesc);
  
!   if (chmod (output_filename, filemode | 0111) == -1)
!     perror_name (output_filename);
! }
! 
! void modify_location (), perform_relocation (), copy_text (), copy_data ();
  
  void
! write_header ()
  {
+   N_SET_MAGIC (outheader, magic);
    outheader.a_text = text_size;
  #ifdef sequent
    outheader.a_text += N_ADDRADJ (outheader);
  #endif
    outheader.a_data = data_size;
    outheader.a_bss = bss_size;
    outheader.a_entry = (entry_symbol ? entry_symbol->value
! 		       : text_start + entry_offset);
  #ifdef COFF_ENCAPSULATE
    if (need_coff_header)
      {
***************
*** 3853,3858 ****
--- 3384,3393 ----
      }
  #endif
  
+ #ifdef INITIALIZE_HEADER
+   INITIALIZE_HEADER;
+ #endif
+ 
    if (strip_symbols == STRIP_ALL)
      nsyms = 0;
    else
***************
*** 3864,3875 ****
        else if (discard_locals == DISCARD_NONE)
  	nsyms += local_sym_count;
        /* One extra for following reference on indirects */
!       if (output_style == OUTPUT_RELOCATABLE)
! #ifndef NeXT
  	nsyms += set_symbol_count + global_indirect_count;
- #else
-         nsyms += set_symbol_count;
- #endif
      }
  
    if (strip_symbols == STRIP_NONE)
--- 3399,3406 ----
        else if (discard_locals == DISCARD_NONE)
  	nsyms += local_sym_count;
        /* One extra for following reference on indirects */
!       if (relocatable_output)
  	nsyms += set_symbol_count + global_indirect_count;
      }
  
    if (strip_symbols == STRIP_NONE)
***************
*** 3877,3883 ****
  
    outheader.a_syms = nsyms * sizeof (struct nlist);
  
!   if (output_style == OUTPUT_RELOCATABLE)
      {
        outheader.a_trsize = text_reloc_size;
        outheader.a_drsize = data_reloc_size;
--- 3408,3414 ----
  
    outheader.a_syms = nsyms * sizeof (struct nlist);
  
!   if (relocatable_output)
      {
        outheader.a_trsize = text_reloc_size;
        outheader.a_drsize = data_reloc_size;
***************
*** 3888,3935 ****
        outheader.a_drsize = 0;
      }
  
-   /* Initialize the various file offsets.  */
- 
-   output_text_offset = N_TXTOFF (outheader);
- #ifdef N_DATOFF
-   output_data_offset = N_DATOFF (outheader);
- #else
-   output_data_offset = output_text_offset + text_size;
- #endif
- #ifdef N_TRELOFF
-   output_trel_offset = N_TRELOFF (outheader);
- #else
-   output_trel_offset = output_data_offset + data_size;
- #endif
- #ifdef N_DRELOFF
-   output_drel_offset = N_DRELOFF (outheader);
- #else
-   output_drel_offset = output_trel_offset + text_reloc_size;
- #endif
-   output_syms_offset = N_SYMOFF (outheader);
-   output_strs_offset = N_STROFF (outheader);
- }
- 
- /* Compute more section offsets once the size of the string table is known.  */
- 
- void
- compute_more_a_out_section_offsets ()
- {
-   output_symseg_offset = output_strs_offset + output_strs_size;
- }
- 
- /* Write the a.out header once everything else is known.  */
- 
- void
- write_a_out_header ()
- {
-   lseek (outdesc, 0L, 0);
- 
  #ifdef COFF_ENCAPSULATE
    if (need_coff_header)
      mywrite (&coffheader, sizeof coffheader, 1, outdesc);
  #endif
- 
    mywrite (&outheader, sizeof (struct exec), 1, outdesc);
  
    /* Output whatever padding is required in the executable file
--- 3419,3428 ----
***************
*** 3939,4570 ****
    padfile (N_TXTOFF (outheader) - sizeof outheader, outdesc);
  #endif
  }
- 
- #endif
- 
- #ifdef MACH_O
- 
- /* Stuff pertaining to creating Mach-O files. */
- 
- /* Convert the Mach-O style n_sect references into something the rest
-    of the loader can understand.  */
- 
- void
- translate_mach_o_symbols (entry)
-      struct file_entry *entry;
- {
-   int i, n, g;
-   struct nlist *sym;
- 
-   n = entry->syms_size / sizeof (struct nlist);
-   for (i = 0; i < n; ++i)
-     if (((sym = &entry->symbols[i])->n_type & ~N_EXT) == N_SECT)
-       {
- 	if (sym->n_sect == entry->text_ordinal)
- 	  sym->n_type = (sym->n_type & N_EXT) | N_TEXT;
- 	else if (sym->n_sect == entry->data_ordinal)
- 	  sym->n_type = (sym->n_type & N_EXT) | N_DATA;
- 	else if (sym->n_sect == entry->bss_ordinal)
- 	  sym->n_type = (sym->n_type & N_EXT) | N_BSS;
- 	else
- 	  fatal_with_file ("unknown section referenced in symbols of ", entry);
- 	sym->n_sect = 0;
-       }
-     else if ((sym = &entry->symbols[i])->n_type == N_SLINE)
-       {
- 	if (sym->n_sect == entry->text_ordinal)
- 	  sym->n_type = N_SLINE;
- 	else if (sym->n_sect == entry->data_ordinal)
- 	  sym->n_type = N_DSLINE;
- 	else if (sym->n_sect == entry->bss_ordinal)
- 	  sym->n_type = N_BSLINE;
- 	else
- 	  fatal_with_file ("unknown section referenced in debugging symbols of ", entry);
-       }
- }
- 
- /* Convert Mach-O style relocation info into a.out style relocation
-    info internally.  */
- void
- translate_mach_o_relocation (entry, reloc, count)
-      struct file_entry *entry;
-      struct relocation_info *reloc;
-      int count;
- {
-   int i;
- 
-   for (i = 0; i < count; ++i)
-     if (!RELOC_EXTERN_P(&reloc[i]))
-       if (RELOC_TYPE(&reloc[i]) == R_ABS)
- 	RELOC_TYPE(&reloc[i]) = N_ABS;
-       else if (RELOC_TYPE(&reloc[i]) == entry->text_ordinal)
- 	RELOC_TYPE(&reloc[i]) = N_TEXT;
-       else if (RELOC_TYPE(&reloc[i]) == entry->data_ordinal)
- 	RELOC_TYPE(&reloc[i]) = N_DATA;
-       else if (RELOC_TYPE(&reloc[i]) == entry->bss_ordinal)
- 	RELOC_TYPE(&reloc[i]) = N_BSS;
-       else
- 	fatal_with_file ("unknown section ordinal in relocation info of ", entry);
- }
- 
- /* Header structure for OUTPUT_RELOCATABLE.  */
- 
- struct
- {
-   struct mach_header header;
-   struct segment_command segment;
-   struct section text;
-   struct section data;
-   struct section bss;
-   struct symtab_command symtab;
- #ifdef LC_SYMSEG
-   struct symseg_command symseg;
- #endif
- } m_object;
- 
- #ifdef NeXT
- #define CPU_TYPE CPU_TYPE_MC68030
- #define CPU_SUBTYPE CPU_SUBTYPE_NeXT
- #define THREAD_FLAVOR NeXT_THREAD_STATE_REGS
- #define THREAD_COUNT NeXT_THREAD_STATE_REGS_COUNT
- typedef struct NeXT_thread_state_regs thread_state;
- #define thread_state_entry_field pc
- #endif
- 
- /* Header structure for all executable output forms.  */
- 
- struct
- {
-   struct mach_header header;
-   struct segment_command pagezero;
-   struct segment_command text_segment;
-   struct section text;
-   struct segment_command data_segment;
-   struct section data;
-   struct section bss;
-   struct thread_command unixthread;
-   unsigned long int flavor;
-   unsigned long int count;
-   thread_state state;
-   struct symtab_command symtab;
- #ifdef LC_SYMSEG
-   struct symseg_command symseg;
- #endif
- } m_exec;
- 
- /* Compute text_start and text_header_size for an a.out file.  */
- 
- void
- initialize_mach_o_text_start ()
- {
-   if (output_style != OUTPUT_RELOCATABLE)
-     {
-       text_header_size = sizeof m_exec;
-       if (!T_flag_specified && output_style != OUTPUT_RELOCATABLE)
- 	/* We reserve the first page of an executable to trap NULL dereferences.  */
- 	text_start = page_size;
-     }
- }
- 
- /* Compute data_start once text_size is known.  */
- 
- void
- initialize_mach_o_data_start ()
- {
-   if (! Tdata_flag_specified)
-     data_start = text_start + text_size;
- }
- 
- /* Compute offsets of various pieces of the Mach-O output file.  */
- void
- compute_mach_o_section_offsets ()
- {
-   int header_size, trsize, drsize;
- 
-   switch (output_style)
-     {
-     case OUTPUT_RELOCATABLE:
-       header_size = sizeof m_object;
-       break;
-     default:
-       header_size = sizeof m_exec;
-       break;
-     }
- 
-   if (strip_symbols == STRIP_ALL)
-     nsyms = 0;
-   else
-     {
-       nsyms = (defined_global_sym_count
- 	       + undefined_global_sym_count);
-       if (discard_locals == DISCARD_L)
- 	nsyms += non_L_local_sym_count;
-       else if (discard_locals == DISCARD_NONE)
- 	nsyms += local_sym_count;
-       /* One extra for following reference on indirects */
-       if (output_style == OUTPUT_RELOCATABLE)
- #ifndef NeXT
- 	nsyms += set_symbol_count + global_indirect_count;
- #else
-         nsyms += set_symbol_count;
- #endif
-     }
- 
-   if (strip_symbols == STRIP_NONE)
-     nsyms += debugger_sym_count;
- 
-   if (output_style != OUTPUT_RELOCATABLE)
-     output_text_offset = header_size;
-   output_data_offset = output_text_offset + text_size;
-   output_trel_offset = output_data_offset + data_size;
-   if (output_style == OUTPUT_RELOCATABLE)
-     trsize = text_reloc_size, drsize = data_reloc_size;
-   else
-     trsize = drsize = 0;
-   output_drel_offset = output_trel_offset + trsize;
-   output_syms_offset = output_drel_offset + drsize;
-   output_strs_offset = output_syms_offset + nsyms * sizeof (struct nlist);
- }
- 
- /* Compute more section offsets once the size of the string table is known.  */
- void
- compute_more_mach_o_section_offsets ()
- {
-   output_symseg_offset = output_strs_offset + output_strs_size;
- }
- 
- /* Write the Mach-O header once everything else is known.  */
- 
- void
- write_mach_o_header ()
- {
-   struct mach_header header;
-   struct section text, data, bss;
-   struct symtab_command symtab;
- #ifdef LC_SYMSEG
-   struct symseg_command symseg;
- #endif
-   thread_state state;
- 
-   lseek (outdesc, 0L, 0);
- 
- 
-   header.magic = MH_MAGIC;
-   header.cputype = CPU_TYPE;
-   header.cpusubtype = CPU_SUBTYPE;
-   header.filetype = output_style == OUTPUT_RELOCATABLE ? MH_OBJECT : MH_EXECUTE;
- #ifdef LC_SYMSEG
-   switch (output_style)
-     {
-     case OUTPUT_RELOCATABLE:
-       header.ncmds = 3;
-       header.sizeofcmds = sizeof m_object - sizeof header;
-       break;
-     default:
-       header.ncmds = 6;
-       header.sizeofcmds = sizeof m_exec - sizeof header;
-       break;
-     }
- #else
-   switch (output_style)
-     {
-     case OUTPUT_RELOCATABLE:
-       header.ncmds = 2;
-       header.sizeofcmds = sizeof m_object - sizeof header;
-       break;
-     default:
-       header.ncmds = 5;
-       header.sizeofcmds = sizeof m_exec - sizeof header;
-       break;
-     }
- #endif
-   header.flags = undefined_global_sym_count ? 0 : MH_NOUNDEFS;
- 
-   bzero((char *) &text, sizeof text);
-   strncpy(text.sectname, SECT_TEXT, sizeof text.sectname);
-   strncpy(text.segname, SEG_TEXT, sizeof text.segname);
-   text.addr = text_start;
-   text.size = text_size;
-   text.offset = output_text_offset;
-   text.align = text.addr % sizeof (double) ? sizeof (int) : sizeof (double);
-   text.reloff = output_trel_offset;
-   text.nreloc = output_style == OUTPUT_RELOCATABLE
-     ? text_reloc_size / sizeof (struct relocation_info) : 0;
-   text.flags = 0;
- 
-   bzero((char *) &data, sizeof data);
-   strncpy(data.sectname, SECT_DATA, sizeof data.sectname);
-   strncpy(data.segname, output_style == OUTPUT_WRITABLE_TEXT ? SEG_TEXT : SEG_DATA,
- 	  sizeof data.segname);
-   data.addr = data_start;
-   data.size = data_size;
-   data.offset = output_data_offset;
-   data.align = data.addr % sizeof (double) ? sizeof (int) : sizeof (double);
-   data.reloff = output_drel_offset;
-   data.nreloc = output_style == OUTPUT_RELOCATABLE
-     ? data_reloc_size / sizeof (struct relocation_info) : 0;
-   data.flags = 0;
- 
-   bzero((char *) &bss, sizeof bss);
-   strncpy(bss.sectname, SECT_BSS, sizeof data.sectname);
-   strncpy(bss.segname, output_style == OUTPUT_WRITABLE_TEXT ? SEG_TEXT : SEG_DATA,
- 	  sizeof bss.segname);
-   bss.addr = data_start + data_size;
-   bss.size = bss_size;
-   bss.align = bss.addr % sizeof (double) ? sizeof (int) : sizeof (double);
-   bss.reloff = 0;
-   bss.nreloc = 0;
-   bss.flags = S_ZEROFILL;
- 
-   symtab.cmd = LC_SYMTAB;
-   symtab.cmdsize = sizeof symtab;
-   symtab.symoff = output_syms_offset;
-   symtab.nsyms = output_syms_size / sizeof (struct nlist);
-   symtab.stroff = output_strs_offset;
-   symtab.strsize = output_strs_size;
- 
- #ifdef LC_SYMSEG
-   symseg.cmd = LC_SYMSEG;
-   symseg.cmdsize = sizeof symseg;
-   symseg.offset = output_symseg_offset;
-   symseg.size = output_symseg_size;
- #endif
- 
-   switch (output_style)
-     {
-     case OUTPUT_RELOCATABLE:
-       m_object.header = header;
-       m_object.segment.cmd = LC_SEGMENT;
-       m_object.segment.cmdsize = sizeof (struct segment_command) + 3 * sizeof (struct section);
-       strncpy(m_object.segment.segname, SEG_TEXT, sizeof m_object.segment.segname);
-       m_object.segment.vmaddr = 0;
-       m_object.segment.vmsize = text.size + data.size + bss.size;
-       m_object.segment.fileoff = text.offset;
-       m_object.segment.filesize = text.size + data.size;
-       m_object.segment.maxprot = VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE;
-       m_object.segment.initprot = VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE;
-       m_object.segment.nsects = 3;
-       m_object.segment.flags = 0;
-       m_object.text = text;
-       m_object.data = data;
-       m_object.bss = bss;
-       m_object.symtab = symtab;
- #ifdef LC_SYMSEG
-       m_object.symseg = symseg;
- #endif
-       mywrite((char *) &m_object, 1, sizeof m_object, outdesc);
-       break;
- 
-     default:
-       m_exec.header = header;
-       m_exec.pagezero.cmd = LC_SEGMENT;
-       m_exec.pagezero.cmdsize = sizeof (struct segment_command);
-       strncpy(m_exec.pagezero.segname, SEG_PAGEZERO, sizeof m_exec.pagezero.segname);
-       m_exec.pagezero.vmaddr = 0;
-       m_exec.pagezero.vmsize = page_size;
-       m_exec.pagezero.fileoff = 0;
-       m_exec.pagezero.filesize = 0;
-       m_exec.pagezero.maxprot = VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE;
-       m_exec.pagezero.initprot = 0;
-       m_exec.pagezero.nsects = 0;
-       m_exec.pagezero.flags = 0;
-       m_exec.text_segment.cmd = LC_SEGMENT;
-       m_exec.text_segment.cmdsize = sizeof (struct segment_command) + sizeof (struct section);
-       strncpy(m_exec.text_segment.segname, SEG_TEXT, sizeof m_exec.text_segment.segname);
-       m_exec.text_segment.vmaddr = text_start;
-       m_exec.text_segment.vmsize = text_size;
-       m_exec.text_segment.fileoff = output_text_offset;
-       m_exec.text_segment.filesize = text_size;
-       m_exec.text_segment.maxprot = VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE;
-       m_exec.text_segment.initprot = VM_PROT_READ | VM_PROT_EXECUTE;
-       if (output_style == OUTPUT_WRITABLE_TEXT)
- 	m_exec.text_segment.initprot |= VM_PROT_WRITE;
-       m_exec.text_segment.nsects = 1;
-       m_exec.text_segment.flags = 0;
-       m_exec.text = text;
-       m_exec.data_segment.cmd = LC_SEGMENT;
-       m_exec.data_segment.cmdsize = sizeof (struct segment_command) + 2 * sizeof (struct section);
-       strncpy(m_exec.data_segment.segname, SEG_DATA, sizeof m_exec.data_segment.segname);
-       m_exec.data_segment.vmaddr = data_start;
-       m_exec.data_segment.vmsize = data_size + bss_size;
-       m_exec.data_segment.fileoff = output_data_offset;
-       m_exec.data_segment.filesize = data_size;
-       m_exec.data_segment.maxprot = VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE;
-       m_exec.data_segment.initprot = VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE;
-       m_exec.data_segment.nsects = 2;
-       m_exec.data_segment.flags = 0;
-       m_exec.data = data;
-       m_exec.bss = bss;
-       m_exec.unixthread.cmd = LC_UNIXTHREAD;
-       m_exec.unixthread.cmdsize
- 	= sizeof (struct thread_command) + 2 * sizeof (long int) + sizeof (thread_state);
-       m_exec.flavor = THREAD_FLAVOR;
-       m_exec.count = THREAD_COUNT;
-       m_exec.state.thread_state_entry_field = entry_symbol
- 	? entry_symbol->value : text_start + text_header_size;
-       m_exec.symtab = symtab;
- #ifdef LC_SYMSEG
-       m_exec.symseg = symseg;
- #endif
-       mywrite((char *) &m_exec, 1, sizeof m_exec, outdesc);
-       break;
-     }
- }
- 
- /* Translate a.out style symbols into Mach-O style symbols.  */
- 
- void
- generate_mach_o_symbols (syms, nsyms)
-      struct nlist *syms;
-      int nsyms;
- {
-   int i;
- 
-   for (i = 0; i < nsyms; ++i)
-     switch (syms[i].n_type)
-       {
-       case N_TEXT:
-       case N_TEXT | N_EXT:
- 	syms[i].n_type = syms[i].n_type & N_EXT | N_SECT;
- 	syms[i].n_sect = 1;	/* text section ordinal */
- 	break;
-       case N_DATA:
-       case N_DATA | N_EXT:
- 	syms[i].n_type = syms[i].n_type & N_EXT | N_SECT;
- 	syms[i].n_sect = 2;	/* data section ordinal */
- 	break;
-       case N_BSS:
-       case N_BSS | N_EXT:
- 	syms[i].n_type = syms[i].n_type & N_EXT | N_BSS;
- 	syms[i].n_sect = 3;	/* bss section ordinal */
- 	break;
-       case N_SLINE:
- 	syms[i].n_type = N_SLINE;
- 	syms[i].n_sect = 1;	/* text section ordinal */
- 	break;
-       case N_DSLINE:
- 	syms[i].n_type = N_SLINE;
- 	syms[i].n_sect = 2;	/* data section ordinal */
- 	break;
-       case N_BSLINE:
- 	syms[i].n_type = N_SLINE;
- 	syms[i].n_sect = 3;	/* bss section ordinal */
- 	break;
-       }
- }
- 
- /* Translate a.out style relocation info into Mach-O style relocation
-    info.  */
- 
- void
- generate_mach_o_relocations (reloc, nreloc)
-      struct relocation_info *reloc;
-      int nreloc;
- {
-   int i;
- 
-   for (i = 0; i < nreloc; ++i)
-     if (!RELOC_EXTERN_P (&reloc[i]))
-       switch (RELOC_TYPE (&reloc[i]))
- 	{
- 	case N_ABS:
- 	case N_ABS | N_EXT:
- 	  RELOC_TYPE (&reloc[i]) = R_ABS;
- 	  break;
- 	case N_TEXT:
- 	case N_TEXT | N_EXT:
- 	  RELOC_TYPE (&reloc[i]) = 1; /* output text section ordinal */
- 	  break;
- 	case N_DATA:
- 	case N_DATA | N_EXT:
- 	  RELOC_TYPE (&reloc[i]) = 2; /* output data section ordinal */
- 	  break;
- 	case N_BSS:
- 	case N_BSS | N_EXT:
- 	  RELOC_TYPE (&reloc[i]) = 3; /* output bss section ordinal */
- 	  break;
- 	}
- }
- 
- #endif
- 
- /* The following functions are simple switches according to the
-    output style.  */
- 
- /* Compute text_start and text_header_size as appropriate for the
-    output format.  */
- 
- void
- initialize_text_start ()
- {
- #ifdef A_OUT
-   if (output_file_type == IS_A_OUT)
-     {
-       initialize_a_out_text_start ();
-       return;
-     }
- #endif
- #ifdef MACH_O
-   if (output_file_type == IS_MACH_O)
-     {
-       initialize_mach_o_text_start ();
-       return;
-     }
- #endif
-   fatal ("unknown output file type (enum file_type)", (char *) 0);
- }
- 
- /* Initialize data_start as appropriate to the output format, once text_size
-    is known.  */
- 
- void
- initialize_data_start ()
- {
- #ifdef A_OUT
-   if (output_file_type == IS_A_OUT)
-     {
-       initialize_a_out_data_start ();
-       return;
-     }
- #endif
- #ifdef MACH_O
-   if (output_file_type == IS_MACH_O)
-     {
-       initialize_mach_o_data_start ();
-       return;
-     }
- #endif
-   fatal ("unknown output file type (enum file_type)", (char *) 0);
- }
- 
- /* Compute offsets of the various sections within the output file.  */
- 
- void
- compute_section_offsets ()
- {
- #ifdef A_OUT
-   if (output_file_type == IS_A_OUT)
-     {
-       compute_a_out_section_offsets ();
-       return;
-     }
- #endif
- #ifdef MACH_O
-   if (output_file_type == IS_MACH_O)
-     {
-       compute_mach_o_section_offsets ();
-       return;
-     }
- #endif
-   fatal ("unknown output file type (enum file_type)", (char *) 0);
- }
- 
- /* Compute more section offsets, once the size of the string table
-    is finalized.  */
- void
- compute_more_section_offsets ()
- {
- #ifdef A_OUT
-   if (output_file_type == IS_A_OUT)
-     {
-       compute_more_a_out_section_offsets ();
-       return;
-     }
- #endif
- #ifdef MACH_O
-   if (output_file_type == IS_MACH_O)
-     {
-       compute_more_mach_o_section_offsets ();
-       return;
-     }
- #endif
-   fatal ("unknown output file type (enum file_type)", (char *) 0);
- }
- 
- /* Write the output file header, once everything is known.  */
- void
- write_header ()
- {
- #ifdef A_OUT
-   if (output_file_type == IS_A_OUT)
-     {
-       write_a_out_header ();
-       return;
-     }
- #endif
- #ifdef MACH_O
-   if (output_file_type == IS_MACH_O)
-     {
-       write_mach_o_header ();
-       return;
-     }
- #endif
-   fatal ("unknown output file type (enum file_type)", (char *) 0);
- }
- 
- /* Write the output file */
- 
- void
- write_output ()
- {
-   struct stat statbuf;
-   int filemode, mask;
- 
-   /* Remove the old file in case it is owned by someone else.
-      This prevents spurious "not owner" error messages.
-      Don't check for errors from unlink; we don't really care
-      whether it worked.
- 
-      Note that this means that if the output file is hard linked,
-      the other names will still have the old contents.  This is
-      the way Unix ld works; I'm going to consider it a feature.  */
-   (void) unlink (output_filename);
-   
-   outdesc = open (output_filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
-   if (outdesc < 0) perror_name (output_filename);
- 
-   if (fstat (outdesc, &statbuf) < 0)
-     perror_name (output_filename);
- 
-   filemode = statbuf.st_mode;
- 
-   chmod (output_filename, filemode & ~0111);
- 
-   /* Calculate the offsets of the various pieces of the output file.  */
-   compute_section_offsets ();
- 
-   /* Output the text and data segments, relocating as we go.  */
-   write_text ();
-   write_data ();
- 
-   /* Output the merged relocation info, if requested with `-r'.  */
-   if (output_style == OUTPUT_RELOCATABLE)
-     write_rel ();
- 
-   /* Output the symbol table (both globals and locals).  */
-   write_syms ();
- 
-   /* At this point the total size of the symbol table and string table
-      are finalized.  */
-   compute_more_section_offsets ();
- 
-   /* Copy any GDB symbol segments from input files.  */
-   write_symsegs ();
- 
-   /* Now that everything is known about the output file, write its header.  */
-   write_header ();
- 
-   close (outdesc);
- 
-   mask = umask (0);
-   umask (mask);
- 
-   if (chmod (output_filename, filemode | (0111 & ~mask)) == -1)
-     perror_name (output_filename);
- }
  
- void modify_location (), perform_relocation (), copy_text (), copy_data ();
- 
  /* Relocate the text segment of each input file
     and write to the output file.  */
  
--- 3432,3438 ----
***************
*** 4574,4582 ****
    if (trace_files)
      fprintf (stderr, "Copying and relocating text:\n\n");
  
!   lseek (outdesc, output_text_offset + text_header_size, 0);
! 
!   each_full_file (copy_text, 0);
    file_close ();
  
    if (trace_files)
--- 3442,3448 ----
    if (trace_files)
      fprintf (stderr, "Copying and relocating text:\n\n");
  
!   each_full_file (copy_text);
    file_close ();
  
    if (trace_files)
***************
*** 4585,4596 ****
    padfile (text_pad, outdesc);
  }
  
  /* Read in all of the relocation information */
  
  void
  read_relocation ()
  {
!   each_full_file (read_file_relocation, 0);
  }
  
  /* Read in the relocation sections of ENTRY if necessary */
--- 3451,3469 ----
    padfile (text_pad, outdesc);
  }
  
+ int
+ text_offset (entry)
+      struct file_entry *entry;
+ {
+   return entry->starting_offset + N_TXTOFF (entry->header);
+ }
+ 
  /* Read in all of the relocation information */
  
  void
  read_relocation ()
  {
!   each_full_file (read_file_relocation);
  }
  
  /* Read in the relocation sections of ENTRY if necessary */
***************
*** 4606,4615 ****
    desc = -1;
    if (!entry->textrel)
      {
!       reloc = (struct relocation_info *) xmalloc (entry->text_reloc_size);
        desc = file_open (entry);
!       lseek (desc, entry->starting_offset + entry->text_reloc_offset, L_SET);
!       if (entry->text_reloc_size != (read_return = read (desc, reloc, entry->text_reloc_size)))
  	{
  	  fprintf (stderr, "Return from read: %d\n", read_return);
  	  fatal_with_file ("premature eof in text relocation of ", entry);
--- 3479,3490 ----
    desc = -1;
    if (!entry->textrel)
      {
!       reloc = (struct relocation_info *) xmalloc (entry->header.a_trsize);
        desc = file_open (entry);
!       lseek (desc,
! 	     text_offset (entry) + entry->header.a_text + entry->header.a_data,
! 	     L_SET);
!       if (entry->header.a_trsize != (read_return = read (desc, reloc, entry->header.a_trsize)))
  	{
  	  fprintf (stderr, "Return from read: %d\n", read_return);
  	  fatal_with_file ("premature eof in text relocation of ", entry);
***************
*** 4619,4641 ****
  
    if (!entry->datarel)
      {
!       reloc = (struct relocation_info *) xmalloc (entry->data_reloc_size);
        if (desc == -1) desc = file_open (entry);
!       lseek (desc, entry->starting_offset + entry->data_reloc_offset, L_SET);
!       if (entry->data_reloc_size != read (desc, reloc, entry->data_reloc_size))
  	fatal_with_file ("premature eof in data relocation of ", entry);
        entry->datarel = reloc;
      }
- 
- #ifdef MACH_O
-   if (entry->file_type == IS_MACH_O)
-     {
-       translate_mach_o_relocation (entry, entry->textrel,
- 				   entry->text_reloc_size / sizeof (struct relocation_info));
-       translate_mach_o_relocation (entry, entry->datarel,
- 				   entry->data_reloc_size / sizeof (struct relocation_info));
-     }
- #endif
  }
  
  /* Read the text segment contents of ENTRY, relocate them,
--- 3494,3509 ----
  
    if (!entry->datarel)
      {
!       reloc = (struct relocation_info *) xmalloc (entry->header.a_drsize);
        if (desc == -1) desc = file_open (entry);
!       lseek (desc,
! 	     text_offset (entry) + entry->header.a_text
! 	     + entry->header.a_data + entry->header.a_trsize,
! 	     L_SET);
!       if (entry->header.a_drsize != read (desc, reloc, entry->header.a_drsize))
  	fatal_with_file ("premature eof in data relocation of ", entry);
        entry->datarel = reloc;
      }
  }
  
  /* Read the text segment contents of ENTRY, relocate them,
***************
*** 4657,4668 ****
  
    /* Allocate space for the file's text section */
  
!   bytes = (char *) alloca (entry->text_size);
  
    /* Deal with relocation information however is appropriate */
  
    if (entry->textrel)  reloc = entry->textrel;
!   else if (output_style == OUTPUT_RELOCATABLE)
      {
        read_file_relocation (entry);
        reloc = entry->textrel;
--- 3525,3536 ----
  
    /* Allocate space for the file's text section */
  
!   bytes = (char *) alloca (entry->header.a_text);
  
    /* Deal with relocation information however is appropriate */
  
    if (entry->textrel)  reloc = entry->textrel;
!   else if (relocatable_output)
      {
        read_file_relocation (entry);
        reloc = entry->textrel;
***************
*** 4669,4699 ****
      }
    else
      {
!       reloc = (struct relocation_info *) alloca (entry->text_reloc_size);
!       lseek (desc, entry->starting_offset + entry->text_reloc_offset, L_SET);
!       if (entry->text_reloc_size != read (desc, reloc, entry->text_reloc_size))
  	fatal_with_file ("premature eof in text relocation of ", entry);
- #ifdef MACH_O
-       if (entry->file_type == IS_MACH_O)
- 	translate_mach_o_relocation (entry, reloc,
- 				     entry->text_reloc_size / sizeof (struct relocation_info));
- #endif
      }
  
    /* Read the text section into core.  */
  
!   lseek (desc, entry->starting_offset + entry->text_offset, L_SET);
!   if (entry->text_size != read (desc, bytes, entry->text_size))
      fatal_with_file ("premature eof in text section of ", entry);
  
    /* Relocate the text according to the text relocation.  */
  
!   perform_relocation (bytes, entry->text_start_address - entry->orig_text_address,
! 		      entry->text_size, reloc, entry->text_reloc_size, entry);
  
    /* Write the relocated text to the output file.  */
  
!   mywrite (bytes, 1, entry->text_size, outdesc);
  }
  
  /* Relocate the data segment of each input file
--- 3537,3563 ----
      }
    else
      {
!       reloc = (struct relocation_info *) alloca (entry->header.a_trsize);
!       lseek (desc, text_offset (entry) + entry->header.a_text + entry->header.a_data, 0);
!       if (entry->header.a_trsize != read (desc, reloc, entry->header.a_trsize))
  	fatal_with_file ("premature eof in text relocation of ", entry);
      }
  
    /* Read the text section into core.  */
  
!   lseek (desc, text_offset (entry), 0);
!   if (entry->header.a_text != read (desc, bytes, entry->header.a_text))
      fatal_with_file ("premature eof in text section of ", entry);
  
+ 
    /* Relocate the text according to the text relocation.  */
  
!   perform_relocation (bytes, entry->text_start_address, entry->header.a_text,
! 		      reloc, entry->header.a_trsize, entry);
  
    /* Write the relocated text to the output file.  */
  
!   mywrite (bytes, 1, entry->header.a_text, outdesc);
  }
  
  /* Relocate the data segment of each input file
***************
*** 4705,4713 ****
    if (trace_files)
      fprintf (stderr, "Copying and relocating data:\n\n");
  
!   lseek (outdesc, output_data_offset, 0);
! 
!   each_full_file (copy_data, 0);
    file_close ();
  
    /* Write out the set element vectors.  See digest symbols for
--- 3569,3575 ----
    if (trace_files)
      fprintf (stderr, "Copying and relocating data:\n\n");
  
!   each_full_file (copy_data);
    file_close ();
  
    /* Write out the set element vectors.  See digest symbols for
***************
*** 4741,4750 ****
  
    desc = file_open (entry);
  
!   bytes = (char *) alloca (entry->data_size);
  
    if (entry->datarel) reloc = entry->datarel;
!   else if (output_style == OUTPUT_RELOCATABLE)	/* Will need this again */
      {
        read_file_relocation (entry);
        reloc = entry->datarel;
--- 3603,3612 ----
  
    desc = file_open (entry);
  
!   bytes = (char *) alloca (entry->header.a_data);
  
    if (entry->datarel) reloc = entry->datarel;
!   else if (relocatable_output)	/* Will need this again */
      {
        read_file_relocation (entry);
        reloc = entry->datarel;
***************
*** 4751,4775 ****
      }
    else
      {
!       reloc = (struct relocation_info *) alloca (entry->data_reloc_size);
!       lseek (desc, entry->starting_offset + entry->data_reloc_offset, L_SET);
!       if (entry->data_reloc_size != read (desc, reloc, entry->data_reloc_size))
  	fatal_with_file ("premature eof in data relocation of ", entry);
- #ifdef MACH_O
-       if (entry->file_type == IS_MACH_O)
- 	translate_mach_o_relocation (entry, reloc,
- 				     entry->data_reloc_size / sizeof (struct relocation_info));
- #endif
      }
  
!   lseek (desc, entry->starting_offset + entry->data_offset, L_SET);
!   if (entry->data_size != read (desc, bytes, entry->data_size))
      fatal_with_file ("premature eof in data section of ", entry);
  
!   perform_relocation (bytes, entry->data_start_address - entry->orig_data_address,
! 		      entry->data_size, reloc, entry->data_reloc_size, entry);
  
!   mywrite (bytes, 1, entry->data_size, outdesc);
  }
  
  /* Relocate ENTRY's text or data section contents.
--- 3613,3634 ----
      }
    else
      {
!       reloc = (struct relocation_info *) alloca (entry->header.a_drsize);
!       lseek (desc, text_offset (entry) + entry->header.a_text
! 	     + entry->header.a_data + entry->header.a_trsize,
! 	     0);
!       if (entry->header.a_drsize != read (desc, reloc, entry->header.a_drsize))
  	fatal_with_file ("premature eof in data relocation of ", entry);
      }
  
!   lseek (desc, text_offset (entry) + entry->header.a_text, 0);
!   if (entry->header.a_data != read (desc, bytes, entry->header.a_data))
      fatal_with_file ("premature eof in data section of ", entry);
  
!   perform_relocation (bytes, entry->data_start_address - entry->header.a_text,
! 		      entry->header.a_data, reloc, entry->header.a_drsize, entry);
  
!   mywrite (bytes, 1, entry->header.a_data, outdesc);
  }
  
  /* Relocate ENTRY's text or data section contents.
***************
*** 4779,4785 ****
       in the output file and its address in the input file.
     RELOC_INFO is the address of the relocation info, in core.
     RELOC_SIZE is its length in bytes.  */
! /* This version is about to be severly hacked by Randy.  Hope it
     works afterwards. */
  void
  perform_relocation (data, pc_relocation, data_size, reloc_info, reloc_size, entry)
--- 3638,3644 ----
       in the output file and its address in the input file.
     RELOC_INFO is the address of the relocation info, in core.
     RELOC_SIZE is its length in bytes.  */
! /* This version is about to be severley hacked by Randy.  Hope it
     works afterwards. */
  void
  perform_relocation (data, pc_relocation, data_size, reloc_info, reloc_size, entry)
***************
*** 4793,4801 ****
    register struct relocation_info *p = reloc_info;
    struct relocation_info *end
      = reloc_info + reloc_size / sizeof (struct relocation_info);
!   int text_relocation = entry->text_start_address - entry->orig_text_address;
!   int data_relocation = entry->data_start_address - entry->orig_data_address;
!   int bss_relocation = entry->bss_start_address - entry->orig_bss_address;
  
    for (; p < end; p++)
      {
--- 3652,3661 ----
    register struct relocation_info *p = reloc_info;
    struct relocation_info *end
      = reloc_info + reloc_size / sizeof (struct relocation_info);
!   int text_relocation = entry->text_start_address;
!   int data_relocation = entry->data_start_address - entry->header.a_text;
!   int bss_relocation
!     = entry->bss_start_address - entry->header.a_text - entry->header.a_data;
  
    for (; p < end; p++)
      {
***************
*** 4820,4826 ****
  	    sp = (symbol *) sp->value;
  #endif
  
! 	  if (symindex >= entry->syms_size)
  	    fatal_with_file ("relocation symbolnum out of range in ", entry);
  
  	  /* If the symbol is undefined, leave it at zero.  */
--- 3680,3686 ----
  	    sp = (symbol *) sp->value;
  #endif
  
! 	  if (symindex >= entry->header.a_syms)
  	    fatal_with_file ("relocation symbolnum out of range in ", entry);
  
  	  /* If the symbol is undefined, leave it at zero.  */
***************
*** 4838,4848 ****
--- 3698,3713 ----
  
  	case N_DATA:
  	case N_DATA | N_EXT:
+ 	  /* A word that points to beginning of the the data section
+ 	     initially contains not 0 but rather the "address" of that section
+ 	     in the input file, which is the length of the file's text.  */
  	  relocation = data_relocation;
  	  break;
  
  	case N_BSS:
  	case N_BSS | N_EXT:
+ 	  /* Similarly, an input word pointing to the beginning of the bss
+ 	     initially contains the length of text plus data of the file.  */
  	  relocation = bss_relocation;
  	  break;
  
***************
*** 4860,4866 ****
  
  #ifdef RELOC_ADD_EXTRA
        relocation += RELOC_ADD_EXTRA(p);
!       if (output_style == OUTPUT_RELOCATABLE)
  	{
  	  /* If this RELOC_ADD_EXTRA is 0, it means that the
  	     symbol was external and the relocation does not
--- 3725,3731 ----
  
  #ifdef RELOC_ADD_EXTRA
        relocation += RELOC_ADD_EXTRA(p);
!       if (relocatable_output)
  	{
  	  /* If this RELOC_ADD_EXTRA is 0, it means that the
  	     symbol was external and the relocation does not
***************
*** 4918,4939 ****
  	  break;
  
  	case 2:
- #ifdef CROSS_LINKER
- 	  /* This is necessary if the host has stricter alignment
- 	     than the target.  Too slow to use all the time.
- 	     Also doesn't deal with differing byte-order.  */
- 	  {
- 	    /* Thing to relocate.  */
- 	    long thing;
- 	    bcopy (data + addr, &thing, sizeof (thing));
- 	    if (RELOC_MEMORY_SUB_P (p))
- 	      relocation -= mask & thing;
- 	    else if (RELOC_MEMORY_ADD_P (p))
- 	      relocation += mask & thing;
- 	    thing = (thing & ~mask) | relocation;
- 	    bcopy (&thing, data + addr, sizeof (thing));
- 	  }
- #else /* not CROSS_LINKER */
  	  if (RELOC_MEMORY_SUB_P(p))
  	    relocation -= mask & *(long *) (data + addr);
  	  else if (RELOC_MEMORY_ADD_P(p))
--- 3783,3788 ----
***************
*** 4940,4946 ****
  	    relocation += mask & *(long *) (data + addr);
  	  *(long *) (data + addr) &= ~mask;
  	  *(long *) (data + addr) |= relocation;
- #endif /* not CROSS_LINKER */
  	  break;
  
  	default:
--- 3789,3794 ----
***************
*** 4949,4955 ****
      }
  }
  
! /* For OUTPUT_RELOCATABLE only: write out the relocation,
     relocating the addresses-to-be-relocated.  */
  
  void coptxtrel (), copdatrel ();
--- 3797,3803 ----
      }
  }
  
! /* For relocatable_output only: write out the relocation,
     relocating the addresses-to-be-relocated.  */
  
  void coptxtrel (), copdatrel ();
***************
*** 4975,5009 ****
  	if (sp->referenced || sp->defined)
  	  {
  	    sp->def_count = count++;
- #ifndef NeXT
  	    /* Leave room for the reference required by N_INDR, if
  	       necessary.  */
  	    if ((sp->defined & ~N_EXT) == N_INDR)
  	      count++;
- #endif
  	  }
      }
!   /* Correct, because if (OUTPUT_RELOCATABLE), we will also be writing
       whatever indirect blocks we have.  */
- #ifndef NeXT
    if (count != defined_global_sym_count
        + undefined_global_sym_count + global_indirect_count)
- #else
-   if (count != defined_global_sym_count
-       + undefined_global_sym_count)
- #endif
      fatal ("internal error");
  
    /* Write out the relocations of all files, remembered from copy_text.  */
  
!   lseek (outdesc, output_trel_offset, 0);
!   each_full_file (coptxtrel, 0);
  
    if (trace_files)
      fprintf (stderr, "\nWriting data relocation:\n\n");
  
!   lseek (outdesc, output_drel_offset, 0);
!   each_full_file (copdatrel, 0);
  
    if (trace_files)
      fprintf (stderr, "\n");
--- 3823,3848 ----
  	if (sp->referenced || sp->defined)
  	  {
  	    sp->def_count = count++;
  	    /* Leave room for the reference required by N_INDR, if
  	       necessary.  */
  	    if ((sp->defined & ~N_EXT) == N_INDR)
  	      count++;
  	  }
      }
!   /* Correct, because if (reloatable_output), we will also be writing
       whatever indirect blocks we have.  */
    if (count != defined_global_sym_count
        + undefined_global_sym_count + global_indirect_count)
      fatal ("internal error");
  
    /* Write out the relocations of all files, remembered from copy_text.  */
  
!   each_full_file (coptxtrel);
  
    if (trace_files)
      fprintf (stderr, "\nWriting data relocation:\n\n");
  
!   each_full_file (copdatrel);
  
    if (trace_files)
      fprintf (stderr, "\n");
***************
*** 5014,5023 ****
       struct file_entry *entry;
  {
    register struct relocation_info *p, *end;
!   register int reloc = entry->text_start_address - text_start;
  
    p = entry->textrel;
!   end = (struct relocation_info *) (entry->text_reloc_size + (char *) p);
    while (p < end)
      {
        RELOC_ADDRESS(p) += reloc;
--- 3853,3862 ----
       struct file_entry *entry;
  {
    register struct relocation_info *p, *end;
!   register int reloc = entry->text_start_address;
  
    p = entry->textrel;
!   end = (struct relocation_info *) (entry->header.a_trsize + (char *) p);
    while (p < end)
      {
        RELOC_ADDRESS(p) += reloc;
***************
*** 5029,5035 ****
  			      (((char *)entry->symbols) + symindex))
  			     ->n_un.n_name));
  
! 	  if (symindex >= entry->syms_size)
  	    fatal_with_file ("relocation symbolnum out of range in ", entry);
  
  #ifdef N_INDR
--- 3868,3874 ----
  			      (((char *)entry->symbols) + symindex))
  			     ->n_un.n_name));
  
! 	  if (symindex >= entry->header.a_syms)
  	    fatal_with_file ("relocation symbolnum out of range in ", entry);
  
  #ifdef N_INDR
***************
*** 5044,5050 ****
  	  if (symptr->defined)
  	    {
  	      RELOC_EXTERN_P(p) = 0;
! 	      RELOC_SYMBOL(p) = (symptr->defined & ~N_EXT);
  #ifdef RELOC_ADD_EXTRA
  	      /* If we aren't going to be adding in the value in
  	         memory on the next pass of the loader, then we need
--- 3883,3889 ----
  	  if (symptr->defined)
  	    {
  	      RELOC_EXTERN_P(p) = 0;
! 	      RELOC_SYMBOL(p) = (symptr->defined & N_TYPE);
  #ifdef RELOC_ADD_EXTRA
  	      /* If we aren't going to be adding in the value in
  	         memory on the next pass of the loader, then we need
***************
*** 5057,5083 ****
  	  else
  	    /* Debugger symbols come first, so have to start this
  	       after them.  */
- #ifndef NeXT
  	      RELOC_SYMBOL(p) = (symptr->def_count + nsyms
  				 - defined_global_sym_count
  				 - undefined_global_sym_count
  				 - global_indirect_count);
- #else
- 	      RELOC_SYMBOL(p) = (symptr->def_count + nsyms
- 				 - defined_global_sym_count
- 				 - undefined_global_sym_count);
- #endif
  	}
        p++;
      }
! 
! #ifdef MACH_O
!   if (output_file_type == IS_MACH_O)
!     generate_mach_o_relocations(entry->textrel,
! 				entry->text_reloc_size / sizeof (struct relocation_info));
! #endif
! 
!   mywrite (entry->textrel, 1, entry->text_reloc_size, outdesc);
  }
  
  void
--- 3896,3909 ----
  	  else
  	    /* Debugger symbols come first, so have to start this
  	       after them.  */
  	      RELOC_SYMBOL(p) = (symptr->def_count + nsyms
  				 - defined_global_sym_count
  				 - undefined_global_sym_count
  				 - global_indirect_count);
  	}
        p++;
      }
!   mywrite (entry->textrel, 1, entry->header.a_trsize, outdesc);
  }
  
  void
***************
*** 5087,5100 ****
    register struct relocation_info *p, *end;
    /* Relocate the address of the relocation.
       Old address is relative to start of the input file's data section.
!      New address is relative to start of the output file's data section.
  
-      So the amount we need to relocate it by is the offset of this
-      input file's data section within the output file's data section.  */
-   register int reloc = entry->data_start_address - data_start;
- 
    p = entry->datarel;
!   end = (struct relocation_info *) (entry->data_reloc_size + (char *) p);
    while (p < end)
      {
        RELOC_ADDRESS(p) += reloc;
--- 3913,3923 ----
    register struct relocation_info *p, *end;
    /* Relocate the address of the relocation.
       Old address is relative to start of the input file's data section.
!      New address is relative to start of the output file's data section.  */
!   register int reloc = entry->data_start_address - text_size;
  
    p = entry->datarel;
!   end = (struct relocation_info *) (entry->header.a_drsize + (char *) p);
    while (p < end)
      {
        RELOC_ADDRESS(p) += reloc;
***************
*** 5107,5113 ****
  			     ->n_un.n_name));
  	  int symtype;
  
! 	  if (symindex >= entry->syms_size)
  	    fatal_with_file ("relocation symbolnum out of range in ", entry);
  
  #ifdef N_INDR
--- 3930,3936 ----
  			     ->n_un.n_name));
  	  int symtype;
  
! 	  if (symindex >= entry->header.a_syms)
  	    fatal_with_file ("relocation symbolnum out of range in ", entry);
  
  #ifdef N_INDR
***************
*** 5116,5122 ****
  	    symptr = (symbol *) symptr->value;
  #endif
  
! 	  symtype = symptr->defined & ~N_EXT;
  
  	  if (force_common_definition
  	      || symtype == N_DATA || symtype == N_TEXT || symtype == N_ABS)
--- 3939,3945 ----
  	    symptr = (symbol *) symptr->value;
  #endif
  
! 	   symtype = symptr->defined & N_TYPE;
  
  	  if (force_common_definition
  	      || symtype == N_DATA || symtype == N_TEXT || symtype == N_ABS)
***************
*** 5127,5133 ****
  	  else
  	    /* Debugger symbols come first, so have to start this
  	       after them.  */
- #ifndef NeXT
  	    RELOC_SYMBOL(p)
  	      = (((symbol *)
  		  (((struct nlist *)
--- 3950,3955 ----
***************
*** 5137,5167 ****
  		 + nsyms - defined_global_sym_count
  		 - undefined_global_sym_count
  		 - global_indirect_count);
- #else
- 	    RELOC_SYMBOL(p)
- 	      = (((symbol *)
- 		  (((struct nlist *)
- 		    (((char *)entry->symbols) + symindex))
- 		   ->n_un.n_name))
- 		 ->def_count
- 		 + nsyms - defined_global_sym_count
- 		 - undefined_global_sym_count);
- #endif
  	}
        p++;
      }
! #ifdef MACH_O
!   if (output_file_type == IS_MACH_O)
!     generate_mach_o_relocations(entry->datarel,
! 				entry->data_reloc_size / sizeof (struct relocation_info));
! #endif
! 
!   mywrite (entry->datarel, 1, entry->data_reloc_size, outdesc);
  }
  
  void write_file_syms ();
  void write_string_table ();
  
  /* Total size of string table strings allocated so far,
     including strings in `strtab_vector'.  */
  int strtab_size;
--- 3959,3985 ----
  		 + nsyms - defined_global_sym_count
  		 - undefined_global_sym_count
  		 - global_indirect_count);
  	}
        p++;
      }
!   mywrite (entry->datarel, 1, entry->header.a_drsize, outdesc);
  }
  
  void write_file_syms ();
  void write_string_table ();
  
+ /* Offsets and current lengths of symbol and string tables in output file. */
+ 
+ int symbol_table_offset;
+ int symbol_table_len;
+ 
+ /* Address in output file where string table starts.  */
+ int string_table_offset;
+ 
+ /* Offset within string table
+    where the strings in `strtab_vector' should be written.  */
+ int string_table_len;
+ 
  /* Total size of string table strings allocated so far,
     including strings in `strtab_vector'.  */
  int strtab_size;
***************
*** 5204,5210 ****
  {
    register int i;
  
!   lseek (outdesc, output_strs_offset + output_strs_size, 0);
  
    if (!outstream)
      outstream = fdopen (outdesc, "w");
--- 4022,4028 ----
  {
    register int i;
  
!   lseek (outdesc, string_table_offset + string_table_len, 0);
  
    if (!outstream)
      outstream = fdopen (outdesc, "w");
***************
*** 5212,5218 ****
    for (i = 0; i < strtab_index; i++)
      {
        fwrite (strtab_vector[i], 1, strtab_lens[i], outstream);
!       output_strs_size += strtab_lens[i];
      }
  
    fflush (outstream);
--- 4030,4036 ----
    for (i = 0; i < strtab_index; i++)
      {
        fwrite (strtab_vector[i], 1, strtab_lens[i], outstream);
!       string_table_len += strtab_lens[i];
      }
  
    fflush (outstream);
***************
*** 5236,5251 ****
       extra struct for each indirect symbol to hold the extra reference
       following. */
    struct nlist *buf
- #ifndef NeXT
      = (struct nlist *) alloca ((defined_global_sym_count
  				+ undefined_global_sym_count
  				+ global_indirect_count)
  			       * sizeof (struct nlist));
- #else
-     = (struct nlist *) alloca ((defined_global_sym_count
- 				+ undefined_global_sym_count)
- 			       * sizeof (struct nlist));
- #endif
    /* Pointer for storing into BUF.  */
    register struct nlist *bufp = buf;
  
--- 4054,4063 ----
***************
*** 5252,5259 ****
    /* Size of string table includes the bytes that store the size.  */
    strtab_size = sizeof strtab_size;
  
!   output_syms_size = 0;
!   output_strs_size = strtab_size;
  
    if (strip_symbols == STRIP_ALL)
      return;
--- 4064,4073 ----
    /* Size of string table includes the bytes that store the size.  */
    strtab_size = sizeof strtab_size;
  
!   symbol_table_offset = N_SYMOFF (outheader);
!   symbol_table_len = 0;
!   string_table_offset = N_STROFF (outheader);
!   string_table_len = strtab_size;
  
    if (strip_symbols == STRIP_ALL)
      return;
***************
*** 5282,5292 ****
        {
  	struct nlist nl;
  
- #ifdef N_SECT
- 	nl.n_sect = 0;
- #else
  	nl.n_other = 0;
- #endif
  	nl.n_desc = 0;
  
  	/* Compute a `struct nlist' for the symbol.  */
--- 4096,4102 ----
***************
*** 5301,5308 ****
  		/* If the target of an indirect symbol has been
  		   defined and we are outputting an executable,
  		   resolve the indirection; it's no longer needed */
! 		if (output_style != OUTPUT_RELOCATABLE
! 		    && ((sp->defined & ~N_EXT) == N_INDR)
  		    && (((symbol *) sp->value)->defined > 1))
  		  {
  		    symbol *newsp = (symbol *) sp->value;
--- 4111,4118 ----
  		/* If the target of an indirect symbol has been
  		   defined and we are outputting an executable,
  		   resolve the indirection; it's no longer needed */
! 		if (!relocatable_output
! 		    && ((sp->defined & N_TYPE) == N_INDR)
  		    && (((symbol *) sp->value)->defined > 1))
  		  {
  		    symbol *newsp = (symbol *) sp->value;
***************
*** 5342,5389 ****
  	    *bufp++ = nl;
  	    syms_written++;
  	    if (nl.n_type == (N_INDR | N_EXT))
- #ifndef NeXT
  	      {
  		struct nlist xtra_ref;
  		xtra_ref.n_type == N_EXT | N_UNDF;
  		xtra_ref.n_un.n_strx
  		  = assign_string_table_index (((symbol *) sp->value)->name);
- #ifdef N_SECT
- 		xtra_ref.n_sect = 0;
- #else
  		xtra_ref.n_other = 0;
- #endif
  		xtra_ref.n_desc = 0;
  		xtra_ref.n_value = 0;
  		*bufp++ = xtra_ref;
  		syms_written++;
  	      }
- #else
- 	    nl.n_value = assign_string_table_index (((symbol *) sp->value)->name);
- #endif
  	  }
        }
  
- #ifdef MACH_O
-   if (output_file_type == IS_MACH_O)
-     generate_mach_o_symbols(buf, bufp - buf);
- #endif
- 
    /* Output the buffer full of `struct nlist's.  */
  
!   lseek (outdesc, output_syms_offset + output_syms_size, 0);
    mywrite (buf, sizeof (struct nlist), bufp - buf, outdesc);
!   output_syms_size += sizeof (struct nlist) * (bufp - buf);
  
    if (syms_written != nsyms)
      fatal ("internal error: wrong number of symbols written into output file", 0);
  
!   /* Now the total string table size is known, so write it into the
!      first word of the string table.  */
  
!   lseek (outdesc, output_strs_offset, 0);
!   mywrite (&strtab_size, sizeof (int), 1, outdesc);
  
    /* Write the strings for the global symbols.  */
  
    write_string_table ();
--- 4152,4188 ----
  	    *bufp++ = nl;
  	    syms_written++;
  	    if (nl.n_type == (N_INDR | N_EXT))
  	      {
  		struct nlist xtra_ref;
  		xtra_ref.n_type == N_EXT | N_UNDF;
  		xtra_ref.n_un.n_strx
  		  = assign_string_table_index (((symbol *) sp->value)->name);
  		xtra_ref.n_other = 0;
  		xtra_ref.n_desc = 0;
  		xtra_ref.n_value = 0;
  		*bufp++ = xtra_ref;
  		syms_written++;
  	      }
  	  }
        }
  
    /* Output the buffer full of `struct nlist's.  */
  
!   lseek (outdesc, symbol_table_offset + symbol_table_len, 0);
    mywrite (buf, sizeof (struct nlist), bufp - buf, outdesc);
!   symbol_table_len += sizeof (struct nlist) * (bufp - buf);
  
    if (syms_written != nsyms)
      fatal ("internal error: wrong number of symbols written into output file", 0);
  
!   if (symbol_table_offset + symbol_table_len != string_table_offset)
!     fatal ("internal error: inconsistent symbol table length", 0);
  
!   /* Now the total string table size is known, so write it.
!      We are already positioned at the right place in the file.  */
  
+   mywrite (&strtab_size, sizeof (int), 1, outdesc);  /* we're at right place */
+ 
    /* Write the strings for the global symbols.  */
  
    write_string_table ();
***************
*** 5401,5416 ****
       int *syms_written_addr;
  {
    register struct nlist *p = entry->symbols;
!   register struct nlist *end = p + entry->syms_size / sizeof (struct nlist);
  
    /* Buffer to accumulate all the syms before writing them.
       It has one extra slot for the local symbol we generate here.  */
    struct nlist *buf
!     = (struct nlist *) alloca (entry->syms_size + sizeof (struct nlist));
    register struct nlist *bufp = buf;
  
    /* Upper bound on number of syms to be written here.  */
!   int max_syms = (entry->syms_size / sizeof (struct nlist)) + 1;
  
    /* Make tables that record, for each symbol, its name and its name's length.
       The elements are filled in by `assign_string_table_index'.  */
--- 4200,4215 ----
       int *syms_written_addr;
  {
    register struct nlist *p = entry->symbols;
!   register struct nlist *end = p + entry->header.a_syms / sizeof (struct nlist);
  
    /* Buffer to accumulate all the syms before writing them.
       It has one extra slot for the local symbol we generate here.  */
    struct nlist *buf
!     = (struct nlist *) alloca (entry->header.a_syms + sizeof (struct nlist));
    register struct nlist *bufp = buf;
  
    /* Upper bound on number of syms to be written here.  */
!   int max_syms = (entry->header.a_syms / sizeof (struct nlist)) + 1;
  
    /* Make tables that record, for each symbol, its name and its name's length.
       The elements are filled in by `assign_string_table_index'.  */
***************
*** 5429,5439 ****
        nl.n_un.n_strx = assign_string_table_index (entry->local_sym_name);
        nl.n_value = entry->text_start_address;
        nl.n_desc = 0;
- #ifdef N_SECT
-       nl.n_sect = 0;
- #else
        nl.n_other = 0;
- #endif
        *bufp++ = nl;
        (*syms_written_addr)++;
        entry->local_syms_offset = *syms_written_addr * sizeof (struct nlist);
--- 4228,4234 ----
***************
*** 5441,5447 ****
  
    /* Read the file's string table.  */
  
!   entry->strings = (char *) alloca (entry->strs_size);
    read_entry_strings (file_open (entry), entry);
  
    for (; p < end; p++)
--- 4236,4242 ----
  
    /* Read the file's string table.  */
  
!   entry->strings = (char *) alloca (entry->string_size);
    read_entry_strings (file_open (entry), entry);
  
    for (; p < end; p++)
***************
*** 5456,5462 ****
  				/* types of symbols are never written */
  				/* globally, though they are stored */
  				/* globally.  */
!         write = output_style == OUTPUT_RELOCATABLE;
        else if (!(type & (N_STAB | N_EXT)))
          /* ordinary local symbol */
  	write = ((discard_locals != DISCARD_ALL)
--- 4251,4257 ----
  				/* types of symbols are never written */
  				/* globally, though they are stored */
  				/* globally.  */
!         write = relocatable_output;
        else if (!(type & (N_STAB | N_EXT)))
          /* ordinary local symbol */
  	write = ((discard_locals != DISCARD_ALL)
***************
*** 5483,5498 ****
  	}
      }
  
- #ifdef MACH_O
-   if (output_file_type == IS_MACH_O)
-     generate_mach_o_symbols(buf, bufp - buf);
- #endif
- 
    /* All the symbols are now in BUF; write them.  */
  
!   lseek (outdesc, output_syms_offset + output_syms_size, 0);
    mywrite (buf, sizeof (struct nlist), bufp - buf, outdesc);
!   output_syms_size += sizeof (struct nlist) * (bufp - buf);
  
    /* Write the string-table data for the symbols just written,
       using the data in vectors `strtab_vector' and `strtab_lens'.  */
--- 4278,4288 ----
  	}
      }
  
    /* All the symbols are now in BUF; write them.  */
  
!   lseek (outdesc, symbol_table_offset + symbol_table_len, 0);
    mywrite (buf, sizeof (struct nlist), bufp - buf, outdesc);
!   symbol_table_len += sizeof (struct nlist) * (bufp - buf);
  
    /* Write the string-table data for the symbols just written,
       using the data in vectors `strtab_vector' and `strtab_lens'.  */
***************
*** 5510,5516 ****
  void
  write_symsegs ()
  {
-   lseek (outdesc, output_symseg_offset, 0);
    each_file (write_file_symseg, 0);
  }
  
--- 4300,4305 ----
***************
*** 5520,5532 ****
  {
    char buffer[4096];
    struct symbol_root root;
!   int indesc, len, total;
  
!   if (entry->symseg_size == 0)
      return;
  
-   output_symseg_size += entry->symseg_size;
- 
    /* This entry has a symbol segment.  Read the root of the segment.  */
  
    indesc = file_open (entry);
--- 4309,4320 ----
  {
    char buffer[4096];
    struct symbol_root root;
!   int indesc;
!   int len;
  
!   if (entry->symseg_offset == 0)
      return;
  
    /* This entry has a symbol segment.  Read the root of the segment.  */
  
    indesc = file_open (entry);
***************
*** 5537,5545 ****
    /* Store some relocation info into the root.  */
  
    root.ldsymoff = entry->local_syms_offset;
!   root.textrel = entry->text_start_address - entry->orig_text_address;
!   root.datarel = entry->data_start_address - entry->orig_data_address;
!   root.bssrel = entry->bss_start_address - entry->orig_bss_address;
    root.databeg = entry->data_start_address - root.datarel;
    root.bssbeg = entry->bss_start_address - root.bssrel;
  
--- 4325,4334 ----
    /* Store some relocation info into the root.  */
  
    root.ldsymoff = entry->local_syms_offset;
!   root.textrel = entry->text_start_address;
!   root.datarel = entry->data_start_address - entry->header.a_text;
!   root.bssrel = entry->bss_start_address
!     - entry->header.a_text - entry->header.a_data;
    root.databeg = entry->data_start_address - root.datarel;
    root.bssbeg = entry->bss_start_address - root.bssrel;
  
***************
*** 5549,5646 ****
  
    /* Copy the rest of the symbol segment unchanged.  */
  
!   total = entry->symseg_size - sizeof root;
! 
!   while (total > 0)
      {
!       len = read (indesc, buffer, min (sizeof buffer, total));
! 
!       if (len != min (sizeof buffer, total))
! 	fatal_with_file ("premature end of file in symbol segment of ", entry);
!       total -= len;
!       mywrite (buffer, len, 1, outdesc);
      }
  
    file_close ();
  }
  
- /* Define a special symbol (etext, edata, or end).  NAME is the
-    name of the symbol, with a leading underscore (whether or not this
-    system uses such underscores).  TYPE is its type (e.g. N_DATA | N_EXT).
-    Store a symbol * for the symbol in *SYM if SYM is non-NULL.  */
- static void
- symbol_define (name, type, sym)
-      /* const */ char *name;
-      int type;
-      symbol **sym;
- {
-   symbol *thesym;
- 
- #if defined(nounderscore)
-   /* Skip the leading underscore.  */
-   name++;
- #endif
- 
-   thesym = getsym (name);
-   if (thesym->defined)
-     {
-       /* The symbol is defined in some input file.  Don't mess with it.  */
-       if (sym)
- 	*sym = 0;
-     }
-   else
-     {
-       if (thesym->referenced)
- 	/* The symbol was not defined, and we are defining it now.  */
- 	undefined_global_sym_count--;
-       thesym->defined = type;
-       thesym->referenced = 1;
-       if (sym)
- 	*sym = thesym;
-     }
- }
- 
  /* Create the symbol table entries for `etext', `edata' and `end'.  */
  
  void
  symtab_init ()
  {
!   symbol_define ("_edata", N_DATA | N_EXT, &edata_symbol);
!   symbol_define ("_etext", N_TEXT | N_EXT, &etext_symbol);
!   symbol_define ("_end", N_BSS | N_EXT, &end_symbol);
! 
!   /* Either _edata or __edata (C names) is OK as far as ANSI is concerned
!      (see section 4.1.2.1).  In general, it is best to use __foo and
!      not worry about the confusing rules for the _foo namespace.
!      But HPUX 7.0 uses _edata, so we might as weel be consistent.  */
!   symbol_define ("__edata", N_DATA | N_EXT, &edata_symbol_alt);
!   symbol_define ("__etext", N_TEXT | N_EXT, &etext_symbol_alt);
!   symbol_define ("__end", N_BSS | N_EXT, &end_symbol_alt);
  
  #ifdef sun
    {
!     symbol *dynamic_symbol;
!     symbol_define ("__DYNAMIC", N_ABS | N_EXT, &dynamic_symbol);
!     if (dynamic_symbol)
!       dynamic_symbol->value = 0;
!   }
! #endif
! #ifdef sequent
!   {
!     symbol *i387_flt_symbol;
!     symbol_define ("_387_flt", N_ABS | N_EXT, &i387_flt_symbol);
!     if (i387_flt_symbol)
!       i387_flt_symbol->value = 0;
!   }
! #endif
! #ifdef NeXT
!   {
!     symbol *shlib_init_symbol;
!     symbol_define ("__shared_library_initialization", N_UNDF | N_EXT, &shlib_init_symbol);
!     if (shlib_init_symbol)
!       shlib_init_symbol->max_common_size = sizeof (long int);
    }
! #endif
  }
  
  /* Compute the hash code for symbol name KEY.  */
--- 4338,4414 ----
  
    /* Copy the rest of the symbol segment unchanged.  */
  
!   if (entry->superfile)
      {
!       /* Library member: number of bytes to copy is determined
! 	 from the member's total size.  */
! 
!       int total = entry->total_size - entry->symseg_offset - sizeof root;
! 
!       while (total > 0)
! 	{
! 	  len = read (indesc, buffer, min (sizeof buffer, total));
! 
! 	  if (len != min (sizeof buffer, total))
! 	    fatal_with_file ("premature end of file in symbol segment of ", entry);
! 	  total -= len;
! 	  mywrite (buffer, len, 1, outdesc);
! 	}
!     }
!   else
!     {
!       /* A separate file: copy until end of file.  */
! 
!       while (len = read (indesc, buffer, sizeof buffer))
! 	{
! 	  mywrite (buffer, len, 1, outdesc);
! 	  if (len < sizeof buffer)
! 	    break;
! 	}
      }
  
    file_close ();
  }
  
  /* Create the symbol table entries for `etext', `edata' and `end'.  */
  
  void
  symtab_init ()
  {
! #ifndef nounderscore
!   edata_symbol = getsym ("_edata");
!   etext_symbol = getsym ("_etext");
!   end_symbol = getsym ("_end");
! #else
!   edata_symbol = getsym ("edata");
!   etext_symbol = getsym ("etext");
!   end_symbol = getsym ("end");
! #endif
  
  #ifdef sun
    {
!     symbol *dynamic_symbol = getsym ("__DYNAMIC");
!     dynamic_symbol->defined = N_ABS | N_EXT;
!     dynamic_symbol->referenced = 1;
!     dynamic_symbol->value = 0;
    }
! #endif
! #ifdef sequent
!   {
!     symbol *_387_flt_symbol = getsym ("_387_flt");
!     _387_flt_symbol->defined = N_ABS | N_EXT;
!     _387_flt_symbol->referenced = 1;
!     _387_flt_symbol->value = 0;
!   }
! #endif
! 
!   edata_symbol->defined = N_DATA | N_EXT;
!   etext_symbol->defined = N_TEXT | N_EXT;
!   end_symbol->defined = N_BSS | N_EXT;
! 
!   edata_symbol->referenced = 1;
!   etext_symbol->referenced = 1;
!   end_symbol->referenced = 1;
  }
  
  /* Compute the hash code for symbol name KEY.  */
***************
*** 5727,5754 ****
    return 0;
  }
  
- /* Report a usage error.
-    Like fatal except prints a usage summary.  */
- 
- void
- usage (string, arg)
-      char *string, *arg;
- {
-   if (string)
-     {
-       fprintf (stderr, "%s: ", progname);
-       fprintf (stderr, string, arg);
-       fprintf (stderr, "\n");
-     }
-   fprintf (stderr, "\
- Usage: %s [-d] [-dc] [-dp] [-e symbol] [-l lib] [-n] [-noinhibit-exec]\n\
-        [-nostdlib] [-o file] [-r] [-s] [-t] [-u symbol] [-x] [-y symbol]\n\
-        [-z] [-A file] [-Bstatic] [-D size] [-L libdir] [-M] [-N]\n\
-        [-S] [-T[{text,data}] addr] [-V prefix] [-X] [file...]\n",
- 	   progname);
-   exit (1);
- }
- 
  /* Report a fatal error.
     STRING is a printf format string and ARG is one arg for it.  */
  
--- 4495,4500 ----
***************
*** 5756,5762 ****
  fatal (string, arg)
       char *string, *arg;
  {
!   fprintf (stderr, "%s: ", progname);
    fprintf (stderr, string, arg);
    fprintf (stderr, "\n");
    exit (1);
--- 4502,4508 ----
  fatal (string, arg)
       char *string, *arg;
  {
!   fprintf (stderr, "ld: ");
    fprintf (stderr, string, arg);
    fprintf (stderr, "\n");
    exit (1);
***************
*** 5770,5776 ****
       char *string;
       struct file_entry *entry;
  {
!   fprintf (stderr, "%s: ", progname);
    fprintf (stderr, string);
    print_file_name (entry, stderr);
    fprintf (stderr, "\n");
--- 4516,4522 ----
       char *string;
       struct file_entry *entry;
  {
!   fprintf (stderr, "ld: ");
    fprintf (stderr, string);
    print_file_name (entry, stderr);
    fprintf (stderr, "\n");
***************
*** 5900,5910 ****
  
  /* Like malloc but get fatal error if memory is exhausted.  */
  
! char *
  xmalloc (size)
       int size;
  {
!   register char *result = malloc (size);
    if (!result)
      fatal ("virtual memory exhausted", 0);
    return result;
--- 4646,4656 ----
  
  /* Like malloc but get fatal error if memory is exhausted.  */
  
! int
  xmalloc (size)
       int size;
  {
!   register int result = malloc (size);
    if (!result)
      fatal ("virtual memory exhausted", 0);
    return result;
***************
*** 5912,5923 ****
  
  /* Like realloc but get fatal error if memory is exhausted.  */
  
! char *
  xrealloc (ptr, size)
       char *ptr;
       int size;
  {
!   register char *result = realloc (ptr, size);
    if (!result)
      fatal ("virtual memory exhausted", 0);
    return result;
--- 4658,4669 ----
  
  /* Like realloc but get fatal error if memory is exhausted.  */
  
! int
  xrealloc (ptr, size)
       char *ptr;
       int size;
  {
!   register int result = realloc (ptr, size);
    if (!result)
      fatal ("virtual memory exhausted", 0);
    return result;
***************
*** 5944,5955 ****
    return (4096);
  }
  
- #endif
- 
- #if defined(sun) && defined(sparc)
- int
- getpagesize ()
- {
-   return 8192;
- }
  #endif
--- 4690,4693 ----
