From: Nathan Wagner Date: Sat, 26 Dec 2015 19:50:37 +0000 (+0000) Subject: add soname program X-Git-Tag: v0.1.6~210 X-Git-Url: https://pd.if.org/git/?p=zpackage;a=commitdiff_plain;h=a7fc9d1dda7e3d2155b78587c4b1393f15a0ffb4 add soname program --- diff --git a/Makefile b/Makefile index 195aca3..5972c35 100644 --- 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 index 0000000..9977015 --- /dev/null +++ b/elf/soname.c @@ -0,0 +1,105 @@ +#define _POSIX_C_SOURCE 200112L +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +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; +}