Subject: diffs to GNU binutils-2.5.2 to add a mips-dec-netbsd configuration
To: None <jtc@cygnus.com>
From: Jonathan Stone <jonathan@DSG.Stanford.EDU>
List: port-pmax
Date: 12/10/1994 15:19:50
Included below are the unmodified, verbatim diffs from binutils-2.5.2
for the toolset I've been using to  successfully build NetBSD  a.out
binaries for a DECstation (little-endian mips cpu).

The changes are probably not suitable for direct incorporation into a
Cygnus source tree.  For example, I haven't supplied ChangeLog entries.
I also stole and simply changed the ldscript for the ``mipsbsd''
target -- 4.4BSD on a pmax.  In retrospect that was clearly not the
right thing to do; a new ldscript should be created for  the NetBSD
pmax target.

I found it necessary to make gas configured for mips-dec-netbsd to
ignore any -G 0 option.  This is necessary to get an assembler that
works with current releases of gcc.  Simply put, GCC isn't yet aware
that, on a mips processor, -mgas may imply lack of support for
GP-relative relocation.  (Gas doesn't support this on a.out, as
there's no standard way of encoding the relevant sections needed for
GP-relative support.)  For similar reasons, and for backward
compatibility with the previous release of gas (i.e., 2.3),
I've changed gas tc-mips.c to  silently translate ".rdata"
sections to ".data" sections, exactly as gas-2.3 did.
(Ralph Campbell's changes to encode .sdata/.rdata sections in
a.out objects is, longer term, probably a better fix; but I haven't
merged those from gas-2.3 into binutils-2.5  yet.)


Explicitly defining N_TXTADDR() and N_TXTOFF() in binutils' netbsd.h,
as the patch below provides better versions of, may or may not be
desirable.  The definitions in the distributed binutils-2.5.2 appear
to be modeled after the definitions in NetBSD's header files (i.e., in
the header files in the NetBSD source tree) . Those definitions are
sufficient for the NetBSD toolset; but are not sufficient for
binutils, at least on a pmax.  I'm told by Andrew Cagney that the
default definitions for a.out targets in binutils are even more
correct than the modified definitions in this patch. If that's true,
then I think the ``default'' binutils definitions should be used.  I
don't know enough myself to say.


There's one point where I think the patch below is likely to be
controversial.  NetBSD's object file format is, currently, a.out, but
with the first 32 bits of the a.out header always ni network
(big-endian) byte order.  The GNU BFD back-end attempts to handle this
quirk of NetBSD's a.out format with a macro that byteswaps the magic
number after it's been read in.


It should be evident to anyone with a clue that this is not a sufficient
solution: it does not address the problem of  WRITING OUT an a.out
header with the magic number in network byte order.  There is no
clean machinery that I could  find in the BFD to handle this; so I
simply inlined some code from WRITE_HEADERS at the appropriate point.
I don't know how the FSF and/or Cygnus will wish to fix this -- but
the abstraction-violating hack I include below seemed like a minimally-
-intrusive fix that illustrates the problem and certainly fixes the
bug.


Anyway, it works for me. If you don't find the patches acceptable,
I'd appreciate some indication of how to make them more acceptable.

--Jonathan Stone


*** /dev/null				Sat Aug  7 15:39:29 1993
--- ./bfd/config/mipsdec-nbsd.mt	Sat Aug  7 15:39:29 1993
***************
*** 0 ****
--- 1,4 ----
+ # Target: DECstation MIPS processor running BSD a.out
+ 
+ DEFAULT_VECTOR=aout_mips_little_vec
+ SELECT_ARCHITECTURES=bfd_mips_arch
*** ./bfd/config.bfd.DIST	Tue Sep 13 11:30:07 1994
--- ./bfd/config.bfd	Sat Nov 26 18:32:40 1994
***************
*** 92,97 ****
--- 92,98 ----
    mips*-big-*)		bfd_name=bigmips ;;
    mips*-dec-bsd*)       bfd_name=mipsdecbsd strip_underscore=yes ;;
    mips*-dec-mach3*)     bfd_name=mips-mach3 ;;
+   mips*-dec-netbsd*)    bfd_name=mipsdec-nbsd strip_underscore=yes ;;
    mips*-dec-*)		bfd_name=decstation ;;
    mips*el-*-ecoff*)	bfd_name=decstation ;;
    mips*-*-ecoff*)	bfd_name=bigmips ;;
*** ./bfd/configure.host.DIST	Tue Sep 13 11:30:08 1994
--- ./bfd/configure.host	Sat Nov 26 18:59:33 1994
***************
*** 49,54 ****
--- 49,55 ----
  i860-*-*)		my_host=stratus ;;
  
  mips-dec-bsd*)          my_host=mipsbsd ;;
+ mips-dec-netbsd*)       my_host=mipsbsd ;;
  mips-dec-mach3*)        my_host=mipsmach3 ;;
  mips-dec-*)		my_host=decstation ;;
  mips-sgi-irix3*)	my_host=irix3 ;;
*** ./bfd/mipsbsd.c.DIST	Tue Jul 12 08:46:32 1994
--- ./bfd/mipsbsd.c	Sat Nov 26 21:02:23 1994
***************
*** 26,37 ****
--- 26,51 ----
      (N_MAGIC(x) != ZMAGIC ? (x).a_entry :	/* object file or NMAGIC */\
  	    TEXT_START_ADDR + EXEC_BYTES_SIZE	/* no padding */\
      )
+ #define	BYTES_IN_WORD	4
+ #undef TARGET_IS_BIG_ENDIAN_P
+ 
+ #if 0 /* old 4.4bsd mips a.out*/
  #define N_DATADDR(x) (N_TXTADDR(x)+N_TXTSIZE(x))
  #define TEXT_START_ADDR 4096
  #define PAGE_SIZE 4096
  #define SEGMENT_SIZE PAGE_SIZE
+ #endif
+ 
+ #define	PAGE_SIZE	4096
+ #define	SEGMENT_SIZE	PAGE_SIZE
+ #define __LDPGSZ	4096
  #define DEFAULT_ARCH bfd_arch_mips
+ 
+ 
+ #define M_MIPS1_NETBSD 139
+ 
  #define MACHTYPE_OK(mtype) ((mtype) == M_UNKNOWN \
+ 			    || (mtype) == M_MIPS1_NETBSD \
  			    || (mtype) == M_MIPS1 || (mtype) == M_MIPS2)
  #define MY_symbol_leading_char '\0'
  
***************
*** 39,46 ****
  
  #include "bfd.h"
  #include "sysdep.h"
! #include "libbfd.h"
! #include "libaout.h"
  
  #define SET_ARCH_MACH(ABFD, EXEC) \
    MY(set_arch_mach)(ABFD, N_MACHTYPE (EXEC)); \
--- 53,61 ----
  
  #include "bfd.h"
  #include "sysdep.h"
! #define NULL 0
! 
! /* Mips customizations of aout-target.h */
  
  #define SET_ARCH_MACH(ABFD, EXEC) \
    MY(set_arch_mach)(ABFD, N_MACHTYPE (EXEC)); \
***************
*** 64,70 ****
  #define MY_backend_data &MY(backend_data)
  #define MY_BFD_TARGET
  
! #include "aout-target.h"
  
  void
  MY(set_arch_mach) (abfd, machtype)
--- 79,90 ----
  #define MY_backend_data &MY(backend_data)
  #define MY_BFD_TARGET
  
! /* get NetBSD definitions and a aout-target.h */
! #include "netbsd.h"
! #ifndef NULL
! #define NULL 0
! #endif
! 
  
  void
  MY(set_arch_mach) (abfd, machtype)
***************
*** 78,83 ****
--- 98,104 ----
    switch (machtype) {
  
    case M_MIPS1:
+   case M_MIPS1_NETBSD:
      arch = bfd_arch_mips;
      machine = 3000;
      break;
***************
*** 152,158 ****
        N_SET_MACHTYPE(*execp, M_MIPS2);
        break;
      default:
!       N_SET_MACHTYPE(*execp, M_MIPS1);
        break;
      }
      break;
--- 173,179 ----
        N_SET_MACHTYPE(*execp, M_MIPS2);
        break;
      default:
!       N_SET_MACHTYPE(*execp, M_MIPS1_NETBSD);
        break;
      }
      break;
***************
*** 161,166 ****
--- 182,215 ----
    }
  
    MY(choose_reloc_size)(abfd);
+ 
+ 
+ /* Her begins a Really Ugly Naueseating Patch.
+  * I'd byteswap the magic number in swap_exec_header_out()
+  * where  it belongs.  But swap_exec_header_out() is in aout32.c,
+  * and doesn't get to be configured to suit  our shenanigans.
+  * The  SWAP_MAGIC macro doesn't do this, and anyone who thinks it's
+  * sufficient is illiterate. */
+ 
+ #if 1
+ /*
+ * Taken from WRITE_HEADERS() in libaout.h
+  * we're about to zap the magic number into network byte order, so make
+  * sure we're all done with it except writing it out.
+  */
+   
+   {									
+     bfd_size_type text_size; /* dummy vars */
+     file_ptr text_end;					
+     if (adata(abfd).magic == undecided_magic)
+       NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size,
+ 					    &text_end);
+ }
+ 
+ #endif
+ 
+   execp->a_info = htonl(execp->a_info);	/*XXX*/
+ 
  
    WRITE_HEADERS(abfd, execp);
  
*** ./bfd/netbsd.h.DIST	Tue Sep 13 11:30:15 1994
--- ./bfd/netbsd.h	Sat Nov 26 21:23:13 1994
***************
*** 52,58 ****
      ( (((ex).a_info)&0xffff0000) ? (((ex).a_info)&0xffff) : \
      (((ex).a_info) | 0x10000) )
  
! #define N_TXTADDR(ex)	(N_GETMAGIC2(ex) == (ZMAGIC|0x10000) ? 0 : __LDPGSZ)
  #define N_TXTOFF(ex) \
  	( N_GETMAGIC2(ex)==ZMAGIC || N_GETMAGIC2(ex)==(QMAGIC|0x10000) ? \
  	0 : (N_GETMAGIC2(ex)==(ZMAGIC|0x10000) ? __LDPGSZ : EXEC_BYTES_SIZE ))
--- 52,68 ----
      ( (((ex).a_info)&0xffff0000) ? (((ex).a_info)&0xffff) : \
      (((ex).a_info) | 0x10000) )
  
! /*#define N_TXTADDR(ex)	(N_GETMAGIC2(ex) == (ZMAGIC|0x10000) ? 0 : __LDPGSZ)*/
! /* from netbsd532.c*/
! /* Use a_entry of 0 to distinguish object files from OMAGIC executables */
! #define N_TXTADDR(x) \
!     ((N_MAGIC(x) == OMAGIC) && \
!       ((signed)(x).a_entry < __LDPGSZ) ? 0 :	/* object file or NMAGIC */\
!      N_SHARED_LIB(x) ? 0 :	\
!      N_HEADER_IN_TEXT(x)  ?	\
! 	    TEXT_START_ADDR + EXEC_BYTES_SIZE :	/* no padding */\
! 	    TEXT_START_ADDR			/* a page of padding */\
!     )
  #define N_TXTOFF(ex) \
  	( N_GETMAGIC2(ex)==ZMAGIC || N_GETMAGIC2(ex)==(QMAGIC|0x10000) ? \
  	0 : (N_GETMAGIC2(ex)==(ZMAGIC|0x10000) ? __LDPGSZ : EXEC_BYTES_SIZE ))
*** ./gas/config/tc-mips.c.DIST	Tue Nov  1 15:18:05 1994
--- ./gas/config/tc-mips.c	Sun Dec  4 23:44:20 1994
***************
*** 4975,4981 ****
  #ifdef GPOPT
  CONST char *md_shortopts = "O::g::G:";
  #else
! CONST char *md_shortopts = "O::g::";
  #endif
  struct option md_longopts[] = {
  #define OPTION_MIPS1 (OPTION_MD_BASE + 1)
--- 4975,4981 ----
  #ifdef GPOPT
  CONST char *md_shortopts = "O::g::G:";
  #else
! CONST char *md_shortopts = "O::g::G:"; /* just ignore for now */
  #endif
  struct option md_longopts[] = {
  #define OPTION_MIPS1 (OPTION_MD_BASE + 1)
***************
*** 5178,5185 ****
        break;
  #endif /* OBJ_ELF */
  
- #ifdef GPOPT
      case 'G':
        if (mips_pic == SVR4_PIC || mips_pic == EMBEDDED_PIC)
  	{
  	  as_bad ("-G may not be used with SVR4 or embedded PIC code");
--- 5178,5187 ----
        break;
  #endif /* OBJ_ELF */
  
      case 'G':
+ #ifndef GPOPT
+   /* Silently ignore -G option if we don't support it.  */
+ #else
        if (mips_pic == SVR4_PIC || mips_pic == EMBEDDED_PIC)
  	{
  	  as_bad ("-G may not be used with SVR4 or embedded PIC code");
***************
*** 5188,5195 ****
        else
  	g_switch_value = atoi (arg);
        g_switch_seen = 1;
-       break;
  #endif
  
      default:
        return 0;
--- 5190,5197 ----
        else
  	g_switch_value = atoi (arg);
        g_switch_seen = 1;
  #endif
+       break;
  
      default:
        return 0;
***************
*** 5699,5707 ****
        demand_empty_rest_of_line ();
        break;
  #else
!       as_bad ("no read-only data section for this object file format");
        demand_empty_rest_of_line ();
!       return;
  #endif
  
      case 's':
--- 5701,5715 ----
        demand_empty_rest_of_line ();
        break;
  #else
! #ifdef overly_strict
! 
        demand_empty_rest_of_line ();
!       return;*/
! #else  /*!overly_strict*/
!       s_data (0);
!       break;
!       as_bad ("no read-only data section for this object file format");
! #endif /*!overly_strict*/
  #endif
  
      case 's':
*** ./gas/configure.in.DIST	Tue Nov  1 15:17:54 1994
--- ./gas/configure.in	Sun Nov 27 01:19:14 1994
***************
*** 124,129 ****
--- 124,130 ----
  
    # don't change emulation like *-*-bsd does
    mips-*-bsd*)		obj_format=aout gas_target=mips-lit ;;
+   mips-dec-netbsd*)	obj_format=aout gas_target=mips-lit emulation=netbsd;;
    mips-*-ultrix*)	obj_format=ecoff gas_target=mips-lit ;;
    mips-*-ecoff*)	obj_format=ecoff 
  			case "$endian" in
*** ./ld/scripttempl/mipsbsd.sc.DIST	Tue Sep 20 14:16:23 1994
--- ./ld/scripttempl/mipsbsd.sc	Sat Nov 26 22:31:59 1994
***************
*** 11,17 ****
    {
      CREATE_OBJECT_SYMBOLS
      *(.text)
!     ${RELOCATING+etext = ${DATA_ALIGNMENT};}
    }
    ${RELOCATING+. = ${DATA_ALIGNMENT};}
    .data :
--- 11,17 ----
    {
      CREATE_OBJECT_SYMBOLS
      *(.text)
!     ${RELOCATING+_etext = ${DATA_ALIGNMENT};}
    }
    ${RELOCATING+. = ${DATA_ALIGNMENT};}
    .data :
***************
*** 18,30 ****
    {
      *(.data)
      ${CONSTRUCTING+CONSTRUCTORS}
!     ${RELOCATING+edata  =  .;}
    }
    .bss :
    {
     *(.bss)
     *(COMMON)
!    ${RELOCATING+end = . };
    }
  }
  EOF
--- 18,30 ----
    {
      *(.data)
      ${CONSTRUCTING+CONSTRUCTORS}
!     ${RELOCATING+_edata  =  .;}
    }
    .bss :
    {
     *(.bss)
     *(COMMON)
!    ${RELOCATING+_end = . };
    }
  }
  EOF
*** ./ld/configure.in.DIST	Fri Oct 21 15:19:47 1994
--- ./ld/configure.in	Sat Nov 26 18:00:36 1994
***************
*** 105,110 ****
--- 105,111 ----
    mips*el-idt-ecoff*)	ld_target=mipsl-idt ;;
    mips*-idt-ecoff*)	ld_target=mips-idt ;;
    mips*-dec-bsd*)	ld_target=mipsbsd ;;
+   mips*-dec-netbsd*)	ld_target=mipsbsd ;;
    mips*el-*-elf*)	ld_target=mipsl-elf32 ;;
    mips*-*-elf*)		ld_target=mipsb-elf32 ;;
    alpha-*-osf*)		ld_target=alpha ;;