]> pd.if.org Git - zpackage/blob - elf/soname.c
add soname program
[zpackage] / elf / soname.c
1 #define _POSIX_C_SOURCE 200112L
2 #include <sys/types.h>
3 #include <sys/stat.h>
4 #include <sys/mman.h>
5 #include <fcntl.h>
6 #include <unistd.h>
7 #include <limits.h>
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <elf.h>
13
14 int main(int ac, char **av) {
15         void *elfbase;
16         int elffd, i;
17         struct stat sbuf;
18         Elf64_Ehdr *hdr;
19         Elf64_Shdr *shdr;
20         Elf64_Shdr *dynsect = 0;
21         Elf64_Shdr *strtab = 0, *dyntab = 0;
22         char *name, *dynname;
23         Elf64_Dyn *dent;
24
25         elffd = open(av[1], O_RDONLY);
26         if (elffd == -1) {
27                 exit(1);
28         }
29         if (fstat(elffd, &sbuf) == -1) {
30                 exit(1);
31         }
32
33         elfbase = mmap(0, sbuf.st_size, PROT_READ,MAP_PRIVATE, elffd, 0);
34         if (!elfbase) {
35                 exit(2);
36         }
37
38         hdr = elfbase;
39         if (hdr->e_ident[EI_MAG0] != ELFMAG0
40                         || hdr->e_ident[EI_MAG1] != ELFMAG1
41                         || hdr->e_ident[EI_MAG2] != ELFMAG2
42                         || hdr->e_ident[EI_MAG3] != ELFMAG3
43            ) {
44                 exit(3);
45         }
46
47         /* only dynamic files will have an soname */
48         if (hdr->e_type != ET_DYN) {
49                 exit(4);
50         }
51         
52         switch (hdr->e_ident[EI_CLASS]) {
53                 case ELFCLASS64:
54                 case ELFCLASS32:
55                 case ELFCLASSNONE:
56                         break;
57                 default:
58                         exit(5);
59         }
60
61         /* check endian ness */
62         switch (hdr->e_ident[EI_DATA]) {
63                 case ELFDATA2LSB: break;
64                 case ELFDATA2MSB: break;
65                 default:
66                         exit(6);
67         }
68
69         /* find the section header table */
70         for (i = 0; i < hdr->e_shnum; i++) {
71                 shdr = (Elf64_Shdr *)((char *)elfbase + hdr->e_shoff + i * hdr->e_shentsize);
72                 if (shdr->sh_type == SHT_DYNAMIC) {
73                         dynsect = shdr;
74                 } else if (shdr->sh_type == SHT_STRTAB && i == hdr->e_shstrndx) {
75                         strtab = shdr;
76                 }
77         }
78         if (!strtab) {
79                 exit(8);
80         }
81         if (!dynsect) {
82                 exit(9);
83         }
84
85         name = (char *) elfbase + strtab->sh_offset;
86         for (i = 0; i < hdr->e_shnum; i++) {
87                 shdr = (Elf64_Shdr *)((char *)elfbase + hdr->e_shoff + i * hdr->e_shentsize);
88                 if (shdr->sh_type == SHT_STRTAB && !strcmp(".dynstr", name+shdr->sh_name)) {
89                         dyntab = shdr;
90                 }
91         }
92         if (!dyntab) {
93                 exit(10);
94         }
95
96         dynname = (char *) elfbase + dyntab->sh_offset;
97         for (dent = (Elf64_Dyn *)((char *)elfbase + dynsect->sh_offset); dent->d_tag != DT_NULL; dent++) {
98                 if (dent->d_tag == DT_SONAME) {
99                         printf("%s\n", dynname + dent->d_un.d_val);
100                         break;
101                 }
102         }
103
104         return 0;
105 }