Rizin
unix-like reverse engineering framework and cli tools
arc-ext.c
Go to the documentation of this file.
1 /* ARC target-dependent stuff. Extension structure access functions
2  Copyright 1995, 1997, 2000, 2001, 2004, 2005, 2009
3  Free Software Foundation, Inc.
4 
5  Copyright 2008-2012 Synopsys Inc.
6 
7  This file is part of libopcodes.
8 
9  This library is free software; you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation; either version 3, or (at your option)
12  any later version.
13 
14  It is distributed in the hope that it will be useful, but WITHOUT
15  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17  License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22  MA 02110-1301, USA. */
23 
24 
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdio.h>
28 
29 #include "arc-ext.h"
30 #include "arc.h"
31 #ifndef _MSC_VER
32 // if one of this files are includes they make a #define const .....
33 // the const prefix is used bellow for api definitions.
34 // If u define the new value of const this dont match with previus const int arc-ext.h api definition
35 // giving a compiler error under MSVC
36 #include "libiberty.h"
37 #include "sysdep.h"
38 #endif
39 
40 /******************************************************************************/
41 /* */
42 /* Outline: */
43 /* This module provides support for extensions to the ARC processor */
44 /* architecture. */
45 /* */
46 /******************************************************************************/
47 
48 
49 /* -------------------------------------------------------------------------- */
50 /* local constants */
51 /* -------------------------------------------------------------------------- */
52 
53 #define FIRST_EXTENSION_CORE_REGISTER 32
54 #define LAST_EXTENSION_CORE_REGISTER 59
55 #define FIRST_EXTENSION_CONDITION_CODE 0x10
56 #define LAST_EXTENSION_CONDITION_CODE 0x1f
57 
58 #define NUM_EXT_CORE (LAST_EXTENSION_CORE_REGISTER - FIRST_EXTENSION_CORE_REGISTER + 1)
59 #define NUM_EXT_COND (LAST_EXTENSION_CONDITION_CODE - FIRST_EXTENSION_CONDITION_CODE + 1)
60 #define INST_HASH_BITS 6
61 #define INST_HASH_SIZE (1 << INST_HASH_BITS)
62 #define INST_HASH_MASK (INST_HASH_SIZE - 1)
63 
64 
65 /* -------------------------------------------------------------------------- */
66 /* local types */
67 /* -------------------------------------------------------------------------- */
68 
69 /* these types define the information stored in the table */
70 
72 {
73  char major;
74  char minor;
75  char flags;
76  char* name;
78 };
79 
81 {
82  long address;
83  char* name;
85 };
86 
88 {
89  short number;
90  enum ExtReadWrite rw;
91  char* name;
92 };
93 
94 struct arcExtMap
95 {
100 };
101 
102 
103 /* -------------------------------------------------------------------------- */
104 /* local data */
105 /* -------------------------------------------------------------------------- */
106 
107 /* extension table */
108 static struct arcExtMap arc_extension_map;
109 
110 
111 /* -------------------------------------------------------------------------- */
112 /* local macros */
113 /* -------------------------------------------------------------------------- */
114 
115 /* a hash function used to map instructions into the table */
116 #define INST_HASH(MAJOR, MINOR) ((((MAJOR) << 3) ^ (MINOR)) & INST_HASH_MASK)
117 
118 
119 /* -------------------------------------------------------------------------- */
120 /* local functions */
121 /* -------------------------------------------------------------------------- */
122 
123 #if 0
124 static void create_map(unsigned char *block, unsigned long length)
125 {
126  unsigned char *p = block;
127 
128 //printf("building ext map...\n");
129 
130  while (p && p < (block + length))
131  {
132  /* p[0] == length of record
133  p[1] == type of record
134  For instructions:
135  p[2] = opcode
136  p[3] = minor opcode (if opcode == 3)
137  p[4] = flags
138  p[5]+ = name
139  For core regs and condition codes:
140  p[2] = value
141  p[3]+ = name
142  For auxiliary regs:
143  p[2..5] = value
144  p[6]+ = name
145  (value is p[2]<<24|p[3]<<16|p[4]<<8|p[5]) */
146 
147  /* the sequence of records is temrinated by an "empty" record */
148  if (p[0] == 0)
149  break;
150 
151 // printf("%d byte type %d record\n", p[0], p[1]);
152 
153  switch (p[1])
154  { /* type */
155  case EXT_INSTRUCTION:
156  {
157  struct ExtInstruction *insn = XNEW (struct ExtInstruction);
158  int major = p[2];
159  int minor = p[3];
160  struct ExtInstruction **bucket =
162 
163  insn->name = strdup ((char *) (p+5));
164  insn->major = major;
165  insn->minor = minor;
166  insn->flags = p[4];
167  insn->next = *bucket;
168  *bucket = insn;
169  break;
170  }
171 
172  case EXT_CORE_REGISTER:
173  {
174  unsigned char number = p[2];
175  char* name = (char *) p+3;
176 
180  break;
181  }
182 
184  {
185  unsigned char number = p[2];
186  char* name = (char *) p+7;
187  enum ExtReadWrite rw = p[6];
188 
192  }
193 
194  case EXT_COND_CODE:
195  {
196  char *cc_name = strdup ((char *) (p+3));
197 
199  break;
200  }
201 
202  case EXT_AUX_REGISTER:
203  {
204  /* trickier -- need to store linked list of these */
205  struct ExtAuxRegister *newAuxRegister = XNEW (struct ExtAuxRegister);
206  char *aux_name = strdup ((char *) (p+6));
207 
208  newAuxRegister->name = aux_name;
209  newAuxRegister->address = p[2]<<24 | p[3]<<16 | p[4]<<8 | p[5];
210  newAuxRegister->next = arc_extension_map.auxRegisters;
211  arc_extension_map.auxRegisters = newAuxRegister;
212  break;
213  }
214 
215  default:
216 // printf("type %d extension record skipped\n", p[1]);
217  break;
218  }
219 
220  p += p[0]; /* move on to next record */
221  }
222 
223 //printf("ext map built\n");
224 }
225 
226 
227 /* Free memory that has been allocated for the extensions. */
228 static void destroy_map(void)
229 {
230  struct ExtAuxRegister *r;
231  unsigned int i;
232 
233  /* free auxiliary registers */
235  while (r)
236  {
237  /* N.B. after r has been freed, r->next is invalid! */
238  struct ExtAuxRegister* next = r->next;
239 
240  free (r->name);
241  free (r);
242  r = next;
243  }
244 
245  /* free instructions */
246  for (i = 0; i < INST_HASH_SIZE; i++)
247  {
249 
250  while (insn)
251  {
252  /* N.B. after insn has been freed, insn->next is invalid! */
253  struct ExtInstruction *next = insn->next;
254 
255  free (insn->name);
256  free (insn);
257  insn = next;
258  }
259  }
260 
261  /* free core registers */
262  for (i = 0; i < NUM_EXT_CORE; i++)
263  {
266  }
267 
268  /* free condition codes */
269  for (i = 0; i < NUM_EXT_COND; i++)
270  {
273  }
274 
276 }
277 #endif
278 
279 
280 static const char* ExtReadWrite_image(enum ExtReadWrite val)
281 {
282  switch (val)
283  {
284  case REG_INVALID : return "INVALID";
285  case REG_READ : return "RO";
286  case REG_WRITE : return "WO";
287  case REG_READWRITE: return "R/W";
288  default : return "???";
289  }
290 }
291 
292 
293 /* -------------------------------------------------------------------------- */
294 /* externally visible functions */
295 /* -------------------------------------------------------------------------- */
296 
297 /* Get the name of an extension instruction. */
298 
299 const char *
300 arcExtMap_instName (int opcode, int insn, int *flags)
301 {
302  /* Here the following tasks need to be done. First of all, the opcode
303  stored in the Extension Map is the real opcode. However, the subopcode
304  stored in the instruction to be disassembled is mangled. We pass (in
305  minor opcode), the instruction word. Here we will un-mangle it and get
306  the real subopcode which we can look for in the Extension Map. This
307  function is used both for the ARCTangent and the ARCompact, so we would
308  also need some sort of a way to distinguish between the two
309  architectures. This is because the ARCTangent does not do any of this
310  mangling so we have no issues there. */
311 
312  /* If P[22:23] is 0 or 2 then un-mangle using iiiiiI. If it is 1 then use
313  iiiiIi. Now, if P is 3 then check M[5:5] and if it is 0 then un-mangle
314  using iiiiiI else iiiiii. */
315 
316  unsigned char minor;
317  struct ExtInstruction *temp;
318 
319  if (*flags != E_ARC_MACH_A4) /* ARCompact extension instructions. */
320  {
321  /* 16-bit instructions. */
322  if (0x08 <= opcode && opcode <= 0x0b)
323  {
324  /* I - set but not used */
325  unsigned char /* I, */ b, c, i;
326 
327  /* I = (insn & 0xf800) >> 11; */
328  b = (insn & 0x0700) >> 8;
329  c = (insn & 0x00e0) >> 5;
330  i = (insn & 0x001f);
331 
332  if (i) {
333  minor = i;
334  } else {
335  minor = (c == 0x07) ? b : c;
336  }
337  }
338  /* 32-bit instructions. */
339  else
340  {
341  /* P, M - set but not used */
342  unsigned char /* P, M, */ I, A, B;
343 
344  /* P = (insn & 0x00c00000) >> 22; */
345  /* M = (insn & 0x00000020); */
346  I = (insn & 0x003f0000) >> 16;
347  A = (insn & 0x0000003f);
348  B = ((insn & 0x07000000) >> 24) | ((insn & 0x00007000) >> 9);
349 
350  if (I != 0x2f)
351  {
352 #ifndef UNMANGLED
353  switch (P)
354  {
355  case 3:
356  if (M)
357  {
358  minor = I;
359  break;
360  }
361  case 0:
362  case 2:
363  minor = (I >> 1) | ((I & 0x1) << 5);
364  break;
365  case 1:
366  minor = (I >> 1) | (I & 0x1) | ((I & 0x2) << 4);
367  }
368 #else
369  minor = I;
370 #endif
371  }
372  else
373  {
374  if (A != 0x3f) {
375  minor = A;
376  } else {
377  minor = B;
378  }
379  }
380  }
381  } else { /* ARCTangent extension instructions. */
382  minor = insn;
383  }
384 
385  temp = arc_extension_map.instructions[INST_HASH (opcode, minor)];
386  while (temp)
387  {
388  if ((temp->major == opcode) && (temp->minor == minor))
389  {
390  *flags = temp->flags;
391  return temp->name;
392  }
393  temp = temp->next;
394  }
395 
396  return NULL;
397 }
398 
399 
400 /* get the name of an extension core register */
401 const char *
403 {
404  if (regnum < FIRST_EXTENSION_CORE_REGISTER || regnum > LAST_EXTENSION_CORE_REGISTER) {
405  return NULL;
406  }
408 }
409 
410 
411 /* get the access mode of an extension core register */
412 enum ExtReadWrite
413 arcExtMap_coreReadWrite (int regnum)
414 {
415  if (regnum < FIRST_EXTENSION_CORE_REGISTER || regnum > LAST_EXTENSION_CORE_REGISTER) {
416  return REG_INVALID;
417  }
419 }
420 
421 
422 /* get the name of an extension condition code */
423 const char *
425 {
427  return NULL;
428  }
430 }
431 
432 
433 /* Get the name of an extension auxiliary register. */
434 const char *
435 arcExtMap_auxRegName (long address)
436 {
437  /* Walk the list of auxiliary register names and find the name. */
438  struct ExtAuxRegister *r;
439 
440  for (r = arc_extension_map.auxRegisters; r; r = r->next)
441  {
442  if (r->address == address) {
443  return (const char *)r->name;
444  }
445  }
446  return NULL;
447 }
448 
449 
450 /* Load extensions described in .arcextmap and .gnu.linkonce.arcextmap.* ELF
451  section. */
452 void
453 build_ARC_extmap (void *text_bfd)
454 {
455 #if 0
456  asection *sect;
457 
458  /* the map is built each time gdb loads an executable file - so free any
459  * existing map, as the map defined by the new file may differ from the old
460  */
461  destroy_map();
462 
463  for (sect = text_bfd->sections; sect != NULL; sect = sect->next)
464  if (!strncmp (sect->name,
465  ".gnu.linkonce.arcextmap.",
466  sizeof (".gnu.linkonce.arcextmap.") - 1)
467  || !strcmp (sect->name,".arcextmap"))
468  {
470  unsigned char* buffer = xmalloc (count);
471 
472  if (buffer)
473  {
474  if (bfd_get_section_contents (text_bfd, sect, buffer, 0, count))
475  create_map(buffer, count);
476  free (buffer);
477  }
478  }
479 #endif
480 }
481 
482 
483 void dump_ARC_extmap (void)
484 {
485  struct ExtAuxRegister* r;
486  int i;
487 
489 
490  while (r)
491  {
492  printf("AUX : %s %ld\n", r->name, r->address);
493  r = r->next;
494  }
495 
496  for (i = 0; i < INST_HASH_SIZE; i++)
497  {
498  struct ExtInstruction *insn;
499 
500  for (insn = arc_extension_map.instructions[i]; insn != NULL; insn = insn->next) {
501  printf ("INST: %d %d %x %s\n", insn->major, insn->minor, insn->flags, insn->name);
502  }
503  }
504 
505  for (i = 0; i < NUM_EXT_CORE; i++)
506  {
508 
509  if (reg.name) {
510  printf ("CORE: %s %d %s\n", reg.name, reg.number, ExtReadWrite_image (reg.rw));
511  }
512  }
513 
514  for (i = 0; i < NUM_EXT_COND; i++) {
516  printf ("COND: %s\n", arc_extension_map.condCodes[i]);
517  }
518  }
519 }
520 
521 /******************************************************************************/
static const char * cc_name(arm_cc cc)
lzma_index ** i
Definition: index.h:629
const char * arcExtMap_auxRegName(long address)
Definition: arc-ext.c:435
#define INST_HASH_SIZE
Definition: arc-ext.c:61
#define LAST_EXTENSION_CORE_REGISTER
Definition: arc-ext.c:54
#define FIRST_EXTENSION_CONDITION_CODE
Definition: arc-ext.c:55
void dump_ARC_extmap(void)
Definition: arc-ext.c:483
const char * arcExtMap_instName(int opcode, int insn, int *flags)
Definition: arc-ext.c:300
#define LAST_EXTENSION_CONDITION_CODE
Definition: arc-ext.c:56
static const char * ExtReadWrite_image(enum ExtReadWrite val)
Definition: arc-ext.c:280
static struct arcExtMap arc_extension_map
Definition: arc-ext.c:108
const char * arcExtMap_condCodeName(int code)
Definition: arc-ext.c:424
const char * arcExtMap_coreRegName(int regnum)
Definition: arc-ext.c:402
#define INST_HASH(MAJOR, MINOR)
Definition: arc-ext.c:116
enum ExtReadWrite arcExtMap_coreReadWrite(int regnum)
Definition: arc-ext.c:413
#define NUM_EXT_CORE
Definition: arc-ext.c:58
#define NUM_EXT_COND
Definition: arc-ext.c:59
#define FIRST_EXTENSION_CORE_REGISTER
Definition: arc-ext.c:53
void build_ARC_extmap(void *text_bfd)
Definition: arc-ext.c:453
@ EXT_LONG_CORE_REGISTER
Definition: arc-ext.h:69
@ EXT_AUX_REGISTER
Definition: arc-ext.h:64
@ EXT_COND_CODE
Definition: arc-ext.h:65
@ EXT_INSTRUCTION
Definition: arc-ext.h:62
@ EXT_CORE_REGISTER
Definition: arc-ext.h:63
ExtReadWrite
Definition: arc-ext.h:77
@ REG_WRITE
Definition: arc-ext.h:80
@ REG_READWRITE
Definition: arc-ext.h:81
@ REG_READ
Definition: arc-ext.h:79
@ REG_INVALID
Definition: arc-ext.h:78
#define A(x)
Definition: arc.h:165
#define I(x)
Definition: arc.h:164
#define E_ARC_MACH_A4
Definition: arc.h:47
#define B(x)
Definition: arc.h:166
ut16 val
Definition: armass64_const.h:6
#define P
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
Definition: cs_driver.c:93
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 count
Definition: sflib.h:98
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
#define xmalloc
Definition: disas-asm.h:43
#define minor(dev)
Definition: fsmagic.c:57
#define major(dev)
Definition: fsmagic.c:56
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
#define XNEW(T)
Definition: libiberty.h:319
#define M
Definition: common.h:37
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")
BFD_HOST_U_64_BIT bfd_size_type
Definition: mybfd.h:113
bfd_boolean bfd_get_section_contents(bfd *abfd, asection *section, void *location, file_ptr offset, bfd_size_type count)
#define bfd_get_section_size(ptr)
Definition: mybfd.h:316
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
#define b(i)
Definition: sha256.c:42
#define c(i)
Definition: sha256.c:43
char * name
Definition: arc-ext.c:83
struct ExtAuxRegister * next
Definition: arc-ext.c:84
long address
Definition: arc-ext.c:82
short number
Definition: arc-ext.c:89
char * name
Definition: arc-ext.c:91
enum ExtReadWrite rw
Definition: arc-ext.c:90
char minor
Definition: arc-ext.c:74
char flags
Definition: arc-ext.c:75
char * name
Definition: arc-ext.c:76
struct ExtInstruction * next
Definition: arc-ext.c:77
char major
Definition: arc-ext.c:73
struct ExtCoreRegister coreRegisters[NUM_EXT_CORE]
Definition: arc-ext.c:98
struct ExtInstruction * instructions[INST_HASH_SIZE]
Definition: arc-ext.c:97
char * condCodes[NUM_EXT_COND]
Definition: arc-ext.c:99
struct ExtAuxRegister * auxRegisters
Definition: arc-ext.c:96
struct bfd_section * next
Definition: mybfd.h:1016
const char * name
Definition: mybfd.h:1007
Definition: buffer.h:15
Definition: inftree9.h:24
Definition: z80asm.h:102