static int _exit_32_shdr(AsmFormatPlugin * format, Elf32_Off offset) { AsmFormatPluginHelper * helper = format->helper; Elf * elf = format->priv; ElfArch * ea = elf->arch; Elf32_Word addralign = ea->addralign; Elf32_Shdr * es32 = elf->es32; Elf32_Shdr hdr; int i; #ifdef DEBUG fprintf(stderr, "DEBUG: %s()\n", __func__); #endif if(helper->seek(helper->format, 0, SEEK_END) < 0) return _elf_error(format); memset(&hdr, 0, sizeof(hdr)); if(ea->endian == ELFDATA2MSB) { hdr.sh_type = _htob32(SHT_NULL); hdr.sh_link = _htob32(SHN_UNDEF); } else { hdr.sh_type = _htol32(SHT_NULL); hdr.sh_link = _htol32(SHN_UNDEF); } if(helper->write(helper->format, &hdr, sizeof(hdr)) != sizeof(hdr)) return -1; for(i = 0; i < elf->es32_cnt; i++) { #ifdef DEBUG fprintf(stderr, "DEBUG: %s() %d\n", __func__, i); #endif if(i + 1 == elf->es32_cnt) es32[i].sh_size = offset - es32[i].sh_offset; else es32[i].sh_size = es32[i + 1].sh_offset - es32[i].sh_offset; es32[i].sh_offset = (ea->endian == ELFDATA2MSB) ? _htob32(es32[i].sh_offset) : _htol32(es32[i].sh_offset); es32[i].sh_size = (ea->endian == ELFDATA2MSB) ? _htob32(es32[i].sh_size) : _htol32(es32[i].sh_size); if(es32[i].sh_type == SHT_PROGBITS) es32[i].sh_addralign = (ea->endian == ELFDATA2MSB) ? _htob32(addralign) : _htol32(addralign); es32[i].sh_type = (ea->endian == ELFDATA2MSB) ? _htob32(es32[i].sh_type) : _htol32(es32[i].sh_type); if(helper->write(helper->format, &es32[i], sizeof(Elf32_Shdr)) != sizeof(Elf32_Shdr)) return -1; } return 0; }
static int _exit_64_shdr(AsmFormatPlugin * format, Elf64_Off offset) { AsmFormatPluginHelper * helper = format->helper; Elf * elf = format->priv; ElfArch * ea = elf->arch; Elf64_Xword addralign = ea->addralign; Elf64_Shdr * es64 = elf->es64; Elf64_Shdr hdr; int i; if(helper->seek(helper->format, 0, SEEK_END) < 0) return _elf_error(format); memset(&hdr, 0, sizeof(hdr)); if(ea->endian == ELFDATA2MSB) { hdr.sh_type = _htob32(SHT_NULL); hdr.sh_link = _htob32(SHN_UNDEF); } else { hdr.sh_type = _htol32(SHT_NULL); hdr.sh_link = _htol32(SHN_UNDEF); } if(helper->write(helper->format, &hdr, sizeof(hdr)) != sizeof(hdr)) return -1; for(i = 0; i < elf->es64_cnt; i++) { if(i + 1 == elf->es64_cnt) es64[i].sh_size = offset - es64[i].sh_offset; else es64[i].sh_size = es64[i + 1].sh_offset - es64[i].sh_offset; es64[i].sh_offset = (ea->endian == ELFDATA2MSB) ? _htob64(es64[i].sh_offset) : _htol64(es64[i].sh_offset); es64[i].sh_size = (ea->endian == ELFDATA2MSB) ? _htob64(es64[i].sh_size) : _htol64(es64[i].sh_size); if(es64[i].sh_type == SHT_PROGBITS) es64[i].sh_addralign = (ea->endian == ELFDATA2MSB) ? _htob64(addralign) : _htol64(addralign); es64[i].sh_type = (ea->endian == ELFDATA2MSB) ? _htob32(es64[i].sh_type) : _htol32(es64[i].sh_type); if(helper->write(helper->format, &es64[i], sizeof(Elf64_Shdr)) != sizeof(Elf64_Shdr)) return -1; } return 0; }
static int _exit_32_phdr(AsmFormatPlugin * format, Elf32_Off offset) { AsmFormatPluginHelper * helper = format->helper; Elf * elf = format->priv; ElfArch * ea = elf->arch; Elf32_Ehdr hdr; #ifdef DEBUG fprintf(stderr, "DEBUG: %s()\n", __func__); #endif if(elf->es32_cnt == 0) return 0; if(helper->seek(helper->format, 0, SEEK_SET) != 0) return -1; if(helper->read(helper->format, &hdr, sizeof(hdr)) != sizeof(hdr)) return _elf_error(format); if(ea->endian == ELFDATA2MSB) { hdr.e_shoff = _htob32(offset); hdr.e_shnum = _htob16(elf->es32_cnt + 1); hdr.e_shstrndx = _htob16(elf->es32_cnt); } else { hdr.e_shoff = _htol32(offset); hdr.e_shnum = _htol16(elf->es32_cnt + 1); hdr.e_shstrndx = _htol16(elf->es32_cnt); } if(helper->seek(helper->format, 0, SEEK_SET) != 0) return -1; if(helper->write(helper->format, &hdr, sizeof(hdr)) != sizeof(hdr)) return -1; return 0; }
static int _exit_32(AsmFormatPlugin * format) { int ret = 0; AsmFormatPluginHelper * helper = format->helper; long offset; #ifdef DEBUG fprintf(stderr, "DEBUG: %s()\n", __func__); #endif if(_section_32(format, ".shstrtab") != 0) ret = -1; else if(helper->write(helper->format, shstrtab.buf, shstrtab.cnt) != (ssize_t)shstrtab.cnt) ret = -1; else if((offset = helper->seek(helper->format, 0, SEEK_CUR)) < 0) ret = -1; else if(_exit_32_phdr(format, offset) != 0 || _exit_32_shdr(format, offset) != 0) ret = -1; free(shstrtab.buf); shstrtab.buf = NULL; shstrtab.cnt = 0; ret |= _elf_exit(format); return ret; }
static int _exit_64_phdr(AsmFormatPlugin * format, Elf64_Off offset) { AsmFormatPluginHelper * helper = format->helper; Elf * elf = format->priv; ElfArch * ea = elf->arch; Elf64_Ehdr hdr; if(elf->es64_cnt == 0) return 0; if(helper->seek(helper->format, 0, SEEK_SET) != 0) return -1; if(helper->read(helper->format, &hdr, sizeof(hdr)) != sizeof(hdr)) return -1; if(ea->endian == ELFDATA2MSB) { hdr.e_shoff = _htob64(offset); hdr.e_shnum = _htob16(elf->es64_cnt); hdr.e_shstrndx = _htob16(elf->es64_cnt - 1); } else { hdr.e_shoff = _htol64(offset); hdr.e_shnum = _htol16(elf->es64_cnt); hdr.e_shstrndx = _htol16(elf->es64_cnt - 1); } if(helper->seek(helper->format, 0, SEEK_SET) != 0) return -1; if(helper->write(helper->format, &hdr, sizeof(hdr)) != sizeof(hdr)) return -1; return 0; }
static int _exit_64(AsmFormatPlugin * format) { int ret = 0; AsmFormatPluginHelper * helper = format->helper; long offset; if(_section_64(format, ".shstrtab") != 0) ret = 1; else if(helper->write(helper->format, shstrtab.buf, shstrtab.cnt) != (ssize_t)shstrtab.cnt) ret = -1; else if((offset = helper->seek(helper->format, 0, SEEK_CUR)) < 0) ret = -1; else if(_exit_64_phdr(format, offset) != 0 || _exit_64_shdr(format, offset) != 0) ret = 1; free(shstrtab.buf); shstrtab.buf = NULL; shstrtab.cnt = 0; ret |= _elf_exit(format); return ret; }
/* init_32 */ static int _init_32(AsmFormatPlugin * format) { AsmFormatPluginHelper * helper = format->helper; Elf * elf = format->priv; ElfArch * ea = elf->arch; Elf32_Ehdr hdr; #ifdef DEBUG fprintf(stderr, "DEBUG: %s()\n", __func__); #endif memset(&hdr, 0, sizeof(hdr)); memcpy(&hdr.e_ident, ELFMAG, SELFMAG); hdr.e_ident[EI_CLASS] = ELFCLASS32; hdr.e_ident[EI_DATA] = ea->endian; hdr.e_ident[EI_VERSION] = EV_CURRENT; if(ea->endian == ELFDATA2MSB) { hdr.e_type = _htob16(ET_REL); hdr.e_machine = _htob16(ea->machine); hdr.e_version = _htob32(EV_CURRENT); hdr.e_ehsize = _htob16(sizeof(hdr)); hdr.e_shentsize = _htob16(sizeof(Elf32_Shdr)); hdr.e_shstrndx = _htob16(SHN_UNDEF); } else { hdr.e_type = _htol16(ET_REL); hdr.e_machine = _htol16(ea->machine); hdr.e_version = _htol32(EV_CURRENT); hdr.e_ehsize = _htol16(sizeof(hdr)); hdr.e_shentsize = _htol16(sizeof(Elf32_Shdr)); hdr.e_shstrndx = _htol16(SHN_UNDEF); } if(helper->write(helper->format, &hdr, sizeof(hdr)) != sizeof(hdr)) return _elf_error(format); return 0; }