~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/tools/dumpimage.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Based on mkimage.c.
 
3
 *
 
4
 * Written by Guilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
 
5
 *
 
6
 * SPDX-License-Identifier:     GPL-2.0+
 
7
 */
 
8
 
 
9
#include "dumpimage.h"
 
10
#include <image.h>
 
11
#include <version.h>
 
12
 
 
13
static void usage(void);
 
14
 
 
15
/* image_type_params linked list to maintain registered image types supports */
 
16
static struct image_type_params *dumpimage_tparams;
 
17
 
 
18
/* parameters initialized by core will be used by the image type code */
 
19
static struct image_tool_params params = {
 
20
        .type = IH_TYPE_KERNEL,
 
21
};
 
22
 
 
23
/**
 
24
 * dumpimage_register() - register respective image generation/list support
 
25
 *
 
26
 * the input struct image_type_params is checked and appended to the link
 
27
 * list, if the input structure is already registered, issue an error
 
28
 *
 
29
 * @tparams: Image type parameters
 
30
 */
 
31
static void dumpimage_register(struct image_type_params *tparams)
 
32
{
 
33
        struct image_type_params **tp;
 
34
 
 
35
        if (!tparams) {
 
36
                fprintf(stderr, "%s: %s: Null input\n", params.cmdname,
 
37
                        __func__);
 
38
                exit(EXIT_FAILURE);
 
39
        }
 
40
 
 
41
        /* scan the linked list, check for registry and point the last one */
 
42
        for (tp = &dumpimage_tparams; *tp != NULL; tp = &(*tp)->next) {
 
43
                if (!strcmp((*tp)->name, tparams->name)) {
 
44
                        fprintf(stderr, "%s: %s already registered\n",
 
45
                                params.cmdname, tparams->name);
 
46
                        return;
 
47
                }
 
48
        }
 
49
 
 
50
        /* add input struct entry at the end of link list */
 
51
        *tp = tparams;
 
52
        /* mark input entry as last entry in the link list */
 
53
        tparams->next = NULL;
 
54
 
 
55
        debug("Registered %s\n", tparams->name);
 
56
}
 
57
 
 
58
/**
 
59
 * dumpimage_get_type() - find the image type params for a given image type
 
60
 *
 
61
 * Scan all registered image types and check the input type_id for each
 
62
 * supported image type
 
63
 *
 
64
 * @return respective image_type_params pointer. If the input type is not
 
65
 * supported by any of registered image types, returns NULL
 
66
 */
 
67
static struct image_type_params *dumpimage_get_type(int type)
 
68
{
 
69
        struct image_type_params *curr;
 
70
 
 
71
        for (curr = dumpimage_tparams; curr != NULL; curr = curr->next) {
 
72
                if (curr->check_image_type) {
 
73
                        if (!curr->check_image_type(type))
 
74
                                return curr;
 
75
                }
 
76
        }
 
77
        return NULL;
 
78
}
 
79
 
 
80
/*
 
81
 * dumpimage_verify_print_header() - verifies the image header
 
82
 *
 
83
 * Scan registered image types and verify the image_header for each
 
84
 * supported image type. If verification is successful, this prints
 
85
 * the respective header.
 
86
 *
 
87
 * @return 0 on success, negative if input image format does not match with
 
88
 * any of supported image types
 
89
 */
 
90
static int dumpimage_verify_print_header(void *ptr, struct stat *sbuf)
 
91
{
 
92
        int retval = -1;
 
93
        struct image_type_params *curr;
 
94
 
 
95
        for (curr = dumpimage_tparams; curr != NULL; curr = curr->next) {
 
96
                if (curr->verify_header) {
 
97
                        retval = curr->verify_header((unsigned char *)ptr,
 
98
                                                     sbuf->st_size, &params);
 
99
                        if (retval != 0)
 
100
                                continue;
 
101
                        /*
 
102
                         * Print the image information  if verify is
 
103
                         * successful
 
104
                         */
 
105
                        if (curr->print_header) {
 
106
                                curr->print_header(ptr);
 
107
                        } else {
 
108
                                fprintf(stderr,
 
109
                                        "%s: print_header undefined for %s\n",
 
110
                                        params.cmdname, curr->name);
 
111
                        }
 
112
                        break;
 
113
                }
 
114
        }
 
115
 
 
116
        return retval;
 
117
}
 
118
 
 
119
/*
 
120
 * dumpimage_extract_datafile -
 
121
 *
 
122
 * It scans all registered image types,
 
123
 * verifies image_header for each supported image type
 
124
 * if verification is successful, it extracts the desired file,
 
125
 * indexed by pflag, from the image
 
126
 *
 
127
 * returns negative if input image format does not match with any of
 
128
 * supported image types
 
129
 */
 
130
static int dumpimage_extract_datafile(void *ptr, struct stat *sbuf)
 
131
{
 
132
        int retval = -1;
 
133
        struct image_type_params *curr;
 
134
 
 
135
        for (curr = dumpimage_tparams; curr != NULL; curr = curr->next) {
 
136
                if (curr->verify_header) {
 
137
                        retval = curr->verify_header((unsigned char *)ptr,
 
138
                                                     sbuf->st_size, &params);
 
139
                        if (retval != 0)
 
140
                                continue;
 
141
                        /*
 
142
                         * Extract the file from the image
 
143
                         * if verify is successful
 
144
                         */
 
145
                        if (curr->extract_datafile) {
 
146
                                curr->extract_datafile(ptr, &params);
 
147
                        } else {
 
148
                                fprintf(stderr,
 
149
                                        "%s: extract_datafile undefined for %s\n",
 
150
                                        params.cmdname, curr->name);
 
151
                        break;
 
152
                        }
 
153
                }
 
154
        }
 
155
 
 
156
        return retval;
 
157
}
 
158
 
 
159
int main(int argc, char **argv)
 
160
{
 
161
        int opt;
 
162
        int ifd = -1;
 
163
        struct stat sbuf;
 
164
        char *ptr;
 
165
        int retval = 0;
 
166
        struct image_type_params *tparams = NULL;
 
167
 
 
168
        /* Init all image generation/list support */
 
169
        register_image_tool(dumpimage_register);
 
170
 
 
171
        params.cmdname = *argv;
 
172
 
 
173
        while ((opt = getopt(argc, argv, "li:o:p:V")) != -1) {
 
174
                switch (opt) {
 
175
                case 'l':
 
176
                        params.lflag = 1;
 
177
                        break;
 
178
                case 'i':
 
179
                        params.imagefile = optarg;
 
180
                        params.iflag = 1;
 
181
                        break;
 
182
                case 'o':
 
183
                        params.outfile = optarg;
 
184
                        break;
 
185
                case 'p':
 
186
                        params.pflag = strtoul(optarg, &ptr, 10);
 
187
                        if (*ptr) {
 
188
                                fprintf(stderr,
 
189
                                        "%s: invalid file position %s\n",
 
190
                                        params.cmdname, *argv);
 
191
                                exit(EXIT_FAILURE);
 
192
                        }
 
193
                        break;
 
194
                case 'V':
 
195
                        printf("dumpimage version %s\n", PLAIN_VERSION);
 
196
                        exit(EXIT_SUCCESS);
 
197
                default:
 
198
                        usage();
 
199
                }
 
200
        }
 
201
 
 
202
        if (optind >= argc)
 
203
                usage();
 
204
 
 
205
        /* set tparams as per input type_id */
 
206
        tparams = dumpimage_get_type(params.type);
 
207
        if (tparams == NULL) {
 
208
                fprintf(stderr, "%s: unsupported type %s\n",
 
209
                        params.cmdname, genimg_get_type_name(params.type));
 
210
                exit(EXIT_FAILURE);
 
211
        }
 
212
 
 
213
        /*
 
214
         * check the passed arguments parameters meets the requirements
 
215
         * as per image type to be generated/listed
 
216
         */
 
217
        if (tparams->check_params) {
 
218
                if (tparams->check_params(&params))
 
219
                        usage();
 
220
        }
 
221
 
 
222
        if (params.iflag)
 
223
                params.datafile = argv[optind];
 
224
        else
 
225
                params.imagefile = argv[optind];
 
226
        if (!params.outfile)
 
227
                params.outfile = params.datafile;
 
228
 
 
229
        ifd = open(params.imagefile, O_RDONLY|O_BINARY);
 
230
        if (ifd < 0) {
 
231
                fprintf(stderr, "%s: Can't open \"%s\": %s\n",
 
232
                        params.cmdname, params.imagefile,
 
233
                        strerror(errno));
 
234
                exit(EXIT_FAILURE);
 
235
        }
 
236
 
 
237
        if (params.lflag || params.iflag) {
 
238
                if (fstat(ifd, &sbuf) < 0) {
 
239
                        fprintf(stderr, "%s: Can't stat \"%s\": %s\n",
 
240
                                params.cmdname, params.imagefile,
 
241
                                strerror(errno));
 
242
                        exit(EXIT_FAILURE);
 
243
                }
 
244
 
 
245
                if ((unsigned)sbuf.st_size < tparams->header_size) {
 
246
                        fprintf(stderr,
 
247
                                "%s: Bad size: \"%s\" is not valid image\n",
 
248
                                params.cmdname, params.imagefile);
 
249
                        exit(EXIT_FAILURE);
 
250
                }
 
251
 
 
252
                ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, ifd, 0);
 
253
                if (ptr == MAP_FAILED) {
 
254
                        fprintf(stderr, "%s: Can't read \"%s\": %s\n",
 
255
                                params.cmdname, params.imagefile,
 
256
                                strerror(errno));
 
257
                        exit(EXIT_FAILURE);
 
258
                }
 
259
 
 
260
                /*
 
261
                 * Both calls bellow scan through dumpimage registry for all
 
262
                 * supported image types and verify the input image file
 
263
                 * header for match
 
264
                 */
 
265
                if (params.iflag) {
 
266
                        /*
 
267
                         * Extract the data files from within the matched
 
268
                         * image type. Returns the error code if not matched
 
269
                         */
 
270
                        retval = dumpimage_extract_datafile(ptr, &sbuf);
 
271
                } else {
 
272
                        /*
 
273
                         * Print the image information for matched image type
 
274
                         * Returns the error code if not matched
 
275
                         */
 
276
                        retval = dumpimage_verify_print_header(ptr, &sbuf);
 
277
                }
 
278
 
 
279
                (void)munmap((void *)ptr, sbuf.st_size);
 
280
                (void)close(ifd);
 
281
 
 
282
                return retval;
 
283
        }
 
284
 
 
285
        (void)close(ifd);
 
286
 
 
287
        return EXIT_SUCCESS;
 
288
}
 
289
 
 
290
static void usage(void)
 
291
{
 
292
        fprintf(stderr, "Usage: %s -l image\n"
 
293
                "          -l ==> list image header information\n",
 
294
                params.cmdname);
 
295
        fprintf(stderr,
 
296
                "       %s -i image [-p position] [-o outfile] data_file\n"
 
297
                "          -i ==> extract from the 'image' a specific 'data_file'"
 
298
                ", indexed by 'position' (starting at 0)\n",
 
299
                params.cmdname);
 
300
        fprintf(stderr,
 
301
                "       %s -V ==> print version information and exit\n",
 
302
                params.cmdname);
 
303
 
 
304
        exit(EXIT_FAILURE);
 
305
}