source: trunk/tools/finsig_dryos.c @ 950

Revision 950, 102.2 KB checked in by rudi_de, 16 months ago (diff)

Aktualisierung auf Rev. 1659 internationaler Branch: Release-1.0
http://trac.assembla.com/chdk/changeset/1659/branches/release-1_0
Danke philmoz!

Betrifft VxWorks und DryOS Signaturfinder

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