Add default Smack manifest for chrpath.spec
[external/chrpath.git] / elf.c
1
2 #ifdef HAVE_CONFIG_H
3 #  include "config.h"
4 #endif
5
6 #include <elf.h>
7 #if defined(HAVE_SYS_LINK_H)
8 #  include <sys/link.h> /* Find DT_RPATH on Solaris 2.6 */
9 #endif /*  HAVE_SYS_LINK_H */
10 #include <stdio.h>
11 #include <string.h>
12 #include <unistd.h>
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <errno.h>
16 #include <fcntl.h>
17 #include "protos.h"
18
19 int
20 elf_open(const char *filename, int flags, Elf_Ehdr *ehdr)
21 {
22    int fd;
23
24    fd = open(filename, flags);
25    if (fd == -1)
26    {
27      perror ("open");
28      return -1;
29    }
30
31    if (read(fd, ehdr, sizeof(*ehdr)) != sizeof(*ehdr))
32    {
33      perror ("reading header");
34      close(fd);
35      return -1;
36    }
37
38    if (0 != memcmp(ehdr->e_ident, ELFMAG, SELFMAG) ||
39        ehdr->e_ident[EI_CLASS] != ELFCLASS ||
40        ehdr->e_ident[EI_DATA] != ELFDATA2 ||
41        ehdr->e_ident[EI_VERSION] != EV_CURRENT)
42    {
43      fprintf(stderr,
44 #ifdef WORDS_BIGENDIAN
45              "`%s' probably isn't a %d-bit MSB-first ELF file.\n",
46 #else /* not WORD_BIGENDIAN */
47              "`%s' probably isn't a %d-bit LSB-first ELF file.\n",
48 #endif /* not WORD_BIGENDIAN */
49              filename, SIZEOF_VOID_P * 8);
50      close(fd);
51      errno = ENOEXEC; /* Hm, is this the best errno code to use? */
52      return -1;
53    }
54
55    if (ehdr->e_phentsize != sizeof(Elf_Phdr))
56    {
57      fprintf(stderr, "section size was read as %d, not %d!\n",
58             ehdr->e_phentsize, sizeof(Elf_Phdr));
59      close(fd);
60      return -1;
61    }
62    return fd;
63 }
64
65 int
66 elf_find_dynamic_section(int fd, Elf_Ehdr *ehdr, Elf_Phdr *phdr)
67 {
68   int i;
69   if (lseek(fd, ehdr->e_phoff, SEEK_SET) == -1)
70   {
71     perror ("positioning for sections");
72     return 1;
73   }
74
75   for (i = 0; i < ehdr->e_phnum; i++)
76   {
77     if (read(fd, phdr, sizeof(*phdr)) != sizeof(*phdr))
78     {
79       perror ("reading section header");
80       return 1;
81     }
82     if (phdr->p_type == PT_DYNAMIC)
83       break;
84   }
85   if (i == ehdr->e_phnum)
86     {
87       fprintf (stderr, "No dynamic section found.\n");
88       return 2;
89     }
90
91   if (0 == phdr->p_filesz)
92     {
93       fprintf (stderr, "Length of dynamic section is zero.\n");
94       return 3;
95     }
96
97   return 0;
98 }
99
100 void
101 elf_close(int fd)
102 {
103   close(fd);
104 }
105
106 const char *
107 elf_tagname(int tag)
108 {
109   switch (tag) {
110   case DT_RPATH:
111     return "RPATH";
112     break;
113 #if defined(DT_RUNPATH)
114   case DT_RUNPATH:
115     return "RUNPATH";
116     break;
117 #endif /* DT_RUNPATH */
118   }
119   return "UNKNOWN";
120 }
121
122 int
123 elf_dynpath_tag(int tag)
124 {
125   return ( tag == DT_RPATH
126 #if defined(DT_RUNPATH)
127            || tag == DT_RUNPATH
128 #endif /* DT_RUNPATH */
129            );
130 }