📄 elf2ecoff.c
字号:
/* * Copyright (c) 1995 * Ted Lemon (hereinafter referred to as the author) * * 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. 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. *//* elf2ecoff.c This program converts an elf executable to an ECOFF executable. No symbol table is retained. This is useful primarily in building net-bootable kernels for machines (e.g., DECstation and Alpha) which only support the ECOFF object file format. */#include <stdio.h>#include <string.h>#include <errno.h>#include <sys/types.h>#include <fcntl.h>#include <unistd.h>#include <elf.h>#include <limits.h>#include <netinet/in.h>#include <stdlib.h>#include "ecoff.h"/* * Some extra ELF definitions */#define PT_MIPS_REGINFO 0x70000000 /* Register usage information *//* -------------------------------------------------------------------- */struct sect { unsigned long vaddr; unsigned long len;};int *symTypeTable;int must_convert_endian = 0;int format_bigendian = 0;static void copy(int out, int in, off_t offset, off_t size){ char ibuf[4096]; int remaining, cur, count; /* Go to the start of the ELF symbol table... */ if (lseek(in, offset, SEEK_SET) < 0) { perror("copy: lseek"); exit(1); } remaining = size; while (remaining) { cur = remaining; if (cur > sizeof(ibuf)) cur = sizeof(ibuf); remaining -= cur; if ((count = read(in, ibuf, cur)) != cur) { fprintf(stderr, "copy: read: %s\n", count ? strerror(errno) : "premature end of file"); exit(1); } if ((count = write(out, ibuf, cur)) != cur) { perror("copy: write"); exit(1); } }}/* * Combine two segments, which must be contiguous. If pad is true, it's * okay for there to be padding between. */static void combine(struct sect *base, struct sect *new, int pad){ if (!base->len) *base = *new; else if (new->len) { if (base->vaddr + base->len != new->vaddr) { if (pad) base->len = new->vaddr - base->vaddr; else { fprintf(stderr, "Non-contiguous data can't be converted.\n"); exit(1); } } base->len += new->len; }}static int phcmp(const void *v1, const void *v2){ const Elf32_Phdr *h1 = v1; const Elf32_Phdr *h2 = v2; if (h1->p_vaddr > h2->p_vaddr) return 1; else if (h1->p_vaddr < h2->p_vaddr) return -1; else return 0;}static char *saveRead(int file, off_t offset, off_t len, char *name){ char *tmp; int count; off_t off; if ((off = lseek(file, offset, SEEK_SET)) < 0) { fprintf(stderr, "%s: fseek: %s\n", name, strerror(errno)); exit(1); } if (!(tmp = (char *) malloc(len))) { fprintf(stderr, "%s: Can't allocate %ld bytes.\n", name, len); exit(1); } count = read(file, tmp, len); if (count != len) { fprintf(stderr, "%s: read: %s.\n", name, count ? strerror(errno) : "End of file reached"); exit(1); } return tmp;}#define swab16(x) \ ((unsigned short)( \ (((unsigned short)(x) & (unsigned short)0x00ffU) << 8) | \ (((unsigned short)(x) & (unsigned short)0xff00U) >> 8) ))#define swab32(x) \ ((unsigned int)( \ (((unsigned int)(x) & (unsigned int)0x000000ffUL) << 24) | \ (((unsigned int)(x) & (unsigned int)0x0000ff00UL) << 8) | \ (((unsigned int)(x) & (unsigned int)0x00ff0000UL) >> 8) | \ (((unsigned int)(x) & (unsigned int)0xff000000UL) >> 24) ))static void convert_elf_hdr(Elf32_Ehdr * e){ e->e_type = swab16(e->e_type); e->e_machine = swab16(e->e_machine); e->e_version = swab32(e->e_version); e->e_entry = swab32(e->e_entry); e->e_phoff = swab32(e->e_phoff); e->e_shoff = swab32(e->e_shoff); e->e_flags = swab32(e->e_flags); e->e_ehsize = swab16(e->e_ehsize); e->e_phentsize = swab16(e->e_phentsize); e->e_phnum = swab16(e->e_phnum); e->e_shentsize = swab16(e->e_shentsize); e->e_shnum = swab16(e->e_shnum); e->e_shstrndx = swab16(e->e_shstrndx);}static void convert_elf_phdrs(Elf32_Phdr * p, int num){ int i; for (i = 0; i < num; i++, p++) { p->p_type = swab32(p->p_type); p->p_offset = swab32(p->p_offset); p->p_vaddr = swab32(p->p_vaddr); p->p_paddr = swab32(p->p_paddr); p->p_filesz = swab32(p->p_filesz); p->p_memsz = swab32(p->p_memsz); p->p_flags = swab32(p->p_flags); p->p_align = swab32(p->p_align); }}static void convert_elf_shdrs(Elf32_Shdr * s, int num){ int i; for (i = 0; i < num; i++, s++) { s->sh_name = swab32(s->sh_name); s->sh_type = swab32(s->sh_type); s->sh_flags = swab32(s->sh_flags); s->sh_addr = swab32(s->sh_addr); s->sh_offset = swab32(s->sh_offset); s->sh_size = swab32(s->sh_size); s->sh_link = swab32(s->sh_link); s->sh_info = swab32(s->sh_info); s->sh_addralign = swab32(s->sh_addralign); s->sh_entsize = swab32(s->sh_entsize); }}static void convert_ecoff_filehdr(struct filehdr *f){ f->f_magic = swab16(f->f_magic); f->f_nscns = swab16(f->f_nscns); f->f_timdat = swab32(f->f_timdat); f->f_symptr = swab32(f->f_symptr); f->f_nsyms = swab32(f->f_nsyms); f->f_opthdr = swab16(f->f_opthdr); f->f_flags = swab16(f->f_flags);}static void convert_ecoff_aouthdr(struct aouthdr *a){ a->magic = swab16(a->magic); a->vstamp = swab16(a->vstamp); a->tsize = swab32(a->tsize); a->dsize = swab32(a->dsize); a->bsize = swab32(a->bsize); a->entry = swab32(a->entry); a->text_start = swab32(a->text_start); a->data_start = swab32(a->data_start); a->bss_start = swab32(a->bss_start); a->gprmask = swab32(a->gprmask); a->cprmask[0] = swab32(a->cprmask[0]); a->cprmask[1] = swab32(a->cprmask[1]); a->cprmask[2] = swab32(a->cprmask[2]); a->cprmask[3] = swab32(a->cprmask[3]); a->gp_value = swab32(a->gp_value);}static void convert_ecoff_esecs(struct scnhdr *s, int num){ int i; for (i = 0; i < num; i++, s++) { s->s_paddr = swab32(s->s_paddr); s->s_vaddr = swab32(s->s_vaddr); s->s_size = swab32(s->s_size); s->s_scnptr = swab32(s->s_scnptr); s->s_relptr = swab32(s->s_relptr); s->s_lnnoptr = swab32(s->s_lnnoptr); s->s_nreloc = swab16(s->s_nreloc); s->s_nlnno = swab16(s->s_nlnno); s->s_flags = swab32(s->s_flags); }}int main(int argc, char *argv[]){ Elf32_Ehdr ex; Elf32_Phdr *ph; Elf32_Shdr *sh; char *shstrtab; int i, pad; struct sect text, data, bss; struct filehdr efh; struct aouthdr eah; struct scnhdr esecs[6]; int infile, outfile; unsigned long cur_vma = ULONG_MAX; int addflag = 0; int nosecs; text.len = data.len = bss.len = 0; text.vaddr = data.vaddr = bss.vaddr = 0; /* Check args... */ if (argc < 3 || argc > 4) { usage: fprintf(stderr, "usage: elf2aout <elf executable> <a.out executable> [-a]\n"); exit(1); } if (argc == 4) { if (strcmp(argv[3], "-a")) goto usage; addflag = 1; } /* Try the input file... */ if ((infile = open(argv[1], O_RDONLY)) < 0) { fprintf(stderr, "Can't open %s for read: %s\n", argv[1], strerror(errno)); exit(1); } /* Read the header, which is at the beginning of the file... */ i = read(infile, &ex, sizeof(ex)); if (i != sizeof(ex)) { fprintf(stderr, "ex: %s: %s.\n", argv[1],
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -