Rizin
unix-like reverse engineering framework and cli tools
bin_elf.inc
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2009-2021 nibble <nibble.ds@gmail.com>
2 // SPDX-FileCopyrightText: 2009-2021 pancake <pancake@nopcode.org>
3 // SPDX-License-Identifier: LGPL-3.0-only
4 
5 #include <stdio.h>
6 #include <rz_types.h>
7 #include <rz_util.h>
8 #include <rz_util/rz_buf.h>
9 #include <rz_util/rz_assert.h>
10 #include <rz_lib.h>
11 #include <rz_bin.h>
12 #include <rz_io.h>
13 #include <rz_cons.h>
14 #include "../i/private.h"
15 #include "elf/elf.h"
16 #include <ht_uu.h>
17 
18 #define rz_bin_file_get_elf(bf) ((ELFOBJ *)bf->o->bin_obj)
19 
20 #define VFILE_NAME_RELOC_TARGETS "reloc-targets"
21 #define VFILE_NAME_PATCHED "patched"
22 
23 #ifdef RZ_BIN_ELF64
24 #define rz_buf_append_word rz_buf_append_ut64
25 #else
26 #define rz_buf_append_word rz_buf_append_ut32
27 #endif
28 
29 typedef struct {
30  ut32 cmpMask; // Opcode bits of instruction.
31  ut32 relocMask; // Relocation bitmask for patching.
32 } HexagonRelocMask;
33 
38 static const HexagonRelocMask hex_rel6_x_masks[] = {
39  { 0x38000000, 0x0000201f }, { 0x39000000, 0x0000201f },
40  { 0x3e000000, 0x00001f80 }, { 0x3f000000, 0x00001f80 },
41  { 0x40000000, 0x000020f8 }, { 0x41000000, 0x000007e0 },
42  { 0x42000000, 0x000020f8 }, { 0x43000000, 0x000007e0 },
43  { 0x44000000, 0x000020f8 }, { 0x45000000, 0x000007e0 },
44  { 0x46000000, 0x000020f8 }, { 0x47000000, 0x000007e0 },
45  { 0x6a000000, 0x00001f80 }, { 0x7c000000, 0x001f2000 },
46  { 0x9a000000, 0x00000f60 }, { 0x9b000000, 0x00000f60 },
47  { 0x9c000000, 0x00000f60 }, { 0x9d000000, 0x00000f60 },
48  { 0x9f000000, 0x001f0100 }, { 0xab000000, 0x0000003f },
49  { 0xad000000, 0x0000003f }, { 0xaf000000, 0x00030078 },
50  { 0xd7000000, 0x006020e0 }, { 0xd8000000, 0x006020e0 },
51  { 0xdb000000, 0x006020e0 }, { 0xdf000000, 0x006020e0 }
52 };
53 
61 static ut32 hexagon_get_bitmask_r6(ut32 insn) {
62  if ((insn & 0xc000) == 0) { // Duplex instruction
63  return 0x03f00000;
64  }
65 
66  for (int i = 0; i < sizeof(hex_rel6_x_masks) / sizeof(HexagonRelocMask); ++i) {
67  if ((0xff000000 & insn) == hex_rel6_x_masks[i].cmpMask) {
68  return hex_rel6_x_masks[i].relocMask;
69  }
70  }
71  RZ_LOG_ERROR("Unrecognized instruction for 6_X relocation: 0x%x", insn);
72  return 0;
73 }
74 
82 static ut32 hexagon_get_bitmask_r8(ut32 insn) {
83  if ((0xff000000 & insn) == 0xde000000) {
84  return 0x00e020e8;
85  }
86  if ((0xff000000 & insn) == 0x3c000000) {
87  return 0x0000207f;
88  }
89  return 0x00001fe0;
90 }
91 
99 static ut32 hexagon_get_bitmask_r11(ut32 insn) {
100  if ((0xff000000 & insn) == 0xa1000000) {
101  return 0x060020ff;
102  }
103  return 0x06003fe0;
104 }
105 
113 static ut32 hexagon_get_bitmask_r16(ut32 insn) {
114  if ((0xff000000 & insn) == 0x48000000) {
115  return 0x061f20ff;
116  }
117  if ((0xff000000 & insn) == 0x49000000) {
118  return 0x061f3fe0;
119  }
120  if ((0xff000000 & insn) == 0x78000000) {
121  return 0x00df3fe0;
122  }
123  if ((0xff000000 & insn) == 0xb0000000) {
124  return 0x0fe03fe0;
125  }
126  if ((insn & 0xc000) == 0) { // Duplex instruction
127  return 0x03f00000;
128  }
129 
130  for (int i = 0; i < sizeof(hex_rel6_x_masks) / sizeof(HexagonRelocMask); ++i) {
131  if ((0xff000000 & insn) == hex_rel6_x_masks[i].cmpMask) {
132  return hex_rel6_x_masks[i].relocMask;
133  }
134  }
135 
136  RZ_LOG_ERROR("Unrecognized instruction for 16_X relocation: 0x%x", insn);
137  return 0;
138 }
139 
140 typedef struct rz_bin_reloc_formular_symbols_t {
141  ut64 A; // Appendend
142  ut64 B; // Base address
143  ut64 G; // Offset into GOT for symbol entry.
144  ut64 GOT; // Address of entry zero in GOT.
145  ut64 L; // Offset into POT for symbol entry.
146  ut64 P; // Place address of the field being relocated. The address of the bytes to patch.
147  ut64 S; // Value of symbol.
148  ut64 TLS; // Thread-pointer-relative offset to a thread-local symbol.
149  ut64 T; // Base address of the static thread-local tmeplate that contains a thread-local symbol.
150  ut64 MB; // Base address of all strings consumed by compiler message base optimization (Hexagon specific).
151  ut64 GP; // Value of GP register (Hexagon specific).
152 } RzBinRelocFormularSymbols;
153 
154 static RzBinInfo *info(RzBinFile *bf);
155 static void patch_relocs(RzBinFile *bf, struct Elf_(rz_bin_elf_obj_t) * bin);
156 static RzList *imports(RzBinFile *bf);
157 
158 struct special_symbol_translation {
159  RzBinSpecialSymbol symbol;
160  ut64 (*get_addr)(ELFOBJ *bin);
161 };
162 
163 static struct special_symbol_translation special_symbol_translation_table[] = {
168 };
169 
170 static Sdb *get_sdb(RzBinFile *bf) {
171  rz_return_val_if_fail(bf && bf->o && bf->o->bin_obj, NULL);
172 
173  ELFOBJ *bin = rz_bin_file_get_elf(bf);
174  return bin->kv;
175 }
176 
177 #ifndef RZ_BIN_CGC
178 static int check_buffer_aux(RzBuffer *buf) {
180 
181  ut8 tmp[SELFMAG + 1] = { 0 };
182 
183  if (rz_buf_read_at(buf, 0, tmp, SELFMAG + 1) < 0) {
184  return ELFCLASSNONE;
185  }
186 
187  if (memcmp(tmp, ELFMAG, SELFMAG)) {
188  return ELFCLASSNONE;
189  }
190 
191  return tmp[SELFMAG];
192 }
193 #endif
194 
195 static bool load_buffer(RZ_UNUSED RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, RZ_UNUSED Sdb *sdb) {
197 
199  if (!bin) {
200  return false;
201  }
202 
203  obj->bin_obj = bin;
204  return true;
205 }
206 
207 static ut64 baddr(RzBinFile *bf) {
208  rz_return_val_if_fail(bf && bf->o, UT64_MAX);
209 
210  ELFOBJ *bin = rz_bin_file_get_elf(bf);
211  return Elf_(rz_bin_elf_get_baddr)(bin);
212 }
213 
214 static ut64 boffset(RzBinFile *bf) {
215  rz_return_val_if_fail(bf && bf->o, UT64_MAX);
216 
217  ELFOBJ *bin = rz_bin_file_get_elf(bf);
219 }
220 
221 static ut64 binsym_aux(ELFOBJ *bin, RzBinSpecialSymbol sym) {
222  for (size_t i = 0; i < RZ_ARRAY_SIZE(special_symbol_translation_table); i++) {
223  if (sym == special_symbol_translation_table[i].symbol) {
224  return special_symbol_translation_table[i].get_addr(bin);
225  }
226  }
227 
228  return UT64_MAX;
229 }
230 
231 static RzBinAddr *rz_bin_addr_new_aux(ELFOBJ *bin, ut64 paddr, ut64 vaddr) {
232  RzBinAddr *result = RZ_NEW0(RzBinAddr);
233  if (!result) {
234  return NULL;
235  }
236 
237  result->paddr = paddr;
238  result->vaddr = vaddr;
239  result->bits = bin->bits;
240 
243  }
244 
245  return result;
246 }
247 
248 static RzBinAddr *rz_bin_addr_new_from_paddr(ELFOBJ *bin, ut64 paddr) {
249  ut64 vaddr = Elf_(rz_bin_elf_p2v)(bin, paddr);
250  if (vaddr == UT64_MAX) {
251  vaddr = paddr;
252  }
253 
254  return rz_bin_addr_new_aux(bin, paddr, vaddr);
255 }
256 
257 static RzBinAddr *rz_bin_addr_new_from_vaddr(ELFOBJ *bin, ut64 vaddr) {
258  ut64 paddr = Elf_(rz_bin_elf_v2p)(bin, vaddr);
259 
260  return rz_bin_addr_new_aux(bin, paddr, vaddr);
261 }
262 
263 static RzBinAddr *binsym(RzBinFile *bf, RzBinSpecialSymbol sym) {
264  rz_return_val_if_fail(bf && bf->o && bf->o, NULL);
265 
266  ELFOBJ *bin = rz_bin_file_get_elf(bf);
267 
268  ut64 paddr = binsym_aux(bin, sym);
269  if (paddr == UT64_MAX) {
270  return NULL;
271  }
272 
273  return rz_bin_addr_new_from_paddr(bin, paddr);
274 }
275 
276 static void add_constructor(ELFOBJ *bin, ut64 addr, ut64 size, int type, RzList *result) {
277  ut64 constructor_offset = Elf_(rz_bin_elf_v2p)(bin, addr);
278  if (constructor_offset == UT64_MAX) {
279  return;
280  }
281 
282  ut64 pos = 0;
283 
284  while (pos < size) {
285  ut64 offset = constructor_offset + pos;
286 
287  Elf_(Addr) vaddr;
288  if (!Elf_(rz_bin_elf_read_addr)(bin, &offset, &vaddr)) {
289  break;
290  }
291 
292  if (!vaddr) {
293  pos += sizeof(Elf_(Addr));
294  continue;
295  }
296 
297  RzBinAddr *tmp = rz_bin_addr_new_from_vaddr(bin, vaddr);
298  if (!tmp) {
299  break;
300  }
301 
302  tmp->hpaddr = constructor_offset + pos;
303  tmp->hvaddr = addr + pos;
304  tmp->type = type;
305 
306  rz_list_append(result, tmp);
307 
308  pos += sizeof(Elf_(Addr));
309  }
310 }
311 
312 static void add_constructors(ELFOBJ *bin, RzList *result) {
313  ut64 addr, size;
314 
316  add_constructor(bin, addr, size, RZ_BIN_ENTRY_TYPE_PREINIT, result);
317  }
318 
320  add_constructor(bin, addr, size, RZ_BIN_ENTRY_TYPE_INIT, result);
321  }
322 
324  add_constructor(bin, addr, size, RZ_BIN_ENTRY_TYPE_FINI, result);
325  }
326 }
327 
328 static void add_entry_offset(ELFOBJ *bin, RzList *result) {
330  if (paddr == UT64_MAX) {
331  return;
332  }
333 
334  RzBinAddr *tmp = rz_bin_addr_new_from_paddr(bin, paddr);
335  if (!tmp) {
336  return;
337  }
338 
339  tmp->hpaddr = E_ENTRYPOINT_OFFSET;
340  tmp->hvaddr = bin->baddr + tmp->hpaddr;
341 
342  if (tmp->vaddr != (ut64)bin->ehdr.e_entry && Elf_(rz_bin_elf_is_executable)(bin)) {
343  RZ_LOG_ERROR("Cannot determine entrypoint, using 0x%08" PFMT64x ".\n", tmp->vaddr);
344  }
345 
346  rz_list_append(result, tmp);
347 }
348 
349 static void add_java_libraries(ELFOBJ *bin, RzList *result) {
350  RzBinElfSymbol *symbol;
352  if (symbol->name && rz_str_startswith(symbol->name, "Java") && rz_str_endswith(symbol->name, "_init")) {
353  RzBinAddr *tmp = rz_bin_addr_new_from_paddr(bin, symbol->paddr);
354  tmp->type = RZ_BIN_ENTRY_TYPE_INIT;
355 
356  rz_list_append(result, tmp);
357  break;
358  }
359  }
360 }
361 
362 static RzList *entries(RzBinFile *bf) {
363  rz_return_val_if_fail(bf && bf->o, NULL);
364 
365  ELFOBJ *bin = rz_bin_file_get_elf(bf);
366 
367  RzList *result = rz_list_newf((RzListFree)free);
368  if (!result) {
369  return NULL;
370  }
371 
372  add_entry_offset(bin, result);
373  add_java_libraries(bin, result);
374  add_constructors(bin, result);
375 
376  return result;
377 }
378 
379 #ifndef RZ_BIN_CGC
380 static void headers(RzBinFile *bf) {
381  rz_return_if_fail(bf && bf->o && bf->o->bin_obj);
382 
383  ELFOBJ *bin = rz_bin_file_get_elf(bf);
384 
386 }
387 
388 static bool create_set_e_ident(RzBuffer *result) {
389  return rz_buf_append_bytes(result, (ut8 *)ELFMAG, SELFMAG) &&
390 #ifdef RZ_BIN_ELF64
391  rz_buf_append_bytes(result, (ut8 *)"\x2\x1\x1\x0", 4) &&
392 #else
393  rz_buf_append_bytes(result, (ut8 *)"\x1\x1\x1\x0", 4) &&
394 #endif
395  rz_buf_append_nbytes(result, 8);
396 }
397 
398 static bool create_set_e_machine(RzBuffer *result, bool is_arm) {
399 #ifdef RZ_BIN_ELF64
400  return rz_buf_append_ut16(result, EM_X86_64);
401 #else
402  if (is_arm) {
403  return rz_buf_append_ut16(result, EM_ARM);
404  }
405 
406  return rz_buf_append_ut16(result, EM_386);
407 #endif
408 }
409 
410 static bool create_set_ehdr(RzBuffer *result, bool is_arm) {
411  return create_set_e_ident(result) &&
412  rz_buf_append_ut16(result, ET_EXEC) &&
413  create_set_e_machine(result, is_arm) &&
414  rz_buf_append_ut32(result, EV_CURRENT) &&
415  rz_buf_append_word(result, sizeof(Elf_(Ehdr)) + sizeof(Elf_(Phdr))) && // e_entry
416  rz_buf_append_word(result, sizeof(Elf_(Ehdr))) && // e_phoff
417  rz_buf_append_word(result, 0) && // e_shoff
418  rz_buf_append_ut32(result, 0) && // e_flags
419  rz_buf_append_ut16(result, sizeof(Elf_(Ehdr))) && // e_ehsize
420  rz_buf_append_ut16(result, sizeof(Elf_(Phdr))) && // e_phentsize
421  rz_buf_append_ut16(result, 1) && // e_phnum
422  rz_buf_append_ut16(result, 0) && // e_shentsize
423  rz_buf_append_ut16(result, 0) && // e_shnum
424  rz_buf_append_ut16(result, 0); // e_shstrndx
425 }
426 
427 static bool create_set_phdr(RzBuffer *result, Elf_(Word) baddr, int codelen) {
428  ut64 length = sizeof(Elf_(Ehdr)) + sizeof(Elf_(Phdr)) + codelen;
429 
430  return rz_buf_append_ut32(result, PT_LOAD) &&
431 #ifdef RZ_BIN_ELF64
432  rz_buf_append_ut32(result, PF_X | PF_R) &&
433  rz_buf_append_ut64(result, 0) && // p_offset
434  rz_buf_append_ut64(result, baddr) && // p_vaddr
435  rz_buf_append_ut64(result, baddr) && // p_paddr
436  rz_buf_append_ut64(result, length) && // p_filesz
437  rz_buf_append_ut64(result, length) && // p_memsz
438  rz_buf_append_ut64(result, 0x200000); // p_align
439 #else
440  rz_buf_append_ut32(result, 0) && // p_offset
441  rz_buf_append_ut32(result, baddr) && // p_vaddr
442  rz_buf_append_ut32(result, baddr) && // p_paddr
443  rz_buf_append_ut32(result, length) && // p_filesz
444  rz_buf_append_ut32(result, length) && // p_memsz
445  rz_buf_append_ut32(result, PF_X | PF_R) && // p_flags
446  rz_buf_append_ut64(result, 0x1000); // p_align
447 #endif
448 }
449 
450 static Elf_(Word) create_get_baddr(bool is_arm) {
451 #ifdef RZ_BIN_ELF64
452  return 0x400000LL;
453 #else
454  if (is_arm) {
455  return 0x40000;
456  }
457 
458  return 0x8048000;
459 #endif
460 }
461 
462 static RzBuffer *create_elf(RzBin *bin, const ut8 *code, int codelen, const ut8 *data, int datalen, RzBinArchOptions *opt) {
463  rz_return_val_if_fail(bin && opt && opt->arch, NULL);
464 
465  RzBuffer *result = rz_buf_new_with_bytes(NULL, 0);
466 
467  bool is_arm = !strcmp(opt->arch, "arm");
468  Elf_(Word) baddr = create_get_baddr(is_arm);
469 
470  if (!create_set_ehdr(result, is_arm) ||
471  !create_set_phdr(result, baddr, codelen) ||
472  !rz_buf_append_bytes(result, code, codelen)) {
473  rz_buf_free(result);
474  return NULL;
475  }
476 
477  if (data && datalen > 0) {
478  // ut32 data_section = buf->length;
479  RZ_LOG_WARN("DATA section not support for ELF yet\n");
480  rz_buf_append_bytes(result, data, datalen);
481  }
482 
483  return result;
484 }
485 #endif
486 
487 static void destroy(RzBinFile *bf) {
488  Elf_(rz_bin_elf_free)(bf->o->bin_obj);
489 }
490 
491 static RzBinSymbol *convert_symbol(ELFOBJ *bin, RzBinElfSymbol *elf_symbol) {
492  RzBinSymbol *result = RZ_NEW0(RzBinSymbol);
493  if (!result) {
494  return NULL;
495  }
496 
497  result->paddr = elf_symbol->paddr;
498  result->vaddr = elf_symbol->vaddr;
499  result->name = rz_str_new(elf_symbol->name);
500  result->forwarder = "NONE";
501  result->bind = elf_symbol->bind;
502  result->type = elf_symbol->type;
503  result->size = elf_symbol->size;
504  result->ordinal = elf_symbol->ordinal;
505  result->bits = bin->bits;
506 
509  }
510 
511  return result;
512 }
513 
514 static RzBinSymbol *get_symbol(ELFOBJ *bin, ut32 ordinal) {
515  RzBinElfSymbol *symbol = Elf_(rz_bin_elf_get_symbol)(bin, ordinal);
516  if (!symbol) {
517  return NULL;
518  }
519 
520  return convert_symbol(bin, symbol);
521 }
522 
523 static RzBinImport *convert_import(RzBinElfSymbol *symbol) {
524  RzBinImport *result = RZ_NEW0(RzBinImport);
525  if (!result) {
526  return NULL;
527  }
528 
529  result->name = rz_str_new(symbol->name);
530  result->bind = symbol->bind;
531  result->type = symbol->type;
532  result->ordinal = symbol->ordinal;
533 
534  return result;
535 }
536 
537 static RzBinImport *get_import(ELFOBJ *bin, ut32 ordinal) {
538  RzBinElfSymbol *symbol = Elf_(rz_bin_elf_get_import)(bin, ordinal);
539  if (!symbol) {
540  return NULL;
541  }
542 
543  return convert_import(symbol);
544 }
545 
546 static int get_file_type(RzBinFile *bf) {
547  struct Elf_(rz_bin_elf_obj_t) *obj = bf->o->bin_obj;
548  char *type = Elf_(rz_bin_elf_get_file_type(obj));
549  int res = type ? ((!strncmp(type, "CORE", 4)) ? RZ_BIN_TYPE_CORE : RZ_BIN_TYPE_DEFAULT) : -1;
550  free(type);
551  return res;
552 }
553 
554 static char *regstate(RzBinFile *bf) {
555  ELFOBJ *obj = bf->o->bin_obj;
556 
557  RzVector *notes;
559  RzBinElfNote *tmp;
560  rz_vector_foreach(notes, tmp) {
561  if (tmp->type != NT_PRSTATUS) {
562  continue;
563  }
564 
565  RzBinElfNotePrStatus *note = &tmp->prstatus;
566  return rz_hex_bin2strdup(note->regstate, note->regstate_size);
567  }
568  }
569 
570  char *machine_name = Elf_(rz_bin_elf_get_machine_name)(obj);
571  RZ_LOG_ERROR("Cannot retrieve regstate on: %s (not yet supported)\n", machine_name);
572  free(machine_name);
573  return NULL;
574 }
575 
576 static char *setphname(ut16 mach, Elf_(Word) ptyp) {
577  // TODO to complete over time
578  if (mach == EM_ARM) {
579  if (ptyp == SHT_ARM_EXIDX) {
580  return strdup("EXIDX");
581  }
582  } else if (mach == EM_MIPS) {
583  if (ptyp == PT_MIPS_ABIFLAGS) {
584  return strdup("ABIFLAGS");
585  } else if (ptyp == PT_MIPS_REGINFO) {
586  return strdup("REGINFO");
587  }
588  }
589 
590  return strdup("UNKNOWN");
591 }
592 
593 static bool is_wordable_section(const char *name) {
594  if (!strcmp(name, ".init_array")) {
595  return true;
596  }
597  if (!strcmp(name, ".fini_array")) {
598  return true;
599  }
600  if (!strcmp(name, ".data.rel.ro")) {
601  return true;
602  }
603  if (!strcmp(name, ".dynamic")) {
604  return true;
605  }
606  if (!strcmp(name, ".got")) {
607  return true;
608  }
609  if (strstr(name, ".rela.")) {
610  return true;
611  }
612  return false;
613 }
614 
615 static RzBinElfNoteFile *note_file_for_load_segment(ELFOBJ *obj, Elf_(Phdr) * phdr) {
616  if (!Elf_(rz_bin_elf_has_notes)(obj)) {
617  return false;
618  }
619 
620  RzVector *notes;
622  RzBinElfNote *tmp;
623  rz_vector_foreach(notes, tmp) {
624  if (tmp->type != NT_FILE) {
625  continue;
626  }
627 
628  RzBinElfNoteFile *note = &tmp->file;
629 
630  if (note->start_vaddr == phdr->p_vaddr) {
631  return note;
632  }
633  }
634  }
635 
636  return NULL;
637 }
638 
639 static ut32 section_perms_from_flags(ut32 flags) {
640  ut32 r = 0;
642  r |= RZ_PERM_X;
643  }
645  r |= RZ_PERM_W;
646  }
648  r |= RZ_PERM_R;
649  }
650  return r;
651 }
652 
653 static RzList *maps_unpatched(RzBinFile *bf) {
654  struct Elf_(rz_bin_elf_obj_t) *obj = (bf && bf->o) ? bf->o->bin_obj : NULL;
655  if (!obj) {
656  return NULL;
657  }
659  if (!ret) {
660  return NULL;
661  }
662 
663  if (Elf_(rz_bin_elf_has_segments)(obj)) {
664  ut64 core_sp = Elf_(rz_bin_elf_get_sp_val)(obj);
665  int n = 0;
666 
669  if (iter->data.p_type != PT_LOAD) {
670  continue;
671  }
672 
674  if (!map) {
675  break;
676  }
677 
678  map->paddr = iter->data.p_offset;
679  map->psize = iter->data.p_filesz;
680  map->vsize = iter->data.p_memsz;
681  map->vaddr = iter->data.p_vaddr;
682  map->perm = iter->data.p_flags | RZ_PERM_R;
683 
684  // map names specific to core files...
685  if (core_sp != UT64_MAX && core_sp >= iter->data.p_vaddr && core_sp < iter->data.p_vaddr + iter->data.p_memsz) {
686  map->name = strdup("[stack]");
687  } else {
688  RzBinElfNoteFile *nf = note_file_for_load_segment(obj, &iter->data);
689  if (nf && nf->file) {
690  map->name = strdup(nf->file);
691  }
692  }
693  // generic names
694  if (!map->name) {
695  map->name = rz_str_newf("LOAD%d", n);
696  }
697  n++;
698  rz_list_append(ret, map);
699  }
700  } else {
701  // Load sections if there is no PHDR
702 
706  if (!map) {
707  break;
708  }
709 
710  map->name = rz_str_new(section->name);
711  map->paddr = section->offset;
712  map->psize = section->type != SHT_NOBITS ? section->size : 0;
713  map->vsize = section->size;
714  map->vaddr = section->rva;
715  map->perm = section_perms_from_flags(section->flags);
716  rz_list_append(ret, map);
717  }
718  }
719 
720  if (rz_list_empty(ret)) {
722  if (!map) {
723  return ret;
724  }
725  map->name = strdup("uphdr");
726  map->paddr = 0;
727  map->psize = bf->size;
728  map->vaddr = 0x10000;
729  map->vsize = bf->size;
730  map->perm = RZ_PERM_RWX;
731  rz_list_append(ret, map);
732  }
733 
734  if (obj->ehdr.e_type == ET_REL) {
736  if (!map) {
737  return ret;
738  }
739  ut64 ehdr_size = sizeof(obj->ehdr);
740  if (bf->size < ehdr_size) {
741  ehdr_size = bf->size;
742  }
743  map->name = strdup("ehdr");
744  map->paddr = 0;
745  map->psize = ehdr_size;
746  map->vaddr = obj->baddr;
747  map->vsize = ehdr_size;
748  map->perm = RZ_PERM_RW;
749  rz_list_append(ret, map);
750  }
751  return ret;
752 }
753 
754 static ut64 reloc_target_size(ELFOBJ *obj) {
755  if (!obj->bits) {
756  return 8;
757  }
758  return obj->bits / 8;
759 }
760 
762 static ut64 reloc_targets_vfile_size(RzBinFile *bf, ELFOBJ *obj) {
763  if (!bf->o || !bf->o->opts.patch_relocs || !Elf_(rz_bin_elf_has_relocs)(obj)) {
764  return 0;
765  }
766 
768 }
769 
781 static ut32 apply_bitmask(const ut32 mask, const ut32 val) {
782  ut32 result = 0;
783  ut32 off = 0;
784 
785  for (ut32 bit = 0; bit != 32; ++bit) {
786  ut32 valBit = (val >> off) & 1;
787  ut32 maskBit = (mask >> bit) & 1;
788  if (maskBit) {
789  result |= (valBit << bit);
790  ++off;
791  }
792  }
793  return result;
794 }
795 
804 static void patch_val_hexagon(RZ_INOUT RzBuffer *buf_patched, const ut32 addr, const ut32 mask, const ut32 val) {
805  rz_return_if_fail(buf_patched);
806  ut8 buf[8] = { 0 };
807 
808  rz_buf_read_at(buf_patched, addr, buf, 4);
809  ut32 opcode = rz_read_le32(buf) | apply_bitmask(mask, val);
810 
811  rz_write_le32(buf, opcode);
812  rz_buf_write_at(buf_patched, addr, buf, 4);
813 }
814 
825 static void patch_reloc_hexagon(RZ_INOUT RzBuffer *buf_patched, const ut64 patch_addr, const int rel_type, const RzBinRelocFormularSymbols *fs) {
826  rz_return_if_fail(buf_patched && fs);
827  ut8 buf[8] = { 0 };
828  ut64 val = 0;
829  ut64 bitmask = R_HEX_BITMASK_WORD32; // Mask of value and opcode bits.
830 
831  switch (rel_type) {
832  default:
833  RZ_LOG_WARN("Patching for reloc type %d not implemented.", rel_type);
835  // For more implementetations check out the LLVM src:
836  // https://github.com/llvm/llvm-project/blob/abc17a67519747be36f1fd03e227c5103da4c677/lld/ELF/Arch/Hexagon.cpp
837  return;
838  case R_HEX_NONE:
839  return;
840  case R_HEX_GLOB_DAT:
841  case R_HEX_JMP_SLOT:
842  val = (fs->S + fs->A);
843  break;
844  case R_HEX_RELATIVE:
845  val = (fs->B + fs->A);
846  break;
847  case R_HEX_B22_PCREL:
848  bitmask = R_HEX_BITMASK_WORD32_B22;
849  val = (fs->S + fs->A - fs->P) >> 2;
850  break;
851  case R_HEX_B15_PCREL:
852  bitmask = R_HEX_BITMASK_WORD32_B15;
853  val = (fs->S + fs->A - fs->P) >> 2;
854  break;
855  case R_HEX_B7_PCREL:
856  bitmask = R_HEX_BITMASK_WORD32_B7;
857  val = (fs->S + fs->A - fs->P) >> 2;
858  break;
859  case R_HEX_LO16:
860  bitmask = R_HEX_BITMASK_WORD32_LO;
861  val = (fs->S + fs->A);
862  break;
863  case R_HEX_HI16:
864  bitmask = R_HEX_BITMASK_WORD32_HL;
865  val = (fs->S + fs->A) >> 16;
866  break;
867  case R_HEX_32:
868  val = (fs->S + fs->A);
869  break;
870  case R_HEX_16:
871  bitmask = R_HEX_BITMASK_WORD16;
872  val = (fs->S + fs->A);
873  break;
874  case R_HEX_8:
875  bitmask = R_HEX_BITMASK_WORD8;
876  val = (fs->S + fs->A);
877  break;
878  case R_HEX_HL16:
879  bitmask = R_HEX_BITMASK_WORD32_HL;
880  val = (fs->S + fs->A);
881  break;
882  case R_HEX_B13_PCREL:
883  bitmask = R_HEX_BITMASK_WORD32_B13;
884  val = (fs->S + fs->A - fs->P) >> 2;
885  break;
886  case R_HEX_B9_PCREL:
887  bitmask = R_HEX_BITMASK_WORD32_B9;
888  val = (fs->S + fs->A - fs->P) >> 2;
889  break;
890  case R_HEX_B32_PCREL_X:
891  bitmask = R_HEX_BITMASK_WORD32_X26;
892  val = (fs->S + fs->A - fs->P) >> 6;
893  break;
894  case R_HEX_32_6_X:
895  bitmask = R_HEX_BITMASK_WORD32_X26;
896  val = (fs->S + fs->A) >> 6;
897  break;
898  case R_HEX_B22_PCREL_X:
899  bitmask = R_HEX_BITMASK_WORD32_B22;
900  val = (fs->S + fs->A - fs->P) & 0x3f;
901  break;
902  case R_HEX_B15_PCREL_X:
903  bitmask = R_HEX_BITMASK_WORD32_B15;
904  val = (fs->S + fs->A - fs->P) & 0x3f;
905  break;
906  case R_HEX_B13_PCREL_X:
907  bitmask = R_HEX_BITMASK_WORD32_B13;
908  val = (fs->S + fs->A - fs->P) & 0x3f;
909  break;
910  case R_HEX_B9_PCREL_X:
911  bitmask = R_HEX_BITMASK_WORD32_B9;
912  val = (fs->S + fs->A - fs->P) & 0x3f;
913  break;
914  case R_HEX_B7_PCREL_X:
915  bitmask = R_HEX_BITMASK_WORD32_B7;
916  val = (fs->S + fs->A - fs->P) & 0x3f;
917  break;
918  case R_HEX_12_X:
919  bitmask = R_HEX_BITMASK_WORD32_R6;
920  val = (fs->S + fs->A);
921  break;
922  case R_HEX_32_PCREL:
923  val = (fs->S + fs->A - fs->P);
924  break;
925  case R_HEX_GOTREL_LO16:
926  bitmask = R_HEX_BITMASK_WORD32_LO;
927  val = (fs->S + fs->A - fs->GOT);
928  break;
929  case R_HEX_GOTREL_HI16:
930  bitmask = R_HEX_BITMASK_WORD32_HL;
931  val = (fs->S + fs->A - fs->GOT) >> 16;
932  break;
933  case R_HEX_GOTREL_32:
934  val = (fs->S + fs->A - fs->GOT);
935  break;
936  case R_HEX_GOTREL_32_6_X:
937  bitmask = R_HEX_BITMASK_WORD32_X26;
938  val = (fs->S + fs->A - fs->GOT) >> 6;
939  break;
940  case R_HEX_PLT_B22_PCREL:
943  bitmask = R_HEX_BITMASK_WORD32_B22;
944  val = (fs->L + fs->A - fs->P) >> 2;
945  break;
948  bitmask = R_HEX_BITMASK_WORD32_B22;
949  val = (fs->S + fs->A - fs->P) & 0x3f;
950  break;
953  bitmask = R_HEX_BITMASK_WORD32_X26;
954  val = (fs->S + fs->A - fs->P) >> 6;
955  break;
956  case R_HEX_16_X:
957  rz_buf_read_at(buf_patched, patch_addr, buf, 4);
958  bitmask = hexagon_get_bitmask_r16(rz_read_le32(buf));
959  val = (fs->S + fs->A) & 0x3f;
960  break;
961  case R_HEX_11_X:
962  rz_buf_read_at(buf_patched, patch_addr, buf, 4);
963  bitmask = hexagon_get_bitmask_r11(rz_read_le32(buf));
964  val = (fs->S + fs->A) & 0x3f;
965  break;
966  case R_HEX_10_X:
967  bitmask = 0x00203fe0;
968  val = (fs->S + fs->A) & 0x3f;
969  break;
970  case R_HEX_9_X:
971  bitmask = 0x00003fe0;
972  val = (fs->S + fs->A) & 0x3f;
973  break;
974  case R_HEX_8_X:
975  rz_buf_read_at(buf_patched, patch_addr, buf, 4);
976  bitmask = hexagon_get_bitmask_r8(rz_read_le32(buf));
977  val = (fs->S + fs->A);
978  break;
979  case R_HEX_6_PCREL_X:
980  rz_buf_read_at(buf_patched, patch_addr, buf, 4);
981  bitmask = hexagon_get_bitmask_r6(rz_read_le32(buf));
982  val = (fs->S + fs->A - fs->P);
983  break;
984  case R_HEX_6_X:
985  rz_buf_read_at(buf_patched, patch_addr, buf, 4);
986  bitmask = hexagon_get_bitmask_r6(rz_read_le32(buf));
987  val = (fs->S + fs->A);
988  break;
989  case R_HEX_GOTREL_16_X:
990  rz_buf_read_at(buf_patched, patch_addr, buf, 4);
991  bitmask = hexagon_get_bitmask_r16(rz_read_le32(buf));
992  val = (fs->S + fs->A - fs->GOT);
993  break;
994  case R_HEX_GOTREL_11_X:
995  rz_buf_read_at(buf_patched, patch_addr, buf, 4);
996  bitmask = hexagon_get_bitmask_r11(rz_read_le32(buf));
997  val = (fs->S + fs->A - fs->GOT);
998  break;
999  case R_HEX_DTPREL_32_6_X:
1000  bitmask = R_HEX_BITMASK_WORD32_X26;
1001  val = (fs->S + fs->A - fs->T) >> 6;
1002  break;
1003  case R_HEX_DTPREL_16_X:
1004  rz_buf_read_at(buf_patched, patch_addr, buf, 4);
1005  bitmask = hexagon_get_bitmask_r16(rz_read_le32(buf));
1006  val = (fs->S + fs->A - fs->T);
1007  break;
1008  case R_HEX_DTPREL_11_X:
1009  rz_buf_read_at(buf_patched, patch_addr, buf, 4);
1010  bitmask = hexagon_get_bitmask_r11(rz_read_le32(buf));
1011  val = (fs->S + fs->A - fs->T);
1012  break;
1013  }
1014  // Patch two opcodes at once.
1015  if (rel_type == R_HEX_HL16) {
1016  patch_val_hexagon(buf_patched, patch_addr, bitmask, val & 0xffffffff);
1017  patch_val_hexagon(buf_patched, patch_addr + 4, bitmask, val >> 32);
1018  } else {
1019  patch_val_hexagon(buf_patched, patch_addr, bitmask, val);
1020  }
1021 }
1022 
1023 static void patch_reloc(struct Elf_(rz_bin_elf_obj_t) * obj, RzBinElfReloc *rel, ut64 S, ut64 B, ut64 L, ut64 GOT) {
1024  ut16 e_machine = obj->ehdr.e_machine;
1025  ut64 val = 0;
1026  ut64 A = rel->addend, P = rel->vaddr;
1027  RzBinRelocFormularSymbols formular_sym = { .A = A, .B = B, .GOT = GOT, .L = L, .S = S, .P = P, .MB = 0, .G = 0, .GP = 0, .T = 0, .TLS = 0 };
1028  ut64 patch_addr = rel->paddr != UT64_MAX ? rel->paddr : Elf_(rz_bin_elf_v2p)(obj, rel->vaddr);
1029  ut8 buf[8];
1030  bool big_endian = obj->big_endian;
1031  switch (e_machine) {
1032  case EM_QDSP6:
1033  patch_reloc_hexagon(obj->buf_patched, patch_addr, rel->type, &formular_sym);
1034  break;
1035  case EM_ARM:
1036  val = S + A;
1037  if (!rel->sym && rel->mode == DT_REL) {
1038  rz_buf_read_at(obj->buf_patched, patch_addr, buf, 4);
1039  val += obj->big_endian ? rz_read_be32(buf) : rz_read_le32(buf);
1040  }
1041  rz_buf_write_ble32_at(obj->buf_patched, patch_addr, val, obj->big_endian);
1042  break;
1043  case EM_AARCH64:
1044  val = S + A;
1045  rz_write_le64(buf, val);
1046  rz_buf_write_at(obj->buf_patched, patch_addr, buf, 8);
1047  break;
1048  case EM_PPC64: {
1049  int low = 0, word = 0;
1050  switch (rel->type) {
1051  case RZ_PPC64_ADDR24:
1052  low = 24;
1053  val = (S + A) >> 2;
1054  break;
1055  case RZ_PPC64_ADDR16_HI:
1056  word = 2;
1057  val = (S + A) >> 16;
1058  break;
1059  case RZ_PPC64_ADDR16_HA:
1060  word = 2;
1061  val = (S + A + 0x8000) >> 16;
1062  break;
1063  case RZ_PPC64_REL16_HA:
1064  word = 2;
1065  val = (S + A - P + 0x8000) >> 16;
1066  break;
1067  case RZ_PPC64_ADDR16_LO:
1068  word = 2;
1069  val = (S + A) & 0xffff;
1070  break;
1071  case RZ_PPC64_REL16_LO:
1072  word = 2;
1073  val = (S + A - P) & 0xffff;
1074  break;
1075  case RZ_PPC64_REL14:
1076  low = 14;
1077  val = (st64)(S + A - P) >> 2;
1078  break;
1079  case RZ_PPC64_REL24:
1080  low = 24;
1081  val = (st64)(S + A - P) >> 2;
1082  break;
1083  case RZ_PPC64_REL32:
1084  word = 4;
1085  val = S + A - P;
1086  break;
1087  default:
1088  RZ_LOG_WARN("Reloc type %d not implemented.\n", rel->type);
1089  break;
1090  }
1091  if (low) {
1092  switch (low) {
1093  case 14:
1094  val &= (1 << 14) - 1;
1095  rz_buf_read_at(obj->buf_patched, patch_addr, buf, 2);
1096  rz_write_ble32(buf, (rz_read_ble32(buf, big_endian) & ~(RZ_BIT_MASK32(16, 2))) | val << 2, big_endian);
1097  rz_buf_write_at(obj->buf_patched, patch_addr, buf, 2);
1098  break;
1099  case 24:
1100  val &= (1 << 24) - 1;
1101  rz_buf_read_at(obj->buf_patched, patch_addr, buf, 4);
1102  rz_write_ble32(buf, (rz_read_ble32(buf, big_endian) & ~(RZ_BIT_MASK32(26, 2))) | val << 2, big_endian);
1103  rz_buf_write_at(obj->buf_patched, patch_addr, buf, 4);
1104  break;
1105  }
1106  } else if (word) {
1107  switch (word) {
1108  case 2:
1109  rz_write_ble16(buf, val, big_endian);
1110  rz_buf_write_at(obj->buf_patched, patch_addr, buf, 2);
1111  break;
1112  case 4:
1113  rz_write_ble32(buf, val, big_endian);
1114  rz_buf_write_at(obj->buf_patched, patch_addr, buf, 4);
1115  break;
1116  }
1117  }
1118  break;
1119  }
1120  case EM_386:
1121  switch (rel->type) {
1122  case RZ_386_32:
1123  case RZ_386_PC32:
1124  rz_buf_read_at(obj->buf_patched, patch_addr, buf, 4);
1125  val = rz_read_le32(buf) + S + A;
1126  if (rel->type == RZ_386_PC32) {
1127  val -= P;
1128  }
1129  rz_write_le32(buf, val);
1130  rz_buf_write_at(obj->buf_patched, patch_addr, buf, 4);
1131  default:
1132  break;
1133  }
1134  break;
1135  case EM_X86_64: {
1136  int word = 0;
1137  switch (rel->type) {
1138  case RZ_X86_64_8:
1139  word = 1;
1140  val = S + A;
1141  break;
1142  case RZ_X86_64_16:
1143  word = 2;
1144  val = S + A;
1145  break;
1146  case RZ_X86_64_32:
1147  case RZ_X86_64_32S:
1148  word = 4;
1149  val = S + A;
1150  break;
1151  case RZ_X86_64_64:
1152  word = 8;
1153  val = S + A;
1154  break;
1155  case RZ_X86_64_GLOB_DAT:
1156  case RZ_X86_64_JUMP_SLOT:
1157  word = 4;
1158  val = S;
1159  break;
1160  case RZ_X86_64_PC8:
1161  word = 1;
1162  val = S + A - P;
1163  break;
1164  case RZ_X86_64_PC16:
1165  word = 2;
1166  val = S + A - P;
1167  break;
1168  case RZ_X86_64_PC32:
1169  word = 4;
1170  val = S + A - P;
1171  break;
1172  case RZ_X86_64_PC64:
1173  word = 8;
1174  val = S + A - P;
1175  break;
1176  case RZ_X86_64_PLT32:
1177  word = 4;
1178  val = L + A - P;
1179  break;
1180  case RZ_X86_64_RELATIVE:
1181  word = 8;
1182  val = B + A;
1183  break;
1184  default:
1185  // RZ_LOG_ERROR("relocation %d not handle at this time\n", rel->type);
1186  break;
1187  }
1188  switch (word) {
1189  case 0:
1190  break;
1191  case 1:
1192  buf[0] = val;
1193  rz_buf_write_at(obj->buf_patched, patch_addr, buf, 1);
1194  break;
1195  case 2:
1196  rz_write_le16(buf, val);
1197  rz_buf_write_at(obj->buf_patched, patch_addr, buf, 2);
1198  break;
1199  case 4:
1200  rz_write_le32(buf, val);
1201  rz_buf_write_at(obj->buf_patched, patch_addr, buf, 4);
1202  break;
1203  case 8:
1204  rz_write_le64(buf, val);
1205  rz_buf_write_at(obj->buf_patched, patch_addr, buf, 8);
1206  break;
1207  }
1208  break;
1209  }
1210  }
1211 }
1212 
1213 static ut64 get_got_addr(ELFOBJ *bin) {
1214  if (!Elf_(rz_bin_elf_has_sections)(bin)) {
1215  return 0;
1216  }
1217 
1219  if (section) {
1220  return section->offset;
1221  }
1222 
1224  if (section) {
1225  return section->offset;
1226  }
1227 
1228  return 0;
1229 }
1230 
1231 static RzBinReloc *reloc_convert(ELFOBJ *bin, RzBinElfReloc *rel, ut64 GOT) {
1232  rz_return_val_if_fail(bin && rel, NULL);
1233 
1234  ut64 B = bin->baddr;
1235  ut64 P = rel->vaddr; // rva has taken baddr into account
1237  if (!r) {
1238  return NULL;
1239  }
1240  r->import = NULL;
1241  r->symbol = NULL;
1242  r->is_ifunc = false;
1243  r->addend = rel->addend;
1244  if (rel->sym) {
1245  r->import = get_import(bin, rel->sym);
1246  if (!r->import) {
1247  r->symbol = get_symbol(bin, rel->sym);
1248  }
1249  }
1250  r->vaddr = rel->vaddr;
1251  r->paddr = rel->paddr;
1252  r->target_vaddr = rel->target_vaddr;
1253 
1254 #define SET(T) \
1255  r->type = RZ_BIN_RELOC_##T; \
1256  r->additive = 0; \
1257  return r
1258 #define ADD(T, A) \
1259  r->type = RZ_BIN_RELOC_##T; \
1260  r->addend += A; \
1261  r->additive = rel->mode == DT_RELA; \
1262  return r
1263 
1264  switch (bin->ehdr.e_machine) {
1265  case EM_386:
1266  switch (rel->type) {
1267  case RZ_386_NONE: break; // malloc then free. meh. then again, there's no real world use for _NONE.
1268  case RZ_386_32: ADD(32, 0);
1269  case RZ_386_PC32: ADD(32, -P);
1270  case RZ_386_GLOB_DAT: SET(32);
1271  case RZ_386_JMP_SLOT: SET(32);
1272  case RZ_386_RELATIVE: ADD(32, B);
1273  case RZ_386_GOTOFF: ADD(32, -GOT);
1274  case RZ_386_GOTPC: ADD(32, GOT - P);
1275  case RZ_386_16: ADD(16, 0);
1276  case RZ_386_PC16: ADD(16, -P);
1277  case RZ_386_8: ADD(8, 0);
1278  case RZ_386_PC8: ADD(8, -P);
1279  case RZ_386_COPY: ADD(32, 0); // XXX: copy symbol at runtime
1280  case RZ_386_IRELATIVE: r->is_ifunc = true; SET(32);
1281  default: break;
1282  }
1283  break;
1284  case EM_X86_64:
1285  switch (rel->type) {
1286  case RZ_X86_64_NONE: break; // malloc then free. meh. then again, there's no real world use for _NONE.
1287  case RZ_X86_64_64: ADD(64, 0);
1288  case RZ_X86_64_PLT32: ADD(32, -P /* +L */);
1289  case RZ_X86_64_GOT32: ADD(32, GOT);
1290  case RZ_X86_64_PC32: ADD(32, -P);
1291  case RZ_X86_64_GLOB_DAT: r->vaddr -= rel->sto; SET(64);
1292  case RZ_X86_64_JUMP_SLOT: r->vaddr -= rel->sto; SET(64);
1293  case RZ_X86_64_RELATIVE: ADD(64, B);
1294  case RZ_X86_64_32: ADD(32, 0);
1295  case RZ_X86_64_32S: ADD(32, 0);
1296  case RZ_X86_64_16: ADD(16, 0);
1297  case RZ_X86_64_PC16: ADD(16, -P);
1298  case RZ_X86_64_8: ADD(8, 0);
1299  case RZ_X86_64_PC8: ADD(8, -P);
1300  case RZ_X86_64_GOTPCREL: ADD(64, GOT - P);
1301  case RZ_X86_64_COPY: ADD(64, 0); // XXX: copy symbol at runtime
1302  case RZ_X86_64_IRELATIVE: r->is_ifunc = true; SET(64);
1303  default: break;
1304  }
1305  break;
1306  case EM_ARM:
1307  switch (rel->type) {
1308  case RZ_ARM_NONE: break;
1309  case RZ_ARM_ABS32: ADD(32, 0);
1310  case RZ_ARM_REL32: ADD(32, -P);
1311  case RZ_ARM_ABS16: ADD(16, 0);
1312  case RZ_ARM_ABS8: ADD(8, 0);
1313  case RZ_ARM_SBREL32: ADD(32, -B);
1314  case RZ_ARM_GLOB_DAT: ADD(32, 0);
1315  case RZ_ARM_JUMP_SLOT: ADD(32, 0);
1316  case RZ_ARM_COPY: ADD(32, 0); // copy symbol at runtime
1317  case RZ_ARM_RELATIVE: ADD(32, B);
1318  case RZ_ARM_GOTOFF: ADD(32, -GOT);
1319  case RZ_ARM_GOTPC: ADD(32, GOT - P);
1320  case RZ_ARM_CALL: ADD(24, -P);
1321  case RZ_ARM_JUMP24: ADD(24, -P);
1322  case RZ_ARM_THM_JUMP24: ADD(24, -P);
1323  case RZ_ARM_PREL31: ADD(32, -P);
1324  case RZ_ARM_MOVW_PREL_NC: ADD(16, -P);
1325  case RZ_ARM_MOVT_PREL: ADD(32, -P);
1326  case RZ_ARM_THM_MOVW_PREL_NC: ADD(16, -P);
1327  case RZ_ARM_REL32_NOI: ADD(32, -P);
1328  case RZ_ARM_ABS32_NOI: ADD(32, 0);
1329  case RZ_ARM_ALU_PC_G0_NC: ADD(32, -P);
1330  case RZ_ARM_ALU_PC_G0: ADD(32, -P);
1331  case RZ_ARM_ALU_PC_G1_NC: ADD(32, -P);
1332  case RZ_ARM_ALU_PC_G1: ADD(32, -P);
1333  case RZ_ARM_ALU_PC_G2: ADD(32, -P);
1334  case RZ_ARM_LDR_PC_G1: ADD(32, -P);
1335  case RZ_ARM_LDR_PC_G2: ADD(32, -P);
1336  case RZ_ARM_LDRS_PC_G0: ADD(32, -P);
1337  case RZ_ARM_LDRS_PC_G1: ADD(32, -P);
1338  case RZ_ARM_LDRS_PC_G2: ADD(32, -P);
1339  case RZ_ARM_LDC_PC_G0: ADD(32, -P);
1340  case RZ_ARM_LDC_PC_G1: ADD(32, -P);
1341  case RZ_ARM_LDC_PC_G2: ADD(32, -P);
1342  default: ADD(32, GOT); break; // reg relocations
1343  }
1344  break;
1345  case EM_RISCV:
1346  switch (rel->type) {
1347  case RZ_RISCV_NONE: break;
1348  case RZ_RISCV_JUMP_SLOT: ADD(64, 0);
1349  case RZ_RISCV_RELATIVE: ADD(64, B);
1350  default: ADD(64, GOT); break; // reg relocations
1351  }
1352  break;
1353  case EM_AARCH64:
1354  switch (rel->type) {
1355  case RZ_AARCH64_NONE: break;
1356  case RZ_AARCH64_ABS32: ADD(32, 0);
1357  case RZ_AARCH64_ABS16: ADD(16, 0);
1358  case RZ_AARCH64_GLOB_DAT: SET(64);
1359  case RZ_AARCH64_JUMP_SLOT: SET(64);
1360  case RZ_AARCH64_RELATIVE: ADD(64, B);
1361  default: break; // reg relocations
1362  }
1363  break;
1364  case EM_PPC:
1365  switch (rel->type) {
1366  case RZ_PPC_NONE: break;
1367  case RZ_PPC_GLOB_DAT: ADD(32, 0);
1368  case RZ_PPC_JMP_SLOT: ADD(32, 0);
1369  case RZ_PPC_COPY: ADD(32, 0); // copy symbol at runtime
1370  case RZ_PPC_REL24: ADD(24, -P);
1371  case RZ_PPC_REL14: ADD(16, -P);
1372  case RZ_PPC_REL32: ADD(32, -P);
1373  case RZ_PPC_RELATIVE: ADD(32, -P);
1374  case RZ_PPC_PLT32: ADD(32, -P);
1375  case RZ_PPC_ADDR16: ADD(16, 0);
1376  case RZ_PPC_ADDR32: ADD(32, 0);
1377  default:
1378  RZ_LOG_WARN("unimplemented ELF/PPC reloc type %d\n", rel->type);
1379  break;
1380  }
1381  break;
1382  default: break;
1383  }
1384 
1385 #undef SET
1386 #undef ADD
1387 
1388  free(r);
1389  return NULL;
1390 }
1391 
1392 static void patch_relocs(RzBinFile *bf, ELFOBJ *bin) {
1393  rz_return_if_fail(bf && bin);
1394  if (bin->relocs_patched || !Elf_(rz_bin_elf_has_relocs)(bin)) {
1395  return;
1396  }
1397  bin->relocs_patched = true; // run this function just once (lazy relocs patching)
1398  RzBinObject *obj = bf->o;
1399  if (!obj || !obj->opts.patch_relocs || (bin->ehdr.e_type != ET_REL && bin->ehdr.e_type != ET_DYN)) {
1400  return;
1401  }
1402  ut64 cdsz = reloc_target_size(bin);
1404  if (!size) {
1405  return;
1406  }
1407  RzBinRelocTargetBuilder *targets = rz_bin_reloc_target_builder_new(cdsz, bin->reloc_targets_map_base);
1408  if (!targets) {
1409  return;
1410  }
1412  if (!bin->buf_patched) {
1414  return;
1415  }
1416  RzBinElfReloc *reloc;
1417  ut64 got_addr = get_got_addr(bin);
1418  ut64 baddr = bf->o->opts.baseaddr;
1419 
1420  rz_bin_elf_foreach_relocs(bin, reloc) {
1421  ut64 sym_addr = 0;
1422  if (reloc->sym) {
1423  RzBinElfSymbol *import = Elf_(rz_bin_elf_get_import)(bin, reloc->sym);
1424  if (import) {
1425  sym_addr = rz_bin_reloc_target_builder_get_target(targets, reloc->sym);
1426  } else {
1427  RzBinElfSymbol *symbol = Elf_(rz_bin_elf_get_symbol)(bin, reloc->sym);
1428  if (symbol) {
1429  sym_addr = symbol->vaddr;
1431  Elf_(rz_bin_elf_fix_arm_thumb_addr)(&sym_addr);
1432  }
1433  } else {
1434  sym_addr = rz_bin_reloc_target_builder_get_target(targets, reloc->sym);
1435  }
1436  }
1437  }
1438  patch_reloc(bin, reloc, sym_addr, baddr, sym_addr, got_addr);
1439  reloc->target_vaddr = sym_addr;
1440  }
1442  // from now on, all writes should propagate through to the actual file
1444 }
1445 
1446 static RzList *virtual_files(RzBinFile *bf) {
1448  if (!r) {
1449  return NULL;
1450  }
1451  RzBinObject *o = bf->o;
1452  struct Elf_(rz_bin_elf_obj_t) *obj = o ? o->bin_obj : NULL;
1453  if (!obj) {
1454  return r;
1455  }
1456  patch_relocs(bf, obj);
1457  // virtual file for reloc targets (where the relocs will point into)
1458  ut64 rtmsz = reloc_targets_vfile_size(bf, obj);
1459  if (rtmsz) {
1460  RzBuffer *buf = rz_buf_new_empty(rtmsz);
1461  if (!buf) {
1462  return r;
1463  }
1465  if (!vf) {
1466  rz_buf_free(buf);
1467  return r;
1468  }
1469  vf->buf = buf;
1470  vf->buf_owned = true;
1472  rz_list_push(r, vf);
1473  }
1474  // virtual file mirroring the raw file, but with relocs patched
1475  if (obj->buf_patched) {
1477  if (!vf) {
1478  return r;
1479  }
1480  vf->buf = obj->buf_patched;
1482  rz_list_push(r, vf);
1483  }
1484  return r;
1485 }
1486 
1487 static RzList *maps(RzBinFile *bf) {
1488  struct Elf_(rz_bin_elf_obj_t) *obj = (bf && bf->o) ? bf->o->bin_obj : NULL;
1489  if (!obj) {
1490  return NULL;
1491  }
1492  RzList *ret = maps_unpatched(bf);
1493  if (!ret) {
1494  return NULL;
1495  }
1496 
1497  // if relocs should be patched, use the patched vfile for everything from the file
1498  patch_relocs(bf, obj);
1499  rz_bin_relocs_patch_maps(ret, obj->buf_patched, 0, obj->reloc_targets_map_base,
1500  reloc_targets_vfile_size(bf, obj),
1503  return ret;
1504 }
1505 
1506 static RzList *sections(RzBinFile *bf) {
1507  ELFOBJ *obj = (bf && bf->o) ? bf->o->bin_obj : NULL;
1508  RzBinSection *ptr = NULL;
1509  RzList *ret = NULL;
1510 
1511  if (!obj || !(ret = rz_list_newf((RzListFree)rz_bin_section_free))) {
1512  return NULL;
1513  }
1514 
1515  // there is not leak in section since they are cached by elf.c
1516  // and freed within Elf_(rz_bin_elf_free)
1517  size_t i;
1520  if (!(ptr = RZ_NEW0(RzBinSection))) {
1521  break;
1522  }
1523  ptr->name = rz_str_new(section->name);
1524  if (!ptr->name) {
1525  ptr->name = rz_str_new("");
1526  }
1527  if (strstr(ptr->name, "data") && !strstr(ptr->name, "rel") && !strstr(ptr->name, "pydata")) {
1528  ptr->is_data = true;
1529  } else if (!strcmp(ptr->name, "C")) {
1530  ptr->is_data = true;
1531  }
1532  if (is_wordable_section(ptr->name)) {
1533  ptr->format = rz_str_newf("Cd %zu %" PFMT64d, sizeof(Elf_(Addr)), section->size / sizeof(Elf_(Addr)));
1534  }
1535  ptr->size = section->type != SHT_NOBITS ? section->size : 0;
1536  ptr->vsize = section->size;
1537  ptr->paddr = section->offset;
1538  ptr->vaddr = section->rva;
1539  ptr->type = section->type;
1540  ptr->flags = section->flags;
1541  ptr->perm = section_perms_from_flags(section->flags);
1542  rz_list_append(ret, ptr);
1543  }
1544 
1545  // program headers is another section
1546  ut16 mach = obj->ehdr.e_machine;
1547 
1548  size_t n = 0;
1551  if (!(ptr = RZ_NEW0(RzBinSection))) {
1552  return ret;
1553  }
1554 
1555  ptr->size = iter->data.p_filesz;
1556  ptr->vsize = iter->data.p_memsz;
1557  ptr->paddr = iter->data.p_offset;
1558  ptr->vaddr = iter->data.p_vaddr;
1559  ptr->perm = iter->data.p_flags;
1560  ptr->align = iter->data.p_align;
1561  ptr->is_segment = true;
1562 
1563  switch (iter->data.p_type) {
1564  case PT_DYNAMIC:
1565  ptr->name = strdup("DYNAMIC");
1566  break;
1567  case PT_LOAD: {
1568  ptr->name = rz_str_newf("LOAD%zu", n++);
1569  ptr->perm |= RZ_PERM_R;
1570  break;
1571  }
1572  case PT_INTERP:
1573  ptr->name = strdup("INTERP");
1574  break;
1575  case PT_GNU_STACK:
1576  ptr->name = strdup("GNU_STACK");
1577  break;
1578  case PT_GNU_RELRO:
1579  ptr->name = strdup("GNU_RELRO");
1580  break;
1581  case PT_GNU_EH_FRAME:
1582  ptr->name = strdup("GNU_EH_FRAME");
1583  break;
1584  case PT_PHDR:
1585  ptr->name = strdup("PHDR");
1586  break;
1587  case PT_TLS:
1588  ptr->name = strdup("TLS");
1589  break;
1590  case PT_NOTE:
1591  ptr->name = strdup("NOTE");
1592  break;
1593  case PT_OPENBSD_RANDOMIZE:
1594  ptr->name = strdup("OPENBSD_RANDOMIZE");
1595  break;
1596  case PT_OPENBSD_WXNEEDED:
1597  ptr->name = strdup("OPENBSD_WXNEEDED");
1598  break;
1599  case PT_OPENBSD_BOOTDATA:
1600  ptr->name = strdup("OPENBSD_BOOTDATA");
1601  break;
1602  default:
1603  if (ptr->size == 0 && ptr->vsize == 0) {
1604  ptr->name = strdup("NONE");
1605  } else {
1606  ptr->name = setphname(mach, iter->data.p_type);
1607  }
1608  break;
1609  }
1610  rz_list_append(ret, ptr);
1611  }
1612 
1613  // add entry for ehdr
1614  ptr = RZ_NEW0(RzBinSection);
1615  if (ptr) {
1616  ut64 ehdr_size = sizeof(obj->ehdr);
1617  if (bf->size < ehdr_size) {
1618  ehdr_size = bf->size;
1619  }
1620  ptr->name = strdup("ehdr");
1621  ptr->paddr = 0;
1622  ptr->vaddr = obj->baddr;
1623  ptr->size = ehdr_size;
1624  ptr->vsize = ehdr_size;
1625  ptr->perm = RZ_PERM_RW;
1626  ptr->is_segment = true;
1627  rz_list_append(ret, ptr);
1628  }
1629 
1630  return ret;
1631 }
1632 
1633 static RzList *symbols(RzBinFile *bf) {
1634  rz_return_val_if_fail(bf && bf->o && bf->o->bin_obj, NULL);
1635 
1636  ELFOBJ *bin = bf->o->bin_obj;
1638  if (!ret) {
1639  return NULL;
1640  }
1641 
1642  RzBinElfSymbol *symbol;
1643  rz_bin_elf_foreach_symbols(bin, symbol) {
1644  RzBinSymbol *tmp = convert_symbol(bin, symbol);
1645  if (!tmp) {
1646  rz_list_free(ret);
1647  return NULL;
1648  }
1649 
1650  rz_list_append(ret, tmp);
1651  }
1652 
1653  RzBinElfSymbol *import;
1654  rz_bin_elf_foreach_imports(bin, import) {
1655  RzBinSymbol *tmp = convert_symbol(bin, import);
1656  if (!tmp) {
1657  rz_list_free(ret);
1658  return NULL;
1659  }
1660 
1661  tmp->is_imported = true;
1662 
1663  rz_list_append(ret, tmp);
1664  }
1665 
1666  return ret;
1667 }
1668 
1669 static RzList *imports(RzBinFile *bf) {
1670  rz_return_val_if_fail(bf && bf->o, NULL);
1671 
1672  ELFOBJ *bin = bf->o->bin_obj;
1673 
1674  if (!Elf_(rz_bin_elf_has_imports)(bin)) {
1675  return NULL;
1676  }
1677 
1679  if (!result) {
1680  return NULL;
1681  }
1682 
1683  RzBinElfSymbol *import;
1684  rz_bin_elf_foreach_imports(bin, import) {
1685  RzBinImport *tmp = convert_import(import);
1686  if (!tmp) {
1687  rz_list_free(result);
1688  return NULL;
1689  }
1690 
1691  rz_list_append(result, tmp);
1692  }
1693 
1694  return result;
1695 }
1696 
1697 static RzList *libs(RzBinFile *bf) {
1698  rz_return_val_if_fail(bf && bf->o && bf->o->bin_obj, NULL);
1699  return Elf_(rz_bin_elf_get_libs)(bf->o->bin_obj);
1700 }
1701 
1702 static RzList *relocs(RzBinFile *bf) {
1703  rz_return_val_if_fail(bf && bf->o && bf->o->bin_obj, NULL);
1704  RzList *ret = NULL;
1705  RzBinReloc *ptr = NULL;
1706 
1707  if (!bf->o) {
1708  return NULL;
1709  }
1710 
1711  ELFOBJ *bin = bf->o->bin_obj;
1712  if (!bin || !Elf_(rz_bin_elf_has_relocs)(bin)) {
1713  return NULL;
1714  }
1715 
1716  patch_relocs(bf, bin);
1717 
1718  if (!(ret = rz_list_newf(free))) {
1719  return NULL;
1720  }
1721 
1722  ut64 got_addr = get_got_addr(bin);
1723 
1724  if (!got_addr) {
1725  got_addr = bin->reloc_targets_map_base;
1726  }
1727 
1728  RzBinElfReloc *reloc;
1729  rz_bin_elf_foreach_relocs(bin, reloc) {
1730  if (!(ptr = reloc_convert(bin, reloc, got_addr))) {
1731  continue;
1732  }
1733 
1734  rz_list_append(ret, ptr);
1735  }
1736 
1737  return ret;
1738 }
1739 
1740 static void lookup_symbols(RzBinFile *bf, RzBinInfo *ret) {
1741  RzList *symbols_list = symbols(bf);
1742  RzListIter *iter;
1743  RzBinSymbol *symbol;
1744  bool is_rust = false;
1745  if (symbols_list) {
1746  rz_list_foreach (symbols_list, iter, symbol) {
1747  if (ret->has_canary && is_rust) {
1748  break;
1749  }
1750  if (!strcmp(symbol->name, "_NSConcreteGlobalBlock")) {
1751  ret->lang = (ret->lang && !strcmp(ret->lang, "c++")) ? "c++ blocks ext." : "c blocks ext.";
1752  }
1753  if (!ret->has_canary) {
1754  if (strstr(symbol->name, "__stack_chk_fail") || strstr(symbol->name, "__stack_smash_handler")) {
1755  ret->has_canary = true;
1756  }
1757  }
1758  if (!is_rust && !strcmp(symbol->name, "__rust_oom")) {
1759  is_rust = true;
1760  ret->lang = "rust";
1761  }
1762  }
1763  rz_list_free(symbols_list);
1764  }
1765 }
1766 
1767 static void lookup_sections(RzBinFile *bf, RzBinInfo *ret) {
1768  RzList *sections_list = sections(bf);
1769  RzListIter *iter;
1771  ret->has_retguard = -1;
1772  rz_list_foreach (sections_list, iter, section) {
1773  if (ret->has_retguard != -1) {
1774  break;
1775  }
1776 #define RZ_BIN_RANDOMDATA_RETGUARD_SZ 48
1777  if (!strcmp(section->name, ".openbsd.randomdata")) {
1778  // The retguard cookie adds 8 per return function inst.
1779  ret->has_retguard = (section->size >= RZ_BIN_RANDOMDATA_RETGUARD_SZ);
1780  break;
1781  }
1782  }
1783  rz_list_free(sections_list);
1784 }
1785 
1786 static bool has_sanitizers(RzBinFile *bf) {
1787  bool ret = false;
1788  RzList *imports_list = imports(bf);
1789  RzListIter *iter;
1790  RzBinImport *import;
1791  rz_list_foreach (imports_list, iter, import) {
1792  if (strstr(import->name, "__sanitizer") ||
1793  strstr(import->name, "__ubsan")) {
1794  ret = true;
1795  break;
1796  }
1797  }
1798  rz_list_free(imports_list);
1799  return ret;
1800 }
1801 
1802 static RzBinInfo *info(RzBinFile *bf) {
1803  RzBinInfo *ret = NULL;
1804  char *str;
1805 
1806  if (!(ret = RZ_NEW0(RzBinInfo))) {
1807  return NULL;
1808  }
1809  ret->file = bf->file
1810  ? strdup(bf->file)
1811  : NULL;
1812  ELFOBJ *obj = bf->o->bin_obj;
1813  if ((str = Elf_(rz_bin_elf_get_rpath)(obj))) {
1814  ret->rpath = strdup(str);
1815  free(str);
1816  } else {
1817  ret->rpath = strdup("NONE");
1818  }
1819  if (!(str = Elf_(rz_bin_elf_get_file_type)(obj))) {
1820  free(ret);
1821  return NULL;
1822  }
1823  ret->type = str;
1824  ret->has_pi = (strstr(str, "DYN")) ? 1 : 0;
1825  ret->has_sanitizers = has_sanitizers(bf);
1826  if (!(str = Elf_(rz_bin_elf_get_elf_class)(obj))) {
1827  free(ret);
1828  return NULL;
1829  }
1830  ret->bclass = str;
1831  if (!(str = Elf_(rz_bin_elf_get_osabi_name)(obj))) {
1832  free(ret);
1833  return NULL;
1834  }
1835  ret->os = str;
1836  if (!(str = Elf_(rz_bin_elf_get_osabi_name)(obj))) {
1837  free(ret);
1838  return NULL;
1839  }
1840  ret->subsystem = str;
1841  if (!(str = Elf_(rz_bin_elf_get_machine_name)(obj))) {
1842  free(ret);
1843  return NULL;
1844  }
1845  ret->machine = str;
1846  if (!(str = Elf_(rz_bin_elf_get_head_flag)(obj))) {
1847  free(ret);
1848  return NULL;
1849  }
1850  ret->head_flag = str;
1851  if (!(str = Elf_(rz_bin_elf_get_arch)(obj))) {
1852  free(ret);
1853  return NULL;
1854  }
1855  ret->arch = str;
1856 
1857  if ((str = Elf_(rz_bin_elf_get_cpu)(obj))) {
1858  ret->cpu = str;
1859  }
1860  if ((str = Elf_(rz_bin_elf_get_abi)(obj))) {
1861  ret->features = str;
1862  }
1863 
1864  ret->rclass = strdup("elf");
1865  ret->bits = obj->bits;
1866  if (!strcmp(ret->arch, "avr")) {
1867  ret->bits = 16;
1868  }
1870  ret->has_va = Elf_(rz_bin_elf_has_va)(obj);
1871  ret->has_nx = Elf_(rz_bin_elf_has_nx)(obj);
1872  ret->intrp = Elf_(rz_bin_elf_get_intrp)(obj);
1873  ret->compiler = Elf_(rz_bin_elf_get_compiler)(obj);
1874  ret->dbg_info = 0;
1875  if (!Elf_(rz_bin_elf_is_stripped)(obj)) {
1877  } else {
1878  ret->dbg_info |= RZ_BIN_DBG_STRIPPED;
1879  }
1880  if (Elf_(rz_bin_elf_is_static)(obj)) {
1881  ret->dbg_info |= RZ_BIN_DBG_STATIC;
1882  }
1883  lookup_sections(bf, ret);
1884  lookup_symbols(bf, ret);
1885 
1886  return ret;
1887 }
1888 
1889 static bool add_fields_aux(ELFOBJ *bin, RzList *result, ut64 offset, size_t size, const char *name, char *(get_value)(ELFOBJ *bin), const char *fmt) {
1890  char *value = get_value(bin);
1891  if (!value) {
1892  return false;
1893  }
1894 
1895  RzBinField *field = rz_bin_field_new(offset, offset, size, name, value, fmt, false);
1896  if (!field) {
1897  free(value);
1898  return false;
1899  }
1900 
1901  if (!rz_list_append(result, field)) {
1902  rz_bin_field_free(field);
1903  free(value);
1904  return false;
1905  }
1906 
1907  free(value);
1908  return true;
1909 }
1910 
1911 static bool add_fields(ELFOBJ *bin, RzList *result) {
1912  size_t size = bin->ehdr.e_ident[EI_CLASS] == ELFCLASS64 ? 8 : 4;
1913 
1914  return add_fields_aux(bin, result, E_IDENT_OFFSET, 16, "MAGIC", Elf_(rz_bin_elf_get_e_indent_as_string), "x") &&
1915  add_fields_aux(bin, result, E_TYPE_OFFSET, 2, "Type", Elf_(rz_bin_elf_get_e_type_as_string), "x") &&
1916  add_fields_aux(bin, result, E_MACHINE_OFFSET, 2, "Machine", Elf_(rz_bin_elf_get_e_machine_as_string), "x") &&
1917  add_fields_aux(bin, result, E_VERSION_OFFSET, 4, "Version", Elf_(rz_bin_elf_get_e_version_as_string), "x") &&
1918  add_fields_aux(bin, result, E_ENTRYPOINT_OFFSET, size, "Entrypoint", Elf_(rz_bin_elf_get_e_entry_as_string), "x") &&
1919  add_fields_aux(bin, result, E_PHOFF_OFFSET, size, "PhOff", Elf_(rz_bin_elf_get_e_phoff_as_string), "x") &&
1920  add_fields_aux(bin, result, E_SHOFF_OFFSET, size, "ShOff", Elf_(rz_bin_elf_get_e_shoff_as_string), "x") &&
1921  add_fields_aux(bin, result, E_FLAGS_OFFSET, 4, "Flags", Elf_(rz_bin_elf_get_e_flags_as_string), "x") &&
1922  add_fields_aux(bin, result, E_EHSIZE_OFFSET, 2, "EhSize", Elf_(rz_bin_elf_get_e_ehsize_as_string), "x") &&
1923  add_fields_aux(bin, result, E_PHENTSIZE_OFFSET, 2, "PhentSize", Elf_(rz_bin_elf_get_e_phentsize_as_string), "d") &&
1924  add_fields_aux(bin, result, E_PHNUM_OFFSET, 2, "PhNum", Elf_(rz_bin_elf_get_e_phnum_as_string), "d") &&
1925  add_fields_aux(bin, result, E_SHENTSIZE_OFFSET, 2, "ShentSize", Elf_(rz_bin_elf_get_e_shentsize_as_string), "d") &&
1926  add_fields_aux(bin, result, E_SHNUM_OFFSET, 2, "ShNum", Elf_(rz_bin_elf_get_e_shnum_as_string), "d") &&
1927  add_fields_aux(bin, result, E_SHSTRNDX_OFFSET, 2, "ShStrndx", Elf_(rz_bin_elf_get_e_shstrndx_as_string), "d");
1928 }
1929 
1930 static RzList *fields(RzBinFile *bf) {
1931  rz_return_val_if_fail(bf && bf->o && bf->o->bin_obj, NULL);
1932 
1933  ELFOBJ *bin = rz_bin_file_get_elf(bf);
1934 
1936  if (!result) {
1937  return NULL;
1938  }
1939 
1940  if (!add_fields(bin, result)) {
1941  rz_list_free(result);
1942  return NULL;
1943  }
1944 
1945  return result;
1946 }
1947 
1948 static ut64 size(RzBinFile *bf) {
1949  ut64 off = 0;
1950  ut64 len = 0;
1951  if (!bf->o->sections) {
1952  RzListIter *iter;
1954  bf->o->sections = sections(bf);
1955  rz_list_foreach (bf->o->sections, iter, section) {
1956  if (section->paddr > off) {
1957  off = section->paddr;
1958  len = section->size;
1959  }
1960  }
1961  }
1962  return off + len;
1963 }
1964 
1965 static RzList *strings(RzBinFile *bf) {
1966  return rz_bin_file_strings(bf, 4, false);
1967 }
size_t len
Definition: 6502dis.c:15
#define T(op)
const aarch64_field fields[]
Definition: aarch64-opc.c:205
#define mask()
static ut64 get_addr(RzAnalysis *analysis, const char *regname, int idx)
Definition: analysis_tp.c:200
lzma_index ** i
Definition: index.h:629
#define A(x)
Definition: arc.h:165
#define B(x)
Definition: arc.h:166
ut16 val
Definition: armass64_const.h:6
RZ_API RZ_OWN RzList * rz_bin_file_strings(RZ_NONNULL RzBinFile *bf, size_t min_length, bool raw_strings)
Generates a RzList struct containing RzBinString from a given RzBinFile.
Definition: bfile_string.c:325
RZ_API void rz_bin_symbol_free(RzBinSymbol *sym)
Definition: bin.c:175
RZ_API void rz_bin_map_free(RzBinMap *map)
Definition: bin.c:1023
RZ_API void rz_bin_field_free(RzBinField *field)
Definition: bin.c:950
RZ_API void rz_bin_import_free(RzBinImport *imp)
Definition: bin.c:137
RZ_API void rz_bin_section_free(RzBinSection *bs)
Definition: bin.c:1116
RZ_API RzBinField * rz_bin_field_new(ut64 paddr, ut64 vaddr, int size, const char *name, const char *comment, const char *format, bool format_named)
Definition: bin.c:935
RZ_API void rz_bin_virtual_file_free(RzBinVirtualFile *vfile)
Definition: bin.c:1012
static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb)
Definition: bin_any.c:50
static void destroy(RzBinFile *bf)
Definition: bin_any.c:54
static ut64 baddr(RzBinFile *bf)
Definition: bin_any.c:58
static Sdb * get_sdb(RzBinFile *bf)
Definition: bin_art.c:60
static RzList * maps(RzBinFile *bf)
Definition: bin_bf.c:116
#define VFILE_NAME_PATCHED
Definition: bin_bflt.c:12
static RzList * virtual_files(RzBinFile *bf)
Definition: bin_bflt.c:167
static RzBinAddr * binsym(RzBinFile *bf, RzBinSpecialSymbol sym)
Definition: bin_coff.c:47
static RzList * libs(RzBinFile *bf)
Definition: bin_coff.c:379
#define VFILE_NAME_RELOC_TARGETS
Definition: bin_coff.c:13
static char * regstate(RzBinFile *bf)
Definition: bin_dmp64.c:252
RzList * entries(RzBinFile *bf)
Definition: bin_ne.c:98
RzBinInfo * info(RzBinFile *bf)
Definition: bin_ne.c:86
RzList * symbols(RzBinFile *bf)
Definition: bin_ne.c:102
RzList * imports(RzBinFile *bf)
Definition: bin_ne.c:106
RzList * sections(RzBinFile *bf)
Definition: bin_ne.c:110
RzList * relocs(RzBinFile *bf)
Definition: bin_ne.c:114
static ut64 boffset(RzBinFile *bf)
Definition: bin_ninds.c:39
static int value
Definition: cmd_api.c:93
#define P
#define NULL
Definition: cris-opc.c:27
RzCryptoSelector bit
Definition: crypto.c:16
#define r
Definition: crypto_rc6.c:12
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void length
Definition: sflib.h:133
uint16_t ut16
uint32_t ut32
ut64 Elf_() rz_bin_elf_p2v(RZ_NONNULL ELFOBJ *bin, ut64 paddr)
Convert a physical address to the virtual address.
Definition: elf.c:400
void Elf_() rz_bin_elf_free(RZ_NONNULL ELFOBJ *bin)
Free the elf binary.
Definition: elf.c:366
RZ_OWN ELFOBJ *Elf_() rz_bin_elf_new_buf(RZ_NONNULL RzBuffer *buf, RZ_NONNULL RzBinObjectLoadOptions *options)
Definition: elf.c:339
ut64 Elf_() rz_bin_elf_v2p(RZ_NONNULL ELFOBJ *bin, ut64 vaddr)
Convert a virtual address to the physical address.
Definition: elf.c:429
bool Elf_() rz_bin_elf_is_big_endian(RZ_NONNULL ELFOBJ *bin)
Check the binary endianness.
Definition: elf_info.c:1757
#define rz_bin_elf_foreach_segments(bin, segment)
Definition: elf.h:26
RZ_OWN char *Elf_() rz_bin_elf_get_e_type_as_string(RZ_NONNULL ELFOBJ *bin)
Definition: elf_ehdr.c:170
size_t Elf_() rz_bin_elf_get_relocs_count(RZ_NONNULL ELFOBJ *bin)
Definition: elf_relocs.c:245
#define rz_bin_elf_fix_arm_thumb_object_dispatch(object)
Definition: elf.h:228
RZ_OWN char *Elf_() rz_bin_elf_get_e_ehsize_as_string(RZ_NONNULL ELFOBJ *bin)
Definition: elf_ehdr.c:82
#define rz_bin_elf_enumerate_sections(bin, section, i)
Definition: elf.h:34
RZ_BORROW RzBinElfSymbol *Elf_() rz_bin_elf_get_symbol(RZ_NONNULL ELFOBJ *bin, ut32 ordinal)
Definition: elf_symbols.c:473
bool Elf_() rz_bin_elf_is_static(RZ_NONNULL ELFOBJ *bin)
Check if the binary is statically-linked library.
Definition: elf_info.c:1674
bool Elf_() rz_bin_elf_is_stripped(RZ_NONNULL ELFOBJ *bin)
Check if the binary is stripped.
Definition: elf_info.c:1591
void Elf_() rz_bin_elf_fix_arm_thumb_symbol(RZ_NONNULL RzBinSymbol *symbol)
Definition: elf_arm.c:49
#define rz_bin_elf_foreach_sections(bin, section)
Definition: elf.h:30
RZ_OWN char *Elf_() rz_bin_elf_get_file_type(RZ_NONNULL ELFOBJ *bin)
Return a string representing the file type.
Definition: elf_info.c:1462
RzBinElfSegment
Definition: elf.h:131
#define RZ_BIN_ELF_SCN_IS_EXECUTABLE(x)
Definition: elf.h:16
RZ_BORROW RzBinElfSymbol *Elf_() rz_bin_elf_get_import(RZ_NONNULL ELFOBJ *bin, ut32 ordinal)
Definition: elf_imports.c:316
#define rz_bin_elf_foreach_symbols(bin, symbol)
Definition: elf.h:46
bool Elf_() rz_bin_elf_is_executable(RZ_NONNULL ELFOBJ *bin)
Check if the elf binary is executable.
Definition: elf_info.c:1648
RZ_OWN char *Elf_() rz_bin_elf_get_e_phnum_as_string(RZ_NONNULL ELFOBJ *bin)
Definition: elf_ehdr.c:134
RZ_OWN char *Elf_() rz_bin_elf_get_e_shstrndx_as_string(RZ_NONNULL ELFOBJ *bin)
Definition: elf_ehdr.c:164
#define rz_bin_elf_foreach_relocs(bin, reloc)
Definition: elf.h:38
ut64 Elf_() rz_bin_elf_get_main_offset(RZ_NONNULL ELFOBJ *bin)
Compute the main offset of the binary.
Definition: elf_info.c:1886
#define rz_bin_elf_foreach_imports(bin, import)
Definition: elf.h:50
bool Elf_() rz_bin_elf_has_va(ELFOBJ *bin)
Check if the elf use virtual address.
Definition: elf_info.c:1637
bool Elf_() rz_bin_elf_read_addr(RZ_NONNULL ELFOBJ *bin, RZ_NONNULL RZ_INOUT ut64 *offset, RZ_NONNULL RZ_OUT Elf_(Addr) *result)
Definition: elf_misc.c:82
#define ELFOBJ
Definition: elf.h:24
RZ_OWN char *Elf_() rz_bin_elf_get_elf_class(RZ_NONNULL ELFOBJ *bin)
Return a string representing the elf class.
Definition: elf_info.c:1443
bool Elf_() rz_bin_elf_has_relocs(RZ_NONNULL ELFOBJ *bin)
Definition: elf_relocs.c:239
#define rz_bin_elf_foreach_notes_segment(bin, notes)
Definition: elf.h:42
RzBinElfNote
Definition: elf.h:182
bool Elf_() rz_bin_elf_has_nx(RZ_NONNULL ELFOBJ *bin)
Check if the stack is not executable.
Definition: elf_info.c:1615
bool Elf_() rz_bin_elf_is_arm_binary_supporting_thumb(RZ_NONNULL ELFOBJ *bin)
Definition: elf_arm.c:19
RZ_OWN char *Elf_() rz_bin_elf_get_intrp(RZ_NONNULL ELFOBJ *bin)
Get the program interpreter.
Definition: elf_info.c:1568
RZ_OWN char *Elf_() rz_bin_elf_get_e_entry_as_string(RZ_NONNULL ELFOBJ *bin)
Definition: elf_ehdr.c:88
RZ_OWN char *Elf_() rz_bin_elf_get_abi(RZ_NONNULL ELFOBJ *bin)
Return a string representing the application binary interface.
Definition: elf_info.c:1386
void Elf_() rz_bin_elf_fix_arm_thumb_addr(ut64 *addr)
Definition: elf_arm.c:28
RZ_OWN char *Elf_() rz_bin_elf_get_e_shoff_as_string(RZ_NONNULL ELFOBJ *bin)
Definition: elf_ehdr.c:158
bool Elf_() rz_bin_elf_is_thumb_addr(ut64 addr)
Definition: elf_arm.c:24
ut64 Elf_() rz_bin_elf_get_baddr(RZ_NONNULL ELFOBJ *bin)
Compute the base address of the binary.
Definition: elf_info.c:1772
RZ_OWN char *Elf_() rz_bin_elf_get_machine_name(RZ_NONNULL ELFOBJ *bin)
Return a string representing the machine name.
Definition: elf_info.c:1508
RZ_OWN char *Elf_() rz_bin_elf_get_e_shentsize_as_string(RZ_NONNULL ELFOBJ *bin)
Definition: elf_ehdr.c:146
#define RZ_BIN_ELF_SCN_IS_READABLE(x)
Definition: elf.h:17
RZ_OWN RzList *Elf_() rz_bin_elf_get_libs(RZ_NONNULL ELFOBJ *bin)
List all imported lib.
Definition: elf_info.c:877
bool Elf_() rz_bin_elf_has_imports(RZ_NONNULL ELFOBJ *bin)
Definition: elf_imports.c:342
bool Elf_() rz_bin_elf_has_notes(RZ_NONNULL ELFOBJ *bin)
Definition: elf_notes.c:255
RZ_BORROW RzBinElfSection *Elf_() rz_bin_elf_get_section_with_name(RZ_NONNULL ELFOBJ *bin, RZ_NONNULL const char *name)
Definition: elf_sections.c:278
RZ_OWN char *Elf_() rz_bin_elf_get_e_machine_as_string(RZ_NONNULL ELFOBJ *bin)
Definition: elf_ehdr.c:122
#define RZ_BIN_ELF_SCN_IS_WRITABLE(x)
Definition: elf.h:18
RzBinElfNoteFile
Definition: elf.h:165
bool Elf_() rz_bin_elf_get_dt_info(RZ_NONNULL ELFOBJ *bin, ut64 key, RZ_OUT ut64 *info)
Definition: elf_dynamic.c:120
RZ_OWN char *Elf_() rz_bin_elf_get_rpath(RZ_NONNULL ELFOBJ *bin)
Get the rpath.
Definition: elf_info.c:1550
RZ_OWN char *Elf_() rz_bin_elf_get_e_flags_as_string(RZ_NONNULL ELFOBJ *bin)
Definition: elf_ehdr.c:94
RZ_OWN char *Elf_() rz_bin_elf_get_arch(RZ_NONNULL ELFOBJ *bin)
Get the elf binary architecture.
Definition: elf_info.c:1403
RZ_OWN char *Elf_() rz_bin_elf_get_e_version_as_string(RZ_NONNULL ELFOBJ *bin)
Definition: elf_ehdr.c:176
bool Elf_() rz_bin_elf_has_segments(RZ_NONNULL ELFOBJ *bin)
Definition: elf_segments.c:149
bool Elf_() rz_bin_elf_has_sections(RZ_NONNULL ELFOBJ *bin)
Definition: elf_sections.c:440
RZ_OWN char *Elf_() rz_bin_elf_get_head_flag(RZ_NONNULL ELFOBJ *bin)
Return the head flag.
Definition: elf_info.c:1487
RZ_OWN char *Elf_() rz_bin_elf_get_e_phoff_as_string(RZ_NONNULL ELFOBJ *bin)
Definition: elf_ehdr.c:140
RZ_OWN char *Elf_() rz_bin_elf_get_osabi_name(RZ_NONNULL ELFOBJ *bin)
Return the os application binary interface name.
Definition: elf_info.c:1527
ut64 Elf_() rz_bin_elf_get_init_offset(RZ_NONNULL ELFOBJ *bin)
Compute the init offset of the binary.
Definition: elf_info.c:1863
ut64 Elf_() rz_bin_elf_get_entry_offset(RZ_NONNULL ELFOBJ *bin)
Get the entry offset.
Definition: elf_info.c:1813
ut64 Elf_() rz_bin_elf_get_boffset(RZ_NONNULL ELFOBJ *bin)
Compute the base offset of the binary.
Definition: elf_info.c:1795
RZ_OWN char *Elf_() rz_bin_elf_get_e_indent_as_string(RZ_NONNULL ELFOBJ *bin)
Definition: elf_ehdr.c:100
RZ_OWN char *Elf_() rz_bin_elf_get_cpu(RZ_NONNULL ELFOBJ *bin)
Return a string representing the cpu.
Definition: elf_info.c:1422
RZ_OWN char *Elf_() rz_bin_elf_get_e_shnum_as_string(RZ_NONNULL ELFOBJ *bin)
Definition: elf_ehdr.c:152
ut64 Elf_() rz_bin_elf_get_sp_val(RZ_NONNULL ELFOBJ *bin)
Get the stack pointer value.
Definition: elf_corefile.c:16
RZ_OWN char *Elf_() rz_bin_elf_get_compiler(RZ_NONNULL ELFOBJ *bin)
Get the compiler info from the .comment section.
Definition: elf_info.c:1339
bool Elf_() rz_bin_elf_print_ehdr(ELFOBJ *bin, RZ_NONNULL PrintfCallback cb)
Definition: elf_ehdr.c:202
RZ_OWN char *Elf_() rz_bin_elf_get_e_phentsize_as_string(RZ_NONNULL ELFOBJ *bin)
Definition: elf_ehdr.c:128
ut64 Elf_() rz_bin_elf_get_fini_offset(RZ_NONNULL ELFOBJ *bin)
Compute the fini offset of the binary.
Definition: elf_info.c:1840
#define E_PHENTSIZE_OFFSET
Definition: elf_specs.h:54
#define E_MACHINE_OFFSET
Definition: elf_specs.h:47
#define PT_OPENBSD_BOOTDATA
Definition: elf_specs.h:210
#define PT_OPENBSD_WXNEEDED
Definition: elf_specs.h:209
#define E_TYPE_OFFSET
Definition: elf_specs.h:46
#define E_SHNUM_OFFSET
Definition: elf_specs.h:57
#define E_VERSION_OFFSET
Definition: elf_specs.h:48
#define E_IDENT_OFFSET
Definition: elf_specs.h:45
#define PT_OPENBSD_RANDOMIZE
Definition: elf_specs.h:208
#define E_FLAGS_OFFSET
Definition: elf_specs.h:52
#define E_SHENTSIZE_OFFSET
Definition: elf_specs.h:56
#define E_PHOFF_OFFSET
Definition: elf_specs.h:50
#define E_ENTRYPOINT_OFFSET
Definition: elf_specs.h:49
#define E_SHOFF_OFFSET
Definition: elf_specs.h:51
#define Elf_(name)
Definition: elf_specs.h:32
#define E_PHNUM_OFFSET
Definition: elf_specs.h:55
#define E_SHSTRNDX_OFFSET
Definition: elf_specs.h:58
#define EM_AARCH64
Definition: elf_specs.h:161
#define E_EHSIZE_OFFSET
Definition: elf_specs.h:53
size_t map(int syms, int left, int len)
Definition: enough.c:237
checking print the parsed form of the magic use in n conjunction with m to debug a new magic file n before installing it n output MIME type strings(--mime-type and\n" " --mime-encoding)\n") OPT('s'
#define RZ_PPC64_ADDR16_HA
Definition: glibc_elf.h:2445
#define RZ_386_GOTOFF
Definition: glibc_elf.h:1414
#define RZ_ARM_REL32
Definition: glibc_elf.h:2804
#define RZ_ARM_ALU_PC_G2
Definition: glibc_elf.h:2863
#define RZ_PPC64_ADDR16_LO
Definition: glibc_elf.h:2443
#define R_HEX_NONE
Definition: glibc_elf.h:3986
#define RZ_ARM_THM_JUMP24
Definition: glibc_elf.h:2832
#define RZ_X86_64_GLOB_DAT
Definition: glibc_elf.h:3288
#define R_HEX_11_X
Definition: glibc_elf.h:4011
#define R_HEX_BITMASK_WORD32
Definition: glibc_elf.h:4089
#define RZ_PPC64_ADDR16_HI
Definition: glibc_elf.h:2444
#define RZ_ARM_RELATIVE
Definition: glibc_elf.h:2825
#define RZ_X86_64_PC16
Definition: glibc_elf.h:3295
#define RZ_ARM_JUMP24
Definition: glibc_elf.h:2831
#define R_HEX_BITMASK_WORD32_X26
Definition: glibc_elf.h:4100
#define R_HEX_B22_PCREL_X
Definition: glibc_elf.h:4004
#define RZ_ARM_COPY
Definition: glibc_elf.h:2822
#define R_HEX_DTPREL_16_X
Definition: glibc_elf.h:4059
#define RZ_PPC64_REL16_HA
Definition: glibc_elf.h:2567
#define RZ_ARM_LDRS_PC_G2
Definition: glibc_elf.h:2868
#define RZ_X86_64_PC32
Definition: glibc_elf.h:3284
#define R_HEX_9_X
Definition: glibc_elf.h:4013
#define R_HEX_B9_PCREL_X
Definition: glibc_elf.h:4007
#define R_HEX_16
Definition: glibc_elf.h:3993
#define RZ_PPC_NONE
Definition: glibc_elf.h:2320
#define R_HEX_B15_PCREL
Definition: glibc_elf.h:3988
#define R_HEX_12_X
Definition: glibc_elf.h:4010
#define RZ_RISCV_JUMP_SLOT
Definition: glibc_elf.h:3737
#define R_HEX_BITMASK_WORD32_B7
Definition: glibc_elf.h:4092
#define SHT_ARM_EXIDX
Definition: glibc_elf.h:2648
#define RZ_AARCH64_RELATIVE
Definition: glibc_elf.h:2785
#define RZ_PPC_COPY
Definition: glibc_elf.h:2339
#define RZ_ARM_THM_MOVW_PREL_NC
Definition: glibc_elf.h:2851
#define RZ_AARCH64_ABS32
Definition: glibc_elf.h:2670
#define RZ_ARM_ABS16
Definition: glibc_elf.h:2806
#define RZ_PPC_REL14
Definition: glibc_elf.h:2331
#define R_HEX_PLT_B22_PCREL
Definition: glibc_elf.h:4022
#define R_HEX_6_X
Definition: glibc_elf.h:4016
#define R_HEX_32_6_X
Definition: glibc_elf.h:4003
#define RZ_386_GLOB_DAT
Definition: glibc_elf.h:1411
#define RZ_X86_64_NONE
Definition: glibc_elf.h:3282
#define RZ_ARM_LDRS_PC_G0
Definition: glibc_elf.h:2866
#define R_HEX_32
Definition: glibc_elf.h:3992
#define RZ_X86_64_PC64
Definition: glibc_elf.h:3306
#define RZ_ARM_MOVW_PREL_NC
Definition: glibc_elf.h:2847
#define R_HEX_LO16
Definition: glibc_elf.h:3990
#define R_HEX_B9_PCREL
Definition: glibc_elf.h:4001
#define R_HEX_10_X
Definition: glibc_elf.h:4012
#define RZ_ARM_ALU_PC_G1
Definition: glibc_elf.h:2862
#define R_HEX_JMP_SLOT
Definition: glibc_elf.h:4020
#define RZ_ARM_LDR_PC_G2
Definition: glibc_elf.h:2865
#define RZ_PPC64_REL24
Definition: glibc_elf.h:2449
#define RZ_X86_64_RELATIVE
Definition: glibc_elf.h:3290
#define RZ_386_16
Definition: glibc_elf.h:1423
#define RZ_X86_64_PLT32
Definition: glibc_elf.h:3286
#define RZ_ARM_JUMP_SLOT
Definition: glibc_elf.h:2824
#define R_HEX_GOTREL_32
Definition: glibc_elf.h:4025
#define RZ_386_NONE
Definition: glibc_elf.h:1405
#define RZ_X86_64_JUMP_SLOT
Definition: glibc_elf.h:3289
#define RZ_ARM_CALL
Definition: glibc_elf.h:2830
#define RZ_386_PC32
Definition: glibc_elf.h:1407
#define R_HEX_8
Definition: glibc_elf.h:3994
#define RZ_ARM_GLOB_DAT
Definition: glibc_elf.h:2823
#define R_HEX_GD_PLT_B22_PCREL
Definition: glibc_elf.h:4035
#define R_HEX_LD_PLT_B22_PCREL
Definition: glibc_elf.h:4072
#define RZ_ARM_ALU_PC_G1_NC
Definition: glibc_elf.h:2861
#define SELFMAG
Definition: glibc_elf.h:122
#define RZ_ARM_LDR_PC_G1
Definition: glibc_elf.h:2864
#define RZ_PPC_REL24
Definition: glibc_elf.h:2330
#define RZ_ARM_LDRS_PC_G1
Definition: glibc_elf.h:2867
#define RZ_X86_64_COPY
Definition: glibc_elf.h:3287
#define R_HEX_GOTREL_16_X
Definition: glibc_elf.h:4053
#define RZ_RISCV_RELATIVE
Definition: glibc_elf.h:3735
#define RZ_PPC_RELATIVE
Definition: glibc_elf.h:2342
#define RZ_X86_64_64
Definition: glibc_elf.h:3283
#define R_HEX_GLOB_DAT
Definition: glibc_elf.h:4019
#define RZ_386_IRELATIVE
Definition: glibc_elf.h:1445
#define R_HEX_HL16
Definition: glibc_elf.h:3999
#define R_HEX_B7_PCREL_X
Definition: glibc_elf.h:4008
#define RZ_PPC_JMP_SLOT
Definition: glibc_elf.h:2341
#define R_HEX_6_PCREL_X
Definition: glibc_elf.h:4051
#define RZ_PPC_ADDR16
Definition: glibc_elf.h:2323
#define R_HEX_GD_PLT_B32_PCREL_X
Definition: glibc_elf.h:4082
#define RZ_PPC64_REL16_LO
Definition: glibc_elf.h:2565
#define RZ_AARCH64_JUMP_SLOT
Definition: glibc_elf.h:2784
#define R_HEX_B13_PCREL_X
Definition: glibc_elf.h:4006
#define R_HEX_16_X
Definition: glibc_elf.h:4009
#define R_HEX_GOTREL_32_6_X
Definition: glibc_elf.h:4052
#define R_HEX_B13_PCREL
Definition: glibc_elf.h:4000
#define RZ_PPC_REL32
Definition: glibc_elf.h:2346
#define RZ_PPC_GLOB_DAT
Definition: glibc_elf.h:2340
#define RZ_PPC_PLT32
Definition: glibc_elf.h:2347
#define RZ_ARM_SBREL32
Definition: glibc_elf.h:2810
#define R_HEX_GOTREL_LO16
Definition: glibc_elf.h:4023
#define R_HEX_B22_PCREL
Definition: glibc_elf.h:3987
#define R_HEX_HI16
Definition: glibc_elf.h:3991
#define R_HEX_B7_PCREL
Definition: glibc_elf.h:3989
#define R_HEX_BITMASK_WORD32_LO
Definition: glibc_elf.h:4090
#define RZ_PPC64_REL14
Definition: glibc_elf.h:2450
#define R_HEX_LD_PLT_B32_PCREL_X
Definition: glibc_elf.h:4084
#define RZ_X86_64_IRELATIVE
Definition: glibc_elf.h:3319
#define RZ_X86_64_GOT32
Definition: glibc_elf.h:3285
#define RZ_386_32
Definition: glibc_elf.h:1406
#define RZ_ARM_PREL31
Definition: glibc_elf.h:2844
#define RZ_AARCH64_ABS16
Definition: glibc_elf.h:2671
#define R_HEX_B32_PCREL_X
Definition: glibc_elf.h:4002
#define RZ_ARM_LDC_PC_G0
Definition: glibc_elf.h:2869
#define RZ_PPC64_ADDR24
Definition: glibc_elf.h:2441
#define RZ_AARCH64_NONE
Definition: glibc_elf.h:2654
#define R_HEX_B15_PCREL_X
Definition: glibc_elf.h:4005
#define RZ_ARM_NONE
Definition: glibc_elf.h:2801
#define RZ_ARM_ABS32_NOI
Definition: glibc_elf.h:2857
#define RZ_X86_64_GOTPCREL
Definition: glibc_elf.h:3291
#define R_HEX_32_PCREL
Definition: glibc_elf.h:4017
#define RZ_PPC64_REL32
Definition: glibc_elf.h:2465
#define RZ_ARM_ALU_PC_G0_NC
Definition: glibc_elf.h:2859
#define RZ_ARM_LDC_PC_G1
Definition: glibc_elf.h:2870
#define RZ_ARM_ABS8
Definition: glibc_elf.h:2809
#define RZ_386_PC8
Definition: glibc_elf.h:1426
#define RZ_ARM_ALU_PC_G0
Definition: glibc_elf.h:2860
#define RZ_ARM_REL32_NOI
Definition: glibc_elf.h:2858
#define RZ_RISCV_NONE
Definition: glibc_elf.h:3732
#define RZ_ARM_GOTPC
Definition: glibc_elf.h:2827
#define R_HEX_DTPREL_11_X
Definition: glibc_elf.h:4060
#define RZ_386_PC16
Definition: glibc_elf.h:1424
#define R_HEX_GOTREL_HI16
Definition: glibc_elf.h:4024
#define RZ_X86_64_32
Definition: glibc_elf.h:3292
#define RZ_X86_64_8
Definition: glibc_elf.h:3296
#define RZ_ARM_MOVT_PREL
Definition: glibc_elf.h:2848
#define R_HEX_BITMASK_WORD32_B15
Definition: glibc_elf.h:4095
#define RZ_386_JMP_SLOT
Definition: glibc_elf.h:1412
#define RZ_X86_64_16
Definition: glibc_elf.h:3294
#define R_HEX_BITMASK_WORD32_B13
Definition: glibc_elf.h:4094
#define R_HEX_BITMASK_WORD32_B22
Definition: glibc_elf.h:4096
#define R_HEX_8_X
Definition: glibc_elf.h:4014
#define RZ_X86_64_PC8
Definition: glibc_elf.h:3297
#define RZ_ARM_LDC_PC_G2
Definition: glibc_elf.h:2871
#define R_HEX_GD_PLT_B22_PCREL_X
Definition: glibc_elf.h:4081
#define R_HEX_DTPREL_32_6_X
Definition: glibc_elf.h:4058
#define PT_MIPS_ABIFLAGS
Definition: glibc_elf.h:1838
#define R_HEX_BITMASK_WORD16
Definition: glibc_elf.h:4088
#define RZ_386_RELATIVE
Definition: glibc_elf.h:1413
#define NT_FILE
Definition: glibc_elf.h:752
#define R_HEX_LD_PLT_B22_PCREL_X
Definition: glibc_elf.h:4083
#define RZ_386_8
Definition: glibc_elf.h:1425
#define R_HEX_GOTREL_11_X
Definition: glibc_elf.h:4054
#define R_HEX_BITMASK_WORD32_B9
Definition: glibc_elf.h:4093
#define RZ_X86_64_32S
Definition: glibc_elf.h:3293
#define R_HEX_RELATIVE
Definition: glibc_elf.h:4021
#define ELFMAG
Definition: glibc_elf.h:121
#define R_HEX_BITMASK_WORD32_R6
Definition: glibc_elf.h:4099
#define R_HEX_BITMASK_WORD8
Definition: glibc_elf.h:4087
#define R_HEX_BITMASK_WORD32_HL
Definition: glibc_elf.h:4091
#define RZ_386_COPY
Definition: glibc_elf.h:1410
#define RZ_ARM_GOTOFF
Definition: glibc_elf.h:2826
#define RZ_ARM_ABS32
Definition: glibc_elf.h:2803
#define RZ_AARCH64_GLOB_DAT
Definition: glibc_elf.h:2783
#define RZ_PPC_ADDR32
Definition: glibc_elf.h:2321
#define RZ_386_GOTPC
Definition: glibc_elf.h:1415
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void uLong size
Definition: ioapi.h:138
voidpf uLong offset
Definition: ioapi.h:144
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
#define DT_INIT_ARRAYSZ
Definition: common.h:564
#define PF_X
Definition: common.h:322
#define EM_RISCV
Definition: common.h:206
#define DT_PREINIT_ARRAYSZ
Definition: common.h:570
#define PT_DYNAMIC
Definition: common.h:304
#define EM_X86_64
Definition: common.h:151
#define EM_QDSP6
Definition: common.h:192
#define ET_REL
Definition: common.h:89
#define EM_MIPS
Definition: common.h:110
#define DT_FINI_ARRAY
Definition: common.h:563
#define EM_PPC64
Definition: common.h:120
#define ET_DYN
Definition: common.h:91
#define PT_PHDR
Definition: common.h:308
#define EI_CLASS
Definition: common.h:51
#define PT_NOTE
Definition: common.h:306
#define EM_386
Definition: common.h:105
#define EV_CURRENT
Definition: common.h:298
#define SHT_NOBITS
Definition: common.h:339
#define PT_LOAD
Definition: common.h:303
#define NT_PRSTATUS
Definition: common.h:393
#define DT_REL
Definition: common.h:554
#define ET_EXEC
Definition: common.h:90
#define PT_TLS
Definition: common.h:309
#define ELFCLASS64
Definition: common.h:54
#define ELFCLASSNONE
Definition: common.h:52
#define PT_GNU_RELRO
Definition: common.h:318
#define PT_GNU_EH_FRAME
Definition: common.h:315
#define PT_INTERP
Definition: common.h:305
#define EM_PPC
Definition: common.h:119
#define DT_INIT_ARRAY
Definition: common.h:562
#define EM_ARM
Definition: common.h:129
#define PF_R
Definition: common.h:324
#define DT_FINI_ARRAYSZ
Definition: common.h:565
#define PT_GNU_STACK
Definition: common.h:317
#define DT_PREINIT_ARRAY
Definition: common.h:569
#define PT_MIPS_REGINFO
Definition: mips.h:520
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
RZ_API RZ_BORROW RzListIter * rz_list_push(RZ_NONNULL RzList *list, void *item)
Alias for rz_list_append.
Definition: list.c:60
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
RZ_API ut64 MACH0_() reloc_targets_vfile_size(struct MACH0_(obj_t) *obj)
size of the artificial reloc target vfile
Definition: mach0_relocs.c:547
RZ_API void MACH0_() patch_relocs(RzBinFile *bf, struct MACH0_(obj_t) *obj)
Patching of external relocs in a sparse overlay buffer.
Definition: mach0_relocs.c:614
static ut64 reloc_target_size(struct MACH0_(obj_t) *obj)
Definition: mach0_relocs.c:538
int n
Definition: mipsasm.c:19
int type
Definition: mipsasm.c:17
int off
Definition: pal.c:13
static int is_arm(RzBinPEObj *bin)
Definition: pe_info.c:12
RZ_API ut64 rz_bin_reloc_target_builder_get_target(RzBinRelocTargetBuilder *builder, ut64 sym)
obtain the address of the target for a given symbol
Definition: relocs_patch.c:69
RZ_API void rz_bin_reloc_target_builder_free(RzBinRelocTargetBuilder *builder)
Definition: relocs_patch.c:51
RZ_API void rz_bin_relocs_patch_maps(RZ_NONNULL RzList *maps, RZ_NULLABLE RzBuffer *buf_patched, ut64 buf_patched_offset, ut64 target_vfile_base, ut64 target_vfile_size, RZ_NONNULL const char *vfile_name_patched, RZ_NONNULL const char *vfile_name_reloc_targets)
Change file-mapped maps to the patched vfile if covered by the buffer and add the reloc target map.
Definition: relocs_patch.c:86
RZ_API RzBinRelocTargetBuilder * rz_bin_reloc_target_builder_new(ut64 target_size, ut64 target_base)
Definition: relocs_patch.c:35
#define ADD
Definition: rsp_idec.c:200
#define rz_warn_if_reached()
Definition: rz_assert.h:29
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
#define RZ_BIN_DBG_STATIC
Definition: rz_bin.h:28
#define RZ_BIN_DBG_RELOCS
Definition: rz_bin.h:31
#define RZ_BIN_DBG_STRIPPED
Definition: rz_bin.h:27
#define RZ_BIN_ENTRY_TYPE_PREINIT
Definition: rz_bin.h:38
#define RZ_BIN_ENTRY_TYPE_FINI
Definition: rz_bin.h:36
@ RZ_BIN_TYPE_DEFAULT
Definition: rz_bin.h:181
@ RZ_BIN_TYPE_CORE
Definition: rz_bin.h:182
RzBinSpecialSymbol
Definition: rz_bin.h:136
@ RZ_BIN_SPECIAL_SYMBOL_FINI
Definition: rz_bin.h:140
@ RZ_BIN_SPECIAL_SYMBOL_ENTRY
Definition: rz_bin.h:137
@ RZ_BIN_SPECIAL_SYMBOL_INIT
Definition: rz_bin.h:138
@ RZ_BIN_SPECIAL_SYMBOL_MAIN
Definition: rz_bin.h:139
#define RZ_BIN_DBG_SYMS
Definition: rz_bin.h:30
#define RZ_BIN_ENTRY_TYPE_INIT
Definition: rz_bin.h:35
#define RZ_BIN_DBG_LINENUMS
Definition: rz_bin.h:29
RZ_API void rz_buf_sparse_set_write_mode(RzBuffer *b, RzBufferSparseWriteMode mode)
Only for sparse RzBuffers.
Definition: buf_sparse.c:325
RZ_API bool rz_buf_append_bytes(RZ_NONNULL RzBuffer *b, RZ_NONNULL const ut8 *buf, ut64 len)
Append an array of bytes to the buffer.
Definition: buf.c:732
RZ_API bool rz_buf_append_nbytes(RZ_NONNULL RzBuffer *b, ut64 len)
Extend the size of the buffer.
Definition: buf.c:748
RZ_API bool rz_buf_append_ut32(RZ_NONNULL RzBuffer *b, ut32 n)
Add a ut32 number at the end of the buffer.
Definition: buf.c:776
RZ_API bool rz_buf_append_ut64(RZ_NONNULL RzBuffer *b, ut64 n)
Add a ut64 number at the end of the buffer.
Definition: buf.c:790
RZ_API st64 rz_buf_write_at(RZ_NONNULL RzBuffer *b, ut64 addr, RZ_NONNULL const ut8 *buf, ut64 len)
Write len bytes of the buffer at the specified address.
Definition: buf.c:1197
RZ_API st64 rz_buf_read_at(RZ_NONNULL RzBuffer *b, ut64 addr, RZ_NONNULL RZ_OUT ut8 *buf, ut64 len)
Read len bytes of the buffer at the specified address.
Definition: buf.c:1136
@ RZ_BUF_SPARSE_WRITE_MODE_SPARSE
all writes are performed in the sparse overlay
Definition: rz_buf.h:60
@ RZ_BUF_SPARSE_WRITE_MODE_THROUGH
all writes are performed in the underlying base buffer
Definition: rz_buf.h:61
RZ_API bool rz_buf_append_ut16(RZ_NONNULL RzBuffer *b, ut16 n)
Add a ut16 number at the end of the buffer.
Definition: buf.c:762
RZ_API void rz_buf_free(RzBuffer *b)
Free all internal data hold by the buffer and the buffer.
Definition: buf.c:1253
RZ_API RZ_OWN RzBuffer * rz_buf_new_empty(ut64 len)
Creates a new empty buffer with a predefined size;.
Definition: buf.c:285
RZ_API RZ_OWN RzBuffer * rz_buf_new_with_bytes(RZ_NULLABLE RZ_BORROW const ut8 *bytes, ut64 len)
Creates a new buffer with a bytes array.
Definition: buf.c:465
RZ_API RZ_OWN RzBuffer * rz_buf_new_sparse_overlay(RzBuffer *b, RzBufferSparseWriteMode write_mode)
Creates a sparse buffer from a already populated buffer.
Definition: buf.c:426
static void rz_write_le32(void *dest, ut32 val)
Definition: rz_endian.h:256
static void rz_write_le16(void *dest, ut16 val)
Definition: rz_endian.h:222
static ut32 rz_read_le32(const void *src)
Definition: rz_endian.h:239
static ut32 rz_read_ble32(const void *src, bool big_endian)
Definition: rz_endian.h:497
static void rz_write_ble32(void *dest, ut32 val, bool big_endian)
Definition: rz_endian.h:540
static void rz_write_ble16(void *dest, ut16 val, bool big_endian)
Definition: rz_endian.h:532
static void rz_write_le64(void *dest, ut64 val)
Definition: rz_endian.h:277
static ut32 rz_read_be32(const void *src)
Definition: rz_endian.h:87
RZ_API char * rz_hex_bin2strdup(const ut8 *in, int len)
Definition: hex.c:415
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
#define RZ_LOG_WARN(fmtstr,...)
Definition: rz_log.h:56
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API char * rz_str_new(const char *str)
Definition: str.c:865
RZ_API bool rz_str_startswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string starts with a specifc sequence of characters (case sensitive)
Definition: str.c:3286
RZ_API bool rz_str_endswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string ends with a specifc sequence of characters (case sensitive)
Definition: str.c:3329
#define PFMT64d
Definition: rz_types.h:394
#define RZ_PERM_R
Definition: rz_types.h:93
#define RZ_BIT_MASK32(x, y)
Definition: rz_types.h:310
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_PERM_RW
Definition: rz_types.h:96
#define RZ_UNUSED
Definition: rz_types.h:73
#define RZ_PERM_W
Definition: rz_types.h:94
#define RZ_PERM_X
Definition: rz_types.h:95
#define RZ_INOUT
Definition: rz_types.h:52
#define RZ_PERM_RWX
Definition: rz_types.h:98
#define RZ_ARRAY_SIZE(x)
Definition: rz_types.h:300
#define PFMT64x
Definition: rz_types.h:393
#define st64
Definition: rz_types_base.h:10
#define UT64_MAX
Definition: rz_types_base.h:86
#define rz_vector_foreach(vec, it)
Definition: rz_vector.h:169
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
Definition: malloc.c:26
Definition: inftree9.h:24
Definition: z80asm.h:102
ut64 vaddr
Definition: rz_bin.h:186
ut64 paddr
Definition: rz_bin.h:187
const char * arch
Definition: rz_bin.h:414
Parsed PT_NOTE of type NT_PRSTATUS.
Definition: elf.h:168
st64 addend
exact addend value taken from the ELF, meaning depends on type
Definition: elf.h:147
ut64 target_vaddr
after patching, the target that this reloc points to
Definition: elf.h:151
ut64 vaddr
source vaddr of the reloc, calculated from offset
Definition: elf.h:150
ut64 paddr
absolute paddr in the file, calculated from offset, or UT64_MAX if no such addr exists
Definition: elf.h:149
RZ_OWN char * name
Definition: elf.h:140
const char * bind
Definition: elf.h:138
const char * type
Definition: elf.h:139
bool patch_relocs
ask the bin plugin to fill relocs with valid contents for analysis
Definition: rz_bin.h:250
ut64 baseaddr
where the linker maps the binary in memory
Definition: rz_bin.h:248
XX curplugin == o->plugin.
Definition: rz_bin.h:298
RzBinObject * o
Definition: rz_bin.h:305
struct rz_bin_t * rbin
Definition: rz_bin.h:316
char * file
Definition: rz_bin.h:299
RzBuffer * buf
Definition: rz_bin.h:303
const char * type
Definition: rz_bin.h:704
const char * bind
Definition: rz_bin.h:703
ut32 ordinal
Definition: rz_bin.h:707
char * name
Definition: rz_bin.h:701
int has_va
Definition: rz_bin.h:228
char * type
Definition: rz_bin.h:211
char * intrp
Definition: rz_bin.h:243
int has_canary
Definition: rz_bin.h:230
char * os
Definition: rz_bin.h:219
char * head_flag
Definition: rz_bin.h:217
char * subsystem
Definition: rz_bin.h:220
int has_pi
Definition: rz_bin.h:229
int has_nx
Definition: rz_bin.h:234
char * machine
Definition: rz_bin.h:216
const char * lang
Definition: rz_bin.h:224
char * bclass
Definition: rz_bin.h:212
char * file
Definition: rz_bin.h:210
ut64 dbg_info
Definition: rz_bin.h:240
int has_retguard
Definition: rz_bin.h:231
char * features
Definition: rz_bin.h:218
char * rpath
Definition: rz_bin.h:221
char * cpu
Definition: rz_bin.h:215
char * rclass
Definition: rz_bin.h:213
char * arch
Definition: rz_bin.h:214
char * compiler
Definition: rz_bin.h:244
int has_sanitizers
Definition: rz_bin.h:232
int big_endian
Definition: rz_bin.h:235
Description of a single memory mapping into virtual memory from a binary.
Definition: rz_bin.h:602
RzBinObjectLoadOptions opts
Definition: rz_bin.h:260
void * bin_obj
Definition: rz_bin.h:293
RzList * sections
Definition: rz_bin.h:267
const char * bind
Definition: rz_bin.h:681
const char * type
Definition: rz_bin.h:682
char * name
Definition: rz_bin.h:675
ut32 ordinal
Definition: rz_bin.h:692
const char * forwarder
Definition: rz_bin.h:680
PrintfCallback cb_printf
Definition: rz_bin.h:345
RZ_NONNULL RzBuffer * buf
Definition: rz_bin.h:597
bool buf_owned
whether buf is owned and freed by this RzBinVirtualFile
Definition: rz_bin.h:598
RZ_OWN RZ_NONNULL char * name
Definition: rz_bin.h:596
Definition: sdb.h:63
uint32_t offset
uint32_t flags
uint32_t size
int pos
Definition: main.c:11
#define MB
Definition: unum.c:92
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int addr
Definition: z80asm.c:58
#define L
Definition: zip_err_str.c:7
#define G
Definition: zip_err_str.c:13
#define S
Definition: zip_err_str.c:9