#include #include #include #include #include #include #include #include uint32_t hash_words[] = { 0x01234567, 0x89abcdef, 0xdeadc0de }; char string_table[] = { /* Offset 0 */ '\0', /* Offset 1 */ '.', 'f', 'o', 'o', '\0', /* Offset 6 */ '.', 's', 'h', 's', 't', 'r', 't', 'a', 'b', '\0' }; int main(int argc, char **argv) { int fd; size_t off_shstrtab, off_foo; Elf *e; Elf_Scn *scn; Elf_Data *data; Elf32_Ehdr *ehdr; Elf32_Phdr *phdr; Elf32_Shdr *shdr; if (argc != 2) errx(EX_USAGE, "usage: %s file-name", getprogname()); if (elf_version(EV_CURRENT) == EV_NONE) errx(EX_SOFTWARE, "ELF library initialization failed: %s", elf_errmsg(-1)); if ((fd = open(argv[1], O_WRONLY|O_CREAT, 0777)) < 0) err(EX_OSERR, "open \"%s\" failed", argv[1]); if ((e = elf_begin(fd, ELF_C_WRITE, NULL)) == NULL) errx(EX_SOFTWARE, "elf_begin() failed: %s.", elf_errmsg(-1)); /* App control LAYOUT */ elf_flagelf(e, ELF_C_SET, ELF_F_LAYOUT); if ((ehdr = elf32_newehdr(e)) == NULL) errx(EX_SOFTWARE, "elf32_newehdr() failed: %s.", elf_errmsg(-1)); ehdr->e_ident[EI_DATA] = ELFDATA2LSB; ehdr->e_machine = EM_386; ehdr->e_type = ET_EXEC; if ((phdr = elf32_newphdr(e, 1)) == NULL) errx(EX_SOFTWARE, "elf32_newphdr() failed: %s.", elf_errmsg(-1)); /* Calculate offsets */ ehdr->e_phoff = elf32_fsize(ELF_T_EHDR, 1, EV_CURRENT); off_foo = ehdr->e_phoff + elf32_fsize(ELF_T_PHDR, 1, EV_CURRENT); off_shstrtab = off_foo + sizeof(hash_words); ehdr->e_shoff = roundup(off_shstrtab + sizeof(string_table), 4); printf("phoff = %d\n", ehdr->e_phoff); printf("off_foo = %d\n", off_foo); printf("off_shstrtab = %d\n", off_shstrtab); printf("shoff = %d\n", ehdr->e_shoff); /* Create .shstrtab fisrt */ if ((scn = elf_newscn(e)) == NULL) errx(EX_SOFTWARE, "elf_newscn() failed: %s.", elf_errmsg(-1)); if ((data = elf_newdata(scn)) == NULL) errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1)); data->d_align = 1; data->d_buf = string_table; data->d_off = 0LL; data->d_size = sizeof(string_table); data->d_type = ELF_T_BYTE; data->d_version = EV_CURRENT; if ((shdr = elf32_getshdr(scn)) == NULL) errx(EX_SOFTWARE, "elf32_getshdr() failed: %s.", elf_errmsg(-1)); shdr->sh_name = 6; shdr->sh_offset = off_shstrtab; shdr->sh_size = sizeof(string_table); shdr->sh_addralign = data->d_align; shdr->sh_type = SHT_STRTAB; shdr->sh_flags = SHF_STRINGS | SHF_ALLOC; shdr->sh_entsize = 0; elf_setshstrndx(e, elf_ndxscn(scn)); /* Create .foo */ if ((scn = elf_newscn(e)) == NULL) errx(EX_SOFTWARE, "elf_newscn() failed: %s.", elf_errmsg(-1)); if ((data = elf_newdata(scn)) == NULL) errx(EX_SOFTWARE, "elf_newdata() failed: %s.", elf_errmsg(-1)); data->d_align = 4; data->d_off = 0LL; data->d_buf = hash_words; data->d_type = ELF_T_WORD; data->d_size = sizeof(hash_words); data->d_version = EV_CURRENT; if ((shdr = elf32_getshdr(scn)) == NULL) errx(EX_SOFTWARE, "elf32_getshdr() failed: %s.", elf_errmsg(-1)); shdr->sh_name = 1; shdr->sh_offset = off_foo; shdr->sh_size = sizeof(hash_words); shdr->sh_addralign = data->d_align; shdr->sh_type = SHT_HASH; shdr->sh_flags = SHF_ALLOC; shdr->sh_entsize = 0; if (elf_update(e, ELF_C_NULL) < 0) errx(EX_SOFTWARE, "elf_update(NULL) failed: %s.", elf_errmsg(-1)); phdr->p_type = PT_PHDR; phdr->p_offset = ehdr->e_phoff; phdr->p_filesz = elf32_fsize(ELF_T_PHDR, 1, EV_CURRENT); (void) elf_flagphdr(e, ELF_C_SET, ELF_F_DIRTY); if (elf_update(e, ELF_C_WRITE) < 0) errx(EX_SOFTWARE, "elf_update() failed: %s.", elf_errmsg(-1)); (void) elf_end(e); (void) close(fd); exit(EX_OK); }