Prepare v2023.10
[platform/kernel/u-boot.git] / tools / dumpimage.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Based on mkimage.c.
4  *
5  * Written by Guilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
6  */
7
8 #include "dumpimage.h"
9 #include <image.h>
10 #include <version.h>
11
12 static void usage(void);
13
14 /* parameters initialized by core will be used by the image type code */
15 static struct image_tool_params params;
16
17 /*
18  * dumpimage_extract_subimage -
19  *
20  * It scans all registered image types,
21  * verifies image_header for each supported image type
22  * if verification is successful, it extracts the desired file,
23  * indexed by pflag, from the image
24  *
25  * returns negative if input image format does not match with any of
26  * supported image types
27  */
28 static int dumpimage_extract_subimage(struct image_type_params *tparams,
29                 void *ptr, struct stat *sbuf)
30 {
31         int retval = -1;
32
33         if (tparams->verify_header) {
34                 retval = tparams->verify_header((unsigned char *)ptr,
35                                 sbuf->st_size, &params);
36                 if (retval != 0) {
37                         fprintf(stderr, "%s: failed to verify header of %s\n",
38                                 params.cmdname, tparams->name);
39                         return -1;
40                 }
41
42                 /*
43                  * Extract the file from the image
44                  * if verify is successful
45                  */
46                 if (tparams->extract_subimage) {
47                         retval = tparams->extract_subimage(ptr, &params);
48                         if (retval != 0) {
49                                 fprintf(stderr, "%s: extract_subimage failed for %s\n",
50                                         params.cmdname, tparams->name);
51                                 return -3;
52                         }
53                 } else {
54                         fprintf(stderr,
55                                 "%s: extract_subimage undefined for %s\n",
56                                 params.cmdname, tparams->name);
57                         return -2;
58                 }
59         }
60
61         return retval;
62 }
63
64 int main(int argc, char **argv)
65 {
66         int opt;
67         int ifd = -1;
68         struct stat sbuf;
69         char *ptr;
70         int retval = EXIT_SUCCESS;
71         struct image_type_params *tparams = NULL;
72
73         params.cmdname = *argv;
74
75         while ((opt = getopt(argc, argv, "hlo:T:p:V")) != -1) {
76                 switch (opt) {
77                 case 'l':
78                         params.lflag = 1;
79                         break;
80                 case 'o':
81                         params.outfile = optarg;
82                         params.iflag = 1;
83                         break;
84                 case 'T':
85                         params.type = genimg_get_type_id(optarg);
86                         if (params.type < 0) {
87                                 fprintf(stderr, "%s: Invalid type\n",
88                                         params.cmdname);
89                                 exit(EXIT_FAILURE);
90                         }
91                         break;
92                 case 'p':
93                         params.pflag = strtoul(optarg, &ptr, 10);
94                         if (*ptr) {
95                                 fprintf(stderr,
96                                         "%s: invalid file position %s\n",
97                                         params.cmdname, *argv);
98                                 exit(EXIT_FAILURE);
99                         }
100                         break;
101                 case 'V':
102                         printf("dumpimage version %s\n", PLAIN_VERSION);
103                         exit(EXIT_SUCCESS);
104                 case 'h':
105                 default:
106                         usage();
107                         break;
108                 }
109         }
110
111         if (argc < 2 || (params.iflag && params.lflag))
112                 usage();
113
114         if (optind >= argc) {
115                 fprintf(stderr, "%s: image file missing\n", params.cmdname);
116                 exit(EXIT_FAILURE);
117         }
118
119         params.imagefile = argv[optind];
120
121         /* set tparams as per input type_id */
122         tparams = imagetool_get_type(params.type);
123         if (!params.lflag && tparams == NULL) {
124                 fprintf(stderr, "%s: unsupported type: %s\n",
125                         params.cmdname, genimg_get_type_name(params.type));
126                 exit(EXIT_FAILURE);
127         }
128
129         /*
130          * check the passed arguments parameters meets the requirements
131          * as per image type to be generated/listed
132          */
133         if (tparams && tparams->check_params) {
134                 if (tparams->check_params(&params)) {
135                         fprintf(stderr, "%s: Parameter check failed\n",
136                                 params.cmdname);
137                         exit(EXIT_FAILURE);
138                 }
139         }
140
141         if (!params.lflag && !params.outfile) {
142                 fprintf(stderr, "%s: No output file provided\n",
143                         params.cmdname);
144                 exit(EXIT_FAILURE);
145         }
146
147         ifd = open(params.imagefile, O_RDONLY|O_BINARY);
148         if (ifd < 0) {
149                 fprintf(stderr, "%s: Can't open \"%s\": %s\n", params.cmdname,
150                         params.imagefile, strerror(errno));
151                 exit(EXIT_FAILURE);
152         }
153
154         if (fstat(ifd, &sbuf) < 0) {
155                 fprintf(stderr, "%s: Can't stat \"%s\": %s\n", params.cmdname,
156                         params.imagefile, strerror(errno));
157                 exit(EXIT_FAILURE);
158         }
159
160         if (tparams && (uint32_t)sbuf.st_size < tparams->header_size) {
161                 fprintf(stderr, "%s: Bad size: \"%s\" is not valid image\n",
162                         params.cmdname, params.imagefile);
163                 exit(EXIT_FAILURE);
164         }
165
166         ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, ifd, 0);
167         if (ptr == MAP_FAILED) {
168                 fprintf(stderr, "%s: Can't read \"%s\": %s\n", params.cmdname,
169                         params.imagefile, strerror(errno));
170                 exit(EXIT_FAILURE);
171         }
172
173         /*
174          * Both calls bellow scan through dumpimage registry for all
175          * supported image types and verify the input image file
176          * header for match
177          */
178         if (params.iflag) {
179                 /*
180                  * Extract the data files from within the matched
181                  * image type. Returns the error code if not matched
182                  */
183                 retval = dumpimage_extract_subimage(tparams, ptr, &sbuf);
184                 if (retval)
185                         fprintf(stderr, "%s: Can't extract subimage from %s\n",
186                                 params.cmdname, params.imagefile);
187         } else {
188                 /*
189                  * Print the image information for matched image type
190                  * Returns the error code if not matched
191                  */
192                 retval = imagetool_verify_print_header(ptr, &sbuf, tparams,
193                                                        &params);
194         }
195
196         (void)munmap((void *)ptr, sbuf.st_size);
197         (void)close(ifd);
198
199         return retval;
200 }
201
202 static void usage(void)
203 {
204         fprintf(stderr, "Usage: %s [-T type] -l image\n"
205                 "          -l ==> list image header information\n"
206                 "          -T ==> parse image file as 'type'\n",
207                 params.cmdname);
208         fprintf(stderr,
209                 "       %s [-T type] [-p position] [-o outfile] image\n"
210                 "          -T ==> declare image type as 'type'\n"
211                 "          -p ==> 'position' (starting at 0) of the component to extract from image\n"
212                 "          -o ==> extract component to file 'outfile'\n",
213                 params.cmdname);
214         fprintf(stderr,
215                 "       %s -h ==> print usage information and exit\n",
216                 params.cmdname);
217         fprintf(stderr,
218                 "       %s -V ==> print version information and exit\n",
219                 params.cmdname);
220
221         exit(EXIT_SUCCESS);
222 }