root/trunk/tools/finsig_dryos.c @ 1385

Revision 1385, 82.1 KB (checked in by philmoz, 19 months ago)

Update for DRYOS signature finder (finsig_dryos.c):
- Fix camera name finder for R49 cameras
- Add PLATFORMID and MAXRAMADDR values in camera info section
Also fix SVN properties for IXUS 1000 files & folders.

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