diff options
Diffstat (limited to 'usr.bin/elf2aout/elf2aout.c')
-rw-r--r-- | usr.bin/elf2aout/elf2aout.c | 842 |
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; } |