#define _POSIX_C_SOURCE 200112L #include #include #include #include #include #include #include #include #include #include #include "elf.h" void *libelf_map(char *path, size_t *fsize); int libelf_iself(void *elf); char *libelf_soname(void *elf); int libelf_type(void *elf); Elf64_Ehdr *libelf_header(void *elf) { return elf; } Elf64_Shdr *libelf_shdr(void *elf, int n) { return 0; } Elf64_Shdr *libelf_sht_strtab(void *elf) { int i; Elf64_Ehdr *hdr; Elf64_Shdr *shdr; hdr = libelf_header(elf); for (i = 0; i < hdr->e_shnum; i++) { shdr = (Elf64_Shdr *)((char *)elf + hdr->e_shoff + i * hdr->e_shentsize); if (shdr->sh_type == SHT_STRTAB && i == hdr->e_shstrndx) { return shdr; } } return 0; } char *libelf_sectionname(Elf64_Shdr *section, Elf64_Shdr *strtab) { return (char *)strtab + section->sh_name; } Elf64_Shdr *libelf_section_n(void *elf, int n) { Elf64_Ehdr *hdr; hdr = libelf_header(elf); if (n > hdr->e_shnum) { return 0; } return (Elf64_Shdr *)((char *)elf + hdr->e_shoff + n * hdr->e_shentsize); } Elf64_Shdr *libelf_section(void *elf, int type) { int i; Elf64_Ehdr *hdr; Elf64_Shdr *shdr; hdr = libelf_header(elf); for (i = 0; i < hdr->e_shnum; i++) { shdr = (Elf64_Shdr *)((char *)elf + hdr->e_shoff + i * hdr->e_shentsize); if (shdr->sh_type == type) { return shdr; } } return 0; } int libelf_type(void *elf) { return ((Elf64_Ehdr *)elf)->e_type; } int libelf_iself(void *elf) { Elf64_Ehdr *hdr; hdr = elf; if (hdr->e_ident[EI_MAG0] != ELFMAG0 || hdr->e_ident[EI_MAG1] != ELFMAG1 || hdr->e_ident[EI_MAG2] != ELFMAG2 || hdr->e_ident[EI_MAG3] != ELFMAG3 ) { return 0; } return 1; } void *libelf_map(char *path, size_t *fsize) { int elffd; struct stat sbuf; void *elfbase; errno = 0; elffd = open(path, O_RDONLY); if (elffd == -1) { perror("open"); return NULL; } if (fstat(elffd, &sbuf) == -1) { close(elffd); return NULL; } /* not a regular file? */ if (!S_ISREG(sbuf.st_mode)) { close(elffd); return NULL; } /* not at least the size of the elf header? */ if (sbuf.st_size < sizeof(Elf64_Ehdr)) { close(elffd); return NULL; } elfbase = mmap(0, sbuf.st_size, PROT_READ,MAP_PRIVATE, elffd, 0); close(elffd); if (!elfbase) { return NULL; } if (!libelf_iself(elfbase)) { munmap(elfbase, sbuf.st_size); return NULL; } *fsize = sbuf.st_size; return elfbase; }