📄 elf2flt.c
字号:
case R_SPARC_PC22: sym_vma = 0; sym_addr += sym_vma + q->addend; sym_addr -= q->address; break; case R_SPARC_WDISP30: sym_addr = (((*(q->sym_ptr_ptr))->value- q->address) >> 2) & 0x3fffffff; sym_addr |= (ntohl(*((unsigned long *) (sectionp + q->address))) & 0xc0000000); break; case R_SPARC_HI22: relocation_needed = 1; pflags = 0x80000000; sym_vma = bfd_section_vma(abs_bfd, sym_section); sym_addr += sym_vma + q->addend; sym_addr |= (htonl(*((unsigned long *) (sectionp + q->address))) & 0xffc00000); break; case R_SPARC_LO10: relocation_needed = 1; pflags = 0x40000000; sym_vma = bfd_section_vma(abs_bfd, sym_section); sym_addr += sym_vma + q->addend; sym_addr &= 0x000003ff; sym_addr |= (htonl(*((unsigned long *) (sectionp + q->address))) & 0xfffffc00); break;#endif /* TARGET_sparc */ default: /* missing support for other types of relocs */ printf("ERROR: bad reloc type %d\n", (*p)->howto->type); continue; } } sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value - bfd_section_vma(abs_bfd, sym_section)); /* * for full elf relocation we have to write back the start_code * relative value to use. */ if (!pic_with_got) {#if defined(TARGET_arm) union { unsigned char c[4]; unsigned long l; } tmp; long hl; int i0, i1, i2, i3; /* * horrible nasty hack to support different endianess */ if (!bfd_big_endian(abs_bfd)) { i0 = 0; i1 = 1; i2 = 2; i3 = 3; } else { i0 = 3; i1 = 2; i2 = 1; i3 = 0; } tmp.l = *((unsigned long *) (sectionp + q->address)); hl = tmp.c[i0] | (tmp.c[i1] << 8) | (tmp.c[i2] << 16); if ((*p)->howto->type != R_ARM_PC24) hl |= (tmp.c[i3] << 24); else if (tmp.c[i2] & 0x80) hl |= 0xff000000; /* sign extend */ hl += sym_addr; tmp.c[i0] = hl & 0xff; tmp.c[i1] = (hl >> 8) & 0xff; tmp.c[i2] = (hl >> 16) & 0xff; if ((*p)->howto->type != R_ARM_PC24) tmp.c[i3] = (hl >> 24) & 0xff; if ((*p)->howto->type == R_ARM_ABS32) *((unsigned long *) (sectionp + q->address)) = htonl(hl); else *((unsigned long *) (sectionp + q->address)) = tmp.l;#endif#if defined(TARGET_m68k) *((unsigned long *) (sectionp + q->address)) = htonl(sym_addr);#endif#if defined(TARGET_sparc) *((unsigned long *) (sectionp + q->address)) = htonl(sym_addr);#endif } if (verbose) printf(" RELOC[%d]: offset=%x symbol=%s%s " "section=%s size=%d " "fixup=%x (reloc=0x%x)\n", flat_reloc_count, q->address, sym_name, addstr, section_name, sym_reloc_size, sym_addr, section_vma + q->address); /* * Create relocation entry (PC relative doesn't need this). */ if (relocation_needed) { flat_relocs = realloc(flat_relocs, (flat_reloc_count + 1) * sizeof(unsigned long)); flat_relocs[flat_reloc_count] = pflags | (section_vma + q->address); if (verbose) printf("reloc[%d] = 0x%x\n", flat_reloc_count, section_vma + q->address); flat_reloc_count++; relocation_needed = 0; pflags = 0; }#if 0printf("%s(%d): symbol name=%s address=%x section=%s -> RELOC=%x\n", __FILE__, __LINE__, sym_name, q->address, section_name, flat_relocs[flat_reloc_count]);#endif } } } if (rc < 0) return(NULL); *n_relocs = flat_reloc_count; return flat_relocs;}#if 0/* shared lib symbols stuff */longget_symbol(char *name, asection *sec, asymbol **symbol_table, long number_of_symbols){ long i; for (i=0; i<number_of_symbols; i++) { if (symbol_table[i]->section == sec) { if (!strcmp(symbol_table[i]->name, name)) { return symbol_table[i]->value; } } } return -1;} intoutput_offset_table(int fd, char *ename, bfd *abfd, asymbol **symbol_table, long number_of_symbols){ long i; FILE *ef; char buf[80]; char libname[80]; long etext_addr; long sym_addr; int foobar = 0; int count = 0; signed short *tab = malloc(32768); /* we don't know how many yet*/ asection *text_section = bfd_get_section_by_name (abfd, ".text"); if (!(ef = fopen(ename, "r"))) { fprintf (stderr,"Can't open %s\n",ename); exit(1); } fgets(libname, 80, ef); if (number_of_symbols < 0) { fprintf (stderr,"Corrupt symbol table!\n"); exit(1); } if ((etext_addr = get_symbol("etext", text_section, symbol_table, number_of_symbols)) == -1) { fprintf (stderr,"Can't find the symbol etext\n"); exit(1); } fgets(buf, 80, ef); while (!feof(ef)) { buf[strlen(buf)-1] = 0; /* Arrrgh! linefeeds */ if ((sym_addr = get_symbol(buf, text_section, symbol_table, number_of_symbols)) == -1) { fprintf (stderr,"Can't find the symbol %s\n",buf); foobar++; } else { tab[++count] = htons(sym_addr - etext_addr); } fgets(buf, 80, ef); } fclose(ef); if (foobar) { fprintf (stderr,"*** %d symbols not found\n",foobar); exit(10); } strcpy((char *)&tab[++count],libname); tab[0] = htons(count * 2); write(fd, tab, count * 2 + strlen(libname) + 2); return 0;}#endifstatic char * program;static void usage(void){ fprintf(stderr, "Usage: %s [vrzd] [-p <abs-pic-file>] [-s stack-size] " "[-o <output-file>] <elf-file>\n\n" " -v : verbose operation\n" " -r : force load to RAM\n" " -z : compress code/data/relocs\n" " -d : compress data/relocs\n" " -p abs-pic-file : GOT/PIC processing with files\n" " -s stacksize : set application stack size\n" " -o output-file : output file name\n\n", program); fprintf(stderr, "Compiled for " ARCH " architecture\n\n"); exit(2);}int main(int argc, char *argv[]){ int fd; bfd *rel_bfd, *abs_bfd; asection *s; char *ofile=NULL, *pfile=NULL; char *fname = NULL; int opt; int i; int stack; char cmd[1024]; FILE *gf = NULL; asymbol **symbol_table; long number_of_symbols; unsigned long data_len; unsigned long bss_len; unsigned long text_len; unsigned long reloc_len; unsigned long data_vma; unsigned long bss_vma; unsigned long text_vma; void *text; void *data; unsigned long *reloc; struct flat_hdr hdr; program = argv[0]; progname = argv[0]; if (argc < 2) usage(); stack = 4096; while ((opt = getopt(argc, argv, "vzdrp:s:o:")) != -1) { switch (opt) { case 'v': verbose++; break; case 'r': load_to_ram++; break; case 'z': compress = 1; break; case 'd': compress = 2; break; case 'p': pfile = optarg; break; case 'o': ofile = optarg; break; case 's': stack = atoi(optarg); break; default: fprintf(stderr, "%s Unknown option\n", argv[0]); usage(); break; } } /* * if neither the -r or -p options was given, default to * a RAM load as that is the only option that makes sense. */ if (!load_to_ram && !pfile) load_to_ram = 1; filename = fname = argv[argc-1]; if (!(rel_bfd = bfd_openr(fname, 0))) { fprintf(stderr, "Can't open %s\n", fname); exit(1); } if (bfd_check_format (rel_bfd, bfd_object) == 0) { fprintf(stderr, "File is not an object file\n"); exit(2); } if (pfile) { pic_with_got = 1; if (!(abs_bfd = bfd_openr(pfile, 0))) { fprintf(stderr, "Can't open %s\n", pfile); exit(1); } if (bfd_check_format (abs_bfd, bfd_object) == 0) { fprintf(stderr, "File is not an object file\n"); exit(2); } } else { abs_bfd = rel_bfd; /* one file does all */ } if (! (bfd_get_file_flags(rel_bfd) & HAS_RELOC)) { fprintf (stderr, "%s: Input file contains no relocation info\n", fname); exit (2); } if (use_resolved && !(bfd_get_file_flags(abs_bfd) & EXEC_P)) { /* `Absolute' file is not absolute, so neither are address contained therein. */ fprintf (stderr, "%s: `-a' option specified with non-fully-resolved input file\n", bfd_get_filename (abs_bfd)); exit (2); } symbol_table = get_symbols(abs_bfd, &number_of_symbols); s = bfd_get_section_by_name (abs_bfd, ".text"); text_vma = s->vma; text_len = s->_raw_size; text = malloc(text_len); if (verbose) { printf("TEXT -> vma=%x len=%x\n", text_vma, text_len); printf(" lma=%x clen=%x oo=%x ap=%x fp=%x\n", s->lma, s->_cooked_size, s->output_offset, s->alignment_power, s->filepos); } if (bfd_get_section_contents(abs_bfd, s, text, 0, s->_raw_size) == false) { fprintf(stderr, "read error section %s\n", s->name); exit(2); } s = bfd_get_section_by_name (abs_bfd, ".data"); data_vma = s->vma; data_len = s->_raw_size; data = malloc(data_len); if (verbose) { printf("DATA -> vma=%x len=%x\n", data_vma, data_len); printf(" lma=%x clen=%x oo=%x ap=%x fp=%x\n", s->lma, s->_cooked_size, s->output_offset, s->alignment_power, s->filepos); } if (text_len != data_vma) { if (text_len > data_vma) { printf("ERROR: text=%x overlaps data=%x ?\n", text_len, data_vma); exit(1); } if (verbose) printf("WARNING: data=%x does not directly follow text=%x\n", data_vma, text_len); text_len = data_vma; } if (bfd_get_section_contents(abs_bfd, s, data, 0, s->_raw_size) == false) { fprintf(stderr, "read error section %s\n", s->name); exit(2); } s = bfd_get_section_by_name (abs_bfd, ".bss"); bss_len = s->_raw_size; bss_vma = s->vma; bss_len += add_com_to_bss(symbol_table, number_of_symbols, bss_len); if (verbose) { printf("BSS -> vma=%x len=%x\n", bss_vma, bss_len); printf(" lma=%x clen=%x oo=%x ap=%x fp=%x\n", s->lma, s->_cooked_size, s->output_offset, s->alignment_power, s->filepos); } if ((text_len + data_len) != bss_vma) { if ((text_len + data_len) > bss_vma) { printf("ERROR: text=%x + data=%x overlaps bss=%x ?\n", text_len, data_len, bss_vma); exit(1); } if (verbose) printf("WARNING: bss=%x does not directly follow text=%x + data=%x(%x)\n", bss_vma, text_len, data_len, text_len + data_len); data_len = bss_vma - text_len; } reloc = (unsigned long *) output_relocs (abs_bfd, symbol_table, number_of_symbols, &reloc_len, text, text_len, data, data_len, rel_bfd); if (reloc == NULL) printf("No relocations in code!\n"); /* Fill in the binflt_flat header */ memcpy(hdr.magic,"bFLT",4); hdr.rev = htonl(FLAT_VERSION); hdr.entry = htonl(16 * 4 + bfd_get_start_address(abs_bfd)); hdr.data_start = htonl(16 * 4 + text_len); hdr.data_end = htonl(16 * 4 + text_len + data_len); hdr.bss_end = htonl(16 * 4 + text_len + data_len + bss_len); hdr.stack_size = htonl(stack); /* FIXME */ hdr.reloc_start = htonl(16 * 4 + text_len + data_len); hdr.reloc_count = htonl(reloc_len); hdr.flags = htonl(0 | (load_to_ram ? FLAT_FLAG_RAM : 0) | (pic_with_got ? FLAT_FLAG_GOTPIC : 0) | (compress ? (compress == 2 ? FLAT_FLAG_GZDATA : FLAT_FLAG_GZIP) : 0) ); bzero(hdr.filler, sizeof(hdr.filler)); for (i=0; i<reloc_len; i++) reloc[i] = htonl(reloc[i]); if (verbose) { printf("SIZE: .text=0x%04x, .data=0x%04x, .bss=0x%04x", text_len, data_len, bss_len); if (reloc) printf(", relocs=0x%04x", reloc_len); printf("\n"); } if (!ofile) { ofile = malloc(strlen(fname) + 5 + 1); /* 5 to add suffix */ strcpy(ofile, fname); strcat(ofile, ".bflt"); } if ((fd = open (ofile, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, 0744)) < 0) { fprintf (stderr, "Can't open output file %s\n", ofile); exit(4); } write(fd, &hdr, sizeof(hdr)); close(fd); /* * get the compression command ready */ sprintf(cmd, "gzip -f -9 >> %s", ofile);#define START_COMPRESSOR do { \ if (gf) fclose(gf); \ if (!(gf = popen(cmd, "w"))) { \ fprintf(stderr, "Can't run cmd %s\n", cmd); \ exit(4); \ } \ } while (0) gf = fopen(ofile, "a"); if (!gf) { fprintf(stderr, "Can't opne file %s for writing\n", ofile); \ exit(4); } if (compress == 1) START_COMPRESSOR; fwrite(text, text_len, 1, gf); if (compress == 2) START_COMPRESSOR; fwrite(data, data_len, 1, gf); if (reloc) fwrite(reloc, reloc_len*4, 1, gf); fclose(gf); exit(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -