Rizin
unix-like reverse engineering framework and cli tools
platform_profile.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2021 RizinOrg <info@rizin.re>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_platform.h>
5 #include <string.h>
6 
14  if (!p) {
15  return;
16  }
17  ht_up_free(p->registers_mmio);
18  ht_up_free(p->registers_extended);
19  free(p);
20 }
21 
22 static void free_mmio_kv(HtUPKv *kv) {
23  free(kv->value);
24 }
25 
31  if (!profile) {
32  return NULL;
33  }
34  profile->registers_mmio = ht_up_new((HtUPDupValue)strdup, free_mmio_kv, (HtUPCalcSizeV)strlen);
35  if (!profile->registers_mmio) {
36  free(profile);
37  return NULL;
38  }
39  profile->registers_extended = ht_up_new((HtUPDupValue)strdup, free_mmio_kv, (HtUPCalcSizeV)strlen);
40  if (!profile->registers_extended) {
41  ht_up_free(profile->registers_mmio);
42  free(profile);
43  return NULL;
44  }
45  return profile;
46 }
47 
53  if (!profile) {
54  return NULL;
55  }
56  profile->profile = rz_platform_profile_new();
57  if (!profile->profile) {
58  free(profile);
59  return NULL;
60  }
61  return profile;
62 }
63 
70  if (!t) {
71  return;
72  }
74  free(t->cpu);
75  free(t->arch);
76  free(t);
77 }
78 
83  rz_return_val_if_fail(profile, NULL);
84 
85  return ht_up_find(profile->registers_mmio, (ut64)address, NULL);
86 }
87 
92  rz_return_val_if_fail(profile, NULL);
93 
94  return ht_up_find(profile->registers_extended, (ut64)address, NULL);
95 }
96 
97 static inline bool cpu_reload_needed(RzPlatformTarget *c, const char *cpu, const char *arch) {
98  if (!c->arch || strcmp(c->arch, arch)) {
99  return true;
100  }
101  return !c->cpu || strcmp(c->cpu, cpu);
102 }
103 
105  rz_return_val_if_fail(t && sdb, false);
106  SdbKv *kv;
107  SdbListIter *iter;
109  if (!c) {
110  return false;
111  }
112  SdbList *l = sdb_foreach_list(sdb, false);
113  ls_foreach (l, iter, kv) {
114  if (!strcmp(sdbkv_key(kv), "PC")) {
115  c->pc = rz_num_math(NULL, sdbkv_value(kv));
116  } else if (!strcmp(sdbkv_key(kv), "EEPROM_SIZE")) {
117  c->eeprom_size = rz_num_math(NULL, sdbkv_value(kv));
118  } else if (!strcmp(sdbkv_key(kv), "IO_SIZE")) {
119  c->io_size = rz_num_math(NULL, sdbkv_value(kv));
120  } else if (!strcmp(sdbkv_key(kv), "SRAM_START")) {
121  c->sram_start = rz_num_math(NULL, sdbkv_value(kv));
122  } else if (!strcmp(sdbkv_key(kv), "SRAM_SIZE")) {
123  c->sram_size = rz_num_math(NULL, sdbkv_value(kv));
124  } else if (!strcmp(sdbkv_key(kv), "PAGE_SIZE")) {
125  c->page_size = rz_num_math(NULL, sdbkv_value(kv));
126  } else if (!strcmp(sdbkv_key(kv), "ROM_SIZE")) {
127  c->rom_size = rz_num_math(NULL, sdbkv_value(kv));
128  } else if (!strcmp(sdbkv_key(kv), "ROM_ADDRESS")) {
129  c->rom_address = rz_num_math(NULL, sdbkv_value(kv));
130  } else if (!strcmp(sdbkv_key(kv), "RAM_SIZE")) {
131  c->ram_size = rz_num_math(NULL, sdbkv_value(kv));
132  }
133  if (!strcmp(sdbkv_value(kv), "io")) {
134  char *io_name = sdbkv_key(kv);
135  char *argument_key = rz_str_newf("%s.address", io_name);
136  ut64 io_address = sdb_num_get(sdb, argument_key, NULL);
137  free(argument_key);
138  ht_up_insert(c->registers_mmio, io_address, io_name);
139  }
140  if (!strcmp(sdbkv_value(kv), "ext_io")) {
141  char *ext_io_name = sdbkv_key(kv);
142  char *argument_key = rz_str_newf("%s.address", ext_io_name);
143  ut64 ext_io_address = sdb_num_get(sdb, argument_key, NULL);
144  free(argument_key);
145  ht_up_insert(c->registers_extended, ext_io_address, ext_io_name);
146  }
147  }
148  ls_free(l);
150  t->profile = c;
151  return true;
152 }
153 
155  Sdb *db = sdb_new(0, path, 0);
156  bool result = sdb_load_arch_profile(t, db);
157  sdb_close(db);
158  sdb_free(db);
159  return result;
160 }
161 
169  if (!rz_file_exists(path)) {
170  return false;
171  }
173 }
174 
175 static bool is_cpu_valid(const char *cpu_dir, const char *cpu) {
176  RzList *files = rz_sys_dir(cpu_dir);
177  if (!files) {
178  return false;
179  }
180  RzListIter *it;
181  char *filename = NULL;
182  char *arch_cpu = NULL;
183 
184  rz_list_foreach (files, it, filename) {
185  char *cpu_name = NULL;
186  if (!strcmp(filename, "..") || !strcmp(filename, "..")) {
187  continue;
188  }
189  arch_cpu = rz_str_ndup(filename, strlen(filename) - 4);
190  if (!arch_cpu) {
191  continue;
192  }
193  cpu_name = strchr(arch_cpu, '-');
194  if (!cpu_name) {
195  free(arch_cpu);
196  continue;
197  }
198  cpu_name[0] = '\0';
199  if (!strcmp(cpu_name + 1, cpu)) {
201  free(arch_cpu);
202  return true;
203  }
204 
205  free(arch_cpu);
206  }
207 
209  return false;
210 }
211 
221 RZ_API bool rz_platform_profiles_init(RzPlatformTarget *t, const char *cpu, const char *arch, const char *cpus_dir) {
222  if (!cpu_reload_needed(t, cpu, arch)) {
223  return false;
224  }
225  if (!cpus_dir || !arch || !cpu) {
226  return false;
227  }
228  char buf[50];
229  char *path = rz_file_path_join(cpus_dir, rz_strf(buf, "%s-%s.sdb", arch, cpu));
230  if (!path) {
231  return false;
232  }
233  if (!is_cpu_valid(cpus_dir, cpu)) {
234  if (!strcmp(arch, "avr")) {
235  free(path);
236  path = rz_file_path_join(cpus_dir, "avr-ATmega8.sdb");
237  }
238  }
239  free(t->cpu);
240  free(t->arch);
241  t->cpu = strdup(cpu);
242  t->arch = strdup(arch);
244  free(path);
245  return true;
246 }
static ut32 cpu[32]
Definition: analysis_or1k.c:21
#define RZ_API
#define NULL
Definition: cris-opc.c:27
cs_arch arch
Definition: cstool.c:13
static static fork const void static count static fd const char const char static newpath const char static path const char path
Definition: sflib.h:35
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 special files
Definition: file_opts.h:46
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
const char * filename
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
void * p
Definition: libc.cpp:67
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 void ls_free(SdbList *list)
Definition: ls.c:191
#define ls_foreach(list, it, pos)
Definition: ls.h:31
RZ_API ut64 sdb_num_get(Sdb *s, const char *key, ut32 *cas)
Definition: num.c:13
static bool sdb_load_arch_profile_by_path(RZ_NONNULL RzPlatformTarget *t, const char *path)
static void free_mmio_kv(HtUPKv *kv)
static bool is_cpu_valid(const char *cpu_dir, const char *cpu)
RZ_API bool rz_platform_profiles_init(RzPlatformTarget *t, const char *cpu, const char *arch, const char *cpus_dir)
Initializes RzPlatformProfile by loading the path to the SDB file of the CPU profile.
RZ_API void rz_platform_profile_free(RzPlatformProfile *p)
Frees an RzPlatformProfile type.
RZ_API void rz_platform_target_free(RzPlatformTarget *t)
Frees an RzPlatformTarget type.
static bool sdb_load_arch_profile(RzPlatformTarget *t, Sdb *sdb)
static bool cpu_reload_needed(RzPlatformTarget *c, const char *cpu, const char *arch)
RZ_API RZ_BORROW const char * rz_platform_profile_resolve_extended_register(RZ_NONNULL RzPlatformProfile *profile, ut64 address)
Resolves an address and returns the linked extended register.
RZ_API bool rz_platform_load_profile_sdb(RzPlatformTarget *t, const char *path)
Loads the contents of the CPU Profile to the RzPlatformProfile.
RZ_API RZ_BORROW const char * rz_platform_profile_resolve_mmio(RZ_NONNULL RzPlatformProfile *profile, ut64 address)
Resolves an address and returns the linked mmio.
RZ_API RZ_OWN RzPlatformTarget * rz_platform_target_new()
Creates a new RzPlatformTarget type.
RZ_API RZ_OWN RzPlatformProfile * rz_platform_profile_new()
Creates a new RzPlatformProfile type.
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API bool rz_file_exists(const char *str)
Definition: file.c:192
RZ_API RZ_OWN char * rz_file_path_join(RZ_NONNULL const char *s1, RZ_NULLABLE const char *s2)
Concatenate two paths to create a new one with s1+s2 with the correct path separator.
Definition: file.c:1312
RZ_API ut64 rz_num_math(RzNum *num, const char *str)
Definition: unum.c:456
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API char * rz_str_ndup(RZ_NULLABLE const char *ptr, int len)
Create new copy of string ptr limited to size len.
Definition: str.c:1006
#define rz_strf(buf,...)
Convenience macro for local temporary strings.
Definition: rz_str.h:59
RZ_API RzList * rz_sys_dir(const char *path)
Definition: sys.c:216
#define RZ_OWN
Definition: rz_types.h:62
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_NONNULL
Definition: rz_types.h:64
#define RZ_BORROW
Definition: rz_types.h:63
RZ_API Sdb * sdb_new(const char *path, const char *name, int lock)
Definition: sdb.c:47
RZ_API void sdb_close(Sdb *s)
Definition: sdb.c:416
RZ_API bool sdb_free(Sdb *s)
Definition: sdb.c:206
RZ_API SdbList * sdb_foreach_list(Sdb *s, bool sorted)
Definition: sdb.c:630
static char * sdbkv_key(const SdbKv *kv)
Definition: sdbht.h:21
static char * sdbkv_value(const SdbKv *kv)
Definition: sdbht.h:25
#define c(i)
Definition: sha256.c:43
Definition: ls.h:17
Definition: ls.h:22
RzPlatformProfile * profile
Definition: rz_platform.h:34
Definition: sdbht.h:14
Definition: sdb.h:63
ut64(WINAPI *w32_GetEnabledXStateFeatures)()