summaryrefslogtreecommitdiff
path: root/usr.bin/elf2aout/elf2aout.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/elf2aout/elf2aout.c')
-rw-r--r--usr.bin/elf2aout/elf2aout.c842
1 files changed, 412 insertions, 430 deletions
diff --git a/usr.bin/elf2aout/elf2aout.c b/usr.bin/elf2aout/elf2aout.c
index a155a3b2202..a784735d721 100644
--- a/usr.bin/elf2aout/elf2aout.c
+++ b/usr.bin/elf2aout/elf2aout.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: elf2aout.c,v 1.2 2001/01/29 01:57:56 niklas Exp $ */
+/* $OpenBSD: elf2aout.c,v 1.3 2003/06/10 22:20:46 deraadt Exp $ */
/*
* Copyright (c) 1995
@@ -41,476 +41,458 @@
#define SHN_MIPS_ACOMMON 0xfff0
-extern char *__progname;
+extern char *__progname;
struct sect {
- unsigned long vaddr;
- unsigned long len;
+ unsigned long vaddr;
+ unsigned long len;
};
-int phcmp ();
-char *saveRead (int file, off_t offset, off_t len, char *name);
-int copy (int, int, off_t, off_t);
-int translate_syms (int, int, off_t, off_t, off_t, off_t);
-extern int errno;
-int *symTypeTable;
+int phcmp();
+char *saveRead(int file, off_t offset, off_t len, char *name);
+int copy(int, int, off_t, off_t);
+int translate_syms(int, int, off_t, off_t, off_t, off_t);
+extern int errno;
+int *symTypeTable;
/* Symbol table entry... */
struct sym {
- unsigned long name; /* Index into strtab of symbol name. */
- unsigned long value; /* Section offset, virt addr or common align. */
- unsigned long size; /* Size of object referenced. */
- unsigned type : 4; /* Symbol type (e.g., function, data)... */
- unsigned binding : 4; /* Symbol binding (e.g., global, local)... */
- unsigned char other; /* Unused. */
- unsigned short shndx; /* Section containing symbol. */
+ unsigned long name; /* Index into strtab of symbol name. */
+ unsigned long value; /* Section offset, virt addr or common align. */
+ unsigned long size; /* Size of object referenced. */
+ unsigned type:4; /* Symbol type (e.g., function, data)... */
+ unsigned binding:4; /* Symbol binding (e.g., global,
+ * local)... */
+ unsigned char other; /* Unused. */
+ unsigned short shndx; /* Section containing symbol. */
};
struct phdr {
- unsigned long type; /* Segment type... */
- unsigned long offset; /* File offset... */
- unsigned long vaddr; /* Virtual address... */
- unsigned long paddr; /* Physical address... */
- unsigned long filesz; /* Size of segment in file... */
- unsigned long memsz; /* Size of segment in memory... */
- unsigned long flags; /* Segment flags... */
- unsigned long align; /* Alighment, file and memory... */
+ unsigned long type; /* Segment type... */
+ unsigned long offset; /* File offset... */
+ unsigned long vaddr; /* Virtual address... */
+ unsigned long paddr; /* Physical address... */
+ unsigned long filesz; /* Size of segment in file... */
+ unsigned long memsz; /* Size of segment in memory... */
+ unsigned long flags; /* Segment flags... */
+ unsigned long align; /* Alighment, file and memory... */
};
-main (int argc, char **argv, char **envp)
+int
+main(int argc, char *argv[])
{
- Elf32_Ehdr ex;
- Elf32_Phdr *ph;
- Elf32_Shdr *sh;
- struct sym *symtab;
- char *shstrtab;
- int strtabix, symtabix;
- int i;
- struct sect text, data, bss;
- struct exec aex;
- int infile, outfile;
- unsigned long cur_vma = ULONG_MAX;
- int symflag = 0;
-
- 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: %s <elf executable> <a.out executable>\n", __progname);
- exit (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], i ? strerror (errno) : "End of file reached");
- exit (1);
- }
-
- /* Read the program headers... */
- ph = (Elf32_Phdr *)saveRead (infile, ex.e_phoff,
- ex.e_phnum * sizeof (Elf32_Phdr), "ph");
- /* 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");
-
- /* Find space for a table matching ELF section indices to a.out symbol
- types. */
- symTypeTable = (int *)malloc (ex.e_shnum * sizeof (int));
- if (!symTypeTable)
- {
- fprintf (stderr, "symTypeTable: can't allocate.\n");
- exit (1);
- }
- memset (symTypeTable, 0, ex.e_shnum * sizeof (int));
-
- /* Look for the symbol table and string table...
- Also map section indices to symbol types for a.out */
- for (i = 0; i < ex.e_shnum; i++)
- {
- char *name = shstrtab + sh [i].sh_name;
- if (!strcmp (name, ".symtab"))
- symtabix = i;
- else if (!strcmp (name, ".strtab"))
- strtabix = i;
- else if (!strcmp (name, ".text") || !strcmp (name, ".rodata"))
- symTypeTable [i] = N_TEXT;
- else if (!strcmp (name, ".data") || !strcmp (name, ".sdata") ||
- !strcmp (name, ".lit4") || !strcmp (name, ".lit8"))
- symTypeTable [i] = N_DATA;
- else if (!strcmp (name, ".bss") || !strcmp (name, ".sbss"))
- symTypeTable [i] = N_BSS;
- }
-
- /* Figure out if we can cram the program header into an a.out header...
- Basically, we can't handle anything but loadable segments, but we
- can ignore some kinds of segments. We can't handle holes in the
- address space, and we handle start addresses other than 0x1000 by
- hoping that the loader will know where to load - a.out doesn't have
- an explicit load address. Segments may be out of order, so we
- sort them first. */
- qsort (ph, ex.e_phnum, sizeof (Elf32_Phdr), phcmp);
- for (i = 0; i < ex.e_phnum; i++)
- {
- /* Section types we can ignore... */
- if (ph [i].p_type == PT_NULL || ph [i].p_type == PT_NOTE ||
- ph [i].p_type == PT_PHDR || ph [i].p_type == PT_MIPS_REGINFO)
- continue;
- /* Section types we can't handle... */
- else if (ph [i].p_type != PT_LOAD)
- {
- fprintf (stderr, "Program header %d type %d can't be converted.\n");
- exit (1);
+ Elf32_Ehdr ex;
+ Elf32_Phdr *ph;
+ Elf32_Shdr *sh;
+ struct sym *symtab;
+ char *shstrtab;
+ int strtabix, symtabix;
+ int i;
+ struct sect text, data, bss;
+ struct exec aex;
+ int infile, outfile;
+ unsigned long cur_vma = ULONG_MAX;
+ int symflag = 0;
+
+ 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: %s elf a.out\n", __progname);
+ exit(1);
}
- /* Writable (data) segment? */
- if (ph [i].p_flags & PF_W)
- {
- struct sect ndata, nbss;
-
- ndata.vaddr = ph [i].p_vaddr;
- ndata.len = ph [i].p_filesz;
- nbss.vaddr = ph [i].p_vaddr + ph [i].p_filesz;
- nbss.len = ph [i].p_memsz - ph [i].p_filesz;
-
- combine (&data, &ndata, 0);
- combine (&bss, &nbss, 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], i ? strerror(errno) : "End of file reached");
+ exit(1);
+ }
+ /* Read the program headers... */
+ ph = (Elf32_Phdr *) saveRead(infile, ex.e_phoff,
+ ex.e_phnum * sizeof(Elf32_Phdr), "ph");
+ /* 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");
+
+ /*
+ * Find space for a table matching ELF section indices to a.out
+ * symbol types.
+ */
+ symTypeTable = (int *) malloc(ex.e_shnum * sizeof(int));
+ if (!symTypeTable) {
+ fprintf(stderr, "symTypeTable: can't allocate.\n");
+ exit(1);
+ }
+ memset(symTypeTable, 0, ex.e_shnum * sizeof(int));
+
+ /*
+ * Look for the symbol table and string table... Also map section
+ * indices to symbol types for a.out
+ */
+ for (i = 0; i < ex.e_shnum; i++) {
+ char *name = shstrtab + sh[i].sh_name;
+ if (!strcmp(name, ".symtab"))
+ symtabix = i;
+ else if (!strcmp(name, ".strtab"))
+ strtabix = i;
+ else if (!strcmp(name, ".text") || !strcmp(name, ".rodata"))
+ symTypeTable[i] = N_TEXT;
+ else if (!strcmp(name, ".data") || !strcmp(name, ".sdata") ||
+ !strcmp(name, ".lit4") || !strcmp(name, ".lit8"))
+ symTypeTable[i] = N_DATA;
+ else if (!strcmp(name, ".bss") || !strcmp(name, ".sbss"))
+ symTypeTable[i] = N_BSS;
}
- else
- {
- struct sect ntxt;
- ntxt.vaddr = ph [i].p_vaddr;
- ntxt.len = ph [i].p_filesz;
+ /*
+ * Figure out if we can cram the program header into an a.out
+ * header... Basically, we can't handle anything but loadable
+ * segments, but we can ignore some kinds of segments. We can't
+ * handle holes in the address space, and we handle start addresses
+ * other than 0x1000 by hoping that the loader will know where to
+ * load - a.out doesn't have an explicit load address. Segments may
+ * be out of order, so we sort them first.
+ */
+ qsort(ph, ex.e_phnum, sizeof(Elf32_Phdr), phcmp);
+ for (i = 0; i < ex.e_phnum; i++) {
+ /* Section types we can ignore... */
+ if (ph[i].p_type == PT_NULL || ph[i].p_type == PT_NOTE ||
+ ph[i].p_type == PT_PHDR || ph[i].p_type == PT_MIPS_REGINFO)
+ continue;
+ /* Section types we can't handle... */
+ else if (ph[i].p_type != PT_LOAD) {
+ fprintf(stderr,
+ "Program header %d type %d can't be converted.\n");
+ exit(1);
+ }
+ /* Writable (data) segment? */
+ if (ph[i].p_flags & PF_W) {
+ struct sect ndata, nbss;
- combine (&text, &ntxt);
- }
- /* Remember the lowest segment start address. */
- if (ph [i].p_vaddr < cur_vma)
- cur_vma = ph [i].p_vaddr;
- }
-
- /* Sections must be in order to be converted... */
- if (text.vaddr > data.vaddr || data.vaddr > bss.vaddr ||
- text.vaddr + text.len > data.vaddr || data.vaddr + data.len > bss.vaddr)
- {
- fprintf (stderr, "Sections ordering prevents a.out conversion.\n");
- exit (1);
- }
-
- /* If there's a data section but no text section, then the loader
- combined everything into one section. That needs to be the
- text section, so just make the data section zero length following
- text. */
- if (data.len && !text.len)
- {
- text = data;
- data.vaddr = text.vaddr + text.len;
- data.len = 0;
- }
-
- /* If there is a gap between text and data, we'll fill it when we copy
- the data, so update the length of the text segment as represented in
- a.out to reflect that, since a.out doesn't allow gaps in the program
- address space. */
- if (text.vaddr + text.len < data.vaddr)
- text.len = data.vaddr - text.vaddr;
-
- /* We now have enough information to cons up an a.out header... */
- aex.a_midmag = htonl ((symflag << 26) | (MID_PMAX << 16) | OMAGIC);
- aex.a_text = text.len;
- aex.a_data = data.len;
- aex.a_bss = bss.len;
- aex.a_entry = ex.e_entry;
- aex.a_syms = (sizeof (struct nlist) *
- (symtabix != -1
- ? sh [symtabix].sh_size / sizeof (struct sym) : 0));
- aex.a_trsize = 0;
- aex.a_drsize = 0;
-
- /* 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));
- exit (1);
- }
- /* Write the header... */
- i = write (outfile, &aex, sizeof aex);
- if (i != sizeof aex)
- {
- perror ("aex: write");
- exit (1);
- }
-
- /* Copy the loadable sections. Zero-fill any gaps less than 64k;
- complain about any zero-filling, and die if we're asked to zero-fill
- more than 64k. */
- for (i = 0; i < ex.e_phnum; i++)
- {
- /* Unprocessable sections were handled above, so just verify that
- the section can be loaded before copying. */
- if (ph [i].p_type == PT_LOAD && ph [i].p_filesz)
- {
- if (cur_vma != ph [i].p_vaddr)
- {
- unsigned long gap = ph [i].p_vaddr - cur_vma;
- char obuf [1024];
- if (gap > 65536)
- {
- fprintf (stderr, "Intersegment gap (%d bytes) too large.\n",
- gap);
- exit (1);
+ ndata.vaddr = ph[i].p_vaddr;
+ ndata.len = ph[i].p_filesz;
+ nbss.vaddr = ph[i].p_vaddr + ph[i].p_filesz;
+ nbss.len = ph[i].p_memsz - ph[i].p_filesz;
+
+ combine(&data, &ndata, 0);
+ combine(&bss, &nbss, 1);
+ } else {
+ struct sect ntxt;
+
+ ntxt.vaddr = ph[i].p_vaddr;
+ ntxt.len = ph[i].p_filesz;
+
+ combine(&text, &ntxt);
}
- fprintf (stderr, "Warning: %d byte intersegment gap.\n", gap);
- memset (obuf, 0, sizeof obuf);
- while (gap)
- {
- int count = write (outfile, obuf, (gap > sizeof obuf
- ? sizeof obuf : gap));
- if (count < 0)
- {
- fprintf (stderr, "Error writing gap: %s\n",
- strerror (errno));
- exit (1);
- }
- gap -= count;
+ /* Remember the lowest segment start address. */
+ if (ph[i].p_vaddr < cur_vma)
+ cur_vma = ph[i].p_vaddr;
+ }
+
+ /* Sections must be in order to be converted... */
+ if (text.vaddr > data.vaddr || data.vaddr > bss.vaddr ||
+ text.vaddr + text.len > data.vaddr || data.vaddr + data.len > bss.vaddr) {
+ fprintf(stderr, "Sections ordering prevents a.out conversion.\n");
+ exit(1);
+ }
+ /*
+ * If there's a data section but no text section, then the loader
+ * combined everything into one section. That needs to be the text
+ * section, so just make the data section zero length following text.
+ */
+ if (data.len && !text.len) {
+ text = data;
+ data.vaddr = text.vaddr + text.len;
+ data.len = 0;
+ }
+ /*
+ * If there is a gap between text and data, we'll fill it when we
+ * copy the data, so update the length of the text segment as
+ * represented in a.out to reflect that, since a.out doesn't allow
+ * gaps in the program address space.
+ */
+ if (text.vaddr + text.len < data.vaddr)
+ text.len = data.vaddr - text.vaddr;
+
+ /* We now have enough information to cons up an a.out header... */
+ aex.a_midmag = htonl((symflag << 26) | (MID_PMAX << 16) | OMAGIC);
+ aex.a_text = text.len;
+ aex.a_data = data.len;
+ aex.a_bss = bss.len;
+ aex.a_entry = ex.e_entry;
+ aex.a_syms = (sizeof(struct nlist) *
+ (symtabix != -1
+ ? sh[symtabix].sh_size / sizeof(struct sym) : 0));
+ aex.a_trsize = 0;
+ aex.a_drsize = 0;
+
+ /* 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));
+ exit(1);
+ }
+ /* Write the header... */
+ i = write(outfile, &aex, sizeof aex);
+ if (i != sizeof aex) {
+ perror("aex: write");
+ exit(1);
+ }
+ /*
+ * Copy the loadable sections. Zero-fill any gaps less than 64k;
+ * complain about any zero-filling, and die if we're asked to
+ * zero-fill more than 64k.
+ */
+ for (i = 0; i < ex.e_phnum; i++) {
+ /*
+ * Unprocessable sections were handled above, so just verify
+ * that the section can be loaded before copying.
+ */
+ if (ph[i].p_type == PT_LOAD && ph[i].p_filesz) {
+ if (cur_vma != ph[i].p_vaddr) {
+ unsigned long gap = ph[i].p_vaddr - cur_vma;
+ char obuf[1024];
+
+ if (gap > 65536) {
+ fprintf(stderr,
+ "Intersegment gap (%d bytes) too large.\n",
+ gap);
+ exit(1);
+ }
+ fprintf(stderr,
+ "Warning: %d byte intersegment gap.\n", gap);
+ memset(obuf, 0, sizeof obuf);
+ while (gap) {
+ int count = write(outfile, obuf,
+ (gap > sizeof obuf ? sizeof obuf : gap));
+ if (count < 0) {
+ fprintf(stderr,
+ "Error writing gap: %s\n",
+ strerror(errno));
+ exit(1);
+ }
+ gap -= count;
+ }
+ }
+ copy(outfile, infile, ph[i].p_offset, ph[i].p_filesz);
+ cur_vma = ph[i].p_vaddr + ph[i].p_filesz;
}
- }
- copy (outfile, infile, ph [i].p_offset, ph [i].p_filesz);
- cur_vma = ph [i].p_vaddr + ph [i].p_filesz;
}
- }
- /* Copy and translate the symbol table... */
- translate_syms (outfile, infile, sh [symtabix].sh_offset,
- sh [symtabix].sh_size,
- sh [strtabix].sh_offset, sh [strtabix].sh_size);
+ /* Copy and translate the symbol table... */
+ translate_syms(outfile, infile, sh[symtabix].sh_offset,
+ sh[symtabix].sh_size,
+ sh[strtabix].sh_offset, sh[strtabix].sh_size);
- /* Looks like we won... */
- exit (0);
+ /* Looks like we won... */
+ exit(0);
}
-/* translate_syms (out, in, offset, size)
-
- Read the ELF symbol table from in at offset; translate it into a.out
- nlist format and write it to out. */
+/*
+ * translate_syms (out, in, offset, size)
+ *
+ * Read the ELF symbol table from in at offset; translate it into a.out nlist
+ * format and write it to out.
+ */
-translate_syms (out, in, symoff, symsize, stroff, strsize)
- int out, in;
- off_t symoff, symsize;
- off_t stroff, strsize;
+translate_syms(int out, int in, off_t symoff, off_t symsize, off_t stroff,
+ off_t strsize)
{
-# define SYMS_PER_PASS 64
- struct sym inbuf [64];
- struct nlist outbuf [64];
- int i, remaining, cur;
- char *oldstrings;
- char *newstrings, *nsp;
- int newstringsize;
-
- /* Zero the unused fields in the output buffer.. */
- memset (outbuf, 0, sizeof outbuf);
-
- /* Find number of symbols to process... */
- remaining = symsize / sizeof (struct sym);
-
- /* Suck in the old string table... */
- oldstrings = saveRead (in, stroff, strsize, "string table");
-
- /* Allocate space for the new one. XXX We make the wild assumption that
- no two symbol table entries will point at the same place in the
- string table - if that assumption is bad, this could easily blow up. */
- newstringsize = strsize + remaining;
- newstrings = (char *)malloc (newstringsize);
- if (!newstrings)
- {
- fprintf (stderr, "No memory for new string table!\n");
- exit (1);
- }
- /* Initialize the table pointer... */
- nsp = newstrings;
-
- /* Go the the start of the ELF symbol table... */
- if (lseek (in, symoff, SEEK_SET) < 0)
- {
- perror ("translate_syms: lseek");
- exit (1);
- }
-
- /* Translate and copy symbols... */
- while (remaining)
- {
- cur = remaining;
- if (cur > SYMS_PER_PASS)
- cur = SYMS_PER_PASS;
- remaining -= cur;
- if ((i = read (in, inbuf, cur * sizeof (struct sym)))
- != cur * sizeof (struct sym))
- {
- if (i < 0)
- perror ("translate_syms");
- else
- fprintf (stderr, "translate_syms: premature end of file.\n");
- exit (1);
+#define SYMS_PER_PASS 64
+ struct sym inbuf[64];
+ struct nlist outbuf[64];
+ int i, remaining, cur;
+ char *oldstrings;
+ char *newstrings, *nsp;
+ int newstringsize;
+
+ /* Zero the unused fields in the output buffer.. */
+ memset(outbuf, 0, sizeof outbuf);
+
+ /* Find number of symbols to process... */
+ remaining = symsize / sizeof(struct sym);
+
+ /* Suck in the old string table... */
+ oldstrings = saveRead(in, stroff, strsize, "string table");
+
+ /*
+ * Allocate space for the new one. XXX We make the wild assumption
+ * that no two symbol table entries will point at the same place in
+ * the string table - if that assumption is bad, this could easily
+ * blow up.
+ */
+ newstringsize = strsize + remaining;
+ newstrings = (char *) malloc(newstringsize);
+ if (!newstrings) {
+ fprintf(stderr, "No memory for new string table!\n");
+ exit(1);
}
+ /* Initialize the table pointer... */
+ nsp = newstrings;
- /* Do the translation... */
- for (i = 0; i < cur; i++)
- {
- /* Copy the symbol into the new table, but prepend an underscore. */
- *nsp = '_';
- strcpy (nsp + 1, oldstrings + inbuf [i].name);
- outbuf [i].n_un.n_strx = nsp - newstrings + 4;
- nsp += strlen (nsp) + 1;
-
- /* Convert ELF symbol type/section/etc info into a.out type info. */
- if (inbuf [i].type == STT_FILE)
- outbuf [i].n_type = N_FN;
- else if (inbuf [i].shndx == SHN_UNDEF)
- outbuf [i].n_type = N_UNDF;
- else if (inbuf [i].shndx == SHN_ABS)
- outbuf [i].n_type = N_ABS;
- else if (inbuf [i].shndx == SHN_COMMON ||
- inbuf [i].shndx == SHN_MIPS_ACOMMON)
- outbuf [i].n_type = N_COMM;
- else
- outbuf [i].n_type = symTypeTable [inbuf [i].shndx];
- if (inbuf [i].binding == STB_GLOBAL)
- outbuf [i].n_type |= N_EXT;
- /* Symbol values in executables should be compatible. */
- outbuf [i].n_value = inbuf [i].value;
+ /* Go the the start of the ELF symbol table... */
+ if (lseek(in, symoff, SEEK_SET) < 0) {
+ perror("translate_syms: lseek");
+ exit(1);
}
- /* Write out the symbols... */
- if ((i = write (out, outbuf, cur * sizeof (struct nlist)))
- != cur * sizeof (struct nlist))
- {
- fprintf (stderr, "translate_syms: write: %s\n", strerror (errno));
- exit (1);
+ /* Translate and copy symbols... */
+ while (remaining) {
+ cur = remaining;
+ if (cur > SYMS_PER_PASS)
+ cur = SYMS_PER_PASS;
+ remaining -= cur;
+ if ((i = read(in, inbuf, cur * sizeof(struct sym)))
+ != cur * sizeof(struct sym)) {
+ if (i < 0)
+ perror("translate_syms");
+ else
+ fprintf(stderr,
+ "translate_syms: premature end of file.\n");
+ exit(1);
+ }
+ /* Do the translation... */
+ for (i = 0; i < cur; i++) {
+ /*
+ * Copy the symbol into the new table, but prepend an
+ * underscore.
+ */
+ *nsp = '_';
+ strcpy(nsp + 1, oldstrings + inbuf[i].name);
+ outbuf[i].n_un.n_strx = nsp - newstrings + 4;
+ nsp += strlen(nsp) + 1;
+
+ /*
+ * Convert ELF symbol type/section/etc info into
+ * a.out type info.
+ */
+ if (inbuf[i].type == STT_FILE)
+ outbuf[i].n_type = N_FN;
+ else if (inbuf[i].shndx == SHN_UNDEF)
+ outbuf[i].n_type = N_UNDF;
+ else if (inbuf[i].shndx == SHN_ABS)
+ outbuf[i].n_type = N_ABS;
+ else if (inbuf[i].shndx == SHN_COMMON ||
+ inbuf[i].shndx == SHN_MIPS_ACOMMON)
+ outbuf[i].n_type = N_COMM;
+ else
+ outbuf[i].n_type = symTypeTable[inbuf[i].shndx];
+ if (inbuf[i].binding == STB_GLOBAL)
+ outbuf[i].n_type |= N_EXT;
+ /* Symbol values in executables should be compatible. */
+ outbuf[i].n_value = inbuf[i].value;
+ }
+ /* Write out the symbols... */
+ if ((i = write(out, outbuf, cur * sizeof(struct nlist)))
+ != cur * sizeof(struct nlist)) {
+ fprintf(stderr, "translate_syms: write: %s\n", strerror(errno));
+ exit(1);
+ }
+ }
+ /* Write out the string table length... */
+ if (write(out, &newstringsize, sizeof newstringsize)
+ != sizeof newstringsize) {
+ fprintf(stderr,
+ "translate_syms: newstringsize: %s\n", strerror(errno));
+ exit(1);
+ }
+ /* Write out the string table... */
+ if (write(out, newstrings, newstringsize) != newstringsize) {
+ fprintf(stderr, "translate_syms: newstrings: %s\n", strerror(errno));
+ exit(1);
}
- }
- /* Write out the string table length... */
- if (write (out, &newstringsize, sizeof newstringsize)
- != sizeof newstringsize)
- {
- fprintf (stderr,
- "translate_syms: newstringsize: %s\n", strerror (errno));
- exit (1);
- }
- /* Write out the string table... */
- if (write (out, newstrings, newstringsize) != newstringsize)
- {
- fprintf (stderr, "translate_syms: newstrings: %s\n", strerror (errno));
- exit (1);
- }
}
-
-copy (out, in, offset, size)
- int out, in;
- off_t offset, size;
+
+copy(int out, int in, off_t offset, off_t size)
{
- char ibuf [4096];
- int remaining, cur, count;
-
- /* Go the 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);
+ char ibuf[4096];
+ int remaining, cur, count;
+
+ /* Go the the start of the ELF symbol table... */
+ if (lseek(in, offset, SEEK_SET) < 0) {
+ perror("copy: lseek");
+ exit(1);
}
- if ((count = write (out, ibuf, cur)) != cur)
- {
- perror ("copy: write");
- 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. */
-combine (base, new, pad)
- struct sect *base, *new;
- int pad;
+/*
+ * Combine two segments, which must be contiguous. If pad is true, it's
+ * okay for there to be padding between.
+ */
+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);
- }
+ 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;
}
- base -> len += new -> len;
- }
}
-phcmp (h1, h2)
- struct phdr *h1, *h2;
+phcmp(struct phdr * h1, struct phdr * h2)
{
- if (h1 -> vaddr > h2 -> vaddr)
- return 1;
- else if (h1 -> vaddr < h2 -> vaddr)
- return -1;
- else
- return 0;
+ if (h1->vaddr > h2->vaddr)
+ return 1;
+ else if (h1->vaddr < h2->vaddr)
+ return -1;
+ else
+ return 0;
}
-char *saveRead (int file, off_t offset, off_t len, char *name)
+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 %d 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;
+ 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 %d 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;
}