]> pd.if.org Git - zpackage/commitdiff
add libelf_soneed function
authorNathan Wagner <nw@hydaspes.if.org>
Sun, 15 Apr 2018 05:45:53 +0000 (05:45 +0000)
committerNathan Wagner <nw@hydaspes.if.org>
Sun, 15 Apr 2018 05:45:53 +0000 (05:45 +0000)
elf/elf.h
elf/libelf.c
lib/zpm.c

index 60d26aac239a418c7593522acffac3a3df15c543..e316a6e4fe57d9dcc09167e8e34c7b0302345d96 100644 (file)
--- 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
index 477344fa76729b0e6bdad1750df2733a470fcd74..063eefa74a9f9256897931ec0d4fae2603f87bea 100644 (file)
@@ -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;
+}
index f0ae5a2a3d2fcf4ab0045f8c4e03e9870875cb05..30ec7a669cae61ae2f8e50c2cb43f2c4f7b427b4 100644 (file)
--- 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");
                        }
                }