summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authorse <se@FreeBSD.org>1999-07-28 20:09:52 +0000
committerse <se@FreeBSD.org>1999-07-28 20:09:52 +0000
commitf5d4fad82d5d1a6ed83cfa416295422c9eb6707b (patch)
tree811f063a1b12f5e9bc8d9a80853c23bd807ddfa0 /usr.sbin
parent0adfd0204463db90782d5e7b23c0815f4ab45365 (diff)
parent7576b7e750de8c5aa91ace601e8b0b3e5fd621fc (diff)
downloadFreeBSD-src-f5d4fad82d5d1a6ed83cfa416295422c9eb6707b.zip
FreeBSD-src-f5d4fad82d5d1a6ed83cfa416295422c9eb6707b.tar.gz
This commit was generated by cvs2svn to compensate for changes in r49182,
which included commits to RCS files with non-trunk default branches.
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/elf2exe/Makefile9
-rw-r--r--usr.sbin/elf2exe/elf2exe.849
-rw-r--r--usr.sbin/elf2exe/elf2exe.c380
3 files changed, 438 insertions, 0 deletions
diff --git a/usr.sbin/elf2exe/Makefile b/usr.sbin/elf2exe/Makefile
new file mode 100644
index 0000000..e0f0f7a
--- /dev/null
+++ b/usr.sbin/elf2exe/Makefile
@@ -0,0 +1,9 @@
+# $Id$
+
+PROG= elf2exe
+SRCS= elf2exe.c
+MAN8= elf2exe.8
+
+MANSUBDIR=/${MACHINE_ARCH}
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/elf2exe/elf2exe.8 b/usr.sbin/elf2exe/elf2exe.8
new file mode 100644
index 0000000..731dc22
--- /dev/null
+++ b/usr.sbin/elf2exe/elf2exe.8
@@ -0,0 +1,49 @@
+.\" Copyright (c) 1999 Stefan Esser
+.\"
+.\" 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.
+.\"
+.\" $Id$
+.\"
+.Dd July 26, 1999
+.Dt ELF2EXE 8
+.Os FreeBSD 4.0
+.Sh NAME
+.Nm elf2exe
+.Nd convert Alpha ELF executable to AlphaBIOS / ARCS format
+.Sh SYNOPSIS
+.Nm elf2exe
+.Ar infile
+.Ar outfile
+.Sh DESCRIPTION
+.Nm Elf2exe
+creates an executable that can be loaded by the AlphaBIOS or ARCS consoles
+as found on systems designed for
+.Tn Windows/NT .
+The input file must have been
+created as a non-relocatable standalone binary with a load address within
+the memory range available for user programs (0x80000000 to 0x806fdfff
+and 0x80900000 to at least 0x80ffffff).
+.Pp
+The command prints a list of sections found in the ELF executable and the
+section sizes and offsets of the output file for diagnostic purposes.
+.Pp
+Given an object file
+.B src.o
+the follwoing two commands will create a binary for ARCS:
+.Dl ld \-o a.out \-M \-N \-Ttext 0x80900000 src.o\c
+.Dl elf2exe a.out a.exe\c
+.Sh BUGS
+.Nm Elf2exe
+does not even attempt to verify that the input file matches the requirements
+for an ARC executable.
+.Sh HISTORY
+The
+.Nm
+command appeared in FreeBSD 4.0.
diff --git a/usr.sbin/elf2exe/elf2exe.c b/usr.sbin/elf2exe/elf2exe.c
new file mode 100644
index 0000000..92919ed
--- /dev/null
+++ b/usr.sbin/elf2exe/elf2exe.c
@@ -0,0 +1,380 @@
+/*-
+ * Copyright (c) 1999 Stefan Esser
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+ *
+ * $Id$
+ */
+
+/*
+ * Make an ARC firmware executable from an ELF file.
+ */
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <elf.h>
+
+#define ALPHA_FMAGIC 0x184
+
+#define TOTHSZ 0x200
+
+typedef struct filehdr {
+ u_int16_t f_magic;
+ u_int16_t f_nscns;
+ u_int32_t f_timdat;
+ u_int32_t f_symptr;
+ u_int32_t f_nsyms;
+ u_int16_t f_opthdr;
+ u_int16_t f_flags;
+} FILHDR;
+#define FILHSZ 20
+
+#define ALPHA_AMAGIC 0407
+
+typedef struct aouthdr {
+ u_int16_t a_magic;
+ u_int16_t a_vstamp;
+ u_int32_t a_tsize;
+ u_int32_t a_dsize;
+ u_int32_t a_bsize;
+ u_int32_t a_entry;
+ u_int32_t a_text_start;
+ u_int32_t a_data_start;
+ u_int32_t a_bss_start;
+ u_int32_t a_gprmask;
+ u_int32_t a_cprmask[4];
+ u_int32_t a_gp_value;
+} AOUTHDR;
+#define AOUTSZ 56
+
+typedef struct scnhdr {
+ char s_name[8];
+ u_int32_t s_fill;
+ u_int32_t s_vaddr;
+ u_int32_t s_size;
+ u_int32_t s_scnptr;
+ u_int32_t s_relptr;
+ u_int32_t s_lnnoptr;
+ u_int16_t s_nreloc;
+ u_int16_t s_nlnno;
+ u_int32_t s_flags;
+} SCNHDR;
+#define SCNHSZ 40
+
+#define ROUNDUP(a,b) ((((a) -1) | ((b) -1)) +1)
+
+/*
+ * initialization subroutines
+ */
+
+int
+open_elffile(char *filename)
+{
+ int fileno = open(filename, O_RDONLY);
+ if (fileno < 0)
+ err(1, filename);
+ return (fileno);
+}
+
+
+Elf64_Ehdr *
+load_ehdr(int fileno)
+{
+ Elf64_Ehdr *ehdr;
+ int bytes = sizeof(*ehdr);
+ ehdr = malloc(bytes);
+ if (ehdr) {
+ lseek(fileno, 0, SEEK_SET);
+ if (read(fileno, ehdr, bytes) != bytes)
+ errx(1, "file truncated (ehdr)");
+ }
+ return (ehdr);
+}
+
+Elf64_Phdr *
+load_phdr(int fileno, Elf64_Ehdr *ehdr)
+{
+ int bytes = ehdr->e_phentsize * ehdr->e_phnum;
+ Elf64_Phdr *phdr = malloc(bytes);
+ if (phdr) {
+ lseek(fileno, ehdr->e_phoff, SEEK_SET);
+ if (read(fileno, phdr, bytes) != bytes)
+ errx(1, "file truncated (phdr)");
+ }
+ return (phdr);
+}
+
+Elf64_Shdr *
+load_shdr(int fileno, Elf64_Ehdr *ehdr)
+{
+ int bytes = ehdr->e_shentsize * ehdr->e_shnum;
+
+ Elf64_Shdr *shdr = malloc(bytes);
+ if (shdr) {
+ lseek(fileno, ehdr->e_shoff, SEEK_SET);
+ if (read(fileno, shdr, bytes) != bytes)
+ errx(1, "file truncated (shdr)");
+ }
+ return (shdr);
+}
+
+char *
+find_shstrtable(int fileno, int sections, Elf64_Shdr *shdr)
+{
+ char *shstrtab = NULL;
+ int i;
+ int shstrtabindex;
+ for (i = 0; shstrtab == NULL && i < sections; i++) {
+ if (shdr[i].sh_type == 3 && shdr[i].sh_flags == 0) {
+ shstrtabindex = i;
+
+ shstrtab = malloc(shdr[shstrtabindex].sh_size);
+ lseek(fileno, shdr[shstrtabindex].sh_offset, SEEK_SET);
+ read(fileno, shstrtab, shdr[shstrtabindex].sh_size);
+
+ if (strcmp (shstrtab + shdr[i].sh_name, ".shstrtab")) {
+ free(shstrtab);
+ shstrtab = NULL;
+ }
+ }
+ }
+ return shstrtab;
+}
+
+int
+open_exefile(char *filename)
+{
+ int fileno = open(filename, O_RDWR | O_TRUNC | O_CREAT, 0666);
+ if (fileno < 0)
+ err(1, filename);
+ return (fileno);
+}
+
+/*
+ * utility subroutines
+ */
+
+static char *shstrtab;
+
+char *
+section_name(Elf64_Shdr *shdr, int i)
+{
+ return (shstrtab + shdr[i].sh_name);
+}
+
+long
+section_index(Elf64_Shdr *shdr, int sections, char *name)
+{
+ int i;
+
+ for (i = 0; i < sections; i++)
+ if (strcmp (name, section_name(shdr, i)) == 0)
+ return (i);
+
+ return -1;
+}
+
+/* first byte of section */
+long
+section_start(Elf64_Shdr *shdr, int sections, char *name)
+{
+ int i = section_index(shdr, sections, name);
+ if (i < 0)
+ return -1;
+
+ return shdr[i].sh_addr;
+}
+
+/* last byte of section */
+long
+section_end(Elf64_Shdr *shdr, int sections, char *name)
+{
+ int i = section_index(shdr, sections, name);
+ if (i < 0)
+ return -1;
+
+ return shdr[i].sh_addr + shdr[i].sh_size -1;
+}
+
+/* last byte of section */
+long
+section_size(Elf64_Shdr *shdr, int sections, char *name)
+{
+ int i = section_index(shdr, sections, name);
+ if (i < 0)
+ return -1;
+
+ return shdr[i].sh_size;
+}
+
+/* file position of section start */
+long
+section_fpos(Elf64_Shdr *shdr, int sections, char *name)
+{
+ int i = section_index(shdr, sections, name);
+ if (i < 0)
+ return -1;
+
+ return shdr[i].sh_offset;
+}
+
+int
+main(int argc, char** argv)
+{
+ int infd, outfd, i;
+ Elf64_Ehdr *ehdr;
+ Elf64_Phdr *phdr;
+ Elf64_Shdr *shdr;
+ int shstrtabindex;
+ FILHDR filehdr;
+ AOUTHDR aouthdr;
+ SCNHDR textscn, datascn;
+ long textstart, textsize, textsize2, textfsize, textfpos;
+ long datastart, datasize, datafsize, datafpos;
+ long bssstart, bsssize;
+ long progentry;
+ char* p;
+ int sections;
+
+ if (argc != 3)
+ errx(1, "usage: elf2exe <infile> <outfile>");
+
+ infd = open_elffile(argv[1]);
+ ehdr = load_ehdr(infd);
+
+ if (ehdr == NULL)
+ errx(1, "canīt read Elf Header\n");
+
+ sections = ehdr->e_shnum;
+ progentry = ehdr->e_entry;
+
+ phdr = load_phdr(infd, ehdr);
+ shdr = load_shdr(infd, ehdr);
+ outfd = open_exefile(argv[2]);
+
+ shstrtab = find_shstrtable(infd, sections, shdr);
+
+ for (i = 1; i < sections; i++) {
+ printf("section %d (%s): "
+ "type=%x flags=0%x "
+ "offs=%x size=%x addr=%x\n",
+ i, shstrtab + shdr[i].sh_name,
+ shdr[i].sh_type, shdr[i].sh_flags,
+ shdr[i].sh_offset, shdr[i].sh_size, shdr[i].sh_addr);
+ }
+
+ textstart = section_start(shdr, sections, ".text");
+ textsize = section_size(shdr, sections, ".text");
+ textsize2 = section_end(shdr, sections, ".rodata") - textstart +1;
+ if (textsize < textsize2)
+ textsize = textsize2;
+ textfsize = ROUNDUP(textsize, 512);
+ textfpos = section_fpos(shdr, sections, ".text");
+
+ datastart = section_start(shdr, sections, ".data");
+ datasize = section_start(shdr, sections, ".bss") - datastart;
+ datafsize = ROUNDUP(datasize, 512);
+ datafpos = section_fpos(shdr, sections, ".data");
+
+ bssstart = section_start(shdr, sections, ".bss");
+ bsssize = section_size(shdr, sections, ".bss");
+
+ printf ("text: %x(%x) @%x data: %x(%x) @%x bss: %x(%x)\n",
+ textstart, textsize, textfpos,
+ datastart, datasize, datafpos,
+ bssstart, bsssize);
+
+ memset(&filehdr, 0, sizeof filehdr);
+ memset(&aouthdr, 0, sizeof aouthdr);
+ memset(&textscn, 0, sizeof textscn);
+ memset(&datascn, 0, sizeof datascn);
+
+ filehdr.f_magic = ALPHA_FMAGIC;
+ filehdr.f_nscns = 2;
+ filehdr.f_timdat = time(0);
+ filehdr.f_symptr = 0;
+ filehdr.f_nsyms = 0;
+ filehdr.f_opthdr = AOUTSZ;
+ filehdr.f_flags = 0x010f;
+
+ aouthdr.a_magic = ALPHA_AMAGIC;
+ aouthdr.a_vstamp = 0x5004;
+ aouthdr.a_tsize = textfsize;
+ aouthdr.a_dsize = datafsize;
+ aouthdr.a_bsize = bsssize;
+ aouthdr.a_entry = progentry;
+ aouthdr.a_text_start = textstart;
+ aouthdr.a_data_start = datastart;
+ aouthdr.a_bss_start = bssstart;
+
+ strcpy(textscn.s_name, ".text");
+ textscn.s_fill = textsize;
+ textscn.s_vaddr = textstart;
+ textscn.s_size = textfsize;
+ textscn.s_scnptr = 0x200;
+ textscn.s_relptr = 0;
+ textscn.s_lnnoptr = 0;
+ textscn.s_nreloc = 0;
+ textscn.s_nlnno = 0;
+ textscn.s_flags = 0x20;
+
+ strcpy(datascn.s_name, ".data");
+ datascn.s_fill = datasize;
+ datascn.s_vaddr = datastart;
+ datascn.s_size = datafsize;
+ datascn.s_scnptr = 0x200 + textfsize;
+ datascn.s_relptr = 0;
+ datascn.s_lnnoptr = 0;
+ datascn.s_nreloc = 0;
+ datascn.s_nlnno = 0;
+ datascn.s_flags = 0x40;
+
+ write(outfd, &filehdr, FILHSZ);
+ write(outfd, &aouthdr, AOUTSZ);
+ write(outfd, &textscn, SCNHSZ);
+ write(outfd, &datascn, SCNHSZ);
+
+ lseek(outfd, textscn.s_scnptr, SEEK_SET);
+ p = malloc(ROUNDUP(textsize, 512));
+ memset(p, 0, ROUNDUP(textsize, 512));
+ lseek(infd, textfpos, SEEK_SET);
+ read(infd, p, textsize);
+ write(outfd, p, ROUNDUP(textsize, 512));
+ free(p);
+
+ lseek(outfd, datascn.s_scnptr, SEEK_SET);
+ p = malloc(ROUNDUP(datasize, 512));
+ memset(p, 0, ROUNDUP(datasize, 512));
+ lseek(infd, datafpos, SEEK_SET);
+ read(infd, p, datasize);
+ write(outfd, p, ROUNDUP(datasize, 512));
+ free(p);
+
+ return 0;
+}
+
OpenPOWER on IntegriCloud