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