From: Nathan Wagner Date: Sun, 15 Apr 2018 05:45:53 +0000 (+0000) Subject: add libelf_soneed function X-Git-Tag: v0.1.6~102 X-Git-Url: https://pd.if.org/git/?p=zpackage;a=commitdiff_plain;h=82e3fcbcf22abcd3921a8946e6ac2b5dd948c44e add libelf_soneed function --- diff --git a/elf/elf.h b/elf/elf.h index 60d26aa..e316a6e 100644 --- a/elf/elf.h +++ b/elf/elf.h @@ -578,5 +578,6 @@ Elf64_Shdr *libelf_section_n(void *elf, int n); Elf64_Shdr *libelf_section(void *elf, unsigned int type); int libelf_type(void *elf); int libelf_iself(void *elf); +char *libelf_soname(void *elf); #endif 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; +} diff --git a/lib/zpm.c b/lib/zpm.c index f0ae5a2..30ec7a6 100644 --- a/lib/zpm.c +++ b/lib/zpm.c @@ -602,57 +602,22 @@ static int set_elf_info(sqlite3 *db, char *hash, char *content, size_t length) { hdr = libelf_header(content); /* if lib, set soname */ if (libelf_type(content) == ET_DYN) { - char *elf; - Elf64_Shdr *shdr, *dynsect, *dynstrtab = 0; - - elf = (char *)content; - for (i = 0; i < hdr->e_shnum; i++) { - shdr = (Elf64_Shdr *)(elf + 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) { - dynstrtab = shdr; - } - } - if (!dynstrtab) { - exit(8); - } - if (!dynsect) { - exit(9); - } - - char *name; - Elf64_Shdr *dyntab; - name = elf + dynstrtab->sh_offset; - for (i = 0; i < hdr->e_shnum; i++) { - shdr = (Elf64_Shdr *)(elf + hdr->e_shoff + i * hdr->e_shentsize); - if (shdr->sh_type == SHT_STRTAB && !strcmp(".dynstr", name+shdr->sh_name)) { - dyntab = shdr; - } - } - if (!dyntab) { - exit(10); - } - - char *dynname; - Elf64_Dyn *dent; - dynname = elf + dyntab->sh_offset; - - for (dent = (Elf64_Dyn *)(elf + dynsect->sh_offset); dent->d_tag != DT_NULL; dent++) { - if (dent->d_tag == DT_SONAME) { - char *soname = dynname + dent->d_un.d_val; - sqlite3_prepare_v2(db, "insert into elflibraries (file,soname) values (?,?)",-1, &ifile, 0); - sqlite3_bind_text(ifile,1,hash,64,SQLITE_STATIC); - sqlite3_bind_text(ifile,2,soname,-1,SQLITE_STATIC); - rc = sqlite3_step(ifile); - if (rc != SQLITE_DONE) { - SQLERROR(sqlite3_errmsg(db)); - sqlite3_finalize(ifile); - fprintf(stderr, "error setting library soname\n"); - return 0; - } + char *soname = libelf_soname(content); + if (soname) { + + sqlite3_prepare_v2(db, "insert into elflibraries (file,soname) values (?,?)",-1, &ifile, 0); + sqlite3_bind_text(ifile,1,hash,64,SQLITE_STATIC); + sqlite3_bind_text(ifile,2,soname,-1,SQLITE_STATIC); + rc = sqlite3_step(ifile); + if (rc != SQLITE_DONE) { + SQLERROR(sqlite3_errmsg(db)); sqlite3_finalize(ifile); + fprintf(stderr, "error setting library soname\n"); + return 0; } + sqlite3_finalize(ifile); + } else { + fprintf(stderr, "can't find soname\n"); } }