📄 elf2ecoff.c
字号:
i ? strerror(errno) : "End of file reached"); exit(1); } if (ex.e_ident[EI_DATA] == ELFDATA2MSB) format_bigendian = 1; if (ntohs(0xaa55) == 0xaa55) { if (!format_bigendian) must_convert_endian = 1; } else { if (format_bigendian) must_convert_endian = 1; } if (must_convert_endian) convert_elf_hdr(&ex); /* Read the program headers... */ ph = (Elf32_Phdr *) saveRead(infile, ex.e_phoff, ex.e_phnum * sizeof(Elf32_Phdr), "ph"); if (must_convert_endian) convert_elf_phdrs(ph, ex.e_phnum); /* Read the section headers... */ sh = (Elf32_Shdr *) saveRead(infile, ex.e_shoff, ex.e_shnum * sizeof(Elf32_Shdr), "sh"); if (must_convert_endian) convert_elf_shdrs(sh, ex.e_shnum); /* Read in the section string table. */ shstrtab = saveRead(infile, sh[ex.e_shstrndx].sh_offset, sh[ex.e_shstrndx].sh_size, "shstrtab"); /* Figure out if we can cram the program header into an ECOFF 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. 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", ex.e_phnum, ph[i].p_type); 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); } else { struct sect ntxt; ntxt.vaddr = ph[i].p_vaddr; ntxt.len = ph[i].p_filesz; combine(&text, &ntxt, 0); } /* 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... */ eah.magic = OMAGIC; eah.vstamp = 200; eah.tsize = text.len; eah.dsize = data.len; eah.bsize = bss.len; eah.entry = ex.e_entry; eah.text_start = text.vaddr; eah.data_start = data.vaddr; eah.bss_start = bss.vaddr; eah.gprmask = 0xf3fffffe; memset(&eah.cprmask, '\0', sizeof(eah.cprmask)); eah.gp_value = 0; /* unused. */ if (format_bigendian) efh.f_magic = MIPSEBMAGIC; else efh.f_magic = MIPSELMAGIC; if (addflag) nosecs = 6; else nosecs = 3; efh.f_nscns = nosecs; efh.f_timdat = 0; /* bogus */ efh.f_symptr = 0; efh.f_nsyms = 0; efh.f_opthdr = sizeof(eah); efh.f_flags = 0x100f; /* Stripped, not sharable. */ memset(esecs, 0, sizeof(esecs)); strcpy(esecs[0].s_name, ".text"); strcpy(esecs[1].s_name, ".data"); strcpy(esecs[2].s_name, ".bss"); if (addflag) { strcpy(esecs[3].s_name, ".rdata"); strcpy(esecs[4].s_name, ".sdata"); strcpy(esecs[5].s_name, ".sbss"); } esecs[0].s_paddr = esecs[0].s_vaddr = eah.text_start; esecs[1].s_paddr = esecs[1].s_vaddr = eah.data_start; esecs[2].s_paddr = esecs[2].s_vaddr = eah.bss_start; if (addflag) { esecs[3].s_paddr = esecs[3].s_vaddr = 0; esecs[4].s_paddr = esecs[4].s_vaddr = 0; esecs[5].s_paddr = esecs[5].s_vaddr = 0; } esecs[0].s_size = eah.tsize; esecs[1].s_size = eah.dsize; esecs[2].s_size = eah.bsize; if (addflag) { esecs[3].s_size = 0; esecs[4].s_size = 0; esecs[5].s_size = 0; } esecs[0].s_scnptr = N_TXTOFF(efh, eah); esecs[1].s_scnptr = N_DATOFF(efh, eah);#define ECOFF_SEGMENT_ALIGNMENT(a) 0x10#define ECOFF_ROUND(s,a) (((s)+(a)-1)&~((a)-1)) esecs[2].s_scnptr = esecs[1].s_scnptr + ECOFF_ROUND(esecs[1].s_size, ECOFF_SEGMENT_ALIGNMENT(&eah)); if (addflag) { esecs[3].s_scnptr = 0; esecs[4].s_scnptr = 0; esecs[5].s_scnptr = 0; } esecs[0].s_relptr = esecs[1].s_relptr = esecs[2].s_relptr = 0; esecs[0].s_lnnoptr = esecs[1].s_lnnoptr = esecs[2].s_lnnoptr = 0; esecs[0].s_nreloc = esecs[1].s_nreloc = esecs[2].s_nreloc = 0; esecs[0].s_nlnno = esecs[1].s_nlnno = esecs[2].s_nlnno = 0; if (addflag) { esecs[3].s_relptr = esecs[4].s_relptr = esecs[5].s_relptr = 0; esecs[3].s_lnnoptr = esecs[4].s_lnnoptr = esecs[5].s_lnnoptr = 0; esecs[3].s_nreloc = esecs[4].s_nreloc = esecs[5].s_nreloc = 0; esecs[3].s_nlnno = esecs[4].s_nlnno = esecs[5].s_nlnno = 0; } esecs[0].s_flags = 0x20; esecs[1].s_flags = 0x40; esecs[2].s_flags = 0x82; if (addflag) { esecs[3].s_flags = 0x100; esecs[4].s_flags = 0x200; esecs[5].s_flags = 0x400; } /* 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); } if (must_convert_endian) convert_ecoff_filehdr(&efh); /* Write the headers... */ i = write(outfile, &efh, sizeof(efh)); if (i != sizeof efh) { perror("efh: write"); exit(1); } for (i = 0; i < nosecs; i++) { printf("Section %d: %s phys %lx size %lx file offset %lx\n", i, esecs[i].s_name, esecs[i].s_paddr, esecs[i].s_size, esecs[i].s_scnptr); } fprintf(stderr, "wrote %d byte file header.\n", i); if (must_convert_endian) convert_ecoff_aouthdr(&eah); i = write(outfile, &eah, sizeof(eah)); if (i != sizeof(eah)) { perror("eah: write"); exit(1); } fprintf(stderr, "wrote %d byte a.out header.\n", i); if (must_convert_endian) convert_ecoff_esecs(&esecs[0], nosecs); i = write(outfile, &esecs, nosecs * sizeof(struct scnhdr)); if (i != nosecs * sizeof(struct scnhdr)) { perror("esecs: write"); exit(1); } fprintf(stderr, "wrote %d bytes of section headers.\n", i); pad = (sizeof(efh) + sizeof(eah) + nosecs * sizeof(struct scnhdr)) & 15; if (pad) { pad = 16 - pad; i = write(outfile, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", pad); if (i < 0) { perror("ipad: write"); exit(1); } fprintf(stderr, "wrote %d byte pad.\n", i); } /* * 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 == 0) continue; 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 (%ld " "bytes) too large.\n", gap); exit(1); } fprintf(stderr, "Warning: %ld 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; } } fprintf(stderr, "writing %d bytes...\n", 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; } /* * Write a page of padding for boot PROMS that read entire pages. * Without this, they may attempt to read past the end of the * data section, incur an error, and refuse to boot. */ { char obuf[4096]; memset(obuf, 0, sizeof(obuf)); if (write(outfile, obuf, sizeof(obuf)) != sizeof(obuf)) { fprintf(stderr, "Error writing PROM padding: %s\n", strerror(errno)); exit(1); } } /* Looks like we won... */ exit(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -