source: branches/release-1_0/tools/finsig_dryos.c @ 1635

Revision 1635, 101.9 KB checked in by philmoz, 2 years ago (diff)

Update for finsig_dryos:

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