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-pmax
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--