]> pd.if.org Git - zpackage/blob - elf/soname.c
added file type tests for soname
[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         if (lstat(av[1], &sbuf) == -1) {
26                 exit(1);
27         }
28         if (!S_ISREG(sbuf.st_mode)) {
29                 exit(1);
30         }
31
32         elffd = open(av[1], O_RDONLY);
33         if (elffd == -1) {
34                 exit(1);
35         }
36         if (fstat(elffd, &sbuf) == -1) {
37                 exit(1);
38         }
39         if (!S_ISREG(sbuf.st_mode)) {
40                 exit(1);
41         }
42
43         elfbase = mmap(0, sbuf.st_size, PROT_READ,MAP_PRIVATE, elffd, 0);
44         if (!elfbase) {
45                 exit(2);
46         }
47
48         hdr = elfbase;
49         if (hdr->e_ident[EI_MAG0] != ELFMAG0
50                         || hdr->e_ident[EI_MAG1] != ELFMAG1
51                         || hdr->e_ident[EI_MAG2] != ELFMAG2
52                         || hdr->e_ident[EI_MAG3] != ELFMAG3
53            ) {
54                 exit(3);
55         }
56
57         /* only dynamic files will have an soname */
58         if (hdr->e_type != ET_DYN) {
59                 exit(4);
60         }
61         
62         switch (hdr->e_ident[EI_CLASS]) {
63                 case ELFCLASS64:
64                 case ELFCLASS32:
65                 case ELFCLASSNONE:
66                         break;
67                 default:
68                         exit(5);
69         }
70
71         /* check endian ness */
72         switch (hdr->e_ident[EI_DATA]) {
73                 case ELFDATA2LSB: break;
74                 case ELFDATA2MSB: break;
75                 default:
76                         exit(6);
77         }
78
79         /* find the section header table */
80         for (i = 0; i < hdr->e_shnum; i++) {
81                 shdr = (Elf64_Shdr *)((char *)elfbase + hdr->e_shoff + i * hdr->e_shentsize);
82                 if (shdr->sh_type == SHT_DYNAMIC) {
83                         dynsect = shdr;
84                 } else if (shdr->sh_type == SHT_STRTAB && i == hdr->e_shstrndx) {
85                         strtab = shdr;
86                 }
87         }
88         if (!strtab) {
89                 exit(8);
90         }
91         if (!dynsect) {
92                 exit(9);
93         }
94
95         name = (char *) elfbase + strtab->sh_offset;
96         for (i = 0; i < hdr->e_shnum; i++) {
97                 shdr = (Elf64_Shdr *)((char *)elfbase + hdr->e_shoff + i * hdr->e_shentsize);
98                 if (shdr->sh_type == SHT_STRTAB && !strcmp(".dynstr", name+shdr->sh_name)) {
99                         dyntab = shdr;
100                 }
101         }
102         if (!dyntab) {
103                 exit(10);
104         }
105
106         dynname = (char *) elfbase + dyntab->sh_offset;
107         for (dent = (Elf64_Dyn *)((char *)elfbase + dynsect->sh_offset); dent->d_tag != DT_NULL; dent++) {
108                 if (dent->d_tag == DT_SONAME) {
109                         printf("%s\n", dynname + dent->d_un.d_val);
110                         break;
111                 }
112         }
113
114         return 0;
115 }