source: trunk/tools/finsig_dryos.c @ 1379

Revision 1379, 80.8 KB checked in by philmoz, 20 months ago (diff)

Update signature finder for new DryOS R49 cameras (SX40HS & SX150IS).

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