source: trunk/tools/finsig_vxworks.c @ 950

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

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

Betrifft VxWorks und DryOS Signaturfinder

  • Ausgabedatei ist 4. Parameter
  • bessere Trennung von Programmausgabe (STDOUT) und Fehlermeldungen (STDERR)
  • CHDK-Shell zeigt die Erzeugungsdauer der stubs_entry.S nicht mehr als Fehler
Line 
1#include <stdlib.h>
2#include <stdio.h>
3#include <stdint.h>
4#include <string.h>
5#include <unistd.h>
6#include <time.h>
7
8#define MAX_MATCHES (64)
9
10typedef struct {
11    uint32_t ptr;
12    uint32_t fail;
13    uint32_t success;
14} Match;
15
16typedef struct {
17    uint32_t offs;
18    uint32_t value;
19    uint32_t mask;
20} FuncSig;
21
22typedef struct {
23    const char *name;
24    FuncSig *sig;
25} FuncsList;
26
27typedef struct bufrange {
28    uint32_t *p;
29    int off;
30    int len;
31    struct bufrange* next;
32} BufRange;
33
34BufRange *br, *last;
35
36void addBufRange(uint32_t *p, int o, int l)
37{
38    BufRange *n = malloc(sizeof(BufRange));
39    n->p = p;
40    n->off = o;
41    n->len = l;
42    n->next = 0;
43    if (br == 0)
44    {
45        br = n;
46    }
47    else
48    {
49        last->next = n;
50    }
51    last = n;
52}
53
54#if defined(PLATFORMOS_vxworks)
55#include "signatures_vxworks.h"
56#elif defined(PLATFORMOS_dryos)
57#include "signatures_dryos.h"
58#else
59#error Undefined platform OS
60#endif
61
62int match_compare(const Match *p1, const Match *p2)
63{
64    /* NOTE: If a function has *more* matches, it will be prefered, even if it has a lower percent matches */
65    if (p1->success > p2->success){
66        return -1;
67    } else
68        if (p1->success < p2->success){
69            return 1;
70        } else {
71            if (p1->fail < p2->fail){
72                return -1;
73            } else
74                if (p1->fail > p2->fail){
75                    return 1;
76                }
77        }
78
79        /* scores are equal. prefer lower address */
80
81        if (p1->ptr < p2->ptr){
82            return -1;
83        } else
84            if (p1->ptr > p2->ptr){
85                return 1;
86            }
87
88            return 0;
89}
90
91FILE *out_fp;
92
93void usage()
94{
95    if (out_fp) fprintf(out_fp,"finsig <primary> <base> <outputfilename>\n");
96    fprintf(stderr,"finsig <primary> <base> <outputfilename>\n");
97    exit(1);
98}
99
100int main(int argc, char **argv)
101{
102    Match matches[MAX_MATCHES];
103    uint32_t *buf, *p;
104    FILE *f;
105    int size;
106    int i,j,k;
107    int fail, success;
108    uint32_t base;
109    FuncSig *sig, *s;
110    int count;
111    int ret = 0;
112    const char *curr_name;
113    BufRange *n;
114
115    clock_t t1 = clock();
116
117    if (argc != 4)
118        usage();
119
120    out_fp = fopen(argv[3],"w");
121    if (out_fp == NULL) usage();
122
123    f = fopen(argv[1], "r+b");
124
125    if (f == NULL)
126        usage();
127
128    base = strtoul(argv[2], NULL, 0);
129
130    fprintf(out_fp,"// !!! THIS FILE IS GENERATED. DO NOT EDIT. !!!\n");
131    fprintf(out_fp,"#include \"stubs_asm.h\"\n\n");
132
133    fseek(f,0,SEEK_END);
134    size=ftell(f)/4;
135    fseek(f,0,SEEK_SET);
136
137    // Max sig size if 32, add extra space at end of buffer and fill with 0xFFFFFFFF
138    // Allows sig matching past end of firmware without checking each time in the inner loop
139    buf=malloc((size+32)*4);
140    fread(buf, 4, size, f);
141    fclose(f);
142    memset(&buf[size],0xff,32*4);
143
144    // Find all the valid ranges for checking (skips over large blocks of 0xFFFFFFFF)
145    br = 0; last = 0;
146    k = -1; j = 0;
147    for (i = 0; i < size; i++)
148    {
149        if (buf[i] == 0xFFFFFFFF)   // Possible start of block to skip
150        {
151            if (k == -1)            // Mark start of possible skip block
152            {
153                k = i;
154            }
155        }
156        else                        // Found end of block ?
157        {
158            if (k != -1)
159            {
160                if (i - k > 32)     // If block more than 32 words then we want to skip it
161                {
162                    if (k - j > 8)
163                    {
164                        // Add a range record for the previous valid range (ignore short ranges)
165                        addBufRange(&buf[j],j,k - j);
166                    }
167                    j = i;          // Reset valid range start to current position
168                }
169                k = -1;             // Reset marker for skip block
170            }
171        }
172    }
173    // Add range for last valid block
174    if (k != -1)   
175    {
176        if (k - j > 8)
177        {
178            addBufRange(&buf[j],j,k - j);
179        }
180    }
181    else
182    {
183        if (i - j > 8)
184        {
185            addBufRange(&buf[j],j,i - j);
186        }
187    }
188
189    for (k = 0; func_list[k].name; k++){
190
191        count = 0;
192        curr_name = func_list[k].name;
193
194        while (1) {
195            sig = func_list[k].sig;
196
197            for (n = br; n != 0; n = n->next){
198                for (p = n->p, i = 0; i < n->len; p++, i++){
199                    fail = 0;
200                    success = 0;
201                    for (s = sig; s->offs != -1; s++){
202                        if ((p[s->offs] & s->mask) != s->value){
203                            fail++;
204                        } else {
205                            success++;
206                        }
207                    }
208                    if (success > fail){
209                        matches[count].ptr = base+((i+n->off)<<2);
210                        matches[count].success = success;
211                        matches[count].fail = fail;
212                        count ++;
213                        if (count >= MAX_MATCHES){
214                            fprintf(out_fp,"// WARNING: too many matches for %s!\n", func_list[k].name);
215                            break;
216                        }
217                    }
218                }
219            }
220
221            // same name, so we have another version of the same function
222            if ((func_list[k+1].name == NULL) || (strcmp(curr_name, func_list[k+1].name) != 0)) {
223                break;
224            }
225            k++;
226        }
227
228        // find best match and report results
229        if (count == 0){
230            fprintf(out_fp,"// ERROR: %s is not found!\n", curr_name);
231            ret = 1;
232        } else {
233            if (count > 1){
234                qsort(matches, count, sizeof(Match), (void*)match_compare);
235            }
236
237            if (matches->fail > 0)
238                fprintf(out_fp,"// Best match: %d%%\n", matches->success*100/(matches->success+matches->fail));
239
240            fprintf(out_fp,"NSTUB(%s, 0x%x)\n", curr_name, matches->ptr);
241
242            for (i=1;i<count && matches[i].fail==matches[0].fail;i++){
243                fprintf(out_fp,"// ALT: NSTUB(%s, 0x%x) // %d/%d\n", curr_name, matches[i].ptr, matches[i].success, matches[i].fail);
244            }
245        }
246    }
247
248    clock_t t2 = clock();
249
250    printf("Time to generate stubs %.2f seconds\n",(double)(t2-t1)/(double)CLOCKS_PER_SEC);
251
252    fclose(out_fp);
253
254    return ret;
255}
256
Note: See TracBrowser for help on using the repository browser.