X-Git-Url: https://pd.if.org/git/?p=zpackage;a=blobdiff_plain;f=elf%2Flibelf.c;fp=elf%2Flibelf.c;h=063eefa74a9f9256897931ec0d4fae2603f87bea;hp=477344fa76729b0e6bdad1750df2733a470fcd74;hb=82e3fcbcf22abcd3921a8946e6ac2b5dd948c44e;hpb=ff478f700fc6179cf7246b4f9624712c4e180c7e diff --git a/elf/libelf.c b/elf/libelf.c index 477344f..063eefa 100644 --- a/elf/libelf.c +++ b/elf/libelf.c @@ -22,9 +22,11 @@ Elf64_Ehdr *libelf_header(void *elf) { return elf; } +#if 0 Elf64_Shdr *libelf_shdr(void *elf, int n) { return 0; } +#endif Elf64_Shdr *libelf_sht_strtab(void *elf) { int i; @@ -58,7 +60,7 @@ Elf64_Shdr *libelf_section_n(void *elf, int n) { return (Elf64_Shdr *)((char *)elf + hdr->e_shoff + n * hdr->e_shentsize); } -Elf64_Shdr *libelf_section(void *elf, int type) { +Elf64_Shdr *libelf_section(void *elf, unsigned int type) { int i; Elf64_Ehdr *hdr; Elf64_Shdr *shdr; @@ -75,7 +77,7 @@ Elf64_Shdr *libelf_section(void *elf, int type) { } int libelf_type(void *elf) { - return ((Elf64_Ehdr *)elf)->e_type; + return libelf_iself(elf) ? libelf_header(elf)->e_type : 0; } int libelf_iself(void *elf) { @@ -113,7 +115,7 @@ void *libelf_map(char *path, size_t *fsize) { return NULL; } /* not at least the size of the elf header? */ - if (sbuf.st_size < sizeof(Elf64_Ehdr)) { + if ((size_t)sbuf.st_size < sizeof(Elf64_Ehdr)) { close(elffd); return NULL; } @@ -133,3 +135,74 @@ void *libelf_map(char *path, size_t *fsize) { return elfbase; } + +char *libelf_soname(void *elfbase) { + Elf64_Ehdr *hdr; + int i; + Elf64_Shdr *shdr; + Elf64_Shdr *dynsect = 0; + Elf64_Shdr *strtab = 0, *dyntab = 0; + char *name, *dynname; + Elf64_Dyn *dent; + + if (!libelf_iself(elfbase)) { + return 0; + } + hdr = libelf_header(elfbase); + + /* only dynamic files will have an soname */ + if (hdr->e_type != ET_DYN) { + return 0; + } + + switch (hdr->e_ident[EI_CLASS]) { + case ELFCLASS64: + case ELFCLASS32: + case ELFCLASSNONE: + break; + default: return 0; break; + } + + /* check endian ness */ + switch (hdr->e_ident[EI_DATA]) { + case ELFDATA2LSB: break; + case ELFDATA2MSB: break; + default: return 0; break; + } + + /* find the section header table */ + for (i = 0; i < hdr->e_shnum; i++) { + shdr = (Elf64_Shdr *)((char *)elfbase + hdr->e_shoff + i * hdr->e_shentsize); + if (shdr->sh_type == SHT_DYNAMIC) { + dynsect = shdr; + } else if (shdr->sh_type == SHT_STRTAB && i == hdr->e_shstrndx) { + strtab = shdr; + } + } + if (!strtab) { + return 0; + } + if (!dynsect) { + return 0; + } + + name = (char *) elfbase + strtab->sh_offset; + for (i = 0; i < hdr->e_shnum; i++) { + shdr = (Elf64_Shdr *)((char *)elfbase + hdr->e_shoff + i * hdr->e_shentsize); + if (shdr->sh_type == SHT_STRTAB && !strcmp(".dynstr", name+shdr->sh_name)) { + dyntab = shdr; + } + } + if (!dyntab) { + return 0; + } + + dynname = (char *) elfbase + dyntab->sh_offset; + for (dent = (Elf64_Dyn *)((char *)elfbase + dynsect->sh_offset); dent->d_tag != DT_NULL; dent++) { + if (dent->d_tag == DT_SONAME) { + return dynname + dent->d_un.d_val; + } + } + + return 0; +}