Rizin
unix-like reverse engineering framework and cli tools
elf_relocs.c File Reference
#include "elf.h"
#include <ht_uu.h>

Go to the source code of this file.

Classes

struct  relocs_segment
 

Functions

static struct relocs_segment relocs_segment_init (ut64 offset, ut64 size, ut64 entry_size, ut64 mode)
 
static void fix_rva_and_offset_relocable_file (ELFOBJ *bin, RzBinElfReloc *reloc, RzBinElfSection *section)
 
static void fix_rva_and_offset_exec_file (ELFOBJ *bin, RzBinElfReloc *reloc)
 
static void fix_rva_and_offset (ELFOBJ *bin, RzBinElfReloc *reloc, RzBinElfSection *section)
 
static ut64 get_size_rel_mode (ut64 mode)
 
static bool read_reloc_entry_aux (ELFOBJ *bin, Elf_(Rela) *reloc, ut64 offset, ut64 mode)
 
static bool read_reloc_entry (ELFOBJ *bin, Elf_(Rela) *reloc, ut64 offset, ut64 mode)
 
static bool get_reloc_entry (ELFOBJ *bin, RzBinElfReloc *reloc, ut64 offset, ut64 mode)
 
static bool has_already_been_processed (ELFOBJ *bin, ut64 offset, HtUU *set)
 
static bool get_relocs_entry (ELFOBJ *bin, RzBinElfSection *section, RzVector *relocs, struct relocs_segment *segment, HtUU *set)
 
static bool get_relocs_entry_from_dt_dynamic_aux (ELFOBJ *bin, RzVector *relocs, ut64 dt_addr, ut64 dt_size, ut64 entry_size, ut64 mode, HtUU *set)
 
static bool get_relocs_entry_from_dt_dynamic (ELFOBJ *bin, RzVector *relocs, HtUU *set)
 
static ut64 get_section_relocation_mode (RzBinElfSection *section)
 
static bool get_relocs_entry_from_sections (ELFOBJ *bin, RzVector *relocs, HtUU *set)
 
RZ_OWN RzVector *Elf_() rz_bin_elf_relocs_new (RZ_NONNULL ELFOBJ *bin)
 
bool Elf_() rz_bin_elf_has_relocs (RZ_NONNULL ELFOBJ *bin)
 
size_t Elf_() rz_bin_elf_get_relocs_count (RZ_NONNULL ELFOBJ *bin)
 
ut64 Elf_() rz_bin_elf_get_num_relocs_dynamic_plt (RZ_NONNULL ELFOBJ *bin)
 

Function Documentation

◆ fix_rva_and_offset()

static void fix_rva_and_offset ( ELFOBJ bin,
RzBinElfReloc reloc,
RzBinElfSection section 
)
static

Definition at line 48 of file elf_relocs.c.

48  {
51  } else {
53  }
54 }
bool Elf_() rz_bin_elf_is_relocatable(RZ_NONNULL ELFOBJ *bin)
Check if the elf binary is relocatable.
Definition: elf_info.c:1662
static void fix_rva_and_offset_exec_file(ELFOBJ *bin, RzBinElfReloc *reloc)
Definition: elf_relocs.c:38
static void fix_rva_and_offset_relocable_file(ELFOBJ *bin, RzBinElfReloc *reloc, RzBinElfSection *section)
Definition: elf_relocs.c:26
#define Elf_(name)
Definition: elf_specs.h:32
Definition: malloc.c:26

References Elf_, fix_rva_and_offset_exec_file(), fix_rva_and_offset_relocable_file(), and rz_bin_elf_is_relocatable().

Referenced by get_relocs_entry().

◆ fix_rva_and_offset_exec_file()

static void fix_rva_and_offset_exec_file ( ELFOBJ bin,
RzBinElfReloc reloc 
)
static

Definition at line 38 of file elf_relocs.c.

38  {
39  reloc->paddr = Elf_(rz_bin_elf_v2p)(bin, reloc->offset);
40 
41  if (reloc->paddr == UT64_MAX) {
42  reloc->paddr = reloc->offset;
43  }
44 
45  reloc->vaddr = reloc->offset;
46 }
ut64 Elf_() rz_bin_elf_v2p(RZ_NONNULL ELFOBJ *bin, ut64 vaddr)
Convert a virtual address to the physical address.
Definition: elf.c:429
#define UT64_MAX
Definition: rz_types_base.h:86
ut64 offset
exact offset value taken from the ELF, meaning depends on the binary type
Definition: elf.h:148
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

References Elf_, rz_bin_elf_reloc_t::offset, rz_bin_elf_reloc_t::paddr, rz_bin_elf_v2p(), UT64_MAX, and rz_bin_elf_reloc_t::vaddr.

Referenced by fix_rva_and_offset().

◆ fix_rva_and_offset_relocable_file()

static void fix_rva_and_offset_relocable_file ( ELFOBJ bin,
RzBinElfReloc reloc,
RzBinElfSection section 
)
static

Definition at line 26 of file elf_relocs.c.

26  {
27  RzBinElfSection *sub_section = Elf_(rz_bin_elf_get_section)(bin, section->info);
28 
29  if (!sub_section) {
30  reloc->paddr = UT64_MAX;
31  reloc->vaddr = reloc->offset;
32  } else {
33  reloc->paddr = sub_section->offset + reloc->offset;
34  reloc->vaddr = Elf_(rz_bin_elf_p2v)(bin, reloc->paddr);
35  }
36 }
ut64 Elf_() rz_bin_elf_p2v(RZ_NONNULL ELFOBJ *bin, ut64 paddr)
Convert a physical address to the virtual address.
Definition: elf.c:400
RZ_BORROW RzBinElfSection *Elf_() rz_bin_elf_get_section(RZ_NONNULL ELFOBJ *bin, Elf_(Half) index)
Definition: elf_sections.c:264

References Elf_, rz_bin_elf_section_t::offset, rz_bin_elf_reloc_t::offset, rz_bin_elf_reloc_t::paddr, rz_bin_elf_get_section(), rz_bin_elf_p2v(), UT64_MAX, and rz_bin_elf_reloc_t::vaddr.

Referenced by fix_rva_and_offset().

◆ get_reloc_entry()

static bool get_reloc_entry ( ELFOBJ bin,
RzBinElfReloc reloc,
ut64  offset,
ut64  mode 
)
static

Definition at line 83 of file elf_relocs.c.

83  {
84  Elf_(Rela) tmp;
85  if (!read_reloc_entry(bin, &tmp, offset, mode)) {
86  return false;
87  }
88 
89  reloc->mode = mode;
90  reloc->offset = tmp.rz_offset;
91  reloc->sym = ELF_R_SYM(tmp.rz_info);
92  reloc->type = ELF_R_TYPE(tmp.rz_info);
93  reloc->addend = tmp.rz_addend;
94 
95  return true;
96 }
static bool read_reloc_entry(ELFOBJ *bin, Elf_(Rela) *reloc, ut64 offset, ut64 mode)
Definition: elf_relocs.c:74
#define ELF_R_SYM
Definition: elf_specs.h:37
#define ELF_R_TYPE
Definition: elf_specs.h:38
voidpf uLong offset
Definition: ioapi.h:144
const char int mode
Definition: ioapi.h:137
st64 addend
exact addend value taken from the ELF, meaning depends on type
Definition: elf.h:147

References rz_bin_elf_reloc_t::addend, Elf_, ELF_R_SYM, ELF_R_TYPE, rz_bin_elf_reloc_t::mode, rz_bin_elf_reloc_t::offset, read_reloc_entry(), rz_bin_elf_reloc_t::sym, autogen_x86imm::tmp, and rz_bin_elf_reloc_t::type.

Referenced by get_relocs_entry().

◆ get_relocs_entry()

static bool get_relocs_entry ( ELFOBJ bin,
RzBinElfSection section,
RzVector relocs,
struct relocs_segment segment,
HtUU *  set 
)
static

Definition at line 105 of file elf_relocs.c.

105  {
106  for (ut64 entry_offset = 0; entry_offset < segment->size; entry_offset += segment->entry_size) {
107  if (has_already_been_processed(bin, segment->offset + entry_offset, set)) {
108  continue;
109  }
110 
111  if (!ht_uu_insert(set, segment->offset + entry_offset, segment->offset + entry_offset)) {
112  return false;
113  }
114 
115  RzBinElfReloc tmp = { 0 };
116  if (!get_reloc_entry(bin, &tmp, segment->offset + entry_offset, segment->mode)) {
117  return false;
118  }
119 
121 
122  if (!rz_vector_push(relocs, &tmp)) {
123  return false;
124  }
125  }
126 
127  return true;
128 }
RzList * relocs(RzBinFile *bf)
Definition: bin_ne.c:114
static bool get_reloc_entry(ELFOBJ *bin, RzBinElfReloc *reloc, ut64 offset, ut64 mode)
Definition: elf_relocs.c:83
static bool has_already_been_processed(ELFOBJ *bin, ut64 offset, HtUU *set)
Definition: elf_relocs.c:98
static void fix_rva_and_offset(ELFOBJ *bin, RzBinElfReloc *reloc, RzBinElfSection *section)
Definition: elf_relocs.c:48
RZ_API void * rz_vector_push(RzVector *vec, void *x)
Definition: vector.c:197
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References relocs_segment::entry_size, fix_rva_and_offset(), get_reloc_entry(), has_already_been_processed(), relocs_segment::mode, relocs_segment::offset, relocs(), rz_vector_push(), relocs_segment::size, autogen_x86imm::tmp, and ut64().

Referenced by get_relocs_entry_from_dt_dynamic_aux(), and get_relocs_entry_from_sections().

◆ get_relocs_entry_from_dt_dynamic()

static bool get_relocs_entry_from_dt_dynamic ( ELFOBJ bin,
RzVector relocs,
HtUU *  set 
)
static

Definition at line 148 of file elf_relocs.c.

148  {
149  ut64 entry_size;
150 
152  return true;
153  }
154 
155  ut64 dt_pltrel;
156  if (Elf_(rz_bin_elf_get_dt_info)(bin, DT_PLTREL, &dt_pltrel)) {
157  entry_size = get_size_rel_mode(dt_pltrel);
158  if (!get_relocs_entry_from_dt_dynamic_aux(bin, relocs, DT_JMPREL, DT_PLTRELSZ, entry_size, dt_pltrel, set)) {
159  return false;
160  }
161  }
162 
163  if (Elf_(rz_bin_elf_get_dt_info)(bin, DT_RELENT, &entry_size)) {
165  return false;
166  }
167  }
168 
169  if (Elf_(rz_bin_elf_get_dt_info)(bin, DT_RELAENT, &entry_size)) {
171  return false;
172  }
173  }
174 
175  return true;
176 }
bool Elf_() rz_bin_elf_has_dt_dynamic(RZ_NONNULL ELFOBJ *bin)
Definition: elf_dynamic.c:130
bool Elf_() rz_bin_elf_get_dt_info(RZ_NONNULL ELFOBJ *bin, ut64 key, RZ_OUT ut64 *info)
Definition: elf_dynamic.c:120
static ut64 get_size_rel_mode(ut64 mode)
Definition: elf_relocs.c:56
static bool get_relocs_entry_from_dt_dynamic_aux(ELFOBJ *bin, RzVector *relocs, ut64 dt_addr, ut64 dt_size, ut64 entry_size, ut64 mode, HtUU *set)
Definition: elf_relocs.c:130
#define DT_RELSZ
Definition: common.h:555
#define DT_RELASZ
Definition: common.h:545
#define DT_RELAENT
Definition: common.h:546
#define DT_PLTREL
Definition: common.h:557
#define DT_REL
Definition: common.h:554
#define DT_PLTRELSZ
Definition: common.h:539
#define DT_JMPREL
Definition: common.h:560
#define DT_RELENT
Definition: common.h:556
#define DT_RELA
Definition: common.h:544

References DT_JMPREL, DT_PLTREL, DT_PLTRELSZ, DT_REL, DT_RELA, DT_RELAENT, DT_RELASZ, DT_RELENT, DT_RELSZ, Elf_, relocs_segment::entry_size, get_relocs_entry_from_dt_dynamic_aux(), get_size_rel_mode(), relocs(), rz_bin_elf_get_dt_info(), rz_bin_elf_has_dt_dynamic(), and ut64().

Referenced by rz_bin_elf_relocs_new().

◆ get_relocs_entry_from_dt_dynamic_aux()

static bool get_relocs_entry_from_dt_dynamic_aux ( ELFOBJ bin,
RzVector relocs,
ut64  dt_addr,
ut64  dt_size,
ut64  entry_size,
ut64  mode,
HtUU *  set 
)
static

Definition at line 130 of file elf_relocs.c.

130  {
131  ut64 addr;
132  ut64 size;
133 
134  if (!Elf_(rz_bin_elf_get_dt_info)(bin, dt_addr, &addr) || !Elf_(rz_bin_elf_get_dt_info)(bin, dt_size, &size)) {
135  return true;
136  }
137 
139  if (offset == UT64_MAX) {
140  return false;
141  }
142 
144 
145  return get_relocs_entry(bin, NULL, relocs, &segment, set);
146 }
#define NULL
Definition: cris-opc.c:27
static bool get_relocs_entry(ELFOBJ *bin, RzBinElfSection *section, RzVector *relocs, struct relocs_segment *segment, HtUU *set)
Definition: elf_relocs.c:105
static struct relocs_segment relocs_segment_init(ut64 offset, ut64 size, ut64 entry_size, ut64 mode)
Definition: elf_relocs.c:17
voidpf void uLong size
Definition: ioapi.h:138
static int addr
Definition: z80asm.c:58

References addr, Elf_, relocs_segment::entry_size, get_relocs_entry(), NULL, relocs(), relocs_segment_init(), rz_bin_elf_get_dt_info(), rz_bin_elf_v2p(), ut64(), and UT64_MAX.

Referenced by get_relocs_entry_from_dt_dynamic().

◆ get_relocs_entry_from_sections()

static bool get_relocs_entry_from_sections ( ELFOBJ bin,
RzVector relocs,
HtUU *  set 
)
static

Definition at line 182 of file elf_relocs.c.

182  {
185  if (!section->is_valid || (section->type != SHT_REL && section->type != SHT_RELA)) {
186  continue;
187  }
188 
190  ut64 entry_size = get_size_rel_mode(mode);
191 
193 
194  if (!get_relocs_entry(bin, section, relocs, &segment, set)) {
195  return false;
196  }
197  }
198 
199  return true;
200 }
#define rz_bin_elf_foreach_sections(bin, section)
Definition: elf.h:30
static ut64 get_section_relocation_mode(RzBinElfSection *section)
Definition: elf_relocs.c:178
#define SHT_REL
Definition: common.h:340
#define SHT_RELA
Definition: common.h:335
uint32_t offset
uint32_t size

References relocs_segment::entry_size, get_relocs_entry(), get_section_relocation_mode(), get_size_rel_mode(), section::offset, relocs(), relocs_segment_init(), rz_bin_elf_foreach_sections, SHT_REL, SHT_RELA, section::size, and ut64().

Referenced by rz_bin_elf_relocs_new().

◆ get_section_relocation_mode()

static ut64 get_section_relocation_mode ( RzBinElfSection section)
static

Definition at line 178 of file elf_relocs.c.

178  {
179  return section->type == SHT_REL ? DT_REL : DT_RELA;
180 }

References DT_REL, DT_RELA, and SHT_REL.

Referenced by get_relocs_entry_from_sections().

◆ get_size_rel_mode()

static ut64 get_size_rel_mode ( ut64  mode)
static

Definition at line 56 of file elf_relocs.c.

56  {
57  return mode == DT_REL ? sizeof(Elf_(Rel)) : sizeof(Elf_(Rela));
58 }

References DT_REL, and Elf_.

Referenced by get_relocs_entry_from_dt_dynamic(), get_relocs_entry_from_sections(), and rz_bin_elf_get_num_relocs_dynamic_plt().

◆ has_already_been_processed()

static bool has_already_been_processed ( ELFOBJ bin,
ut64  offset,
HtUU *  set 
)
static

Definition at line 98 of file elf_relocs.c.

98  {
99  bool found;
100  ht_uu_find(set, offset, &found);
101 
102  return found;
103 }
RZ_API const KEY_TYPE bool * found
Definition: ht_inc.h:130

References found.

Referenced by get_relocs_entry().

◆ read_reloc_entry()

static bool read_reloc_entry ( ELFOBJ bin,
Elf_(Rela) *  reloc,
ut64  offset,
ut64  mode 
)
static

Definition at line 74 of file elf_relocs.c.

74  {
75  if (!read_reloc_entry_aux(bin, reloc, offset, mode)) {
76  RZ_LOG_WARN("Failed to read reloc at 0x%" PFMT64x ".\n", offset);
77  return false;
78  }
79 
80  return true;
81 }
static bool read_reloc_entry_aux(ELFOBJ *bin, Elf_(Rela) *reloc, ut64 offset, ut64 mode)
Definition: elf_relocs.c:60
#define RZ_LOG_WARN(fmtstr,...)
Definition: rz_log.h:56
#define PFMT64x
Definition: rz_types.h:393

References PFMT64x, read_reloc_entry_aux(), and RZ_LOG_WARN.

Referenced by get_reloc_entry().

◆ read_reloc_entry_aux()

static bool read_reloc_entry_aux ( ELFOBJ bin,
Elf_(Rela) *  reloc,
ut64  offset,
ut64  mode 
)
static

Definition at line 60 of file elf_relocs.c.

60  {
61  if (!Elf_(rz_bin_elf_read_addr)(bin, &offset, &reloc->rz_offset) ||
62  !Elf_(rz_bin_elf_read_word_xword)(bin, &offset, &reloc->rz_info)) {
63  return false;
64  }
65 
66  if (mode == DT_REL) {
67  reloc->rz_addend = 0;
68  return true;
69  }
70 
71  return Elf_(rz_bin_elf_read_sword_sxword)(bin, &offset, &reloc->rz_addend);
72 }
bool Elf_() rz_bin_elf_read_word_xword(RZ_NONNULL ELFOBJ *bin, RZ_NONNULL RZ_INOUT ut64 *offset, RZ_NONNULL RZ_OUT Elf_(Word) *result)
Definition: elf_misc.c:117
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
bool Elf_() rz_bin_elf_read_sword_sxword(RZ_NONNULL ELFOBJ *bin, RZ_NONNULL RZ_INOUT ut64 *offset, RZ_NONNULL RZ_OUT Elf_(Sword) *result)
Definition: elf_misc.c:131

References DT_REL, Elf_, rz_bin_elf_read_addr(), rz_bin_elf_read_sword_sxword(), and rz_bin_elf_read_word_xword().

Referenced by read_reloc_entry().

◆ relocs_segment_init()

static struct relocs_segment relocs_segment_init ( ut64  offset,
ut64  size,
ut64  entry_size,
ut64  mode 
)
static

Definition at line 1 of file elf_relocs.c.

17  {
18  return (struct relocs_segment){
19  .offset = offset,
20  .size = size,
21  .entry_size = entry_size,
22  .mode = mode,
23  };
24 }

Referenced by get_relocs_entry_from_dt_dynamic_aux(), and get_relocs_entry_from_sections().

◆ rz_bin_elf_get_num_relocs_dynamic_plt()

ut64 Elf_() rz_bin_elf_get_num_relocs_dynamic_plt ( RZ_NONNULL ELFOBJ bin)

Definition at line 255 of file elf_relocs.c.

255  {
257 
258  ut64 dt_pltrel;
259  ut64 size;
260 
262  return 0;
263  }
264 
265  ut64 entry_size = get_size_rel_mode(dt_pltrel);
266  return size / entry_size;
267 }
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108

References DT_PLTREL, DT_PLTRELSZ, Elf_, relocs_segment::entry_size, get_size_rel_mode(), rz_bin_elf_get_dt_info(), rz_return_val_if_fail, and ut64().

Referenced by get_import_addr_ppc().

◆ rz_bin_elf_get_relocs_count()

size_t Elf_() rz_bin_elf_get_relocs_count ( RZ_NONNULL ELFOBJ bin)

Definition at line 245 of file elf_relocs.c.

245  {
247 
248  if (!bin->relocs) {
249  return 0;
250  }
251 
252  return rz_vector_len(bin->relocs);
253 }
static size_t rz_vector_len(const RzVector *vec)
Definition: rz_vector.h:82

References rz_return_val_if_fail, and rz_vector_len().

◆ rz_bin_elf_has_relocs()

bool Elf_() rz_bin_elf_has_relocs ( RZ_NONNULL ELFOBJ bin)

Definition at line 239 of file elf_relocs.c.

239  {
240  rz_return_val_if_fail(bin, false);
241 
242  return bin->relocs;
243 }

References rz_return_val_if_fail.

Referenced by get_import_addr().

◆ rz_bin_elf_relocs_new()

RZ_OWN RzVector* Elf_() rz_bin_elf_relocs_new ( RZ_NONNULL ELFOBJ bin)

Definition at line 202 of file elf_relocs.c.

202  {
204 
205  HtUU *set = ht_uu_new0();
206  if (!set) {
207  return NULL;
208  }
209 
210  RzVector *result = rz_vector_new(sizeof(RzBinElfReloc), NULL, NULL);
211  if (!result) {
212  ht_uu_free(set);
213  return NULL;
214  }
215 
216  if (!get_relocs_entry_from_dt_dynamic(bin, result, set)) {
217  rz_vector_free(result);
218  ht_uu_free(set);
219  return NULL;
220  }
221 
222  if (!get_relocs_entry_from_sections(bin, result, set)) {
223  rz_vector_free(result);
224  ht_uu_free(set);
225  return NULL;
226  }
227 
228  if (!rz_vector_len(result)) {
229  rz_vector_free(result);
230  ht_uu_free(set);
231  return NULL;
232  }
233 
234  ht_uu_free(set);
235 
236  return result;
237 }
static bool get_relocs_entry_from_sections(ELFOBJ *bin, RzVector *relocs, HtUU *set)
Definition: elf_relocs.c:182
static bool get_relocs_entry_from_dt_dynamic(ELFOBJ *bin, RzVector *relocs, HtUU *set)
Definition: elf_relocs.c:148
RZ_API void rz_vector_free(RzVector *vec)
Definition: vector.c:75
RZ_API RzVector * rz_vector_new(size_t elem_size, RzVectorFree free, void *free_user)
Definition: vector.c:42

References get_relocs_entry_from_dt_dynamic(), get_relocs_entry_from_sections(), NULL, rz_return_val_if_fail, rz_vector_free(), rz_vector_len(), and rz_vector_new().

Referenced by init().