Rizin
unix-like reverse engineering framework and cli tools
arch.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2017 Srimanta Barua <srimanta.barua1@gmail.com>
2 // SPDX-FileCopyrightText: 2018 Alyssa Milburn <noopwafel@gmail.com>
3 // SPDX-FileCopyrightText: 2020 Zi Fan <zifan.tan@gmail.com>
4 // SPDX-License-Identifier: LGPL-3.0-only
5 
6 #include <rz_util.h>
7 #include "arch.h"
8 
9 static ut64 parse_size(char *s, char **end) {
10  if (*s == '.') {
11  return strtoul(s + 1, end, 10);
12  }
13  char *has_dot = strchr(s, '.');
14  if (has_dot) {
15  *has_dot++ = 0;
16  ut64 a = strtoul(s, end, 0) << 3;
17  ut64 b = strtoul(has_dot, end, 0);
18  return a + b;
19  }
20  return strtoul(s, end, 0) << 3;
21 }
22 
23 gdb_reg_t *parse_def(char **tok) {
24  char *end;
26  if (!r) {
27  return NULL;
28  }
29 
30  strcpy(r->name, tok[1]);
31  r->size = parse_size(tok[2], &end);
32  if (*end != '\0' || !r->size) {
33  free(r);
34  return NULL;
35  }
36  if (!strcmp(tok[3], "?")) {
37  free(r);
38  return NULL;
39  } else {
40  r->offset = parse_size(tok[3], &end);
41  }
42  return r;
43 }
44 
45 #define PARSER_MAX_TOKENS 8
46 gdb_reg_t *arch_parse_reg_profile(const char *reg_profile) {
47  char *tok[PARSER_MAX_TOKENS];
48  char tmp[128];
49  int i, j, l;
50  const char *p = reg_profile;
51  RzList *gdb_regs_list = rz_list_newf(free);
53  gdb_reg_t *reg;
54 
55  // Line number
56  l = 0;
57  // For every line
58  do {
59  // Increment line number
60  l++;
61  // Skip comment lines
62  if (*p == '#') {
63  const char *q = p;
64  while (*q != '\n') {
65  q++;
66  }
67  p = q;
68  continue;
69  }
70  j = 0;
71  // For every word
72  while (*p) {
73  // Skip the whitespace
74  while (*p == ' ' || *p == '\t') {
75  p++;
76  }
77  // EOL ?
78  if (*p == '\n') {
79  break;
80  }
81  if (*p == '#') {
82  // Place the rest of the line in the token if a comment is encountered
83  for (i = 0; *p != '\n'; p++) {
84  if (i < sizeof(tmp) - 1) {
85  tmp[i++] = *p;
86  }
87  }
88  } else {
89  // Save all characters up to a space/tab
90  // Use isgraph instead of isprint because the latter considers ' ' printable
91  for (i = 0; isgraph((const unsigned char)*p) && i < sizeof(tmp) - 1;) {
92  tmp[i++] = *p++;
93  }
94  }
95  tmp[i] = '\0';
96  // Limit the number of tokens
97  if (j > PARSER_MAX_TOKENS - 1) {
98  break;
99  }
100  // Save the token
101  tok[j++] = strdup(tmp);
102  }
103  // Empty line, eww
104  if (j) {
105  // Do the actual parsing
106  char *first = tok[0];
107  // Check whether it's defining an alias or a register
108  if (*first != '=') {
109  reg = parse_def(tok);
110  // Warn the user if something went wrong
111  if (!reg) {
112  eprintf("gdb_regs: Parse error @ line %d\n", l);
113  for (i = 0; i < j; i++) {
114  free(tok[i]);
115  }
116  // Clean up
117  rz_list_free(gdb_regs_list);
118  return NULL;
119  }
120  rz_list_append(gdb_regs_list, reg);
121  }
122  // Clean up
123  for (i = 0; i < j; i++) {
124  free(tok[i]);
125  }
126  }
127  } while (*p++);
128 
129  gdb_reg_t *gdb_regs = malloc((rz_list_length(gdb_regs_list) + 1) * sizeof(gdb_reg_t));
130  if (!gdb_regs) {
131  return NULL;
132  }
133  i = 0;
134  rz_list_foreach (gdb_regs_list, iter, reg) {
135  memcpy(gdb_regs + i, reg, sizeof(gdb_reg_t));
136  i++;
137  }
138  memset(gdb_regs + i, 0, sizeof(gdb_reg_t));
139 
140  rz_list_free(gdb_regs_list);
141  return gdb_regs;
142 }
lzma_index ** i
Definition: index.h:629
#define PARSER_MAX_TOKENS
Definition: arch.c:45
static ut64 parse_size(char *s, char **end)
Definition: arch.c:9
gdb_reg_t * arch_parse_reg_profile(const char *reg_profile)
Definition: arch.c:46
gdb_reg_t * parse_def(char **tok)
Definition: arch.c:23
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
#define reg(n)
return memset(p, 0, total)
void * p
Definition: libc.cpp:67
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
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 ut32 rz_list_length(RZ_NONNULL const RzList *list)
Returns the length of the list.
Definition: list.c:109
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
void * malloc(size_t size)
Definition: malloc.c:123
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")
#define eprintf(x, y...)
Definition: rlcc.c:7
static RzSocket * s
Definition: rtr.c:28
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define isgraph(c)
Definition: safe-ctype.h:133
#define b(i)
Definition: sha256.c:42
#define a(i)
Definition: sha256.c:41
Definition: arch.h:13
ut64(WINAPI *w32_GetEnabledXStateFeatures)()