1 /* radare - LGPL - Copyright 2008-2020 - nibble, pancake, alvaro_fe */
2 
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <assert.h>
7 #include <r_types.h>
8 #include <r_util.h>
9 #include "elf.h"
10 
11 #define MIPS_PLT_OFFSET 0x20
12 #define RISCV_PLT_OFFSET 0x20
13 
14 #define RISCV_PLT_ENTRY_SIZE 0x10
15 #define X86_PLT_ENTRY_SIZE 0x10
16 
17 #define SPARC_OFFSET_PLT_ENTRY_FROM_GOT_ADDR -0x6
18 #define X86_OFFSET_PLT_ENTRY_FROM_GOT_ADDR -0x6
19 
20 #define ELF_PAGE_MASK 0xFFFFFFFFFFFFF000LL
21 #define ELF_PAGE_SIZE 12
22 
23 #define R_ELF_NO_RELRO 0
24 #define R_ELF_PART_RELRO 1
25 #define R_ELF_FULL_RELRO 2
26 
27 #define bprintf if(bin->verbose) R_LOG_WARN
28 
29 #define MAX_REL_RELA_SZ (sizeof (Elf_(Rel)) > sizeof (Elf_(Rela))? sizeof (Elf_(Rel)): sizeof (Elf_(Rela)))
30 
31 #define READ8(x, i) r_read_ble8((x) + (i)); (i) += 1
32 #define READ16(x, i) r_read_ble16((x) + (i), bin->endian); (i) += 2
33 #define READ32(x, i) r_read_ble32((x) + (i), bin->endian); (i) += 4
34 #define READ64(x, i) r_read_ble64((x) + (i), bin->endian); (i) += 8
35 
36 #define BREAD8(x, i) r_buf_read_ble8_at (x, i); (i) += 1
37 #define BREAD16(x, i) r_buf_read_ble16_at (x, i, bin->endian); (i) += 2
38 #define BREAD32(x, i) r_buf_read_ble32_at (x, i, bin->endian); (i) += 4
39 #define BREAD64(x, i) r_buf_read_ble64_at (x, i, bin->endian); (i) += 8
40 
41 #define NUMENTRIES_ROUNDUP(sectionsize, entrysize) (((sectionsize) + (entrysize)-1) / (entrysize))
42 #define COMPUTE_PLTGOT_POSITION(rel, pltgot_addr, n_initial_unused_entries) \
43 	((rel->rva - pltgot_addr - n_initial_unused_entries * R_BIN_ELF_WORDSIZE) / R_BIN_ELF_WORDSIZE)
44 
45 #define GROWTH_FACTOR (1.5)
46 
47 #define round_up(a) ((((a) + (4) - (1)) / (4)) * (4))
48 
49 #define EF_MIPS_ABI_O32		0x00001000  /* O32 ABI.  */
50 #define EF_MIPS_ABI_O64		0x00002000  /* O32 extended for 64 bit.  */
51 #define EF_MIPS_ABI			0x0000f000
52 
is_elfclass64(Elf_ (Ehdr)* h)53 static inline bool is_elfclass64(Elf_(Ehdr) *h) {
54 	return h->e_ident[EI_CLASS] == ELFCLASS64;
55 }
56 
is_mips_o32(Elf_ (Ehdr)* h)57 static bool is_mips_o32(Elf_(Ehdr) *h) {
58 	if (h->e_ident[EI_CLASS] != ELFCLASS32) {
59 		return false;
60 	}
61 	if ((h->e_flags & EF_MIPS_ABI2) != 0) {
62 		return false;
63 	}
64 	if (((h->e_flags & EF_MIPS_ABI) != 0) &&
65 		((h->e_flags & EF_MIPS_ABI) != EF_MIPS_ABI_O32)) {
66 		return false;
67 	}
68 	return true;
69 }
70 
is_mips_n32(Elf_ (Ehdr)* h)71 static bool is_mips_n32(Elf_(Ehdr) *h) {
72 	if (h->e_ident[EI_CLASS] != ELFCLASS32) {
73 		return false;
74 	}
75 	if (((h->e_flags & EF_MIPS_ABI2) == 0) ||
76 		((h->e_flags & EF_MIPS_ABI) != 0)) {
77 		return false;
78 	}
79 	return true;
80 }
81 
82 enum {
83 	X86,
84 	X86_64,
85 	ARM,
86 	AARCH64,
87 	RCE,
88 	ARCH_LEN
89 };
90 
91 typedef struct reginfo {
92 	ut32 regsize;
93 	ut32 regdelta;
94 } reginfo_t;
95 
96 static reginfo_t reginf[ARCH_LEN] = {
97 	{ 160, 0x5c },
98 	{ 216, 0x84 },
99 	{ 72, 0x5c },
100 	{ 272, 0x84 },
101 	{ 272, 0x84 }
102 };
103 
__strnlen(const char * str,int len)104 static inline int __strnlen(const char *str, int len) {
105 	int l = 0;
106 	while (IS_PRINTABLE (*str) && --len) {
107 		if (((ut8)*str) == 0xff) {
108 			break;
109 		}
110 		str++;
111 		l++;
112 	}
113 	return l + 1;
114 }
115 
is_bin_etrel(ELFOBJ * bin)116 static bool is_bin_etrel(ELFOBJ *bin) {
117 	return bin->ehdr.e_type == ET_REL;
118 }
119 
__is_valid_ident(ELFOBJ * bin)120 static bool __is_valid_ident(ELFOBJ *bin) {
121 	return !strncmp ((char *)bin->ehdr.e_ident, ELFMAG, SELFMAG) ||
122 		!strncmp ((char *)bin->ehdr.e_ident, CGCMAG, SCGCMAG);
123 }
124 
init_ehdr(ELFOBJ * bin)125 static bool init_ehdr(ELFOBJ *bin) {
126 	ut8 e_ident[EI_NIDENT];
127 	ut8 ehdr[sizeof (Elf_(Ehdr))] = { 0 };
128 	int i, len;
129 	if (r_buf_read_at (bin->b, 0, e_ident, EI_NIDENT) == -1) {
130 		bprintf ("read (magic)\n");
131 		return false;
132 	}
133 	sdb_set (bin->kv, "elf_type.cparse", "enum elf_type { ET_NONE=0, ET_REL=1,"
134 			" ET_EXEC=2, ET_DYN=3, ET_CORE=4, ET_LOOS=0xfe00, ET_HIOS=0xfeff,"
135 			" ET_LOPROC=0xff00, ET_HIPROC=0xffff };", 0);
136 	sdb_set (bin->kv, "elf_machine.cparse", "enum elf_machine {EM_NONE=0, EM_M32=1,"
137 			" EM_SPARC=2, EM_386=3, EM_68K=4, EM_88K=5, EM_IAMCU=6, EM_860=7, EM_MIPS=8,"
138 			" EM_S370=9, EM_MIPS_RS3_LE=10, EM_RS6000=11, EM_PARISC=15, EM_nCUBE=16,"
139 			" EM_VPP500=17, EM_SPARC32PLUS=18, EM_960=19, EM_PPC=20, EM_PPC64=21, EM_S390=22,"
140 			" EM_SPU=23, EM_V800=36, EM_FR20=37, EM_RH32=38, EM_RCE=39, EM_ARM=40,"
141 			" EM_ALPHA=41, EM_SH=42, EM_SPARCV9=43, EM_TRICORE=44, EM_ARC=45, EM_H8_300=46,"
142 			" EM_H8_300H=47, EM_H8S=48, EM_H8_500=49, EM_IA_64=50, EM_MIPS_X=51,"
143 			" EM_COLDFIRE=52, EM_68HC12=53, EM_MMA=54, EM_PCP=55, EM_NCPU=56, EM_NDR1=57,"
144 			" EM_STARCORE=58, EM_ME16=59, EM_ST100=60, EM_TINYJ=61, EM_X86_64=62, EM_PDSP=63,"
145 			" EM_PDP10=64, EM_PDP11=65, EM_FX66=66, EM_ST9PLUS=67, EM_ST7=68, EM_68HC16=69,"
146 			" EM_68HC11=70, EM_68HC08=71, EM_68HC05=72, EM_SVX=73, EM_ST19=74, EM_VAX=75,"
147 			" EM_CRIS=76, EM_JAVELIN=77, EM_FIREPATH=78, EM_ZSP=79, EM_MMIX=80, EM_HUANY=81,"
148 			" EM_PRISM=82, EM_AVR=83, EM_FR30=84, EM_D10V=85, EM_D30V=86, EM_V850=87,"
149 			" EM_M32R=88, EM_MN10300=89, EM_MN10200=90, EM_PJ=91, EM_OPENRISC=92,"
150 			" EM_ARC_COMPACT=93, EM_XTENSA=94, EM_VIDEOCORE=95, EM_TMM_GPP=96, EM_NS32K=97,"
151 			" EM_TPC=98, EM_SNP1K=99, EM_ST200=100, EM_IP2K=101, EM_MAX=102, EM_CR=103,"
152 			" EM_F2MC16=104, EM_MSP430=105, EM_BLACKFIN=106, EM_SE_C33=107, EM_SEP=108,"
153 			" EM_ARCA=109, EM_UNICORE=110, EM_EXCESS=111, EM_DXP=112, EM_ALTERA_NIOS2=113,"
154 			" EM_CRX=114, EM_XGATE=115, EM_C166=116, EM_M16C=117, EM_DSPIC30F=118, EM_CE=119,"
155 			" EM_M32C=120, EM_TSK3000=131, EM_RS08=132, EM_SHARC=133, EM_ECOG2=134,"
156 			" EM_SCORE7=135, EM_DSP24=136, EM_VIDEOCORE3=137, EM_LATTICEMICO32=138,"
157 			" EM_SE_C17=139, EM_TI_C6000=140, EM_TI_C2000=141, EM_TI_C5500=142,"
158 			" EM_TI_ARP32=143, EM_TI_PRU=144,"
159 			" EM_MMDSP_PLUS=160, EM_CYPRESS_M8C=161, EM_R32C=162, EM_TRIMEDIA=163,"
160 			" EM_QDSP6=164, EM_8051=165, EM_STXP7X=166, EM_NDS32=167,"
161 			" EM_ECOG1X=168, EM_MAXQ30=169, EM_XIMO16=170, EM_MANIK=171, EM_CRAYNV2=172,"
162 			" EM_RX=173, EM_METAG=174, EM_MCST_ELBRUS=175, EM_ECOG16=176, EM_CR16=177,"
163 			" EM_ETPU=178, EM_SLE9X=179, EM_L10M=180, EM_K10M=181, EM_AARCH64=183,"
164 			" EM_AVR32=185, EM_STM8=186, EM_TILE64=187, EM_TILEPRO=188, EM_CUDA=190,"
165 			" EM_TILEGX=191, EM_CLOUDSHIELD=192, EM_COREA_1ST=193, EM_COREA_2ND=194,"
166 			" EM_ARC_COMPACT2=195, EM_OPEN8=196, EM_RL78=197, EM_VIDEOCORE5=198,"
167 			" EM_78KOR=199, EM_56800EX=200, EM_BA1=201, EM_BA2=202, EM_XCORE=203,"
168 			" EM_MCHP_PIC=204, EM_INTEL205=205, EM_INTEL206=206, EM_INTEL207=207,"
169 			" EM_INTEL208=208, EM_INTEL209=209, EM_KM32=210, EM_KMX32=211, EM_KMX16=212,"
170 			" EM_KMX8=213, EM_KVARC=214, EM_CDP=215, EM_COGE=216, EM_COOL=217, EM_NORC=218,"
171 			" EM_CSR_KALIMBA=219, EM_AMDGPU=224, EM_RISCV=243, EM_LANAI=244, EM_BPF=247,"
172 			" EM_CSKY=252}", 0);
173 	sdb_set (bin->kv, "elf_class.cparse", "enum elf_class {ELFCLASSNONE=0, ELFCLASS32=1, ELFCLASS64=2};", 0);
174 	sdb_set (bin->kv, "elf_data.cparse", "enum elf_data {ELFDATANONE=0, ELFDATA2LSB=1, ELFDATA2MSB=2};", 0);
175 	sdb_set (bin->kv, "elf_hdr_version.cparse", "enum elf_hdr_version {EV_NONE=0, EV_CURRENT=1};", 0);
176 	sdb_set (bin->kv, "elf_obj_version.cparse", "enum elf_obj_version {EV_NONE=0, EV_CURRENT=1};", 0);
177 	sdb_num_set (bin->kv, "elf_header.offset", 0, 0);
178 	sdb_num_set (bin->kv, "elf_header.size", sizeof (Elf_(Ehdr)), 0);
179 	sdb_set (bin->kv, "elf_ident.format", "[4]z[1]E[1]E[1]E.::"
180 	         " magic (elf_class)class (elf_data)data (elf_hdr_version)version", 0);
181 #if R_BIN_ELF64
182 	sdb_set (bin->kv, "elf_header.format", "?[2]E[2]E[4]EqqqxN2N2N2N2N2N2"
183 		" (elf_ident)ident (elf_type)type (elf_machine)machine (elf_obj_version)version"
184 		" entry phoff shoff flags ehsize phentsize phnum shentsize shnum shstrndx", 0);
185 #else
186 	sdb_set (bin->kv, "elf_header.format", "?[2]E[2]E[4]ExxxxN2N2N2N2N2N2"
187 		" (elf_ident)ident (elf_type)type (elf_machine)machine (elf_obj_version)version"
188 		" entry phoff shoff flags ehsize phentsize phnum shentsize shnum shstrndx", 0);
189 #endif
190 	bin->endian = (e_ident[EI_DATA] == ELFDATA2MSB)? 1: 0;
191 	memset (&bin->ehdr, 0, sizeof (Elf_(Ehdr)));
192 	len = r_buf_read_at (bin->b, 0, ehdr, sizeof (ehdr));
193 	if (len < 32) { // tinyelf != sizeof (Elf_(Ehdr))) {
194 		bprintf ("read (ehdr)\n");
195 		return false;
196 	}
197 	// XXX no need to check twice
198 	memcpy (&bin->ehdr.e_ident, ehdr, 16);
199 	if (!__is_valid_ident (bin)) {
200 		return false;
201 	}
202 	i = 16;
203 	// TODO: use r_read or r_buf_read_ apis instead
204 	bin->ehdr.e_type = READ16 (ehdr, i);
205 	bin->ehdr.e_machine = READ16 (ehdr, i);
206 	bin->ehdr.e_version = READ32 (ehdr, i);
207 #if R_BIN_ELF64
208 	bin->ehdr.e_entry = READ64 (ehdr, i);
209 	bin->ehdr.e_phoff = READ64 (ehdr, i);
210 	bin->ehdr.e_shoff = READ64 (ehdr, i);
211 #else
212 	bin->ehdr.e_entry = READ32 (ehdr, i);
213 	bin->ehdr.e_phoff = READ32 (ehdr, i);
214 	bin->ehdr.e_shoff = READ32 (ehdr, i);
215 #endif
216 	bin->ehdr.e_flags = READ32 (ehdr, i);
217 	bin->ehdr.e_ehsize = READ16 (ehdr, i);
218 	bin->ehdr.e_phentsize = READ16 (ehdr, i);
219 	bin->ehdr.e_phnum = READ16 (ehdr, i);
220 	bin->ehdr.e_shentsize = READ16 (ehdr, i);
221 	bin->ehdr.e_shnum = READ16 (ehdr, i);
222 	bin->ehdr.e_shstrndx = READ16 (ehdr, i);
223 	return true;
224 	// [Outdated] Usage example:
225 	// > td `k bin/cur/info/elf_type.cparse`; td `k bin/cur/info/elf_machine.cparse`
226 	// > pf `k bin/cur/info/elf_header.format` @ `k bin/cur/info/elf_header.offset`
227 }
228 
read_phdr(ELFOBJ * bin,bool linux_kernel_hack)229 static bool read_phdr(ELFOBJ *bin, bool linux_kernel_hack) {
230 	bool phdr_found = false;
231 	int i;
232 #if R_BIN_ELF64
233 	const bool is_elf64 = true;
234 #else
235 	const bool is_elf64 = false;
236 #endif
237 	for (i = 0; i < bin->ehdr.e_phnum; i++) {
238 		ut8 phdr[sizeof (Elf_(Phdr))] = { 0 };
239 		int j = 0;
240 		const size_t rsize = bin->ehdr.e_phoff + i * sizeof (Elf_(Phdr));
241 		int len = r_buf_read_at (bin->b, rsize, phdr, sizeof (Elf_(Phdr)));
242 		if (len < 1) {
243 			bprintf ("read (phdr)\n");
244 			R_FREE (bin->phdr);
245 			return false;
246 		}
247 		bin->phdr[i].p_type = READ32 (phdr, j);
248 		if (bin->phdr[i].p_type == PT_PHDR) {
249 			phdr_found = true;
250 		}
251 
252 		if (is_elf64) {
253 			bin->phdr[i].p_flags = READ32 (phdr, j);
254 		}
255 		bin->phdr[i].p_offset = R_BIN_ELF_READWORD (phdr, j);
256 		bin->phdr[i].p_vaddr = R_BIN_ELF_READWORD (phdr, j);
257 		bin->phdr[i].p_paddr = R_BIN_ELF_READWORD (phdr, j);
258 		bin->phdr[i].p_filesz = R_BIN_ELF_READWORD (phdr, j);
259 		bin->phdr[i].p_memsz = R_BIN_ELF_READWORD (phdr, j);
260 		if (!is_elf64) {
261 			bin->phdr[i].p_flags = READ32 (phdr, j);
262 		//	bin->phdr[i].p_flags |= 1; tiny.elf needs this somehow :? LOAD0 is always +x for linux?
263 		}
264 		bin->phdr[i].p_align = R_BIN_ELF_READWORD (phdr, j);
265 	}
266 	/* Here is the where all the fun starts.
267 	 * Linux kernel since 2005 calculates phdr offset wrongly
268 	 * adding it to the load address (va of the LOAD0).
269 	 * See `fs/binfmt_elf.c` file this line:
270 	 *    NEW_AUX_ENT(AT_PHDR, load_addr + exec->e_phoff);
271 	 * So after the first read, we fix the address and read it again
272 	 */
273 	if (linux_kernel_hack && phdr_found) {
274 		ut64 load_addr = Elf_(r_bin_elf_get_baddr) (bin);
275 		bin->ehdr.e_phoff = Elf_(r_bin_elf_v2p) (bin, load_addr + bin->ehdr.e_phoff);
276 		return read_phdr (bin, false);
277 	}
278 	return true;
279 }
280 
init_phdr(ELFOBJ * bin)281 static int init_phdr(ELFOBJ *bin) {
282 	ut32 phdr_size;
283 
284 	r_return_val_if_fail (!bin->phdr, false);
285 
286 	if (!bin->ehdr.e_phnum) {
287 		return false;
288 	}
289 	if (!UT32_MUL (&phdr_size, (ut32)bin->ehdr.e_phnum, sizeof (Elf_(Phdr)))) {
290 		return false;
291 	}
292 	if (!phdr_size) {
293 		return false;
294 	}
295 	if (phdr_size > bin->size) {
296 		return false;
297 	}
298 	if (phdr_size > (ut32)bin->size) {
299 		return false;
300 	}
301 	if (bin->ehdr.e_phoff > bin->size) {
302 		return false;
303 	}
304 	if (bin->ehdr.e_phoff + phdr_size > bin->size) {
305 		return false;
306 	}
307 	if (!(bin->phdr = R_NEWS0 (Elf_(Phdr), bin->ehdr.e_phnum))) {
308 		perror ("malloc (phdr)");
309 		return false;
310 	}
311 
312 	bool linux_kern_hack = false;
313 	/* Enable this hack only for the X86 64bit ELFs */
314 	const int _128K = 1024 * 128;
315 	if (r_buf_size (bin->b) > _128K && (bin->ehdr.e_machine == EM_X86_64 || bin->ehdr.e_machine == EM_386)) {
316 		linux_kern_hack = true;
317 	}
318 	if (!read_phdr (bin, linux_kern_hack)) {
319 		return false;
320 	}
321 
322 	sdb_num_set (bin->kv, "elf_phdr.offset", bin->ehdr.e_phoff, 0);
323 	sdb_num_set (bin->kv, "elf_phdr.size", sizeof (Elf_(Phdr)), 0);
324 	sdb_set (bin->kv, "elf_p_type.cparse", "enum elf_p_type {PT_NULL=0,PT_LOAD=1,PT_DYNAMIC=2,"
325 		"PT_INTERP=3,PT_NOTE=4,PT_SHLIB=5,PT_PHDR=6,PT_LOOS=0x60000000,"
326 		"PT_HIOS=0x6fffffff,PT_LOPROC=0x70000000,PT_HIPROC=0x7fffffff};",
327 		0);
328 	sdb_set (bin->kv, "elf_p_flags.cparse", "enum elf_p_flags {PF_None=0,PF_Exec=1,"
329 			"PF_Write=2,PF_Write_Exec=3,PF_Read=4,PF_Read_Exec=5,PF_Read_Write=6,"
330 			"PF_Read_Write_Exec=7};", 0);
331 #if R_BIN_ELF64
332 	sdb_set (bin->kv, "elf_phdr.format", "[4]E[4]Eqqqqqq (elf_p_type)type (elf_p_flags)flags"
333 			" offset vaddr paddr filesz memsz align", 0);
334 #else
335 	sdb_set (bin->kv, "elf_phdr.format", "[4]Exxxxx[4]Ex (elf_p_type)type offset vaddr paddr"
336 			" filesz memsz (elf_p_flags)flags align", 0);
337 #endif
338 	return true;
339 	// Usage example:
340 	// > td `k bin/cur/info/elf_p_type.cparse`; td `k bin/cur/info/elf_p_flags.cparse`
341 	// > pf `k bin/cur/info/elf_phdr.format` @ `k bin/cur/info/elf_phdr.offset`
342 }
343 
init_shdr(ELFOBJ * bin)344 static int init_shdr(ELFOBJ *bin) {
345 	ut32 shdr_size;
346 	ut8 shdr[sizeof (Elf_(Shdr))] = { 0 };
347 	int i, j, len;
348 
349 	r_return_val_if_fail (bin && !bin->shdr, false);
350 
351 	if (!UT32_MUL (&shdr_size, bin->ehdr.e_shnum, sizeof (Elf_(Shdr)))) {
352 		return false;
353 	}
354 	if (shdr_size < 1) {
355 		return false;
356 	}
357 	if (shdr_size > bin->size) {
358 		return false;
359 	}
360 	if (bin->ehdr.e_shoff > bin->size) {
361 		return false;
362 	}
363 	if (bin->ehdr.e_shoff + shdr_size > bin->size) {
364 		return false;
365 	}
366 	if (!(bin->shdr = R_NEWS0 (Elf_(Shdr), bin->ehdr.e_shnum))) {
367 		perror ("malloc (shdr)");
368 		return false;
369 	}
370 	sdb_num_set (bin->kv, "elf_shdr.offset", bin->ehdr.e_shoff, 0);
371 	sdb_num_set (bin->kv, "elf_shdr.size", sizeof (Elf_(Shdr)), 0);
372 	sdb_set (bin->kv, "elf_s_type.cparse", "enum elf_s_type {SHT_NULL=0,SHT_PROGBITS=1,"
373 			"SHT_SYMTAB=2,SHT_STRTAB=3,SHT_RELA=4,SHT_HASH=5,SHT_DYNAMIC=6,SHT_NOTE=7,"
374 			"SHT_NOBITS=8,SHT_REL=9,SHT_SHLIB=10,SHT_DYNSYM=11,SHT_LOOS=0x60000000,"
375 			"SHT_HIOS=0x6fffffff,SHT_LOPROC=0x70000000,SHT_HIPROC=0x7fffffff};", 0);
376 
377 	for (i = 0; i < bin->ehdr.e_shnum; i++) {
378 		j = 0;
379 		len = r_buf_read_at (bin->b, bin->ehdr.e_shoff + i * sizeof (Elf_(Shdr)), shdr, sizeof (Elf_(Shdr)));
380 		if (len < 1) {
381 			bprintf ("read (shdr) at 0x%" PFMT64x "\n", (ut64) bin->ehdr.e_shoff);
382 			R_FREE (bin->shdr);
383 			return false;
384 		}
385 		bin->shdr[i].sh_name = READ32 (shdr, j);
386 		bin->shdr[i].sh_type = READ32 (shdr, j);
387 		bin->shdr[i].sh_flags = R_BIN_ELF_READWORD (shdr, j);
388 		bin->shdr[i].sh_addr = R_BIN_ELF_READWORD (shdr, j);
389 		bin->shdr[i].sh_offset = R_BIN_ELF_READWORD (shdr, j);
390 		bin->shdr[i].sh_size = R_BIN_ELF_READWORD (shdr, j);
391 		bin->shdr[i].sh_link = READ32 (shdr, j);
392 		bin->shdr[i].sh_info = READ32 (shdr, j);
393 		bin->shdr[i].sh_addralign = R_BIN_ELF_READWORD (shdr, j);
394 		bin->shdr[i].sh_entsize = R_BIN_ELF_READWORD (shdr, j);
395 	}
396 
397 #if R_BIN_ELF64
398 	sdb_set (bin->kv, "elf_s_flags_64.cparse", "enum elf_s_flags_64 {SF64_None=0,SF64_Exec=1,"
399 			"SF64_Alloc=2,SF64_Alloc_Exec=3,SF64_Write=4,SF64_Write_Exec=5,"
400 			"SF64_Write_Alloc=6,SF64_Write_Alloc_Exec=7};", 0);
401 	sdb_set (bin->kv, "elf_shdr.format", "x[4]E[8]Eqqqxxqq name (elf_s_type)type"
402 			" (elf_s_flags_64)flags addr offset size link info addralign entsize", 0);
403 #else
404 	sdb_set (bin->kv, "elf_s_flags_32.cparse", "enum elf_s_flags_32 {SF32_None=0,SF32_Exec=1,"
405 			"SF32_Alloc=2,SF32_Alloc_Exec=3,SF32_Write=4,SF32_Write_Exec=5,"
406 			"SF32_Write_Alloc=6,SF32_Write_Alloc_Exec=7};", 0);
407 	sdb_set (bin->kv, "elf_shdr.format", "x[4]E[4]Exxxxxxx name (elf_s_type)type"
408 			" (elf_s_flags_32)flags addr offset size link info addralign entsize", 0);
409 #endif
410 	return true;
411 	// Usage example:
412 	// > td `k bin/cur/info/elf_s_type.cparse`; td `k bin/cur/info/elf_s_flags_64.cparse`
413 	// > pf `k bin/cur/info/elf_shdr.format` @ `k bin/cur/info/elf_shdr.offset`
414 }
415 
is_shidx_valid(ELFOBJ * bin,Elf_ (Half)value)416 static bool is_shidx_valid(ELFOBJ *bin, Elf_(Half) value) {
417 	return value < bin->ehdr.e_shnum && !R_BETWEEN (SHN_LORESERVE, value, SHN_HIRESERVE);
418 }
419 
init_strtab(ELFOBJ * bin)420 static int init_strtab(ELFOBJ *bin) {
421 	r_return_val_if_fail (!bin->strtab, false);
422 
423 	if (!bin->shdr) {
424 		return false;
425 	}
426 
427 	Elf_(Half) shstrndx = bin->ehdr.e_shstrndx;
428 	if (shstrndx != SHN_UNDEF && !is_shidx_valid (bin, shstrndx)) {
429 		return false;
430 	}
431 
432 	/* sh_size must be lower than UT32_MAX and not equal to zero, to avoid bugs on malloc() */
433 	if (bin->shdr[shstrndx].sh_size > UT32_MAX) {
434 		return false;
435 	}
436 	if (!bin->shdr[shstrndx].sh_size) {
437 		return false;
438 	}
439 	bin->shstrtab_section = bin->strtab_section = &bin->shdr[shstrndx];
440 	bin->shstrtab_size = bin->shstrtab_section->sh_size;
441 	if (bin->shstrtab_size > bin->size) {
442 		return false;
443 	}
444 	if (bin->shstrtab_section->sh_offset > bin->size) {
445 		return false;
446 	}
447 	if (bin->shstrtab_section->sh_offset + bin->shstrtab_section->sh_size > bin->size) {
448 		return false;
449 	}
450 
451 	if (!(bin->shstrtab = calloc (1, bin->shstrtab_size + 1))) {
452 		perror ("malloc");
453 		bin->shstrtab = NULL;
454 		return false;
455 	}
456 	int res = r_buf_read_at (bin->b, bin->shstrtab_section->sh_offset, (ut8*)bin->shstrtab,
457 		bin->shstrtab_section->sh_size);
458 	if (res < 1) {
459 		bprintf ("read (shstrtab) at 0x%" PFMT64x "\n", (ut64) bin->shstrtab_section->sh_offset);
460 		R_FREE (bin->shstrtab);
461 		return false;
462 	}
463 	bin->shstrtab[bin->shstrtab_section->sh_size] = '\0';
464 
465 	sdb_num_set (bin->kv, "elf_shstrtab.offset", bin->shstrtab_section->sh_offset, 0);
466 	sdb_num_set (bin->kv, "elf_shstrtab.size", bin->shstrtab_section->sh_size, 0);
467 
468 	return true;
469 }
470 
Elf_(Phdr)471 static Elf_(Phdr) *get_dynamic_segment(ELFOBJ *bin) {
472 	int i;
473 	for (i = 0; i < bin->ehdr.e_phnum; i++) {
474 		if (bin->phdr[i].p_type == PT_DYNAMIC) {
475 			if (bin->phdr[i].p_filesz > bin->size) {
476 				return NULL;
477 			}
478 			if (bin->phdr[i].p_offset > bin->size) {
479 				return NULL;
480 			}
481 			if (bin->phdr[i].p_offset + sizeof (Elf_(Dyn)) > bin->size) {
482 				return NULL;
483 			}
484 			return &bin->phdr[i];
485 		}
486 	}
487 	return NULL;
488 }
489 
init_dynamic_section_sdb(ELFOBJ * bin,Elf_ (Addr)strtabaddr,size_t strsize)490 static void init_dynamic_section_sdb(ELFOBJ *bin, Elf_(Addr) strtabaddr, size_t strsize) {
491 	int r = Elf_(r_bin_elf_has_relro) (bin);
492 	switch (r) {
493 	case R_ELF_FULL_RELRO:
494 		sdb_set (bin->kv, "elf.relro", "full", 0);
495 		break;
496 	case R_ELF_PART_RELRO:
497 		sdb_set (bin->kv, "elf.relro", "partial", 0);
498 		break;
499 	default:
500 		sdb_set (bin->kv, "elf.relro", "no", 0);
501 		break;
502 	}
503 	sdb_num_set (bin->kv, "elf_strtab.offset", strtabaddr, 0);
504 	sdb_num_set (bin->kv, "elf_strtab.size", strsize, 0);
505 }
506 
set_default_value_dynamic_info(ELFOBJ * bin)507 static void set_default_value_dynamic_info(ELFOBJ *bin) {
508 	bin->dyn_info.dt_pltrelsz = 0;
509 	bin->dyn_info.dt_pltgot = R_BIN_ELF_ADDR_MAX;
510 	bin->dyn_info.dt_hash = R_BIN_ELF_ADDR_MAX;
511 	bin->dyn_info.dt_strtab = R_BIN_ELF_ADDR_MAX;
512 	bin->dyn_info.dt_symtab = R_BIN_ELF_ADDR_MAX;
513 	bin->dyn_info.dt_rela = R_BIN_ELF_ADDR_MAX;
514 	bin->dyn_info.dt_relasz = 0;
515 	bin->dyn_info.dt_relaent = 0;
516 	bin->dyn_info.dt_strsz = 0;
517 	bin->dyn_info.dt_syment = 0;
518 	bin->dyn_info.dt_rel = R_BIN_ELF_ADDR_MAX;
519 	bin->dyn_info.dt_relsz = 0;
520 	bin->dyn_info.dt_relent = 0;
521 	bin->dyn_info.dt_pltrel = R_BIN_ELF_XWORD_MAX;
522 	bin->dyn_info.dt_jmprel = R_BIN_ELF_ADDR_MAX;
523 	bin->dyn_info.dt_pltgot = R_BIN_ELF_ADDR_MAX;
524 	bin->dyn_info.dt_mips_pltgot = R_BIN_ELF_ADDR_MAX;
525 	bin->dyn_info.dt_bind_now = false;
526 	bin->dyn_info.dt_flags = R_BIN_ELF_XWORD_MAX;
527 	bin->dyn_info.dt_flags_1 = R_BIN_ELF_XWORD_MAX;
528 	bin->dyn_info.dt_rpath = R_BIN_ELF_XWORD_MAX;
529 	bin->dyn_info.dt_runpath = R_BIN_ELF_XWORD_MAX;
530 	r_vector_init(&bin->dyn_info.dt_needed, sizeof(Elf_(Off)), NULL, NULL);
531 }
532 
get_maximum_number_of_dynamic_entries(ut64 dyn_size)533 static size_t get_maximum_number_of_dynamic_entries(ut64 dyn_size) {
534 	return dyn_size / sizeof (Elf_(Dyn));
535 }
536 
fill_dynamic_entry(ELFOBJ * bin,ut64 entry_offset,Elf_ (Dyn)* d)537 static bool fill_dynamic_entry(ELFOBJ *bin, ut64 entry_offset, Elf_(Dyn) *d) {
538 	ut8 sdyn[sizeof (Elf_(Dyn))] = { 0 };
539 	int j = 0;
540 	int len = r_buf_read_at (bin->b, entry_offset, sdyn, sizeof (Elf_(Dyn)));
541 	if (len < 1) {
542 		return false;
543 	}
544 
545 	d->d_tag = R_BIN_ELF_READWORD (sdyn, j);
546 	d->d_un.d_ptr = R_BIN_ELF_READWORD (sdyn, j);
547 
548 	return true;
549 }
550 
fill_dynamic_entries(ELFOBJ * bin,ut64 loaded_offset,ut64 dyn_size)551 static void fill_dynamic_entries(ELFOBJ *bin, ut64 loaded_offset, ut64 dyn_size) {
552 	Elf_(Dyn) d = { 0 };
553 	size_t i;
554 	size_t number_of_entries = get_maximum_number_of_dynamic_entries(dyn_size);
555 
556 	for (i = 0; i < number_of_entries; i++) {
557 		ut64 entry_offset = loaded_offset + i * sizeof (Elf_(Dyn));
558 		if (!fill_dynamic_entry (bin, entry_offset, &d)) {
559 			break;
560 		}
561 
562 		switch (d.d_tag) {
563 		case DT_NULL:
564 			break;
565 		case DT_PLTRELSZ:
566 			bin->dyn_info.dt_pltrelsz = d.d_un.d_val;
567 			break;
568 		case DT_PLTGOT:
569 			bin->dyn_info.dt_pltgot = d.d_un.d_ptr;
570 			break;
571 		case DT_HASH:
572 			bin->dyn_info.dt_hash = d.d_un.d_ptr;
573 			break;
574 		case DT_STRTAB:
575 			bin->dyn_info.dt_strtab = d.d_un.d_ptr;
576 			break;
577 		case DT_SYMTAB:
578 			bin->dyn_info.dt_symtab = d.d_un.d_ptr;
579 			break;
580 		case DT_RELA:
581 			bin->dyn_info.dt_rela = d.d_un.d_ptr;
582 			break;
583 		case DT_RELASZ:
584 			bin->dyn_info.dt_relasz = d.d_un.d_val;
585 			break;
586 		case DT_RELAENT:
587 			bin->dyn_info.dt_relaent = d.d_un.d_val;
588 			break;
589 		case DT_STRSZ:
590 			bin->dyn_info.dt_strsz = d.d_un.d_val;
591 			break;
592 		case DT_SYMENT:
593 			bin->dyn_info.dt_syment = d.d_un.d_val;
594 			break;
595 		case DT_REL:
596 			bin->dyn_info.dt_rel = d.d_un.d_ptr;
597 			break;
598 		case DT_RELSZ:
599 			bin->dyn_info.dt_relsz = d.d_un.d_val;
600 			break;
601 		case DT_RELENT:
602 			bin->dyn_info.dt_relent = d.d_un.d_val;
603 			break;
604 		case DT_PLTREL:
605 			bin->dyn_info.dt_pltrel = d.d_un.d_val;
606 			break;
607 		case DT_JMPREL:
608 			bin->dyn_info.dt_jmprel = d.d_un.d_ptr;
609 			break;
610 		case DT_MIPS_PLTGOT:
611 			bin->dyn_info.dt_mips_pltgot = d.d_un.d_ptr;
612 			break;
613 		case DT_BIND_NOW:
614 			bin->dyn_info.dt_bind_now = true;
615 			break;
616 		case DT_FLAGS:
617 			bin->dyn_info.dt_flags = d.d_un.d_val;
618 			break;
619 		case DT_FLAGS_1:
620 			bin->dyn_info.dt_flags_1 = d.d_un.d_val;
621 			break;
622 		case DT_RPATH:
623 			bin->dyn_info.dt_rpath = d.d_un.d_val;
624 			break;
625 		case DT_RUNPATH:
626 			bin->dyn_info.dt_runpath = d.d_un.d_val;
627 			break;
628 		case DT_NEEDED:
629 			r_vector_push (&bin->dyn_info.dt_needed, &d.d_un.d_val);
630 			break;
631 		case DT_INIT:
632 		case DT_FINI:
633 		case DT_DEBUG:
634 		case DT_INIT_ARRAY:
635 		case DT_FINI_ARRAY:
636 		case DT_INIT_ARRAYSZ:
637 		case DT_FINI_ARRAYSZ:
638 		case DT_PREINIT_ARRAY:
639 		case DT_PREINIT_ARRAYSZ:
640 		case DT_SONAME:
641 		case DT_GNU_HASH:
642 			// common dynamic entries in ELF, but we don't need to
643 			// do anything with them.
644 			break;
645 		default:
646 			if ((d.d_tag >= DT_VERSYM) && (d.d_tag <= DT_VERNEEDNUM)) {
647 				bin->version_info[DT_VERSIONTAGIDX (d.d_tag)] = d.d_un.d_val;
648 			} else {
649 				R_LOG_DEBUG ("Dynamic tag %" PFMT64d " not handled\n", (ut64) d.d_tag);
650 			}
651 			break;
652 		}
653 		if (d.d_tag == DT_NULL) {
654 			break;
655 		}
656 	}
657 }
658 
init_dynamic_section(ELFOBJ * bin)659 static int init_dynamic_section(ELFOBJ *bin) {
660 	ut64 strtabaddr = 0;
661 	char *strtab = NULL;
662 	size_t strsize = 0;
663 	int r;
664 	ut64 dyn_size = 0, loaded_offset;
665 	set_default_value_dynamic_info(bin);
666 
667 	r_return_val_if_fail (bin, false);
668 	if (!bin->phdr || !bin->ehdr.e_phnum) {
669 		return false;
670 	}
671 
672 	Elf_(Phdr) *dyn_phdr = get_dynamic_segment (bin);
673 	if (!dyn_phdr) {
674 		return false;
675 	}
676 
677 	dyn_size = dyn_phdr->p_filesz;
678 	loaded_offset = Elf_(r_bin_elf_v2p_new) (bin, dyn_phdr->p_vaddr);
679 	if (loaded_offset == UT64_MAX) {
680 		return false;
681 	}
682 
683 	if (!dyn_size || loaded_offset + dyn_size > bin->size) {
684 		return false;
685 	}
686 
687 	fill_dynamic_entries (bin, loaded_offset, dyn_size);
688 
689 	if (bin->dyn_info.dt_strtab != R_BIN_ELF_ADDR_MAX) {
690 		strtabaddr = Elf_(r_bin_elf_v2p_new) (bin, bin->dyn_info.dt_strtab);
691 	}
692 
693 	if (bin->dyn_info.dt_strsz > 0) {
694 		strsize = bin->dyn_info.dt_strsz;
695 	}
696 
697 	if (strtabaddr == UT64_MAX || strtabaddr > bin->size || strsize > ST32_MAX || !strsize || strsize > bin->size || strtabaddr + strsize > bin->size) {
698 		if (!strtabaddr) {
699 			bprintf ("DT_STRTAB not found or invalid\n");
700 		}
701 		return false;
702 	}
703 	strtab = (char *)calloc (1, strsize + 1);
704 	if (!strtab) {
705 		return false;
706 	}
707 	r = r_buf_read_at (bin->b, strtabaddr, (ut8 *)strtab, strsize);
708 	if (r < 1) {
709 		free (strtab);
710 		return false;
711 	}
712 
713 	bin->strtab = strtab;
714 	bin->strtab_size = strsize;
715 	init_dynamic_section_sdb (bin, strtabaddr, strsize);
716 	return true;
717 }
718 
get_section_by_name(ELFOBJ * bin,const char * section_name)719 static RBinElfSection* get_section_by_name(ELFOBJ *bin, const char *section_name) {
720 	if (bin->g_sections) {
721 		size_t i;
722 		for (i = 0; !bin->g_sections[i].last; i++) {
723 			if (!strncmp (bin->g_sections[i].name, section_name, ELF_STRING_LENGTH - 1)) {
724 				return &bin->g_sections[i];
725 			}
726 		}
727 	}
728 	return NULL;
729 }
730 
get_ver_flags(ut32 flags)731 static char *get_ver_flags(ut32 flags) {
732 	static char buff[32];
733 	buff[0] = 0;
734 
735 	if (!flags) {
736 		return "none";
737 	}
738 	if (flags & VER_FLG_BASE) {
739 		strcpy (buff, "BASE ");
740 	}
741 	if (flags & VER_FLG_WEAK) {
742 		if (flags & VER_FLG_BASE) {
743 			strcat (buff, "| ");
744 		}
745 		strcat (buff, "WEAK ");
746 	}
747 
748 	if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK)) {
749 		strcat (buff, "| <unknown>");
750 	}
751 	return buff;
752 }
753 
store_versioninfo_gnu_versym(ELFOBJ * bin,Elf_ (Shdr)* shdr,int sz)754 static Sdb *store_versioninfo_gnu_versym(ELFOBJ *bin, Elf_(Shdr) *shdr, int sz) {
755 	size_t i;
756 	const ut64 num_entries = sz / sizeof (Elf_(Versym));
757 	const char *section_name = "";
758 	const char *link_section_name = "";
759 	Sdb *sdb = sdb_new0 ();
760 	if (!sdb) {
761 		return NULL;
762 	}
763 	if (!bin->version_info[DT_VERSIONTAGIDX (DT_VERSYM)]) {
764 		sdb_free (sdb);
765 		return NULL;
766 	}
767 	if (shdr->sh_link >= bin->ehdr.e_shnum) {
768 		sdb_free (sdb);
769 		return NULL;
770 	}
771 	Elf_(Shdr) *link_shdr = &bin->shdr[shdr->sh_link];
772 	ut8 *edata = (ut8*) calloc (R_MAX (1, num_entries), 2 * sizeof (ut8));
773 	if (!edata) {
774 		sdb_free (sdb);
775 		return NULL;
776 	}
777 	ut16 *data = (ut16 *)calloc (R_MAX (1, num_entries), sizeof (ut16));
778 	if (!data) {
779 		free (edata);
780 		sdb_free (sdb);
781 		return NULL;
782 	}
783 	ut64 off = Elf_(r_bin_elf_v2p) (bin, bin->version_info[DT_VERSIONTAGIDX (DT_VERSYM)]);
784 	if (bin->shstrtab && shdr->sh_name < bin->shstrtab_size) {
785 		section_name = &bin->shstrtab[shdr->sh_name];
786 	}
787 	if (bin->shstrtab && link_shdr->sh_name < bin->shstrtab_size) {
788 		link_section_name = &bin->shstrtab[link_shdr->sh_name];
789 	}
790 	r_buf_read_at (bin->b, off, edata, sizeof (ut16) * num_entries);
791 	sdb_set (sdb, "section_name", section_name, 0);
792 	sdb_num_set (sdb, "num_entries", num_entries, 0);
793 	sdb_num_set (sdb, "addr", shdr->sh_addr, 0);
794 	sdb_num_set (sdb, "offset", shdr->sh_offset, 0);
795 	sdb_num_set (sdb, "link", shdr->sh_link, 0);
796 	sdb_set (sdb, "link_section_name", link_section_name, 0);
797 	for (i = num_entries; i--;) {
798 		data[i] = r_read_ble16 (&edata[i * sizeof (ut16)], bin->endian);
799 	}
800 	R_FREE (edata);
801 	char *tmp_val = NULL;
802 	for (i = 0; i < num_entries; i += 4) {
803 		size_t j;
804 		int check_def;
805 		char key[32] = { 0 };
806 
807 		for (j = 0; (j < 4) && (i + j) < num_entries; j++) {
808 			int k;
809 			snprintf (key, sizeof (key), "entry%zd", i + j);
810 			switch (data[i + j]) {
811 			case 0:
812 				sdb_set (sdb, key, "0 (*local*)", 0);
813 				break;
814 			case 1:
815 				sdb_set (sdb, key, "1 (*global*)", 0);
816 				break;
817 			default:
818 				free (tmp_val);
819 				tmp_val = strdup (sdb_fmt ("%x ", data[i+j] & 0x7FFF));
820 				check_def = true;
821 				if (bin->version_info[DT_VERSIONTAGIDX (DT_VERNEED)]) {
822 					Elf_(Verneed) vn;
823 					ut8 svn[sizeof (Elf_(Verneed))] = { 0 };
824 					ut64 offset = Elf_(r_bin_elf_v2p) (bin, bin->version_info[DT_VERSIONTAGIDX (DT_VERNEED)]);
825 					do {
826 						Elf_(Vernaux) vna;
827 						ut8 svna[sizeof (Elf_(Vernaux))] = { 0 };
828 						ut64 a_off;
829 						if (offset > bin->size || offset + sizeof (vn) > bin->size) {
830 							goto beach;
831 						}
832 						if (r_buf_read_at (bin->b, offset, svn, sizeof (svn)) < 0) {
833 							bprintf ("Cannot read Verneed for Versym\n");
834 							goto beach;
835 						}
836 						k = 0;
837 						vn.vn_version = READ16 (svn, k);
838 						vn.vn_cnt = READ16 (svn, k);
839 						vn.vn_file = READ32 (svn, k);
840 						vn.vn_aux = READ32 (svn, k);
841 						vn.vn_next = READ32 (svn, k);
842 						a_off = offset + vn.vn_aux;
843 						do {
844 							if (a_off > bin->size || a_off + sizeof (vna) > bin->size) {
845 								goto beach;
846 							}
847 							if (r_buf_read_at (bin->b, a_off, svna, sizeof (svna)) < 0) {
848 								bprintf ("Cannot read Vernaux for Versym\n");
849 								goto beach;
850 							}
851 							k = 0;
852 							vna.vna_hash = READ32 (svna, k);
853 							vna.vna_flags = READ16 (svna, k);
854 							vna.vna_other = READ16 (svna, k);
855 							vna.vna_name = READ32 (svna, k);
856 							vna.vna_next = READ32 (svna, k);
857 							a_off += vna.vna_next;
858 						} while (vna.vna_other != data[i + j] && vna.vna_next != 0);
859 
860 						if (vna.vna_other == data[i + j]) {
861 							if (vna.vna_name > bin->strtab_size) {
862 								goto beach;
863 							}
864 							sdb_set (sdb, key, sdb_fmt ("%s(%s)", tmp_val, bin->strtab + vna.vna_name), 0);
865 							check_def = false;
866 							break;
867 						}
868 						offset += vn.vn_next;
869 					} while (vn.vn_next);
870 				}
871 
872 				ut64 vinfoaddr = bin->version_info[DT_VERSIONTAGIDX (DT_VERDEF)];
873 				if (check_def && data[i + j] != 0x8001 && vinfoaddr) {
874 					Elf_(Verdef) vd;
875 					ut8 svd[sizeof (Elf_(Verdef))] = { 0 };
876 					ut64 offset = Elf_(r_bin_elf_v2p) (bin, vinfoaddr);
877 					if (offset > bin->size || offset + sizeof (vd) > bin->size) {
878 						goto beach;
879 					}
880 					do {
881 						if (r_buf_read_at (bin->b, offset, svd, sizeof (svd)) < 0) {
882 							bprintf ("Cannot read Verdef for Versym\n");
883 							goto beach;
884 						}
885 						k = 0;
886 						vd.vd_version = READ16 (svd, k);
887 						vd.vd_flags = READ16 (svd, k);
888 						vd.vd_ndx = READ16 (svd, k);
889 						vd.vd_cnt = READ16 (svd, k);
890 						vd.vd_hash = READ32 (svd, k);
891 						vd.vd_aux = READ32 (svd, k);
892 						vd.vd_next = READ32 (svd, k);
893 						offset += vd.vd_next;
894 					} while (vd.vd_ndx != (data[i + j] & 0x7FFF) && vd.vd_next != 0);
895 
896 					if (vd.vd_ndx == (data[i + j] & 0x7FFF)) {
897 						Elf_(Verdaux) vda;
898 						ut8 svda[sizeof (Elf_(Verdaux))] = { 0 };
899 						ut64 off_vda = offset - vd.vd_next + vd.vd_aux;
900 						if (off_vda > bin->size || off_vda + sizeof (vda) > bin->size) {
901 							goto beach;
902 						}
903 						if (r_buf_read_at (bin->b, off_vda, svda, sizeof (svda)) < 0) {
904 							bprintf ("Cannot read Verdaux for Versym\n");
905 							goto beach;
906 						}
907 						k = 0;
908 						vda.vda_name = READ32 (svda, k);
909 						vda.vda_next = READ32 (svda, k);
910 						if (vda.vda_name > bin->strtab_size) {
911 							goto beach;
912 						}
913 						const char *name = bin->strtab + vda.vda_name;
914 						if (name) {
915 							const char *fname = sdb_fmt ("%s(%s%-*s)", tmp_val, name, (int)(12 - strlen (name)),")");
916 							sdb_set (sdb, key, fname, 0);
917 						}
918 					}
919 				}
920 			}
921 		}
922 		R_FREE (tmp_val);
923 	}
924 beach:
925 	R_FREE (tmp_val);
926 	free (data);
927 	return sdb;
928 }
929 
store_versioninfo_gnu_verdef(ELFOBJ * bin,Elf_ (Shdr)* shdr,int sz)930 static Sdb *store_versioninfo_gnu_verdef(ELFOBJ *bin, Elf_(Shdr) *shdr, int sz) {
931 	const char *section_name = "";
932 	const char *link_section_name = "";
933 	char *end = NULL;
934 	ut8 dfs[sizeof (Elf_(Verdef))] = { 0 };
935 	Sdb *sdb;
936 	ut32 cnt;
937 	size_t i;
938 	if (shdr->sh_link >= bin->ehdr.e_shnum) {
939 		return false;
940 	}
941 	Elf_(Shdr) *link_shdr = &bin->shdr[shdr->sh_link];
942 #ifdef R_BIN_ELF64
943 	if ((int)shdr->sh_size < 1 || shdr->sh_size > SIZE_MAX) {
944 #else
945 	if ((int)shdr->sh_size < 1) {
946 #endif
947 		return false;
948 	}
949 	if (shdr->sh_size < sizeof (Elf_(Verdef)) || shdr->sh_size < sizeof (Elf_(Verdaux))) {
950 		return false;
951 	}
952 	Elf_(Verdef) *defs = calloc (shdr->sh_size, 1);
953 	if (!defs) {
954 		bprintf ("Cannot allocate memory (Check Elf_(Verdef))\n");
955 		return false;
956 	}
957 	if (bin->shstrtab && shdr->sh_name < bin->shstrtab_size) {
958 		section_name = &bin->shstrtab[shdr->sh_name];
959 	}
960 	if (link_shdr && bin->shstrtab && link_shdr->sh_name < bin->shstrtab_size) {
961 		link_section_name = &bin->shstrtab[link_shdr->sh_name];
962 	}
963 	sdb = sdb_new0 ();
964 	end = (char *)defs + shdr->sh_size;
965 	sdb_set (sdb, "section_name", section_name, 0);
966 	sdb_num_set (sdb, "entries", shdr->sh_info, 0);
967 	sdb_num_set (sdb, "addr", shdr->sh_addr, 0);
968 	sdb_num_set (sdb, "offset", shdr->sh_offset, 0);
969 	sdb_num_set (sdb, "link", shdr->sh_link, 0);
970 	sdb_set (sdb, "link_section_name", link_section_name, 0);
971 
972 	for (cnt = 0, i = 0; cnt < shdr->sh_info && i < shdr->sh_size; cnt++) {
973 		Sdb *sdb_verdef = sdb_new0 ();
974 		char *vstart = ((char*)defs) + i;
975 		size_t vstart_off = i;
976 		char key[32] = { 0 };
977 		Elf_(Verdef) *verdef = (Elf_(Verdef)*)vstart;
978 		Elf_(Verdaux) aux = { 0 };
979 		int j = 0;
980 		int isum = 0;
981 
982 		if (vstart + sizeof (*verdef) > end) {
983 			break;
984 		}
985 		r_buf_read_at (bin->b, shdr->sh_offset + i, dfs, sizeof (Elf_(Verdef)));
986 		verdef->vd_version = READ16 (dfs, j);
987 		verdef->vd_flags = READ16 (dfs, j);
988 		verdef->vd_ndx = READ16 (dfs, j);
989 		verdef->vd_cnt = READ16 (dfs, j);
990 		verdef->vd_hash = READ32 (dfs, j);
991 		verdef->vd_aux = READ32 (dfs, j);
992 		verdef->vd_next = READ32 (dfs, j);
993 		int vdaux = verdef->vd_aux;
994 		if (vdaux < 1 || shdr->sh_size - vstart_off < vdaux) {
995 			sdb_free (sdb_verdef);
996 			goto out_error;
997 		}
998 		vstart += vdaux;
999 		vstart_off += vdaux;
1000 		if (vstart > end || shdr->sh_size - sizeof (Elf_(Verdaux)) < vstart_off) {
1001 			sdb_free (sdb_verdef);
1002 			goto out_error;
1003 		}
1004 
1005 		j = 0;
1006 		aux.vda_name = READ32 (vstart, j);
1007 		aux.vda_next = READ32 (vstart, j);
1008 
1009 		isum = i + verdef->vd_aux;
1010 		if (aux.vda_name > bin->dynstr_size) {
1011 			sdb_free (sdb_verdef);
1012 			goto out_error;
1013 		}
1014 
1015 		sdb_num_set (sdb_verdef, "idx", i, 0);
1016 		sdb_num_set (sdb_verdef, "vd_version", verdef->vd_version, 0);
1017 		sdb_num_set (sdb_verdef, "vd_ndx", verdef->vd_ndx, 0);
1018 		sdb_num_set (sdb_verdef, "vd_cnt", verdef->vd_cnt, 0);
1019 		sdb_set (sdb_verdef, "vda_name", &bin->dynstr[aux.vda_name], 0);
1020 		sdb_set (sdb_verdef, "flags", get_ver_flags (verdef->vd_flags), 0);
1021 
1022 		for (j = 1; j < verdef->vd_cnt; j++) {
1023 			int k;
1024 			Sdb *sdb_parent = sdb_new0 ();
1025 			if (shdr->sh_size - vstart_off < aux.vda_next) {
1026 				sdb_free (sdb_verdef);
1027 				sdb_free (sdb_parent);
1028 				goto out_error;
1029 			}
1030 			isum += aux.vda_next;
1031 			vstart += aux.vda_next;
1032 			vstart_off += aux.vda_next;
1033 			if (vstart > end || shdr->sh_size - sizeof (Elf_(Verdaux)) < vstart_off) {
1034 				sdb_free (sdb_verdef);
1035 				sdb_free (sdb_parent);
1036 				goto out_error;
1037 			}
1038 			k = 0;
1039 			aux.vda_name = READ32 (vstart, k);
1040 			aux.vda_next = READ32 (vstart, k);
1041 			if (aux.vda_name > bin->dynstr_size) {
1042 				sdb_free (sdb_verdef);
1043 				sdb_free (sdb_parent);
1044 				goto out_error;
1045 			}
1046 			sdb_num_set (sdb_parent, "idx", isum, 0);
1047 			sdb_num_set (sdb_parent, "parent", j, 0);
1048 			sdb_set (sdb_parent, "vda_name", &bin->dynstr[aux.vda_name], 0);
1049 			snprintf (key, sizeof (key), "parent%d", j - 1);
1050 			sdb_ns_set (sdb_verdef, key, sdb_parent);
1051 		}
1052 
1053 		snprintf (key, sizeof (key), "verdef%u", cnt);
1054 		sdb_ns_set (sdb, key, sdb_verdef);
1055 		if (!verdef->vd_next || shdr->sh_size - i < verdef->vd_next) {
1056 			sdb_free (sdb_verdef);
1057 			goto out_error;
1058 		}
1059 		if ((st32)verdef->vd_next < 1) {
1060 			bprintf ("Invalid vd_next in the ELF version\n");
1061 			break;
1062 		}
1063 		i += verdef->vd_next;
1064 	}
1065 	free (defs);
1066 	return sdb;
1067 out_error:
1068 	free (defs);
1069 	sdb_free (sdb);
1070 	return NULL;
1071 }
1072 
1073 static Sdb *store_versioninfo_gnu_verneed(ELFOBJ *bin, Elf_(Shdr) *shdr, int sz) {
1074 	ut8 *end, *need = NULL;
1075 	const char *section_name = "";
1076 	Elf_(Shdr) *link_shdr = NULL;
1077 	const char *link_section_name = "";
1078 	Sdb *sdb_vernaux = NULL;
1079 	Sdb *sdb_version = NULL;
1080 	Sdb *sdb = NULL;
1081 	ut64 i;
1082 	int cnt;
1083 
1084 	if (!bin || !bin->dynstr) {
1085 		return NULL;
1086 	}
1087 	if (shdr->sh_link >= bin->ehdr.e_shnum) {
1088 		return NULL;
1089 	}
1090 #ifdef R_BIN_ELF64
1091 	if ((int)shdr->sh_size < 1 || shdr->sh_size > SIZE_MAX) {
1092 #else
1093 	if ((int)shdr->sh_size < 1) {
1094 #endif
1095 		return NULL;
1096 	}
1097 	sdb = sdb_new0 ();
1098 	if (!sdb) {
1099 		return NULL;
1100 	}
1101 	link_shdr = &bin->shdr[shdr->sh_link];
1102 	if (bin->shstrtab && shdr->sh_name < bin->shstrtab_size) {
1103 		section_name = &bin->shstrtab[shdr->sh_name];
1104 	}
1105 	if (bin->shstrtab && link_shdr->sh_name < bin->shstrtab_size) {
1106 		link_section_name = &bin->shstrtab[link_shdr->sh_name];
1107 	}
1108 	if (!(need = (ut8*) calloc (R_MAX (1, shdr->sh_size), sizeof (ut8)))) {
1109 		bprintf ("Cannot allocate memory for Elf_(Verneed)\n");
1110 		goto beach;
1111 	}
1112 	end = need + shdr->sh_size;
1113 	sdb_set (sdb, "section_name", section_name, 0);
1114 	sdb_num_set (sdb, "num_entries", shdr->sh_info, 0);
1115 	sdb_num_set (sdb, "addr", shdr->sh_addr, 0);
1116 	sdb_num_set (sdb, "offset", shdr->sh_offset, 0);
1117 	sdb_num_set (sdb, "link", shdr->sh_link, 0);
1118 	sdb_set (sdb, "link_section_name", link_section_name, 0);
1119 
1120 	if (shdr->sh_offset > bin->size || shdr->sh_offset + shdr->sh_size > bin->size) {
1121 		goto beach;
1122 	}
1123 	if (shdr->sh_offset + shdr->sh_size < shdr->sh_size) {
1124 		goto beach;
1125 	}
1126 	i = r_buf_read_at (bin->b, shdr->sh_offset, need, shdr->sh_size);
1127 	if (i < 1) {
1128 		goto beach;
1129 	}
1130 	//XXX we should use DT_VERNEEDNUM instead of sh_info
1131 	//TODO https://sourceware.org/ml/binutils/2014-11/msg00353.html
1132 	for (i = 0, cnt = 0; cnt < shdr->sh_info; cnt++) {
1133 		int j, isum;
1134 		ut8 *vstart = need + i;
1135 		Elf_(Verneed) vvn = { 0 };
1136 		if (vstart + sizeof (Elf_(Verneed)) > end) {
1137 			goto beach;
1138 		}
1139 		Elf_(Verneed) *entry = &vvn;
1140 		char key[32] = { 0 };
1141 		sdb_version = sdb_new0 ();
1142 		if (!sdb_version) {
1143 			goto beach;
1144 		}
1145 		j = 0;
1146 		vvn.vn_version = READ16 (vstart, j);
1147 		vvn.vn_cnt = READ16 (vstart, j);
1148 		vvn.vn_file = READ32 (vstart, j);
1149 		vvn.vn_aux = READ32 (vstart, j);
1150 		vvn.vn_next = READ32 (vstart, j);
1151 
1152 		sdb_num_set (sdb_version, "vn_version", entry->vn_version, 0);
1153 		sdb_num_set (sdb_version, "idx", i, 0);
1154 		if (entry->vn_file > bin->dynstr_size) {
1155 			goto beach;
1156 		}
1157 		{
1158 			char *s = r_str_ndup (&bin->dynstr[entry->vn_file], 16);
1159 			sdb_set (sdb_version, "file_name", s, 0);
1160 			free (s);
1161 		}
1162 		sdb_num_set (sdb_version, "cnt", entry->vn_cnt, 0);
1163 		st32 vnaux = entry->vn_aux;
1164 		if (vnaux < 1) {
1165 			goto beach;
1166 		}
1167 		vstart += vnaux;
1168 		ut32 vn_cnt = entry->vn_cnt;
1169 		for (j = 0, isum = i + entry->vn_aux; j < vn_cnt && vstart + sizeof (Elf_(Vernaux)) <= end; j++) {
1170 			int k;
1171 			Elf_(Vernaux) *aux = NULL;
1172 			Elf_(Vernaux) vaux = {0};
1173 			aux = (Elf_(Vernaux)*)&vaux;
1174 			k = 0;
1175 			vaux.vna_hash = READ32 (vstart, k);
1176 			vaux.vna_flags = READ16 (vstart, k);
1177 			vaux.vna_other = READ16 (vstart, k);
1178 			vaux.vna_name = READ32 (vstart, k);
1179 			vaux.vna_next = READ32 (vstart, k);
1180 			if (aux->vna_name > bin->dynstr_size) {
1181 				goto beach;
1182 			}
1183 #if 1
1184 			sdb_vernaux = sdb_new0 ();
1185 			if (!sdb_vernaux) {
1186 				goto beach;
1187 			}
1188 			sdb_num_set (sdb_vernaux, "idx", isum, 0);
1189 			if (aux->vna_name > 0 && aux->vna_name + 8 < bin->dynstr_size) {
1190 				char name [16];
1191 				strncpy (name, &bin->dynstr[aux->vna_name], sizeof (name)-1);
1192 				name[sizeof(name)-1] = 0;
1193 				sdb_set (sdb_vernaux, "name", name, 0);
1194 			}
1195 			sdb_set (sdb_vernaux, "flags", get_ver_flags (aux->vna_flags), 0);
1196 			sdb_num_set (sdb_vernaux, "version", aux->vna_other, 0);
1197 			isum += aux->vna_next;
1198 			vstart += aux->vna_next;
1199 			snprintf (key, sizeof (key), "vernaux%d", j);
1200 			sdb_ns_set (sdb_version, key, sdb_vernaux);
1201 #else
1202 			char *key = r_str_newf ("vernaux%d", j);
1203 			char *val = r_str_newf ("%d,%s", isum, get_ver_flags (aux->vna_flags));
1204 			sdb_set (sdb_version, key, val, 0);
1205 			free (key);
1206 			free (val);
1207 #endif
1208 		}
1209 		if ((int)entry->vn_next < 0) {
1210 			bprintf ("Invalid vn_next\n");
1211 			break;
1212 		}
1213 		i += entry->vn_next;
1214 		snprintf (key, sizeof (key), "version%d", cnt );
1215 		sdb_ns_set (sdb, key, sdb_version);
1216 		//if entry->vn_next is 0 it iterate infinitely
1217 		if (!entry->vn_next) {
1218 			break;
1219 		}
1220 	}
1221 	free (need);
1222 	return sdb;
1223 beach:
1224 	free (need);
1225 	sdb_free (sdb_vernaux);
1226 	sdb_free (sdb_version);
1227 	sdb_free (sdb);
1228 	return NULL;
1229 }
1230 
1231 static Sdb *store_versioninfo(ELFOBJ *bin) {
1232 	Sdb *sdb_versioninfo = NULL;
1233 	int num_verdef = 0;
1234 	int num_verneed = 0;
1235 	int num_versym = 0;
1236 	size_t i;
1237 
1238 	if (!bin || !bin->shdr) {
1239 		return NULL;
1240 	}
1241 	if (!(sdb_versioninfo = sdb_new0 ())) {
1242 		return NULL;
1243 	}
1244 
1245 	for (i = 0; i < bin->ehdr.e_shnum; i++) {
1246 		Sdb *sdb = NULL;
1247 		char key[32] = {0};
1248 		int size = bin->shdr[i].sh_size;
1249 
1250 		if (size - (i * sizeof (Elf_(Shdr)) > bin->size)) {
1251 			size = bin->size - (i*sizeof(Elf_(Shdr)));
1252 		}
1253 		int left = size - (i * sizeof (Elf_(Shdr)));
1254 		left = R_MIN (left, bin->shdr[i].sh_size);
1255 		if (left < 0) {
1256 			break;
1257 		}
1258 		switch (bin->shdr[i].sh_type) {
1259 		case SHT_GNU_verdef:
1260 			sdb = store_versioninfo_gnu_verdef (bin, &bin->shdr[i], left);
1261 			snprintf (key, sizeof (key), "verdef%d", num_verdef++);
1262 			sdb_ns_set (sdb_versioninfo, key, sdb);
1263 			break;
1264 		case SHT_GNU_verneed:
1265 			sdb = store_versioninfo_gnu_verneed (bin, &bin->shdr[i], left);
1266 			snprintf (key, sizeof (key), "verneed%d", num_verneed++);
1267 			sdb_ns_set (sdb_versioninfo, key, sdb);
1268 			break;
1269 		case SHT_GNU_versym:
1270 			sdb = store_versioninfo_gnu_versym (bin, &bin->shdr[i], left);
1271 			snprintf (key, sizeof (key), "versym%d", num_versym++);
1272 			sdb_ns_set (sdb_versioninfo, key, sdb);
1273 			break;
1274 		}
1275 	}
1276 
1277 	return sdb_versioninfo;
1278 }
1279 
1280 static bool init_dynstr(ELFOBJ *bin) {
1281 	int i, r;
1282 	const char *section_name = NULL;
1283 	if (!bin || !bin->shdr) {
1284 		return false;
1285 	}
1286 	if (!bin->shstrtab) {
1287 		return false;
1288 	}
1289 	for (i = 0; i < bin->ehdr.e_shnum; i++) {
1290 		if (bin->shdr[i].sh_name > bin->shstrtab_size) {
1291 			return false;
1292 		}
1293 		section_name = &bin->shstrtab[bin->shdr[i].sh_name];
1294 		if (bin->shdr[i].sh_type == SHT_STRTAB && !strcmp (section_name, ".dynstr")) {
1295 			if (!(bin->dynstr = (char*) calloc (bin->shdr[i].sh_size + 1, sizeof (char)))) {
1296 				bprintf("Cannot allocate memory for dynamic strings\n");
1297 				return false;
1298 			}
1299 			if (bin->shdr[i].sh_offset > bin->size) {
1300 				return false;
1301 			}
1302 			if (bin->shdr[i].sh_offset + bin->shdr[i].sh_size > bin->size) {
1303 				return false;
1304 			}
1305 			if (bin->shdr[i].sh_offset + bin->shdr[i].sh_size < bin->shdr[i].sh_size) {
1306 				return false;
1307 			}
1308 			r = r_buf_read_at (bin->b, bin->shdr[i].sh_offset, (ut8*)bin->dynstr, bin->shdr[i].sh_size);
1309 			if (r < 1) {
1310 				R_FREE (bin->dynstr);
1311 				bin->dynstr_size = 0;
1312 				return false;
1313 			}
1314 			bin->dynstr_size = bin->shdr[i].sh_size;
1315 			return true;
1316 		}
1317 	}
1318 	return false;
1319 }
1320 
1321 static HtUP *rel_cache_new(RBinElfReloc *relocs, ut32 reloc_num) {
1322 	if (!relocs || reloc_num == 0) {
1323 		return NULL;
1324 	}
1325 	const int htsize = R_MIN (reloc_num, 1024);
1326 	HtUP *rel_cache = ht_up_new_size (htsize, NULL, NULL, NULL);
1327 	if (rel_cache) {
1328 		size_t i;
1329 		for (i = 0; i < reloc_num; i++) {
1330 			RBinElfReloc *tmp = relocs + i;
1331 			ht_up_insert (rel_cache, tmp->sym, tmp);
1332 		}
1333 	}
1334 	return rel_cache;
1335 }
1336 
1337 static bool elf_init(ELFOBJ *bin) {
1338 	/* bin is not an ELF */
1339 	if (!init_ehdr (bin)) {
1340 		return false;
1341 	}
1342 	if (!init_phdr (bin) && !is_bin_etrel (bin)) {
1343 		bprintf ("Cannot initialize program headers\n");
1344 	}
1345 	if (bin->ehdr.e_type != ET_CORE) {
1346 		if (!init_shdr (bin)) {
1347 			bprintf ("Cannot initialize section headers\n");
1348 		}
1349 		if (!init_strtab (bin)) {
1350 			bprintf ("Cannot initialize strings table\n");
1351 		}
1352 		if (!init_dynstr (bin) && !is_bin_etrel (bin)) {
1353 			bprintf ("Cannot initialize dynamic strings\n");
1354 		}
1355 		bin->baddr = Elf_(r_bin_elf_get_baddr) (bin);
1356 		if (!init_dynamic_section (bin) && !Elf_(r_bin_elf_is_static) (bin) && !is_bin_etrel (bin)) {
1357 			bprintf ("Cannot initialize dynamic section\n");
1358 		}
1359 	}
1360 
1361 	bin->imports_by_ord_size = 0;
1362 	bin->imports_by_ord = NULL;
1363 	bin->symbols_by_ord_size = 0;
1364 	bin->symbols_by_ord = NULL;
1365 	bin->g_sections = Elf_(r_bin_elf_get_sections) (bin);
1366 	bin->boffset = Elf_(r_bin_elf_get_boffset) (bin);
1367 	bin->g_relocs = Elf_(r_bin_elf_get_relocs) (bin);
1368 	bin->rel_cache = rel_cache_new (bin->g_relocs, bin->g_reloc_num);
1369 	sdb_ns_set (bin->kv, "versioninfo", store_versioninfo (bin));
1370 	return true;
1371 }
1372 
1373 ut64 Elf_(r_bin_elf_get_section_offset)(ELFOBJ *bin, const char *section_name) {
1374 	RBinElfSection *section = get_section_by_name (bin, section_name);
1375 	return section? section->offset: UT64_MAX;
1376 }
1377 
1378 ut64 Elf_(r_bin_elf_get_section_addr)(ELFOBJ *bin, const char *section_name) {
1379 	RBinElfSection *section = get_section_by_name (bin, section_name);
1380 	return section? section->rva: UT64_MAX;
1381 }
1382 
1383 ut64 Elf_(r_bin_elf_get_section_addr_end)(ELFOBJ *bin, const char *section_name) {
1384 	RBinElfSection *section = get_section_by_name (bin, section_name);
1385 	return section? section->rva + section->size: UT64_MAX;
1386 }
1387 
1388 static ut64 get_got_entry(ELFOBJ *bin, RBinElfReloc *rel) {
1389 	if (!rel->rva) {
1390 		return UT64_MAX;
1391 	}
1392 
1393 	ut64 p_sym_got_addr = Elf_(r_bin_elf_v2p_new) (bin, rel->rva);
1394 	ut64 addr = R_BIN_ELF_BREADWORD (bin->b, p_sym_got_addr);
1395 
1396 	return (!addr || addr == R_BIN_ELF_WORD_MAX) ? UT64_MAX : addr;
1397 }
1398 
1399 static bool is_thumb_symbol(ut64 plt_addr) {
1400 	return plt_addr & 1;
1401 }
1402 
1403 static ut64 get_import_addr_arm(ELFOBJ *bin, RBinElfReloc *rel) {
1404 	ut64 got_addr = bin->dyn_info.dt_pltgot;
1405 	if (got_addr == R_BIN_ELF_ADDR_MAX) {
1406 		return UT64_MAX;
1407 	}
1408 
1409 	ut64 plt_addr = get_got_entry (bin, rel);
1410 	if (plt_addr == UT64_MAX) {
1411 		return UT64_MAX;
1412 	}
1413 
1414 	ut64 pos = COMPUTE_PLTGOT_POSITION (rel, got_addr, 0x3);
1415 
1416 	switch (rel->type) {
1417 	case R_ARM_JUMP_SLOT:
1418 		plt_addr += pos * 12 + 20;
1419 		if (is_thumb_symbol (plt_addr)) {
1420 			plt_addr--;
1421 		}
1422 		return plt_addr;
1423 	case R_AARCH64_RELATIVE:
1424 		eprintf ("Unsupported relocation type for imports %d\n", rel->type);
1425 		return UT64_MAX;
1426 	case R_AARCH64_IRELATIVE:
1427 		if (rel->addend > plt_addr) { // start
1428 			return (plt_addr + pos * 16 + 32) + rel->addend;
1429 		}
1430 		// same as fallback to JUMP_SLOT
1431 		return plt_addr + pos * 16 + 32;
1432 	case R_AARCH64_JUMP_SLOT:
1433 		return plt_addr + pos * 16 + 32;
1434 	default:
1435 		bprintf ("Unsupported relocation type for imports %d\n", rel->type);
1436 		return UT64_MAX;
1437 	}
1438 	return UT64_MAX;
1439 }
1440 
1441 static ut64 get_import_addr_mips(ELFOBJ *bin, RBinElfReloc *rel) {
1442 	ut64 jmprel_addr = bin->dyn_info.dt_jmprel;
1443 	ut64 got_addr = bin->dyn_info.dt_mips_pltgot;
1444 
1445 	if (jmprel_addr == R_BIN_ELF_ADDR_MAX || got_addr == R_BIN_ELF_ADDR_MAX) {
1446 		return UT64_MAX;
1447 	}
1448 
1449 	ut64 pos = COMPUTE_PLTGOT_POSITION(rel, got_addr, 0x2);
1450 
1451 	ut8 buf[1024];
1452 	ut64 plt_addr = jmprel_addr + bin->dyn_info.dt_pltrelsz;
1453 	ut64 p_plt_addr = Elf_(r_bin_elf_v2p_new) (bin, plt_addr);
1454 	int res = r_buf_read_at (bin->b, p_plt_addr, buf, sizeof (buf));
1455 	if (res != sizeof (buf)) {
1456 		return UT64_MAX;
1457 	}
1458 
1459 	const ut8 *base = r_mem_mem_aligned (buf, sizeof (buf), (const ut8 *)"\x3c\x0f\x00", 3, 4);
1460 	plt_addr += base? (int)(size_t) (base - buf):  MIPS_PLT_OFFSET + 8; // HARDCODED HACK
1461 	plt_addr += pos * 16;
1462 
1463 	return plt_addr;
1464 }
1465 
1466 static size_t get_size_rel_mode(Elf_(Xword) rel_mode) {
1467 	return rel_mode == DT_RELA? sizeof (Elf_(Rela)): sizeof (Elf_(Rel));
1468 }
1469 
1470 static ut64 get_num_relocs_dynamic_plt(ELFOBJ *bin) {
1471 	if (bin->dyn_info.dt_pltrelsz) {
1472 		const ut64 size = bin->dyn_info.dt_pltrelsz;
1473 		const ut64 relsize = get_size_rel_mode (bin->dyn_info.dt_pltrel);
1474 		return size / relsize;
1475 	}
1476 	return 0;
1477 }
1478 
1479 static ut64 get_import_addr_riscv(ELFOBJ *bin, RBinElfReloc *rel) {
1480 	ut64 got_addr = bin->dyn_info.dt_pltgot;
1481 	if (got_addr == R_BIN_ELF_ADDR_MAX) {
1482 		return UT64_MAX;
1483 	}
1484 
1485 	ut64 plt_addr = get_got_entry (bin, rel);
1486 	if (plt_addr == UT64_MAX) {
1487 		return UT64_MAX;
1488 	}
1489 
1490 	ut64 pos = COMPUTE_PLTGOT_POSITION(rel, got_addr, 0x2);
1491 	return plt_addr + RISCV_PLT_OFFSET + pos * RISCV_PLT_ENTRY_SIZE;
1492 }
1493 
1494 static ut64 get_import_addr_sparc(ELFOBJ *bin, RBinElfReloc *rel) {
1495 	if (rel->type != R_SPARC_JMP_SLOT) {
1496 		bprintf ("Unknown sparc reloc type %d\n", rel->type);
1497 		return UT64_MAX;
1498 	}
1499 	ut64 tmp = get_got_entry (bin, rel);
1500 
1501 	return (tmp == UT64_MAX) ? UT64_MAX : tmp + SPARC_OFFSET_PLT_ENTRY_FROM_GOT_ADDR;
1502 }
1503 
1504 static ut64 get_import_addr_ppc(ELFOBJ *bin, RBinElfReloc *rel) {
1505 	ut64 plt_addr = bin->dyn_info.dt_pltgot;
1506 	if (plt_addr == R_BIN_ELF_ADDR_MAX) {
1507 		return UT64_MAX;
1508 	}
1509 	ut64 p_plt_addr = Elf_(r_bin_elf_v2p_new) (bin, plt_addr);
1510 	if (p_plt_addr == UT64_MAX) {
1511 		return UT64_MAX;
1512 	}
1513 
1514 	ut64 base = r_buf_read_ble32_at (bin->b, p_plt_addr, bin->endian);
1515 	if (base == UT32_MAX) {
1516 		return UT64_MAX;
1517 	}
1518 
1519 	ut64 nrel = get_num_relocs_dynamic_plt (bin);
1520 	ut64 pos = COMPUTE_PLTGOT_POSITION(rel, plt_addr, 0x0);
1521 
1522 	if (bin->endian) {
1523 		base -= (nrel * 16);
1524 		base += (pos * 16);
1525 		return base;
1526 	}
1527 
1528 	base -= (nrel * 12) + 20;
1529 	base += (pos * 8);
1530 	return base;
1531 }
1532 
1533 static ut64 get_import_addr_x86_manual(ELFOBJ *bin, RBinElfReloc *rel) {
1534 	ut64 got_addr = bin->dyn_info.dt_pltgot;
1535 	if (got_addr == R_BIN_ELF_ADDR_MAX) {
1536 		return UT64_MAX;
1537 	}
1538 
1539 	ut64 got_offset = Elf_(r_bin_elf_v2p_new) (bin, got_addr);
1540 	if (got_offset == UT64_MAX) {
1541 		return UT64_MAX;
1542 	}
1543 
1544 	//XXX HACK ALERT!!!! full relro?? try to fix it
1545 	//will there always be .plt.got, what would happen if is .got.plt?
1546 	RBinElfSection *s = get_section_by_name (bin, ".plt.got");
1547 	if (Elf_(r_bin_elf_has_relro) (bin) < R_ELF_PART_RELRO || !s) {
1548 		return UT64_MAX;
1549 	}
1550 
1551 	ut8 buf[sizeof (Elf_(Addr))] = { 0 };
1552 
1553 	ut64 plt_addr = s->offset;
1554 	ut64 plt_sym_addr;
1555 
1556 	while (plt_addr + 2 + 4 < s->offset + s->size) {
1557 		/*we try to locate the plt entry that correspond with the relocation
1558 		  since got does not point back to .plt. In this case it has the following
1559 		  form
1560 		  ff253a152000   JMP QWORD [RIP + 0x20153A]
1561 		  6690		     NOP
1562 		  ----
1563 		  ff25ec9f0408   JMP DWORD [reloc.puts_236]
1564 		  plt_addr + 2 to remove jmp opcode and get the imm reading 4
1565 		  and if RIP (plt_addr + 6) + imm == rel->offset
1566 		  return plt_addr, that will be our sym addr
1567 		  perhaps this hack doesn't work on 32 bits
1568 		  */
1569 		int res = r_buf_read_at (bin->b, plt_addr + 2, buf, sizeof (ut32));
1570 		if (res < 0) {
1571 			return UT64_MAX;
1572 		}
1573 
1574 		size_t i = 0;
1575 		plt_sym_addr = R_BIN_ELF_READWORD (buf, i);
1576 
1577 		//relative address
1578 		if ((plt_addr + 6 + Elf_(r_bin_elf_v2p) (bin, plt_sym_addr)) == rel->rva) {
1579 			return plt_addr;
1580 		}
1581 		if (plt_sym_addr == rel->rva) {
1582 			return plt_addr;
1583 		}
1584 		plt_addr += 8;
1585 	}
1586 
1587 	return UT64_MAX;
1588 }
1589 
1590 static ut64 get_import_addr_x86(ELFOBJ *bin, RBinElfReloc *rel) {
1591 	ut64 tmp = get_got_entry (bin, rel);
1592 	if (tmp == UT64_MAX) {
1593 		return get_import_addr_x86_manual (bin, rel);
1594 	}
1595 
1596 	RBinElfSection *pltsec_section = get_section_by_name (bin, ".plt.sec");
1597 	if (pltsec_section) {
1598 		ut64 got_addr = bin->dyn_info.dt_pltgot;
1599 		ut64 pos = COMPUTE_PLTGOT_POSITION (rel, got_addr, 0x3);
1600 		return pltsec_section->rva + pos * X86_PLT_ENTRY_SIZE;
1601 	}
1602 
1603 	return tmp + X86_OFFSET_PLT_ENTRY_FROM_GOT_ADDR;
1604 }
1605 
1606 static ut64 get_import_addr(ELFOBJ *bin, int sym) {
1607 	if ((!bin->shdr || !bin->strtab) && !bin->phdr) {
1608 		return UT64_MAX;
1609 	}
1610 
1611 	if (!bin->rel_cache) {
1612 		return UT64_MAX;
1613 	}
1614 
1615 	// lookup the right rel/rela entry
1616 	RBinElfReloc *rel = ht_up_find (bin->rel_cache, sym, NULL);
1617 	if (!rel) {
1618 		return UT64_MAX;
1619 	}
1620 
1621 	switch (bin->ehdr.e_machine) {
1622 	case EM_ARM:
1623 	case EM_AARCH64:
1624 		return get_import_addr_arm (bin, rel);
1625 	case EM_MIPS: // MIPS32 BIG ENDIAN relocs
1626 		return get_import_addr_mips (bin, rel);
1627 	case EM_RISCV:
1628 		return get_import_addr_riscv (bin, rel);
1629 	case EM_SPARC:
1630 	case EM_SPARCV9:
1631 	case EM_SPARC32PLUS:
1632 		return get_import_addr_sparc (bin, rel);
1633 	case EM_PPC:
1634 	case EM_PPC64:
1635 		return get_import_addr_ppc (bin, rel);
1636 	case EM_386:
1637 	case EM_X86_64:
1638 		return get_import_addr_x86 (bin, rel);
1639 	default:
1640 		eprintf ("Unsupported relocs type %" PFMT64u " for arch %d\n",
1641 				(ut64) rel->type, bin->ehdr.e_machine);
1642 		return UT64_MAX;
1643 	}
1644 }
1645 
1646 int Elf_(r_bin_elf_has_nx)(ELFOBJ *bin) {
1647 	r_return_val_if_fail (bin, 0);
1648 	int i;
1649 	if (bin && bin->phdr) {
1650 		for (i = 0; i < bin->ehdr.e_phnum; i++) {
1651 			if (bin->phdr[i].p_type == PT_GNU_STACK) {
1652 				return (!(bin->phdr[i].p_flags & 1))? 1: 0;
1653 			}
1654 		}
1655 	}
1656 	return 0;
1657 }
1658 
1659 int Elf_(r_bin_elf_has_relro)(ELFOBJ *bin) {
1660 	r_return_val_if_fail (bin, R_ELF_NO_RELRO);
1661 	bool haveBindNow = false;
1662 	bool haveGnuRelro = false;
1663 
1664 	if (bin->dyn_info.dt_bind_now) {
1665 		haveBindNow = true;
1666 	} else if (bin->dyn_info.dt_flags != R_BIN_ELF_XWORD_MAX && bin->dyn_info.dt_flags != R_BIN_ELF_XWORD_MAX) {
1667 		haveBindNow = bin->dyn_info.dt_flags_1 & DF_1_NOW;
1668 	}
1669 
1670 	if (bin->phdr) {
1671 		size_t i;
1672 		for (i = 0; i < bin->ehdr.e_phnum; i++) {
1673 			if (bin->phdr[i].p_type == PT_GNU_RELRO) {
1674 				haveGnuRelro = true;
1675 				break;
1676 			}
1677 		}
1678 	}
1679 	if (haveGnuRelro) {
1680 		if (haveBindNow) {
1681 			return R_ELF_FULL_RELRO;
1682 		}
1683 		return R_ELF_PART_RELRO;
1684 	}
1685 	return R_ELF_NO_RELRO;
1686 }
1687 
1688 /*
1689 To compute the base address, one determines the memory
1690 address associated with the lowest p_vaddr value for a
1691 PT_LOAD segment. One then obtains the base address by
1692 truncating the memory address to the nearest multiple
1693 of the maximum page size
1694 */
1695 
1696 ut64 Elf_(r_bin_elf_get_baddr)(ELFOBJ *bin) {
1697 	ut64 tmp, base = UT64_MAX;
1698 	if (!bin) {
1699 		return 0;
1700 	}
1701 	if (bin->phdr) {
1702 		size_t i;
1703 		for (i = 0; i < bin->ehdr.e_phnum; i++) {
1704 			if (bin->phdr[i].p_type == PT_LOAD) {
1705 				tmp = (ut64)bin->phdr[i].p_vaddr & ELF_PAGE_MASK;
1706 				tmp = tmp - (tmp % (1 << ELF_PAGE_SIZE));
1707 				if (tmp < base) {
1708 					base = tmp;
1709 				}
1710 			}
1711 		}
1712 	}
1713 	if (base == UT64_MAX && is_bin_etrel (bin)) {
1714 		//we return our own base address for ET_REL type
1715 		//we act as a loader for ELF
1716 		return 0x08000000;
1717 	}
1718 	return base == UT64_MAX? 0: base;
1719 }
1720 
1721 ut64 Elf_(r_bin_elf_get_boffset)(ELFOBJ *bin) {
1722 	ut64 tmp, base = UT64_MAX;
1723 	r_return_val_if_fail (bin, 0);
1724 
1725 	if (!bin->phdr) {
1726 		return 0;
1727 	}
1728 
1729 	size_t i;
1730 	for (i = 0; i < bin->ehdr.e_phnum; i++) {
1731 		if (bin->phdr[i].p_type == PT_LOAD) {
1732 			tmp = (ut64)bin->phdr[i].p_offset & ELF_PAGE_MASK;
1733 			tmp = tmp - (tmp % (1 << ELF_PAGE_SIZE));
1734 			if (tmp < base) {
1735 				base = tmp;
1736 			}
1737 		}
1738 	}
1739 	return base == UT64_MAX? 0: base;
1740 }
1741 
1742 ut64 Elf_(r_bin_elf_get_init_offset)(ELFOBJ *bin) {
1743 	ut64 entry = Elf_(r_bin_elf_get_entry_offset) (bin);
1744 	ut8 buf[128];
1745 	if (!bin || entry == UT64_MAX) {
1746 		return UT64_MAX;
1747 	}
1748 	if (r_buf_read_at (bin->b, entry + 16, buf, sizeof (buf)) < 1) {
1749 		bprintf ("read (init_offset)\n");
1750 		return 0;
1751 	}
1752 	if (buf[0] == 0x68) { // push // x86 only
1753 		ut64 addr;
1754 		memmove (buf, buf + 1, 4);
1755 		addr = (ut64)r_read_le32 (buf);
1756 		return Elf_(r_bin_elf_v2p) (bin, addr);
1757 	}
1758 	return 0;
1759 }
1760 
1761 ut64 Elf_(r_bin_elf_get_fini_offset)(ELFOBJ *bin) {
1762 	r_return_val_if_fail (bin, UT64_MAX);
1763 	ut64 entry = Elf_(r_bin_elf_get_entry_offset) (bin);
1764 	if (entry == UT64_MAX) {
1765 		return UT64_MAX;
1766 	}
1767 	ut8 buf[512];
1768 	if (r_buf_read_at (bin->b, entry + 11, buf, sizeof (buf)) == -1) {
1769 		bprintf ("read (get_fini)\n");
1770 		return 0;
1771 	}
1772 	if (*buf == 0x68) { // push // x86/32 only
1773 		memmove (buf, buf + 1, 4);
1774 		ut64 addr = (ut64)r_read_le32 (buf);
1775 		return Elf_(r_bin_elf_v2p) (bin, addr);
1776 	}
1777 	return 0;
1778 }
1779 
1780 ut64 Elf_(r_bin_elf_get_entry_offset)(ELFOBJ *bin) {
1781 	r_return_val_if_fail (bin, UT64_MAX);
1782 	ut64 entry = bin->ehdr.e_entry;
1783 	if (!entry) {
1784 		if (!Elf_(r_bin_elf_is_executable) (bin)) {
1785 			return UT64_MAX;
1786 		}
1787 		entry = Elf_(r_bin_elf_get_section_offset)(bin, ".init.text");
1788 		if (entry != UT64_MAX) {
1789 			return entry;
1790 		}
1791 		entry = Elf_(r_bin_elf_get_section_offset)(bin, ".text");
1792 		if (entry != UT64_MAX) {
1793 			return entry;
1794 		}
1795 		return Elf_(r_bin_elf_get_section_offset)(bin, ".init");
1796 	}
1797 	return Elf_(r_bin_elf_v2p) (bin, entry);
1798 }
1799 
1800 static ut64 getmainsymbol(ELFOBJ *bin) {
1801 	struct r_bin_elf_symbol_t *symbol = Elf_(r_bin_elf_get_symbols) (bin);
1802 	if (symbol) {
1803 		size_t i;
1804 		for (i = 0; !symbol[i].last; i++) {
1805 			if (!strcmp (symbol[i].name, "main")) {
1806 				return symbol[i].offset;
1807 			}
1808 		}
1809 	}
1810 	return UT64_MAX;
1811 }
1812 
1813 ut64 Elf_(r_bin_elf_get_main_offset)(ELFOBJ *bin) {
1814 	r_return_val_if_fail (bin, UT64_MAX);
1815 	ut64 entry = Elf_(r_bin_elf_get_entry_offset) (bin);
1816 	if (entry == UT64_MAX) {
1817 		return UT64_MAX;
1818 	}
1819 	ut8 buf[256];
1820 	if (entry > bin->size || (entry + sizeof (buf)) > bin->size) {
1821 		return UT64_MAX;
1822 	}
1823 	// unnecessary to read 512 bytes imho
1824 	if (r_buf_read_at (bin->b, entry, buf, sizeof (buf)) < 1) {
1825 		bprintf ("read (main)\n");
1826 		return UT64_MAX;
1827 	}
1828 	// ARM64
1829 	if (buf[0x18+3] == 0x58 && buf[0x2f] == 0x00) {
1830 		ut32 entry_vaddr = Elf_(r_bin_elf_p2v) (bin, entry);
1831 		ut32 main_addr = r_read_le32 (&buf[0x30]);
1832 		if ((main_addr >> 16) == (entry_vaddr >> 16)) {
1833 			return Elf_(r_bin_elf_v2p) (bin, main_addr);
1834 		}
1835 	}
1836 
1837 	// TODO: Use arch to identify arch before memcmp's
1838 
1839 	// ARM Glibc
1840 	if (entry & 1) {
1841 		int delta = 0;
1842 		/* thumb entry points */
1843 		if (!memcmp (buf, "\xf0\x00\x0b\x4f\xf0\x00\x0e\x02\xbc\x6a\x46", 11)) {
1844 			/* newer versions of gcc use push/pop */
1845 			delta = 0x28;
1846 		} else if (!memcmp (buf, "\xf0\x00\x0b\x4f\xf0\x00\x0e\x5d\xf8\x04\x1b", 11)) {
1847 			/* older versions of gcc (4.5.x) use ldr/str */
1848 			delta = 0x30;
1849 		}
1850 		if (delta) {
1851 			ut64 pa = Elf_(r_bin_elf_v2p) (bin, r_read_le32 (&buf[delta-1]) & ~1);
1852 			if (pa < r_buf_size (bin->b)) {
1853 				return pa;
1854 			}
1855 		}
1856 	} else {
1857 		/* non-thumb entry points */
1858 		if (!memcmp (buf, "\x00\xb0\xa0\xe3\x00\xe0\xa0\xe3", 8)) {
1859 			return Elf_(r_bin_elf_v2p) (bin, r_read_le32 (&buf[0x34]) & ~1);
1860 		}
1861 		if (!memcmp (buf, "\x24\xc0\x9f\xe5\x00\xb0\xa0\xe3", 8)) {
1862 			return Elf_(r_bin_elf_v2p) (bin, r_read_le32 (&buf[0x30]) & ~1);
1863 		}
1864 	}
1865 
1866 	// MIPS
1867 	/* get .got, calculate offset of main symbol */
1868 	if (!memcmp (buf, "\x21\x00\xe0\x03\x01\x00\x11\x04", 8)) {
1869 
1870 		/*
1871 		    assuming the startup code looks like
1872 		        got = gp-0x7ff0
1873 		        got[index__libc_start_main] ( got[index_main] );
1874 
1875 		    looking for the instruction generating the first argument to find main
1876 		        lw a0, offset(gp)
1877 		*/
1878 
1879 		ut64 got_offset;
1880 		if ((got_offset = Elf_(r_bin_elf_get_section_offset) (bin, ".got")) != -1 ||
1881 		    (got_offset = Elf_(r_bin_elf_get_section_offset) (bin, ".got.plt")) != -1)
1882 		{
1883 			const ut64 gp = got_offset + 0x7ff0;
1884 			size_t i, len = sizeof (buf) / sizeof (buf[0]);
1885 			for (i = 0; i < len; i += 4) {
1886 				const ut32 instr = r_read_le32 (&buf[i]);
1887 				if ((instr & 0xffff0000) == 0x8f840000) { // lw a0, offset(gp)
1888 					const short delta = instr & 0x0000ffff;
1889 					r_buf_read_at (bin->b, /* got_entry_offset = */ gp + delta, buf, 4);
1890 					return Elf_(r_bin_elf_v2p) (bin, r_read_le32 (&buf[0]));
1891 				}
1892 			}
1893 		}
1894 
1895 		return 0;
1896 	}
1897 	// X86-CGC
1898 	if (buf[0] == 0xe8 && !memcmp (buf + 5, "\x50\xe8\x00\x00\x00\x00\xb8\x01\x00\x00\x00\x53", 12)) {
1899 		size_t SIZEOF_CALL = 5;
1900 		ut64 rel_addr = (ut64)((int)(buf[1] + (buf[2] << 8) + (buf[3] << 16) + (buf[4] << 24)));
1901 		ut64 addr = Elf_(r_bin_elf_p2v)(bin, entry + SIZEOF_CALL);
1902 		addr += rel_addr;
1903 		return Elf_(r_bin_elf_v2p) (bin, addr);
1904 	}
1905 	// X86-PIE
1906 	if (buf[0x00] == 0x48 && buf[0x1e] == 0x8d && buf[0x11] == 0xe8) {
1907 		ut32 *pmain = (ut32*)(buf + 0x30);
1908 		ut64 vmain = Elf_(r_bin_elf_p2v) (bin, (ut64)*pmain);
1909 		ut64 ventry = Elf_(r_bin_elf_p2v) (bin, entry);
1910 		if (vmain >> 16 == ventry >> 16) {
1911 			return (ut64)vmain;
1912 		}
1913 	}
1914 	// X86-PIE
1915 	if (buf[0x1d] == 0x48 && buf[0x1e] == 0x8b) {
1916 		if (!memcmp (buf, "\x31\xed\x49\x89", 4)) {// linux
1917 			ut64 maddr, baddr;
1918 			ut8 n32s[sizeof (ut32)] = {0};
1919 			maddr = entry + 0x24 + r_read_le32 (buf + 0x20);
1920 			if (r_buf_read_at (bin->b, maddr, n32s, sizeof (ut32)) == -1) {
1921 				bprintf ("read (maddr) 2\n");
1922 				return 0;
1923 			}
1924 			maddr = (ut64)r_read_le32 (&n32s[0]);
1925 			baddr = (bin->ehdr.e_entry >> 16) << 16;
1926 			if (bin->phdr) {
1927 				baddr = Elf_(r_bin_elf_get_baddr) (bin);
1928 			}
1929 			maddr += baddr;
1930 			return maddr;
1931 		}
1932 	}
1933 	// X86-NONPIE
1934 #if R_BIN_ELF64
1935 	if (!memcmp (buf, "\x49\x89\xd9", 3) && buf[156] == 0xe8) { // openbsd
1936 		return r_read_le32 (&buf[157]) + entry + 156 + 5;
1937 	}
1938 	if (!memcmp (buf+29, "\x48\xc7\xc7", 3)) { // linux
1939 		ut64 addr = (ut64)r_read_le32 (&buf[29 + 3]);
1940 		return Elf_(r_bin_elf_v2p) (bin, addr);
1941 	}
1942 #else
1943 	if (buf[23] == '\x68') {
1944 		ut64 addr = (ut64)r_read_le32 (&buf[23 + 1]);
1945 		return Elf_(r_bin_elf_v2p) (bin, addr);
1946 	}
1947 #endif
1948 	/* linux64 pie main -- probably buggy in some cases */
1949 	int bo = 29; // Begin offset may vary depending on the entry prelude
1950 	// endbr64 - fedora bins have this
1951 	if (buf[0] == 0xf3 && buf[1] == 0x0f && buf[2] == 0x1e && buf[3] == 0xfa) {
1952 		// Change begin offset if binary starts with 'endbr64'
1953 		bo = 33;
1954 	}
1955 	if (buf[bo] == 0x48) {
1956 		ut8 ch = buf[bo + 1];
1957 		if (ch == 0x8d) { // lea rdi, qword [rip-0x21c4]
1958 			ut8 *p = buf + bo + 3;
1959 			st32 maindelta = (st32)r_read_le32 (p);
1960 			ut64 vmain = (ut64)(entry + bo + maindelta) + 7;
1961 			ut64 ventry = Elf_(r_bin_elf_p2v) (bin, entry);
1962 			if (vmain>>16 == ventry>>16) {
1963 				return (ut64)vmain;
1964 			}
1965 		} else if (0xc7) { // mov rdi, 0xADDR
1966 			ut8 *p = buf + bo + 3;
1967 			return (ut64)(ut32)r_read_le32 (p);
1968 		}
1969 	}
1970 
1971 	/* find sym.main if possible */
1972 	{
1973 		ut64 m = getmainsymbol (bin);
1974 		if (m != UT64_MAX) {
1975 			return m;
1976 		}
1977 	}
1978 	return UT64_MAX;
1979 }
1980 
1981 bool Elf_(r_bin_elf_get_stripped)(ELFOBJ *bin) {
1982 	if (!bin->shdr) {
1983 		return false;
1984 	}
1985 	size_t i;
1986 	for (i = 0; i < bin->ehdr.e_shnum; i++) {
1987 		if (bin->shdr[i].sh_type == SHT_SYMTAB) {
1988 			return false;
1989 		}
1990 	}
1991 	return true;
1992 }
1993 
1994 char *Elf_(r_bin_elf_intrp)(ELFOBJ *bin) {
1995 	int i;
1996 	if (!bin || !bin->phdr) {
1997 		return NULL;
1998 	}
1999 	for (i = 0; i < bin->ehdr.e_phnum; i++) {
2000 		if (bin->phdr[i].p_type == PT_INTERP) {
2001 			ut64 addr = bin->phdr[i].p_offset;
2002 			int sz = bin->phdr[i].p_filesz;
2003 			sdb_num_set (bin->kv, "elf_header.intrp_addr", addr, 0);
2004 			sdb_num_set (bin->kv, "elf_header.intrp_size", sz, 0);
2005 			if (sz < 1 || sz > r_buf_size (bin->b)) {
2006 				return NULL;
2007 			}
2008 			char *str = malloc (sz + 1);
2009 			if (!str) {
2010 				return NULL;
2011 			}
2012 			if (r_buf_read_at (bin->b, addr, (ut8*)str, sz) < 1) {
2013 				bprintf ("read (main)\n");
2014 				free (str);
2015 				return 0;
2016 			}
2017 			str[sz] = 0;
2018 			sdb_set (bin->kv, "elf_header.intrp", str, 0);
2019 			return str;
2020 		}
2021 	}
2022 	return NULL;
2023 }
2024 
2025 bool Elf_(r_bin_elf_is_static)(ELFOBJ *bin) {
2026 	size_t i;
2027 	if (!bin->phdr) {
2028 		return false;
2029 	}
2030 	for (i = 0; i < bin->ehdr.e_phnum; i++) {
2031 		if (bin->phdr[i].p_type == PT_INTERP ||
2032 			bin->phdr[i].p_type == PT_DYNAMIC) {
2033 			return false;
2034 		}
2035 	}
2036 	return true;
2037 }
2038 
2039 char* Elf_(r_bin_elf_get_data_encoding)(ELFOBJ *bin) {
2040 	switch (bin->ehdr.e_ident[EI_DATA]) {
2041 	case ELFDATANONE: return strdup ("none");
2042 	case ELFDATA2LSB: return strdup ("2's complement, little endian");
2043 	case ELFDATA2MSB: return strdup ("2's complement, big endian");
2044 	default: return r_str_newf ("<unknown: %x>", bin->ehdr.e_ident[EI_DATA]);
2045 	}
2046 }
2047 
2048 int Elf_(r_bin_elf_has_va)(ELFOBJ *bin) {
2049 	return true;
2050 }
2051 
2052 char* Elf_(r_bin_elf_get_arch)(ELFOBJ *bin) {
2053 	switch (bin->ehdr.e_machine) {
2054 	case EM_ARC:
2055 	case EM_ARC_A5:
2056 		return strdup ("arc");
2057 	case EM_AVR: return strdup ("avr");
2058 	case EM_BA2_NON_STANDARD:
2059 	case EM_BA2: return strdup ("ba2");
2060 	case EM_CRIS: return strdup ("cris");
2061 	case EM_68K: return strdup ("m68k");
2062 	case EM_MIPS:
2063 	case EM_MIPS_RS3_LE:
2064 	case EM_MIPS_X:
2065 		return strdup ("mips");
2066 	case EM_MCST_ELBRUS:
2067 		return strdup ("elbrus");
2068 	case EM_TRICORE:
2069 		return strdup ("tricore");
2070 	case EM_RCE:
2071 		return strdup ("mcore");
2072 	case EM_ARM:
2073 	case EM_AARCH64:
2074 		return strdup ("arm");
2075 	case EM_QDSP6: // EM_HEXAGON
2076 		return strdup ("hexagon");
2077 	case EM_BLACKFIN:
2078 		return strdup ("blackfin");
2079 	case EM_SPARC:
2080 	case EM_SPARC32PLUS:
2081 	case EM_SPARCV9:
2082 		return strdup ("sparc");
2083 	case EM_PPC:
2084 	case EM_PPC64:
2085 		return strdup ("ppc");
2086 	case EM_PARISC:
2087 		return strdup ("hppa");
2088 	case EM_PROPELLER:
2089 		return strdup ("propeller");
2090 	case EM_MICROBLAZE:
2091 		return strdup ("microblaze.gnu");
2092 	case EM_RISCV:
2093 		return strdup ("riscv");
2094 	case EM_VAX:
2095 		return strdup ("vax");
2096 	case EM_XTENSA:
2097 		return strdup ("xtensa");
2098 	case EM_LANAI:
2099 		return strdup ("lanai");
2100 	case EM_VIDEOCORE3:
2101 	case EM_VIDEOCORE4:
2102 		return strdup ("vc4");
2103 	case EM_MSP430:
2104 		return strdup ("msp430");
2105 	case EM_SH:
2106 		return strdup ("sh");
2107 	case EM_V800:
2108 		return strdup ("v850");
2109 	case EM_V850:
2110 		return strdup ("v850");
2111 	case EM_IA_64:
2112 		return strdup ("ia64");
2113 	case EM_S390:
2114 		return strdup ("sysz");
2115 	default: return strdup ("x86");
2116 	}
2117 }
2118 char* Elf_(r_bin_elf_get_abi)(ELFOBJ *bin) {
2119 	Elf_(Ehdr)* ehdr = (Elf_(Ehdr) *) &bin->ehdr;
2120 
2121 	if (ehdr->e_machine == EM_MIPS) {
2122 		if (is_elfclass64 (ehdr)) {
2123 			return strdup ("n64");
2124 		}
2125 		if (is_mips_n32 (ehdr)) {
2126 			return strdup ("n32");
2127 		}
2128 		if (is_mips_o32 (ehdr)) {
2129 			return strdup ("o32");
2130 		}
2131 	}
2132 	return NULL;
2133 }
2134 
2135 char* Elf_(r_bin_elf_get_cpu)(ELFOBJ *bin) {
2136 	if (bin->phdr && bin->ehdr.e_machine == EM_MIPS) {
2137 		const ut32 mipsType = bin->ehdr.e_flags & EF_MIPS_ARCH;
2138 		switch (mipsType) {
2139 		case EF_MIPS_ARCH_1:        return strdup ("mips1");
2140 		case EF_MIPS_ARCH_2:        return strdup ("mips2");
2141 		case EF_MIPS_ARCH_3:        return strdup ("mips3");
2142 		case EF_MIPS_ARCH_4:        return strdup ("mips4");
2143 		case EF_MIPS_ARCH_5:        return strdup ("mips5");
2144 		case EF_MIPS_ARCH_32:       return strdup ("mips32");
2145 		case EF_MIPS_ARCH_64:       return strdup ("mips64");
2146 		case EF_MIPS_ARCH_32R2:     return strdup ("mips32r2");
2147 		case EF_MIPS_ARCH_64R2:     return strdup ("mips64r2");
2148 		default :                   return strdup (" Unknown mips ISA");
2149 		}
2150 	}
2151 	return NULL;
2152 }
2153 
2154 char* Elf_(r_bin_elf_get_head_flag)(ELFOBJ *bin) {
2155 	char *head_flag = NULL;
2156 	char *str = Elf_(r_bin_elf_get_cpu) (bin);
2157 	if (str) {
2158 		head_flag = r_str_append (head_flag, str);
2159 	}
2160 	str = Elf_(r_bin_elf_get_abi) (bin);
2161 	if (str) {
2162 		head_flag = r_str_appendf (head_flag, " %s", str);
2163 	}
2164 	if (R_STR_ISEMPTY (head_flag)) {
2165 		head_flag = r_str_append (head_flag, "unknown_flag");
2166 	}
2167 	return head_flag;
2168 }
2169 
2170 // http://www.sco.com/developers/gabi/latest/ch4.eheader.html
2171 
2172 char* Elf_(r_bin_elf_get_machine_name)(ELFOBJ *bin) {
2173 	switch (bin->ehdr.e_machine) {
2174 	case EM_NONE:          return strdup ("No machine");
2175 	case EM_M32:           return strdup ("AT&T WE 32100");
2176 	case EM_SPARC:         return strdup ("SUN SPARC");
2177 	case EM_386:           return strdup ("Intel 80386");
2178 	case EM_68K:           return strdup ("Motorola m68k family");
2179 	case EM_88K:           return strdup ("Motorola m88k family");
2180 	case EM_860:           return strdup ("Intel 80860");
2181 	case EM_MIPS:          return strdup ("MIPS R3000");
2182 	case EM_S370:          return strdup ("IBM System/370");
2183 	case EM_MIPS_RS3_LE:   return strdup ("MIPS R3000 little-endian");
2184 	case EM_PARISC:        return strdup ("HPPA");
2185 	case EM_VPP500:        return strdup ("Fujitsu VPP500");
2186 	case EM_SPARC32PLUS:   return strdup ("Sun's \"v8plus\"");
2187 	case EM_960:           return strdup ("Intel 80960");
2188 	case EM_PPC:           return strdup ("PowerPC");
2189 	case EM_PPC64:         return strdup ("PowerPC 64-bit");
2190 	case EM_S390:          return strdup ("IBM S390");
2191 	case EM_V800:          return strdup ("NEC V800 series");
2192 	case EM_FR20:          return strdup ("Fujitsu FR20");
2193 	case EM_RH32:          return strdup ("TRW RH-32");
2194 	case EM_RCE:           return strdup ("Motorola RCE");
2195 	case EM_ARM:           return strdup ("ARM");
2196 	case EM_BLACKFIN:      return strdup ("Analog Devices Blackfin");
2197 	case EM_FAKE_ALPHA:    return strdup ("Digital Alpha");
2198 	case EM_SH:            return strdup ("Hitachi SH");
2199 	case EM_SPARCV9:       return strdup ("SPARC v9 64-bit");
2200 	case EM_TRICORE:       return strdup ("Siemens Tricore");
2201 	case EM_ARC:           return strdup ("Argonaut RISC Core");
2202 	case EM_H8_300:        return strdup ("Hitachi H8/300");
2203 	case EM_H8_300H:       return strdup ("Hitachi H8/300H");
2204 	case EM_H8S:           return strdup ("Hitachi H8S");
2205 	case EM_H8_500:        return strdup ("Hitachi H8/500");
2206 	case EM_IA_64:         return strdup ("Intel Merced");
2207 	case EM_MIPS_X:        return strdup ("Stanford MIPS-X");
2208 	case EM_COLDFIRE:      return strdup ("Motorola Coldfire");
2209 	case EM_68HC12:        return strdup ("Motorola M68HC12");
2210 	case EM_MMA:           return strdup ("Fujitsu MMA Multimedia Accelerator");
2211 	case EM_PCP:           return strdup ("Siemens PCP");
2212 	case EM_NCPU:          return strdup ("Sony nCPU embeeded RISC");
2213 	case EM_NDR1:          return strdup ("Denso NDR1 microprocessor");
2214 	case EM_STARCORE:      return strdup ("Motorola Start*Core processor");
2215 	case EM_ME16:          return strdup ("Toyota ME16 processor");
2216 	case EM_ST100:         return strdup ("STMicroelectronic ST100 processor");
2217 	case EM_TINYJ:         return strdup ("Advanced Logic Corp. Tinyj emb.fam");
2218 	case EM_X86_64:        return strdup ("AMD x86-64 architecture");
2219 	case EM_LANAI:         return strdup ("32bit LANAI architecture");
2220 	case EM_PDSP:          return strdup ("Sony DSP Processor");
2221 	case EM_PDP10:         return strdup ("Digital Equipment Corp. PDP-10");
2222 	case EM_PDP11:         return strdup ("Digital Equipment Corp. PDP-11");
2223 	case EM_FX66:          return strdup ("Siemens FX66 microcontroller");
2224 	case EM_ST9PLUS:       return strdup ("STMicroelectronics ST9+ 8/16 mc");
2225 	case EM_ST7:           return strdup ("STmicroelectronics ST7 8 bit mc");
2226 	case EM_68HC16:        return strdup ("Motorola MC68HC16 microcontroller");
2227 	case EM_68HC11:        return strdup ("Motorola MC68HC11 microcontroller");
2228 	case EM_68HC08:        return strdup ("Motorola MC68HC08 microcontroller");
2229 	case EM_68HC05:        return strdup ("Motorola MC68HC05 microcontroller");
2230 	case EM_SVX:           return strdup ("Silicon Graphics SVx");
2231 	case EM_ST19:          return strdup ("STMicroelectronics ST19 8 bit mc");
2232 	case EM_VAX:           return strdup ("Digital VAX");
2233 	case EM_CRIS:          return strdup ("Axis Communications 32-bit embedded processor");
2234 	case EM_JAVELIN:       return strdup ("Infineon Technologies 32-bit embedded processor");
2235 	case EM_FIREPATH:      return strdup ("Element 14 64-bit DSP Processor");
2236 	case EM_ZSP:           return strdup ("LSI Logic 16-bit DSP Processor");
2237 	case EM_MMIX:          return strdup ("Donald Knuth's educational 64-bit processor");
2238 	case EM_HUANY:         return strdup ("Harvard University machine-independent object files");
2239 	case EM_PRISM:         return strdup ("SiTera Prism");
2240 	case EM_AVR:           return strdup ("Atmel AVR 8-bit microcontroller");
2241 	case EM_FR30:          return strdup ("Fujitsu FR30");
2242 	case EM_D10V:          return strdup ("Mitsubishi D10V");
2243 	case EM_D30V:          return strdup ("Mitsubishi D30V");
2244 	case EM_V850:          return strdup ("NEC v850");
2245 	case EM_M32R:          return strdup ("Mitsubishi M32R");
2246 	case EM_MN10300:       return strdup ("Matsushita MN10300");
2247 	case EM_MN10200:       return strdup ("Matsushita MN10200");
2248 	case EM_PJ:            return strdup ("picoJava");
2249 	case EM_OPENRISC:      return strdup ("OpenRISC 32-bit embedded processor");
2250 	case EM_ARC_A5:        return strdup ("ARC Cores Tangent-A5");
2251 	case EM_XTENSA:        return strdup ("Tensilica Xtensa Architecture");
2252 	case EM_AARCH64:       return strdup ("ARM aarch64");
2253 	case EM_PROPELLER:     return strdup ("Parallax Propeller");
2254 	case EM_MICROBLAZE:    return strdup ("Xilinx MicroBlaze");
2255 	case EM_RISCV:         return strdup ("RISC V");
2256 	case EM_VIDEOCORE3:    return strdup ("VideoCore III");
2257 	case EM_VIDEOCORE4:    return strdup ("VideoCore IV");
2258 	case EM_LATTICEMICO32: return strdup ("RISC processor for Lattice FPGA architecture");
2259 	case EM_SE_C17:        return strdup ("Seiko Epson C17 family");
2260 	case EM_TI_C6000:      return strdup ("The Texas Instruments TMS320C6000 DSP family");
2261 	case EM_TI_C2000:      return strdup ("The Texas Instruments TMS320C2000 DSP family");
2262 	case EM_TI_C5500:      return strdup ("The Texas Instruments TMS320C55x DSP family");
2263 	case EM_TI_ARP32:      return strdup ("Texas Instruments Application Specific RISC Processor, 32bit fetch");
2264 	case EM_TI_PRU:        return strdup ("Texas Instruments Programmable Realtime Unit");
2265 	case EM_MMDSP_PLUS:    return strdup ("STMicroelectronics 64bit VLIW Data Signal Processor");
2266 	case EM_CYPRESS_M8C:   return strdup ("Cypress M8C microprocessor");
2267 	case EM_R32C:          return strdup ("Renesas R32C series microprocessors");
2268 	case EM_TRIMEDIA:      return strdup ("NXP Semiconductors TriMedia architecture family");
2269 	case EM_QDSP6:         return strdup ("QUALCOMM DSP6 Processor");  // Nonstandard
2270 	case EM_8051:          return strdup ("Intel 8051 and variants");
2271 	case EM_STXP7X:        return strdup ("STMicroelectronics STxP7x family of configurable and extensible RISC processors");
2272 	case EM_NDS32:         return strdup ("Andes Technology compact code size embedded RISC processor family");
2273 	case EM_ECOG1:         return strdup ("Cyan Technology eCOG1X family");
2274 	// case EM_ECOG1X:        return strdup ("Cyan Technology eCOG1X family");  // Nonstandard
2275 	case EM_MAXQ30:        return strdup ("Dallas Semiconductor MAXQ30 Core Micro-controllers");
2276 	case EM_XIMO16:        return strdup ("New Japan Radio (NJR) 16-bit DSP Processor");
2277 	case EM_MANIK:         return strdup ("M2000 Reconfigurable RISC Microprocessor");
2278 	case EM_CRAYNV2:       return strdup ("Cray Inc. NV2 vector architecture");
2279 	case EM_RX:            return strdup ("Renesas RX family");
2280 	case EM_METAG:         return strdup ("Imagination Technologies META processor architecture");
2281 	case EM_MCST_ELBRUS:   return strdup ("MCST Elbrus general purpose hardware architecture");
2282 	case EM_ECOG16:        return strdup ("Cyan Technology eCOG16 family");
2283 	case EM_CR16:          return strdup ("National Semiconductor CompactRISC CR16 16-bit microprocessor");
2284 	case EM_ETPU:          return strdup ("Freescale Extended Time Processing Unit");
2285 	case EM_SLE9X:         return strdup ("Infineon Technologies SLE9X core");
2286 	case EM_L10M:          return strdup ("Intel L10M");
2287 	case EM_K10M:          return strdup ("Intel K10M");
2288 	// case EM_AARCH64:       return strdup ("ARM 64-bit architecture (AARCH64)");  // Nonstandard
2289 	case EM_AVR32:         return strdup ("Atmel Corporation 32-bit microprocessor family");
2290 	case EM_STM8:          return strdup ("STMicroeletronics STM8 8-bit microcontroller");
2291 	case EM_TILE64:        return strdup ("Tilera TILE64 multicore architecture family");
2292 	case EM_TILEPRO:       return strdup ("Tilera TILEPro multicore architecture family");
2293 	// case EM_MICROBLAZE:    return strdup ("Xilinx MicroBlaze 32-bit RISC soft processor core");  // Nonstandard
2294 	case EM_CUDA:          return strdup ("NVIDIA CUDA architecture");
2295 	case EM_TILEGX:        return strdup ("Tilera TILE-Gx multicore architecture family");
2296 	case EM_CLOUDSHIELD:   return strdup ("CloudShield architecture family");
2297 	case EM_COREA_1ST:     return strdup ("KIPO-KAIST Core-A 1st generation processor family");
2298 	case EM_COREA_2ND:     return strdup ("KIPO-KAIST Core-A 2nd generation processor family");
2299 	case EM_ARC_COMPACT2:  return strdup ("Synopsys ARCompact V2");
2300 	case EM_OPEN8:         return strdup ("Open8 8-bit RISC soft processor core");
2301 	case EM_RL78:          return strdup ("Renesas RL78 family");
2302 	case EM_VIDEOCORE5:    return strdup ("Broadcom VideoCore V processor");
2303 	case EM_78KOR:         return strdup ("Renesas 78KOR family");
2304 	// case EM_56800EX:       return strdup ("Freescale 56800EX Digital Signal Controller (DSC)");  // Nonstandard
2305 	case EM_BA1:           return strdup ("Beyond BA1 CPU architecture");
2306 	case EM_BA2_NON_STANDARD:
2307 	case EM_BA2:           return strdup ("Beyond BA2 CPU architecture");
2308 	case EM_XCORE:         return strdup ("XMOS xCORE processor family");
2309 	case EM_MCHP_PIC:      return strdup ("Microchip 8-bit PIC(r) family");
2310 	case EM_INTEL205:      return strdup ("Reserved by Intel");
2311 	case EM_INTEL206:      return strdup ("Reserved by Intel");
2312 	case EM_INTEL207:      return strdup ("Reserved by Intel");
2313 	case EM_INTEL208:      return strdup ("Reserved by Intel");
2314 	case EM_INTEL209:      return strdup ("Reserved by Intel");
2315 	case EM_KM32:          return strdup ("KM211 KM32 32-bit processor");
2316 	case EM_KMX32:         return strdup ("KM211 KMX32 32-bit processor");
2317 	case EM_KMX16:         return strdup ("KM211 KMX16 16-bit processor");
2318 	case EM_KMX8:          return strdup ("KM211 KMX8 8-bit processor");
2319 	case EM_KVARC:         return strdup ("KM211 KVARC processor");
2320 	case EM_CDP:           return strdup ("Paneve CDP architecture family");
2321 	case EM_COGE:          return strdup ("Cognitive Smart Memory Processor");
2322 	case EM_COOL:          return strdup ("Bluechip Systems CoolEngine");
2323 	case EM_NORC:          return strdup ("Nanoradio Optimized RISC");
2324 	case EM_CSR_KALIMBA:   return strdup ("CSR Kalimba architecture family");
2325 	case EM_Z80:           return strdup ("Zilog Z80");
2326 	case EM_VISIUM:        return strdup ("Controls and Data Services VISIUMcore processor");
2327 	case EM_FT32:          return strdup ("FTDI Chip FT32 high performance 32-bit RISC architecture");
2328 	case EM_MOXIE:         return strdup ("Moxie processor family");
2329 	case EM_AMDGPU:        return strdup ("AMD GPU architecture");
2330 
2331 	default:             return r_str_newf ("<unknown>: 0x%x", bin->ehdr.e_machine);
2332 	}
2333 }
2334 
2335 char* Elf_(r_bin_elf_get_file_type)(ELFOBJ *bin) {
2336 	r_return_val_if_fail (bin, NULL);
2337 	ut32 e_type = (ut32)bin->ehdr.e_type; // cast to avoid warn in iphone-gcc, must be ut16
2338 	switch (e_type) {
2339 	case ET_NONE: return strdup ("NONE (None)");
2340 	case ET_REL:  return strdup ("REL (Relocatable file)");
2341 	case ET_EXEC: return strdup ("EXEC (Executable file)");
2342 	case ET_DYN:  return strdup ("DYN (Shared object file)");
2343 	case ET_CORE: return strdup ("CORE (Core file)");
2344 	}
2345 	if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC)) {
2346 		return r_str_newf ("Processor Specific: %x", e_type);
2347 	}
2348 	if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS)) {
2349 		return r_str_newf ("OS Specific: %x", e_type);
2350 	}
2351 	return r_str_newf ("<unknown>: %x", e_type);
2352 }
2353 
2354 char* Elf_(r_bin_elf_get_elf_class)(ELFOBJ *bin) {
2355 	switch (bin->ehdr.e_ident[EI_CLASS]) {
2356 	case ELFCLASSNONE: return strdup ("none");
2357 	case ELFCLASS32:   return strdup ("ELF32");
2358 	case ELFCLASS64:   return strdup ("ELF64");
2359 	default:           return r_str_newf ("<unknown: %x>", bin->ehdr.e_ident[EI_CLASS]);
2360 	}
2361 }
2362 
2363 int Elf_(r_bin_elf_get_bits)(ELFOBJ *bin) {
2364 	/* Hack for ARCompact */
2365 	if (bin->ehdr.e_machine == EM_ARC_A5) {
2366 		return 16;
2367 	}
2368 	/* Hack for Ps2 */
2369 	if (bin->phdr && bin->ehdr.e_machine == EM_MIPS) {
2370 		const ut32 mipsType = bin->ehdr.e_flags & EF_MIPS_ARCH;
2371 		if (bin->ehdr.e_type == ET_EXEC) {
2372 			int i;
2373 			bool haveInterp = false;
2374 			for (i = 0; i < bin->ehdr.e_phnum; i++) {
2375 				if (bin->phdr[i].p_type == PT_INTERP) {
2376 					haveInterp = true;
2377 				}
2378 			}
2379 			if (!haveInterp && mipsType == EF_MIPS_ARCH_3) {
2380 				// Playstation2 Hack
2381 				return 64;
2382 			}
2383 		}
2384 		// TODO: show this specific asm.cpu somewhere in bininfo (mips1, mips2, mips3, mips32r2, ...)
2385 		switch (mipsType) {
2386 		case EF_MIPS_ARCH_1:
2387 		case EF_MIPS_ARCH_2:
2388 		case EF_MIPS_ARCH_3:
2389 		case EF_MIPS_ARCH_4:
2390 		case EF_MIPS_ARCH_5:
2391 		case EF_MIPS_ARCH_32:
2392 			return 32;
2393 		case EF_MIPS_ARCH_64:
2394 			return 64;
2395 		case EF_MIPS_ARCH_32R2:
2396 			return 32;
2397 		case EF_MIPS_ARCH_64R2:
2398 			return 64;
2399 			break;
2400 		}
2401 		return 32;
2402 	}
2403 	/* Hack for Thumb */
2404 	if (bin->ehdr.e_machine == EM_ARM) {
2405 		if (bin->ehdr.e_type != ET_EXEC) {
2406 			struct r_bin_elf_symbol_t *symbol;
2407 			if ((symbol = Elf_(r_bin_elf_get_symbols) (bin))) {
2408 				int i = 0;
2409 				for (i = 0; !symbol[i].last; i++) {
2410 					ut64 paddr = symbol[i].offset;
2411 					if (paddr & 1) {
2412 						return 16;
2413 					}
2414 				}
2415 			}
2416 		}
2417 		ut64 entry = Elf_(r_bin_elf_get_entry_offset) (bin);
2418 		if (entry & 1) {
2419 			return 16;
2420 		}
2421 	}
2422 	switch (bin->ehdr.e_ident[EI_CLASS]) {
2423 	case ELFCLASS32:   return 32;
2424 	case ELFCLASS64:   return 64;
2425 	case ELFCLASSNONE:
2426 	default:           return 32; // defaults
2427 	}
2428 }
2429 
2430 static inline int noodle(ELFOBJ *bin, const char *s) {
2431 	if (r_buf_size (bin->b) <= 64)  {
2432 		return 0;
2433 	}
2434 	ut8 tmp[64];
2435 	r_buf_read_at (bin->b, r_buf_size (bin->b) - 64, tmp, 64);
2436 	return r_mem_mem (tmp, 64, (const ut8 *)s, strlen (s)) != NULL;
2437 }
2438 
2439 static inline int needle(ELFOBJ *bin, const char *s) {
2440 	if (bin->shstrtab) {
2441 		ut32 len = bin->shstrtab_size;
2442 		if (len > 4096) {
2443 			len = 4096; // avoid slow loading .. can be buggy?
2444 		}
2445 		return r_mem_mem ((const ut8*)bin->shstrtab, len,
2446 				(const ut8*)s, strlen (s)) != NULL;
2447 	}
2448 	return 0;
2449 }
2450 
2451 // TODO: must return const char * all those strings must be const char os[LINUX] or so
2452 char* Elf_(r_bin_elf_get_osabi_name)(ELFOBJ *bin) {
2453 	size_t i;
2454 	size_t num = bin->ehdr.e_shnum;
2455 	const char *section_name = NULL;
2456 	switch (bin->ehdr.e_ident[EI_OSABI]) {
2457 	case ELFOSABI_LINUX: return strdup("linux");
2458 	case ELFOSABI_SOLARIS: return strdup("solaris");
2459 	case ELFOSABI_FREEBSD: return strdup("freebsd");
2460 	case ELFOSABI_HPUX: return strdup("hpux");
2461 	}
2462 
2463 	if (bin->shdr && bin->shstrtab) {
2464 		for (i = 0; i < num; i++) {
2465 			if (bin->shdr[i].sh_type == SHT_NOTE && bin->shdr[i].sh_name < bin->shstrtab_size) {
2466 				section_name = &bin->shstrtab[bin->shdr[i].sh_name];
2467 				if (!strcmp (section_name, ".note.openbsd.ident")) {
2468 					return strdup ("openbsd");
2469 				}
2470 				if (!strcmp (section_name, ".note.minix.ident")) {
2471 					return strdup ("minix");
2472 				}
2473 				if (!strcmp (section_name, ".note.netbsd.ident")) {
2474 					return strdup ("netbsd");
2475 				}
2476 				if (!strcmp (section_name, ".note.android.ident")) {
2477 					return strdup ("android");
2478 				}
2479 			}
2480 		}
2481 	}
2482 	/* Hack to identify OS */
2483 	if (needle (bin, "freebsd")) {
2484 		return strdup ("freebsd");
2485 	}
2486 	if (noodle (bin, "BEOS:APP_VERSION")) {
2487 		return strdup ("beos");
2488 	}
2489 	if (needle (bin, "GNU")) {
2490 		return strdup ("linux");
2491 	}
2492 	return strdup ("linux");
2493 }
2494 
2495 ut8 *Elf_(r_bin_elf_grab_regstate)(ELFOBJ *bin, int *len) {
2496 	if (bin->phdr) {
2497 		size_t i;
2498 		int num = bin->ehdr.e_phnum;
2499 		for (i = 0; i < num; i++) {
2500 			if (bin->phdr[i].p_type != PT_NOTE) {
2501 				continue;
2502 			}
2503 			int bits = Elf_(r_bin_elf_get_bits)(bin);
2504 			int elf_nhdr_size = (bits == 64) ? sizeof (Elf64_Nhdr) : sizeof (Elf32_Nhdr);
2505 			void *elf_nhdr = calloc (elf_nhdr_size, 1);
2506 			bool regs_found = false;
2507 			ut64 offset = 0;
2508 
2509 			while (!regs_found) {
2510 				ut32 n_descsz, n_namesz, n_type;
2511 				int ret;
2512 				ret = r_buf_read_at (bin->b, bin->phdr[i].p_offset + offset, elf_nhdr, elf_nhdr_size);
2513 				if (ret != elf_nhdr_size) {
2514 					bprintf ("Cannot read NOTES hdr from CORE file\n");
2515 					free (elf_nhdr);
2516 					return NULL;
2517 				}
2518 				if (bits == 64) {
2519 					n_descsz = round_up (((Elf64_Nhdr *)elf_nhdr)->n_descsz);
2520 					n_namesz = round_up (((Elf64_Nhdr *)elf_nhdr)->n_namesz);
2521 					n_type = ((Elf64_Nhdr *)elf_nhdr)->n_type;
2522 				} else {
2523 					n_descsz = round_up (((Elf32_Nhdr *)elf_nhdr)->n_descsz);
2524 					n_namesz = round_up (((Elf32_Nhdr *)elf_nhdr)->n_namesz);
2525 					n_type = ((Elf32_Nhdr *)elf_nhdr)->n_type;
2526 				}
2527 				if (n_type == NT_PRSTATUS) {
2528 					regs_found = true;
2529 					free (elf_nhdr);
2530 				} else {
2531 					offset += elf_nhdr_size + n_descsz + n_namesz;
2532 				}
2533 			}
2534 
2535 			int regdelta = 0;
2536 			int regsize = 0;
2537 			switch (bin->ehdr.e_machine) {
2538 				case EM_AARCH64:
2539 					regsize = reginf[AARCH64].regsize;
2540 					regdelta = reginf[AARCH64].regdelta;
2541 					break;
2542 				case EM_ARM:
2543 					regsize = reginf[ARM].regsize;
2544 					regdelta = reginf[ARM].regdelta;
2545 					break;
2546 				case EM_386:
2547 					regsize = reginf[X86].regsize;
2548 					regdelta = reginf[X86].regdelta;
2549 					break;
2550 				case EM_X86_64:
2551 					regsize = reginf[X86_64].regsize;
2552 					regdelta = reginf[X86_64].regdelta;
2553 					break;
2554 			}
2555 			ut8 *buf = malloc (regsize);
2556 			if (r_buf_read_at (bin->b, bin->phdr[i].p_offset + offset + regdelta, buf, regsize) != regsize) {
2557 				free (buf);
2558 				bprintf ("Cannot read register state from CORE file\n");
2559 				return NULL;
2560 			}
2561 			if (len) {
2562 				*len = regsize;
2563 			}
2564 			return buf;
2565 		}
2566 	}
2567 	bprintf ("Cannot find NOTE section\n");
2568 	return NULL;
2569 }
2570 
2571 int Elf_(r_bin_elf_is_big_endian)(ELFOBJ *bin) {
2572 	return (bin->ehdr.e_ident[EI_DATA] == ELFDATA2MSB);
2573 }
2574 
2575 /* XXX Init dt_strtab? */
2576 char *Elf_(r_bin_elf_get_rpath)(ELFOBJ *bin) {
2577 	r_return_val_if_fail (bin, NULL);
2578 	char *ret;
2579 	Elf_(Xword) val;
2580 
2581 	if (!bin->phdr || !bin->strtab) {
2582 		return NULL;
2583 	}
2584 
2585 	if (bin->dyn_info.dt_rpath != R_BIN_ELF_XWORD_MAX)  {
2586 		val = bin->dyn_info.dt_rpath;
2587 	} else if (bin->dyn_info.dt_runpath != R_BIN_ELF_XWORD_MAX) {
2588 		val = bin->dyn_info.dt_runpath;
2589 	} else {
2590 		return NULL;
2591 	}
2592 
2593 	if (val > bin->strtab_size) {
2594 		return NULL;
2595 	}
2596 
2597 	if (!(ret = calloc (1, ELF_STRING_LENGTH))) {
2598 		return NULL;
2599 	}
2600 
2601 	r_str_ncpy (ret, bin->strtab + val, ELF_STRING_LENGTH);
2602 
2603 	return ret;
2604 }
2605 
2606 static bool has_valid_section_header(ELFOBJ *bin, size_t pos) {
2607 	return bin->g_sections[pos].info < bin->ehdr.e_shnum && bin->shdr;
2608 }
2609 
2610 static void fix_rva_and_offset_relocable_file(ELFOBJ *bin, RBinElfReloc *r, size_t pos) {
2611 	if (has_valid_section_header (bin, pos)) {
2612 		r->rva = bin->shdr[bin->g_sections[pos].info].sh_offset + r->offset;
2613 		r->rva = Elf_(r_bin_elf_p2v) (bin, r->rva);
2614 	} else {
2615 		r->rva = r->offset;
2616 	}
2617 }
2618 
2619 static void fix_rva_and_offset_exec_file(ELFOBJ *bin, RBinElfReloc *r) {
2620 	r->rva = r->offset;
2621 	r->offset = Elf_(r_bin_elf_v2p) (bin, r->offset);
2622 }
2623 
2624 static void fix_rva_and_offset(ELFOBJ *bin, RBinElfReloc *r, size_t pos) {
2625 	if (is_bin_etrel (bin)) {
2626 		fix_rva_and_offset_relocable_file (bin, r, pos);
2627 	} else {
2628 		fix_rva_and_offset_exec_file (bin, r);
2629 	}
2630 }
2631 
2632 static bool read_reloc(ELFOBJ *bin, RBinElfReloc *r, Elf_(Xword) rel_mode, ut64 vaddr) {
2633 	ut64 offset = Elf_(r_bin_elf_v2p_new) (bin, vaddr);
2634 	if (offset == UT64_MAX) {
2635 		return false;
2636 	}
2637 
2638 	size_t size_struct = get_size_rel_mode (rel_mode);
2639 
2640 	ut8 buf[sizeof (Elf_(Rela))] = { 0 };
2641 	int res = r_buf_read_at (bin->b, offset, buf, size_struct);
2642 	if (res != size_struct) {
2643 		return false;
2644 	}
2645 
2646 	size_t i = 0;
2647 	Elf_(Rela) reloc_info;
2648 
2649 	reloc_info.r_offset = R_BIN_ELF_READWORD (buf, i);
2650 	reloc_info.r_info = R_BIN_ELF_READWORD (buf, i);
2651 
2652 	if (rel_mode == DT_RELA) {
2653 		reloc_info.r_addend = R_BIN_ELF_READWORD (buf, i);
2654 		r->addend = reloc_info.r_addend;
2655 	}
2656 
2657 	r->rel_mode = rel_mode;
2658 	r->last = 0;
2659 	r->offset = reloc_info.r_offset;
2660 	r->sym = ELF_R_SYM (reloc_info.r_info);
2661 	r->type = ELF_R_TYPE (reloc_info.r_info);
2662 
2663 	return true;
2664 }
2665 
2666 static size_t get_num_relocs_dynamic(ELFOBJ *bin) {
2667 	size_t res = 0;
2668 
2669 	if (bin->dyn_info.dt_relaent) {
2670 		res += bin->dyn_info.dt_relasz / bin->dyn_info.dt_relaent;
2671 	}
2672 
2673 	if (bin->dyn_info.dt_relent) {
2674 		res += bin->dyn_info.dt_relsz / bin->dyn_info.dt_relent;
2675 	}
2676 
2677 	return res + get_num_relocs_dynamic_plt (bin);
2678 }
2679 
2680 static bool sectionIsValid(ELFOBJ *bin, RBinElfSection *sect) {
2681 	return (sect->offset + sect->size <= bin->size);
2682 }
2683 
2684 static Elf_(Xword) get_section_mode(ELFOBJ *bin, size_t pos) {
2685 	if (r_str_startswith (bin->g_sections[pos].name, ".rela.")) {
2686 		return DT_RELA;
2687 	}
2688 	if (r_str_startswith (bin->g_sections[pos].name, ".rel.")) {
2689 		return DT_REL;
2690 	}
2691 	return 0;
2692 }
2693 
2694 static bool is_reloc_section(Elf_(Xword) rel_mode) {
2695 	return rel_mode == DT_REL || rel_mode == DT_RELA;
2696 }
2697 
2698 static size_t get_num_relocs_sections(ELFOBJ *bin) {
2699 	size_t i, size, ret = 0;
2700 	Elf_(Xword) rel_mode;
2701 
2702 	if (!bin->g_sections) {
2703 		return 0;
2704 	}
2705 
2706 	for (i = 0; !bin->g_sections[i].last; i++) {
2707 		if (!sectionIsValid (bin, &bin->g_sections[i])) {
2708 			continue;
2709 		}
2710 		rel_mode = get_section_mode (bin, i);
2711 		if (!is_reloc_section (rel_mode)) {
2712 			continue;
2713 		}
2714 		size = get_size_rel_mode (rel_mode);
2715 		ret += NUMENTRIES_ROUNDUP (bin->g_sections[i].size, size);
2716 	}
2717 
2718 	return ret;
2719 }
2720 
2721 static size_t get_num_relocs_approx(ELFOBJ *bin) {
2722 	return get_num_relocs_dynamic (bin) + get_num_relocs_sections (bin);
2723 }
2724 
2725 static size_t populate_relocs_record_from_dynamic(ELFOBJ *bin, RBinElfReloc *relocs, size_t pos, size_t num_relocs) {
2726 	size_t offset;
2727 	size_t size = get_size_rel_mode (bin->dyn_info.dt_pltrel);
2728 
2729 	for (offset = 0; offset < bin->dyn_info.dt_pltrelsz && pos < num_relocs; offset += size, pos++) {
2730 		if (!read_reloc (bin, relocs + pos, bin->dyn_info.dt_pltrel, bin->dyn_info.dt_jmprel + offset)) {
2731 			break;
2732 		}
2733 		fix_rva_and_offset_exec_file (bin, relocs + pos);
2734 	}
2735 
2736 	for (offset = 0; offset < bin->dyn_info.dt_relasz && pos < num_relocs; offset += bin->dyn_info.dt_relaent, pos++) {
2737 		if (!read_reloc (bin, relocs + pos, DT_RELA, bin->dyn_info.dt_rela + offset)) {
2738 			break;
2739 		}
2740 		fix_rva_and_offset_exec_file (bin, relocs + pos);
2741 	}
2742 
2743 	for (offset = 0; offset < bin->dyn_info.dt_relsz && pos < num_relocs; offset += bin->dyn_info.dt_relent, pos++) {
2744 		if (!read_reloc (bin, relocs + pos, DT_REL, bin->dyn_info.dt_rel + offset)) {
2745 			break;
2746 		}
2747 		fix_rva_and_offset_exec_file (bin, relocs + pos);
2748 	}
2749 
2750 	return pos;
2751 }
2752 
2753 static size_t get_next_not_analysed_offset(ELFOBJ *bin, size_t section_vaddr, size_t offset) {
2754 	size_t gvaddr = section_vaddr + offset;
2755 
2756 	if (bin->dyn_info.dt_rela != R_BIN_ELF_ADDR_MAX && bin->dyn_info.dt_rela <= gvaddr
2757 		&& gvaddr < bin->dyn_info.dt_rela + bin->dyn_info.dt_relasz) {
2758 		return bin->dyn_info.dt_rela + bin->dyn_info.dt_relasz - section_vaddr;
2759 	}
2760 
2761 	if (bin->dyn_info.dt_rel != R_BIN_ELF_ADDR_MAX && bin->dyn_info.dt_rel <= gvaddr
2762 		&& gvaddr < bin->dyn_info.dt_rel + bin->dyn_info.dt_relsz) {
2763 		return bin->dyn_info.dt_rel + bin->dyn_info.dt_relsz - section_vaddr;
2764 	}
2765 
2766 	if (bin->dyn_info.dt_jmprel != R_BIN_ELF_ADDR_MAX && bin->dyn_info.dt_jmprel <= gvaddr
2767 		&& gvaddr < bin->dyn_info.dt_jmprel + bin->dyn_info.dt_pltrelsz) {
2768 		return bin->dyn_info.dt_jmprel + bin->dyn_info.dt_pltrelsz - section_vaddr;
2769 	}
2770 
2771 	return offset;
2772 }
2773 
2774 static size_t populate_relocs_record_from_section(ELFOBJ *bin, RBinElfReloc *relocs, size_t pos, size_t num_relocs) {
2775 	size_t size, i, j;
2776 	Elf_(Xword) rel_mode;
2777 
2778 	if (!bin->g_sections) {
2779 		return pos;
2780 	}
2781 
2782 	for (i = 0; !bin->g_sections[i].last; i++) {
2783 		rel_mode = get_section_mode (bin, i);
2784 
2785 		if (!is_reloc_section (rel_mode) || bin->g_sections[i].size > bin->size || bin->g_sections[i].offset > bin->size) {
2786 			continue;
2787 		}
2788 
2789 		size = get_size_rel_mode (rel_mode);
2790 
2791 		for (j = get_next_not_analysed_offset (bin, bin->g_sections[i].rva, 0);
2792 			j < bin->g_sections[i].size && pos < num_relocs;
2793 			j = get_next_not_analysed_offset (bin, bin->g_sections[i].rva, j + size)) {
2794 
2795 			if (!read_reloc (bin, relocs + pos, rel_mode, bin->g_sections[i].rva + j)) {
2796 				break;
2797 			}
2798 
2799 			fix_rva_and_offset (bin, relocs + pos, i);
2800 			pos++;
2801 		}
2802 	}
2803 
2804 	return pos;
2805 }
2806 
2807 static RBinElfReloc *populate_relocs_record(ELFOBJ *bin) {
2808 	size_t i = 0;
2809 	size_t num_relocs = get_num_relocs_approx (bin);
2810 	RBinElfReloc *relocs = R_NEWS0 (RBinElfReloc, num_relocs + 1);
2811 	if (!relocs) {
2812 		// In case we can't allocate enough memory for all the claimed
2813 		// relocation entries, try to parse only the ones specified in
2814 		// the dynamic segment.
2815 		num_relocs = get_num_relocs_dynamic (bin);
2816 		relocs = R_NEWS0 (RBinElfReloc, num_relocs + 1);
2817 		if (!relocs) {
2818 			return NULL;
2819 		}
2820 	}
2821 
2822 	i = populate_relocs_record_from_dynamic (bin, relocs, i, num_relocs);
2823 	i = populate_relocs_record_from_section (bin, relocs, i, num_relocs);
2824 	relocs[i].last = 1;
2825 
2826 	bin->g_reloc_num = i;
2827 	return relocs;
2828 }
2829 
2830 RBinElfReloc* Elf_(r_bin_elf_get_relocs) (ELFOBJ *bin) {
2831 	if (!bin) {
2832 		return NULL;
2833 	}
2834 
2835 	if (!bin->g_relocs) {
2836 		bin->g_relocs = populate_relocs_record (bin);
2837 	}
2838 	return bin->g_relocs;
2839 }
2840 
2841 RBinElfLib* Elf_(r_bin_elf_get_libs)(ELFOBJ *bin) {
2842 	RBinElfLib *ret = NULL;
2843 	Elf_(Off) *it = NULL;
2844 	size_t k = 0;
2845 
2846 	if (!bin || !bin->phdr || !bin->strtab || *(bin->strtab+1) == '0') {
2847 		return NULL;
2848 	}
2849 
2850 	r_vector_foreach(&bin->dyn_info.dt_needed, it) {
2851 		Elf_(Off) val = *it;
2852 
2853 		RBinElfLib *r = realloc (ret, (k + 1) * sizeof (RBinElfLib));
2854 		if (!r) {
2855 			perror ("realloc (libs)");
2856 			free (ret);
2857 			return NULL;
2858 		}
2859 		ret = r;
2860 		if (val > bin->strtab_size) {
2861 			free (ret);
2862 			return NULL;
2863 		}
2864 		strncpy (ret[k].name, bin->strtab + val, ELF_STRING_LENGTH);
2865 		ret[k].name[ELF_STRING_LENGTH - 1] = '\0';
2866 		ret[k].last = 0;
2867 		if (ret[k].name[0]) {
2868 			k++;
2869 		}
2870 	}
2871 
2872 	RBinElfLib *r = realloc (ret, (k + 1) * sizeof (RBinElfLib));
2873 	if (!r) {
2874 		perror ("realloc (libs)");
2875 		free (ret);
2876 		return NULL;
2877 	}
2878 	ret = r;
2879 	ret[k].last = 1;
2880 	return ret;
2881 }
2882 
2883 static void create_section_from_phdr(ELFOBJ *bin, RBinElfSection *ret, size_t *i, const char *name, ut64 addr, ut64 sz) {
2884 	if (!addr) {
2885 		return;
2886 	}
2887 
2888 	ret[*i].offset = Elf_(r_bin_elf_v2p_new) (bin, addr);
2889 	ret[*i].rva = addr;
2890 	ret[*i].size = sz;
2891 	strncpy (ret[*i].name, name, R_ARRAY_SIZE (ret[*i].name) - 1);
2892 	ret[*i].name[R_ARRAY_SIZE (ret[*i].name) - 1] = '\0';
2893 	ret[*i].last = 0;
2894 	*i = *i + 1;
2895 }
2896 
2897 static RBinElfSection *get_sections_from_phdr(ELFOBJ *bin) {
2898 	RBinElfSection *ret;
2899 	size_t num_sections = 0;
2900 	ut64 reldyn = 0, relava = 0, pltgotva = 0, relva = 0;
2901 	ut64 reldynsz = 0, relasz = 0, pltgotsz = 0;
2902 	r_return_val_if_fail (bin && bin->phdr, NULL);
2903 
2904 	if (!bin->ehdr.e_phnum) {
2905 		return NULL;
2906 	}
2907 
2908 	if (bin->dyn_info.dt_rel != R_BIN_ELF_ADDR_MAX) {
2909 		reldyn = bin->dyn_info.dt_rel;
2910 		num_sections++;
2911 	}
2912 	if (bin->dyn_info.dt_rela != R_BIN_ELF_ADDR_MAX) {
2913 		relva = bin->dyn_info.dt_rela;
2914 		num_sections++;
2915 	}
2916 	if (bin->dyn_info.dt_relsz) {
2917 		reldynsz = bin->dyn_info.dt_relsz;
2918 	}
2919 	if (bin->dyn_info.dt_relasz) {
2920 		relasz = bin->dyn_info.dt_relasz;
2921 	}
2922 	if (bin->dyn_info.dt_pltgot != R_BIN_ELF_ADDR_MAX) {
2923 		pltgotva = bin->dyn_info.dt_pltgot;
2924 		num_sections++;
2925 	}
2926 	if (bin->dyn_info.dt_pltrelsz) {
2927 		pltgotsz = bin->dyn_info.dt_pltrelsz;
2928 	}
2929 	if (bin->dyn_info.dt_jmprel != R_BIN_ELF_ADDR_MAX) {
2930 		relava = bin->dyn_info.dt_jmprel;
2931 		num_sections++;
2932 	}
2933 
2934 	ret = calloc (num_sections + 1, sizeof (RBinElfSection));
2935 	if (!ret) {
2936 		return NULL;
2937 	}
2938 
2939 	size_t i = 0;
2940 	create_section_from_phdr (bin, ret, &i, ".rel.dyn", reldyn, reldynsz);
2941 	create_section_from_phdr (bin, ret, &i, ".rela.plt", relava, pltgotsz);
2942 	create_section_from_phdr (bin, ret, &i, ".rel.plt", relva, relasz);
2943 	create_section_from_phdr (bin, ret, &i, ".got.plt", pltgotva, pltgotsz);
2944 	ret[i].last = 1;
2945 
2946 	return ret;
2947 }
2948 
2949 RBinElfSection* Elf_(r_bin_elf_get_sections)(ELFOBJ *bin) {
2950 	RBinElfSection *ret = NULL;
2951 	char unknown_s[32], invalid_s[32];
2952 	int i, nidx, unknown_c=0, invalid_c=0;
2953 
2954 	r_return_val_if_fail (bin, NULL);
2955 	if (bin->g_sections) {
2956 		return bin->g_sections;
2957 	}
2958 	if (!bin->shdr && bin->phdr) {
2959 		//we don't give up search in phdr section
2960 		return get_sections_from_phdr (bin);
2961 	}
2962 	if (!bin->shdr) {
2963 		return NULL;
2964 	}
2965 	if (!(ret = calloc ((bin->ehdr.e_shnum + 1), sizeof (RBinElfSection)))) {
2966 		return NULL;
2967 	}
2968 	for (i = 0; i < bin->ehdr.e_shnum; i++) {
2969 		ret[i].offset = bin->shdr[i].sh_offset;
2970 		ret[i].size = bin->shdr[i].sh_size;
2971 		ret[i].align = bin->shdr[i].sh_addralign;
2972 		ret[i].flags = bin->shdr[i].sh_flags;
2973 		ret[i].link = bin->shdr[i].sh_link;
2974 		ret[i].info = bin->shdr[i].sh_info;
2975 		ret[i].type = bin->shdr[i].sh_type;
2976 		if (is_bin_etrel (bin)) {
2977 			ret[i].rva = bin->baddr + bin->shdr[i].sh_offset;
2978 		} else {
2979 			ret[i].rva = bin->shdr[i].sh_addr;
2980 		}
2981 
2982 		const int SHNAME = (int)bin->shdr[i].sh_name;
2983 		const int SHSIZE = (int)bin->shstrtab_size;
2984 		nidx = SHNAME;
2985 		if (nidx < 0 || !bin->shstrtab_section || !bin->shstrtab_size || nidx > bin->shstrtab_size) {
2986 			snprintf (invalid_s, sizeof (invalid_s), "invalid%d", invalid_c);
2987 			strncpy (ret[i].name, invalid_s, sizeof (ret[i].name) - 1);
2988 			invalid_c++;
2989 		} else if (bin->shstrtab && (SHNAME > 0) && (SHNAME < SHSIZE)) {
2990 			strncpy (ret[i].name, &bin->shstrtab[SHNAME], sizeof (ret[i].name) - 1);
2991 		} else if (bin->shdr[i].sh_type == SHT_NULL) {
2992 			//to follow the same behaviour as readelf
2993 			ret[i].name[0] = '\0';
2994 		} else {
2995 			snprintf (unknown_s, sizeof (unknown_s), "unknown%d", unknown_c);
2996 			strncpy (ret[i].name, unknown_s, sizeof (ret[i].name) - 1);
2997 			unknown_c++;
2998 		}
2999 		ret[i].name[ELF_STRING_LENGTH - 1] = '\0';
3000 		ret[i].last = 0;
3001 	}
3002 	ret[i].last = 1;
3003 	return ret;
3004 }
3005 
3006 static bool is_special_arm_symbol(ELFOBJ *bin, Elf_(Sym) *sym, const char *name) {
3007 	if (name[0] != '$') {
3008 		return false;
3009 	}
3010 	switch (name[1]) {
3011 	case 'a':
3012 	case 't':
3013 	case 'd':
3014 	case 'x':
3015 		return (name[2] == '\0' || name[2] == '.') &&
3016 			ELF_ST_TYPE (sym->st_info) == STT_NOTYPE &&
3017 			ELF_ST_BIND (sym->st_info) == STB_LOCAL &&
3018 			ELF_ST_VISIBILITY (sym->st_info) == STV_DEFAULT;
3019 	default:
3020 		return false;
3021 	}
3022 }
3023 
3024 static bool is_special_symbol(ELFOBJ *bin, Elf_(Sym) *sym, const char *name) {
3025 	switch (bin->ehdr.e_machine) {
3026 	case EM_ARM:
3027 	case EM_AARCH64:
3028 		return is_special_arm_symbol (bin, sym, name);
3029 	default:
3030 		return false;
3031 	}
3032 }
3033 
3034 static const char *bind2str(Elf_(Sym) *sym) {
3035 	switch (ELF_ST_BIND (sym->st_info)) {
3036 	case STB_LOCAL:  return R_BIN_BIND_LOCAL_STR;
3037 	case STB_GLOBAL: return R_BIN_BIND_GLOBAL_STR;
3038 	case STB_WEAK:   return R_BIN_BIND_WEAK_STR;
3039 	case STB_NUM:    return R_BIN_BIND_NUM_STR;
3040 	case STB_LOOS:   return R_BIN_BIND_LOOS_STR;
3041 	case STB_HIOS:   return R_BIN_BIND_HIOS_STR;
3042 	case STB_LOPROC: return R_BIN_BIND_LOPROC_STR;
3043 	case STB_HIPROC: return R_BIN_BIND_HIPROC_STR;
3044 	default:         return R_BIN_BIND_UNKNOWN_STR;
3045 	}
3046 }
3047 
3048 static const char *type2str(ELFOBJ *bin, struct r_bin_elf_symbol_t *ret, Elf_(Sym) *sym) {
3049 	if (bin && ret && is_special_symbol (bin, sym, ret->name)) {
3050 		return R_BIN_TYPE_SPECIAL_SYM_STR;
3051 	}
3052 	switch (ELF_ST_TYPE (sym->st_info)) {
3053 	case STT_NOTYPE: return R_BIN_TYPE_NOTYPE_STR;
3054 	case STT_OBJECT: return R_BIN_TYPE_OBJECT_STR;
3055 	case STT_FUNC: return R_BIN_TYPE_FUNC_STR;
3056 	case STT_SECTION: return R_BIN_TYPE_SECTION_STR;
3057 	case STT_FILE: return R_BIN_TYPE_FILE_STR;
3058 	case STT_COMMON: return R_BIN_TYPE_COMMON_STR;
3059 	case STT_TLS: return R_BIN_TYPE_TLS_STR;
3060 	case STT_NUM: return R_BIN_TYPE_NUM_STR;
3061 	case STT_LOOS: return R_BIN_TYPE_LOOS_STR;
3062 	case STT_HIOS: return R_BIN_TYPE_HIOS_STR;
3063 	case STT_LOPROC: return R_BIN_TYPE_LOPROC_STR;
3064 	case STT_HIPROC: return R_BIN_TYPE_HIPROC_STR;
3065 	default: return R_BIN_TYPE_UNKNOWN_STR;
3066 	}
3067 }
3068 
3069 static void fill_symbol_bind_and_type(ELFOBJ *bin, struct r_bin_elf_symbol_t *ret, Elf_(Sym) *sym) {
3070 	ret->bind = bind2str (sym);
3071 	ret->type = type2str (bin, ret, sym);
3072 }
3073 
3074 static RBinElfSymbol* get_symbols_from_phdr(ELFOBJ *bin, int type) {
3075 	Elf_(Sym) *sym = NULL;
3076 	Elf_(Addr) addr_sym_table = 0;
3077 	ut8 s[sizeof (Elf_(Sym))] = {0};
3078 	RBinElfSymbol *ret = NULL;
3079 	int i, r, tsize, nsym, ret_ctr;
3080 	ut64 toffset = 0, tmp_offset;
3081 	ut32 size, sym_size = 0;
3082 
3083 	if (!bin || !bin->phdr || !bin->ehdr.e_phnum) {
3084 		return NULL;
3085 	}
3086 
3087 	if (bin->dyn_info.dt_symtab == R_BIN_ELF_ADDR_MAX || !bin->dyn_info.dt_syment) {
3088 		return NULL;
3089 	}
3090 
3091 	addr_sym_table = Elf_(r_bin_elf_v2p) (bin, bin->dyn_info.dt_symtab);
3092 	sym_size = bin->dyn_info.dt_syment;
3093 	if (!sym_size) {
3094 		goto beach;
3095 	}
3096 
3097 	//since ELF doesn't specify the symbol table size we may read until the end of the buffer
3098 	nsym = (bin->size - addr_sym_table) / sym_size;
3099 	if (!UT32_MUL (&size, nsym, sizeof (Elf_ (Sym)))) {
3100 		goto beach;
3101 	}
3102 	if (size < 1) {
3103 		goto beach;
3104 	}
3105 	if (addr_sym_table > bin->size || addr_sym_table + size > bin->size) {
3106 		goto beach;
3107 	}
3108 	if (nsym < 1) {
3109 		return NULL;
3110 	}
3111 	// we reserve room for 4096 and grow as needed.
3112 	size_t capacity1 = 4096;
3113 	size_t capacity2 = 4096;
3114 	sym = (Elf_(Sym)*) calloc (capacity1, sym_size);
3115 	ret = (RBinElfSymbol *) calloc (capacity2, sizeof (struct r_bin_elf_symbol_t));
3116 	if (!sym || !ret) {
3117 		goto beach;
3118 	}
3119 	for (i = 1, ret_ctr = 0; i < nsym; i++) {
3120 		if (i >= capacity1) { // maybe grow
3121 			// You take what you want, but you eat what you take.
3122 			Elf_(Sym)* temp_sym = (Elf_(Sym)*) realloc (sym, (capacity1 * GROWTH_FACTOR) * sym_size);
3123 			if (!temp_sym) {
3124 				goto beach;
3125 			}
3126 			sym = temp_sym;
3127 			capacity1 *= GROWTH_FACTOR;
3128 		}
3129 		if (ret_ctr >= capacity2) { // maybe grow
3130 			RBinElfSymbol *temp_ret = realloc (ret, capacity2 * GROWTH_FACTOR * sizeof (struct r_bin_elf_symbol_t));
3131 			if (!temp_ret) {
3132 				goto beach;
3133 			}
3134 			ret = temp_ret;
3135 			capacity2 *= GROWTH_FACTOR;
3136 		}
3137 		// read in one entry
3138 		r = r_buf_read_at (bin->b, addr_sym_table + i * sizeof (Elf_ (Sym)), s, sizeof (Elf_ (Sym)));
3139 		if (r < 1) {
3140 			goto beach;
3141 		}
3142 		int j = 0;
3143 #if R_BIN_ELF64
3144 		sym[i].st_name = READ32 (s, j);
3145 		sym[i].st_info = READ8 (s, j);
3146 		sym[i].st_other = READ8 (s, j);
3147 		sym[i].st_shndx = READ16 (s, j);
3148 		sym[i].st_value = READ64 (s, j);
3149 		sym[i].st_size = READ64 (s, j);
3150 #else
3151 		sym[i].st_name = READ32 (s, j);
3152 		sym[i].st_value = READ32 (s, j);
3153 		sym[i].st_size = READ32 (s, j);
3154 		sym[i].st_info = READ8 (s, j);
3155 		sym[i].st_other = READ8 (s, j);
3156 		sym[i].st_shndx = READ16 (s, j);
3157 #endif
3158 		bool is_sht_null = false;
3159 		bool is_vaddr = false;
3160 		// zero symbol is always empty
3161 		// Examine entry and maybe store
3162 		if (type == R_BIN_ELF_IMPORT_SYMBOLS && sym[i].st_shndx == SHT_NULL) {
3163 			if (sym[i].st_value) {
3164 				toffset = sym[i].st_value;
3165 			} else if ((toffset = get_import_addr (bin, i)) == -1){
3166 				toffset = 0;
3167 			}
3168 			tsize = 16;
3169 		} else if (type == R_BIN_ELF_ALL_SYMBOLS) {
3170 			tsize = sym[i].st_size;
3171 			toffset = (ut64) sym[i].st_value;
3172 			is_sht_null = sym[i].st_shndx == SHT_NULL;
3173 		} else {
3174 			continue;
3175 		}
3176 		// since we don't know the size of the sym table in this case,
3177 		// let's stop at the first invalid entry
3178 		if (!strcmp (bind2str (&sym[i]), R_BIN_BIND_UNKNOWN_STR) ||
3179 		    !strcmp (type2str (NULL, NULL, &sym[i]), R_BIN_TYPE_UNKNOWN_STR)) {
3180 			goto done;
3181 		}
3182 		tmp_offset = Elf_(r_bin_elf_v2p_new) (bin, toffset);
3183 		if (tmp_offset == UT64_MAX) {
3184 			tmp_offset = toffset;
3185 			is_vaddr = true;
3186 		}
3187 		if (sym[i].st_name + 2 > bin->strtab_size) {
3188 			// Since we are reading beyond the symbol table what's happening
3189 			// is that some entry is trying to dereference the strtab beyond its capacity
3190 			// is not a symbol so is the end
3191 			goto done;
3192 		}
3193 		ret[ret_ctr].offset = tmp_offset;
3194 		ret[ret_ctr].size = tsize;
3195 		{
3196 			int rest = ELF_STRING_LENGTH - 1;
3197 			int st_name = sym[i].st_name;
3198 			int maxsize = R_MIN (bin->size, bin->strtab_size);
3199 			if (st_name < 0 || st_name >= maxsize) {
3200 				ret[ret_ctr].name[0] = 0;
3201 			} else {
3202 				const int len = __strnlen (bin->strtab + st_name, rest);
3203 				memcpy (ret[ret_ctr].name, &bin->strtab[st_name], len);
3204 			}
3205 		}
3206 		ret[ret_ctr].ordinal = i;
3207 		ret[ret_ctr].in_shdr = false;
3208 		ret[ret_ctr].name[ELF_STRING_LENGTH - 2] = '\0';
3209 		fill_symbol_bind_and_type (bin, &ret[ret_ctr], &sym[i]);
3210 		ret[ret_ctr].is_sht_null = is_sht_null;
3211 		ret[ret_ctr].is_vaddr = is_vaddr;
3212 		ret[ret_ctr].last = 0;
3213 		ret_ctr++;
3214 	}
3215 done:
3216 	// Size everything down to only what is used
3217 	{
3218 		nsym = i > 0? i: 1;
3219 		Elf_(Sym) *temp_sym = (Elf_(Sym) *)realloc (sym, (nsym * GROWTH_FACTOR) * sym_size);
3220 		if (!temp_sym) {
3221 			goto beach;
3222 		}
3223 		sym = temp_sym;
3224 	}
3225 	{
3226 		ret_ctr = ret_ctr > 0? ret_ctr: 1;
3227 		RBinElfSymbol *p = (RBinElfSymbol *)realloc (ret, (ret_ctr + 1) * sizeof (RBinElfSymbol));
3228 		if (!p) {
3229 			goto beach;
3230 		}
3231 		ret = p;
3232 	}
3233 	ret[ret_ctr].last = 1;
3234 	if (type == R_BIN_ELF_IMPORT_SYMBOLS && !bin->imports_by_ord_size) {
3235 		bin->imports_by_ord_size = ret_ctr + 1;
3236 		if (ret_ctr > 0) {
3237 			bin->imports_by_ord = (RBinImport * *) calloc (ret_ctr + 1, sizeof (RBinImport*));
3238 		} else {
3239 			bin->imports_by_ord = NULL;
3240 		}
3241 	} else if (type == R_BIN_ELF_ALL_SYMBOLS && !bin->symbols_by_ord_size && ret_ctr) {
3242 		bin->symbols_by_ord_size = ret_ctr + 1;
3243 		if (ret_ctr > 0) {
3244 			bin->symbols_by_ord = (RBinSymbol * *) calloc (ret_ctr + 1, sizeof (RBinSymbol*));
3245 		} else {
3246 			bin->symbols_by_ord = NULL;
3247 		}
3248 	}
3249 	free (sym);
3250 	return ret;
3251 beach:
3252 	free (sym);
3253 	free (ret);
3254 	return NULL;
3255 }
3256 
3257 static RBinElfSymbol *Elf_(r_bin_elf_get_phdr_symbols)(ELFOBJ *bin) {
3258 	if (!bin) {
3259 		return NULL;
3260 	}
3261 	if (bin->phdr_symbols) {
3262 		return bin->phdr_symbols;
3263 	}
3264 	bin->phdr_symbols = get_symbols_from_phdr (bin, R_BIN_ELF_ALL_SYMBOLS);
3265 	return bin->phdr_symbols;
3266 }
3267 
3268 static RBinElfSymbol *Elf_(r_bin_elf_get_phdr_imports)(ELFOBJ *bin) {
3269 	r_return_val_if_fail (bin, NULL);
3270 	if (!bin->phdr_imports) {
3271 		bin->phdr_imports = get_symbols_from_phdr (bin, R_BIN_ELF_IMPORT_SYMBOLS);
3272 	}
3273 	return bin->phdr_imports;
3274 }
3275 
3276 static RBinElfSymbol *Elf_(get_phdr_symbols)(ELFOBJ *bin, int type) {
3277 	return (type != R_BIN_ELF_IMPORT_SYMBOLS)
3278 		? Elf_(r_bin_elf_get_phdr_symbols) (bin)
3279 		: Elf_(r_bin_elf_get_phdr_imports) (bin);
3280 }
3281 
3282 static int Elf_(fix_symbols)(ELFOBJ *bin, int nsym, int type, RBinElfSymbol **sym) {
3283 	int count = 0;
3284 	int result = -1;
3285 	RBinElfSymbol *ret = *sym;
3286 	RBinElfSymbol *phdr_symbols = Elf_(get_phdr_symbols) (bin, type);
3287 	RBinElfSymbol *tmp, *p;
3288 	HtUP *phd_offset_map = ht_up_new0 ();
3289 	HtUP *phd_ordinal_map = ht_up_new0 ();
3290 	if (phdr_symbols) {
3291 		RBinElfSymbol *d = ret;
3292 		while (!d->last) {
3293 			ht_up_insert (phd_offset_map, d->offset, d);
3294 			ht_up_insert (phd_ordinal_map, d->ordinal, d);
3295 			d++;
3296 		}
3297 		p = phdr_symbols;
3298 		while (!p->last) {
3299 			/* find match in phdr */
3300 			d = ht_up_find (phd_offset_map, p->offset, NULL);
3301 			if (!d) {
3302 				d = ht_up_find (phd_ordinal_map, p->ordinal, NULL);
3303 			}
3304 			if (d) {
3305 				p->in_shdr = true;
3306 				if (*p->name && *d->name && r_str_startswith (d->name, "$")) {
3307 					strcpy (d->name, p->name);
3308 				}
3309 			}
3310 			p++;
3311 		}
3312 		p = phdr_symbols;
3313 		while (!p->last) {
3314 			if (!p->in_shdr) {
3315 				count++;
3316 			}
3317 			p++;
3318 		}
3319 		/*Take those symbols that are not present in the shdr but yes in phdr*/
3320 		/*This should only should happen with fucked up binaries*/
3321 		if (count > 0) {
3322 			/*what happens if a shdr says it has only one symbol? we should look anyway into phdr*/
3323 			tmp = (RBinElfSymbol*)realloc (ret, (nsym + count + 1) * sizeof (RBinElfSymbol));
3324 			if (!tmp) {
3325 				result = -1;
3326 				goto done;
3327 			}
3328 			ret = tmp;
3329 			ret[nsym--].last = 0;
3330 			p = phdr_symbols;
3331 			while (!p->last) {
3332 				if (!p->in_shdr) {
3333 					memcpy (&ret[++nsym], p, sizeof (RBinElfSymbol));
3334 				}
3335 				p++;
3336 			}
3337 			ret[nsym + 1].last = 1;
3338 		}
3339 		*sym = ret;
3340 		result = nsym + 1;
3341 		goto done;
3342 	}
3343 	result = nsym;
3344 done:
3345 	ht_up_free (phd_offset_map);
3346 	ht_up_free (phd_ordinal_map);
3347 	return result;
3348 }
3349 
3350 static bool is_section_local_sym(ELFOBJ *bin, Elf_(Sym) *sym) {
3351 	if (sym->st_name != 0) {
3352 		return false;
3353 	}
3354 	if (ELF_ST_TYPE (sym->st_info) != STT_SECTION) {
3355 		return false;
3356 	}
3357 	if (ELF_ST_BIND (sym->st_info) != STB_LOCAL) {
3358 		return false;
3359 	}
3360 	if (!is_shidx_valid (bin, sym->st_shndx)) {
3361 		return false;
3362 	}
3363 	Elf_(Word) sh_name = bin->shdr[sym->st_shndx].sh_name;
3364 	return bin->shstrtab && sh_name < bin->shstrtab_size;
3365 }
3366 
3367 static void setsymord(ELFOBJ* eobj, ut32 ord, RBinSymbol *ptr) {
3368 	if (!eobj->symbols_by_ord || ord >= eobj->symbols_by_ord_size) {
3369 		return;
3370 	}
3371 	r_bin_symbol_free (eobj->symbols_by_ord[ord]);
3372 	eobj->symbols_by_ord[ord] = ptr;
3373 }
3374 
3375 static void _set_arm_thumb_bits(struct Elf_(r_bin_elf_obj_t) *bin, RBinSymbol **sym) {
3376 	int bin_bits = Elf_(r_bin_elf_get_bits) (bin);
3377 	RBinSymbol *ptr = *sym;
3378 	int len = strlen (ptr->name);
3379 	if (ptr->name[0] == '$' && (len >= 2 && !ptr->name[2])) {
3380 		switch (ptr->name[1]) {
3381 		case 'a' : //arm
3382 			ptr->bits = 32;
3383 			break;
3384 		case 't': //thumb
3385 			ptr->bits = 16;
3386 			if (ptr->vaddr & 1) {
3387 				ptr->vaddr--;
3388 			}
3389 			if (ptr->paddr & 1) {
3390 				ptr->paddr--;
3391 			}
3392 			break;
3393 		case 'd': //data
3394 			break;
3395 		default:
3396 			goto arm_symbol;
3397 		}
3398 	} else {
3399 arm_symbol:
3400 		ptr->bits = bin_bits;
3401 		if (bin_bits != 64) {
3402 			ptr->bits = 32;
3403 			if (ptr->paddr != UT64_MAX) {
3404 				if (ptr->vaddr & 1) {
3405 					ptr->vaddr--;
3406 					ptr->bits = 16;
3407 				}
3408 				if (ptr->paddr & 1) {
3409 					ptr->paddr--;
3410 					ptr->bits = 16;
3411 				}
3412 			}
3413 		}
3414 	}
3415 }
3416 
3417 RBinSymbol *Elf_(_r_bin_elf_convert_symbol)(struct Elf_(r_bin_elf_obj_t) *bin,
3418 					  struct r_bin_elf_symbol_t *symbol,
3419 					  const char *namefmt) {
3420 	ut64 paddr, vaddr;
3421 	RBinSymbol *ptr = NULL;
3422 	if (symbol->is_vaddr) {
3423 		paddr = UT64_MAX;
3424 		vaddr = symbol->offset;
3425 	} else {
3426 		paddr = symbol->offset;
3427 		vaddr = Elf_(r_bin_elf_p2v_new) (bin, paddr);
3428 	}
3429 
3430 	if (!(ptr = R_NEW0 (RBinSymbol))) {
3431 		return NULL;
3432 	}
3433 	ptr->name = symbol->name[0] ? r_str_newf (namefmt, &symbol->name[0]) : strdup ("");
3434 	ptr->forwarder = "NONE";
3435 	ptr->bind = symbol->bind;
3436 	ptr->type = symbol->type;
3437 	ptr->is_imported = symbol->is_imported;
3438 	ptr->paddr = paddr;
3439 	ptr->vaddr = vaddr;
3440 	ptr->size = symbol->size;
3441 	ptr->ordinal = symbol->ordinal;
3442 	// detect thumb
3443 	if (bin->ehdr.e_machine == EM_ARM && *ptr->name) {
3444 		_set_arm_thumb_bits (bin, &ptr);
3445 	}
3446 
3447 	return ptr;
3448 }
3449 
3450 static ut32 hashRBinElfSymbol(const void * obj) {
3451 	const RBinElfSymbol *symbol = (const RBinElfSymbol *)obj;
3452 	int hash = sdb_hash (symbol->name);
3453 	hash ^= sdb_hash (symbol->type);
3454 	hash ^= (symbol->offset >> 32);
3455 	hash ^= (symbol->offset & 0xffffffff);
3456 	return hash;
3457 }
3458 
3459 static int cmp_RBinElfSymbol(const RBinElfSymbol *a, const RBinElfSymbol *b) {
3460 	int result = 0;
3461 	if (a->offset != b->offset) {
3462 		return 1;
3463 	}
3464 	result = strcmp(a->name, b->name);
3465 	if (result != 0) {
3466 		return result;
3467 	}
3468 	return strcmp(a->type, b->type);
3469 }
3470 
3471 // TODO: return RList<RBinSymbol*> .. or run a callback with that symbol constructed, so we don't have to do it twice
3472 static RBinElfSymbol* Elf_(_r_bin_elf_get_symbols_imports)(ELFOBJ *bin, int type) {
3473 	ut32 shdr_size;
3474 	int tsize, nsym, ret_ctr = 0, i, j, r, k, newsize;
3475 	ut64 toffset;
3476 	ut32 size = 0;
3477 	RBinElfSymbol *ret = NULL, *import_ret = NULL;
3478 	RBinSymbol *import_sym_ptr = NULL;
3479 	size_t ret_size = 0, prev_ret_size = 0, import_ret_ctr = 0;
3480 	Elf_(Shdr) *strtab_section = NULL;
3481 	Elf_(Sym) *sym = NULL;
3482 	ut8 s[sizeof (Elf_(Sym))] = { 0 };
3483 	char *strtab = NULL;
3484 	HtPP *symbol_map = NULL;
3485 	HtPPOptions symbol_map_options = {
3486 		.cmp = (HtPPListComparator)cmp_RBinElfSymbol,
3487 		.hashfn = hashRBinElfSymbol,
3488 		.dupkey = NULL,
3489 		.calcsizeK = NULL,
3490 		.calcsizeV = NULL,
3491 		.freefn = NULL,
3492 		.elem_size = sizeof (HtPPKv),
3493 	};
3494 
3495 	if (!bin || !bin->shdr || !bin->ehdr.e_shnum || bin->ehdr.e_shnum == 0xffff) {
3496 		return Elf_(get_phdr_symbols) (bin, type);
3497 	}
3498 	if (!UT32_MUL (&shdr_size, bin->ehdr.e_shnum, sizeof (Elf_(Shdr)))) {
3499 		return false;
3500 	}
3501 	if (shdr_size + 8 > bin->size) {
3502 		return false;
3503 	}
3504 	for (i = 0; i < bin->ehdr.e_shnum; i++) {
3505 		if (((type & R_BIN_ELF_SYMTAB_SYMBOLS) && bin->shdr[i].sh_type == SHT_SYMTAB) ||
3506 			((type & R_BIN_ELF_DYNSYM_SYMBOLS) && bin->shdr[i].sh_type == SHT_DYNSYM)) {
3507 			if (bin->shdr[i].sh_link < 1) {
3508 				/* oops. fix out of range pointers */
3509 				continue;
3510 			}
3511 			// hack to avoid asan cry
3512 			if ((bin->shdr[i].sh_link * sizeof(Elf_(Shdr))) >= shdr_size) {
3513 				/* oops. fix out of range pointers */
3514 				continue;
3515 			}
3516 			strtab_section = &bin->shdr[bin->shdr[i].sh_link];
3517 			if (strtab_section->sh_size > ST32_MAX || strtab_section->sh_size+8 > bin->size) {
3518 				bprintf ("size (syms strtab)");
3519 				free (ret);
3520 				free (strtab);
3521 				return NULL;
3522 			}
3523 			if (!strtab) {
3524 				if (!(strtab = (char *)calloc (1, 8 + strtab_section->sh_size))) {
3525 					bprintf ("malloc (syms strtab)");
3526 					goto beach;
3527 				}
3528 				if (strtab_section->sh_offset > bin->size ||
3529 						strtab_section->sh_offset + strtab_section->sh_size > bin->size) {
3530 					goto beach;
3531 				}
3532 				if (r_buf_read_at (bin->b, strtab_section->sh_offset,
3533 							(ut8*)strtab, strtab_section->sh_size) == -1) {
3534 					bprintf ("read (syms strtab)\n");
3535 					goto beach;
3536 				}
3537 			}
3538 
3539 			newsize = 1 + bin->shdr[i].sh_size;
3540 			if (newsize < 0 || newsize > bin->size) {
3541 				bprintf ("invalid shdr %d size\n", i);
3542 				goto beach;
3543 			}
3544 			nsym = (int)(bin->shdr[i].sh_size / sizeof (Elf_(Sym)));
3545 			if (nsym < 0) {
3546 				goto beach;
3547 			}
3548 			{
3549 				ut64 sh_begin = bin->shdr[i].sh_offset;
3550 				ut64 sh_end = sh_begin + bin->shdr[i].sh_size;
3551 				if (sh_begin > bin->size) {
3552 					goto beach;
3553 				}
3554 				if (sh_end > bin->size) {
3555 					st64 newshsize = bin->size - sh_begin;
3556 					nsym = (int)(newshsize / sizeof (Elf_(Sym)));
3557 				}
3558 			}
3559 			if (!(sym = (Elf_(Sym) *)calloc (nsym, sizeof (Elf_(Sym))))) {
3560 				bprintf ("calloc (syms)");
3561 				goto beach;
3562 			}
3563 			if (!UT32_MUL (&size, nsym, sizeof (Elf_(Sym)))) {
3564 				goto beach;
3565 			}
3566 			if (size < 1 || size > bin->size) {
3567 				goto beach;
3568 			}
3569 			if (bin->shdr[i].sh_offset > bin->size) {
3570 				goto beach;
3571 			}
3572 			if (bin->shdr[i].sh_offset + size > bin->size) {
3573 				goto beach;
3574 			}
3575 			for (j = 0; j < nsym; j++) {
3576 				int k = 0;
3577 				r = r_buf_read_at (bin->b, bin->shdr[i].sh_offset + j * sizeof (Elf_(Sym)), s, sizeof (Elf_(Sym)));
3578 				if (r < 1) {
3579 					bprintf ("read (sym)\n");
3580 					goto beach;
3581 				}
3582 #if R_BIN_ELF64
3583 				sym[j].st_name = READ32 (s, k);
3584 				sym[j].st_info = READ8 (s, k);
3585 				sym[j].st_other = READ8 (s, k);
3586 				sym[j].st_shndx = READ16 (s, k);
3587 				sym[j].st_value = READ64 (s, k);
3588 				sym[j].st_size = READ64 (s, k);
3589 #else
3590 				sym[j].st_name = READ32 (s, k);
3591 				sym[j].st_value = READ32 (s, k);
3592 				sym[j].st_size = READ32 (s, k);
3593 				sym[j].st_info = READ8 (s, k);
3594 				sym[j].st_other = READ8 (s, k);
3595 				sym[j].st_shndx = READ16 (s, k);
3596 #endif
3597 			}
3598 			ret = realloc (ret, (ret_size + nsym) * sizeof (RBinElfSymbol));
3599 			if (!ret) {
3600 				bprintf ("Cannot allocate %d symbols\n", nsym);
3601 				goto beach;
3602 			}
3603 			memset (ret + ret_size, 0, nsym * sizeof (RBinElfSymbol));
3604 			prev_ret_size = ret_size;
3605 			ret_size += nsym;
3606 			symbol_map = ht_pp_new_opt (&symbol_map_options);
3607 			for (k = 0; k < prev_ret_size; k++) {
3608 				if (ret[k].name[0]) {
3609 					ht_pp_insert (symbol_map, ret + k, ret + k);
3610 				}
3611 			}
3612 			for (k = 1; k < nsym; k++) {
3613 				bool is_sht_null = false;
3614 				bool is_vaddr = false;
3615 				bool is_imported = false;
3616 				if (type == R_BIN_ELF_IMPORT_SYMBOLS) {
3617 					if (sym[k].st_value) {
3618 						toffset = sym[k].st_value;
3619 					} else if ((toffset = get_import_addr (bin, k)) == -1) {
3620 						toffset = 0;
3621 					}
3622 					tsize = 16;
3623 					is_imported = sym[k].st_shndx == STN_UNDEF;
3624 				} else {
3625 					tsize = sym[k].st_size;
3626 					toffset = (ut64)sym[k].st_value;
3627 					is_sht_null = sym[k].st_shndx == SHT_NULL;
3628 				}
3629 				if (is_bin_etrel (bin)) {
3630 					if (sym[k].st_shndx < bin->ehdr.e_shnum) {
3631 						ret[ret_ctr].offset = sym[k].st_value + bin->shdr[sym[k].st_shndx].sh_offset;
3632 					}
3633 				} else {
3634 					ret[ret_ctr].offset = Elf_(r_bin_elf_v2p_new) (bin, toffset);
3635 					if (ret[ret_ctr].offset == UT64_MAX) {
3636 						ret[ret_ctr].offset = toffset;
3637 						is_vaddr = true;
3638 					}
3639 				}
3640 				ret[ret_ctr].size = tsize;
3641 				if (sym[k].st_name + 1 > strtab_section->sh_size) {
3642 					bprintf ("index out of strtab range\n");
3643 					continue;
3644 				}
3645 				{
3646 					int st_name = sym[k].st_name;
3647 					int maxsize = R_MIN (r_buf_size (bin->b), strtab_section->sh_size);
3648 					if (is_section_local_sym (bin, &sym[k])) {
3649 						const char *shname = &bin->shstrtab[bin->shdr[sym[k].st_shndx].sh_name];
3650 						r_str_ncpy (ret[ret_ctr].name, shname, ELF_STRING_LENGTH);
3651 					} else if (st_name <= 0 || st_name >= maxsize) {
3652 						ret[ret_ctr].name[0] = 0;
3653 					} else {
3654 						r_str_ncpy(ret[ret_ctr].name, &strtab[st_name], ELF_STRING_LENGTH);
3655 						ret[ret_ctr].type = type2str (bin, &ret[ret_ctr], &sym[k]);
3656 
3657 						if (ht_pp_find (symbol_map, &ret[ret_ctr], NULL)) {
3658 							memset (ret + ret_ctr, 0, sizeof (RBinElfSymbol));
3659 							continue;
3660 						}
3661 					}
3662 				}
3663 				ret[ret_ctr].ordinal = k;
3664 				ret[ret_ctr].name[ELF_STRING_LENGTH - 2] = '\0';
3665 				fill_symbol_bind_and_type (bin, &ret[ret_ctr], &sym[k]);
3666 				ret[ret_ctr].is_sht_null = is_sht_null;
3667 				ret[ret_ctr].is_vaddr = is_vaddr;
3668 				ret[ret_ctr].last = 0;
3669 				ret[ret_ctr].is_imported = is_imported;
3670 				ret_ctr++;
3671 				if (type == R_BIN_ELF_IMPORT_SYMBOLS && is_imported) {
3672 					import_ret_ctr++;
3673 				}
3674 			}
3675 			R_FREE (strtab);
3676 			R_FREE (sym);
3677 			ht_pp_free (symbol_map);
3678 			symbol_map = NULL;
3679 			if (type == R_BIN_ELF_IMPORT_SYMBOLS) {
3680 				break;
3681 			}
3682 		}
3683 	}
3684 	if (!ret) {
3685 		return Elf_(get_phdr_symbols) (bin, type);
3686 	}
3687 	ret[ret_ctr].last = 1; // ugly dirty hack :D
3688 	int max = -1;
3689 	RBinElfSymbol *aux = NULL;
3690 	nsym = Elf_(fix_symbols) (bin, ret_ctr, type, &ret);
3691 	if (nsym == -1) {
3692 		goto beach;
3693 	}
3694 
3695 	// Elf_(fix_symbols) may find additional symbols, some of which could be
3696 	// imported symbols. Let's reserve additional space for them.
3697 	r_warn_if_fail (nsym >= ret_ctr);
3698 	import_ret_ctr += nsym - ret_ctr;
3699 
3700 	aux = ret;
3701 	while (!aux->last) {
3702 		if ((int)aux->ordinal > max) {
3703 			max = aux->ordinal;
3704 		}
3705 		aux++;
3706 	}
3707 	nsym = max;
3708 	if (type == R_BIN_ELF_IMPORT_SYMBOLS) {
3709 		R_FREE (bin->imports_by_ord);
3710 		bin->imports_by_ord_size = nsym + 1;
3711 		bin->imports_by_ord = (RBinImport**)calloc (R_MAX (1, nsym + 1), sizeof (RBinImport*));
3712 		R_FREE (bin->symbols_by_ord);
3713 		bin->symbols_by_ord_size = nsym + 1;
3714 		bin->symbols_by_ord = (RBinSymbol**)calloc (R_MAX (1, nsym + 1), sizeof (RBinSymbol*));
3715 		import_ret = calloc (import_ret_ctr + 1, sizeof (RBinElfSymbol));
3716 		if (!import_ret) {
3717 			bprintf ("Cannot allocate %d symbols\n", nsym);
3718 			goto beach;
3719 		}
3720 		import_ret_ctr = 0;
3721 		i = -1;
3722 		while (!ret[++i].last) {
3723 			if (!(import_sym_ptr = Elf_(_r_bin_elf_convert_symbol) (bin, &ret[i], "%s"))) {
3724 				continue;
3725 			}
3726 			setsymord (bin, import_sym_ptr->ordinal, import_sym_ptr);
3727 			if (ret[i].is_imported) {
3728 				memcpy (&import_ret[import_ret_ctr], &ret[i], sizeof (RBinElfSymbol));
3729 				++import_ret_ctr;
3730 			}
3731 		}
3732 		import_ret[import_ret_ctr].last = 1;
3733 		R_FREE (ret);
3734 		return import_ret;
3735 	}
3736 	return ret;
3737 beach:
3738 	free (ret);
3739 	free (sym);
3740 	free (strtab);
3741 	ht_pp_free (symbol_map);
3742 	return NULL;
3743 }
3744 
3745 RBinElfSymbol *Elf_(r_bin_elf_get_symbols)(ELFOBJ *bin) {
3746 	if (!bin->g_symbols) {
3747 		bin->g_symbols = Elf_(_r_bin_elf_get_symbols_imports) (bin, R_BIN_ELF_ALL_SYMBOLS);
3748 	}
3749 	return bin->g_symbols;
3750 }
3751 
3752 RBinElfSymbol *Elf_(r_bin_elf_get_imports)(ELFOBJ *bin) {
3753 	if (!bin->g_imports) {
3754 		bin->g_imports = Elf_(_r_bin_elf_get_symbols_imports) (bin, R_BIN_ELF_IMPORT_SYMBOLS);
3755 	}
3756 	return bin->g_imports;
3757 }
3758 
3759 RBinElfField* Elf_(r_bin_elf_get_fields)(ELFOBJ *bin) {
3760 	RBinElfField *ret = NULL;
3761 	int i = 0, j;
3762 	if (!bin || !(ret = calloc ((bin->ehdr.e_phnum + 3 + 1), sizeof (RBinElfField)))) {
3763 		return NULL;
3764 	}
3765 	strncpy (ret[i].name, "ehdr", ELF_STRING_LENGTH);
3766 	ret[i].offset = 0;
3767 	ret[i++].last = 0;
3768 	strncpy (ret[i].name, "shoff", ELF_STRING_LENGTH);
3769 	ret[i].offset = bin->ehdr.e_shoff;
3770 	ret[i++].last = 0;
3771 	strncpy (ret[i].name, "phoff", ELF_STRING_LENGTH);
3772 	ret[i].offset = bin->ehdr.e_phoff;
3773 	ret[i++].last = 0;
3774 	for (j = 0; bin->phdr && j < bin->ehdr.e_phnum; i++, j++) {
3775 		snprintf (ret[i].name, ELF_STRING_LENGTH, "phdr_%i", j);
3776 		ret[i].offset = bin->phdr[j].p_offset;
3777 		ret[i].last = 0;
3778 	}
3779 	ret[i].last = 1;
3780 	return ret;
3781 }
3782 
3783 void Elf_(r_bin_elf_free)(ELFOBJ* bin) {
3784 	if (!bin) {
3785 		return;
3786 	}
3787 	free (bin->phdr);
3788 	free (bin->shdr);
3789 	free (bin->strtab);
3790 	free (bin->shstrtab);
3791 	free (bin->dynstr);
3792 	r_vector_fini (&bin->dyn_info.dt_needed);
3793 	//free (bin->strtab_section);
3794 	size_t i;
3795 	if (bin->imports_by_ord) {
3796 		for (i = 0; i<bin->imports_by_ord_size; i++) {
3797 			free (bin->imports_by_ord[i]);
3798 		}
3799 		free (bin->imports_by_ord);
3800 	}
3801 	if (bin->symbols_by_ord) {
3802 		for (i = 0; i<bin->symbols_by_ord_size; i++) {
3803 			r_bin_symbol_free (bin->symbols_by_ord[i]);
3804 		}
3805 		free (bin->symbols_by_ord);
3806 	}
3807 	r_buf_free (bin->b);
3808 	if (bin->g_symbols != bin->phdr_symbols) {
3809 		R_FREE (bin->phdr_symbols);
3810 	}
3811 	if (bin->g_imports != bin->phdr_imports) {
3812 		R_FREE (bin->phdr_imports);
3813 	}
3814 	R_FREE (bin->g_sections);
3815 	R_FREE (bin->g_symbols);
3816 	R_FREE (bin->g_imports);
3817 	R_FREE (bin->g_relocs);
3818 	ht_up_free (bin->rel_cache);
3819 	bin->rel_cache = NULL;
3820 	free (bin);
3821 }
3822 
3823 ELFOBJ* Elf_(r_bin_elf_new_buf)(RBuffer *buf, bool verbose) {
3824 	ELFOBJ *bin = R_NEW0 (ELFOBJ);
3825 	if (bin) {
3826 		bin->kv = sdb_new0 ();
3827 		bin->size = r_buf_size (buf);
3828 		bin->verbose = verbose;
3829 		bin->b = r_buf_ref (buf);
3830 		if (!elf_init (bin)) {
3831 			Elf_(r_bin_elf_free) (bin);
3832 			return NULL;
3833 		}
3834 	}
3835 	return bin;
3836 }
3837 
3838 static int is_in_pphdr(Elf_(Phdr) * p, ut64 addr) {
3839 	return addr >= p->p_offset && addr < p->p_offset + p->p_filesz;
3840 }
3841 
3842 static int is_in_vphdr(Elf_(Phdr) * p, ut64 addr) {
3843 	return addr >= p->p_vaddr && addr < p->p_vaddr + p->p_filesz;
3844 }
3845 
3846 /* Deprecated temporarily. Use r_bin_elf_p2v_new in new code for now. */
3847 ut64 Elf_(r_bin_elf_p2v) (ELFOBJ *bin, ut64 paddr) {
3848 	size_t i;
3849 
3850 	r_return_val_if_fail (bin, 0);
3851 	if (!bin->phdr) {
3852 		if (is_bin_etrel (bin)) {
3853 			return bin->baddr + paddr;
3854 		}
3855 		return paddr;
3856 	}
3857 	for (i = 0; i < bin->ehdr.e_phnum; i++) {
3858 		Elf_(Phdr) *p = &bin->phdr[i];
3859 		if (p->p_type == PT_LOAD && is_in_pphdr (p, paddr)) {
3860 			if (!p->p_vaddr && !p->p_offset) {
3861 				continue;
3862 			}
3863 			return p->p_vaddr + paddr - p->p_offset;
3864 		}
3865 	}
3866 
3867 	return paddr;
3868 }
3869 
3870 /* Deprecated temporarily. Use r_bin_elf_v2p_new in new code for now. */
3871 ut64 Elf_(r_bin_elf_v2p) (ELFOBJ *bin, ut64 vaddr) {
3872 	r_return_val_if_fail (bin, 0);
3873 	if (!bin->phdr) {
3874 		if (is_bin_etrel (bin)) {
3875 			return vaddr - bin->baddr;
3876 		}
3877 		return vaddr;
3878 	}
3879 
3880 	size_t i;
3881 	for (i = 0; i < bin->ehdr.e_phnum; i++) {
3882 		Elf_(Phdr) *p = &bin->phdr[i];
3883 		if (p->p_type == PT_LOAD && is_in_vphdr (p, vaddr)) {
3884 			if (!p->p_offset && !p->p_vaddr) {
3885 				continue;
3886 			}
3887 			return p->p_offset + vaddr - p->p_vaddr;
3888 		}
3889 	}
3890 	return vaddr;
3891 }
3892 
3893 /* converts a physical address to the virtual address, looking
3894  * at the program headers in the binary bin */
3895 ut64 Elf_(r_bin_elf_p2v_new) (ELFOBJ *bin, ut64 paddr) {
3896 	size_t i;
3897 
3898 	r_return_val_if_fail (bin, UT64_MAX);
3899 	if (!bin->phdr) {
3900 		if (is_bin_etrel (bin)) {
3901 			return bin->baddr + paddr;
3902 		}
3903 		return UT64_MAX;
3904 	}
3905 	for (i = 0; i < bin->ehdr.e_phnum; i++) {
3906 		Elf_(Phdr) *p = &bin->phdr[i];
3907 		if (p->p_type == PT_LOAD && is_in_pphdr (p, paddr)) {
3908 			return p->p_vaddr + paddr - p->p_offset;
3909 		}
3910 	}
3911 
3912 	return UT64_MAX;
3913 }
3914 
3915 /* converts a virtual address to the relative physical address, looking
3916  * at the program headers in the binary bin */
3917 ut64 Elf_(r_bin_elf_v2p_new) (ELFOBJ *bin, ut64 vaddr) {
3918 	size_t i;
3919 
3920 	r_return_val_if_fail (bin, UT64_MAX);
3921 	if (!bin->phdr) {
3922 		if (is_bin_etrel (bin)) {
3923 			return vaddr - bin->baddr;
3924 		}
3925 		return UT64_MAX;
3926 	}
3927 	for (i = 0; i < bin->ehdr.e_phnum; i++) {
3928 		Elf_(Phdr) *p = &bin->phdr[i];
3929 		if (p->p_type == PT_LOAD && is_in_vphdr (p, vaddr)) {
3930 			return p->p_offset + vaddr - p->p_vaddr;
3931 		}
3932 	}
3933 	return UT64_MAX;
3934 }
3935 
3936 static bool get_nt_file_maps (ELFOBJ *bin, RList *core_maps) {
3937 	ut16 ph, ph_num = bin->ehdr.e_phnum;
3938 
3939 	for (ph = 0; ph < ph_num; ph++) {
3940 		Elf_(Phdr) *p = &bin->phdr[ph];
3941 		if (p->p_type == PT_NOTE) {
3942 			int bits = Elf_(r_bin_elf_get_bits)(bin);
3943 			int elf_nhdr_size = (bits == 64) ? sizeof (Elf64_Nhdr) : sizeof (Elf32_Nhdr);
3944 			int size_of = (bits == 64) ? sizeof (ut64) : sizeof (ut32);
3945 			void *elf_nhdr = calloc (elf_nhdr_size, 1);
3946 			ut64 offset = 0;
3947 			bool found = false;
3948 
3949 			while (!found) {
3950 				int ret;
3951 				ut32 n_descsz, n_namesz, n_type;
3952 				ret = r_buf_read_at (bin->b,
3953 						bin->phdr[ph].p_offset + offset,
3954 						elf_nhdr, elf_nhdr_size);
3955 				if (ret != elf_nhdr_size) {
3956 					eprintf ("Cannot read more NOTES header from CORE\n");
3957 					free (elf_nhdr);
3958 					goto fail;
3959 				}
3960 				if (bits == 64) {
3961 					n_descsz = round_up (((Elf64_Nhdr *)elf_nhdr)->n_descsz);
3962 					n_namesz = round_up (((Elf64_Nhdr *)elf_nhdr)->n_namesz);
3963 					n_type = ((Elf64_Nhdr *)elf_nhdr)->n_type;
3964 				} else {
3965 					n_descsz = round_up (((Elf32_Nhdr *)elf_nhdr)->n_descsz);
3966 					n_namesz = round_up (((Elf32_Nhdr *)elf_nhdr)->n_namesz);
3967 					n_type = ((Elf32_Nhdr *)elf_nhdr)->n_type;
3968 				}
3969 
3970 				if (n_type == NT_FILE) {
3971 					found = true;
3972 					offset += elf_nhdr_size + n_namesz;
3973 					free (elf_nhdr);
3974 				} else {
3975 					offset += elf_nhdr_size + n_descsz + n_namesz;
3976 				}
3977 			}
3978 			ut64 i = bin->phdr[ph].p_offset + offset;
3979 			ut64 n_maps;
3980 			if (bits == 64) {
3981 				n_maps = BREAD64 (bin->b, i);
3982 				(void)BREAD64 (bin->b, i);
3983 			} else {
3984 				n_maps = BREAD32 (bin->b, i);
3985 				(void)BREAD32 (bin->b, i);
3986 			}
3987 			ut64 jump = ((size_of * 3) * n_maps) + i;
3988 			int len_str = 0;
3989 			while (n_maps > 0) {
3990 				ut64 addr;
3991 				if (bits == 64) {
3992 					addr = BREAD64 (bin->b, i);
3993 				} else {
3994 					addr = BREAD32 (bin->b, i);
3995 				}
3996 				if (addr == UT64_MAX) {
3997 					break;
3998 				}
3999 				char str[512] = {0};
4000 				r_buf_read_at (bin->b, jump + len_str, (ut8*)str, sizeof (str) - 1);
4001 				str[sizeof (str) - 1] = 0; // null terminate string
4002 				RListIter *iter;
4003 				RBinMap *p;
4004 				r_list_foreach (core_maps, iter, p) {
4005 					if (p->addr == addr) {
4006 						p->file = strdup (str);
4007 					 }
4008 				}
4009 				len_str += strlen (str) + 1;
4010 				n_maps--;
4011 				i += (size_of * 2);
4012 			}
4013 		}
4014 	}
4015 
4016 	return true;
4017 fail:
4018 	return false;
4019 }
4020 
4021 static void r_bin_elf_map_free(RBinMap *map) {
4022 	if (map) {
4023 		free (map->file);
4024 		free (map);
4025 	}
4026 }
4027 
4028 RList *Elf_(r_bin_elf_get_maps)(ELFOBJ *bin) {
4029 	ut16 ph, ph_num = bin->ehdr.e_phnum; //Skip PT_NOTE
4030 	if (!bin->phdr) {
4031 		return NULL;
4032 	}
4033 	RList *maps = r_list_newf ((RListFree)r_bin_elf_map_free);
4034 	for (ph = 0; ph < ph_num; ph++) {
4035 		Elf_(Phdr) *p = &bin->phdr[ph];
4036 		if (p->p_type == PT_LOAD) {
4037 			RBinMap *map = R_NEW0 (RBinMap);
4038 			if (map) {
4039 				map->addr = p->p_vaddr;
4040 				map->size = p->p_memsz;
4041 				map->perms = p->p_flags;
4042 				map->offset = p->p_offset;
4043 				map->file = NULL;
4044 				r_list_append (maps, map);
4045 			}
4046 		}
4047 	}
4048 
4049 	if (!r_list_empty (maps)) {
4050 		if (!get_nt_file_maps (bin, maps)) {
4051 			eprintf ("Could not retrieve the names of all maps from NT_FILE\n");
4052 		}
4053 	}
4054 
4055 	return maps;
4056 }
4057 
4058 char *Elf_(r_bin_elf_compiler)(ELFOBJ *bin) {
4059 	RBinElfSection *section = get_section_by_name (bin, ".comment");
4060 	if (!section) {
4061 		return NULL;
4062 	}
4063 	ut64 off = section->offset;
4064 	ut32 sz = R_MIN (section->size, 128);
4065 	if (sz < 1) {
4066 		return NULL;
4067 	}
4068 	char *buf = malloc (sz + 1);
4069 	if (!buf) {
4070 		return NULL;
4071 	}
4072 	if (r_buf_read_at (bin->b, off, (ut8*)buf, sz) < 1) {
4073 		free (buf);
4074 		return NULL;
4075 	}
4076 	buf[sz] = 0;
4077 	const size_t buflen = strlen (buf);
4078 	char *nullbyte = buf + buflen;
4079 	if (buflen != sz && nullbyte[1] && buflen < sz) {
4080 		nullbyte[0] = ' ';
4081 	}
4082 	buf[sz] = 0;
4083 	r_str_trim (buf);
4084 	char * res = r_str_escape (buf);
4085 	free (buf);
4086 	return res;
4087 }
4088 
4089 bool Elf_(r_bin_elf_is_executable)(ELFOBJ *bin) {
4090 	const int t = bin->ehdr.e_type;
4091 	return t == ET_EXEC || t == ET_DYN;
4092 }
4093