CHDK_DE Vorschauversion  Trunk Rev. 6014
 Alle Datenstrukturen Dateien Funktionen Variablen Typdefinitionen Aufzählungen Aufzählungswerte Makrodefinitionen
chdk_dasm.c-Dateireferenz
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <ctype.h>
#include <sys/stat.h>
#include "stubs_load.h"
#include "firmware_load.h"
#include "chdk_dasm.h"
+ Include-Abhängigkeitsdiagramm für chdk_dasm.c:

gehe zum Quellcode dieser Datei

Datenstrukturen

struct  lnode
 
struct  llist
 

Makrodefinitionen

#define Sbit   (1<<20) /* set condition codes (data processing) */
 
#define Lbit   (1<<20) /* load, not store (data transfer) */
 
#define Wbit   (1<<21) /* writeback (data transfer) */
 
#define Bbit   (1<<22) /* single byte (data transfer, SWP) */
 
#define Ubit   (1<<23) /* up, not down (data transfer) */
 
#define Pbit   (1<<24) /* pre-, not post-, indexed (data transfer) */
 
#define Ibit   (1<<25) /* non-immediate (data transfer) */
 
#define SPSRbit   (1<<22) /* SPSR, not CPSR (MRS, MSR) */
 
#define RD(x)   ((x)<<12) /* destination register */
 
#define RN(x)   ((x)<<16) /* operand/base register */
 
#define CP(x)   ((x)<<8) /* coprocessor number */
 
#define RDbits   RD(15)
 
#define RNbits   RN(15)
 
#define CPbits   CP(15)
 
#define RD_is(x)   ((instr&RDbits)==RD(x))
 
#define RN_is(x)   ((instr&RNbits)==RN(x))
 
#define CP_is(x)   ((instr&CPbits)==CP(x))
 
#define BitsDiffer(a, b)   ((instr^(instr>>(b-a)))&(1<<a))
 

Aufzählungen

enum  eTargetType {
  target_None, target_Data, target_FloatS, target_FloatD,
  target_FloatE, target_FloatP, target_Code, target_Unknown
}
 

Funktionen

 declstruct (Instruction)
 
 defstruct (Instruction)
 
struct llistnew_list ()
 
void free_list (struct llist *lst)
 
struct lnodenew_node (t_address address, t_value data)
 
struct lnodel_search (struct llist *ls, t_address address)
 
int l_insert (struct llist *ls, t_address address, t_value data)
 
void l_remove (struct llist *ls, t_address addr)
 
static void set_patch_old_values (t_address w, char *nm)
 
void swiname (t_value, char *, size_t)
 
static char * append (char *op, const char *ip)
 
static char * print_ascii_str (firmware *fw, char *op, t_value w)
 
static char * xhex8 (firmware *fw, char *op, t_value w)
 
static char * ahex8 (firmware *fw, char *op, t_value w)
 
static char * yhex8 (firmware *fw, char *op, t_value w)
 
static char * sub_hex8 (firmware *fw, char *op, t_value w)
 
static char * sub_ahex8 (firmware *fw, char *op, t_value w)
 
static char * reg (char *op, char c, t_value n)
 
static char * num (char *op, t_value w, t_value decmax)
 
pInstruction instr_disassemble (firmware *fw, t_value instr, t_address addr, pDisOptions opts)
 
void disassemble1 (firmware *fw, t_address start, t_value length)
 
void disassemble (firmware *fw, FILE *outfile, t_address start, t_value length)
 
t_address find_end (firmware *fw, t_address start)
 
void swiname (__attribute__((unused)) t_value w, __attribute__((unused)) char *s, __attribute__((unused)) size_t sz)
 

Variablen

char * patch_func_name
 
t_address patch_new_val
 
t_address patch_old_val
 
char * patch_old_func_name
 
int patch_ref_address [20]
 
char patch_ref_name [20][256]
 
int save_patch_ref
 
char * patch_comment
 
static char * reg_names [16]
 
sDisOptions options
 
struct llistdcd_list
 
struct llistbranch_list
 
t_address addr
 
t_address last_used_addr
 

Makro-Dokumentation

#define Bbit   (1<<22) /* single byte (data transfer, SWP) */

Definiert in Zeile 106 der Datei chdk_dasm.c.

#define BitsDiffer (   a,
 
)    ((instr^(instr>>(b-a)))&(1<<a))

Definiert in Zeile 128 der Datei chdk_dasm.c.

#define CP (   x)    ((x)<<8) /* coprocessor number */

Definiert in Zeile 117 der Datei chdk_dasm.c.

#define CP_is (   x)    ((instr&CPbits)==CP(x))

Definiert in Zeile 123 der Datei chdk_dasm.c.

#define CPbits   CP(15)

Definiert in Zeile 120 der Datei chdk_dasm.c.

#define Ibit   (1<<25) /* non-immediate (data transfer) */

Definiert in Zeile 109 der Datei chdk_dasm.c.

#define Lbit   (1<<20) /* load, not store (data transfer) */

Definiert in Zeile 104 der Datei chdk_dasm.c.

#define Pbit   (1<<24) /* pre-, not post-, indexed (data transfer) */

Definiert in Zeile 108 der Datei chdk_dasm.c.

#define RD (   x)    ((x)<<12) /* destination register */

Definiert in Zeile 115 der Datei chdk_dasm.c.

#define RD_is (   x)    ((instr&RDbits)==RD(x))

Definiert in Zeile 121 der Datei chdk_dasm.c.

#define RDbits   RD(15)

Definiert in Zeile 118 der Datei chdk_dasm.c.

#define RN (   x)    ((x)<<16) /* operand/base register */

Definiert in Zeile 116 der Datei chdk_dasm.c.

#define RN_is (   x)    ((instr&RNbits)==RN(x))

Definiert in Zeile 122 der Datei chdk_dasm.c.

#define RNbits   RN(15)

Definiert in Zeile 119 der Datei chdk_dasm.c.

#define Sbit   (1<<20) /* set condition codes (data processing) */

Definiert in Zeile 103 der Datei chdk_dasm.c.

#define SPSRbit   (1<<22) /* SPSR, not CPSR (MRS, MSR) */

Definiert in Zeile 111 der Datei chdk_dasm.c.

#define Ubit   (1<<23) /* up, not down (data transfer) */

Definiert in Zeile 107 der Datei chdk_dasm.c.

#define Wbit   (1<<21) /* writeback (data transfer) */

Definiert in Zeile 105 der Datei chdk_dasm.c.

Dokumentation der Aufzählungstypen

Aufzählungswerte
target_None 
target_Data 
target_FloatS 
target_FloatD 
target_FloatE 
target_FloatP 
target_Code 
target_Unknown 

Definiert in Zeile 58 der Datei chdk_dasm.c.

58  {
59  target_None, /* instruction doesn't refer to an address */
60  target_Data, /* instruction refers to address of data */
61  target_FloatS, /* instruction refers to address of single-float */
62  target_FloatD, /* instruction refers to address of double-float */
63  target_FloatE, /* blah blah extended-float */
64  target_FloatP, /* blah blah packed decimal float */
65  target_Code, /* instruction refers to address of code */
66  target_Unknown /* instruction refers to address of *something* */
67 } eTargetType;

Dokumentation der Funktionen

static char* ahex8 ( firmware fw,
char *  op,
t_value  w 
)
static

Definiert in Zeile 363 der Datei chdk_dasm.c.

364 {
365  struct lnode * lptr ;
366  lptr = l_search( dcd_list, w) ; // does this DCD address exist already ?
367 
368  if ( lptr ) w = lptr->data ; // dereference indirect address (typically pass 3)
369  else l_insert(dcd_list, w, 0) ; // add node if not found - typically on pass 1
370 
371  return xhex8(fw, op, w);
372 }
static char* append ( char *  op,
const char *  ip 
)
static

Definiert in Zeile 279 der Datei chdk_dasm.c.

279  {
280  char c;
281  while ((c=*ip++)!=0) *op++=c;
282  return op;
283 }
declstruct ( Instruction  )
defstruct ( Instruction  )

Definiert in Zeile 69 der Datei chdk_dasm.c.

69  {
70  char text[128]; /* the disassembled instruction */
71  int undefined; /* non-0 iff it's an undefined instr */
72  int badbits; /* non-0 iff something reserved has the wrong value */
73  int oddbits; /* non-0 iff something unspecified isn't 0 */
74  int is_SWI; /* non-0 iff it's a SWI */
75  t_value swinum; /* only set for SWIs */
76  t_address target; /* address instr refers to */
77  eTargetType target_type; /* and what we expect to be there */
78  int offset; /* offset from register in LDR or STR or similar */
79  char * addrstart; /* start of address part of instruction, or 0 */
80  t_value instr ; /* the raw instruction data */
81 };
void disassemble ( firmware fw,
FILE outfile,
t_address  start,
t_value  length 
)

Definiert in Zeile 1328 der Datei chdk_dasm.c.

1329 {
1330  t_value w;
1331 
1332  int dcd_mode_on = 0;
1333 
1334  // Only need 1 pass here - assumes disassemble1 called previously
1335  addr = start ;
1336  t_value word_count = 0 ;
1337 
1338  while (word_count < length )
1339  {
1340  w = fwval(fw,adr2idx(fw,addr));
1341 
1342  pInstruction instr = instr_disassemble(fw, w, addr, &options);
1343 
1344  if (l_search(branch_list, addr))
1345  {
1346  fprintf(outfile,"\n\"loc_%08X:\\n\"\n", addr);
1347  dcd_mode_on = 0;
1348  }
1349  struct lnode* lptr = l_search(dcd_list,addr);
1350  if ( lptr || dcd_mode_on )
1351  {
1352  if ((options.flags & disopt_exclude_dcd) == 0)
1353  fprintf(outfile,"\"dword_%8.8X DCD 0x%X \\n\"\n", addr , w);
1354  dcd_mode_on = 1;
1355  /*
1356  t_value aword ;
1357  int i ;
1358  unsigned char ch ;
1359  aword = lptr->data ;
1360  for ( i=0 ; i< 4 ; i++ )
1361  {
1362  ch = aword & 0xFF ;
1363  if ( (ch>=0x20) && ( ch < 0x80) ) fprintf(outfile," %c" , ch );
1364  else fprintf(outfile,"_" );
1365  aword = aword >> 8 ;
1366  }
1367  fprintf(outfile, "\n" ) ;
1368  */
1369  }
1370  else
1371  {
1372  if (instr->undefined || instr->badbits || instr->oddbits) {
1373  fprintf(outfile,"Error: ");
1374  if (instr->undefined) fprintf(outfile,"[---undefined instr---] 0x%8.8X ", w);
1375  if (instr->badbits) fprintf(outfile, "[---illegal bits---] 0x%8.8X ", w);
1376  if (instr->oddbits) fprintf(outfile, "[---unexpected bits---] 0x%8.8X ", w);
1377  if ( !((instr->undefined) || (instr->badbits) || (instr->oddbits)) )
1378  fprintf(outfile, "[---unknown error---] 0x%8.8X ", w);
1379  if ( options.flags & disopt_print_address_mode)
1380  {
1381  fprintf(outfile,"// rom:%.8x 0x%8.8X \n", addr, w);
1382  }
1383  else fprintf(outfile,"\n");
1384  }
1385  else
1386  {
1387  strcat( instr->text, " \\n\"") ;
1388  if (options.flags & disopt_line_numbers) fprintf(outfile,"/*%3d*/",(addr - options.start_address) / 4 + 1);
1389  char *indent = "\" ";
1391  indent = "//\" ";
1393  fprintf(outfile," ");
1394  if (options.flags & disopt_print_address_mode)
1395  {
1396  fprintf(outfile,"%s%-40s // rom:%.8x 0x%8.8X", indent, instr->text, addr, w);
1397  }
1398  else fprintf(outfile,"%s%s", indent, instr->text);
1399 
1400  if ((options.flags & disopt_patch_branch) || (options.flags & disopt_patch_value))
1401  {
1402  if (patch_old_func_name)
1403  fprintf(outfile," // --> Patched. Old value = _%s.", patch_old_func_name);
1404  else
1405  fprintf(outfile," // --> Patched. Old value = 0x%X.", patch_old_val);
1406  if ((options.flags & disopt_patch_comment) && patch_comment)
1407  {
1408  fprintf(outfile, " %s", patch_comment);
1409  patch_comment = 0;
1410  }
1411  }
1412  else if ((options.flags & disopt_patch_comment) && patch_comment)
1413  {
1414  fprintf(outfile, " // %s", patch_comment);
1415  patch_comment = 0;
1416  }
1417  else if (options.flags & disopt_nullsub_call)
1418  {
1419  fprintf(outfile," // --> Nullsub call removed.");
1420  }
1421  fprintf(outfile,"\n");
1422  }
1423  }
1424 
1425  word_count++ ;
1426  addr += 4;
1427  }
1428 }
void disassemble1 ( firmware fw,
t_address  start,
t_value  length 
)

Definiert in Zeile 1283 der Datei chdk_dasm.c.

1284 {
1285  t_value w;
1286 
1287  free(dcd_list);
1288  dcd_list = new_list();
1289  free(branch_list);
1290  branch_list = new_list();
1291 
1292  // Do three passes; but don't generate any code
1293  int pass;
1294  for ( pass = 1 ; pass <=3 ; pass++ )
1295  {
1296  if ( pass == 2 )
1297  {
1298  struct lnode* lptr = dcd_list->head;
1299  while ( lptr != NULL )
1300  {
1301  addr = (t_address) lptr->address ;
1302  w = fwval(fw,adr2idx(fw,addr));
1303  lptr->data = w ;
1304  lptr = lptr->next ;
1305  }
1306  }
1307  else // pass 1 & 3
1308  {
1309  addr = start ;
1310  t_value word_count = 0 ;
1311 
1312  while (word_count < length )
1313  {
1314  w = fwval(fw,adr2idx(fw,addr));
1315  instr_disassemble(fw, w, addr, &options);
1316 
1317  struct lnode* lptr = l_search(dcd_list,addr);
1318  if (!lptr)
1319  last_used_addr = addr;
1320 
1321  word_count++ ;
1322  addr += 4;
1323  }
1324  }
1325  }
1326 }
t_address find_end ( firmware fw,
t_address  start 
)

Definiert in Zeile 1430 der Datei chdk_dasm.c.

1431 {
1432  int i;
1433  start = adr2idx(fw,start);
1434  for (i=0; i<500; i++, start++)
1435  if ((fwval(fw,start+1) & 0xFFFF4000) == 0xE92D4000) // STMFD SP!, {...,LR}
1436  {
1437  int j;
1438  for (j=0; j<50; j++, start--)
1439  {
1440  if ((fwval(fw,start) & 0xFF000000) == 0xEA000000) // B
1441  {
1442  return idx2adr(fw,start);
1443  }
1444  if ((fwval(fw,start) & 0xFFFF8000) == 0xE8BD8000) // LDMFD SP!, {...,PC}
1445  {
1446  return idx2adr(fw,start);
1447  }
1448  if ((fwval(fw,start) & 0xFFFFFFF0) == 0xE12FFF10) // BX
1449  {
1450  return idx2adr(fw,start);
1451  }
1452  if ((fwval(fw,start) & 0xFFFFF000) == 0xE49DF000) // LDR PC,[SP,...
1453  {
1454  return idx2adr(fw,start);
1455  }
1456  }
1457  return 0;
1458  }
1459  return 0;
1460 }
void free_list ( struct llist lst)

Definiert in Zeile 165 der Datei chdk_dasm.c.

166 {
167  if (lst)
168  {
169  struct lnode *p, *n;
170  p = lst->head;
171  while (p)
172  {
173  n = p->next;
174  free(p);
175  p = n;
176  }
177  free(lst);
178  }
179 }
pInstruction instr_disassemble ( firmware fw,
t_value  instr,
t_address  addr,
pDisOptions  opts 
)

Definiert in Zeile 567 der Datei chdk_dasm.c.

567  {
568  static char flagchars[4];
569  static sInstruction result;
570  const char * mnemonic = 0;
571  char * flagp = flagchars;
572  const char * format = 0;
573  t_value fpn;
574  eTargetType poss_tt = target_None;
575  int is_v4 = 0;
576 
577  options.flags &= ~disopt_nullsub_call;
578 
579  /* PHASE 0. Set up default values for |result|. */
580 
581  fpn = ((instr>>15)&1) + ((instr>>21)&2);
582 
583  result.undefined =
584  result.badbits =
585  result.oddbits =
586  result.instr =
587  result.is_SWI = 0;
588  result.target_type = target_None;
589  result.offset = 0x80000000;
590  result.addrstart = 0;
591 
592  /* PHASE 1. Decode and classify instruction. */
593  static char _i_mul[4][6] = { "UMULL", "UMLAL", "SMULL", "SMLAL" };
594  static char _i_ldr_str[2][4] = { "LDR", "STR" };
595  static char _i_str_ldr[2][4] = { "STR", "LDR" };
596  static char _i_stm_ldm[2][4] = { "STM", "LDM" };
597  static char _i_stf_ldf[2][4] = { "STF", "LDF" };
598  static char _i_stc_ldc[2][4] = { "STC", "LDC" };
599  static char _i_sfm_lfm[2][4] = { "SFM", "LFM" };
600  static char _i_b_bl[2][3] = { "B", "BL" };
601  static char _i_alu[16][4] = {
602  "AND","EOR","SUB","RSB","ADD","ADC","SBC","RSC",
603  "TST","TEQ","CMP","CMN","ORR","MOV","BIC","MVN"
604  };
605  static char _i_cmf[4][5] = { "CMF","CNF","CMFE","CNFE" };
606  static char _i_flt[6][4] = { "FLT","FIX","WFS","RFS","WFC","RFC" };
607  static char _i_mcr_mrc[2][4] = { "MCR","MRC" };
608  static char _i_copro[32][4] = {
609  /* dyadics: */
610  "ADF","MUF","SUF","RSF",
611  "DVF","RDF","POW","RPW",
612  "RMF","FML","FDV","FRD",
613  "POL","***","***","***",
614  /* monadics: */
615  "MVF","MNF","ABS","RND",
616  "SQT","LOG","LGN","EXP",
617  "SIN","COS","TAN","ASN",
618  "ACS","ATN","URD","NRM"
619  };
620  static char _i_lsl_lsr[4][4] = { "LSL","LSR","ASR","ROR" };
621  static char _i_stk[4][2] = { "ED","EA","FD","FA" };
622  static char _i_cond[16][2] = { "EQ","NE","CS","CC","MI","PL","VS","VC","HI","LS","GE","LT","GT","LE","AL","NV" };
623 
624  switch ((instr>>24)&15) {
625 
626  case 0: /* multiply or data processing, or LDRH etc */
627  if ((instr&(15<<4))!=(9<<4)) goto lMaybeLDRHetc; // F0 90
628 
629  if (instr&(1<<23)) { /* long multiply */
630  mnemonic = _i_mul[(instr>>21)&3];
631  format = "3,4,0,2";
632  }
633  else {
634  if (instr&(1<<22)) goto laUndefined; /* "class C" */
635 
636  if (instr&(1<<21)) { /* short multiply */
637  mnemonic = "MLA";
638  format = "4,0,2,3";
639  }
640  else {
641  mnemonic = "MUL";
642  format = "4,0,2";
643  }
644  }
645  if (instr&Sbit) *flagp++='S';
646  break;
647 
648  case 1: /* SWP or MRS/MSR or BX or data processing */
649  case 3:
650 
651  if ((instr&0x0FF000F0)==0x01200010) { /* BX */
652  mnemonic = "BX";
653  format = "0";
654  break;
655  }
656  if ((instr&0x0FF000F0)==0x01200030) { /* BLX */
657  mnemonic = "BLX";
658  format = "0";
659  break;
660  }
661  if ((instr&0x02B00FF0)==0x00000090) { /* SWP */
662  mnemonic = "SWP";
663  format = "3,0,[4]";
664  if (instr&Bbit) *flagp++='B';
665  break;
666  }
667  if ((instr&0x02BF0FFF)==0x000F0000) { /* MRS */
668  mnemonic = "MRS";
669  format = (instr&SPSRbit) ? "3,SPSR" : "3,CPSR";
670  break;
671  }
672 
673  if ((instr&0x0FB00010)==0x03200000) { /* MSR psr<P=0/1...>,Rm */
674  mnemonic = "MSR";
675  format = (instr&SPSRbit) ? "SPSR,0" : "CPSR,0";
676  break;
677  }
678 
679  if ((instr&0x0FB00010)==0x01200000) { /* MSR {C,S}PSR_flag,op2 */
680  mnemonic = "MSR";
681  format = (instr&SPSRbit) ? "SPSR_cxsf,*" : "CPSR_cxsf,*";
682  if (!(instr&Ibit) && (instr&(15<<4)))
683  goto lMaybeLDRHetc;
684  break;
685  }
686 
687 
688 lMaybeLDRHetc: /* fall through here */
689  if ( (instr&(14<<24))==0 && ((instr&(9<<4))==(9<<4)) )
690  { /* Might well be LDRH or similar. */
691  if ((instr&(Wbit+Pbit))==Wbit) goto lbUndefined; /* "class E", case 1 */
692  if ((instr&(Lbit+(1<<6)))==(1<<6)) /* is it LDRD/STRD or LDRSH/STRSH */
693  {
694  if ((instr&(1<<6))!=(1<<6)) goto lcUndefined ;
695  mnemonic = _i_ldr_str[(instr & 0x0000020) >> 5]; /* */
696  if (instr&(1<<6)) *flagp++='D';
697  format = "3,/";
698  if (!(instr&(1<<22))) instr |= Ibit;
699  is_v4=1;
700  }
701  else
702  {
703  mnemonic = _i_str_ldr[(instr&Lbit) >> 20];
704  if (instr&(1<<6)) *flagp++='S';
705  *flagp++ = (instr&(1<<5)) ? 'H' : 'B'; /* fixed 2011/03/27 - B & H reversed */
706  format = "3,/"; /* aargh: */
707  if (!(instr&(1<<22))) instr |= Ibit;
708  is_v4=1;
709  }
710  break;
711  }
712 
713  case 2: /* data processing */
714  { t_value op21 = instr&(15<<21);
715  if ((op21==(2<<21) || (op21==(4<<21))) /* ADD or SUB */
716  && ((instr&(RNbits+Ibit+Sbit))==RN(15)+Ibit) /* imm, no S */
717  /*&& ((instr&(30<<7))==0 || (instr&3))*/) { /* normal rot */
718  /* ADD ...,pc,#... or SUB ...,pc,#...: turn into ADR */
719  mnemonic = "LDR"; //** 2011/03/27 changed from "ADR" to "LDR" for gcc assembler compatability
720  format = "3,.";
721  if ((instr&(30<<7))!=0 && !(instr&3)) result.oddbits=1;
722  break;
723  }
724  if ((op21==(4<<21)) /* ADD */
725  && ((instr&(Ibit))==Ibit) /* imm */
726  && ((instr&0xFFF)==0) /* 0 offset */
727  ) {
728  /* ADD Rn, Rd, #0 --> MOV */
729  mnemonic = "MOV";
730  format = "3,4";
731  if (instr&Sbit && (op21<(8<<21) || op21>=(12<<21))) *flagp++='S';
732  break;
733  }
734  mnemonic = _i_alu[op21 >> 21];
735  /* Rd needed for all but TST,TEQ,CMP,CMN (8..11) */
736  /* Rn needed for all but MOV,MVN (13,15) */
737  if (op21 < ( 8<<21)) format = "3,4,*";
738  else if (op21 < (12<<21)) {
739  format = "4,*";
740  if (instr&RDbits) {
741  if ((instr&Sbit) && RD_is(15))
742  *flagp++='P';
743  else result.oddbits=1;
744  }
745  if (!(instr&Sbit)) goto ldUndefined; /* CMP etc, no S bit */
746  }
747  else if (op21 & (1<<21)) {
748  format = "3,*";
749  if (instr&RNbits) result.oddbits=1;
750  }
751  else format = "3,4,*";
752  if (instr&Sbit && (op21<(8<<21) || op21>=(12<<21))) *flagp++='S';
753  }
754  break;
755 
756  case 4: /* undefined or STR/LDR */
757  case 5:
758  case 6:
759  case 7:
760  if ((instr&Ibit) && (instr&(1<<4))) goto leUndefined; /* "class A" */
761  mnemonic = _i_str_ldr[(instr&Lbit) >> 20];
762  format = "3,/";
763  if (instr&Bbit) *flagp++='B';
764  if ((instr&(Wbit+Pbit))==Wbit) *flagp++='T';
765  poss_tt = target_Data;
766  break;
767 
768  case 8: /* STM/LDM */
769  case 9:
770  mnemonic = _i_stm_ldm[(instr&Lbit) >> 20];
771  if (RN_is(13)) { /* r13, so treat as stack */
772  t_value x = (instr&(3<<23)) >> 23;
773  if (instr&Lbit) x^=3;
774  {
775  const char * foo = _i_stk[x];
776  *flagp++ = *foo++;
777  *flagp++ = *foo;
778  }
779  }
780  else { /* not r13, so don't treat as stack */
781  *flagp++ = (instr&Ubit) ? 'I' : 'D';
782  *flagp++ = (instr&Pbit) ? 'B' : 'A';
783  }
784  format = "4',%";
785  break;
786 
787  case 10: /* B or BL */
788  case 11:
789  mnemonic = _i_b_bl[(instr&(1<<24))>>24];
790  format = "&";
791  break;
792 
793  case 12: /* STC or LDC */
794  case 13:
795  if (CP_is(1)) { /* copro 1: FPU. This is STF or LDF. */
796  mnemonic = _i_stf_ldf[(instr&Lbit) >> 20];
797  format = "8,/";
798  *flagp++ = "SDEP"[fpn];
799  poss_tt = (eTargetType)(target_FloatS+fpn);
800  }
801  else if (CP_is(2)) { /* copro 2: this is LFM or SFM. */
802  mnemonic = _i_sfm_lfm[(instr&Lbit) >> 20];
803  if (!fpn) fpn=4;
804  if (RN_is(13) && BitsDiffer(23,24)) {
805  if ((instr&255)!=fpn) goto lNonStackLFM; /* r13 and U!=P, so treat as stack */
806  if (BitsDiffer(20,24)) { /* L != P, so FD */
807  *flagp++ = 'F'; *flagp++ = 'D';
808  }
809  else { /* L == P, so EA */
810  *flagp++ = 'E'; *flagp++ = 'A';
811  }
812  format = "8,(,[4]'";
813  }
814  else {
815 lNonStackLFM: /* not r13 or U=P or wrong offset, so don't treat as stack */
816  format = "8,(,/";
817  poss_tt = target_FloatE;
818  }
819  }
820  else { /* some other copro number: STC or LDC. */
821  mnemonic = _i_stc_ldc[(instr&Lbit) >> 20];
822  format = ";,\004,/";
823  if (instr&(1<<22)) *flagp++ = 'L';
824  poss_tt = target_Unknown;
825  }
826  break;
827 
828  case 14: /* CDP or MRC/MCR */
829  if (instr&(1<<4)) { /* MRC/MCR. */
830  if (CP_is(1)) { /* copro 1: FPU. */
831  if ((instr&Lbit) && RD_is(15)) { /* MCR in FPU with Rd=r15: comparison (ugh) */
832  if (!(instr&(1<<23))) goto lfUndefined; /* unused operation */
833  mnemonic = _i_cmf[(instr&(3<<21)) >> 21];
834  format = "9,+";
835  if (instr&((1<<19)+(7<<5)))
836  result.badbits=1; /* size,rmode reseved */
837  }
838  else { /* normal FPU MCR/MRC */
839  t_value op20 = instr&(15<<20);
840  if (op20>=6<<20) goto lgUndefined;
841  mnemonic = _i_flt[op20>>20];
842  if (op20==0) { /* FLT instruction */
843  format = "9,3";
844  { char c = "SDE*"[((instr>>7)&1) + ((instr>>18)&2)];
845  if (c=='*') goto lhUndefined; else *flagp++=c;
846  }
847  if (instr&15) result.oddbits=1; /* Fm and const flag unused */
848  }
849  else { /* not FLT instruction */
850  if (instr&((1<<7)+(1<<19)))
851  result.badbits=1; /* size bits reserved */
852  if (op20==1<<20) { /* FIX instruction */
853  format = "3,+";
854  if (opts->flags&disopt_FIXS)
855  *flagp++ = "SDEP"[((instr>>7)&1) + ((instr>>18)&2)];
856  *flagp++ = "\0PMZ"[(instr&(3<<5))>>5];
857  if (instr&(7<<15)) result.oddbits=1; /* Fn unused */
858  if (instr&(1<<3)) result.badbits=1; /* no immediate consts */
859  }
860  else { /* neither FLT nor FIX */
861  format = "3";
862  if (instr&(3<<5)) result.badbits=1; /* rmode reserved */
863  if (instr&(15+(7<<15))) result.oddbits=1; /* iFm, Fn unused */
864  }
865  }
866  }
867  }
868  else { /* some other copro number. Not FPU. */
869  mnemonic = _i_mcr_mrc[(instr&Lbit)>>20];
870  format = ";,:,3,\005,\001-";
871  }
872  }
873  else { /* CDP. */
874  if (CP_is(1)) { /* copro 1: FPU. */
875  mnemonic = _i_copro[
876  ((instr&(15<<20)) >> 20) /* opcode -> bits 5432 */
877  + ((instr&(1<<15)) >> 11)]; /* monadicP -> bit 6 */
878  format = (instr&(1<<15)) ? "8,+" : "8,9,+";
879  *flagp++ = "SDE*"[((instr>>7)&1) + ((instr>>18)&2)];
880  *flagp++ = "\0PMZ"[(instr&(3<<5))>>5]; /* foregoing relies on this being the last flag! */
881  if (*mnemonic=='*' || *flagchars=='*') goto liUndefined;
882  }
883  else { /* some other copro number. Not FPU. */
884  mnemonic = "CDP";
885  format = ";,),\004,\005,\001-";
886  }
887  }
888  break;
889  case 15: /* SWI */
890  // not used in Canon firmware, treat as data
891  /*
892  mnemonic = "SWI";
893  format = "$";
894  break;
895  */
896  goto lUndefined;
897 
898 
899 /* Nasty hack: this is code that won't be reached in the normal
900  * course of events, and after the last case of the switch is a
901  * convenient place for it.
902  */
903 laUndefined:
904  strcpy(result.text, "Undefined instruction a"); goto lUndefined ;
905 lbUndefined:
906  strcpy(result.text, "Undefined instruction b"); goto lUndefined ;
907 lcUndefined:
908  strcpy(result.text, "Undefined instruction c"); goto lUndefined ;
909 ldUndefined:
910  strcpy(result.text, "Undefined instruction d"); goto lUndefined ;
911 leUndefined:
912  strcpy(result.text, "Undefined instruction e"); goto lUndefined ;
913 lfUndefined:
914  strcpy(result.text, "Undefined instruction f"); goto lUndefined ;
915 lgUndefined:
916  strcpy(result.text, "Undefined instruction g"); goto lUndefined ;
917 lhUndefined:
918  strcpy(result.text, "Undefined instruction h"); goto lUndefined ;
919 liUndefined:
920  strcpy(result.text, "Undefined instruction i"); goto lUndefined ;
921 ljUndefined:
922  strcpy(result.text, "Undefined instruction j"); goto lUndefined ;
923 lkUndefined:
924  strcpy(result.text, "Undefined instruction k"); goto lUndefined ;
925 llUndefined:
926  strcpy(result.text, "Undefined instruction l"); goto lUndefined ;
927 lUndefined:
928  // treat every undefined instruction as data
929  /*
930  result.undefined = 1;
931  result.instr = instr ;
932  return &result;
933  */
934  result.badbits = 1; // cause 'erroneous instructions' check below to convert this to data
935  break;
936  }
937 
938  if (result.oddbits || result.badbits) { // treat erroneous instructions as data
939  result.instr = instr ;
940  mnemonic = ".long";
941  format = "=";
942  instr = 14 << 28; // no condition code please, see below
943  result.oddbits = result.badbits = 0; // no need for error display
944  result.text[0] = flagchars[0] = 0;
945  }
946 
947  *flagp=0;
948 
949  /* PHASE 2. Produce string. */
950 
951  { char * op = result.text;
952 
953  /* 2a. Mnemonic. */
954 
955  op = append(op,mnemonic);
956 
957  /* 2b. Condition code. */
958 
959  {
960  t_value cond = instr>>28;
961  if (cond!=14) {
962  const char * ip = _i_cond[cond];
963  *op++ = *ip++;
964  *op++ = *ip;
965  }
966  }
967 
968  /* 2c. Flags. */
969 
970  { const char * ip = flagchars;
971  while (*ip) *op++ = *ip++;
972  }
973 
974  /* 2d. A tab character. */
975 
976  do {
977  *op++ = ' ';
978  *op = 0 ;
979  } while ( strlen( result.text ) < 8 ) ;
980 
981  /* 2e. Other stuff, determined by format string. */
982 
983  { const char * ip = format;
984  char c;
985 
986  char * * regnames = opts->regnames;
987  t_value oflags = opts->flags;
988 
989  while ((c=*ip++) != 0) {
990  switch(c) {
991  case '=':
992  if (((unsigned long)result.instr > (unsigned long)addr) && ((unsigned long)result.instr < (unsigned long)addr+0x1000)) { // looks like a jumptable
993  result.addrstart = op;
994  op = sub_hex8(fw, op, result.instr);
995  }
996  else {
997  op = yhex8(fw, op, result.instr);
998  }
999  break;
1000  case '$':
1001  result.is_SWI = 1;
1002  result.swinum = instr&0x00FFFFFF;
1003  result.addrstart = op;
1004  if (oflags&disopt_SWInames) {
1005  swiname(result.swinum, op, 128-(op-result.text));
1006  op += strlen(op);
1007  }
1008  else
1009  op += sprintf(op, "&%X", result.swinum);
1010  break;
1011  case '%':
1012  *op++='{';
1013  { t_value w = instr&0xFFFF;
1014  int i=0;
1015  while (w) {
1016  int j;
1017  while (!(w&(1ul<<i))) ++i;
1018  for (j=i+1; w&(1ul<<j); ++j) ;
1019  --j;
1020  /* registers [i..j] */
1021  op = append(op, regnames[i]);
1022  if (j-i) {
1023  *op++ = (j-i>1) ? '-' : ',';
1024  op = append(op, regnames[j]);
1025  }
1026  i=j; w=(w>>(j+1))<<(j+1);
1027  if (w) *op++=',';
1028  }
1029  }
1030  *op++='}';
1031  if (instr&(1<<22)) *op++='^';
1032  break;
1033  case '&':
1034  // address target = ((addr+8 + ((((int)instr)<<8)>>6)) & 0x03FFFFFC) | ( addr&0xFC000000) ;
1035  { t_address target = ((t_address) addr ) + 8 + ((t_address) ((((int)instr)<<8) >>6 )) ;
1036  result.addrstart = op;
1037  op = sub_hex8(fw, op, target);
1038  result.target_type = target_Code;
1039  result.target = target;
1040  }
1041  break;
1042  case '\'':
1043 lPling:
1044  if (instr&Wbit) *op++='!';
1045  break;
1046  case '(':
1047  *op++ = (char)('0'+fpn);
1048  break;
1049  case ')':
1050  { t_value w = (instr>>20)&15;
1051  if (w>=10) { *op++='1'; *op++=(char)('0'-10+w); }
1052  else *op++=(char)(w+'0');
1053  }
1054  break;
1055 
1056  case '*':
1057  case '.':
1058  if (instr&Ibit) {
1059  /* immediate constant */
1060  t_value imm8 = (instr&255);
1061  t_value rot = (instr>>7)&30;
1062  //if (rot && !(imm8&3) && c=='*') {
1063  // /* Funny immediate const. Guaranteed not '.', btw */
1064  // *op++='#'; // *op++='&';
1065  // *op++='0'; // added in 2.04 to indicate this is a hex value
1066  // *op++='x'; // ditto
1067  // *op++="0123456789ABCDEF"[imm8>>4];
1068  // *op++="0123456789ABCDEF"[imm8&15];
1069  // *op++=',';
1070  // op = num(op, rot, 10);
1071  //}
1072  //else {
1073  imm8 = (imm8>>rot) | (imm8<<(32-rot));
1074  if (c=='*') {
1075  *op++='#';
1076  if (imm8>256 && ((imm8&(imm8-1))==0)) {
1077  /* only one bit set, and that later than bit 8.
1078  * Represent as 1<<... .
1079  */
1080  //op = append(op,"1<<");
1081  { int n=0;
1082  while (!(imm8&15)) { n+=4; imm8=imm8>>4; }
1083  /* Now imm8 is 1, 2, 4 or 8. */
1084  n += (0x30002010 >> 4*(imm8-1))&15;
1085  n= 1<<n ;
1086  op = yhex8(fw, op, n);
1087  }
1088 
1089  }
1090  else {
1091  if (((int)imm8)<0 && ((int)imm8)>-100) {
1092  *op++='-'; imm8=-imm8;
1093  }
1094  op = num(op, imm8, 10);
1095  }
1096  }
1097  else {
1098  t_address a = addr+8;
1099  if (instr&(1<<22)) a-=imm8; else a+=imm8;
1100  result.addrstart=op;
1101  op = xhex8(fw, op, a);
1102  result.target=a; result.target_type=target_Unknown;
1103  }
1104  //}
1105  }
1106  else {
1107  /* rotated register */
1108  const char * rot = _i_lsl_lsr[(instr&(3<<5)) >> 5];
1109  op = append(op, regnames[instr&15]);
1110  if (instr&(1<<4)) {
1111  /* register rotation */
1112  if (instr&(1<<7)) goto ljUndefined;
1113  *op++=','; if (oflags&disopt_CommaSpace) *op++=' ';
1114  op = append(op,rot); *op++=' ';
1115  op = append(op,regnames[(instr&(15<<8))>>8]);
1116  }
1117  else {
1118  /* constant rotation */
1119  t_value n = instr&(31<<7);
1120  if (!n) {
1121  if (!(instr&(3<<5))) break;
1122  else if ((instr&(3<<5))==(3<<5)) {
1123  op = append(op, ",RRX");
1124  break;
1125  }
1126  else n=32<<7;
1127  }
1128  *op++ = ','; if (oflags&disopt_CommaSpace) *op++=' ';
1129  op = num(append(append(op,rot),"#"),n>>7,32);
1130  }
1131  }
1132  break;
1133  case '+':
1134  if (instr&(1<<3)) {
1135  t_value w = instr&7;
1136  *op++='#';
1137  if (w<6) *op++=(char)('0'+w);
1138  else op = append(op, w==6 ? "0.5" : "10");
1139  }
1140  else {
1141  *op++='f';
1142  *op++=(char)('0'+(instr&7));
1143  }
1144  break;
1145  case ',':
1146  *op++=',';
1147  if (oflags&disopt_CommaSpace) *op++=' ';
1148  break;
1149  case '-':
1150  { t_value w = instr&(7<<5);
1151  if (w) {
1152  *op++=',';
1153  if (oflags&disopt_CommaSpace) *op++=' ';
1154  *op++ = (char)('0'+(w>>5));
1155  }
1156  }
1157  break;
1158  case '/':
1159  result.addrstart = op;
1160  *op++='[';
1161 
1162  op = append(op, regnames[(instr&RNbits)>>16]);
1163 
1164  if (!(instr&Pbit)) *op++=']';
1165 
1166  *op++=',';
1167 
1168  if (oflags&disopt_CommaSpace) *op++=' ';
1169 
1170  /* For following, NB that bit 25 is always 0 for LDC, SFM etc */
1171  if (instr&Ibit) {
1172  /* shifted offset */
1173  if (!(instr&Ubit)) *op++='-';
1174  /* We're going to transfer to '*', basically. The stupid
1175  * thing is that the meaning of bit 25 is reversed there;
1176  * I don't know why the designers of the ARM did that.
1177  */
1178  instr ^= Ibit;
1179  if (instr&(1<<4)) {
1180 
1181  if (is_v4 && !(instr&(15<<8))) {
1182  ip = (instr&Pbit) ? "0]" : "0";
1183  break;
1184  }
1185  }
1186  /* Need a ] iff it was pre-indexed; and an optional ! iff
1187  * it's pre-indexed *or* a copro instruction,
1188  * except that FPU operations don't need the !. Bletch.
1189  */
1190  if (instr&Pbit) ip="*]'";
1191  else if (instr&(1<<27)) {
1192  if (CP_is(1) || CP_is(2)) {
1193  if (!(instr&Wbit)) goto lkUndefined;
1194  ip="*";
1195  }
1196  else ip="*'";
1197  }
1198  else ip="*";
1199  }
1200  else {
1201  /* immediate offset */
1202  t_value offset;
1203  if (instr&(1<<27)) { /* LDF or LFM or similar */
1204  offset = (instr&255)<<2;
1205  }
1206 
1207  else if (is_v4) offset = (instr&15) + ((instr&(15<<8))>>4);
1208  else { /* LDR or STR */
1209  offset = instr&0xFFF;
1210  }
1211 
1212  if ( offset == 0 ){
1213  if (oflags&disopt_CommaSpace) op-- ;
1214  op-- ; *op++=']'; goto lPling; }
1215 
1216  *op++='#';
1217  if (!(instr&Ubit))
1218  {
1219  if (offset) *op++='-';
1220  else result.oddbits=1;
1221  result.offset = -offset;
1222  }
1223  else result.offset = offset;
1224 
1225  op = num(op, offset, 10);
1226  if (RN_is(15) && (instr&Pbit))
1227  {
1228  /* Immediate, pre-indexed and PC-relative. Set target. */
1229  result.target_type = poss_tt;
1230  result.target = (instr&Ubit) ? addr+8 + offset
1231  : addr+8 - offset;
1232  if (!(instr&Wbit))
1233  {
1234  /* no writeback, either. Use friendly form. */
1235  if (RD_is(15))
1236  op = sub_ahex8(fw, result.addrstart, result.target);
1237  else
1238  op = ahex8(fw, result.addrstart, result.target);
1239  break;
1240  }
1241  }
1242  if (instr&Pbit) { *op++=']'; goto lPling; }
1243  else if (instr&(1<<27)) {
1244  if (CP_is(1) || CP_is(2)) {
1245  if (!(instr&Wbit)) goto llUndefined;
1246  }
1247  else goto lPling;
1248  }
1249  }
1250  break;
1251 
1252  case '0': case '1': case '2': case '3': case '4':
1253  op = append(op, regnames[(instr>>(4*(c-'0')))&15]);
1254  break;
1255  case '5': case '6': case '7': case '8': case '9':
1256  *op++='f';
1257  *op++=(char)('0' + ((instr>>(4*(c-'5')))&7));
1258  break;
1259  case ':':
1260  *op++ = (char)('0' + ((instr>>21)&7));
1261  break;
1262  case ';':
1263  op = reg(op, 'p', instr>>8);
1264  break;
1265  default:
1266  if (c<=5)
1267  op = reg(op, 'c', instr >> (4*(c-1)));
1268  else *op++ = c;
1269  }
1270  }
1271  *op=0;
1272  }
1273  }
1274 
1275  /* DONE! */
1276 
1277  return &result;
1278 }
int l_insert ( struct llist ls,
t_address  address,
t_value  data 
)

Definiert in Zeile 219 der Datei chdk_dasm.c.

220 {
221  struct lnode *node;
222 
223  if( l_search(ls, address)) return -1 ;
224  node = new_node(address, data);
225  if (node == NULL) return 0;
226  node->next = ls->head;
227  ls->head = node;
228  (ls->size)++;
229 
230  return 1;
231 }
void l_remove ( struct llist ls,
t_address  addr 
)

Definiert in Zeile 233 der Datei chdk_dasm.c.

234 {
235  if (ls)
236  {
237  struct lnode *p, *l;
238  l = 0;
239  p = ls->head;
240  while (p)
241  {
242  if (p->address == addr)
243  {
244  if (l)
245  l->next = p->next;
246  else
247  ls->head = p->next;
248  (ls->size)--;
249  return;
250  }
251  l = p;
252  p = p->next;
253  }
254  }
255 }
struct lnode* l_search ( struct llist ls,
t_address  address 
)

Definiert in Zeile 202 der Datei chdk_dasm.c.

202  {
203  struct lnode *node;
204 
205  node = ls->head;
206  while ( node != NULL && node->address != address ) {
207  node = node->next ;
208  }
209  if (node == NULL) {
210  return 0; /* 'item' not found */
211  }
212 
213  return node;
214 }
struct llist* new_list ( )

Definiert in Zeile 150 der Datei chdk_dasm.c.

151 {
152  struct llist *lst;
153 
154  lst = (struct llist *) malloc(sizeof(struct llist));
155  if (lst == NULL) {
156  printf("\n **new_list() : malloc error");
157  return NULL;
158  }
159  lst->head = 0;
160  lst->size = 0;
161 
162  return lst;
163 }
struct lnode* new_node ( t_address  address,
t_value  data 
)

Definiert in Zeile 184 der Datei chdk_dasm.c.

184  {
185  struct lnode *node;
186 
187  node = (struct lnode *) malloc (sizeof (struct lnode));
188  if (node == NULL) {
189  printf("\n **new_node() : malloc error");
190  return NULL;
191  }
192  node->address = address;
193  node->data = data;
194  node->next = 0;
195 
196  return node;
197 }
static char* num ( char *  op,
t_value  w,
t_value  decmax 
)
static

Definiert in Zeile 485 der Datei chdk_dasm.c.

486 {
487  char tmpbuf[16] ;
488  char * tptr ;
489  tptr = tmpbuf ;
490 
491  if (options.flags & disopt_patch_value)
492  {
494  w = patch_new_val;
495  }
496 
497  if ( w<decmax ) sprintf( tptr, "%d", w) ;
498  else
499  {
500  if (w < 16)
501  sprintf( tptr, "0x%X", w);
502  else
503  sprintf( tptr, "0x%X", w);
504  }
505  tptr = tmpbuf ;
506  while(*tptr) *op++ = *tptr++ ;
507  return op;
508 }
static char* print_ascii_str ( firmware fw,
char *  op,
t_value  w 
)
static

Definiert in Zeile 285 der Datei chdk_dasm.c.

286 {
287  if (isASCIIstring(fw, w))
288  {
289  char s[500];
290  char *p = adr2ptr(fw, w);
291  int i = 0;
292  while (*p)
293  {
294  switch (*p)
295  {
296  case '\r':
297  s[i++] = '\\';
298  s[i++] = 'r';
299  break;
300  case '\n':
301  s[i++] = '\\';
302  s[i++] = 'n';
303  break;
304  case '\t':
305  s[i++] = '\\';
306  s[i++] = 't';
307  break;
308  default:
309  s[i++] = *p;
310  break;
311  }
312  p++;
313  }
314  s[i] = 0;
315  op += sprintf(op," /*'%s'*/",s);
316  }
317  return op;
318 }
static char* reg ( char *  op,
char  c,
t_value  n 
)
static

Definiert in Zeile 473 der Datei chdk_dasm.c.

473  {
474  *op++=c;
475  n&=15;
476  if (n>=10) { *op++='1'; n+='0'-10; } else n+='0';
477  *op++=(char)n;
478 
479  return op;
480 }
static void set_patch_old_values ( t_address  w,
char *  nm 
)
static

Definiert in Zeile 268 der Datei chdk_dasm.c.

269 {
270  patch_old_val = w;
271  patch_old_func_name = nm;
272 }
static char* sub_ahex8 ( firmware fw,
char *  op,
t_value  w 
)
static

Definiert in Zeile 459 der Datei chdk_dasm.c.

460 {
461  struct lnode * lptr ;
462  lptr = l_search( dcd_list, w) ; // does this DCD address exist already ?
463 
464  if ( !lptr )
465  l_insert(dcd_list, w, 0) ; // add node if not found - typically on pass 1
466 
467  w = fwval(fw,adr2idx(fw,w));
468  return sub_hex8(fw, op, w);
469 }
static char* sub_hex8 ( firmware fw,
char *  op,
t_value  w 
)
static

Definiert in Zeile 390 der Datei chdk_dasm.c.

391 {
392  if (options.flags & disopt_remember_branches)
393  l_insert(branch_list, w, 0) ;
394 
395  char *s = op;
396 
397  // If call to Branch then follow branch; but only if original branch is in main FW (not code copied to RAM)
398  if (w >= fw->base)
399  w = followBranch(fw,w,1);
401 
403  {
404  set_patch_old_values(w, (o) ? o->nm : 0);
405  op += sprintf(op,"%s",patch_func_name);
406  }
407  else
408  {
409  if (o && !o->is_comment)
410  {
411  op += sprintf(op,"_%s",o->nm);
412  }
413  else
414  {
415  if (( w >= options.start_address )&&( w <= options.end_address ))
416  {
417  op += sprintf(op,"loc_%08X",w);
418  }
419  else
420  {
421  if (options.flags & disopt_comment_lines)
422  op += sprintf(op,"_sub_%08X",w); // prevent sub from appearing in stubs_auto.S
423  else
424  {
425  // Get 1st instruction in sub_XXXXXXXX
426  t_value v = fwval(fw,adr2idx(fw,w));
427  if (v == 0xE12FFF1E) // BX LR?
428  {
429  // Comment out 'nullsub' calls
430  op += sprintf(op,"_sub_%08X",w);
431  options.flags |= disopt_nullsub_call;
432  }
433  else
434  {
435  op += sprintf(op,"sub_%08X",w);
436  if (o && o->is_comment)
437  op += sprintf(op," /*_%s*/",o->nm);
438  }
439  }
440  }
441  if (options.flags & disopt_patch_branch)
442  {
444  op += sprintf(op,"_my");
445  }
446  }
447  }
448 
449  if ((save_patch_ref >= 0) && (options.flags & disopt_patch_branch))
450  {
451  *op = 0;
454  }
455 
456  return op;
457 }
void swiname ( t_value  ,
char *  ,
size_t   
)
void swiname ( __attribute__((unused)) t_value  w,
__attribute__((unused)) char *  s,
__attribute__((unused)) size_t  sz 
)

Definiert in Zeile 1464 der Datei chdk_dasm.c.

1464 { return; }
static char* xhex8 ( firmware fw,
char *  op,
t_value  w 
)
static

Definiert in Zeile 322 der Datei chdk_dasm.c.

323 {
324  char *s = op;
325 
326  if (options.flags & disopt_patch_value)
327  {
329  w = patch_new_val;
330  }
331 
332  if (options.flags & disopt_patch_branch)
333  {
335  if (patch_func_name)
336  op += sprintf(op,"=%s",patch_func_name) ;
337  else
338  {
339  if (options.flags & disopt_comment_lines)
340  op += sprintf(op,"=_sub_%08X_my",w); // prepend '_' to prevent sub from appearing in stubs_auto.S
341  else
342  op += sprintf(op,"=sub_%08X_my",w);
343  }
344  if (save_patch_ref >= 0)
345  {
346  *op = 0;
349  }
350  }
351  else
352  {
353  op += sprintf(op,"=0x%X",w);
354  op = print_ascii_str(fw, op, w);
355  }
356 
357  return op;
358 }
static char* yhex8 ( firmware fw,
char *  op,
t_value  w 
)
static

Definiert in Zeile 376 der Datei chdk_dasm.c.

377 {
378  if (options.flags & disopt_patch_value)
379  {
381  w = patch_new_val;
382  }
383  op += sprintf(op,"0x%X",w) ;
384  op = print_ascii_str(fw, op, w);
385  return op;
386 }

Variablen-Dokumentation

t_address addr

Definiert in Zeile 1281 der Datei chdk_dasm.c.

struct llist* branch_list

Definiert in Zeile 262 der Datei chdk_dasm.c.

struct llist* dcd_list

Definiert in Zeile 261 der Datei chdk_dasm.c.

t_address last_used_addr

Definiert in Zeile 1281 der Datei chdk_dasm.c.

sDisOptions options
Initialisierung:

Definiert in Zeile 96 der Datei chdk_dasm.c.

char* patch_comment

Definiert in Zeile 90 der Datei chdk_dasm.c.

char* patch_func_name

Definiert in Zeile 81 der Datei chdk_dasm.c.

t_address patch_new_val

Definiert in Zeile 84 der Datei chdk_dasm.c.

char* patch_old_func_name

Definiert in Zeile 86 der Datei chdk_dasm.c.

t_address patch_old_val

Definiert in Zeile 85 der Datei chdk_dasm.c.

int patch_ref_address[20]

Definiert in Zeile 87 der Datei chdk_dasm.c.

char patch_ref_name[20][256]

Definiert in Zeile 88 der Datei chdk_dasm.c.

char* reg_names[16]
static
Initialisierung:
= {
"R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", "R12", "SP", "LR", "PC"
}

Definiert in Zeile 92 der Datei chdk_dasm.c.

int save_patch_ref

Definiert in Zeile 89 der Datei chdk_dasm.c.