14 #define SIZEOF_VOID_P 4
15 #if SIZEOF_VOID_P == 8
16 typedef Elf64_Ehdr Elf_Ehdr;
17 typedef Elf64_Shdr Elf_Shdr;
18 #elif SIZEOF_VOID_P == 4
19 typedef Elf32_Ehdr Elf_Ehdr;
20 typedef Elf32_Shdr Elf_Shdr;
22 #error "Unknown void* size"
25 static size_t fsize(int fd)
32 static void *mmap_file(const char *filepath, size_t * len)
34 int fd = open(filepath, O_RDONLY);
38 void *mem = mmap(NULL, *len, PROT_READ, MAP_PRIVATE, fd, 0);
40 return mem == MAP_FAILED ? NULL : mem;
43 static const Elf_Shdr *elf_find_debug_header(const void *obj)
45 const Elf_Ehdr *elf_header = obj;
46 const Elf_Shdr *section_table = obj + elf_header->e_shoff;
47 const Elf_Shdr *string_entry = section_table + elf_header->e_shstrndx;
48 const char *string_section = obj + string_entry->sh_offset;
51 for (index = 0; index != elf_header->e_shnum; ++index) {
52 const Elf_Shdr *entry = section_table + index;
53 if (!strcmp(".debug_str", string_section + entry->sh_name))
59 static int read_elf_header(Elf_Ehdr * header, const char *filepath)
61 int fd = open(filepath, O_RDONLY);
64 bool read_failed = read(fd, header, sizeof(*header)) != sizeof(*header);
66 return read_failed ? -EIO : 0;
69 static int elf_type(const char *filepath)
72 int err = read_elf_header(&header, filepath);
73 return err ? err : header.e_type;
76 uint32_t get_binary_type(const char *path)
78 int type = elf_type(path);
82 return BINARY_TYPE_PIE;
84 return BINARY_TYPE_NO_PIE;
86 return BINARY_TYPE_UNKNOWN;
90 static int is_like_absolute_path(const char *str)
94 if (isupper(*str) && str[1] == ':' && str[2] == '\\')
99 void get_build_dir(char builddir[PATH_MAX], const char *filename)
102 void *filemem = mmap_file(filename, &len);
104 const Elf_Shdr *debug_header = elf_find_debug_header(filemem);
106 const char *debug_section =
107 filemem + debug_header->sh_offset;
108 const char *debug_section_end =
109 debug_section + debug_header->sh_size;
110 const char *p = debug_section;
111 /* `is_like_absolute_path' checks three chars forward. */
112 while (p < debug_section_end - 3) {
113 if (is_like_absolute_path(p)) {
114 snprintf(builddir, PATH_MAX, "%s", p);
117 p = 1 + memchr(p, '\0', debug_section_end - p);
120 munmap(filemem, len);