source: trunk/tools/finsig_dryos.c @ 1769

Revision 1769, 104.0 KB checked in by philmoz, 14 months ago (diff)

Merged revision(s) 1768 from branches/release-1_0:

  • Update to finsig_dryos.c for new DryOS version R50, in SX260HS.
Line 
1#include <stdlib.h>
2#include <stdio.h>
3#include <stdint.h>
4#include <string.h>
5#include <unistd.h>
6#include <time.h>
7#include <stdarg.h>
8
9#include "dancingbits.h"
10
11//------------------------------------------------------------------------------------------------------------
12
13// For testing - define to compare new values against old values in stubs_entry.S.orig
14//#define COMP_OSTUBS     1
15
16// For testing - define to add entries to stubs_entry_2.s where new address does not match old address
17// and not already defined in stubs_entry_2.s (for backwards compatability).
18//#define UPDATE_STUBS2   1
19
20//------------------------------------------------------------------------------------------------------------
21
22// Buffer output into header and body sections
23
24FILE    *out_fp;
25char    out_buf[32*1024] = "";
26int             out_len = 0;
27char    hdr_buf[32*1024] = "";
28int             hdr_len = 0;
29int             out_hdr = 1;
30
31void bprintf(char *fmt, ...)
32{
33        va_list argp;
34        va_start(argp, fmt);
35
36        if (out_hdr)
37                hdr_len += vsprintf(hdr_buf+hdr_len,fmt,argp);
38        else
39                out_len += vsprintf(out_buf+out_len,fmt,argp);
40
41        va_end(argp);
42}
43
44void add_blankline()
45{
46        if (strcmp(hdr_buf+hdr_len-2,"\n\n") != 0)
47        {
48                hdr_buf[hdr_len++] = '\n';
49                hdr_buf[hdr_len] = 0;
50        }
51}
52
53void write_output()
54{
55        add_blankline();
56    if (out_fp)
57    {
58            fprintf(out_fp,"%s",hdr_buf);
59        fprintf(out_fp,"%s",out_buf);
60    }
61}
62
63//------------------------------------------------------------------------------------------------------------
64
65void usage(char *err)
66{
67    bprintf("finsig <primary> <base> <outputfilename> - Error = %s\n",err);
68    write_output();
69    fprintf(stderr,"finsig <primary> <base> <outputfilename> - Error = %s\n",err);
70    exit(1);
71}
72
73//------------------------------------------------------------------------------------------------------------
74
75// Load original stubs_entry.S, stubs_entry_2.s and stubs_min.S to compare results to
76
77typedef struct _osig
78{
79    char        nm[100];
80    uint32_t    val;
81        char            sval[100];
82    int         pct;
83    struct _osig *nxt;
84} osig;
85
86#ifdef  COMP_OSTUBS
87osig *stubs = 0;
88#endif
89osig *stubs2 = 0;
90osig *stubs_min = 0;
91osig *modemap = 0;
92
93void print_stubs(osig *p)
94{
95    while (p)
96    {
97        bprintf("//%s 0x%08x (%s) %d\n",p->nm,p->val,p->sval,p->pct);
98        p = p->nxt;
99    }
100}
101
102int read_line(FILE *f, char *buf)
103{
104    int eof = 0;
105    int len = 0;
106    while (1)
107    {
108        if (fread(buf,1,1,f) != 1) { eof = 1; break; }
109        if ((*buf == 0x0A) || (*buf == 0x0D)) break;
110        len++;
111        buf++;
112    }
113    *buf = 0;
114    return (eof == 0) || (len > 0);
115}
116
117char* get_str(char *s, char *d)
118{
119    while ((*s == ' ') || (*s == '\t') || (*s == ',')) s++;
120    while (*s && (*s != ' ') && (*s != '\t') && (*s != ',') && (*s != ')'))
121    {
122        *d++ = *s++;
123    }
124        while (*s && (*s != ',') && (*s != ')'))
125        {
126                if (*s == '+')
127                {
128                        *d++ = *s++;
129                        while ((*s == ' ') || (*s == '\t') || (*s == ',')) s++;
130                        while (*s && (*s != ' ') && (*s != '\t') && (*s != ',') && (*s != ')'))
131                        {
132                                *d++ = *s++;
133                        }
134                }
135                else s++;
136        }
137    *d = 0;
138    return s;
139}
140
141void add_sig(char *nm, char *val, int pct, osig **hdr)
142{
143    osig *p = malloc(sizeof(osig));
144    strcpy(p->nm, nm);
145        strcpy(p->sval, val);
146    p->pct = pct;
147    p->nxt = *hdr;
148    *hdr = p;
149
150        uint32_t v = 0, n = 0;
151        if ((strncmp(val,"0x",2) == 0) || (strncmp(val,"0X",2) == 0))
152        {
153                while (val)
154                {
155                        sscanf(val,"%x",&n);
156                        v += n;
157                        val = strchr(val,'+');
158                        if (val) val++;
159                }
160        }
161        else
162        {
163                sscanf(val,"%d",&v);
164        }
165
166        p->val = v;
167}
168
169osig* find_sig(osig* p, const char *nm)
170{
171    while (p)
172    {
173        if (strcmp(p->nm, nm) == 0) return p;
174        p = p->nxt;
175    }
176    return 0;
177}
178
179osig* find_sig_val(osig* p, uint32_t val)
180{
181    while (p)
182    {
183        if (p->val == val) return p;
184        p = p->nxt;
185    }
186    return 0;
187}
188
189#ifdef  COMP_OSTUBS
190void load_stubs()
191{
192    FILE *f = fopen("stubs_entry.S.orig", "rb");
193
194    if (f == NULL) return;
195
196    char line[500];
197    char nm[100];
198    char val[12];
199    int pct = 100;
200    char *s;
201
202    while (read_line(f,line))
203    {
204        s = strstr(line, "Best match:");
205        if (s != 0)
206        {
207            strncpy(val,s+12,2); val[2] = 0;
208            pct = atoi(val);
209            continue;
210        }
211       
212        s = strstr(line, "NSTUB(");
213        if (s != 0)
214        {
215            if (strstr(line, "ALT: ") == 0)
216            {
217                s = get_str(s+6,nm);
218                get_str(s,val);
219                add_sig(nm, val, pct, &stubs);
220                pct = 100;
221                continue;
222            }
223        }
224
225        s = strstr(line, "ERROR:");
226        if (s != 0)
227        {
228            get_str(s+6,nm);
229            add_sig(nm, "0", 0, &stubs);
230            continue;
231        }
232    }
233}
234#endif
235
236void load_stubs2()
237{
238    FILE *f = fopen("stubs_entry_2.S", "rb");
239
240    if (f == NULL) return;
241
242    char line[500];
243    char nm[100];
244    char val[12];
245    int pct = 100;
246    char *s;
247
248    while (read_line(f,line))
249    {
250                int off = 7;
251        s = strstr(line, "NHSTUB(");
252                if (s == 0) { off = 6; s = strstr(line, "NSTUB("); }
253                if (s == 0) { off = 4; s = strstr(line, "DEF("); }
254        if (s != 0)
255        {
256            char *c = strstr(line, "//");
257            if ((c == 0) || (c > s))
258            {
259                s = get_str(s+off,nm);
260                get_str(s,val);
261                add_sig(nm, val, pct, &stubs2);
262                pct = 100;
263                continue;
264            }
265        }
266    }
267}
268
269void load_stubs_min()
270{
271    FILE *f = fopen("stubs_min.S", "rb");
272
273    if (f == NULL) return;
274
275    char line[500];
276    char nm[100];
277    char val[12];
278    int pct = 100;
279    char *s;
280
281    while (read_line(f,line))
282    {
283                int off = 7;
284        s = strstr(line, "NHSTUB(");
285                if (s == 0) { off = 4; s = strstr(line, "DEF("); }
286        if (s != 0)
287        {
288            char *c = strstr(line, "//");
289            if ((c == 0) || (c > s))
290            {
291                s = get_str(s+off,nm);
292                get_str(s,val);
293                add_sig(nm, val, pct, &stubs_min);
294                pct = 100;
295                continue;
296            }
297        }
298    }
299}
300
301void load_modemap()
302{
303    FILE *f = fopen("../../shooting.c", "rb");
304
305    if (f == NULL) return;
306
307    char line[500];
308    char nm[100];
309    char val[12];
310        int found_modemap = 0;
311    char *s;
312
313    while (read_line(f,line))
314    {
315                if (found_modemap)
316                {
317                        s = strstr(line, "};");
318                        if (s != 0) return;
319                        s = strstr(line, "MODE_");
320                        if (s != 0)
321                        {
322                                char *c = strstr(line, "//");
323                                if ((c == 0) || (c > s))
324                                {
325                                        s = get_str(s,nm);
326                                        get_str(s,val);
327                                        add_sig(nm, val, 0, &modemap);
328                                }
329                        }
330                }
331                else
332                {
333                        s = strstr(line, "modemap[");
334                        if (s != 0) found_modemap = 1;
335                }
336    }
337}
338
339int min_focus_len = 0;
340int max_focus_len = 0;
341
342void load_platform()
343{
344    FILE *f = fopen("../../platform_camera.h", "rb");
345
346    if (f == NULL) return;
347
348    char line[500];
349    char val[12];
350    char div[12];
351    int v, d;
352    char *s;
353
354    while (read_line(f,line))
355    {
356                s = strstr(line, "CAM_DNG_LENS_INFO");
357                if (s != 0)
358                {
359                        char *c = strstr(line, "//");
360                        if ((c == 0) || (c > s))
361                        {
362                s = strstr(line,"{")+1;
363                                s = get_str(s,val);
364                                s = get_str(s,div);
365                v = atoi(val);
366                d = atoi(div);
367                min_focus_len = (v * 1000) / d;
368                                s = get_str(s,val);
369                                s = get_str(s,div);
370                v = atoi(val);
371                d = atoi(div);
372                max_focus_len = (v * 1000) / d;
373                        }
374                }
375    }
376}
377
378//------------------------------------------------------------------------------------------------------------
379
380// Signature match handling
381
382typedef struct {
383    uint32_t ptr;
384    uint32_t fail;
385    uint32_t success;
386    int k;
387        int sig;
388} Match;
389
390int     disp_sort = 0;
391
392int match_compare1(const Match *p1, const Match *p2)
393{
394    /* NOTE: If a function has *more* matches, it will be prefered, even if it has a lower percent matches */
395    if (p1->success > p2->success)
396        {
397                if (p2->fail != 0)
398                {
399                        return -1;
400                }
401                else
402                {
403                        return 1;
404                }
405    }
406        else if (p1->success < p2->success)
407        {
408                if ((p1->fail == 0) && (p2->fail > 0))
409                {
410                        return -1;
411                }
412                else
413                {
414                        return 1;
415                }
416    }
417        else
418        {
419        if (p1->fail < p2->fail)
420                {
421            return -1;
422        }
423                else if (p1->fail > p2->fail)
424                {
425            return 1;
426        }
427    }
428
429        if (p1->sig < p2->sig)
430        {
431                return -1;
432        }
433        else if (p1->sig > p2->sig)
434        {
435                return 1;
436        }
437       
438    /* scores are equal. prefer lower address */
439
440    if (p1->ptr < p2->ptr)
441        {
442        return -1;
443    }
444        else if (p1->ptr > p2->ptr)
445        {
446        return 1;
447    }
448
449    return 0;
450}
451
452int match_compare(const Match *p1, const Match *p2)
453{
454        int r = match_compare1(p1, p2);
455        if (disp_sort)
456        {
457                bprintf("  // %08x %2d %2d %3d %3d <-> %08x %2d %2d %3d %3d == %d\n",
458                        p1->ptr,p1->success,p1->fail,p1->k,p1->sig,
459                        p2->ptr,p2->success,p2->fail,p2->k,p2->sig,
460                        r);
461        }
462        return r;
463}
464
465#define MAX_MATCHES (8192)
466
467Match matches[MAX_MATCHES];
468int count;
469
470void addMatch(uint32_t fadr, int s, int f, int k, int sig)
471{
472    matches[count].ptr = fadr;
473    matches[count].success = s;
474    matches[count].fail = f;
475    matches[count].k = k;
476        matches[count].sig = sig;
477    count++;
478}
479
480void print_matches()
481{
482    int i;
483    for (i=0; i<count; i++)
484    {
485        bprintf("\t//0x%08x %2d %2d %d %d\n",matches[i].ptr,matches[i].success,matches[i].fail,matches[i].k,matches[i].sig);
486    }
487}
488
489//------------------------------------------------------------------------------------------------------------
490
491// Signature structures generated by gensig2.exe
492
493typedef struct {
494    uint32_t offs;
495    uint32_t value;
496    uint32_t mask;
497} FuncSig;
498
499typedef struct {
500    const char *name;
501    FuncSig *sig;
502        int ver;
503} FuncsList;
504
505//------------------------------------------------------------------------------------------------------------
506
507// Firmware handling
508
509typedef struct bufrange {
510    uint32_t *p;
511    int off;
512    int len;
513    struct bufrange* next;
514} BufRange;
515
516typedef struct {
517    uint32_t        *buf;
518    uint32_t        base;
519    int             size;
520    BufRange        *br, *last;
521        int                         dryos_ver;
522    int             pid;
523    int             maxram;
524        char                cam[100];
525
526    // Alt copy of ROM in RAM (DryOS R50)
527    uint32_t        *buf2;
528    uint32_t        base2;
529    int             size2;
530} firmware;
531
532uint32_t fwval(firmware *fw, int i)
533{
534    if ((i >= 0) && (i < fw->size))
535        return fw->buf[i];
536    if (fw->dryos_ver == 50)
537    {
538        i = ((i * 4) + (fw->base - fw->base2)) / 4;
539        if ((i >= 0) && (i < fw->size2))
540            return fw->buf2[i];
541    }
542    fprintf(stderr,"Invalid firmware offset %d.\n",i);
543    bprintf("\nInvalid firmware offset %d. Possible corrupt firmware or incorrect start address.\n",i);
544    write_output();
545    exit(1);
546}
547
548void addBufRange(firmware *fw, int o, int l)
549{
550    BufRange *n = malloc(sizeof(BufRange));
551    n->p = &fw->buf[o];
552    n->off = o;
553    n->len = l;
554    n->next = 0;
555    if (fw->br == 0)
556    {
557        fw->br = n;
558    }
559    else
560    {
561        fw->last->next = n;
562    }
563    fw->last = n;
564}
565
566int find_str(firmware *fw, char *str)
567{
568    int nlen = strlen(str);
569    uint32_t nm0 = *((uint32_t*)str);
570        uint32_t *p;
571        int j;
572
573    for (p = fw->buf, j = 0; j < fw->size - nlen/4; j++, p++)
574    {
575        if ((nm0 == *p) && (memcmp(p+1,str+4,nlen-4) == 0))
576        {
577                        return j;
578                }
579        }
580       
581        return -1;
582}
583
584void findRanges(firmware *fw)
585{
586    int i, j, k;
587
588    // Find all the valid ranges for checking (skips over large blocks of 0xFFFFFFFF)
589    fw->br = 0; fw->last = 0;
590    k = -1; j = 0;
591    for (i = 0; i < fw->size; i++)
592    {
593        if (fw->buf[i] == 0xFFFFFFFF)   // Possible start of block to skip
594        {
595            if (k == -1)            // Mark start of possible skip block
596            {
597                k = i;
598            }
599        }
600        else                        // Found end of block ?
601        {
602            if (k != -1)
603            {
604                if (i - k > 32)     // If block more than 32 words then we want to skip it
605                {
606                    if (k - j > 8)
607                    {
608                        // Add a range record for the previous valid range (ignore short ranges)
609                        addBufRange(fw,j,k - j);
610                    }
611                    j = i;          // Reset valid range start to current position
612                }
613                k = -1;             // Reset marker for skip block
614            }
615        }
616    }
617    // Add range for last valid block
618    if (k != -1)   
619    {
620        if (k - j > 8)
621        {
622            addBufRange(fw,j,k - j);
623        }
624    }
625    else
626    {
627        if (i - j > 8)
628        {
629            addBufRange(fw,j,i - j);
630        }
631    }
632}
633
634uint32_t idx2adr(firmware *fw, int idx)
635{
636    return fw->base + (idx << 2);
637}
638
639uint32_t adr2idx(firmware *fw, int adr)
640{
641    return (adr - fw->base) >> 2;
642}
643
644uint32_t ptr2idx(firmware *fw, int idx)
645{
646    return (fwval(fw,idx) - fw->base) >> 2;
647}
648
649int idxFollowBranch(firmware *fw, int fidx, int offset)
650{
651    if (offset)
652    {
653                uint32_t msk = ~(offset & 0xFF000000);
654        fidx += ((offset & 0x00FFFFFF) - 1);
655        uint32_t inst = fwval(fw,fidx);
656        if ((inst & (0xFF000000&msk)) == (0xEA000000&msk))    // Branch (B or BL depending on msk)
657        {
658            int o = inst & 0x00FFFFFF;
659            if (o & 0x00800000) o |= 0xFF000000;
660            fidx = fidx + o + 2;
661        }
662    }
663    return fidx;
664}
665
666uint32_t followBranch(firmware *fw, uint32_t fadr, int offset)
667{
668    if (offset)
669    {
670                uint32_t msk = ~(offset & 0xFF000000);
671        uint32_t fidx = adr2idx(fw,fadr);  // function index
672        fidx += ((offset & 0x00FFFFFF) - 1);
673        uint32_t inst = fwval(fw,fidx);
674        if ((inst & (0xFF000000&msk)) == (0xEA000000&msk))    // Branch (B or BL depending on msk)
675        {
676            int o = inst & 0x00FFFFFF;
677            if (o & 0x00800000) o |= 0xFF000000;
678            fadr = idx2adr(fw,fidx+o+2);
679        }
680    }
681    return fadr;
682}
683
684uint32_t followBranch2(firmware *fw, uint32_t fadr, int offset)
685{
686        fadr = followBranch(fw, fadr, offset);
687        if ((offset & 0x00FFFFFF) == 1)
688                fadr = followBranch(fw, fadr, offset);
689        return fadr;
690}
691
692uint32_t ADR2adr(firmware *fw, int offset)  // decode ADR instruction at offset and return firmware address pointed to
693{
694    uint32_t inst = fwval(fw,offset);
695    int rot = 32 - ((inst & 0xF00) >> 7);
696    int offst = (inst & 0xFF) <<rot;
697    uint32_t fadr = 0;
698    switch (inst & 0x01E00000)
699    {
700    case 0x00400000:    // SUB
701        fadr = idx2adr(fw,offset+2)-offst;
702        break;
703    case 0x00800000:    // ADD
704        fadr = idx2adr(fw,offset+2)+offst;
705        break;
706    case 0x01A00000:    // MOV
707        //fprintf(stderr,"***** ADR2adr MOV\n");
708        break;
709    case 0x01E00000:    // MVN
710        //fprintf(stderr,"***** ADR2adr MVN\n");
711        break;
712    }
713    return fadr;
714}
715
716uint32_t ALUop2(firmware *fw, int offset)  // decode operand2 from ALU inst (not complete!)
717{
718    uint32_t inst = fwval(fw,offset);
719    int rot = 32 - ((inst & 0xF00) >> 7);
720    int offst = (inst & 0xFF) <<rot;
721    uint32_t fadr = 0;
722    switch (inst & 0x03E00000)
723    {
724    case 0x02400000:    // SUB Immed
725    case 0x02800000:    // ADD Immed
726    case 0x03A00000:    // MOV Immed
727    case 0x03C00000:    // BIC Immed
728                fadr = offst;
729        break;
730    }
731    return fadr;
732}
733
734uint32_t LDR2adr(firmware *fw, int offset)  // decode LDR instruction at offset and return firmware address pointed to
735{
736    uint32_t inst = fwval(fw,offset);
737    int offst = (inst & 0xFFF);
738    uint32_t fadr = (inst & 0x00800000)?idx2adr(fw,offset+2)+offst:idx2adr(fw,offset+2)-offst;
739    return fadr;
740}
741
742uint32_t LDR2idx(firmware *fw, int offset)  // decode LDR instruction at offset and return firmware buffer index of the new address
743{
744        return adr2idx(fw,LDR2adr(fw,offset));
745}
746
747uint32_t LDR2val(firmware *fw, int offset)  // decode LDR instruction at offset and return firmware value stored at the address
748{
749        return fwval(fw,adr2idx(fw,LDR2adr(fw,offset)));
750}
751
752int isLDR_PC(firmware *fw, int offset)
753{
754        return ((fwval(fw,offset) & 0xFE1F0000) == 0xE41F0000);
755}
756
757int isLDR_PC_cond(firmware *fw, int offset)
758{
759        return ((fwval(fw,offset) & 0x0E1F0000) == 0x041F0000);
760}
761
762int isADR_PC(firmware *fw, int offset)
763{
764        return ((fwval(fw,offset) & 0xFE0F0000) == 0xE20F0000);
765}
766
767int isADR_PC_cond(firmware *fw, int offset)
768{
769        return ((fwval(fw,offset) & 0x0E0F0000) == 0x020F0000);
770}
771
772int isSTR_PC(firmware *fw, int offset)
773{
774        return ((fwval(fw,offset) & 0xFE1F0000) == 0xE40F0000);
775}
776
777int isLDR(firmware *fw, int offset)
778{
779        return ((fwval(fw,offset) & 0xFE100000) == 0xE4100000);
780}
781
782int isSTR(firmware *fw, int offset)
783{
784        return ((fwval(fw,offset) & 0xFE100000) == 0xE4000000);
785}
786
787int isBL(firmware *fw, int offset)
788{
789        return ((fwval(fw,offset) & 0xFF000000) == 0xEB000000); // BL
790}
791
792int isB(firmware *fw, int offset)
793{
794        return ((fwval(fw,offset) & 0xFF000000) == 0xEA000000); // B
795}
796
797void load_firmware(firmware *fw, char *filename, char *base_addr)
798{
799    FILE *f = fopen(filename, "rb");
800
801    if (f == NULL)
802        {
803                fprintf(stderr,"Error opening %s\n",filename);
804        usage("firmware open");
805        }
806
807    fw->base = strtoul(base_addr, NULL, 0);
808
809    fseek(f,0,SEEK_END);
810    fw->size = (ftell(f)+3)/4;
811    fseek(f,0,SEEK_SET);
812
813    // Max sig size if 32, add extra space at end of buffer and fill with 0xFFFFFFFF
814    // Allows sig matching past end of firmware without checking each time in the inner loop
815    fw->buf = malloc((fw->size+32)*4);
816    fread(fw->buf, 4, fw->size, f);
817    fclose(f);
818       
819    memset(&fw->buf[fw->size],0xff,32*4);
820
821        bprintf("// Camera info:\n");
822       
823        // Get DRYOS version
824        fw->dryos_ver = 0;
825        int k = find_str(fw, "DRYOS version 2.3, release #");
826        if (k == -1)
827        {
828                bprintf("//   Can't find DRYOS version !!!\n\n");
829        }
830        else
831        {
832                fw->dryos_ver = atoi(((char*)&fw->buf[k])+28);
833        if (fw->dryos_ver > 50)
834                bprintf("//   DRYOS R%d (%s) *** New DRYOS Version - please update finsig_dryos.c ***\n",fw->dryos_ver,(char*)&fw->buf[k]);
835        else
836                bprintf("//   DRYOS R%d (%s)\n",fw->dryos_ver,(char*)&fw->buf[k]);
837        }
838   
839        // Get firmware version info
840        k = find_str(fw, "Firmware Ver ");
841        if (k == -1)
842        {
843                bprintf("//   Can't find firmware version !!!\n\n");
844        }
845        else
846        {
847                bprintf("//   %s",(char*)&fw->buf[k]);
848                bprintf("\n");
849        }
850
851        // Get camera name & platformid     ***** UPDATE for new DryOS version *****
852        int fsize = -((int)fw->base)/4;
853        int cam_idx = 0;
854    int pid_idx = 0;
855        switch (fw->dryos_ver)
856        {
857        case 20:
858        case 23:
859        case 31:
860        case 39:
861        cam_idx = (0xFFFE0110 - fw->base) / 4;
862        pid_idx = (0xFFFE0130 - fw->base) / 4;
863        break;
864        case 43:
865        case 45:
866        cam_idx = (0xFFFE00D0 - fw->base) / 4;
867        pid_idx = (0xFFFE0130 - fw->base) / 4;
868        break;
869        case 47:
870        cam_idx = (((fw->base==0xFF000000)?0xFFF40170:0xFFFE0170) - fw->base) / 4;
871        pid_idx = (((fw->base==0xFF000000)?0xFFF40040:0xFFFE0040) - fw->base) / 4;
872        break;
873        case 49:
874        case 50:
875        cam_idx = (((fw->base==0xFF000000)?0xFFF40190:0xFFFE0170) - fw->base) / 4;
876        pid_idx = (((fw->base==0xFF000000)?0xFFF40040:0xFFFE0040) - fw->base) / 4;
877        if ((cam_idx < fw->size) && (strncmp((char*)&fw->buf[cam_idx],"Canon ",6) != 0))
878            cam_idx = (((fw->base==0xFF000000)?0xFFF40170:0xFFFE0170) - fw->base) / 4;
879        break;
880        }
881
882    if (fsize > (fw->size + 256))
883        {
884                bprintf("//   Possible corrupt firmware dump - file size to small for start address 0x%08x\n",fw->base);
885                bprintf("//     file size = %.2fMB, should be %.2fMB\n", ((double)fw->size*4.0)/(1024.0*1024.0),((double)fsize*4.0)/(1024.0*1024.0));
886        }
887       
888        strcpy(fw->cam,"Unknown");
889        if ((cam_idx < fw->size) && (strncmp((char*)&fw->buf[cam_idx],"Canon ",6) == 0))
890        {
891                strcpy(fw->cam,(char*)&fw->buf[cam_idx]);
892                bprintf("//   %s\n",fw->cam);
893        }
894        else
895        {
896                bprintf("//   Could not find Camera name - possible corrupt firmware dump\n");
897        }
898
899        bprintf("\n// Values for makefile.inc\n");
900
901    if ((pid_idx > 0) && (pid_idx < fw->size))
902    {
903        fw->pid = fw->buf[pid_idx] & 0xFFFF;
904                bprintf("//   PLATFORMID = %d (0x%04x) // Found @ 0x%08x\n",fw->pid,fw->pid,idx2adr(fw,pid_idx));
905    }
906    else fw->pid = 0;
907
908    // Calc MAXRAMADDR
909    if (((fw->buf[0x10] & 0xFFFFFF00) == 0xE3A00000) && (fw->buf[0x11] == 0xEE060F12))
910    {
911        fw->maxram = (1 << (((fw->buf[0x10] & 0x3E) >> 1) + 1)) - 1;
912    }
913    else if (((fw->buf[0x14] & 0xFFFFFF00) == 0xE3A00000) && (fw->buf[0x15] == 0xEE060F12))
914    {
915        fw->maxram = (1 << (((fw->buf[0x14] & 0x3E) >> 1) + 1)) - 1;
916    }
917    else fw->maxram = 0;
918
919    if (fw->maxram != 0)
920                bprintf("//   MAXRAMADDR = 0x%08x\n",fw->maxram);
921
922    uint32_t ofst = adr2idx(fw,0xFFFF0000);    // Offset of area to find dancing bits
923    if ((ofst < fw->size) && isB(fw,ofst) && isLDR_PC(fw,ofst+1))
924    {
925        // Get KEYSYS value
926        ofst = adr2idx(fw,LDR2val(fw,ofst+1));     // Address of firmware encryption key
927        if (ofst < fw->size)
928        {
929            char *ksys = "? Not found, possible new firmware encryption key.";
930            switch (fw->buf[ofst])
931            {
932            case 0x70726964:    ksys = "d3   "; break;
933            case 0x646C726F:    ksys = "d3enc"; break;
934            case 0x774D450B:    ksys = "d4   "; break;
935            case 0x80751A95:    ksys = "d4a  "; break;
936            case 0x76894368:    ksys = "d4b  "; break;
937            case 0x50838EF7:    ksys = "d4c  "; break;
938            }
939            bprintf("//   KEYSYS = %s              // Found @ 0x%08x\n",ksys,idx2adr(fw,ofst));
940        }
941
942        // Get NEED_ENCODED_DISKBOOT value
943        ofst = ofst + 4; // Address of dancing bits data (try after firmware key)
944        if (ofst < fw->size)
945        {
946            int fnd = 0, i, j;
947            for (i=0; i<VITALY && !fnd; i++)
948            {
949                fnd = i+1;
950                for (j=0; j<8 && fnd; j++)
951                {
952                    if ((fw->buf[ofst+j] & 0xFF) != _chr_[i][j])
953                    {
954                        fnd = 0;
955                    }
956                }
957            }
958            if (!fnd)
959            {
960                // Try before firmware key
961                ofst = ofst - 12;
962                for (i=0; i<VITALY && !fnd; i++)
963                {
964                    fnd = i+1;
965                    for (j=0; j<8 && fnd; j++)
966                    {
967                        if ((fw->buf[ofst+j] & 0xFF) != _chr_[i][j])
968                        {
969                            fnd = 0;
970                        }
971                    }
972                }
973            }
974            if (fnd)
975            {
976                        bprintf("//   NEED_ENCODED_DISKBOOT = %d   // Found @ 0x%08x\n",fnd,idx2adr(fw,ofst));
977            }
978            else
979            {
980                        bprintf("//   NEED_ENCODED_DISKBOOT = ? Not found, possible new 'dancing bits' entry needed. // Found @ 0x%08x\n",idx2adr(fw,ofst));
981            }
982        }
983    }
984       
985    // DryOS R50 copies a block of ROM to RAM and then uses that copy
986    // Need to allow for this in finding addresses
987    // Seen on SX260HS
988    if (fw->dryos_ver == 50)
989    {
990        fw->buf2 = 0;
991        fw->base2 = 0;
992        fw->size2 = 0;
993       
994        int i;
995        // Try and find ROM address copied, and location copied to
996        for (i=3; i<100; i++)
997        {
998            if (isLDR_PC(fw,i) && isLDR_PC(fw,i+1) && (isLDR_PC(fw,i+2)))
999            {
1000                uint32_t fadr = LDR2val(fw,i);
1001                uint32_t dadr = LDR2val(fw,i+1);
1002                uint32_t eadr = LDR2val(fw,i+2);
1003                if ((fadr > fw->base) && (dadr < fw->base))
1004                {
1005                    fw->buf2 = &fw->buf[adr2idx(fw,fadr)];
1006                    fw->base2 = dadr;
1007                    fw->size2 = (eadr - dadr) / 4;
1008                    bprintf("\n// Note, ROM copied to RAM :- from 0x%08x, to 0x%08x, len %d words.\n",fadr,dadr,(eadr-dadr)/4);
1009                    break;
1010                }
1011            }
1012        }
1013    }
1014
1015        bprintf("\n");
1016}
1017
1018//------------------------------------------------------------------------------------------------------------
1019
1020// Signature matches to save for reference by later signature searches
1021
1022typedef struct {
1023        char            *name;
1024        uint32_t        val;
1025} sig_stuff;
1026
1027sig_stuff saved_sigs[] = {
1028        { "task_PhySw", 0 },
1029        { "kbd_p1_f", 0 },
1030        { "kbd_read_keys", 0 },
1031        { "UpdateMBROnFlash", 0 },
1032        { "MakeSDCardBootable", 0 },
1033        { "CreateJumptable", 0 },
1034        { "strtol", 0 },
1035        { "LockAndRefresh", 0 },
1036        { "StartRecModeMenu", 0 },
1037        { "GetSDProtect", 0 },
1038        { "DispCon_ShowBitmapColorBar", 0 },
1039        { "FreeUncacheableMemory", 0 },
1040        { "GetParameterData", 0 },
1041        { "ResetZoomLens", 0 },
1042        { "ResetFocusLens", 0 },
1043        { "NR_GetDarkSubType", 0 },
1044       
1045        { 0, 0 }
1046};
1047
1048sig_stuff min_ver[] = {
1049        { "CreateJumptable", 10000 },
1050        { "ScreenLock", 39 },
1051        { "ScreenUnlock", 39 },
1052        { "MakeSDCardBootable", 47 },
1053       
1054        { 0, 0 }
1055};
1056
1057sig_stuff max_ver[] = {
1058        { "UpdateMBROnFlash", 45 },
1059       
1060        { 0, 0 }
1061};
1062
1063int find_min_ver(const char *name)
1064{
1065        int i;
1066        for (i=0; min_ver[i].name != 0; i++)
1067        {
1068                if (strcmp(name,min_ver[i].name) == 0)
1069                {
1070                        return min_ver[i].val;
1071                }
1072        }
1073        return 0;
1074}
1075
1076int find_max_ver(const char *name)
1077{
1078        int i;
1079        for (i=0; max_ver[i].name != 0; i++)
1080        {
1081                if (strcmp(name,max_ver[i].name) == 0)
1082                {
1083                        return max_ver[i].val;
1084                }
1085        }
1086        return 99999;
1087}
1088
1089uint32_t find_saved_sig(const char *name)
1090{
1091        int i;
1092        for (i=0; saved_sigs[i].name != 0; i++)
1093        {
1094                if (strcmp(name,saved_sigs[i].name) == 0)
1095                {
1096                        return i;
1097                }
1098        }
1099        return -1;
1100}
1101
1102void save_sig(const char *name, uint32_t val)
1103{
1104        int i = find_saved_sig(name);
1105        if (i >= 0)
1106        {
1107                saved_sigs[i].val = val;
1108        }
1109}
1110
1111uint32_t get_saved_sig(firmware *fw, const char *name)
1112{
1113        int j = find_saved_sig(name);
1114        if (j >= 0)
1115        {
1116                if (saved_sigs[j].val == 0)
1117                {
1118                        int find_func(const char* name);
1119                        int k1 = find_func(name);
1120                        if (k1 >= 0)
1121                        {
1122                                int find_matches(firmware*,int);
1123                                find_matches(fw, k1);
1124                                count = 0;
1125                        }
1126                        else
1127                        {
1128                                void find_str_sig_matches(firmware*,const char*);
1129                                find_str_sig_matches(fw, name);
1130                                count = 0;
1131                        }
1132                }
1133                if (saved_sigs[j].val == 0)
1134                {
1135                        j = -1;
1136                }
1137        }
1138        return j;
1139}
1140
1141//------------------------------------------------------------------------------------------------------------
1142
1143// New string / signature matching structure
1144
1145typedef struct {
1146    int     type;           // 1 = func*, string, 2 = string, ... string*, func*, 3 = ADR Rx, func, ADR Ry, string, BL, ... string
1147    char    *name;
1148    char    *ev_name;
1149    int     offset;
1150        int             dryos20_offset;     // ***** UPDATE for new DryOS version *****
1151        int             dryos23_offset;
1152        int             dryos31_offset;
1153        int             dryos39_offset;
1154        int             dryos43_offset;
1155        int             dryos45_offset;
1156        int             dryos47_offset;
1157        int             dryos49_offset;
1158        int             dryos50_offset;
1159} string_sig;
1160
1161#if defined(PLATFORMOS_dryos)
1162#include "signatures_dryos.h"
1163
1164FuncsList   func_list2[] =
1165{
1166    { "ResetZoomLens", 0, 0 },
1167    { "ResetFocusLens", 0, 0 },
1168    { "NR_GetDarkSubType", 0, 0 },
1169    { 0, 0, 0}
1170};
1171
1172uint32_t log_test[] = {
1173        0x1526E50E, 0x3FDBCB7B, 0
1174};
1175
1176string_sig string_sigs[] = {
1177        { 1, "AllocateMemory", "AllocateMemory", 1 },
1178    { 1, "Close", "Close", 1 },
1179        { 1, "CreateTask", "CreateTask", 1 },
1180        { 1, "DoAFLock", "PT_DoAFLock", 0x01000002 },
1181    { 1, "ExitTask", "ExitTask", 1 },
1182        { 1, "exmem_alloc", "ExMem.AllocCacheable", 4 },
1183    { 1, "Fclose_Fut", "Fclose_Fut", 1 },
1184    { 1, "Feof_Fut", "Feof_Fut", 1 },
1185    { 1, "Fflush_Fut", "Fflush_Fut", 1 },
1186    { 1, "Fgets_Fut", "Fgets_Fut", 1 },
1187    { 1, "Fopen_Fut", "Fopen_Fut", 1 },
1188    { 1, "Fread_Fut", "Fread_Fut", 1 },
1189        { 1, "FreeMemory", "FreeMemory", 1 },
1190    { 1, "Fseek_Fut", "Fseek_Fut", 1 },
1191    { 1, "Fwrite_Fut", "Fwrite_Fut", 1 },
1192        { 1, "GetParameterData", "PTM_RestoreUIProperty", 0xF0000004 },
1193        { 1, "GetPropertyCase", "PT_GetPropertyCaseString", 1 },
1194        { 1, "GetPropertyCase", "PT_GetPropertyCaseInt", 0x0100000F },
1195        { 1, "GetSDProtect", "GetSDProtect", 1 },
1196        { 1, "GetSystemTime", "GetSystemTime", 1 },
1197        { 1, "LEDDrive", "LEDDrive", 1 },
1198    { 1, "LockMainPower", "LockMainPower", 1 },
1199    { 1, "Lseek", "Lseek", 1 },
1200    { 1, "lseek", "Lseek", 1 },
1201    { 1, "memcpy", "memcpy", 1 },
1202    { 1, "memcmp", "memcmp", 1 },
1203    { 1, "memset", "memset", 1 },
1204    { 1, "NewTaskShell", "NewTaskShell", 1 },
1205    { 1, "Open", "Open", 1 },
1206    { 1, "PostLogicalEventToUI", "PostLogicalEventToUI", 1 },
1207    { 1, "PostLogicalEventForNotPowerType", "PostLogicalEventForNotPowerType", 1 },
1208    { 1, "Read", "Read", 1 },
1209    { 1, "read", "Read", 1 },
1210        { 1, "RefreshPhysicalScreen", "RefreshPhysicalScreen", 1 },
1211    { 1, "SetAutoShutdownTime", "SetAutoShutdownTime", 1 },
1212    { 1, "SetCurrentCaptureModeType", "SetCurrentCaptureModeType", 1 },
1213    { 1, "SetLogicalEventActive", "UiEvnt_SetLogicalEventActive", 1 },
1214    { 1, "SetParameterData", "PTM_BackupUIProperty", 1 },
1215        { 1, "SetPropertyCase", "PT_SetPropertyCaseInt", 0x01000003 },
1216        { 1, "SetScriptMode", "SetScriptMode", 1 },
1217    { 1, "SleepTask", "SleepTask", 1 },
1218    { 1, "strcmp", "strcmp", 0 },
1219    { 1, "strcpy", "strcpy", 1 },
1220    { 1, "strlen", "strlen", 1 },
1221    { 1, "strtol", "atol", 3 },
1222    { 1, "TakeSemaphore", "TakeSemaphore", 1 },
1223    { 1, "UIFS_WriteFirmInfoToFile", "UIFS_WriteFirmInfoToFile", 1 },
1224        { 1, "UnlockAF", "PT_UnlockAF", 0x01000002 },
1225    { 1, "UnlockMainPower", "UnlockMainPower", 1 },
1226    { 1, "VbattGet", "VbattGet", 1 },
1227    { 1, "Write", "Write", 1 },
1228    { 1, "write", "Write", 1 },
1229
1230    { 2, "GetBatteryTemperature", "GetBatteryTemperature", 1 },
1231    { 2, "GetCCDTemperature", "GetCCDTemperature", 1 },
1232    { 2, "GetOpticalTemperature", "GetOpticalTemperature", 1 },
1233    { 2, "GetFocusLensSubjectDistance", "GetCurrentTargetDistance", 1 },
1234    { 2, "GetZoomLensCurrentPoint", "GetZoomLensCurrentPoint", 1 },
1235    { 2, "GetZoomLensCurrentPosition", "GetZoomLensCurrentPosition", 1 },
1236    { 2, "MoveFocusLensToDistance", "MoveFocusLensToDistance", 1 },
1237    { 2, "MoveZoomLensWithPoint", "MoveZoomLensWithPoint", 1 },
1238    { 2, "GetCurrentAvValue", "GetCurrentAvValue", 1 },
1239        { 2, "PT_MoveOpticalZoomAt", "PT_MoveOpticalZoomAt", 1 },
1240        { 2, "PT_MoveDigitalZoomToWide", "PT_MoveDigitalZoomToWide", 1 },
1241        { 2, "MoveIrisWithAv", "MoveIrisWithAv", 1},
1242    { 2, "PutInNdFilter", "TurnOnNdFilter", 1 },
1243    { 2, "PutOutNdFilter", "TurnOffNdFilter", 1 },
1244    { 2, "PutInNdFilter", "PutInNdFilter", 1 },
1245    { 2, "PutOutNdFilter", "PutOutNdFilter", 1 },
1246        { 2, "IsStrobeChargeCompleted", "EF.IsChargeFull", 1 },
1247        { 2, "GetPropertyCase", "PT_GetPropertyCaseInt", 0x01000012 },
1248        { 2, "SetPropertyCase", "PT_SetPropertyCaseInt", 0x01000008 },
1249        { 2, "SetPropertyCase", "PT_SetPropertyCaseInt", 0x01000009 },
1250        { 2, "UnlockAF", "PT_UnlockAF", 0x01000002 },
1251        { 2, "DoAFLock", "PT_DoAFLock", 0x01000002 },
1252        { 2, "GetSystemTime", "PT_GetSystemTime", 0x01000003 },
1253        { 2, "PT_PlaySound", "PT_PlaySound", 0x01000005 },
1254        { 2, "StartRecModeMenu", "StartRecModeMenu", 1 },
1255        { 2, "GetSDProtect", "GetSDProtect", 1 },
1256        { 2, "DispCon_ShowBitmapColorBar", "DispCon_ShowBitmapColorBar", 1 },
1257        { 2, "SetAE_ShutterSpeed", "SetAE_ShutterSpeed", 1 },
1258    { 2, "ResetZoomLens", "ResetZoomLens", 1 },
1259    { 2, "ResetFocusLens", "ResetFocusLens", 1 },
1260    { 2, "NR_GetDarkSubType", "NR_GetDarkSubType", 1 },
1261    { 2, "NR_GetDarkSubType", "NRTBL.GetDarkSubType", 1 },
1262       
1263        { 3, "AllocateMemory", "AllocateMemory", 1 },
1264        { 3, "FreeMemory", "FreeMemory", 1 },
1265    { 3, "PostLogicalEventToUI", "PostLogicalEventToUI", 1 },
1266    { 3, "PostLogicalEventForNotPowerType", "PostLogicalEventForNotPowerType", 1 },
1267    { 3, "LockMainPower", "LockMainPower", 1 },
1268    { 3, "UnlockMainPower", "UnlockMainPower", 1 },
1269    { 3, "SetAutoShutdownTime", "SetAutoShutdownTime", 1 },
1270    { 3, "NewTaskShell", "NewTaskShell", 1 },
1271    { 3, "VbattGet", "VbattGet", 1 },
1272        { 3, "LEDDrive", "LEDDrive", 1 },
1273        { 3, "SetPropertyCase", "PT_SetPropertyCaseInt", 0x01000003 },
1274        { 3, "UnlockAF", "PT_UnlockAF", 0x01000002 },
1275        { 3, "DoAFLock", "PT_DoAFLock", 0x01000002 },
1276    { 3, "UIFS_WriteFirmInfoToFile", "UIFS_WriteFirmInfoToFile", 1 },
1277        { 3, "PT_MoveOpticalZoomAt", "PT_MoveOpticalZoomAt", 1 },
1278        { 3, "PT_MoveDigitalZoomToWide", "PT_MoveDigitalZoomToWide", 1 },
1279        { 3, "PT_PlaySound", "PT_PlaySound", 1 },
1280        { 3, "exmem_alloc", "ExMem.AllocCacheable", 4 },
1281        { 3, "GetSDProtect", "GetSDProtect", 1 },
1282
1283    { 4, "TurnOnBackLight", "TurnOnBackLight", 1 },
1284    { 4, "TurnOffBackLight", "TurnOffBackLight", 1 },
1285    { 4, "EnterToCompensationEVF", "SSAPI::EnterToCompensationEVF", 1 },
1286    { 4, "EnterToCompensationEVF", "ExpComp On", 1 },
1287    { 4, "EnterToCompensationEVF", "ExpOn", 1 },
1288    { 4, "ExitFromCompensationEVF", "SSAPI::ExitFromCompensationEVF", 1 },
1289    { 4, "ExitFromCompensationEVF", "ExpComp Off", 1 },
1290    { 4, "ExitFromCompensationEVF", "ExpOff", 1 },
1291    { 4, "PB2Rec", "AC:PB2Rec", 1 },
1292    { 4, "PB2Rec", "AC:PB2Rec", 6 },
1293    { 4, "PB2Rec", "AC:PB2Rec", 11 },
1294    { 4, "Rec2PB", "AC:Rec2PB", 1 },
1295        { 4, "RefreshPhysicalScreen", "ScreenUnLock", 1 },
1296        { 4, "RefreshPhysicalScreen", "ScreenUnLock", 7 },
1297        { 4, "RefreshPhysicalScreen", "ScreenUnLock", 15 },
1298        { 4, "RefreshPhysicalScreen", "Reduce ScreenUnLock", 5 },
1299        { 4, "RefreshPhysicalScreen", "Window:IneffectiveLockPhysicalScreen", 8 },
1300        { 4, "UnsetZoomForMovie", "ZoomCon_UnsetZoomForMovie", 1 },
1301        { 4, "ExpCtrlTool_StopContiAE", "StopContiAE", 9 },
1302        { 4, "ExpCtrlTool_StopContiAE", "StopContiAE", 10 },
1303        { 4, "ExpCtrlTool_StartContiAE", "StartContiAE", 9 },
1304        { 4, "ExpCtrlTool_StartContiAE", "StartContiAE", 10 },
1305
1306    { 5, "UIFS_WriteFirmInfoToFile", "UIFS_WriteFirmInfoToFile", 1 },
1307    { 5, "CreateTask", "CreateTask", 1 },
1308    { 5, "ExitTask", "ExitTask", 1 },
1309    { 5, "SleepTask", "SleepTask", 1 },
1310        //                                                                                                                                       R20   R23   R31   R39   R43   R45   R47   R49   R50
1311        { 5, "UpdateMBROnFlash", "MakeBootDisk", 0x01000003,                              11,   11,   11,   11,   11,   11,    1,    1,    1 },
1312        { 5, "MakeSDCardBootable", "MakeBootDisk", 0x01000003,                             1,    1,    1,    1,    1,    1,    8,    8,    8 },
1313
1314    { 6, "Restart", "Bye", 0 },
1315        { 6, "GetImageFolder", "GetCameraObjectTmpPath ERROR[ID:%lx] [TRY:%lx]\n", 0 },
1316       
1317        { 7, "task_CaptSeq", "CaptSeqTask", 1 },
1318        { 7, "task_ExpDrv", "ExpDrvTask", 1 },
1319        { 7, "task_InitFileModules", "InitFileModules", 1 },
1320        { 7, "task_MovieRecord", "MovieRecord", 1 },
1321        { 7, "task_PhySw", "PhySw", 1 },
1322        { 7, "task_RotaryEncoder", "RotaryEncoder", 1 },
1323        { 7, "task_RotaryEncoder", "RotarySw", 1 },
1324       
1325        { 8, "WriteSDCard", "Mounter.c", 0 },
1326       
1327        //                                                                                                                                       R20   R23   R31   R39   R43   R45   R47   R49   R50
1328        { 9, "kbd_p1_f", "task_PhySw", 0x01000001,                                                         5,    5,    5,    5,    5,    5,    5,    5,    5 },
1329        { 9, "kbd_p2_f", "task_PhySw", 0xf1000001,                                                         7,    7,    7,    7,    7,    7,    7,    7,    7 },
1330        { 9, "kbd_read_keys", "kbd_p1_f", 0x01000001,                                              2,    2,    2,    2,    2,    2,    2,    2,    2 },
1331        { 9, "kbd_p1_f_cont", "kbd_p1_f", 0,                                                               3,    3,    3,    3,    3,    3,    3,    3,    3 },
1332        { 9, "kbd_read_keys_r2", "kbd_read_keys", 0x0100000C },
1333        { 9, "GetKbdState", "kbd_read_keys", 0x01000009 },
1334        { 9, "GetKbdState", "kbd_read_keys", 0x0100000A },
1335        { 9, "strtolx", "strtol", 2 },
1336       
1337        { 10, "task_CaptSeq", "CaptSeqTask", 1 },
1338        { 10, "task_ExpDrv", "ExpDrvTask", 1 },
1339        { 10, "task_InitFileModules", "InitFileModules", 1 },
1340        { 10, "task_MovieRecord", "MovieRecord", 1 },
1341        { 10, "task_PhySw", "PhySw", 1 },
1342        { 10, "task_RotaryEncoder", "RotaryEncoder", 1 },
1343        { 10, "task_RotaryEncoder", "RotarySw", 1 },
1344
1345        //                                                                                                                                       R20   R23   R31   R39   R43   R45   R47   R49   R50
1346        { 11, "DebugAssert", "\nAssert: File %s Line %d\n", 0,                             5,    5,    5,    5,    5,    5,    5,    5,    5 },
1347        { 11, "set_control_event", "Button:0x%08X:%s", 0x01000001,                        14,   14,   14,   14,   14,   14,   14,   14,   14 },
1348        { 11, "set_control_event", "Button:0x%08X:%s", 0x01000001,                        15,   15,   15,   15,   15,   15,   15,   15,   15 },
1349        { 11, "set_control_event", "Button:0x%08X:%s", 0x01000001,                        20,   20,   20,   20,   20,   20,   19,   20,   20 },
1350        { 11, "_log", (char*)log_test, 0x01000001,                                                         1,    1,    1,    1,    1,    1,    1,    1,    1 },
1351       
1352        //                                                                                                                                       R20   R23   R31   R39   R43   R45   R47   R49   R50
1353        { 12, "DeleteFile_Fut", "DeleteFile_Fut", 1,                                            0x38, 0x38, 0x4C, 0x4C, 0x4C, 0x54, 0x54, 0x54, 0x00 },
1354        { 12, "AllocateUncacheableMemory", "AllocateUncacheableMemory", 1,      0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x34, 0x34, 0x34, 0x4C },
1355        { 12, "FreeUncacheableMemory", "FreeUncacheableMemory", 1,                      0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x38, 0x38, 0x50 },
1356        { 12, "free", "free", 1,                                                                                        0x28, 0x28, 0x28, 0x28, 0x28, 0x30, 0x30, 0x30, 0x48 },
1357        { 12, "malloc", "malloc", 0x01000003,                                                           0x24, 0x24, 0x24, 0x24, 0x24, 0x2C, 0x2C, 0x2C, 0x44 },
1358        { 12, "TakeSemaphore", "TakeSemaphore", 1,                                                      0x14, 0x14, 0x14, 0x14, 0x14, 0x1C, 0x1C, 0x1C, 0x1C },
1359        { 12, "GiveSemaphore", "GiveSemaphore", 1,                                                      0x18, 0x18, 0x18, 0x18, 0x18, 0x20, 0x20, 0x20, 0x20 },
1360        { 12, "_log10", "_log10", 0x01000006,                                                      0x278,0x280,0x280,0x284,0x294,0x2FC,0x2FC,0x31C,0x354 },
1361        { 12, "_log10", "_log10", 0x01000006,                                                      0x000,0x278,0x27C,0x000,0x000,0x000,0x000,0x000,0x000 },
1362        { 12, "_log10", "_log10", 0x01000006,                                                      0x000,0x000,0x2C4,0x000,0x000,0x000,0x000,0x000,0x000 },
1363       
1364        { 13, "strftime", "Sunday", 1 },
1365       
1366        { 14, "_pow", "_pow", 0 },
1367       
1368    { 0, 0, 0, 0 }
1369};
1370#else
1371#error Incorrect platform OS - DryOS only.
1372#endif
1373
1374int find_func(const char* name)
1375{
1376        int i;
1377        for (i=0; func_list[i].name != 0; i++)
1378        {
1379                if (strcmp(name, func_list[i].name) == 0)
1380                {
1381                        return i;
1382                }
1383        }
1384        return -1;
1385}
1386
1387int dryos_offset(firmware *fw, string_sig *sig)
1388{
1389        switch (fw->dryos_ver)
1390        {
1391        case 20:        return sig->dryos20_offset;
1392        case 23:        return sig->dryos23_offset;
1393        case 31:        return sig->dryos31_offset;
1394        case 39:        return sig->dryos39_offset;
1395        case 43:        return sig->dryos43_offset;
1396        case 45:        return sig->dryos45_offset;
1397        case 47:        return sig->dryos47_offset;
1398        case 49:        return sig->dryos49_offset;
1399        case 50:        return sig->dryos50_offset;
1400        }
1401        return 0;
1402}
1403       
1404//------------------------------------------------------------------------------------------------------------
1405
1406// Optional functions, if not found no error is written to output
1407
1408char *optional[] = {
1409        "DebugAssert",
1410        "PT_MoveOpticalZoomAt",
1411        "PT_MoveDigitalZoomToWide",
1412        "PT_ChangeZoomSpeed",
1413        "MoveIrisWithAv",
1414        "err_init_task",
1415        "PutInNdFilter",
1416        "PutOutNdFilter",
1417        "GiveSemaphore",
1418        "GetImageFolder",
1419        "UnsetZoomForMovie",
1420        "task_RotaryEncoder",
1421        "task_PhySw",
1422        "MakeSDCardBootable",
1423        "LEDDrive",
1424    "ResetZoomLens",
1425    "ResetFocusLens",
1426    "NR_GetDarkSubType",
1427        0
1428};
1429
1430//------------------------------------------------------------------------------------------------------------
1431
1432// Load optional list of signatures to ignore
1433
1434char* ignore_list[200];
1435int num_ignore = 0;
1436char* ignore_names;
1437
1438void load_ignore_list()
1439{
1440    FILE *f = fopen("../ignore_stubs.txt","r");
1441    if (f != NULL)
1442    {
1443        fseek(f,0,SEEK_END);
1444        int size = ftell(f);
1445        fseek(f,0,SEEK_SET);
1446
1447        ignore_names = malloc(size+1);
1448        fread(ignore_names, 1, size, f);
1449        ignore_names[size] = 0;
1450
1451        int save = 1;
1452        int i;
1453        for (i = 0; i < size; i++)
1454        {
1455            if (save)
1456            {
1457                ignore_list[num_ignore] = &ignore_names[i];
1458                num_ignore++;
1459                save = 0;
1460            }
1461            if (ignore_names[i] == 0x0d) { ignore_names[i] = 0; }
1462            if (ignore_names[i] == 0x0a) { ignore_names[i] = 0; save = 1; }
1463        }
1464
1465        fclose(f);
1466    }
1467}
1468
1469int is_in_list(const char *str, char *list[])
1470{
1471        int i;
1472        for (i=0; list[i] != 0; i++)
1473        {
1474                if (strcmp(str,list[i]) == 0)
1475                {
1476                        return 1;
1477                }
1478        }
1479        return 0;
1480}
1481
1482//------------------------------------------------------------------------------------------------------------
1483
1484// New string / signature matching functions
1485
1486// Sig pattern:
1487//              Function pointer        -       DCD     func
1488//              String                          -       DCB     "func"
1489int find_strsig1(firmware *fw, string_sig *sig, int k)
1490{
1491    int nlen = strlen(sig->ev_name);
1492    uint32_t nm0 = *((uint32_t*)sig->ev_name);
1493        uint32_t *p;
1494        int j;
1495
1496    for (p = fw->buf, j = 0; j < fw->size - nlen/4; j++, p++)
1497    {
1498        if ((nm0 == *p) && (memcmp(p+1,sig->ev_name+4,nlen-3) == 0))
1499        {
1500            uint32_t fadr = fw->buf[j-1];       // function address (*padr)
1501            if (fadr >= fw->base)
1502            {
1503                                if (sig->offset > 1) fadr = followBranch(fw, fadr, 1);
1504                fadr = followBranch2(fw, fadr, sig->offset);
1505                //fprintf(stderr,"%s %08x\n",curr_name,fadr);
1506                addMatch(fadr,32,0,k,101);
1507                return 1;
1508            }
1509        }
1510    }
1511        return 0;
1512}
1513
1514// Sig pattern:
1515//              String pointer          -               DCD     str
1516//              Function pointer        -               DCD     func
1517//                              ...
1518//              String                          -       str     DCB     "func"
1519int find_strsig2(firmware *fw, string_sig *sig, int k)
1520{
1521    int nlen = strlen(sig->ev_name);
1522        int j;
1523       
1524    char *c = (char*)(&fw->buf[0]);
1525    for (j = 0; j < fw->size*4 - nlen; j++, c++)
1526    {
1527        if (strcmp(c,sig->ev_name) == 0)
1528        {
1529            uint32_t sadr = fw->base + j;        // string address
1530            int j1;
1531            uint32_t *p1;
1532            for (p1 = fw->buf, j1 = 0; j1 < fw->size - nlen/4; j1++, p1++)
1533            {
1534                if (*p1 == sadr)                // pointer to string?
1535                {
1536                    uint32_t fadr = fw->buf[j1+1];      // function address (*padr)
1537                    if (fadr >= fw->base)
1538                    {
1539                        uint32_t bfadr = followBranch2(fw, fadr, sig->offset);
1540                                                if ((sig->offset <= 1) || (bfadr != fadr))
1541                                                {
1542                                                        //fprintf(stderr,"%s %08x\n",curr_name,fadr);
1543                                                        addMatch(bfadr,32,0,k,102);
1544                                                        return 1;
1545                                                }
1546                    }
1547                }
1548            }
1549        }
1550    }
1551
1552        return 0;
1553}
1554
1555// Sig pattern:
1556//              Load Func Address       -       ADR     Rx, func
1557//              Load String Address     -       ADR     Rx, "func"
1558//              Branch                          -       BL
1559//                              ...
1560//              String                          -       DCB     "func"
1561int find_strsig3(firmware *fw, string_sig *sig, int k)
1562{
1563    int nlen = strlen(sig->ev_name);
1564        uint32_t nm0 = *((uint32_t*)sig->ev_name);
1565        uint32_t *p;
1566        int j;
1567       
1568        for (p = fw->buf, j = 0; j < fw->size - nlen/4; j++, p++)
1569        {
1570                if ((nm0 == *p) && (memcmp(p+1,sig->ev_name+4,nlen-3) == 0))
1571                {
1572                        uint32_t sadr = idx2adr(fw,j);        // string address
1573                        int j1;
1574                        uint32_t *p1;
1575                        for (p1 = p-3, j1 = j-3; j1 >= 0; j1--, p1--)
1576                        {
1577                                if (((p1[1] & 0xFE0F0000) == 0xE20F0000) && // ADR ?
1578                                        ((p1[2] & 0xFE000000) == 0xEA000000))   // B or BL ?
1579                                {
1580                                        uint32_t padr = ADR2adr(fw,j1+1);
1581                                        if (padr == sadr)
1582                                        {
1583                                                int j2 = j1;
1584                                                int found = 0;
1585                                                if ((p1[0] & 0xFE0F0000) == 0xE20F0000) // ADR ?
1586                                                        found = 1;
1587                                                else
1588                                                {
1589                                                        uint32_t *p2;
1590                                                        for (p2 = p1-2, j2 = j1-2; j2 >= 0 && j2 >= j1-4096; j2--, p2--)
1591                                                        {
1592                                                                if (((p2[0] & 0xFE0F0000) == 0xE20F0000) && // ADR ?
1593                                                                        ((p2[1] & 0xFF000000) == 0xEA000000))   // B
1594                                                                {
1595                                                                        uint32_t fa = idx2adr(fw,j2+1);
1596                                                                        fa = followBranch(fw,fa,1);
1597                                                                        if (adr2idx(fw,fa) == j1+1)
1598                                                                        {
1599                                                                                found = 1;
1600                                                                                break;
1601                                                                        }
1602                                                                }
1603                                                        }
1604                                                }
1605                                                if (found)
1606                                                {
1607                                                        uint32_t fadr = ADR2adr(fw,j2);
1608                                                        if (sig->offset > 1) fadr = followBranch(fw, fadr, 1);
1609                                                        fadr = followBranch2(fw, fadr, sig->offset);
1610                                                        //fprintf(stderr,"%s %08x\n",curr_name,fadr);
1611                                                        addMatch(fadr,32,0,k,103);
1612                                                        return 1;
1613                                                }
1614                                        }
1615                                }
1616                        }
1617                }
1618        }
1619
1620        return 0;
1621}
1622
1623// Sig pattern:
1624//              Save Regs                       -       STMFD
1625//                              ... (ofst)
1626//              Load String Address     -       ADR     Rx, "func"
1627//                              ...
1628//              String                          -       DCB     "func"
1629int find_strsig4(firmware *fw, string_sig *sig, int k)
1630{
1631    int nlen = strlen(sig->ev_name);
1632        uint32_t nm0 = *((uint32_t*)sig->ev_name);
1633        uint32_t *p;
1634        int j;
1635
1636        for (p = fw->buf, j = 0; j < fw->size - nlen/4; j++, p++)
1637        {
1638                if ((nm0 == *p) && (memcmp(p+1,sig->ev_name+4,nlen-3) == 0))
1639                {
1640                        uint32_t sadr = idx2adr(fw,j);        // string address
1641                        int j1;
1642                        uint32_t *p1;
1643                        int ofst = sig->offset;
1644                        for (p1 = p-ofst-1, j1 = j-ofst-1; j1 >= 0; j1--, p1--)
1645                        {
1646                                if (((p1[0] & 0xFFFF0000) == 0xE92D0000) &&     // STMFD
1647                                        ((p1[ofst] & 0xFE0F0000) == 0xE20F0000))        // ADR ?
1648                                {
1649                                        uint32_t padr = ADR2adr(fw,j1+ofst);
1650                                        if (padr == sadr)
1651                                        {
1652                                                uint32_t fadr = idx2adr(fw,j1);
1653                                                //fprintf(stderr,"%s %08x\n",curr_name,fadr);
1654                                                addMatch(fadr,32,0,k,104);
1655                                                return 1;
1656                                        }
1657                                }
1658                        }
1659                }
1660        }
1661 
1662        return 0;
1663}
1664
1665// Sig pattern:
1666//              Load Func Address       -       LDR     Rx, =func
1667//              Load String Address     -       xDR     Rx, "func"  (LDR or ADR)
1668//              Branch                          -       BL
1669//                              ...
1670//              String                          -       DCB     "func"
1671int find_strsig5(firmware *fw, string_sig *sig, int k)
1672{
1673    int nlen = strlen(sig->ev_name);
1674        uint32_t nm0 = *((uint32_t*)sig->ev_name);
1675        uint32_t *p;
1676        int j;
1677
1678        for (p = fw->buf, j = 0; j < fw->size - nlen/4; j++, p++)
1679        {
1680                if ((nm0 == *p) && (memcmp(p+1,sig->ev_name+4,nlen-3) == 0))
1681                {
1682                        uint32_t sadr = idx2adr(fw,j);        // string address
1683                        int j1;
1684                        uint32_t *p1;
1685                        for (p1 = fw->buf, j1 = 0; j1 < fw->size - nlen/4; j1++, p1++)
1686                        {
1687                                if ((((p1[1] & 0xFE0F0000) == 0xE20F0000) || ((p1[1] & 0xFE1F0000) == 0xE41F0000)) && // LDR or ADR ?
1688                                        ((p1[2] & 0xFE000000) == 0xEA000000))   // B or BL ?
1689                                {
1690                                        uint32_t padr;
1691                                        if ((p1[1] & 0xFE1F0000) == 0xE41F0000) // LDR ?
1692                        padr = LDR2val(fw,j1+1);
1693                                        else
1694                        padr = ADR2adr(fw,j1+1);
1695                                        if (padr == sadr)
1696                                        {
1697                                                int j2 = j1;
1698                                                int found = 0;
1699                                                if ((p1[0] & 0xFE1F0000) == 0xE41F0000) // LDR ?
1700                                                        found = 1;
1701                                                else
1702                                                {
1703                                                        uint32_t *p2;
1704                                                        for (p2 = p1-2, j2 = j1-2; j2 >= 0 && j2 >= j1-4096; j2--, p2--)
1705                                                        {
1706                                                                if (((p2[0] & 0xFE1F0000) == 0xE41F0000) && // LDR ?
1707                                                                        ((p2[1] & 0xFF000000) == 0xEA000000))   // B
1708                                                                {
1709                                                                        uint32_t fa = idx2adr(fw,j2+1);
1710                                                                        fa = followBranch(fw,fa,1);
1711                                                                        if (adr2idx(fw,fa) == j1+1)
1712                                                                        {
1713                                                                                found = 1;
1714                                                                                break;
1715                                                                        }
1716                                                                }
1717                                                        }
1718                                                }
1719                                                if (found)
1720                                                {
1721                                                        uint32_t fadr = LDR2val(fw,j2);
1722                                                        if (sig->offset > 1) fadr = followBranch(fw, fadr, 1);
1723                                                        fadr = followBranch2(fw, fadr, sig->offset);
1724                            int ofst = dryos_offset(fw,sig);
1725                            if (ofst != 0)
1726                            {
1727                                uint32_t fadr2 = followBranch(fw, fadr, ofst);
1728                                if (fadr == fadr2) return 0;
1729                                fadr = fadr2;
1730                            }
1731                                                        //fprintf(stderr,"%s %08x\n",curr_name,fadr);
1732                                                        addMatch(fadr,32,0,k,105);
1733                                                        return 1;
1734                                                }
1735                                        }
1736                                }
1737                        }
1738                }
1739        }
1740
1741        return 0;
1742}
1743
1744// Sig pattern:
1745//      Function immediately preceeding string
1746int find_strsig6(firmware *fw, string_sig *sig, int k)
1747{
1748    int nlen = strlen(sig->ev_name);
1749        uint32_t nm0 = *((uint32_t*)sig->ev_name);
1750        uint32_t *p;
1751        int j;
1752       
1753        for (p = fw->buf, j = 0; j < fw->size - nlen/4; j++, p++)
1754        {
1755                if ((nm0 == *p) && (memcmp(p+1,sig->ev_name+4,nlen-3) == 0))
1756                {
1757                        int j1;
1758                        uint32_t *p1;
1759                        for (p1 = p-1, j1 = j-1; j1 >= 0; j1--, p1--)
1760                        {
1761                                if ((p1[0] & 0xFFFFF000) == 0xe92d4000)    // STMFD SP!, {..,LR}
1762                                {
1763                                        uint32_t fadr = idx2adr(fw,j1);
1764                                        //fprintf(stderr,"%s %08x\n",curr_name,fadr);
1765                                        addMatch(fadr,32,0,k,106);
1766                                        return 1;
1767                                }
1768                        }
1769                }
1770        }
1771
1772        return 0;
1773}
1774
1775// Sig pattern:
1776//              Load Func Address       -       ADR     R3, func        - these four may occur in any order ?
1777//              Load String Address     -       ADR     R0, "func"     
1778//              Load value                      -       MOV R2, x               
1779//              Load value                      -       MOV R1, y               
1780//              Branch                          -       BL
1781//                              ...
1782//              String                          -       DCB     "func"
1783int find_strsig7(firmware *fw, string_sig *sig, int k)
1784{
1785    int nlen = strlen(sig->ev_name);
1786        uint32_t nm0 = *((uint32_t*)sig->ev_name);
1787        uint32_t *p;
1788        int j;
1789       
1790        for (p = fw->buf, j = 0; j < fw->size - nlen/4; j++, p++)
1791        {
1792                if ((nm0 == *p) && (memcmp(p+1,sig->ev_name+4,nlen-3) == 0))
1793                {
1794                        uint32_t sadr = idx2adr(fw,j);        // string address
1795                        int j1;
1796                        uint32_t *p1;
1797                        for (p1 = p-5, j1 = j-5; j1 >= 0; j1--, p1--)
1798                        {
1799                                if (((p1[0] & 0xFE000000) == 0xE2000000) && // ADR or MOV
1800                                        ((p1[1] & 0xFE000000) == 0xE2000000) && // ADR or MOV
1801                                        ((p1[2] & 0xFE000000) == 0xE2000000) && // ADR or MOV
1802                                        ((p1[3] & 0xFE000000) == 0xE2000000) && // ADR or MOV
1803                                        ((p1[4] & 0xFE000000) == 0xEA000000))   // B or BL ?
1804                                {
1805                                        uint32_t padr;
1806                                        padr = ADR2adr(fw,j1+0);
1807                                        if (padr != sadr) padr = ADR2adr(fw,j1+1);
1808                                        if (padr != sadr) padr = ADR2adr(fw,j1+2);
1809                                        if (padr != sadr) padr = ADR2adr(fw,j1+3);
1810                                        if (padr == sadr)
1811                                        {
1812                                                uint32_t fadr = 0;
1813                                                if ((p1[0] & 0xFE0FF000) == 0xE20F3000)          fadr = ADR2adr(fw,j1);         // R3 ?
1814                                                else if ((p1[1] & 0xFE0FF000) == 0xE20F3000) fadr = ADR2adr(fw,j1+1);   // R3 ?
1815                                                else if ((p1[2] & 0xFE0FF000) == 0xE20F3000) fadr = ADR2adr(fw,j1+2);   // R3 ?
1816                                                else if ((p1[3] & 0xFE0FF000) == 0xE20F3000) fadr = ADR2adr(fw,j1+3);   // R3 ?
1817                                                if (fadr != 0)
1818                                                {
1819                                                        fadr = followBranch2(fw, fadr, sig->offset);
1820                                                        //fprintf(stderr,"%s %08x\n",curr_name,fadr);
1821                                                        addMatch(fadr,32,0,k,107);
1822                                                        return 1;
1823                                                }
1824                                        }
1825                                }
1826                        }
1827                }
1828        }
1829
1830        return 0;
1831}
1832
1833// Sig pattern:
1834//              Special case for WriteSDCard
1835int find_strsig8(firmware *fw, string_sig *sig, int k)
1836{
1837    int nlen = strlen(sig->ev_name);
1838        uint32_t nm0 = *((uint32_t*)sig->ev_name);
1839        uint32_t *p;
1840        uint32_t fadr = 0;
1841        int srch = 20;
1842
1843        // Find "UpdateMBROnFlash" code
1844        int j = get_saved_sig(fw,"UpdateMBROnFlash");
1845        if (j >= 0)
1846        {
1847                fadr = saved_sigs[j].val;
1848        }
1849        else
1850        {
1851                j = get_saved_sig(fw,"MakeSDCardBootable");
1852                if (j >= 0)
1853                {
1854                        fadr = saved_sigs[j].val;
1855                        srch = 32;
1856                }
1857        }
1858       
1859        if (fadr == 0) return 0;
1860       
1861        int idx = adr2idx(fw, fadr);
1862        int ofst = -1;
1863       
1864        for (j=idx+srch; j<idx+srch+12; j++)
1865        {
1866                if (isLDR(fw,j) && isLDR(fw,j+1) && isLDR(fw,j+2))
1867                {
1868                        ofst = (fw->buf[j] & 0xfff) + (fw->buf[j+1] & 0xfff) + (fw->buf[j+2] & 0xfff);
1869                        break;
1870                }
1871        }
1872       
1873        if (ofst == -1) return 0;
1874       
1875        for (p = fw->buf, j = 0; j < fw->size - nlen/4; j++, p++)
1876        {
1877                if ((nm0 == *p) && (memcmp(p+1,sig->ev_name+4,nlen-3) == 0))
1878                {
1879                        int j1;
1880                        for (j1=j-2; j1<j+8; j1++)
1881                        {
1882                                fadr = idx2adr(fw,j1);
1883                                if (fw->buf[j1] >= fw->base)    // pointer ??
1884                                {
1885                                        int j2;
1886                                        for (j2=j1-1; j2>=j1-1000 && j2>=0; j2--)
1887                                        {
1888                                                if (isLDR_PC(fw,j2) && (LDR2adr(fw,j2) == fadr))        // LDR ?
1889                                                {
1890                                                        if ((isSTR(fw,j2+1) && ((fw->buf[j2+1] & 0xfff) == ofst)) ||    // STR ?
1891                                                                (isSTR(fw,j2+2) && ((fw->buf[j2+2] & 0xfff) == ofst)))          // STR ?
1892                                                        {
1893                                                                fadr = fw->buf[j1];
1894                                                                if (fadr >= fw->base)
1895                                                                {
1896                                                                        //fprintf(stderr,"%s %08x\n",curr_name,fadr);
1897                                                                        addMatch(fadr,32,0,k,108);
1898                                                                        return 1;
1899                                                                }
1900                                                        }
1901                                                }
1902                                        }
1903                                }
1904                        }
1905                }
1906        }
1907
1908        return 0;
1909}
1910
1911// Sig pattern:
1912//              Func is B/BL @ offset from previous found func
1913//                      prev_func
1914//                              ... (offset)
1915//                              BL      func
1916int find_strsig9(firmware *fw, string_sig *sig, int k)
1917{
1918        int j = get_saved_sig(fw,sig->ev_name);
1919        if (j >= 0)
1920        {
1921                if (saved_sigs[j].val != 0)
1922                {                       
1923                        int ofst = dryos_offset(fw, sig);
1924                        uint32_t fadr = followBranch(fw, saved_sigs[j].val+ofst*4, sig->offset);
1925                        if ((sig->offset == 0) || (fadr != saved_sigs[j].val+ofst*4))
1926                        {
1927                                //fprintf(stderr,"%s %08x\n",curr_name,fadr);
1928                                addMatch(fadr,32,0,k,109);
1929                                return 1;
1930                        }
1931                }
1932        }
1933
1934        return 0;
1935}
1936
1937// Sig pattern:
1938//              Load Func Address       -       LDR     R3, =func       - these four may occur in any order ?
1939//              Load String Address     -       ADR     R0, "func"     
1940//              Load value                      -       MOV R2, x               
1941//              Load value                      -       MOV R1, y               
1942//              Branch                          -       BL
1943//                              ...
1944//              String                          -       DCB     "func"
1945int find_strsig10(firmware *fw, string_sig *sig, int k)
1946{
1947    int nlen = strlen(sig->ev_name);
1948        uint32_t nm0 = *((uint32_t*)sig->ev_name);
1949        uint32_t *p;
1950        int j;
1951       
1952        for (p = fw->buf, j = 0; j < fw->size - nlen/4; j++, p++)
1953        {
1954                if ((nm0 == *p) && (memcmp(p+1,sig->ev_name+4,nlen-3) == 0))
1955                {
1956                        uint32_t sadr = idx2adr(fw,j);        // string address
1957                        int j1;
1958                        uint32_t *p1;
1959                        for (p1 = p-5, j1 = j-5; j1 >= 0; j1--, p1--)
1960                        {
1961                                if ((((p1[0] & 0xFE000000) == 0xE2000000) || ((p1[0] & 0xFE000000) == 0xE4000000)) && // LDR, ADR or MOV
1962                                        (((p1[1] & 0xFE000000) == 0xE2000000) || ((p1[1] & 0xFE000000) == 0xE4000000)) && // LDR, ADR or MOV
1963                                        (((p1[2] & 0xFE000000) == 0xE2000000) || ((p1[2] & 0xFE000000) == 0xE4000000)) && // LDR, ADR or MOV
1964                                        (((p1[3] & 0xFE000000) == 0xE2000000) || ((p1[3] & 0xFE000000) == 0xE4000000)) && // LDR, ADR or MOV
1965                                        ((p1[4] & 0xFE000000) == 0xEA000000))   // B or BL ?
1966                                {
1967                                        uint32_t padr;
1968                                        padr = ADR2adr(fw,j1+0);
1969                                        if (padr != sadr) padr = ADR2adr(fw,j1+1);
1970                                        if (padr != sadr) padr = ADR2adr(fw,j1+2);
1971                                        if (padr != sadr) padr = ADR2adr(fw,j1+3);
1972                                        if (padr == sadr)
1973                                        {
1974                                                uint32_t fadr = 0;
1975                                                if ((p1[0] & 0xFE0FF000) == 0xE40F3000)          fadr = LDR2adr(fw,j1);         // R3 ?
1976                                                else if ((p1[1] & 0xFE0FF000) == 0xE40F3000) fadr = LDR2adr(fw,j1+1);   // R3 ?
1977                                                else if ((p1[2] & 0xFE0FF000) == 0xE40F3000) fadr = LDR2adr(fw,j1+2);   // R3 ?
1978                                                else if ((p1[3] & 0xFE0FF000) == 0xE40F3000) fadr = LDR2adr(fw,j1+3);   // R3 ?
1979                                                if (fadr != 0)
1980                                                {
1981                                                        fadr = followBranch2(fw, fw->buf[adr2idx(fw,fadr)], sig->offset);
1982                                                        //fprintf(stderr,"%s %08x\n",curr_name,fadr);
1983                                                        addMatch(fadr,32,0,k,110);
1984                                                        return 1;
1985                                                }
1986                                        }
1987                                }
1988                        }
1989                }
1990        }
1991
1992        return 0;
1993}
1994
1995// Sig pattern:
1996//              Func -                  func
1997//                      .... (offset)
1998//              Ref to string -         ADR Rx, str
1999//                      ....
2000//              String -                        DCB "str"
2001int find_strsig11(firmware *fw, string_sig *sig, int k)
2002{
2003    int nlen = strlen(sig->ev_name);
2004        uint32_t nm0 = *((uint32_t*)sig->ev_name);
2005        uint32_t *p;
2006        int j;
2007
2008        int ofst = dryos_offset(fw, sig);
2009       
2010        for (p = fw->buf, j = 0; j < fw->size - nlen/4; j++, p++)
2011        {
2012                if ((nm0 == *p) && (memcmp(p+1,sig->ev_name+4,nlen-4) == 0))
2013                {
2014                        uint32_t sadr = idx2adr(fw,j);        // string address
2015                        int j1;
2016                        uint32_t *p1;
2017                        for (p1 = p-1, j1 = j-1; j1 >= 0; j1--, p1--)
2018                        {
2019                                if ((p1[0] & 0x0E0F0000) == 0x020F0000) // ADR ?
2020                                {
2021                                        uint32_t padr = ADR2adr(fw,j1);
2022                                        if (padr == sadr)
2023                                        {
2024                                                uint32_t fadr = idx2adr(fw,j1-ofst);
2025                                                uint32_t bfadr = followBranch(fw,fadr,sig->offset);
2026                                                // special case for 'set_control_event'
2027                                                int found = 0;
2028                                                if (strcmp(sig->name,"set_control_event") == 0)
2029                                                {
2030                                                        uint32_t *p2 = p1 - ofst;
2031                                                        if (((p2[0] & 0xFF000000) == 0xEB000000) &&             // BL
2032                                                                ((p2[1] & 0xFFFFF000) == 0xE59D0000) &&         // LDR R0,[SP,x]
2033                                                                ((p2[2] & 0xFF000000) == 0xEB000000) &&         // BL
2034                                                                ((p2[3] & 0xFFFFF000) == 0xE1A04000))           // LDR R4, R0
2035                                                        {
2036                                                                found = 1;
2037                                                        }
2038                                                }
2039                                                else
2040                                                        found = 1;
2041                                                if (found && ((sig->offset == 0) || (bfadr != fadr)))
2042                                                {
2043                                                        //fprintf(stderr,"%s %08x\n",curr_name,fadr);
2044                                                        addMatch(bfadr,32,0,k,111);
2045                                                        return 1;
2046                                                }
2047                                        }
2048                                }
2049                        }
2050                }
2051        }
2052
2053        return 0;
2054}
2055
2056// Sig pattern:
2057//              Func is referenced in 'CreateJumptable'
2058//                      LDR R1, =func
2059//                      STR R1, [R0,nnn]
2060//              nnn - dryos version dependant offset
2061int find_strsig12(firmware *fw, string_sig *sig, int k)
2062{
2063        int j = get_saved_sig(fw,"CreateJumptable");   
2064
2065        int ofst = dryos_offset(fw, sig);
2066       
2067        if (ofst == 0) return 0;
2068       
2069        if (j >= 0)
2070        {
2071                if (saved_sigs[j].val != 0)
2072                {
2073                        int idx = adr2idx(fw, saved_sigs[j].val);
2074                        for(; fw->buf[idx] != 0xE12FFF1E; idx++)        // BX LR
2075                        {
2076                                if (((fw->buf[idx+1] & 0xFFFFF000) == 0xE5801000) && // STR R1,[R0,nnn]
2077                                    ((fw->buf[idx+1] & 0x00000FFF) == ofst))
2078                                {
2079                                        uint32_t fadr = LDR2val(fw,idx);
2080                                        uint32_t bfadr = followBranch2(fw,fadr,sig->offset);
2081                                        if ((sig->offset <= 1) || ((bfadr != fadr) && ((fw->buf[adr2idx(fw,fadr)] & 0xFFFF0000) == 0xE92D0000)))
2082                                        {
2083                                                //fprintf(stderr,"%s %08x\n",curr_name,bfadr);
2084                                                addMatch(bfadr,32,0,k,112);
2085                                                return 1;
2086                                        }
2087                                }
2088                                else if (isB(fw,idx))   // B
2089                                {
2090                                        idx = adr2idx(fw,followBranch(fw,idx2adr(fw,idx),1)) - 1;
2091                                }
2092                        }
2093                }
2094        }
2095
2096        return 0;
2097}
2098
2099// Sig pattern:
2100//              Func -                  func
2101//                      ... (offset)
2102//              Str ref -                       LDR Rx, =str_ptr
2103//                      ...
2104//              Str ptr -                       DCD str_ptr
2105//                      ...
2106//              Str ptr -               str_ptr
2107//                                                      DCD str
2108//                      ...
2109//              String                          DCB "str"
2110int find_strsig13(firmware *fw, string_sig *sig, int k)
2111{
2112    int nlen = strlen(sig->ev_name);
2113        char *p;
2114        int j;
2115       
2116        for (p = (char*)fw->buf, j = 0; j < fw->size*4 - nlen; j++, p++)
2117        {
2118                if (strncmp(sig->ev_name,(char*)p,nlen) == 0)
2119                {
2120                        uint32_t sadr = fw->base + j;                   // string address
2121                        int j1;
2122                        uint32_t *p1;
2123                        for (p1 = &fw->buf[(j/4)-1], j1 = (j/4)-1; j1 >= 0; j1--, p1--)
2124                        {
2125                                if (p1[0] == sadr)    // string ptr
2126                                {
2127                                        uint32_t padr = idx2adr(fw,j1);         // string ptr address
2128                                        int j2;
2129                                        uint32_t *p2;
2130                                        for (p2 = p1-1, j2 = j1-1; j2 >= 0; j2--, p2--)
2131                                        {
2132                                                if (p2[0] == padr)    // string ptr address
2133                                                {
2134                                                        uint32_t ppadr = idx2adr(fw,j2);                // string ptr ptr address
2135                                                        int j3;
2136                                                        for (j3 = j2-1; j3 >= 0; j3--)
2137                                                        {
2138                                                                if (isLDR_PC(fw,j3) && (LDR2adr(fw,j3) == ppadr))
2139                                                                {
2140                                                                        uint32_t fadr = idx2adr(fw,j3-sig->offset);
2141                                                                        //fprintf(stderr,"%s %08x\n",curr_name,fadr);
2142                                                                        addMatch(fadr,32,0,k,113);
2143                                                                        return 1;
2144                                                                }
2145                                                        }
2146                                                }
2147                                        }
2148                                }
2149                        }
2150                }
2151        }
2152
2153        return 0;
2154}
2155
2156// Sig pattern:
2157//              Special case for _pow
2158int find_strsig14(firmware *fw, string_sig *sig, int k)
2159{
2160        uint32_t *p;
2161        int j;
2162       
2163        for (p = fw->buf, j = 0; j < fw->size; j++, p++)
2164        {
2165                // Find values passed to _pow
2166                if ((p[0] == 0x00000000) && (p[1] == 0x40000000) && (p[2] == 0x00000000) && (p[3] == 0x408F4000))
2167                {
2168                        uint32_t adr1 = idx2adr(fw,j);          // address of 1st value
2169                        uint32_t adr2 = idx2adr(fw,j+2);        // address of 2nd value
2170                        uint32_t *p1;
2171                        int j1;
2172                       
2173                        for (p1 = p-5, j1 = j-5; j1>0; p1--, j1--)
2174                        {
2175                                if (((p1[0] & 0x0E0F0000) == 0x020F0000) &&     // ADR ?
2176                                         (p1[1] == 0xE8900003) &&                               // LDMIA R0,{R0,R1}
2177                                        ((p1[2] & 0xFF000000) == 0xEB000000) && // BL
2178                                        ((p1[4] & 0x0E0F0000) == 0x020F0000))   // ADR ?
2179                                {
2180                                        if ((ADR2adr(fw,j1) == adr1) && (ADR2adr(fw,j1+4) == adr2))
2181                                        {
2182                                                uint32_t fadr = followBranch(fw,idx2adr(fw,j1+2),0x01000001);
2183                                                //fprintf(stderr,"%s %08x\n",curr_name,fadr);
2184                                                addMatch(fadr,32,0,k,114);
2185                                                return 1;
2186                                        }
2187                                }
2188                                else
2189                                if (((p1[0] & 0x0E0F0000) == 0x020F0000) &&     // ADR ?
2190                                         (p1[2] == 0xE8900003) &&                               // LDMIA R0,{R0,R1}
2191                                        ((p1[3] & 0xFF000000) == 0xEB000000) && // BL
2192                                        ((p1[4] & 0x0E0F0000) == 0x020F0000))   // ADR ?
2193                                {
2194                                        if ((ADR2adr(fw,j1) == adr1) && (ADR2adr(fw,j1+4) == adr2))
2195                                        {
2196                                                uint32_t fadr = followBranch(fw,idx2adr(fw,j1+3),0x01000001);
2197                                                //fprintf(stderr,"%s %08x\n",curr_name,fadr);
2198                                                addMatch(fadr,32,0,k,114);
2199                                                return 1;
2200                                        }
2201                                }
2202                        }
2203                }
2204        }
2205       
2206        return 0;
2207}
2208
2209int find_strsig(firmware *fw, string_sig *sig, int k)
2210{
2211        switch (sig->type)
2212        {
2213                case 1:         return find_strsig1(fw, sig, k);
2214                case 2:         return find_strsig2(fw, sig, k);
2215                case 3:         return find_strsig3(fw, sig, k);
2216                case 4:         return find_strsig4(fw, sig, k);
2217                case 5:         return find_strsig5(fw, sig, k);
2218                case 6:         return find_strsig6(fw, sig, k);
2219                case 7:         return find_strsig7(fw, sig, k);
2220                case 8:         return find_strsig8(fw, sig, k);
2221                case 9:         return find_strsig9(fw, sig, k);
2222                case 10:        return find_strsig10(fw, sig, k);
2223                case 11:        return find_strsig11(fw, sig, k);
2224                case 12:        return find_strsig12(fw, sig, k);
2225                case 13:        return find_strsig13(fw, sig, k);
2226                case 14:        return find_strsig14(fw, sig, k);
2227        }
2228       
2229        return 0;
2230}
2231
2232//------------------------------------------------------------------------------------------------------------
2233
2234// Matching functions
2235
2236void find_str_sig_matches(firmware *fw, const char *curr_name)
2237{
2238        int i;
2239       
2240        int found_ev = 0;
2241
2242        count = 0;
2243
2244        for (i = 0; string_sigs[i].ev_name != 0 && !found_ev; i++)
2245        {
2246                if (strcmp(curr_name, string_sigs[i].name) == 0)
2247                {
2248                        if (find_strsig(fw, &string_sigs[i], -1))
2249                        {
2250                                found_ev = 1;
2251                                break;
2252                        }
2253                }
2254        }
2255
2256        if (count > 1)
2257        {
2258                //if (strcmp(curr_name,"GetDrive_FreeClusters") == 0) disp_sort = 1; else disp_sort = 0;
2259                qsort(matches, count, sizeof(Match), (void*)match_compare);
2260    }
2261
2262        if (count > 0)
2263        {
2264                save_sig(curr_name, matches->ptr);     
2265        }
2266}
2267
2268int find_matches(firmware *fw, int k)
2269{
2270    const char *curr_name;
2271    FuncSig *sig, *s;
2272    BufRange *n;
2273    uint32_t *p;
2274        int i;
2275    int fail, success;
2276       
2277        int found_ev = 0;
2278
2279        count = 0;
2280    curr_name = func_list[k].name;
2281
2282        while (1) {
2283                sig = func_list[k].sig;
2284
2285                for (i = 0; string_sigs[i].ev_name != 0 && !found_ev; i++)
2286                {
2287                        if (strcmp(curr_name, string_sigs[i].name) == 0)
2288                        {
2289                                if (find_strsig(fw, &string_sigs[i], k))
2290                                {
2291                                        found_ev = 1;
2292                                        break;
2293                                }
2294                        }
2295                }
2296
2297                if (!found_ev)
2298                {
2299                        for (n = fw->br; n != 0; n = n->next){
2300                                for (p = n->p, i = 0; i < n->len; p++, i++){
2301                                        fail = 0;
2302                                        success = 0;
2303                                        for (s = sig; s->offs != -1; s++){
2304                                                if ((p[s->offs] & s->mask) != s->value){
2305                                                        fail++;
2306                                                } else {
2307                                                        success++;
2308                                                }
2309                                        }
2310                                        if (success > fail){
2311                                                if (s->mask == -2)
2312                                                {
2313                                                        int end_branch = 0;
2314                                                        uint32_t idx = 0;
2315                                                        uint32_t *p1 = 0;
2316                                                        if ((fw->buf[n->off+i+s->value] & 0x0F000000) == 0x0A000000)   // B
2317                                                        {
2318                                                                idx = adr2idx(fw, followBranch2(fw, idx2adr(fw,n->off+i+s->value), 0xF0000001));
2319                                                                if ((idx >= 0) && (idx < fw->size))
2320                                                                {
2321                                                                        end_branch = 1;
2322                                                                        p1 = &fw->buf[idx];
2323                                                                }
2324                                                        }
2325                                                        int fail2 = 0;
2326                                                        int success2 = 0;
2327                                                        //fprintf(stderr,"\t%s %d %08x %08x %d %d\n",curr_name,idx,idx2adr(fw,idx),idx2adr(fw,i+n->off),success,fail);
2328                                                        s++;
2329                                                        for (; s->offs != -1; s++){
2330                                                                if (!end_branch || (p1[s->offs] & s->mask) != s->value){
2331                                                                        fail2++;
2332                                                                } else {
2333                                                                        success2++;
2334                                                                }
2335                                                        }
2336                                                        if (fail2 == 0)
2337                                                        {
2338                                                                success = success + fail + success2;
2339                                                                fail = 0;
2340                                                        }
2341                                                        else
2342                                                        {
2343                                                                success = success + success2;
2344                                                                fail = fail + fail2;
2345                                                        }
2346                                                        //fprintf(stderr,"\t%s %d %08x %08x %d %d\n",curr_name,idx,idx2adr(fw,idx),idx2adr(fw,i+n->off),success,fail);
2347                                                }
2348                                        }
2349                                        if (success > fail){
2350                                                addMatch(idx2adr(fw,i+n->off),success,fail,k,func_list[k].ver);
2351                                                if (count >= MAX_MATCHES){
2352                                                        bprintf("// WARNING: too many matches for %s!\n", func_list[k].name);
2353                                                        break;
2354                                                }
2355                                        }
2356                                }
2357                        }
2358                }
2359
2360                // same name, so we have another version of the same function
2361                if ((func_list[k+1].name == NULL) || (strcmp(curr_name, func_list[k+1].name) != 0)) {
2362                        break;
2363                }
2364                k++;
2365        }
2366
2367        if (count > 1)
2368        {
2369                //if (strcmp(curr_name,"GetDrive_FreeClusters") == 0) disp_sort = 1; else disp_sort = 0;
2370                qsort(matches, count, sizeof(Match), (void*)match_compare);
2371    }
2372
2373        if (count > 0)
2374        {
2375                save_sig(curr_name, matches->ptr);     
2376        }
2377               
2378        return k;
2379}
2380
2381int find_matches2(firmware *fw, int k)
2382{
2383    const char *curr_name;
2384        int i;
2385       
2386        int found_ev = 0;
2387
2388        count = 0;
2389    curr_name = func_list2[k].name;
2390
2391        for (i = 0; string_sigs[i].ev_name != 0 && !found_ev; i++)
2392        {
2393                if (strcmp(curr_name, string_sigs[i].name) == 0)
2394                {
2395                        if (find_strsig(fw, &string_sigs[i], k))
2396                        {
2397                                found_ev = 1;
2398                                break;
2399                        }
2400                }
2401        }
2402
2403        if (count > 1)
2404        {
2405                qsort(matches, count, sizeof(Match), (void*)match_compare);
2406    }
2407
2408        if (count > 0)
2409        {
2410                save_sig(curr_name, matches->ptr);     
2411        }
2412               
2413        return k;
2414}
2415
2416void print_results(const char *curr_name)
2417{
2418        int i;
2419        int err = 0;
2420    char line[500] = "";
2421       
2422        // find best match and report results
2423#ifdef  COMP_OSTUBS
2424        osig* ostub = find_sig(stubs,curr_name);
2425#endif
2426        osig* ostub2 = find_sig(stubs2,curr_name);
2427
2428        if ((count == 0)
2429                || (matches->fail > 0)
2430                || (ostub2 && (matches->ptr != ostub2->val))
2431#ifdef  COMP_OSTUBS
2432                || (ostub && (matches->ptr != ostub->val) && (ostub->pct != 0) && (!ostub2 || (matches->ptr != ostub2->val)))
2433#endif
2434       )
2435                err = 1;
2436
2437        // write to header (if error) or body buffer (no error)
2438        out_hdr = err;
2439
2440        char *macro = "NSTUB";
2441        if (strncmp(curr_name,"task_",5) == 0) macro = "  DEF";
2442       
2443#if defined(UPDATE_STUBS2) && defined(COMP_OSTUBS)
2444    if (ostub && (count > 0) && (ostub->val != matches->ptr) && (ostub->pct != 0) && out_hdr && !ostub2)
2445    {
2446        static int hdr_added = 0;
2447        FILE *fp = fopen("stubs_entry_2.S","a");
2448        if (hdr_added == 0)
2449        {
2450            fprintf(fp,"\n\n// Added by finsig_dryos V2 to match old values found by finsig.\n");
2451            fprintf(fp,"// Values should be checked in firmware, if the new address in stubs_entry.S\n// is correct then delete the correspoding entry below.\n");
2452            hdr_added = 1;
2453        }
2454        fprintf(fp,"NHSTUB(%-30s,0x%08x) // New address = 0x%08x\n",curr_name,ostub->val,matches->ptr);
2455        fclose(fp);
2456
2457        ostub2 = malloc(sizeof(osig));
2458        strcpy(ostub2->nm, curr_name);
2459        ostub2->val = ostub->val;
2460    }
2461#endif
2462
2463        if (count == 0)
2464        {
2465                int opt = is_in_list(curr_name,optional);
2466                if (opt == 1) return;
2467                char fmt[50] = "";
2468                sprintf(fmt, "// ERROR: %%s is not found. %%%ds//--- --- ", 34-strlen(curr_name));
2469                sprintf(line+strlen(line), fmt, curr_name, "");
2470        }
2471        else
2472        {
2473                if (ostub2)
2474                    sprintf(line+strlen(line),"//%s(%-38s,0x%08x) //%3d ", macro, curr_name, matches->ptr, matches->sig);
2475                else
2476                        sprintf(line+strlen(line),"%s(%-40s,0x%08x) //%3d ", macro, curr_name, matches->ptr, matches->sig);
2477
2478                if (matches->fail > 0)
2479                        sprintf(line+strlen(line),"%2d%% ", matches->success*100/(matches->success+matches->fail));
2480                else
2481                        sprintf(line+strlen(line),"    ");
2482        }
2483
2484        if (ostub2)
2485        {
2486                if ((count > 0) && (matches->ptr == ostub2->val))
2487                        sprintf(line+strlen(line),"       == 0x%08x    ",ostub2->val);
2488                else
2489                        sprintf(line+strlen(line),"   *** != 0x%08x    ",ostub2->val);
2490        }
2491        else
2492                sprintf(line+strlen(line),"                        ");
2493
2494#ifdef  COMP_OSTUBS
2495        if (ostub)
2496        {
2497                if ((count > 0) && (ostub->val != matches->ptr) && (ostub->pct != 0))
2498                {
2499                        if (out_hdr)
2500                                sprintf(line+strlen(line),"  *** != 0x%08x @ %3d%%",ostub->val,ostub->pct);
2501                        else
2502                                sprintf(line+strlen(line),"      != 0x%08x @ %3d%%",ostub->val,ostub->pct);
2503                }
2504                else if ((ostub->pct != 0) && (ostub->pct != 100))
2505                {
2506                        sprintf(line+strlen(line),"      == 0x%08x @ %3d%%",ostub->val,ostub->pct);
2507                }
2508                else if (ostub->pct == 0)
2509                {
2510                        sprintf(line+strlen(line),"          Not Found");
2511                }
2512        }
2513#endif
2514
2515    for (i=strlen(line)-1; i>=0 && line[i]==' '; i--) line[i] = 0;
2516    bprintf("%s\n",line);
2517
2518        for (i=1;i<count && matches[i].fail==matches[0].fail;i++)
2519        {
2520                if (matches[i].ptr != matches->ptr)
2521                {
2522                        bprintf("// ALT: %s(%s, 0x%x) // %d %d/%d\n", macro, curr_name, matches[i].ptr, matches[i].sig, matches[i].success, matches[i].fail);
2523                }
2524        }
2525}
2526
2527//------------------------------------------------------------------------------------------------------------
2528
2529int find_str_ref(firmware *fw, char *str)
2530{
2531        int k = find_str(fw, str);
2532        if (k >= 0)
2533        {
2534                uint32_t sadr = idx2adr(fw,k);          // string address
2535                for (k=0; k<fw->size; k++)
2536                {
2537                        if (isADR_PC_cond(fw,k) && (ADR2adr(fw,k) == sadr))
2538                        {
2539                                return k;
2540                        }
2541            else if (isLDR_PC_cond(fw,k) && (LDR2val(fw,k) == sadr))
2542            {
2543                return k;
2544            }
2545                }
2546        }
2547        return -1;
2548}
2549
2550int find_nxt_str_ref(firmware *fw, int str_adr, int ofst)
2551{
2552        if (str_adr >= 0)
2553        {
2554        int k;
2555                uint32_t sadr = idx2adr(fw,str_adr);            // string address
2556                for (k=ofst+1; k<fw->size; k++)
2557                {
2558                        if (isADR_PC_cond(fw,k) && (ADR2adr(fw,k) == sadr))
2559                        {
2560                                return k;
2561                        }
2562            else if (isLDR_PC_cond(fw,k) && (LDR2val(fw,k) == sadr))
2563            {
2564                return k;
2565            }
2566                }
2567        }
2568        return -1;
2569}
2570
2571//------------------------------------------------------------------------------------------------------------
2572
2573typedef struct
2574{
2575        uint16_t mode;
2576        char *nm;
2577} ModeMapName;
2578
2579ModeMapName mmnames[] = {
2580        { 32768,"MODE_AUTO" },
2581        { 32769,"MODE_M" },
2582        { 32770,"MODE_AV" },
2583        { 32771,"MODE_TV" },
2584        { 32772,"MODE_P" },
2585       
2586        { 65535,"" }
2587};
2588
2589char* mode_name(uint16_t v)
2590{
2591        int i;
2592        for (i=0; mmnames[i].mode != 65535; i++)
2593        {
2594                if (mmnames[i].mode == v)
2595                        return mmnames[i].nm;
2596        }
2597       
2598        return "";
2599}
2600
2601void find_modemap(firmware *fw)
2602{
2603        int k,k1,cnt = 0;
2604       
2605        out_hdr = 1;
2606        add_blankline();
2607
2608        bprintf("// Check of modemap from 'platform/CAMERA/shooting.c':\n");
2609
2610        k = find_str_ref(fw, "AC:PTM_Init");
2611        if (k >= 0)
2612        {
2613                bprintf("// Firmware modemap table found @%08x -> ",idx2adr(fw,k));
2614                if (isBL(fw,k+2))
2615                {
2616                        k = idxFollowBranch(fw,k+2,0x01000001);
2617                        bprintf("%08x -> ",idx2adr(fw,k));
2618                        for (k1 = 22; k1 <= 26; k1++)
2619                        {
2620                                if (isBL(fw,k+k1))
2621                                {
2622                                        k = idxFollowBranch(fw,k+k1,0x01000001);
2623                                        bprintf("%08x -> ",idx2adr(fw,k));
2624                                        for (k1 = 37; k1 <= 41; k1++)
2625                                        {
2626                                                if (isBL(fw,k+k1))
2627                                                {
2628                                                        k = idxFollowBranch(fw,k+k1,0x01000001);
2629                                                        bprintf("%08x -> ",idx2adr(fw,k));
2630                                                        if (isLDR_PC(fw,k))
2631                                                        {
2632                                                                k = adr2idx(fw,LDR2val(fw,k));
2633                                                                bprintf("%08x\n",idx2adr(fw,k));
2634                                                                uint16_t *p = (uint16_t*)(&fw->buf[k]);
2635                                                                k = 0;
2636                                                                while ((*p != 0xFFFF) && (k < 50))
2637                                                                {
2638                                                                        if (((fw->dryos_ver < 49) && ((*p < 8000) || (*p > 8999))) || ((fw->dryos_ver >= 49) && ((*p < 4000) || (*p > 4999))))
2639                                                                        {
2640                                                                                osig *m = find_sig_val(modemap, *p);
2641                                                                                if (!m)
2642                                                                                {
2643                                                                                        char *s = mode_name(*p);
2644                                                                                        bprintf("// Mode %5d in firmware but not in current modemap",*p);
2645                                                                                        if (strcmp(s,"") != 0)
2646                                                                                                bprintf(" (%s)",s);
2647                                                                                        bprintf("\n");
2648                                                                                        cnt++;
2649                                                                                }
2650                                                                                else
2651                                                                                {
2652                                                                                        m->pct = 100;
2653                                                                                }
2654                                                                        }
2655                                                                        p++;
2656                                                                        k++;
2657                                                                }
2658                                                        }
2659                                                        osig *m = modemap;
2660                                                        while (m)
2661                                                        {
2662                                                                if (m->pct != 100)      // not matched above?
2663                                                                {
2664                                                                        bprintf("// Current modemap entry not found in firmware - %-24s %5d\n",m->nm,m->val);
2665                                                                        cnt++;
2666                                                                }
2667                                                                m = m->nxt;
2668                                                        }
2669                                                        if (cnt == 0)
2670                                                        {
2671                                                                bprintf("// No problems found with modemap table.\n");
2672                                                        }
2673                                                        return;
2674                                                }
2675                                        }
2676                                }
2677                        }
2678                }
2679                bprintf("\n");
2680        }
2681}
2682
2683//------------------------------------------------------------------------------------------------------------
2684
2685uint32_t craw_bufsize = 0;
2686
2687// Search for things that go in 'platform_camera.h'
2688void find_platform_vals(firmware *fw)
2689{
2690        int k,k1;
2691       
2692        out_hdr = 1;
2693        add_blankline();
2694
2695        bprintf("// Values below go in 'platform_camera.h':\n");
2696        bprintf("//#define CAM_DRYOS         1\n");
2697        if (fw->dryos_ver >= 39)
2698                bprintf("//#define CAM_DRYOS_2_3_R39 1 // Defined for cameras with DryOS version R39 or higher\n");
2699        if (fw->dryos_ver >= 47)
2700                bprintf("//#define CAM_DRYOS_2_3_R47 1 // Defined for cameras with DryOS version R47 or higher\n");
2701
2702        // Find 'RAW' image size
2703        uint32_t raw_width = 0;
2704        uint32_t raw_height = 0;
2705        uint32_t kw=0, kh=0;
2706       
2707        k = find_str_ref(fw, "\r[%ld] AdjDrvType[%02ld] -> DrvType[%02");
2708        if (k >= 0)
2709        {
2710        // Width
2711                for (k1 = k-1; k1 >= k-20; k1--)
2712                {
2713                        if ((fw->buf[k1] & 0x0FFF0FFF) == 0x058D0034)                   // STRxx Rn, [SP,#0x34]
2714                        {
2715                                if ((fw->buf[k1-1] & 0x0FFF0000) == 0x03A00000)         // MOVxx Rn, #YYY
2716                                {
2717                                        raw_width = ALUop2(fw, k1-1);
2718                                        kw = k1-1;
2719                                }
2720                                else if ((fw->buf[k1-2] & 0x0FFF0000) == 0x03A00000)// MOVxx Rn, #YYY
2721                                {
2722                                        raw_width = ALUop2(fw, k1-2);
2723                                        kw = k1-2;
2724                                }
2725                                else if (isLDR_PC_cond(fw,k1-1))
2726                                {
2727                                        raw_width = LDR2val(fw,k1-1);
2728                                        kw = k1-1;
2729                                }
2730                                else if (isLDR_PC_cond(fw,k1-2))
2731                                {
2732                                        raw_width = LDR2val(fw,k1-2);
2733                                        kw = k1-2;
2734                                }
2735                        }
2736        }
2737        // Height
2738                for (k1 = k-1; k1 >= k-20; k1--)
2739                {
2740                        if ((fw->buf[k1] & 0x0FFF0FFF) == 0x058D0030)                   // STRxx Rn, [SP,#0x30]
2741                        {
2742                                if ((fw->buf[k1-1] & 0x0FFF0000) == 0x03A00000)         // MOVxx Rn, #YYY
2743                                {
2744                                        raw_height = ALUop2(fw, k1-1);
2745                                        kh = k1-1;
2746                                }
2747                                else if ((fw->buf[k1-2] & 0x0FFF0000) == 0x03A00000)// MOVxx Rn, #YYY
2748                                {
2749                                        raw_height = ALUop2(fw, k1-2);
2750                                        kh = k1-2;
2751                                }
2752                                else if (isLDR_PC_cond(fw,k1-1))
2753                                {
2754                                        raw_height = LDR2val(fw,k1-1);
2755                                        kh = k1-1;
2756                                }
2757                                else if (isLDR_PC_cond(fw,k1-2))
2758                                {
2759                                        raw_height = LDR2val(fw,k1-2);
2760                                        kh = k1-2;
2761                                }
2762                                if ((fw->buf[k1-1] & 0x0FFF0000) == 0x02400000)         // SUBxx Rn, #YYY
2763                                {
2764                                        raw_height = raw_width - ALUop2(fw, k1-1);
2765                                        kh = k1-1;
2766                                }
2767                        }
2768                }
2769        }
2770
2771        if ((raw_width == 0) && (raw_height == 0))
2772        {
2773                k = find_str_ref(fw, " CrwAddress %lx, CrwSize H %ld V %ld\r");
2774                if (k >= 0)
2775                {
2776                        // Width
2777                        for (k1=k-1; k1>=k-5; k1--)
2778                        {
2779                                if ((fw->buf[k1] & 0xFFFFF000) == 0xE3A02000)   // MOV R2, #nnn
2780                                {
2781                                        raw_width = ALUop2(fw,k1);
2782                                        kw = k1;
2783                                }
2784                                else
2785                                if (isLDR_PC(fw,k1) && ((fw->buf[k1]& 0x0000F000) == 0x00002000))       // LDR R2, =nnn
2786                                {
2787                                        raw_width = LDR2val(fw,k1);
2788                                        kw = k1;
2789                                }
2790                        }
2791                        // Height
2792                        for (k1=k-1; k1>=k-5; k1--)
2793                        {
2794                                if ((fw->buf[k1] & 0xFFFFF000) == 0xE3A03000)   // MOV R3, #nnn
2795                                {
2796                                        raw_height = ALUop2(fw,k1);
2797                                        kh = k1;
2798                                }
2799                                else
2800                                if (isLDR_PC(fw,k1) && ((fw->buf[k1]& 0x0000F000) == 0x00003000))       // LDR R3, =nnn
2801                                {
2802                                        raw_height = LDR2val(fw,k1);
2803                                        kh = k1;
2804                                }
2805                                else
2806                                if ((fw->buf[k1] & 0xFFFFF000) == 0xE2423000)   // SUB R3, R2, #nnn
2807                                {
2808                                        raw_height = raw_width - ALUop2(fw,k1);
2809                                        kh = k1;
2810                                }
2811                        }
2812                }
2813        }
2814       
2815        if (raw_width != 0)
2816        {
2817                bprintf("//#define CAM_RAW_ROWPIX    %d // Found @0x%08x\n",raw_width,idx2adr(fw,kw));
2818        }
2819    else
2820    {
2821                bprintf("//#define CAM_RAW_ROWPIX    *** Not Found ***\n");
2822    }
2823        if (raw_height != 0)
2824        {
2825                bprintf("//#define CAM_RAW_ROWS      %d // Found @0x%08x\n",raw_height,idx2adr(fw,kh));
2826        }
2827    else
2828    {
2829                bprintf("//#define CAM_RAW_ROWS      *** Not Found ***\n");
2830    }
2831
2832        // Find 'CAM_UNCACHED_BIT'
2833        k = get_saved_sig(fw, "FreeUncacheableMemory");
2834        if (k >= 0)
2835        {
2836                uint32_t fadr = saved_sigs[k].val;
2837                int idx = adr2idx(fw, fadr);
2838               
2839                for (k=idx; k<idx+8; k++)
2840                {
2841                        if ((fw->buf[k] & 0x0FFFF000) == 0x03C00000)    // BIC
2842                        {
2843                                fadr = ALUop2(fw,k);
2844                                bprintf("//#undef  CAM_UNCACHED_BIT\n");
2845                                bprintf("//#define CAM_UNCACHED_BIT  0x%08x // Found @0x%08x\n",fadr,idx2adr(fw,k));
2846                        }
2847                }
2848        }
2849}
2850
2851//------------------------------------------------------------------------------------------------------------
2852
2853// Search for things that go in 'lib.c'
2854void find_lib_vals(firmware *fw)
2855{
2856        int k,k1;
2857       
2858        out_hdr = 1;
2859        add_blankline();
2860
2861        bprintf("// Values below go in 'lib.c':\n");
2862
2863        // Find 'vid_get_bitmap_fb'
2864        k = get_saved_sig(fw, "DispCon_ShowBitmapColorBar");
2865        if (k >= 0)
2866        {
2867                uint32_t fadr = saved_sigs[k].val;
2868                int idx = adr2idx(fw, fadr);
2869               
2870                for (k=idx+1; k<idx+30; k++)
2871                {
2872                        if (isBL(fw,k-1) && // BL
2873                            isLDR_PC(fw,k))
2874                        {
2875                                uint32_t v1 = LDR2val(fw,k);
2876                                bprintf("//void *vid_get_bitmap_fb()        { return (void*)0x%08x; }             // Found @0x%08x\n",v1,idx2adr(fw,k));
2877                                break;
2878                        }
2879                        else
2880                        if (isBL(fw,k-1) && // BL
2881                            (isLDR_PC(fw,k+1)))
2882                        {
2883                                uint32_t v1 = LDR2val(fw,k+1);
2884                                bprintf("//void *vid_get_bitmap_fb()        { return (void*)0x%08x; }             // Found @0x%08x\n",v1,idx2adr(fw,k));
2885                                break;
2886                        }
2887                }
2888        }
2889       
2890        // find 'vid_get_viewport_fb'
2891        k = find_str_ref(fw, "VRAM Address  : %p\r");
2892        if (k >= 0)
2893        {
2894                for (k1=k-1; k1>k-8; k1--)
2895                {
2896                        if (isLDR(fw,k1) && isLDR(fw,k1+1))
2897                        {
2898                                uint32_t v1 = LDR2val(fw,k1);
2899                                uint32_t v2 = LDR2val(fw,k1+1);
2900                                if (v2 > v1) v1 = v2;
2901                                bprintf("//void *vid_get_viewport_fb()      { return (void*)0x%08x; }             // Found @0x%08x\n",v1,idx2adr(fw,k1));
2902                        }
2903                }
2904        }
2905       
2906        // find 'vid_get_viewport_fb_d'
2907    static int fbd[3][3] =
2908    {
2909        { -2, -3,  1 },
2910        {  1,  3,  4 },
2911        { -1, -2,  1 },
2912    };
2913    int sadr = find_str(fw, "ImagePlayer.c");
2914        k = find_nxt_str_ref(fw, sadr, -1);
2915    int found = 0;
2916        while ((k >= 0) && !found)
2917        {
2918        int f;
2919        for (f=0; f<3 && !found; f++)
2920        {
2921                    if (isLDR(fw,k+fbd[f][0]) && isLDR(fw,k+fbd[f][1]) && isLDR(fw,k+fbd[f][2]))
2922                    {
2923                int reg = fw->buf[k+fbd[f][2]] & 0x000F0000;    // Index register used
2924                int ka = 0;
2925                if (((fw->buf[k+fbd[f][0]] & 0x0000F000) << 4) == reg)      { ka = k+fbd[f][0]; }
2926                else if (((fw->buf[k+fbd[f][1]] & 0x0000F000) << 4) == reg) { ka = k+fbd[f][1]; }
2927                if (ka > 0)
2928                {
2929                    uint32_t adr = LDR2val(fw,ka);
2930                    for (k1=k+2; k1<k+20; k1++)
2931                    {
2932                        if (isSTR(fw,k1) && ((fw->buf[k1] & 0x000F0000) == reg))
2933                        {
2934                            uint32_t ofst = fw->buf[k1] & 0x00000FFF;
2935                                    bprintf("//void *vid_get_viewport_fb_d()    { return (void*)(*(int*)(0x%04x+0x%02x)); } // Found @0x%08x & 0x%08x\n",adr,ofst,idx2adr(fw,ka),idx2adr(fw,k1));
2936                            found = 1;
2937                            break;
2938                        }
2939                    }
2940                }
2941                    }
2942        }
2943        k = find_nxt_str_ref(fw, sadr, k);
2944        }
2945       
2946        // find 'camera_jpeg_count_str'
2947        k = find_str_ref(fw, "9999");
2948        if (k >= 0)
2949        {
2950                if (isLDR(fw,k-1) && isBL(fw,k+1))
2951                {
2952                        uint32_t v1 = LDR2val(fw,k-1);
2953                        bprintf("//char *camera_jpeg_count_str()    { return (char*)0x%08x; }             // Found @0x%08x\n",v1,idx2adr(fw,k-1));
2954                }
2955        }
2956       
2957        // find 'hook_raw_size'
2958        k = find_str_ref(fw, "CRAW BUFF SIZE  %p");
2959        if (k >= 0)
2960        {
2961                if (isLDR(fw,k-1))
2962                {
2963                        craw_bufsize = LDR2val(fw,k-1);
2964                        bprintf("//long hook_raw_size()             { return 0x%08x; }                    // Found @0x%08x\n",craw_bufsize,idx2adr(fw,k-1));
2965                }
2966        }
2967       
2968        // Find value for 'get_flash_params_count'
2969        k = get_saved_sig(fw, "GetParameterData");
2970        if (k >= 0)
2971        {
2972                uint32_t fadr = saved_sigs[k].val;
2973                int idx = adr2idx(fw, fadr);
2974               
2975                for (k=idx; k<idx+30; k++)
2976                {
2977                        if ((fw->buf[k] & 0xFFF00FFF) == 0xE3C00901)    // BIC Rn, Rn, #0x4000
2978                        {
2979                                uint32_t r = fw->buf[k] & 0x000F0000;   // Register
2980                                if (((fw->buf[k+1] & 0xFFF00000) == 0xE3500000) && ((fw->buf[k+1] & 0x000F0000) == r))  // CMP, Rn #val
2981                                {
2982                                        bprintf("//int get_flash_params_count(void) { return 0x%02x; }                          // Found @0x%08x\n",fw->buf[k+1]&0xFFF,idx2adr(fw,k+1));
2983                                        break;
2984                                }
2985                        }
2986                }
2987        }
2988}
2989
2990//------------------------------------------------------------------------------------------------------------
2991
2992void print_stubs_min(firmware *fw, const char *name, uint32_t fadr, uint32_t atadr)
2993{
2994        osig *o = find_sig(stubs_min,name);
2995        if (o)
2996        {
2997        bprintf("//DEF(%-40s,0x%08x) // Found @0x%08x",name,fadr,atadr);
2998                if (fadr != o->val)
2999                {
3000                        bprintf(", ** != ** stubs_min = 0x%08x (%s)",o->val,o->sval);
3001                }
3002                else
3003                {
3004                        bprintf(",          stubs_min = 0x%08x (%s)",o->val,o->sval);
3005                }
3006        }
3007    else
3008    {
3009        bprintf("DEF(%-40s,0x%08x) // Found @0x%08x",name,fadr,atadr);
3010    }
3011        bprintf("\n");
3012}
3013
3014// Search for things that go in 'stubs_min.S'
3015void find_stubs_min(firmware *fw)
3016{
3017        int k,k1;
3018       
3019        out_hdr = 1;
3020        add_blankline();
3021
3022        bprintf("// Values below can be overridden in 'stubs_min.S':\n");
3023
3024        // Find 'physw_status'
3025        k = get_saved_sig(fw, "kbd_read_keys");
3026        if (k >= 0)
3027        {
3028                uint32_t fadr = saved_sigs[k].val;
3029                int idx = adr2idx(fw, fadr);
3030               
3031                for (k=0; k<5; k++)
3032                {
3033                        if (isLDR_PC(fw,idx+k))
3034                        {
3035                                print_stubs_min(fw,"physw_status",LDR2val(fw,idx+k),idx2adr(fw,idx+k));
3036                                //break;
3037                        }
3038                }
3039        }
3040       
3041        // Find 'physw_run'
3042        k = get_saved_sig(fw, "task_PhySw");
3043        if (k >= 0)
3044        {
3045                uint32_t fadr = saved_sigs[k].val;
3046                int idx = adr2idx(fw, fadr);
3047               
3048                for (k=0; k<5; k++)
3049                {
3050                        if (isLDR_PC(fw,idx+k))
3051                        {
3052                                uint32_t base = LDR2val(fw,idx+k);
3053                                uint32_t fadr = followBranch(fw, idx2adr(fw,idx+k+1), 1);
3054                                uint32_t ofst = fw->buf[adr2idx(fw,fadr)] & 0x00000FFF;
3055                                print_stubs_min(fw,"physw_run",base+ofst,idx2adr(fw,idx+k));
3056                                //break;
3057                        }
3058                }
3059        }
3060       
3061        // Find 'levent_table'
3062        for (k=0; k<fw->size; k++)
3063        {
3064                if ((fw->buf[k] > fw->base) && (fw->buf[k+1] == 0x00000800) && (fw->buf[k+2] == 0x00000002))
3065                {
3066                        print_stubs_min(fw,"levent_table",idx2adr(fw,k),idx2adr(fw,k));
3067                        //break;
3068                }
3069        }
3070       
3071        // Find 'FlashParamsTable'
3072        for (k=0; k<fw->size; k++)
3073        {
3074                if ((fw->buf[k] > fw->base) && (fw->buf[k+1] == 0x00010000) && (fw->buf[k+2] == 0xFFFF0002))
3075                {
3076                        uint32_t fadr = idx2adr(fw,k);
3077                        for (k1=0; k1<fw->size; k1++)
3078                        {
3079                                if (fw->buf[k1] == fadr)
3080                                {
3081                                        print_stubs_min(fw,"FlashParamsTable",idx2adr(fw,k1),idx2adr(fw,k1));
3082                                        k = fw->size;
3083                                        //break;
3084                                }
3085                        }
3086                }
3087        }
3088       
3089        // Find 'movie_status'
3090        for (k=0; k<fw->size; k++)
3091        {
3092                if (isLDR_PC(fw, k) &&                                                          // LDR R0, =base
3093                        ((fw->buf[k+1] & 0xFE0F0000) == 0xE20F0000) &&  // ADR R1, =sub
3094                        isSTR(fw, k+2) &&                                                               // STR R1, [R0,N]
3095                        (fw->buf[k+3] == 0xE3A01003) &&                                 // MOV R1, 3
3096                        isSTR(fw, k+4) &&                                                               // STR R1, [R0,ofst]
3097                        (LDR2val(fw,k) < fw->base))
3098                {
3099                        uint32_t base = LDR2val(fw,k);
3100                        uint32_t ofst = fw->buf[k+4] & 0x00000FFF;
3101                        print_stubs_min(fw,"movie_status",base+ofst,idx2adr(fw,k));
3102                        //break;
3103                }
3104                else
3105                if (isLDR_PC(fw, k) &&                                                          // LDR R1, =sub
3106                        isLDR_PC(fw, k+1) &&                                                    // LDR R0, =base
3107                        isSTR(fw, k+2) &&                                                               // STR R1, [R0,N]
3108                        (fw->buf[k+3] == 0xE3A01003) &&                                 // MOV R1, 3
3109                        isSTR(fw, k+4) &&                                                               // STR R1, [R0,ofst]
3110                        (LDR2val(fw,k+1) < fw->base))
3111                {
3112                        uint32_t base = LDR2val(fw,k+1);
3113                        uint32_t ofst = fw->buf[k+4] & 0x00000FFF;
3114                        print_stubs_min(fw,"movie_status",base+ofst,idx2adr(fw,k));
3115                        //break;
3116                }
3117        }
3118       
3119        // Find 'full_screen_refresh'
3120        for (k=0; k<fw->size; k++)
3121        {
3122                if (((fw->buf[k] & 0xFF1FF000) == 0xE51F0000) &&        // LDR R0, =base
3123                        (fw->buf[k+1] == 0xE5D01000) &&                                 // LDRB R1, [R0]
3124                        (fw->buf[k+2] == 0xE3811002) &&                                 // ORR R1, R1, #2
3125                        (fw->buf[k+3] == 0xE5C01000) &&                                 // STRB R1, [R0]
3126                        (fw->buf[k+4] == 0xE12FFF1E))                                   // BX LR
3127                {
3128                        uint32_t base = LDR2val(fw,k);
3129                        print_stubs_min(fw,"full_screen_refresh",base,idx2adr(fw,k));
3130                        //break;
3131                }
3132        }
3133       
3134        // Find 'canon_menu_active'
3135        k = get_saved_sig(fw, "StartRecModeMenu");
3136        if (k >= 0)
3137        {
3138                uint32_t fadr = saved_sigs[k].val;
3139                int idx = adr2idx(fw, fadr);
3140               
3141                for (k=0; k<5; k++)
3142                {
3143                        if (isLDR_PC(fw,idx+k))
3144                        {
3145                                uint32_t base = LDR2val(fw,idx+k);
3146                                for (k1=k+1; k1<k+5; k1++)
3147                                {
3148                                        if (isLDR(fw,idx+k1))
3149                                        {
3150                                                uint32_t ofst = fw->buf[idx+k1] & 0x00000FFF;
3151                                                print_stubs_min(fw,"canon_menu_active",base+ofst,idx2adr(fw,idx+k));
3152                                                //break;
3153                                        }
3154                                }
3155                        }
3156                }
3157        }
3158       
3159        // Find 'canon_shoot_menu_active'
3160        for (k=0; k<fw->size; k++)
3161        {
3162                if (((fw->buf[k]   & 0xFF1FF000) == 0xE51F1000) &&      // LDR R1, =base
3163                        ((fw->buf[k+1] & 0xFFFFF000) == 0xE5D10000) &&  // LDRB R0, [R1, #n]
3164                        (fw->buf[k+2] == 0xE2800001) &&                                 // ADD R0, R0, #1
3165                        ((fw->buf[k+3] & 0xFFFFF000) == 0xE5C10000) &&  // STRB R0, [R1, #n]
3166                        (isB(fw,k+4)))                                  // B
3167                {
3168                        uint32_t base = LDR2val(fw,k);
3169                        uint32_t ofst = fw->buf[k+1] & 0x00000FFF;
3170                        print_stubs_min(fw,"canon_shoot_menu_active",base+ofst,idx2adr(fw,k));
3171                        //break;
3172                }
3173                else
3174                if (((fw->buf[k]   & 0xFF1FF000) == 0xE51F0000) &&      // LDR R0, =base
3175                        ((fw->buf[k+1] & 0xFFFFF000) == 0xE5D01000) &&  // LDRB R1, [R0, #n]
3176                        (fw->buf[k+2] == 0xE2811001) &&                                 // ADD R1, R1, #1
3177                        ((fw->buf[k+3] & 0xFFFFF000) == 0xE5C01000) &&  // STRB R1, [R0, #n]
3178                        (isB(fw,k+4)))                                  // B
3179                {
3180                        uint32_t base = LDR2val(fw,k);
3181                        uint32_t ofst = fw->buf[k+1] & 0x00000FFF;
3182                        print_stubs_min(fw,"canon_shoot_menu_active",base+ofst,idx2adr(fw,k));
3183                        //break;
3184                }
3185        }
3186       
3187        // Find 'playrec_mode'
3188        int found_playrec_mode = 0;
3189        k = find_str_ref(fw, "AFFChg");
3190        if ((k >= 0) && isBL(fw,k+6))
3191        {
3192                k = idxFollowBranch(fw, k+6, 0x01000001);
3193                if (isLDR_PC(fw,k) && isLDR(fw,k+1))
3194                {
3195                        uint32_t base = LDR2val(fw,k);
3196                        uint32_t ofst = fw->buf[k+1] & 0x00000FFF;
3197                        print_stubs_min(fw,"playrec_mode",base+ofst,idx2adr(fw,k));
3198                        found_playrec_mode = 1;
3199                }
3200        }
3201        if (!found_playrec_mode)
3202        {
3203                for (k=0; k<fw->size; k++)
3204                {
3205                        if (((fw->buf[k]    & 0xFF1FF000) == 0xE51F1000) &&     // LDR R1, =base
3206                                ((fw->buf[k+1]  & 0xFFFFF000) == 0xE5810000) && // STR R0, [R1, #n]
3207                                ((fw->buf[k+3]  & 0xFF1FF000) == 0xE51F0000) && // LDR R0, =base
3208                                ((fw->buf[k+4]  & 0xFFFFF000) == 0xE5900000) && // LDR R0, [R0, #n]
3209                                ((fw->buf[k+6]  & 0xFF1FF000) == 0xE51F1000) && // LDR R1, =base
3210                                ((fw->buf[k+9]  & 0xFF1FF000) == 0xE51F0000) && // LDR R0, =base
3211                                ((fw->buf[k+12] & 0xFF1FF000) == 0xE51F1000) && // LDR R1, =base
3212                                ((fw->buf[k+15] & 0xFF1FF000) == 0xE51F0000) && // LDR R0, =base
3213                                ((fw->buf[k+18] & 0xFF1FF000) == 0xE51F1000) && // LDR R1, =base
3214                                (LDR2val(fw,k) == LDR2val(fw,k+3)) &&
3215                                (LDR2val(fw,k) == LDR2val(fw,k+6)) &&
3216                                (LDR2val(fw,k) == LDR2val(fw,k+9)) &&
3217                                (LDR2val(fw,k) == LDR2val(fw,k+12)) &&
3218                                (LDR2val(fw,k) == LDR2val(fw,k+15)) &&
3219                                (LDR2val(fw,k) == LDR2val(fw,k+18)))
3220                        {
3221                                uint32_t base = LDR2val(fw,k);
3222                                uint32_t ofst = fw->buf[k+1] & 0x00000FFF;
3223                                print_stubs_min(fw,"playrec_mode",base+ofst,idx2adr(fw,k));
3224                                found_playrec_mode = 1;
3225                                //break;
3226                        }
3227                }
3228        }
3229       
3230        // Find 'zoom_status'
3231        int found_zoom_status = 0;
3232       
3233        k = find_str_ref(fw, "m_ZoomState            :%d\n");
3234        if (k >= 0)
3235        {
3236                if (isLDR(fw,k-1))
3237                {
3238                        uint32_t ofst = fw->buf[k-1] & 0x00000FFF;
3239                        uint32_t reg = (fw->buf[k-1] & 0x000F0000) >> 16;
3240                        uint32_t ldr_inst = 0xE51F0000 | (reg << 12);
3241                        for (k1=k-2; k1>k-20; k1--)
3242                        {
3243                                if ((fw->buf[k1] & 0xFF1FF000) == ldr_inst)
3244                                {
3245                                        uint32_t base = LDR2val(fw,k1);
3246                                        print_stubs_min(fw,"zoom_status",base+ofst,idx2adr(fw,k));
3247                                        found_zoom_status = 1;
3248                                        break;
3249                                }
3250                        }
3251                }
3252        }
3253       
3254        if (!found_zoom_status)
3255        {
3256                for (k=0; k<fw->size; k++)
3257                {
3258                        if (((fw->buf[k] & 0xFF1FF000) == 0xE51F0000) &&        // LDR R0, =base
3259                                (fw->buf[k+1] == 0xE5D00000) &&                                 // LDRB R0, [R0]
3260                                (fw->buf[k+2] == 0xE1B00000) &&                                 // MOVS R0, R0
3261                                (fw->buf[k+3] == 0x13A00001) &&                                 // MOVNE R0, #1
3262                                (fw->buf[k+4] == 0xE12FFF1E))                                   // BX LR
3263                        {
3264                                uint32_t base = LDR2val(fw,k);
3265                                print_stubs_min(fw,"zoom_status",base,idx2adr(fw,k));
3266                                found_zoom_status = 1;
3267                                //break;
3268                        }
3269                }
3270        }
3271       
3272        if (!found_zoom_status)
3273        {
3274                k = find_str_ref(fw, "TerminateDeliverToZoomController");
3275                if (k >= 0)
3276                {
3277                        for (k1=0; k1<5; k1++)
3278                        {
3279                                if (isLDR_PC(fw,k+k1))
3280                                {
3281                                        uint32_t base = LDR2val(fw,k+k1);
3282                                        print_stubs_min(fw,"zoom_status",base+0x20,idx2adr(fw,k+k1));
3283                                        found_zoom_status = 1;
3284                                        break;
3285                                }
3286                        }
3287                }
3288        }
3289       
3290        // Find 'some_flag_for_af_scan'
3291        for (k=0; k<fw->size; k++)
3292        {
3293                if (isB(fw,k)   &&  // B loc
3294                        isB(fw,k+1) &&  // B loc
3295                        isB(fw,k+2) &&  // B loc
3296                        isB(fw,k+3) &&  // B loc
3297                        isB(fw,k+4) &&  // B loc
3298                        isB(fw,k+5) &&  // B loc
3299                        isB(fw,k+6) &&  // B loc
3300                        isB(fw,k+7) &&  // B loc
3301                        (followBranch(fw,idx2adr(fw,k),1) != followBranch(fw,idx2adr(fw,k+1),1)) &&
3302                        (followBranch(fw,idx2adr(fw,k),1) == followBranch(fw,idx2adr(fw,k+2),1)) &&
3303                        (followBranch(fw,idx2adr(fw,k),1) == followBranch(fw,idx2adr(fw,k+3),1)) &&
3304                        (followBranch(fw,idx2adr(fw,k),1) != followBranch(fw,idx2adr(fw,k+4),1)) &&
3305                        (followBranch(fw,idx2adr(fw,k),1) != followBranch(fw,idx2adr(fw,k+5),1)) &&
3306                        (followBranch(fw,idx2adr(fw,k),1) == followBranch(fw,idx2adr(fw,k+6),1)) &&
3307                        (followBranch(fw,idx2adr(fw,k),1) == followBranch(fw,idx2adr(fw,k+7),1)) &&
3308                        (isLDR_PC(fw,adr2idx(fw,followBranch(fw,idx2adr(fw,k),1)))))    // LDR R0, =base
3309                {
3310                        uint32_t base = LDR2val(fw,adr2idx(fw,followBranch(fw,idx2adr(fw,k),1)));
3311                        print_stubs_min(fw,"some_flag_for_af_scan",base,followBranch(fw,idx2adr(fw,k),1));
3312                        //break;
3313                }
3314        }
3315
3316    // focus_len_table
3317    if (min_focus_len != 0)
3318    {
3319        int found = 0, pos = 0, len = 0, size = 0;
3320        for (k=0; k<fw->size; k++)
3321            {
3322            if (fw->buf[k] == min_focus_len)
3323            {
3324                int mul = 1;
3325                if ((fw->buf[k+1] == 100) && (fw->buf[k+2] == 0)) mul = 3;
3326                if ((fw->buf[k+1] == 100) && (fw->buf[k+2] != 0)) mul = 2;
3327                for (k1 = k + mul; (k1 < fw->size) && (fw->buf[k1] > fw->buf[k1-mul]) && (fw->buf[k1] != max_focus_len); k1 += mul) ;
3328                if (fw->buf[k1] == max_focus_len)
3329                {
3330                    found++;
3331                    pos = k;
3332                    len = ((k1 - k) / mul) + 1;
3333                    size = mul;
3334                }
3335            }
3336        }
3337        if (found == 1)
3338        {
3339            bprintf("// focus_len_table contains zoom focus lengths for use in 'get_focal_length' (main.c).\n");
3340            if (size == 1)
3341                bprintf("// each entry contains 1 int value, which is the the zoom focus length.\n",size);
3342            else
3343                bprintf("// each entry contains %d int value(s), the first is the zoom focus length.\n",size);
3344            bprintf("// there are %d entries in the table - set NUM_FL to %d\n",len,len);
3345                        print_stubs_min(fw,"focus_len_table",idx2adr(fw,pos),idx2adr(fw,pos));
3346        }
3347    }
3348       
3349        // Find 'zoom_busy'
3350        k = get_saved_sig(fw, "ResetZoomLens");
3351        if (k >= 0)
3352        {
3353                uint32_t fadr = saved_sigs[k].val;
3354                int idx = adr2idx(fw, fadr);
3355               
3356                for (k=idx; k<idx+5; k++)
3357                {
3358            if (isBL(fw,k))
3359            {
3360                int idx1 = idxFollowBranch(fw,k,0x01000001);
3361                for (k1=idx1; k1<idx1+50; k1++)
3362                {
3363                    if ((fw->buf[k1] & 0xFFFF0000) == 0xE8BD0000)   // LDMFD
3364                    {
3365                        fadr = 0;
3366                        if (isADR_PC(fw,k1+1))
3367                        {
3368                            fadr = ADR2adr(fw,k1+1);
3369                        }
3370                        else if (isADR_PC(fw,k1+2))
3371                        {
3372                            fadr = ADR2adr(fw,k1+2);
3373                        }
3374                        else if (isADR_PC(fw,k1-3))
3375                        {
3376                            fadr = ADR2adr(fw,k1-3);
3377                        }
3378                        else if (isLDR_PC(fw,k1+1))
3379                        {
3380                            fadr = LDR2val(fw,k1+1);
3381                        }
3382                        else if (isLDR_PC(fw,k1+2))
3383                        {
3384                            fadr = LDR2val(fw,k1+2);
3385                        }
3386                        if (fadr != 0)
3387                        {
3388                            int idx2 = adr2idx(fw,fadr);
3389                            if (isLDR_PC(fw,idx2+1) && isLDR(fw,idx2+2))
3390                            {
3391                                int base = LDR2val(fw,idx2+1);
3392                                int ofst = fw->buf[idx2+2] & 0xFFF;
3393                                        print_stubs_min(fw,"zoom_busy",base+ofst-4,fadr);
3394                                break;
3395                            }
3396                        }
3397                    }
3398                }
3399            }
3400        }
3401    }
3402       
3403        // Find 'focus_busy'
3404        k = get_saved_sig(fw, "ResetFocusLens");
3405        if (k >= 0)
3406        {
3407                uint32_t fadr = saved_sigs[k].val;
3408                int idx = adr2idx(fw, fadr);
3409               
3410                for (k=idx; k<idx+25; k++)
3411                {
3412            if ((fw->buf[k] & 0xFFFF0000) == 0xE8BD0000)   // LDMFD
3413            {
3414                k1 = 0;
3415                if (isBL(fw,k-2))
3416                {
3417                    k1 = idxFollowBranch(fw,k-2,0x01000001);
3418                }
3419                if (isBL(fw,k-1))
3420                {
3421                    k1 = idxFollowBranch(fw,k-1,0x01000001);
3422                }
3423                if (k1 != 0)
3424                {
3425                    if (isLDR_PC(fw,k1+1) && isLDR(fw,k1+3))
3426                    {
3427                        int base = LDR2val(fw,k1+1);
3428                        int ofst = fw->buf[k1+3] & 0xFFF;
3429                        print_stubs_min(fw,"focus_busy",base+ofst-4,idx2adr(fw,k1));
3430                        break;
3431                    }
3432                }
3433            }
3434        }
3435    }
3436       
3437        // Find 'recreview_hold'
3438        k = find_str_ref(fw, "ShootCon_NotifyStartReviewHold");
3439        if (k >= 0)
3440        {
3441        for (k1=k; k1<k+20; k1++)
3442        {
3443            if (isLDR_PC(fw,k1) && ((fw->buf[k1+1] & 0xFFFF0FFF) == 0xE3A00001) && isSTR(fw,k1+2) &&
3444                ((fw->buf[k1+1] & 0x0000F000) == (fw->buf[k1+2] & 0x0000F000)) &&
3445                ((fw->buf[k1] & 0x0000F000) == ((fw->buf[k1+2] & 0x000F0000) >> 4)))
3446            {
3447                uint32_t base = LDR2val(fw,k1);
3448                int ofst = fw->buf[k1+2] & 0x00000FFF;
3449                print_stubs_min(fw,"recreview_hold",base+ofst,idx2adr(fw,k1));
3450                break;
3451            }
3452        }
3453        }
3454}
3455
3456//------------------------------------------------------------------------------------------------------------
3457
3458// Search for things
3459void find_other_vals(firmware *fw)
3460{
3461        out_hdr = 1;
3462        add_blankline();
3463
3464        bprintf("// Misc stuff\n");
3465
3466    unsigned char ctypes[] =
3467    {
3468        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x60, 0x60, 0x60, 0x60, 0x20, 0x20,
3469        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
3470        0x48, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
3471        0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
3472        0x10, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 1, 1, 1, 1, 1, 1, 1, 1, 1,
3473        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0x10, 0x10, 0x10, 0x10, 0x10,
3474        0x10, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3475        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0x10, 0x10, 0x10, 0x10, 0x20
3476    };
3477
3478    unsigned char *p = (unsigned char*)fw->buf;
3479    int i, found = 0;
3480    for (i=0; i<fw->size*4-sizeof(ctypes); i++, p++)
3481    {
3482        if (memcmp(p,ctypes,sizeof(ctypes)) == 0)
3483        {
3484            bprintf("DEF(ctypes, 0x%08x)\n", fw->base + i);
3485            found = 1;
3486            break;
3487        }
3488    }
3489    if (!found)
3490    {
3491        bprintf("//DEF(ctypes, *** Not Found ***)\n");
3492    }
3493
3494    // Look for nrflag (for capt_seq.c)
3495    int k, k1, k2, k3, k4, idx, ofst1, ofst2;
3496        k = get_saved_sig(fw, "NR_GetDarkSubType");
3497        if (k >= 0)
3498        {
3499                uint32_t fadr = saved_sigs[k].val;
3500                idx = adr2idx(fw, fadr);
3501
3502        // Found NR_GetDarkSubType function, now follow first BL call.
3503        k1 = 0;
3504        for (k=idx; k<idx+20; k++)
3505        {
3506            if (isBL(fw,k))
3507            {
3508                k1 = idxFollowBranch(fw,k,0x01000001);
3509                break;
3510            }
3511        }
3512
3513        if (k1 > 0)
3514        {
3515            int found = 0;
3516            // Found function called from NR_GetDarkSubType
3517            // Check if old version - see what value passed in R3
3518            for (k2=0; k2<fw->size && !found; k2++)
3519            {
3520                if (isBL(fw,k2) && (idxFollowBranch(fw,k2,0x01000001) == k1))
3521                {
3522                    // Found call to function, work out R3 value passed in
3523                    ofst1 = 0;
3524                    k4 = 0;
3525                    for (k3=k2; k3>k2-30 && !found; k3--)
3526                    {
3527                        if ((fw->buf[k3] & 0x0F0FF000) == 0x020D3000)       // Dest = R3, Src = SP = skip
3528                            break;
3529                        if ((fw->buf[k3] & 0xFF0FF000) == 0xE2033000)       // ADD/SUB R3,R3,x
3530                        {
3531                            k4 = k3;
3532                            if ((fw->buf[k3] & 0x00F00000) == 0x00400000)   // SUB
3533                                ofst1 -= (fw->buf[k3] & 0x00000FFF);
3534                            else
3535                                ofst1 += (fw->buf[k3] & 0x00000FFF);
3536                        }
3537                        if (isLDR_PC(fw,k3) && ((fw->buf[k3] & 0x0000F000) == 0x00003000))
3538                        {
3539                            ofst2 = LDR2val(fw,k3);
3540                            bprintf("\n// For capt_seq.c\n");
3541                            if (ofst1 == 0)
3542                                bprintf("//static long *nrflag = (long*)(0x%04x);       // Found @ %08x\n",ofst2,idx2adr(fw,k3));
3543                            else if (ofst1 < 0)
3544                                bprintf("//static long *nrflag = (long*)(0x%04x-0x%02x);  // Found @ %08x & %08x\n",ofst2,-ofst1,idx2adr(fw,k3),idx2adr(fw,k4));
3545                            else
3546                                bprintf("//static long *nrflag = (long*)(0x%04x+0x%02x);  // Found @ %08x & %08x\n",ofst2,ofst1,idx2adr(fw,k3),idx2adr(fw,k4));
3547                            found = 1;
3548                            break;
3549                        }
3550                    }
3551                }
3552            }
3553
3554            // Try for new version, find address inside function
3555            static int fx[2][5] =
3556            {
3557                {  0, 1, 2, 3, 4 },
3558                {  0, 1, 3, 4, 5 },
3559            };
3560                for (k=k1; k<k1+200 && !found; k++)
3561            {
3562                if ((fw->buf[k] & 0xFFFF0FFF) == 0x13E00000)    // MOVNE Rx, 0xFFFFFFFF
3563                {
3564                    for (k2=k-5; k2>k-16 && !found; k2--)
3565                    {
3566                        int f;
3567                        for (f=0; f<2; f++)
3568                        {
3569                            if (isLDR(fw,k2+fx[f][0]) &&                                   // LDR
3570                                ((fw->buf[k2+fx[f][1]] & 0xFFF0FFFF) == 0xE3500000) &&     // CMP Rx, #0
3571                                ((fw->buf[k2+fx[f][2]] & 0xFFF00000) == 0x15800000) &&     // STRNE
3572                                isLDR(fw,k2+fx[f][3]) &&                                   // LDR
3573                                ((fw->buf[k2+fx[f][4]] & 0xFFF0FFFF) == 0xE3500000))       // CMP Rx, #0
3574                            {
3575                                ofst1 = fw->buf[k2+fx[f][0]] & 0x00000FFF;
3576                                ofst2 = fw->buf[k2+fx[f][3]] & 0x00000FFF;
3577                                int reg1 = fw->buf[k2+fx[f][0]] & 0x000F0000;
3578                                int reg2 = fw->buf[k2+fx[f][3]] & 0x000F0000;
3579                                if ((reg1 == reg2) && (ofst1 == ofst2 - 4))
3580                                {
3581                                    reg1 = reg1 >> 4;
3582                                    for (k3=k2; k3>k2-50 && !found; k3--)
3583                                    {
3584                                        if (isLDR_PC(fw,k3) && ((fw->buf[k3] & 0x0000F000) == reg1))
3585                                        {
3586                                            ofst2 = LDR2val(fw,k3);
3587                                            bprintf("\n// For capt_seq.c\n");
3588                                            bprintf("//static long *nrflag = (long*)(0x%04x+0x%02x);  // Found @ %08x & %08x\n",ofst2,ofst1,idx2adr(fw,k3),idx2adr(fw,k2));
3589                                            bprintf("//#define NR_AUTO (0)                          // have to explictly reset value back to 0 to enable auto\n");
3590                                            found = 1;
3591                                            break;
3592                                        }
3593                                    }
3594                                }
3595                            }
3596                        }
3597                    }
3598                }
3599            }
3600        }
3601    }
3602}
3603
3604//------------------------------------------------------------------------------------------------------------
3605
3606void print_kval(firmware *fw, uint32_t tadr, int tsiz, int tlen, uint32_t ev, const char *name, char *sfx)
3607{
3608        int tidx = adr2idx(fw,tadr);
3609        int k, kval = 0;
3610        for (k=0; k<tlen; k+=tsiz)
3611        {
3612                if (fw->buf[tidx+k+1] == ev)
3613                {
3614                        kval = fw->buf[tidx+k];
3615                        tadr = idx2adr(fw,tidx+k);
3616                        break;
3617                }
3618        }
3619        if (kval > 0)
3620        {
3621                char fn[100], rn[100];
3622                strcpy(fn,name); strcat(fn,sfx);
3623                strcpy(rn,name); strcat(rn,"_IDX");
3624               
3625                int r = (kval >> 5) & 7;
3626                uint32_t b = (1 << (kval & 0x1F));
3627               
3628                bprintf("//#define %-20s0x%08x // Found @0x%08x, levent 0x%x\n",fn,b,tadr,ev);
3629                bprintf("//#define %-20s%d\n",rn,r);
3630        }
3631}
3632
3633typedef struct {
3634        int                     reg;
3635        uint32_t        bits;
3636        char            nm[32];
3637        uint32_t        fadr;
3638        uint32_t        ev;
3639} kinfo;
3640
3641int             kmask[3];
3642kinfo   key_info[100];
3643int             kcount = 0;
3644
3645void add_kinfo(int r, uint32_t b, const char *nm, uint32_t adr, uint32_t ev)
3646{
3647        key_info[kcount].reg = r;
3648        key_info[kcount].bits = b;
3649        strcpy(key_info[kcount].nm, nm);
3650        key_info[kcount].fadr = adr;
3651        key_info[kcount].ev = ev;
3652        kcount++;
3653        kmask[r] |= b;
3654}
3655
3656uint32_t add_kmval(firmware *fw, uint32_t tadr, int tsiz, int tlen, uint32_t ev, const char *name, uint32_t xtra)
3657{
3658        int tidx = adr2idx(fw,tadr);
3659        int r, k, kval = 0;
3660        uint32_t b = 0;
3661        for (k=0; k<tlen; k+=tsiz)
3662        {
3663                if (fw->buf[tidx+k+1] == ev)
3664                {
3665                        kval = fw->buf[tidx+k];
3666                        tadr = idx2adr(fw,tidx+k);
3667                        break;
3668                }
3669        }
3670        if (kval > 0)
3671        {
3672                r = (kval >> 5) & 7;
3673                b = (1 << (kval & 0x1F));
3674               
3675                add_kinfo(r,b|xtra,name,tadr,ev);
3676        }
3677       
3678        return b;
3679}
3680
3681int kinfo_compare(const kinfo *p1, const kinfo *p2)
3682{
3683    if (p1->reg > p2->reg)
3684        {
3685                return 1;
3686    }
3687        else if (p1->reg < p2->reg)
3688        {
3689                return -1;
3690    }
3691        if (p1->ev <= 1)        // output shutter entries in reverse order
3692        {
3693                if (p1->bits > p2->bits)
3694                {
3695                        return -1;
3696                }
3697                else if (p1->bits < p2->bits)
3698                {
3699                        return 1;
3700                }
3701        }
3702    if (p1->bits > p2->bits)
3703        {
3704        return 1;
3705    }
3706        else if (p1->bits < p2->bits)
3707        {
3708        return -1;
3709    }
3710
3711    return 0;
3712}
3713
3714void print_kmvals()
3715{
3716        qsort(key_info, kcount, sizeof(kinfo), (void*)kinfo_compare);
3717       
3718        bprintf("//static KeyMap keymap[] = {\n");
3719       
3720        int k;
3721        for (k=0; k<kcount; k++)
3722        {
3723                bprintf("//    { %d, %-20s,0x%08x }, // Found @0x%08x, levent 0x%02x\n",key_info[k].reg,key_info[k].nm,key_info[k].bits,key_info[k].fadr,key_info[k].ev);
3724        }
3725       
3726        bprintf("//    { 0, 0, 0 }\n//};\n");
3727}
3728
3729void find_key_vals(firmware *fw)
3730{
3731        int k,k1;
3732       
3733        out_hdr = 1;
3734        add_blankline();
3735
3736        // find 'SD_READONLY_FLAG'
3737        uint32_t tadr = 0;
3738        k = get_saved_sig(fw, "GetSDProtect");
3739        if (k >= 0)
3740        {
3741                uint32_t fadr = saved_sigs[k].val;
3742                k = adr2idx(fw,fadr);
3743                if (isB(fw,k+1))        // B
3744                {
3745                        fadr = followBranch(fw,fadr+4,1);
3746                        k1 = adr2idx(fw,fadr);
3747                        if (isLDR_PC(fw,k1))
3748                        {
3749                                tadr = LDR2val(fw,k1);
3750                        }
3751                }
3752        }
3753        if (tadr == 0)
3754        {
3755                k = find_str_ref(fw,"SD Not Exist\n");
3756                if (k >= 0)
3757                {
3758                        for (k1=k-1; k1>k-5; k1--)
3759                        {
3760                                if (isBL(fw,k1))        // BL
3761                                {
3762                                        uint32_t fadr = followBranch(fw,idx2adr(fw,k1),0x01000001);
3763                                        int k2 = adr2idx(fw,fadr);
3764                                        if (isLDR_PC(fw,k2))
3765                                        {
3766                                                tadr = LDR2val(fw,k2);
3767                                        }
3768                                }
3769                        }
3770                }
3771        }
3772        if (tadr != 0)
3773        {
3774                int tsiz = 2;
3775                if (fw->buf[adr2idx(fw,tadr)+2] == 0) tsiz = 3;
3776               
3777                uint32_t madr = fw->base + (fw->size*4-4);
3778                for (k=0; k<(tadr-fw->base)/4; k++)
3779                {
3780                        if (isLDR_PC(fw,k))
3781                        {
3782                                uint32_t adr = LDR2val(fw,k);
3783                                if ((adr > tadr) && (adr < madr))
3784                                {
3785                                        madr = adr;
3786                                }
3787                        }
3788                }
3789                int tlen = (madr - tadr) / 4;
3790                if (tsiz == 2)
3791                {
3792                        k1 = adr2idx(fw,tadr);
3793                        for (k=0; k<tlen/3; k+=3)
3794                        {
3795                                if ((fw->buf[k1+k+1] == 0xFFFFFFFF) && (fw->buf[k1+k+4] == 0xFFFFFFFF))
3796                                {
3797                                        tsiz = 3;
3798                                        break;
3799                                }
3800                        }
3801                }
3802                if (tlen > 50*tsiz) tlen = 50*tsiz;
3803               
3804                bprintf("// Bitmap masks and physw_status index values for SD_READONLY and USB power flags (for kbd.c).\n");
3805        if (fw->dryos_ver >= 49)
3806        {
3807            // Event ID's have changed in DryOS R49 **********
3808                print_kval(fw,tadr,tsiz,tlen,0x20A,"SD_READONLY","_FLAG");
3809                print_kval(fw,tadr,tsiz,tlen,0x202,"USB","_MASK");
3810        }
3811        else
3812        {
3813                print_kval(fw,tadr,tsiz,tlen,0x90A,"SD_READONLY","_FLAG");
3814                print_kval(fw,tadr,tsiz,tlen,0x902,"USB","_MASK");
3815        }
3816                               
3817                uint32_t key_half = add_kmval(fw,tadr,tsiz,tlen,0,"KEY_SHOOT_HALF",0);
3818                add_kmval(fw,tadr,tsiz,tlen,1,"KEY_SHOOT_FULL",key_half);
3819                add_kmval(fw,tadr,tsiz,tlen,1,"KEY_SHOOT_FULL_ONLY",0);
3820                add_kmval(fw,tadr,tsiz,tlen,2,"KEY_ZOOM_IN",0);
3821                add_kmval(fw,tadr,tsiz,tlen,3,"KEY_ZOOM_OUT",0);
3822                add_kmval(fw,tadr,tsiz,tlen,4,"KEY_UP",0);
3823                add_kmval(fw,tadr,tsiz,tlen,5,"KEY_DOWN",0);
3824                add_kmval(fw,tadr,tsiz,tlen,6,"KEY_LEFT",0);
3825                add_kmval(fw,tadr,tsiz,tlen,7,"KEY_RIGHT",0);
3826                add_kmval(fw,tadr,tsiz,tlen,8,"KEY_SET",0);
3827                add_kmval(fw,tadr,tsiz,tlen,9,"KEY_MENU",0);
3828                add_kmval(fw,tadr,tsiz,tlen,0xA,"KEY_DISPLAY",0);
3829                               
3830                bprintf("\n// Keymap values for kbd.c. Additional keys may be present, only common values included here.\n");
3831                print_kmvals();
3832        }
3833}
3834
3835//------------------------------------------------------------------------------------------------------------
3836
3837int main(int argc, char **argv)
3838{
3839    firmware fw;
3840    int k;
3841    int ret = 0;
3842    const char *curr_name;
3843
3844    clock_t t1 = clock();
3845
3846    if (argc != 4)
3847        usage("args");
3848
3849    out_fp = fopen(argv[3],"w");
3850    if (out_fp == NULL) usage("failed to open outputfile");
3851
3852    //load_ignore_list();
3853
3854#ifdef  COMP_OSTUBS
3855    load_stubs();
3856    //print_stubs(stubs);
3857#endif
3858    load_stubs2();
3859    //print_stubs(stubs2);
3860        load_stubs_min();
3861    //print_stubs(stubs_min);
3862        load_modemap();
3863    //print_stubs(modemap);
3864    load_platform();
3865       
3866    bprintf("// !!! THIS FILE IS GENERATED. DO NOT EDIT. !!!\n");
3867    bprintf("#include \"stubs_asm.h\"\n\n");
3868
3869    load_firmware(&fw,argv[1],argv[2]);
3870       
3871    // Find all the valid ranges for checking (skips over large blocks of 0xFFFFFFFF)
3872    findRanges(&fw);
3873
3874#ifdef  COMP_OSTUBS
3875        out_hdr = 1;
3876        bprintf("// Stubs below should be checked. Stub not matched 100%%, or difference\n");
3877        bprintf("// found to current 'stubs_entry_2.S' or original 'stubs_entry.S'\n");
3878        bprintf("//    Name                                     Address      Rule  %%  Comp to stubs_entry_2.S  Comp to stubs_entry.S.orig\n");
3879        out_hdr = 0;
3880        bprintf("// Stubs below matched 100%%.\n");
3881        bprintf("//    Name                                     Address                Comp to stubs_entry_2.S  Comp to stubs_entry.S.orig\n");
3882#else
3883        out_hdr = 1;
3884        bprintf("// Stubs below should be checked. Stub not matched 100%%, or difference found to current 'stubs_entry_2.S'\n");
3885        bprintf("//    Name                                     Address      Rule  %%  Comp to stubs_entry_2.S\n");
3886        out_hdr = 0;
3887        bprintf("// Stubs below matched 100%%.\n");
3888        bprintf("//    Name                                     Address                Comp to stubs_entry_2.S\n");
3889#endif
3890
3891    for (k = 0; func_list[k].name; k++){
3892
3893        count = 0;
3894        curr_name = func_list[k].name;
3895
3896        int ignore = is_in_list(curr_name,ignore_list);
3897
3898        if (!ignore)
3899        {
3900                        k = find_matches(&fw, k);
3901
3902                        if ((fw.dryos_ver >= find_min_ver(curr_name)) && (fw.dryos_ver <= find_max_ver(curr_name)))
3903                                print_results(curr_name);
3904
3905                        if (count == 0)
3906                        {
3907                                ret = 1;
3908                        }
3909        }
3910    }
3911
3912    for (k = 0; func_list2[k].name; k++){
3913
3914        count = 0;
3915        curr_name = func_list2[k].name;
3916
3917                k = find_matches2(&fw, k);
3918
3919        //if ((fw.dryos_ver >= find_min_ver(curr_name)) && (fw.dryos_ver <= find_max_ver(curr_name)))
3920                //      print_results(curr_name);
3921    }
3922
3923    clock_t t2 = clock();
3924
3925        find_modemap(&fw);
3926        find_stubs_min(&fw);
3927        find_lib_vals(&fw);
3928        find_key_vals(&fw);
3929        find_platform_vals(&fw);
3930    find_other_vals(&fw);
3931
3932    printf("Time to generate stubs %.2f seconds\n",(double)(t2-t1)/(double)CLOCKS_PER_SEC);
3933       
3934        write_output();
3935       
3936    fclose(out_fp);
3937
3938    return ret;
3939}
3940
3941//------------------------------------------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.