Subject: cross-elf2ecoff
To: None <port-mips@netbsd.org, port-pmax@netbsd.org, port-sgimips@netbsd.org>
From: Manuel Bouyer <bouyer@antioche.lip6.fr>
List: port-sgimips
Date: 03/22/2002 00:16:25
--zYM0uCDKw75PZbzx
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi,
With the attached patch I get a elf2ecoff built from src/tools, which produces
valid ecoff files that can be loaded by my SGI indy from both by i386 and
my sparc64.
I've had to add a sys/exec_ecoff.h with fixed-size types, and
change machine/ecoff_machdep.h the same way, so that the ecoff structures are
the same on LP32 and LP64 hosts.
elf2ecoff.c uses bswap* to convert structures, which are handled by
tools/config, so it shouldn't be a problem for non-NetBSD hosts (although
I didn't test it yet).

Anyone object if I commit this ?
I'd like to get this in before next monday ...

--
Manuel Bouyer, LIP6, Universite Paris VI.           Manuel.Bouyer@lip6.fr
--

--zYM0uCDKw75PZbzx
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=diff

--- /dev/null	Fri Mar 22 00:07:47 2002
+++ tools/mips-elf2ecoff/sys/exec_ecoff.h	Fri Mar 22 00:06:10 2002
@@ -0,0 +1,120 @@
+/*	$NetBSD: exec_ecoff.h,v 1.12 2000/11/21 00:37:56 jdolecek Exp $	*/
+
+/*
+ * Copyright (c) 1994 Adam Glass
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Adam Glass.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef	_SYS_EXEC_ECOFF_H_
+#define	_SYS_EXEC_ECOFF_H_
+
+#include <machine/ecoff_machdep.h>
+
+struct ecoff_filehdr {
+	ECOFF_USHORT f_magic;	/* magic number */
+	ECOFF_USHORT f_nscns;	/* # of sections */
+	ECOFF_UINT   f_timdat;	/* time and date stamp */
+	ECOFF_ULONG  f_symptr;	/* file offset of symbol table */
+	ECOFF_UINT   f_nsyms;	/* # of symbol table entries */
+	ECOFF_USHORT f_opthdr;	/* sizeof the optional header */
+	ECOFF_USHORT f_flags;	/* flags??? */
+};
+
+struct ecoff_aouthdr {
+	ECOFF_USHORT magic;
+	ECOFF_USHORT vstamp;
+	ECOFF_PAD
+	ECOFF_ULONG  tsize;
+	ECOFF_ULONG  dsize;
+	ECOFF_ULONG  bsize;
+	ECOFF_ULONG  entry;
+	ECOFF_ULONG  text_start;
+	ECOFF_ULONG  data_start;
+	ECOFF_ULONG  bss_start;
+	ECOFF_MACHDEP;
+};
+
+struct ecoff_scnhdr {		/* needed for size info */
+	char	s_name[8];	/* name */
+	ECOFF_ULONG  s_paddr;	/* physical addr? for ROMing?*/
+	ECOFF_ULONG  s_vaddr;	/* virtual addr? */
+	ECOFF_ULONG  s_size;	/* size */
+	ECOFF_ULONG  s_scnptr;	/* file offset of raw data */
+	ECOFF_ULONG  s_relptr;	/* file offset of reloc data */
+	ECOFF_ULONG  s_lnnoptr;	/* file offset of line data */
+	ECOFF_USHORT s_nreloc;	/* # of relocation entries */
+	ECOFF_USHORT s_nlnno;	/* # of line entries */
+	ECOFF_UINT   s_flags;	/* flags */
+};
+
+struct ecoff_exechdr {
+	struct ecoff_filehdr f;
+	struct ecoff_aouthdr a;
+};
+
+#define ECOFF_HDR_SIZE (sizeof(struct ecoff_exechdr))
+
+#define ECOFF_OMAGIC 0407
+#define ECOFF_NMAGIC 0410
+#define ECOFF_ZMAGIC 0413
+
+#define ECOFF_ROUND(value, by) \
+        (((value) + (by) - 1) & ~((by) - 1))
+
+#define ECOFF_BLOCK_ALIGN(ep, value) \
+        ((ep)->a.magic == ECOFF_ZMAGIC ? ECOFF_ROUND((value), ECOFF_LDPGSZ) : \
+	 (value))
+
+#define ECOFF_TXTOFF(ep) \
+        ((ep)->a.magic == ECOFF_ZMAGIC ? 0 : \
+	 ECOFF_ROUND(ECOFF_HDR_SIZE + (ep)->f.f_nscns * \
+		     sizeof(struct ecoff_scnhdr), ECOFF_SEGMENT_ALIGNMENT(ep)))
+
+#define ECOFF_DATOFF(ep) \
+        (ECOFF_BLOCK_ALIGN((ep), ECOFF_TXTOFF(ep) + (ep)->a.tsize))
+
+#define ECOFF_SEGMENT_ALIGN(ep, value) \
+        (ECOFF_ROUND((value), ((ep)->a.magic == ECOFF_ZMAGIC ? ECOFF_LDPGSZ : \
+         ECOFF_SEGMENT_ALIGNMENT(ep))))
+
+#ifdef _KERNEL
+int	exec_ecoff_makecmds __P((struct proc *, struct exec_package *));
+int	exec_ecoff_setup_stack __P((struct proc *, struct exec_package *));
+int	cpu_exec_ecoff_probe __P((struct proc *, struct exec_package *));
+void	cpu_exec_ecoff_setregs __P((struct proc *, struct exec_package *,
+	    u_long));
+
+int	exec_ecoff_prep_omagic __P((struct proc *, struct exec_package *,
+	    struct ecoff_exechdr *, struct vnode *));
+int	exec_ecoff_prep_nmagic __P((struct proc *, struct exec_package *,
+	    struct ecoff_exechdr *, struct vnode *));
+int	exec_ecoff_prep_zmagic __P((struct proc *, struct exec_package *,
+	    struct ecoff_exechdr *, struct vnode *));
+
+#endif /* _KERNEL */
+#endif /* !_SYS_EXEC_ECOFF_H_ */
Index: tools/mips-elf2ecoff/machine/ecoff_machdep.h
===================================================================
RCS file: /cvsroot/basesrc/tools/mips-elf2ecoff/machine/ecoff_machdep.h,v
retrieving revision 1.1
diff -u -r1.1 ecoff_machdep.h
--- ecoff_machdep.h	2002/02/23 21:32:28	1.1
+++ ecoff_machdep.h	2002/03/21 23:07:30
@@ -34,14 +34,18 @@
  * SUCH DAMAGE.
  */
 
+typedef u_int16_t	ECOFF_USHORT;
+typedef u_int32_t	ECOFF_UINT;
+typedef u_int32_t	ECOFF_ULONG;
+
 #define ECOFF_LDPGSZ 4096
 
 #define ECOFF_PAD
 
 #define ECOFF_MACHDEP \
-        u_long gprmask; \
-        u_long cprmask[4]; \
-        u_long gp_value
+        ECOFF_ULONG gprmask; \
+        ECOFF_ULONG cprmask[4]; \
+        ECOFF_ULONG gp_value
 #ifdef _KERNEL
 #include <mips/cpu.h>		/* mips CPU architecture levels */
 #define _MIPS3_OK() CPUISMIPS3
Index: usr.bin/elf2ecoff/elf2ecoff.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/elf2ecoff/elf2ecoff.c,v
retrieving revision 1.15
diff -u -r1.15 elf2ecoff.c
--- elf2ecoff.c	2002/03/19 09:29:04	1.15
+++ elf2ecoff.c	2002/03/21 23:07:30
@@ -101,8 +101,10 @@
     long strsize);
 
 void    pad16(int fd, int size, const char *msg);
+void	bswap32_region(u_int32_t* , int);
 
 int    *symTypeTable;
+int	needswap;
 
 
 
@@ -132,7 +134,9 @@
 	unsigned long cur_vma = ULONG_MAX;
 	int     symflag = 0;
 	int     nsecs = 0;
+	int	mipsel;
 
+
 	text.len = data.len = bss.len = 0;
 	text.vaddr = data.vaddr = bss.vaddr = 0;
 
@@ -164,15 +168,56 @@
 		    argv[1], i ? strerror(errno) : "End of file reached");
 		exit(1);
 	}
+	if (ex.e_ident[EI_DATA] == ELFDATA2LSB)
+		mipsel = 1;
+	else if (ex.e_ident[EI_DATA] == ELFDATA2MSB)
+		mipsel = 0;
+	else {
+		fprintf(stderr, "invalid ELF byte order %d\n",
+		    ex.e_ident[EI_DATA]);
+		exit(1);
+	}
+#if BYTE_ORDER == BIG_ENDIAN
+	if (mipsel)
+		needswap = 1;
+	else
+		needswap = 0;
+#elif BYTE_ORDER == LITTLE_ENDIAN
+	if (mipsel)
+		needswap = 0;
+	else
+		needswap = 1;
+#else
+#error "unknown endian"
+#endif
+
+	if (needswap) {
+		ex.e_type	= bswap16(ex.e_type);
+		ex.e_machine	= bswap16(ex.e_machine);
+		ex.e_version	= bswap32(ex.e_version);
+		ex.e_entry 	= bswap32(ex.e_entry);
+		ex.e_phoff	= bswap32(ex.e_phoff);
+		ex.e_shoff	= bswap32(ex.e_shoff);
+		ex.e_flags	= bswap32(ex.e_flags);
+		ex.e_ehsize	= bswap16(ex.e_ehsize);
+		ex.e_phentsize	= bswap16(ex.e_phentsize);
+		ex.e_phnum	= bswap16(ex.e_phnum);
+		ex.e_shentsize	= bswap16(ex.e_shentsize);
+		ex.e_shnum	= bswap16(ex.e_shnum);
+		ex.e_shstrndx	= bswap16(ex.e_shstrndx);
+	}
+
 	/* Read the program headers... */
 	ph = (Elf32_Phdr *) saveRead(infile, ex.e_phoff,
 	    ex.e_phnum * sizeof(Elf32_Phdr), "ph");
+	if (needswap)
+		bswap32_region((u_int32_t*)ph, sizeof(Elf32_Phdr) * ex.e_phnum);
 	/* Read the section headers... */
 	sh = (Elf32_Shdr *) saveRead(infile, ex.e_shoff,
 	    ex.e_shnum * sizeof(Elf32_Shdr), "sh");
-	/* Read in the section string table. */
-	shstrtab = saveRead(infile, sh[ex.e_shstrndx].sh_offset,
-	    sh[ex.e_shstrndx].sh_size, "shstrtab");
+	if (needswap) 
+		bswap32_region((u_int32_t*)sh, sizeof(Elf32_Shdr) * ex.e_shnum);
+
 	/* Read in the section string table. */
 	shstrtab = saveRead(infile, sh[ex.e_shstrndx].sh_offset,
 	    sh[ex.e_shstrndx].sh_size, "shstrtab");
@@ -288,15 +333,10 @@
 	memset(&ep.a.cprmask, 0, sizeof ep.a.cprmask);
 	ep.a.gp_value = 0;	/* unused. */
 
-	if (ex.e_ident[EI_DATA] == ELFDATA2LSB)
+	if (mipsel)
 		ep.f.f_magic = ECOFF_MAGIC_MIPSEL;
-	else if (ex.e_ident[EI_DATA] == ELFDATA2MSB)
+	else 
 		ep.f.f_magic = ECOFF_MAGIC_MIPSEB;
-	else {
-		fprintf(stderr, "invalid ELF byte order %d\n",
-		    ex.e_ident[EI_DATA]);
-		exit(1);
-	}
 
 	ep.f.f_nscns = 6;
 	ep.f.f_timdat = 0;	/* bogus */
@@ -313,6 +353,39 @@
 
 	nsecs = ep.f.f_nscns;
 
+	if (needswap) {
+		ep.f.f_magic	= bswap16(ep.f.f_magic);
+		ep.f.f_nscns	= bswap16(ep.f.f_nscns);
+		ep.f.f_timdat	= bswap32(ep.f.f_timdat);
+		ep.f.f_symptr	= bswap32(ep.f.f_symptr);
+		ep.f.f_nsyms	= bswap32(ep.f.f_nsyms);
+		ep.f.f_opthdr	= bswap16(ep.f.f_opthdr);
+		ep.f.f_flags	= bswap16(ep.f.f_flags);
+		ep.a.magic	= bswap16(ep.a.magic);
+		ep.a.vstamp	= bswap16(ep.a.vstamp);
+		ep.a.tsize	= bswap32(ep.a.tsize);
+		ep.a.dsize	= bswap32(ep.a.dsize);
+		ep.a.bsize	= bswap32(ep.a.bsize);
+		ep.a.entry	= bswap32(ep.a.entry);
+		ep.a.text_start	= bswap32(ep.a.text_start);
+		ep.a.data_start	= bswap32(ep.a.data_start);
+		ep.a.bss_start	= bswap32(ep.a.bss_start);
+		ep.a.gprmask	= bswap32(ep.a.gprmask);
+		bswap32_region((u_int32_t*)ep.a.cprmask, sizeof(ep.a.cprmask));
+		ep.a.gp_value	= bswap32(ep.a.gp_value);
+		for (i = 0; i < sizeof(esecs) / sizeof(esecs[0]); i++) {
+			esecs[i].s_paddr	= bswap32(esecs[i].s_paddr);
+			esecs[i].s_vaddr	= bswap32(esecs[i].s_vaddr);
+			esecs[i].s_size 	= bswap32(esecs[i].s_size);
+			esecs[i].s_scnptr	= bswap32(esecs[i].s_scnptr);
+			esecs[i].s_relptr	= bswap32(esecs[i].s_relptr);
+			esecs[i].s_lnnoptr	= bswap32(esecs[i].s_lnnoptr);
+			esecs[i].s_nreloc	= bswap16(esecs[i].s_nreloc);
+			esecs[i].s_nlnno	= bswap16(esecs[i].s_nlnno);
+			esecs[i].s_flags	= bswap32(esecs[i].s_flags);
+		}
+	}
+
 	/* Make the output file... */
 	if ((outfile = open(argv[2], O_WRONLY | O_CREAT, 0777)) < 0) {
 		fprintf(stderr, "Unable to create %s: %s\n", argv[2], strerror(errno));
@@ -590,6 +663,14 @@
 		    sizeof(*symhdrp), strsize,
 		    (nesyms * sizeof(struct ecoff_extsym)));
 
+	if (needswap) {
+		bswap32_region((u_int32_t*)&symhdrp->ilineMax,
+		    sizeof(*symhdrp) -  sizeof(symhdrp->magic) -
+		    sizeof(symhdrp->ilineMax));
+		symhdrp->magic = bswap16(symhdrp->magic);
+		symhdrp->ilineMax = bswap16(symhdrp->ilineMax);
+	}
+		
 	safewrite(out, symhdrp, sizeof(*symhdrp),
 	    "writing symbol header: %s\n");
 }
@@ -603,6 +684,7 @@
 	off_t   stroff, strsize;
 {
 	register int nsyms;
+	int i;
 	nsyms = symsize / sizeof(Elf32_Sym);
 
 	/* Suck in the ELF symbol list... */
@@ -610,6 +692,15 @@
 	    saveRead(in, symoff, nsyms * sizeof(Elf32_Sym),
 	    "ELF symboltable");
 	elfsymsp->nsymbols = nsyms;
+	if (needswap) {
+		for (i = 0; i < nsyms; i++) {
+			Elf32_Sym *s = &elfsymsp->elf_syms[i];
+			s->st_name	= bswap32(s->st_name);
+			s->st_value	= bswap32(s->st_value);
+			s->st_size	= bswap32(s->st_size);
+			s->st_shndx	= bswap16(s->st_shndx);
+		}
+	}
 
 	/* Suck in the ELF string table... */
 	elfsymsp->stringtab = (char *)
@@ -633,7 +724,7 @@
 	struct ecoff_syms ecoffsymtab;
 	register u_long ecoff_symhdr_off, symtaboff, stringtaboff;
 	register u_long nextoff, symtabsize, ecoff_strsize;
-	int     nsyms;
+	int     nsyms, i;
 	struct ecoff_symhdr symhdr;
 	int     padding;
 
@@ -672,6 +763,14 @@
 
 	/* Write out the symbol table... */
 	padding = symtabsize - (nsyms * sizeof(struct ecoff_extsym));
+
+	for (i = 0; i < nsyms; i++) {
+		struct ecoff_extsym *es = &ecoffsymtab.ecoff_syms[i];
+		es->es_flags	= bswap16(es->es_flags);
+		es->es_ifd	= bswap16(es->es_ifd);
+		bswap32_region(&es->es_strindex,
+		    sizeof(*es) - sizeof(es->es_flags) - sizeof(es->es_ifd));
+	}
 	safewrite(out, ecoffsymtab.ecoff_syms,
 	    nsyms * sizeof(struct ecoff_extsym),
 	    "symbol table: write: %s\n");
@@ -753,4 +852,14 @@
 pad16(int fd, int size, const char *msg)
 {
 	safewrite(fd, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", size, msg);
+}
+
+/* swap a 32bit region */
+void
+bswap32_region(u_int32_t* p, int len)
+{
+	int i;
+
+	for (i = 0; i < len / sizeof(u_int32_t); i++, p++)
+		*p = bswap32(*p);
 }

--zYM0uCDKw75PZbzx--