4 * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
8 * Cherepanov Vitaliy <v.cherepanov@samsung.com>
9 * Dmitry Bogatov <d.bogatov@samsung.com>
10 * Nikita Kalyazin <n.kalyazin@samsung.com>
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
16 * http://www.apache.org/licenses/LICENSE-2.0
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
25 * - Samsung RnD Institute Russia
31 #include <sys/types.h>
43 #define SIZEOF_VOID_P 4
44 #if SIZEOF_VOID_P == 8
45 typedef Elf64_Ehdr Elf_Ehdr;
46 typedef Elf64_Shdr Elf_Shdr;
47 #elif SIZEOF_VOID_P == 4
48 typedef Elf32_Ehdr Elf_Ehdr;
49 typedef Elf32_Shdr Elf_Shdr;
51 #error "Unknown void* size"
54 static size_t fsize(int fd)
61 static void *mmap_file(const char *filepath, size_t * len)
63 int fd = open(filepath, O_RDONLY);
67 void *mem = mmap(NULL, *len, PROT_READ, MAP_PRIVATE, fd, 0);
69 return mem == MAP_FAILED ? NULL : mem;
72 static const Elf_Shdr *elf_find_debug_header(const void *obj)
74 const Elf_Ehdr *elf_header = obj;
75 const Elf_Shdr *section_table = obj + elf_header->e_shoff;
76 const Elf_Shdr *string_entry = section_table + elf_header->e_shstrndx;
77 const char *string_section = obj + string_entry->sh_offset;
80 for (index = 0; index != elf_header->e_shnum; ++index) {
81 const Elf_Shdr *entry = section_table + index;
82 if (!strcmp(".debug_str", string_section + entry->sh_name))
88 static int read_elf_header(Elf_Ehdr * header, const char *filepath)
90 int fd = open(filepath, O_RDONLY);
93 bool read_failed = read(fd, header, sizeof(*header)) != sizeof(*header);
95 return read_failed ? -EIO : 0;
98 static int elf_type(const char *filepath)
101 int err = read_elf_header(&header, filepath);
102 return err ? err : header.e_type;
105 uint32_t get_binary_type(const char *path)
107 int type = elf_type(path);
111 return BINARY_TYPE_PIE;
113 return BINARY_TYPE_NO_PIE;
115 return BINARY_TYPE_UNKNOWN;
119 static int is_like_absolute_path(const char *str)
123 if (isupper(*str) && str[1] == ':' && str[2] == '\\')
128 static bool exist(const char *filename)
131 return stat(filename, &decoy) == 0;
134 static void suffix_filename(char buf[PATH_MAX], const char *filename)
136 char adj_filename[PATH_MAX];
137 sprintf(adj_filename, "%s.exe", filename);
138 const char *use_filename = exist(adj_filename) ? adj_filename
140 strcpy(buf, use_filename);
143 void get_build_dir(char builddir[PATH_MAX], const char *filename)
147 char adj_filename[PATH_MAX];
148 suffix_filename(adj_filename, filename);
150 filemem = mmap_file(adj_filename, &len);
152 const Elf_Shdr *debug_header = elf_find_debug_header(filemem);
154 const char *debug_section =
155 filemem + debug_header->sh_offset;
156 const char *debug_section_end =
157 debug_section + debug_header->sh_size;
158 const char *p = debug_section;
159 /* `is_like_absolute_path' checks three chars forward. */
160 while (p < debug_section_end - 3) {
161 if (is_like_absolute_path(p)) {
162 snprintf(builddir, PATH_MAX, "%s", p);
165 p = 1 + memchr(p, '\0', debug_section_end - p);
168 munmap(filemem, len);