]> pd.if.org Git - zpackage/commitdiff
add soname program
authorNathan Wagner <nw@hydaspes.if.org>
Sat, 26 Dec 2015 19:50:37 +0000 (19:50 +0000)
committerNathan Wagner <nw@hydaspes.if.org>
Sat, 26 Dec 2015 19:50:37 +0000 (19:50 +0000)
Makefile
elf/soname.c [new file with mode: 0644]

index 195aca3a7faf0495c5f0fc6abf86f16410d1b363..5972c352785dbf238ee32ec0624b83a24b6d8a84 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -3,6 +3,9 @@ CFLAGS=-Wall -std=c99
 elftype: elf/elftype.c
        $(CC) $(CFLAGS) -o $@ $+
 
+soname: elf/soname.c
+       $(CC) $(CFLAGS) -o $@ $+
+
 install: elftype
        install -D zpm $(DESTDIR)/bin/zpm
        install -D zpm-note $(DESTDIR)/bin/zpm-note
diff --git a/elf/soname.c b/elf/soname.c
new file mode 100644 (file)
index 0000000..9977015
--- /dev/null
@@ -0,0 +1,105 @@
+#define _POSIX_C_SOURCE 200112L
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <limits.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <elf.h>
+
+int main(int ac, char **av) {
+       void *elfbase;
+       int elffd, i;
+       struct stat sbuf;
+       Elf64_Ehdr *hdr;
+       Elf64_Shdr *shdr;
+       Elf64_Shdr *dynsect = 0;
+       Elf64_Shdr *strtab = 0, *dyntab = 0;
+       char *name, *dynname;
+       Elf64_Dyn *dent;
+
+       elffd = open(av[1], O_RDONLY);
+       if (elffd == -1) {
+               exit(1);
+       }
+       if (fstat(elffd, &sbuf) == -1) {
+               exit(1);
+       }
+
+       elfbase = mmap(0, sbuf.st_size, PROT_READ,MAP_PRIVATE, elffd, 0);
+       if (!elfbase) {
+               exit(2);
+       }
+
+       hdr = elfbase;
+       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
+          ) {
+               exit(3);
+       }
+
+       /* only dynamic files will have an soname */
+       if (hdr->e_type != ET_DYN) {
+               exit(4);
+       }
+       
+       switch (hdr->e_ident[EI_CLASS]) {
+               case ELFCLASS64:
+               case ELFCLASS32:
+               case ELFCLASSNONE:
+                       break;
+               default:
+                       exit(5);
+       }
+
+       /* check endian ness */
+       switch (hdr->e_ident[EI_DATA]) {
+               case ELFDATA2LSB: break;
+               case ELFDATA2MSB: break;
+               default:
+                       exit(6);
+       }
+
+       /* 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) {
+               exit(8);
+       }
+       if (!dynsect) {
+               exit(9);
+       }
+
+       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) {
+               exit(10);
+       }
+
+       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) {
+                       printf("%s\n", dynname + dent->d_un.d_val);
+                       break;
+               }
+       }
+
+       return 0;
+}