1 #define _POSIX_C_SOURCE 200112L
16 void *libelf_map(char *path, size_t *fsize);
17 int libelf_iself(void *elf);
18 char *libelf_soname(void *elf);
19 int libelf_type(void *elf);
21 Elf64_Ehdr *libelf_header(void *elf) {
26 Elf64_Shdr *libelf_shdr(void *elf, int n) {
31 Elf64_Shdr *libelf_sht_strtab(void *elf) {
36 hdr = libelf_header(elf);
38 for (i = 0; i < hdr->e_shnum; i++) {
39 shdr = (Elf64_Shdr *)((char *)elf + hdr->e_shoff + i * hdr->e_shentsize);
40 if (shdr->sh_type == SHT_STRTAB && i == hdr->e_shstrndx) {
47 char *libelf_sectionname(Elf64_Shdr *section, Elf64_Shdr *strtab) {
48 return (char *)strtab + section->sh_name;
51 Elf64_Shdr *libelf_section_n(void *elf, int n) {
54 hdr = libelf_header(elf);
56 if (n > hdr->e_shnum) {
60 return (Elf64_Shdr *)((char *)elf + hdr->e_shoff + n * hdr->e_shentsize);
63 Elf64_Shdr *libelf_section(void *elf, unsigned int type) {
68 hdr = libelf_header(elf);
70 for (i = 0; i < hdr->e_shnum; i++) {
71 shdr = (Elf64_Shdr *)((char *)elf + hdr->e_shoff + i * hdr->e_shentsize);
72 if (shdr->sh_type == type) {
79 int libelf_type(void *elf) {
80 return libelf_iself(elf) ? libelf_header(elf)->e_type : 0;
83 int libelf_iself(void *elf) {
86 if (hdr->e_ident[EI_MAG0] != ELFMAG0
87 || hdr->e_ident[EI_MAG1] != ELFMAG1
88 || hdr->e_ident[EI_MAG2] != ELFMAG2
89 || hdr->e_ident[EI_MAG3] != ELFMAG3
96 void *libelf_map(char *path, size_t *fsize) {
103 elffd = open(path, O_RDONLY);
108 if (fstat(elffd, &sbuf) == -1) {
112 /* not a regular file? */
113 if (!S_ISREG(sbuf.st_mode)) {
117 /* not at least the size of the elf header? */
118 if ((size_t)sbuf.st_size < sizeof(Elf64_Ehdr)) {
123 elfbase = mmap(0, sbuf.st_size, PROT_READ,MAP_PRIVATE, elffd, 0);
129 if (!libelf_iself(elfbase)) {
130 munmap(elfbase, sbuf.st_size);
134 *fsize = sbuf.st_size;
139 char *libelf_soname(void *elfbase) {
143 Elf64_Shdr *dynsect = 0;
144 Elf64_Shdr *strtab = 0, *dyntab = 0;
145 char *name, *dynname;
148 if (!libelf_iself(elfbase)) {
151 hdr = libelf_header(elfbase);
153 /* only dynamic files will have an soname */
154 if (hdr->e_type != ET_DYN) {
158 switch (hdr->e_ident[EI_CLASS]) {
163 default: return 0; break;
166 /* check endian ness */
167 switch (hdr->e_ident[EI_DATA]) {
168 case ELFDATA2LSB: break;
169 case ELFDATA2MSB: break;
170 default: return 0; break;
173 /* find the section header table */
174 for (i = 0; i < hdr->e_shnum; i++) {
175 shdr = (Elf64_Shdr *)((char *)elfbase + hdr->e_shoff + i * hdr->e_shentsize);
176 if (shdr->sh_type == SHT_DYNAMIC) {
178 } else if (shdr->sh_type == SHT_STRTAB && i == hdr->e_shstrndx) {
189 name = (char *) elfbase + strtab->sh_offset;
190 for (i = 0; i < hdr->e_shnum; i++) {
191 shdr = (Elf64_Shdr *)((char *)elfbase + hdr->e_shoff + i * hdr->e_shentsize);
192 if (shdr->sh_type == SHT_STRTAB && !strcmp(".dynstr", name+shdr->sh_name)) {
200 dynname = (char *) elfbase + dyntab->sh_offset;
201 for (dent = (Elf64_Dyn *)((char *)elfbase + dynsect->sh_offset); dent->d_tag != DT_NULL; dent++) {
202 if (dent->d_tag == DT_SONAME) {
203 return dynname + dent->d_un.d_val;