File: TriCoreMapping.c

package info (click to toggle)
capstone 5.0.6-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 58,188 kB
  • sloc: ansic: 96,086; cpp: 67,489; cs: 29,510; python: 25,829; pascal: 24,412; java: 15,582; ml: 14,473; makefile: 1,275; sh: 479; ruby: 386
file content (241 lines) | stat: -rw-r--r-- 5,560 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
/* Capstone Disassembly Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */

#ifdef CAPSTONE_HAS_TRICORE

#include <stdio.h> // debug
#include <string.h>
#include <assert.h>

#include "../../utils.h"
#include "../../cs_simple_types.h"

#include "TriCoreMapping.h"
#include "TriCoreLinkage.h"

#define GET_INSTRINFO_ENUM

#include "TriCoreGenInstrInfo.inc"

static const insn_map insns[] = {
	// dummy item
	{ 0,
	  0,
#ifndef CAPSTONE_DIET
	  { 0 },
	  { 0 },
	  { 0 },
	  0,
	  0
#endif
	},

#include "TriCoreGenCSMappingInsn.inc"
};

void TriCore_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id)
{
	// Not used. Information is set after disassembly.
}

#ifndef CAPSTONE_DIET
static const tricore_reg flag_regs[] = { TRICORE_REG_PSW };
#endif // CAPSTONE_DIET

static inline void check_updates_flags(MCInst *MI)
{
#ifndef CAPSTONE_DIET
	if (!MI->flat_insn->detail)
		return;
	cs_detail *detail = MI->flat_insn->detail;
	for (int i = 0; i < detail->regs_write_count; ++i) {
		if (detail->regs_write[i] == 0)
			return;
		for (int j = 0; j < ARR_SIZE(flag_regs); ++j) {
			if (detail->regs_write[i] == flag_regs[j]) {
				detail->tricore.update_flags = true;
				return;
			}
		}
	}
#endif // CAPSTONE_DIET
}

void TriCore_set_instr_map_data(MCInst *MI)
{
	map_cs_id(MI, insns, ARR_SIZE(insns));
	map_implicit_reads(MI, insns);
	map_implicit_writes(MI, insns);
	check_updates_flags(MI);
	map_groups(MI, insns);
}

#ifndef CAPSTONE_DIET

static const char * const insn_names[] = {
	NULL,

#include "TriCoreGenCSMappingInsnName.inc"
};

// special alias insn
static const name_map alias_insn_names[] = { { 0, NULL } };
#endif

const char *TriCore_insn_name(csh handle, unsigned int id)
{
#ifndef CAPSTONE_DIET
	unsigned int i;

	if (id >= TRICORE_INS_ENDING)
		return NULL;

	// handle special alias first
	for (i = 0; i < ARR_SIZE(alias_insn_names); i++) {
		if (alias_insn_names[i].id == id)
			return alias_insn_names[i].name;
	}

	return insn_names[id];
#else
	return NULL;
#endif
}

#ifndef CAPSTONE_DIET
static const name_map group_name_maps[] = {
	{ TRICORE_GRP_INVALID, NULL },
	{ TRICORE_GRP_CALL, "call" },
	{ TRICORE_GRP_JUMP, "jump" },
};
#endif

const char *TriCore_group_name(csh handle, unsigned int id)
{
#ifndef CAPSTONE_DIET
	if (id >= TRICORE_GRP_ENDING)
		return NULL;

	return group_name_maps[id].name;
#else
	return NULL;
#endif
}

#ifndef CAPSTONE_DIET
/// A LLVM<->CS Mapping entry of an operand.
typedef struct insn_op {
	uint8_t /* cs_op_type */ type;	 ///< Operand type (e.g.: reg, imm, mem)
	uint8_t /* cs_ac_type */ access; ///< The access type (read, write)
	uint8_t				 /* cs_data_type */
		dtypes[10]; ///< List of op types. Terminated by CS_DATA_TYPE_LAST
} insn_op;

///< Operands of an instruction.
typedef struct {
	insn_op ops[16]; ///< NULL terminated array of operands.
} insn_ops;

const insn_ops insn_operands[] = {
#include "TriCoreGenCSMappingInsnOp.inc"
};
#endif

void TriCore_set_access(MCInst *MI)
{
#ifndef CAPSTONE_DIET
	if (!(MI->csh->detail == CS_OPT_ON && MI->flat_insn->detail))
		return;

	assert(MI->Opcode < ARR_SIZE(insn_operands));

	cs_detail *detail = MI->flat_insn->detail;
	cs_tricore *tc = &(detail->tricore);
	for (int i = 0; i < tc->op_count; ++i) {
		cs_ac_type ac = map_get_op_access(MI, i);
		cs_tricore_op *op = &tc->operands[i];
		op->access = ac;
		cs_op_type op_type = map_get_op_type(MI, i);
		if (op_type != CS_OP_REG) {
			continue;
		}
		if (ac & CS_AC_READ) {
			detail->regs_read[detail->regs_read_count++] = op->reg;
		}
		if (ac & CS_AC_WRITE) {
			detail->regs_write[detail->regs_write_count++] =
				op->reg;
		}
	}
#endif
}

void TriCore_reg_access(const cs_insn *insn, cs_regs regs_read,
			uint8_t *regs_read_count, cs_regs regs_write,
			uint8_t *regs_write_count)
{
#ifndef CAPSTONE_DIET
	uint8_t read_count, write_count;
	cs_detail *detail = insn->detail;
	read_count = detail->regs_read_count;
	write_count = detail->regs_write_count;

	// implicit registers
	memcpy(regs_read, detail->regs_read,
	       read_count * sizeof(detail->regs_read[0]));
	memcpy(regs_write, detail->regs_write,
	       write_count * sizeof(detail->regs_write[0]));

	// explicit registers
	cs_tricore *tc = &detail->tricore;
	for (uint8_t i = 0; i < tc->op_count; i++) {
		cs_tricore_op *op = &(tc->operands[i]);
		switch ((int)op->type) {
		case TRICORE_OP_REG:
			if ((op->access & CS_AC_READ) &&
			    !arr_exist(regs_read, read_count, op->reg)) {
				regs_read[read_count] = (uint16_t)op->reg;
				read_count++;
			}
			if ((op->access & CS_AC_WRITE) &&
			    !arr_exist(regs_write, write_count, op->reg)) {
				regs_write[write_count] = (uint16_t)op->reg;
				write_count++;
			}
			break;
		case TRICORE_OP_MEM:
			// registers appeared in memory references always being read
			if ((op->mem.base != ARM_REG_INVALID) &&
			    !arr_exist(regs_read, read_count, op->mem.base)) {
				regs_read[read_count] = (uint16_t)op->mem.base;
				read_count++;
			}
		default:
			break;
		}
	}

	*regs_read_count = read_count;
	*regs_write_count = write_count;
#endif
}

bool TriCore_getInstruction(csh handle, const uint8_t *Bytes, size_t ByteLen,
			    MCInst *MI, uint16_t *Size, uint64_t Address,
			    void *Info)
{
	return TriCore_LLVM_getInstruction(handle, Bytes, ByteLen, MI, Size,
					   Address, Info);
}

void TriCore_printInst(MCInst *MI, SStream *O, void *Info)
{
	TriCore_LLVM_printInst(MI, MI->address, O);
}

const char *TriCore_getRegisterName(csh handle, unsigned int RegNo)
{
	return TriCore_LLVM_getRegisterName(RegNo);
}

#endif // CAPSTONE_HAS_TRICORE