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