Bug Summary

File:util/nvidia/cbootimage/src/data_layout.c
Warning:line 604, column 12
Potential leak of memory pointed to by 'hash_buffer'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name data_layout.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/home/coreboot/node-root/workspace/coreboot_scanbuild -resource-dir /opt/xgcc/lib/clang/17 -internal-isystem /opt/xgcc/lib/clang/17/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -source-date-epoch 1714465709 -O2 -std=c99 -fdebug-compilation-dir=/home/coreboot/node-root/workspace/coreboot_scanbuild -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-opt-analyze-headers -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /cb-build/coreboot_scanbuild.0/sharedutils-scanbuildtmp/2024-05-02-073004-2299942-1 -x c util/nvidia/cbootimage/src/data_layout.c
1/*
2 * Copyright (c) 2012-2014, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * See file CREDITS for list of people who contributed to this
17 * project.
18 */
19
20/*
21 * data_layout.c - Code to manage the layout of data in the boot device.
22 *
23 */
24
25#include "data_layout.h"
26#include "cbootimage.h"
27#include "crypto.h"
28#include "set.h"
29#include "context.h"
30#include "parse.h"
31#include <sys/param.h>
32
33typedef struct blk_data_rec
34{
35 uint32_t blk_number;
36 uint32_t pages_used; /* pages always used starting from 0. */
37 uint8_t *data;
38
39 /* Pointer to ECC errors? */
40
41 struct blk_data_rec *next;
42} block_data;
43
44/* Function prototypes */
45static block_data
46*new_block(uint32_t blk_number, uint32_t block_size);
47static block_data
48*find_block(uint32_t blk_number, block_data *block_list);
49static block_data
50*add_block(uint32_t blk_number, block_data **block_list,
51 uint32_t block_size);
52static int
53erase_block(build_image_context *context, uint32_t blk_number);
54
55static int
56write_page(build_image_context *context,
57 uint32_t blk_number,
58 uint32_t page_number,
59 uint8_t *data);
60
61static void
62insert_padding(uint8_t *data, uint32_t length);
63
64static void
65write_padding(uint8_t *data, uint32_t length);
66
67static int write_bct(build_image_context *context,
68 uint32_t block,
69 uint32_t bct_slot);
70
71static void
72set_bl_data(build_image_context *context,
73 uint32_t instance,
74 uint32_t start_blk,
75 uint32_t start_page,
76 uint32_t length);
77
78static int write_image(build_image_context *context, file_type image_type);
79
80static void find_new_bct_blk(build_image_context *context);
81static int finish_update(build_image_context *context);
82
83uint32_t
84iceil_log2(uint32_t a, uint32_t b)
85{
86 return (a + (1 << b) - 1) >> b;
87}
88
89/* Returns the smallest power of 2 >= a */
90uint32_t
91ceil_log2(uint32_t a)
92{
93 uint32_t result;
94
95 result = log2(a);
96 if ((1UL << result) < a)
97 result++;
98
99 return result;
100}
101
102static block_data *new_block(uint32_t blk_number, uint32_t block_size)
103{
104 block_data *new_block = malloc(sizeof(block_data));
105 if (new_block == NULL((void*)0))
106 return NULL((void*)0);
107
108 new_block->blk_number = blk_number;
109 new_block->pages_used = 0;
110 new_block->data = malloc(block_size);
111 if (new_block->data == NULL((void*)0)) {
112 free(new_block);
113 return NULL((void*)0);
114 }
115 new_block->next = NULL((void*)0);
116
117 memset(new_block->data, 0, block_size);
118
119 return new_block;
120}
121
122block_data *new_block_list(void)
123{
124 return NULL((void*)0);
125}
126
127void destroy_block_list(block_data *block_list)
128{
129 block_data *next;
130
131 while (block_list) {
132 next = block_list->next;
133 free(block_list->data);
134 free(block_list);
135 block_list = next;
136 }
137}
138
139static block_data *find_block(uint32_t blk_number, block_data *block_list)
140{
141 while (block_list) {
142 if (block_list->blk_number == blk_number)
143 return block_list;
144
145 block_list = block_list->next;
146 }
147
148 return NULL((void*)0);
149}
150
151/* Returns pointer to block after adding it to block_list, if needed. */
152static block_data *add_block(uint32_t blk_number,
153 block_data **block_list,
154 uint32_t block_size)
155{
156 block_data *block = find_block(blk_number,*block_list);
157 block_data *parent;
158
159 if (block == NULL((void*)0)) {
160 block = new_block(blk_number, block_size);
161 if (block == NULL((void*)0))
162 return block;
163
164 /* Insert block into the list */
165 if ((*block_list == NULL((void*)0)) ||
166 (blk_number < (*block_list)->blk_number)) {
167 block->next = *block_list;
168 *block_list = block;
169 } else {
170 /* Search for the correct place to insert the block. */
171 parent = *block_list;
172 while (parent->next != NULL((void*)0) &&
173 parent->next->blk_number < blk_number) {
174 parent = parent->next;
175 }
176
177 block->next = parent->next;
178 parent->next = block;
179 }
180 }
181
182 return block;
183}
184
185static int
186erase_block(build_image_context *context, uint32_t blk_number)
187{
188 block_data *block;
189
190 assert(context != NULL)((context != ((void*)0)) ? (void) (0) : __assert_fail ("context != NULL"
, "util/nvidia/cbootimage/src/data_layout.c", 190, __extension__
__PRETTY_FUNCTION__))
;
191
192 block = add_block(blk_number, &(context->memory), context->block_size);
193
194 if (block == NULL((void*)0))
195 return -ENOMEM12;
196 if (block->data == NULL((void*)0))
197 return -ENOMEM12;
198
199 memset(block->data, 0, context->block_size);
200 block->pages_used = 0;
201 return 0;
202}
203
204static int
205write_page(build_image_context *context,
206 uint32_t blk_number,
207 uint32_t page_number,
208 uint8_t *data)
209{
210 block_data *block;
211 uint8_t *page_ptr;
212
213 assert(context)((context) ? (void) (0) : __assert_fail ("context", "util/nvidia/cbootimage/src/data_layout.c"
, 213, __extension__ __PRETTY_FUNCTION__))
;
214
215 block = add_block(blk_number, &(context->memory), context->block_size);
216
217 if (block == NULL((void*)0))
218 return -ENOMEM12;
219 if (block->data == NULL((void*)0))
220 return -ENOMEM12;
221 if (((page_number + 1) * context->page_size) > context->block_size) {
222 printf("Page number outside block; likely config file error.\n");
223 return -ENOMEM12;
224 }
225
226 if (block->pages_used != page_number) {
227 printf("Warning: Writing page in block out of order.\n");
228 printf(" block=%d page=%d\n", blk_number, page_number);
229 }
230
231 page_ptr = block->data + (page_number * context->page_size);
232 memcpy(page_ptr, data, context->page_size);
233 if (block->pages_used < (page_number+1))
234 block->pages_used = page_number+1;
235 return 0;
236}
237
238static void
239insert_padding(uint8_t *data, uint32_t length)
240{
241 uint32_t aes_blks;
242 uint32_t remaining;
243
244 aes_blks = iceil_log2(length, NVBOOT_AES_BLOCK_SIZE_LOG24);
245 remaining = (aes_blks << NVBOOT_AES_BLOCK_SIZE_LOG24) - length;
246
247 write_padding(data + length, remaining);
248}
249
250static void
251write_padding(uint8_t *p, uint32_t remaining)
252{
253 uint8_t value = 0x80;
254
255 while (remaining) {
256 *p++ = value;
257 remaining--;
258 value = 0x00;
259 }
260}
261
262static int
263write_bct(build_image_context *context,
264 uint32_t block,
265 uint32_t bct_slot)
266{
267 uint32_t pagesremaining;
268 uint32_t page;
269 uint32_t pages_per_bct;
270 uint8_t *buffer;
271 uint8_t *data;
272 int err = 0;
273
274 assert(context)((context) ? (void) (0) : __assert_fail ("context", "util/nvidia/cbootimage/src/data_layout.c"
, 274, __extension__ __PRETTY_FUNCTION__))
;
275
276 pages_per_bct = iceil_log2(context->bct_size, context->page_size_log2);
277 pagesremaining = pages_per_bct;
278 page = bct_slot * pages_per_bct;
279
280 /* Create a local copy of the BCT data */
281 buffer = malloc(pages_per_bct * context->page_size);
282 if (buffer == NULL((void*)0))
283 return -ENOMEM12;
284 memset(buffer, 0, pages_per_bct * context->page_size);
285
286 memcpy(buffer, context->bct, context->bct_size);
287
288 insert_padding(buffer, context->bct_size);
289
290 /* Encrypt and compute hash */
291 err = sign_bct(context, buffer);
292 if (err != 0)
293 goto fail;
294
295 /* Write the BCT data to the storage device, picking up ECC errors */
296 data = buffer;
297 while (pagesremaining > 0) {
298 err = write_page(context, block, page, data);
299 if (err != 0)
300 goto fail;
301 page++;
302 pagesremaining--;
303 data += context->page_size;
304 }
305fail:
306 /* Cleanup */
307 free(buffer);
308 return err;
309}
310
311#define SET_BL_FIELD(instance, field, value)do { g_soc_config->setbl_param(instance, token_bl_field, &
(value), context->bct); } while (0);
\
312do { \
313 g_soc_config->setbl_param(instance, \
314 token_bl_##field, \
315 &(value), \
316 context->bct); \
317} while (0);
318
319#define GET_BL_FIELD(instance, field, ptr)g_soc_config->getbl_param(instance, token_bl_field, ptr, context
->bct);
\
320g_soc_config->getbl_param(instance, \
321 token_bl_##field, \
322 ptr, \
323 context->bct);
324
325#define COPY_BL_FIELD(from, to, field)do { uint32_t v; g_soc_config->getbl_param(from, token_bl_field
, &v, context->bct);; do { g_soc_config->setbl_param
(to, token_bl_field, &(v), context->bct); } while (0);
; } while (0);
\
326do { \
327 uint32_t v; \
328 GET_BL_FIELD(from, field, &v)g_soc_config->getbl_param(from, token_bl_field, &v, context
->bct);
; \
329 SET_BL_FIELD(to, field, v)do { g_soc_config->setbl_param(to, token_bl_field, &(v
), context->bct); } while (0);
; \
330} while (0);
331
332#define SET_MTS_FIELD(instance, field, value)do { g_soc_config->set_mts_info(context, instance, token_mts_info_field
, value); } while (0);
\
333do { \
334 g_soc_config->set_mts_info(context, \
335 instance, \
336 token_mts_info_##field, \
337 value); \
338} while (0);
339
340#define GET_MTS_FIELD(instance, field, ptr)g_soc_config->get_mts_info(context, instance, token_mts_info_field
, ptr);
\
341g_soc_config->get_mts_info(context, \
342 instance, \
343 token_mts_info_##field, \
344 ptr);
345
346#define COPY_MTS_FIELD(from, to, field)do { uint32_t v; g_soc_config->get_mts_info(context, from,
token_mts_info_field, &v);; do { g_soc_config->set_mts_info
(context, to, token_mts_info_field, v); } while (0);; } while
(0);
\
347do { \
348 uint32_t v; \
349 GET_MTS_FIELD(from, field, &v)g_soc_config->get_mts_info(context, from, token_mts_info_field
, &v);
; \
350 SET_MTS_FIELD(to, field, v)do { g_soc_config->set_mts_info(context, to, token_mts_info_field
, v); } while (0);
; \
351} while (0);
352
353#define SET_FIELD(is_bl, instance, field, value)do { if (is_bl) { do { g_soc_config->setbl_param(instance,
token_bl_field, &(value), context->bct); } while (0);
; } else { do { g_soc_config->set_mts_info(context, instance
, token_mts_info_field, value); } while (0);; } } while (0);
\
354do { \
355 if (is_bl) { \
356 SET_BL_FIELD(instance, field,value)do { g_soc_config->setbl_param(instance, token_bl_field, &
(value), context->bct); } while (0);
; \
357 } \
358 else { \
359 SET_MTS_FIELD(instance, field, value)do { g_soc_config->set_mts_info(context, instance, token_mts_info_field
, value); } while (0);
; \
360 } \
361} while (0);
362
363#define GET_FIELD(is_bl, instance, field, ptr)do { if (is_bl) { g_soc_config->getbl_param(instance, token_bl_field
, ptr, context->bct);; } else { g_soc_config->get_mts_info
(context, instance, token_mts_info_field, ptr);; } } while (0
);
\
364do { \
365 if (is_bl) { \
366 GET_BL_FIELD(instance, field, ptr)g_soc_config->getbl_param(instance, token_bl_field, ptr, context
->bct);
; \
367 } \
368 else { \
369 GET_MTS_FIELD(instance, field, ptr)g_soc_config->get_mts_info(context, instance, token_mts_info_field
, ptr);
; \
370 } \
371} while (0);
372
373#define COPY_FIELD(is_bl, from, to, field)do { if (is_bl) { do { uint32_t v; g_soc_config->getbl_param
(from, token_bl_field, &v, context->bct);; do { g_soc_config
->setbl_param(to, token_bl_field, &(v), context->bct
); } while (0);; } while (0);; } else { do { uint32_t v; g_soc_config
->get_mts_info(context, from, token_mts_info_field, &v
);; do { g_soc_config->set_mts_info(context, to, token_mts_info_field
, v); } while (0);; } while (0);; } } while (0);
\
374do { \
375 if (is_bl) { \
376 COPY_BL_FIELD(from, to, field)do { uint32_t v; g_soc_config->getbl_param(from, token_bl_field
, &v, context->bct);; do { g_soc_config->setbl_param
(to, token_bl_field, &(v), context->bct); } while (0);
; } while (0);
; \
377 } \
378 else { \
379 COPY_MTS_FIELD(from, to, field)do { uint32_t v; g_soc_config->get_mts_info(context, from,
token_mts_info_field, &v);; do { g_soc_config->set_mts_info
(context, to, token_mts_info_field, v); } while (0);; } while
(0);
; \
380 } \
381} while (0);
382
383static void
384set_bl_data(build_image_context *context,
385 uint32_t instance,
386 uint32_t start_blk,
387 uint32_t start_page,
388 uint32_t length)
389{
390 assert(context)((context) ? (void) (0) : __assert_fail ("context", "util/nvidia/cbootimage/src/data_layout.c"
, 390, __extension__ __PRETTY_FUNCTION__))
;
391
392 SET_BL_FIELD(instance, version, context->version)do { g_soc_config->setbl_param(instance, token_bl_version,
&(context->version), context->bct); } while (0);
;
393 SET_BL_FIELD(instance, start_blk, start_blk)do { g_soc_config->setbl_param(instance, token_bl_start_blk
, &(start_blk), context->bct); } while (0);
;
394 SET_BL_FIELD(instance, start_page, start_page)do { g_soc_config->setbl_param(instance, token_bl_start_page
, &(start_page), context->bct); } while (0);
;
395 SET_BL_FIELD(instance, length, length)do { g_soc_config->setbl_param(instance, token_bl_length, &
(length), context->bct); } while (0);
;
396 SET_BL_FIELD(instance, load_addr, context->newbl_load_addr)do { g_soc_config->setbl_param(instance, token_bl_load_addr
, &(context->newbl_load_addr), context->bct); } while
(0);
;
397 SET_BL_FIELD(instance, entry_point, context->newbl_entry_point)do { g_soc_config->setbl_param(instance, token_bl_entry_point
, &(context->newbl_entry_point), context->bct); } while
(0);
;
398 SET_BL_FIELD(instance, attribute, context->newbl_attr)do { g_soc_config->setbl_param(instance, token_bl_attribute
, &(context->newbl_attr), context->bct); } while (0
);
;
399}
400
401static void
402set_mts_data(build_image_context *context,
403 uint32_t instance,
404 uint32_t start_blk,
405 uint32_t start_page,
406 uint32_t length)
407{
408 assert(context)((context) ? (void) (0) : __assert_fail ("context", "util/nvidia/cbootimage/src/data_layout.c"
, 408, __extension__ __PRETTY_FUNCTION__))
;
409
410 SET_MTS_FIELD(instance, version, context->version)do { g_soc_config->set_mts_info(context, instance, token_mts_info_version
, context->version); } while (0);
;
411 SET_MTS_FIELD(instance, start_blk, start_blk)do { g_soc_config->set_mts_info(context, instance, token_mts_info_start_blk
, start_blk); } while (0);
;
412 SET_MTS_FIELD(instance, start_page, start_page)do { g_soc_config->set_mts_info(context, instance, token_mts_info_start_page
, start_page); } while (0);
;
413 SET_MTS_FIELD(instance, length, length)do { g_soc_config->set_mts_info(context, instance, token_mts_info_length
, length); } while (0);
;
414 SET_MTS_FIELD(instance, load_addr, context->mts_load_addr)do { g_soc_config->set_mts_info(context, instance, token_mts_info_load_addr
, context->mts_load_addr); } while (0);
;
415 SET_MTS_FIELD(instance, entry_point, context->mts_entry_point)do { g_soc_config->set_mts_info(context, instance, token_mts_info_entry_point
, context->mts_entry_point); } while (0);
;
416 SET_MTS_FIELD(instance, attribute, context->mts_attr)do { g_soc_config->set_mts_info(context, instance, token_mts_info_attribute
, context->mts_attr); } while (0);
;
417}
418
419#define SET_DATA(is_bl, context, instance, start_blk, start_page, length)do { if (is_bl) set_bl_data(context, instance, start_blk, start_page
, length); else set_mts_data(context, instance, start_blk, start_page
, length); } while (0);
\
420do { \
421 if (is_bl) \
422 set_bl_data(context, instance, start_blk, start_page, length); \
423 else \
424 set_mts_data(context, instance, start_blk, start_page, length); \
425} while (0);
426
427/*
428 * Load the image then update it with the information from config file.
429 * In the interest of expediency, all image's allocated from bottom to top
430 * start at page 0 of a block, and all image's allocated from top to bottom
431 * end at the end of a block.
432 *
433 * @param context The main context pointer
434 * @param image_type The image type. Can be file_type_bl or file_type_mts
435 * only right now
436 * @return 0 for success
437 */
438static int
439write_image(build_image_context *context, file_type image_type)
440{
441 uint32_t i, j;
442 uint32_t image_instance;
443 uint32_t image_move_count = 0;
444 uint32_t image_move_remaining;
445 uint32_t current_blk;
446 uint32_t current_page;
447 uint32_t pages_in_image;
448 uint32_t image_used;
449 uint8_t *image_storage; /* Holds the image after reading */
450 uint8_t *buffer; /* Holds the image for writing */
451 uint8_t *src; /* Scans through the image during writing */
452 uint32_t image_actual_size; /* In bytes */
453 uint32_t pagesremaining;
454 uint32_t virtual_blk;
455 uint32_t pages_per_blk;
456 uint32_t image_version;
457 uint8_t *hash_buffer;
458 uint32_t hash_size;
459 uint32_t image_max;
460 parse_token token;
461 int err = 0, is_bl;
462
463 assert(context)((context) ? (void) (0) : __assert_fail ("context", "util/nvidia/cbootimage/src/data_layout.c"
, 463, __extension__ __PRETTY_FUNCTION__))
;
1
Assuming 'context' is non-null
2
'?' condition is true
464
465 /* Only support bootloader and mts image right now */
466 if (image_type == file_type_bl) {
3
Assuming 'image_type' is equal to file_type_bl
4
Taking true branch
467 is_bl = 1;
468 }
469 else if (image_type == file_type_mts) {
470 is_bl = 0;
471 }
472 else {
473 printf("Not supported image type!\n");
474 return -EINVAL22;
475 }
476
477 pages_per_blk = 1 << (context->block_size_log2
478 - context->page_size_log2);
479
480 g_soc_config->get_value(token_hash_size,
481 &hash_size, context->bct);
482 token = is_bl
4.1
'is_bl' is 1
? token_bootloaders_max : token_mts_max;
5
'?' condition is true
483 g_soc_config->get_value(token, &image_max, context->bct);
484
485 hash_buffer = calloc(1, hash_size);
6
Memory is allocated
486 if (hash_buffer == NULL((void*)0))
7
Assuming 'hash_buffer' is not equal to NULL
8
Taking false branch
487 return -ENOMEM12;
488
489 if (enable_debug) {
9
Assuming 'enable_debug' is 0
10
Taking false branch
490 printf("writing %s\n", is_bl ? "bootloader" : "mts image");
491 printf(" redundancy = %d\n", context->redundancy);
492 }
493
494 /* Make room for the image in the BCT. */
495
496 /* Determine how many to move.
497 * Note that this code will count Mts[0] only if there is already
498 * a mts in the device.
499 */
500 GET_FIELD(is_bl, 0, version, &image_version)do { if (is_bl) { g_soc_config->getbl_param(0, token_bl_version
, &image_version, context->bct);; } else { g_soc_config
->get_mts_info(context, 0, token_mts_info_version, &image_version
);; } } while (0);
;
11
Taking true branch
501 token = is_bl
12.1
'is_bl' is 1
? token_bootloader_used : token_mts_used;
12
Loop condition is false. Exiting loop
13
'?' condition is true
502 g_soc_config->get_value(token, &image_used, context->bct);
503 for (image_instance = 0; image_instance < image_used; image_instance++) {
14
Assuming 'image_instance' is >= 'image_used'
504 uint32_t tmp;
505 GET_FIELD(is_bl, image_instance, version, &tmp)do { if (is_bl) { g_soc_config->getbl_param(image_instance
, token_bl_version, &tmp, context->bct);; } else { g_soc_config
->get_mts_info(context, image_instance, token_mts_info_version
, &tmp);; } } while (0);
;
506 if (tmp == image_version)
507 image_move_count++;
508 }
509
510 /* Adjust the move count, if needed, to avoid overflowing the mts table.
511 * This can happen due to too much redundancy.
512 */
513 image_move_count = MIN(image_move_count, image_max - context->redundancy)(((image_move_count)<(image_max - context->redundancy))
?(image_move_count):(image_max - context->redundancy))
;
15
Loop condition is false. Execution continues on line 513
16
Assuming the condition is true
17
'?' condition is true
514
515 /* Move the mts entries down. */
516 image_move_remaining = image_move_count;
517 while (image_move_remaining > 0) {
18
Loop condition is false. Execution continues on line 545
518 uint32_t inst_from = image_move_remaining - 1;
519 uint32_t inst_to =
520 image_move_remaining + context->redundancy - 1;
521
522 COPY_FIELD(is_bl, inst_from, inst_to, version)do { if (is_bl) { do { uint32_t v; g_soc_config->getbl_param
(inst_from, token_bl_version, &v, context->bct);; do {
g_soc_config->setbl_param(inst_to, token_bl_version, &
(v), context->bct); } while (0);; } while (0);; } else { do
{ uint32_t v; g_soc_config->get_mts_info(context, inst_from
, token_mts_info_version, &v);; do { g_soc_config->set_mts_info
(context, inst_to, token_mts_info_version, v); } while (0);; }
while (0);; } } while (0);
;
523 COPY_FIELD(is_bl, inst_from, inst_to, start_blk)do { if (is_bl) { do { uint32_t v; g_soc_config->getbl_param
(inst_from, token_bl_start_blk, &v, context->bct);; do
{ g_soc_config->setbl_param(inst_to, token_bl_start_blk, &
(v), context->bct); } while (0);; } while (0);; } else { do
{ uint32_t v; g_soc_config->get_mts_info(context, inst_from
, token_mts_info_start_blk, &v);; do { g_soc_config->set_mts_info
(context, inst_to, token_mts_info_start_blk, v); } while (0);
; } while (0);; } } while (0);
;
524 COPY_FIELD(is_bl, inst_from, inst_to, start_page)do { if (is_bl) { do { uint32_t v; g_soc_config->getbl_param
(inst_from, token_bl_start_page, &v, context->bct);; do
{ g_soc_config->setbl_param(inst_to, token_bl_start_page,
&(v), context->bct); } while (0);; } while (0);; } else
{ do { uint32_t v; g_soc_config->get_mts_info(context, inst_from
, token_mts_info_start_page, &v);; do { g_soc_config->
set_mts_info(context, inst_to, token_mts_info_start_page, v);
} while (0);; } while (0);; } } while (0);
;
525 COPY_FIELD(is_bl, inst_from, inst_to, length)do { if (is_bl) { do { uint32_t v; g_soc_config->getbl_param
(inst_from, token_bl_length, &v, context->bct);; do { g_soc_config
->setbl_param(inst_to, token_bl_length, &(v), context->
bct); } while (0);; } while (0);; } else { do { uint32_t v; g_soc_config
->get_mts_info(context, inst_from, token_mts_info_length, &
v);; do { g_soc_config->set_mts_info(context, inst_to, token_mts_info_length
, v); } while (0);; } while (0);; } } while (0);
;
526 COPY_FIELD(is_bl, inst_from, inst_to, load_addr)do { if (is_bl) { do { uint32_t v; g_soc_config->getbl_param
(inst_from, token_bl_load_addr, &v, context->bct);; do
{ g_soc_config->setbl_param(inst_to, token_bl_load_addr, &
(v), context->bct); } while (0);; } while (0);; } else { do
{ uint32_t v; g_soc_config->get_mts_info(context, inst_from
, token_mts_info_load_addr, &v);; do { g_soc_config->set_mts_info
(context, inst_to, token_mts_info_load_addr, v); } while (0);
; } while (0);; } } while (0);
;
527 COPY_FIELD(is_bl, inst_from, inst_to, entry_point)do { if (is_bl) { do { uint32_t v; g_soc_config->getbl_param
(inst_from, token_bl_entry_point, &v, context->bct);; do
{ g_soc_config->setbl_param(inst_to, token_bl_entry_point
, &(v), context->bct); } while (0);; } while (0);; } else
{ do { uint32_t v; g_soc_config->get_mts_info(context, inst_from
, token_mts_info_entry_point, &v);; do { g_soc_config->
set_mts_info(context, inst_to, token_mts_info_entry_point, v)
; } while (0);; } while (0);; } } while (0);
;
528 COPY_FIELD(is_bl, inst_from, inst_to, attribute)do { if (is_bl) { do { uint32_t v; g_soc_config->getbl_param
(inst_from, token_bl_attribute, &v, context->bct);; do
{ g_soc_config->setbl_param(inst_to, token_bl_attribute, &
(v), context->bct); } while (0);; } while (0);; } else { do
{ uint32_t v; g_soc_config->get_mts_info(context, inst_from
, token_mts_info_attribute, &v);; do { g_soc_config->set_mts_info
(context, inst_to, token_mts_info_attribute, v); } while (0);
; } while (0);; } } while (0);
;
529
530 if (is_bl) {
531 g_soc_config->getbl_param(inst_from,
532 token_bl_crypto_hash,
533 (uint32_t*)hash_buffer,
534 context->bct);
535 g_soc_config->setbl_param(inst_to,
536 token_bl_crypto_hash,
537 (uint32_t*)hash_buffer,
538 context->bct);
539 }
540
541 image_move_remaining--;
542 }
543
544 /* Read the image into memory. */
545 if (read_from_image(
21
Assuming the condition is false
22
Taking false branch
546 is_bl
18.1
'is_bl' is 1
? context->newbl_filename : context->mts_filename,
19
'?' condition is true
547 0,
548 is_bl
19.1
'is_bl' is 1
? MAX_BOOTLOADER_SIZE(16 * 1024 * 1024) : MAX_MTS_SIZE(4 * 1024 * 1024),
20
'?' condition is true
549 &image_storage,
550 &image_actual_size,
551 image_type) == 1) {
552 printf("Error reading image %s.\n",
553 is_bl ? context->newbl_filename : context->mts_filename);
554 exit(1);
555 }
556
557 pages_in_image = iceil_log2(image_actual_size, context->page_size_log2);
558
559 current_blk = context->next_bct_blk;
560 current_page = 0;
561 for (image_instance = 0; image_instance < context->redundancy;
23
Assuming 'image_instance' is < field 'redundancy'
24
Loop condition is true. Entering loop body
28
Assuming 'image_instance' is >= field 'redundancy'
29
Loop condition is false. Execution continues on line 598
562 image_instance++) {
563
564 pagesremaining = pages_in_image;
565 /* Advance to the next block if needed. */
566 if (current_page
24.1
'current_page' is <= 0
> 0) {
25
Taking false branch
567 current_blk++;
568 current_page = 0;
569 }
570
571 virtual_blk = 0;
572
573 while (pagesremaining > 0) {
26
Assuming 'pagesremaining' is <= 0
27
Loop condition is false. Execution continues on line 562
574 /* Update the bad block table with relative
575 * bad blocks.
576 */
577 if (virtual_blk == 0) {
578 SET_DATA(is_bl,do { if (is_bl) set_bl_data(context, image_instance, current_blk
, current_page, image_actual_size); else set_mts_data(context
, image_instance, current_blk, current_page, image_actual_size
); } while (0);
579 context,do { if (is_bl) set_bl_data(context, image_instance, current_blk
, current_page, image_actual_size); else set_mts_data(context
, image_instance, current_blk, current_page, image_actual_size
); } while (0);
580 image_instance,do { if (is_bl) set_bl_data(context, image_instance, current_blk
, current_page, image_actual_size); else set_mts_data(context
, image_instance, current_blk, current_page, image_actual_size
); } while (0);
581 current_blk,do { if (is_bl) set_bl_data(context, image_instance, current_blk
, current_page, image_actual_size); else set_mts_data(context
, image_instance, current_blk, current_page, image_actual_size
); } while (0);
582 current_page,do { if (is_bl) set_bl_data(context, image_instance, current_blk
, current_page, image_actual_size); else set_mts_data(context
, image_instance, current_blk, current_page, image_actual_size
); } while (0);
583 image_actual_size)do { if (is_bl) set_bl_data(context, image_instance, current_blk
, current_page, image_actual_size); else set_mts_data(context
, image_instance, current_blk, current_page, image_actual_size
); } while (0);
;
584 }
585
586 if (pagesremaining > pages_per_blk) {
587 current_blk++;
588 virtual_blk++;
589 pagesremaining -= pages_per_blk;
590 } else {
591 current_page = pagesremaining;
592 pagesremaining = 0;
593 }
594 }
595 }
596
597 /* Scan forwards to write each copy. */
598 for (image_instance = 0; image_instance < context->redundancy;
30
Loop condition is true. Entering loop body
599 image_instance++) {
600
601 /* Create a local copy of the BCT data */
602 buffer = malloc(pages_in_image * context->page_size);
603 if (buffer == NULL((void*)0))
31
Assuming 'buffer' is equal to NULL
32
Taking true branch
604 return -ENOMEM12;
33
Potential leak of memory pointed to by 'hash_buffer'
605
606 memset(buffer, 0, pages_in_image * context->page_size);
607 memcpy(buffer, image_storage, image_actual_size);
608
609 insert_padding(buffer, image_actual_size);
610
611 pagesremaining = pages_in_image;
612
613 if (is_bl) {
614 GET_BL_FIELD(image_instance, start_blk, &current_blk)g_soc_config->getbl_param(image_instance, token_bl_start_blk
, &current_blk, context->bct);
;
615 GET_BL_FIELD(image_instance, start_page, &current_page)g_soc_config->getbl_param(image_instance, token_bl_start_page
, &current_page, context->bct);
;
616
617 /* Encrypt and compute hash */
618 sign_data_block(buffer,
619 image_actual_size,
620 hash_buffer);
621 g_soc_config->setbl_param(image_instance,
622 token_bl_crypto_hash,
623 (uint32_t*)hash_buffer,
624 context->bct);
625 }
626
627 GET_FIELD(is_bl, image_instance, start_blk, &current_blk)do { if (is_bl) { g_soc_config->getbl_param(image_instance
, token_bl_start_blk, &current_blk, context->bct);; } else
{ g_soc_config->get_mts_info(context, image_instance, token_mts_info_start_blk
, &current_blk);; } } while (0);
;
628 GET_FIELD(is_bl, image_instance, start_page, &current_page)do { if (is_bl) { g_soc_config->getbl_param(image_instance
, token_bl_start_page, &current_page, context->bct);; }
else { g_soc_config->get_mts_info(context, image_instance
, token_mts_info_start_page, &current_page);; } } while (
0);
;
629
630 /* Write the BCT data to the storage device,
631 * picking up ECC errors
632 */
633 src = buffer;
634
635 /* Write pages as we go. */
636 virtual_blk = 0;
637 while (pagesremaining) {
638 if (current_page == 0) {
639 /* Erase the block before writing into it. */
640 erase_block(context, current_blk);
641 }
642
643 err = write_page(context,
644 current_blk, current_page, src);
645 if (err != 0)
646 goto fail;
647 pagesremaining--;
648 src += context->page_size;
649 current_page++;
650 if (current_page >= pages_per_blk) {
651 current_page = 0;
652 current_blk++;
653 virtual_blk++;
654 }
655 context->last_blk = current_blk;
656 }
657 context->next_bct_blk = context->last_blk + 1;
658 free(buffer);
659 }
660
661 image_used = context->redundancy + image_move_count;
662 token = is_bl ? token_bootloader_used : token_mts_used;
663 g_soc_config->set_value(token, &image_used, context->bct);
664
665 if (enable_debug) {
666 for (i = 0; i < image_max; i++) {
667 uint32_t version;
668 uint32_t start_blk;
669 uint32_t start_page;
670 uint32_t length;
671 uint32_t load_addr;
672 uint32_t entry_point;
673
674 GET_FIELD(is_bl, i, version, &version)do { if (is_bl) { g_soc_config->getbl_param(i, token_bl_version
, &version, context->bct);; } else { g_soc_config->
get_mts_info(context, i, token_mts_info_version, &version
);; } } while (0);
;
675 GET_FIELD(is_bl, i, start_blk, &start_blk)do { if (is_bl) { g_soc_config->getbl_param(i, token_bl_start_blk
, &start_blk, context->bct);; } else { g_soc_config->
get_mts_info(context, i, token_mts_info_start_blk, &start_blk
);; } } while (0);
;
676 GET_FIELD(is_bl, i, start_page, &start_page)do { if (is_bl) { g_soc_config->getbl_param(i, token_bl_start_page
, &start_page, context->bct);; } else { g_soc_config->
get_mts_info(context, i, token_mts_info_start_page, &start_page
);; } } while (0);
;
677 GET_FIELD(is_bl, i, length, &length)do { if (is_bl) { g_soc_config->getbl_param(i, token_bl_length
, &length, context->bct);; } else { g_soc_config->get_mts_info
(context, i, token_mts_info_length, &length);; } } while (
0);
;
678 GET_FIELD(is_bl, i, load_addr, &load_addr)do { if (is_bl) { g_soc_config->getbl_param(i, token_bl_load_addr
, &load_addr, context->bct);; } else { g_soc_config->
get_mts_info(context, i, token_mts_info_load_addr, &load_addr
);; } } while (0);
;
679 GET_FIELD(is_bl, i, entry_point, &entry_point)do { if (is_bl) { g_soc_config->getbl_param(i, token_bl_entry_point
, &entry_point, context->bct);; } else { g_soc_config->
get_mts_info(context, i, token_mts_info_entry_point, &entry_point
);; } } while (0);
;
680
681 printf("%s%s[%d]: %d %04d %04d %04d 0x%08x 0x%08x\n",
682 i < image_used ? " " : "**",
683 is_bl ? "BL" : "MTS",
684 i,
685 version,
686 start_blk,
687 start_page,
688 length,
689 load_addr,
690 entry_point);
691 if (is_bl) {
692 g_soc_config->getbl_param(i,
693 token_bl_crypto_hash,
694 (uint32_t*)hash_buffer,
695 context->bct);
696 for (j = 0; j < hash_size / 4; j++) {
697 printf("%08x",
698 *((uint32_t*)(hash_buffer + 4*j)));
699 }
700 printf("\n");
701 }
702 }
703 }
704 free(image_storage);
705 free(hash_buffer);
706 return 0;
707
708fail:
709 /* Cleanup. */
710 free(buffer);
711 free(image_storage);
712 free(hash_buffer);
713 printf("Write image failed, error: %d.\n", err);
714 return err;
715}
716
717void
718update_context(struct build_image_context_rec *context)
719{
720 g_soc_config->get_value(token_partition_size,
721 &context->partition_size,
722 context->bct);
723 g_soc_config->get_value(token_page_size_log2,
724 &context->page_size_log2,
725 context->bct);
726 g_soc_config->get_value(token_block_size_log2,
727 &context->block_size_log2,
728 context->bct);
729 g_soc_config->get_value(token_odm_data,
730 &context->odm_data,
731 context->bct);
732
733 context->page_size = 1 << context->page_size_log2;
734 context->block_size = 1 << context->block_size_log2;
735 context->pages_per_blk = 1 << (context->block_size_log2 -
736 context->page_size_log2);
737}
738
739/*
740 * Allocate and initialize the memory for bct data.
741 *
742 * @param context The main context pointer
743 * @return 0 for success
744 */
745int
746init_bct(struct build_image_context_rec *context)
747{
748 /* Allocate space for the bct. */
749 context->bct = malloc(context->bct_size);
750
751 if (context->bct == NULL((void*)0))
752 return -ENOMEM12;
753
754 memset(context->bct, 0, context->bct_size);
755 context->bct_init = 1;
756
757 return 0;
758}
759
760/*
761 * Read the bct data from given file to allocated memory.
762 * Assign the global parse interface to corresponding hardware interface
763 * according to the boot data version in bct file.
764 *
765 * @param context The main context pointer
766 * @return 0 for success
767 */
768int
769read_bct_file(struct build_image_context_rec *context)
770{
771 uint8_t *bct_storage; /* Holds the Bl after reading */
772 uint32_t bct_actual_size; /* In bytes */
773 file_type bct_filetype = file_type_bct;
774 int err = 0;
775
776 if (read_from_image(context->bct_filename,
777 0,
778 NVBOOT_CONFIG_TABLE_SIZE_MAX(10 * 1024),
779 &bct_storage,
780 &bct_actual_size,
781 bct_filetype) == 1) {
782 printf("Error reading bct file %s.\n", context->bct_filename);
783 exit(1);
784 }
785
786 context->bct_size = bct_actual_size;
787 if (context->bct_init != 1)
788 err = init_bct(context);
789 if (err != 0) {
790 printf("Context initialization failed. Aborting.\n");
791 return err;
792 }
793 memcpy(context->bct, bct_storage, context->bct_size);
794 free(bct_storage);
795
796 if (!data_is_valid_bct(context))
797 return -ENODATA61;
798
799 return err;
800}
801
802/*
803 * Update the next_bct_blk and make it point to the next
804 * new blank block according to bct_copy given.
805 *
806 * @param context The main context pointer
807 */
808static void
809find_new_bct_blk(build_image_context *context)
810{
811 uint32_t max_bct_search_blks;
812
813 assert(context)((context) ? (void) (0) : __assert_fail ("context", "util/nvidia/cbootimage/src/data_layout.c"
, 813, __extension__ __PRETTY_FUNCTION__))
;
814
815 g_soc_config->get_value(token_max_bct_search_blks,
816 &max_bct_search_blks, context->bct);
817
818 if (context->next_bct_blk > max_bct_search_blks) {
819 printf("Error: Unable to locate a journal block.\n");
820 exit(1);
821 }
822 context->next_bct_blk++;
823}
824
825/*
826 * Initialization before bct and bootloader update.
827 * Find the new blank block and erase it.
828 *
829 * @param context The main context pointer
830 * @return 0 for success
831 */
832int
833begin_update(build_image_context *context)
834{
835 uint32_t hash_size;
836 uint32_t reserved_size;
837 uint32_t reserved_offset;
838 int err = 0;
839 int i;
840
841 assert(context)((context) ? (void) (0) : __assert_fail ("context", "util/nvidia/cbootimage/src/data_layout.c"
, 841, __extension__ __PRETTY_FUNCTION__))
;
842
843 if (context->page_size_log2 < NVBOOT_AES_BLOCK_SIZE_LOG24) {
844 printf("Page size is too small; likely config file error\n");
845 return 1;
846 }
847
848 /* Ensure that the BCT block & page data is current. */
849 if (enable_debug) {
850 uint32_t block_size_log2;
851 uint32_t page_size_log2;
852
853 g_soc_config->get_value(token_block_size_log2,
854 &block_size_log2, context->bct);
855 g_soc_config->get_value(token_page_size_log2,
856 &page_size_log2, context->bct);
857
858 printf("begin_update(): bct data: b=%d p=%d\n",
859 block_size_log2, page_size_log2);
860 }
861
862 g_soc_config->set_value(token_boot_data_version,
863 &(context->boot_data_version), context->bct);
864 g_soc_config->get_value(token_hash_size,
865 &hash_size, context->bct);
866 g_soc_config->get_value(token_reserved_size,
867 &reserved_size, context->bct);
868 g_soc_config->get_value(token_reserved_offset,
869 &reserved_offset, context->bct);
870 /* Set the odm data */
871 g_soc_config->set_value(token_odm_data,
872 &(context->odm_data), context->bct);
873
874 /* Initialize the bad block table field. */
875 g_soc_config->init_bad_block_table(context);
876 /* Fill the reserved data w/the padding pattern. */
877 write_padding(context->bct + reserved_offset, reserved_size);
878
879 /* Create the pad before the BCT starting at block 1 */
880 for (i = 0; i < context->pre_bct_pad_blocks; i++) {
881 find_new_bct_blk(context);
882 err = erase_block(context, i);
883 if (err != 0)
884 goto fail;
885 }
886 /* Find the next bct block starting at block pre_bct_pad_blocks. */
887 for (i = 0; i < context->bct_copy; i++) {
888 find_new_bct_blk(context);
889 err = erase_block(context, i + context->pre_bct_pad_blocks);
890 if (err != 0)
891 goto fail;
892 }
893 return 0;
894fail:
895 printf("Erase block failed, error: %d.\n", err);
896 return err;
897}
898
899/*
900 * Write the BCT(s) starting at slot 0 of block context->pre_bct_pad_blocks.
901 *
902 * @param context The main context pointer
903 * @return 0 for success
904 */
905static int
906finish_update(build_image_context *context)
907{
908 int err = 0;
909 int i;
910
911 for (i = 0; i < context->bct_copy; i++) {
912 err = write_bct(context, i + context->pre_bct_pad_blocks, 0);
913 if (err != 0)
914 goto fail;
915 }
916
917 return 0;
918fail:
919 printf("Write BCT failed, error: %d.\n", err);
920 return err;
921}
922
923/*
924 * For now, ignore end state.
925 */
926int
927update_bl(build_image_context *context)
928{
929 if (enable_debug)
930 printf("**update_bl()\n");
931
932 if (begin_update(context) != 0)
933 return 1;
934 if (write_image(context, file_type_bl) != 0)
935 return 1;
936 if (finish_update(context) != 0)
937 return 1;
938 return 0;
939}
940
941int
942update_mts_image(build_image_context *context)
943{
944 if (enable_debug)
945 printf("**update_mts()\n");
946
947 if (begin_update(context) != 0)
948 return 1;
949 if (write_image(context, file_type_mts) != 0)
950 return 1;
951 if (finish_update(context) != 0)
952 return 1;
953 return 0;
954}
955
956/*
957 * To write the current image:
958 * Loop over all blocks in the block data list:
959 * Write out the data of real blocks.
960 * Write out 0's for unused blocks.
961 * Stop on the last used page of the last used block.
962 *
963 * @param context The main context pointer
964 * @return 0 for success
965 */
966int
967write_block_raw(build_image_context *context)
968{
969 block_data *block_list;
970 block_data *block;
971 uint32_t blk_number;
972 uint32_t last_blk;
973 uint32_t pages_to_write;
974 uint8_t *data;
975 uint8_t *empty_blk = NULL((void*)0);
976
977 assert(context != NULL)((context != ((void*)0)) ? (void) (0) : __assert_fail ("context != NULL"
, "util/nvidia/cbootimage/src/data_layout.c", 977, __extension__
__PRETTY_FUNCTION__))
;
978 assert(context->memory)((context->memory) ? (void) (0) : __assert_fail ("context->memory"
, "util/nvidia/cbootimage/src/data_layout.c", 978, __extension__
__PRETTY_FUNCTION__))
;
979
980 block_list = context->memory;
981
982 /* Compute the end of the image. */
983 block_list = context->memory;
984 while (block_list->next)
985 block_list = block_list->next;
986
987 last_blk = block_list->blk_number;
988
989 /* Loop over all the storage from block 0, page 0 to
990 *last_blk, Lastpage
991 */
992 for (blk_number = 0; blk_number <= last_blk; blk_number++) {
993 block = find_block(blk_number, context->memory);
994 if (block) {
995 pages_to_write = (blk_number == last_blk) ?
996 block->pages_used :
997 context->pages_per_blk;
998 data = block->data;
999 } else {
1000 /* Allocate empty_blk if needed. */
1001 if (empty_blk == NULL((void*)0)) {
1002 empty_blk = malloc(context->block_size);
1003 if (!empty_blk)
1004 return -ENOMEM12;
1005 memset(empty_blk, 0, context->block_size);
1006 }
1007 pages_to_write = context->pages_per_blk;
1008 data = empty_blk;
1009 }
1010 /* Write the data */
1011 {
1012 size_t bytes = pages_to_write * context->page_size;
1013
1014 if (fwrite(data, 1, bytes, context->raw_file) != bytes) {
1015 if (empty_blk) free(empty_blk);
1016 return -1;
1017 }
1018 }
1019 }
1020
1021 if (empty_blk) free(empty_blk);
1022 return 0;
1023}
1024
1025int write_data_block(FILE *fp, uint32_t offset, uint32_t size, uint8_t *buffer)
1026{
1027 if (fseek(fp, offset, 0))
1028 return -1;
1029
1030 return fwrite(buffer, 1, size, fp);
1031}
1032
1033int data_is_valid_bct(build_image_context *context)
1034{
1035 /* get proper soc_config pointer by polling each supported chip */
1036 if (if_bct_is_t20_get_soc_config(context, &g_soc_config))
1037 return 1;
1038 if (if_bct_is_t30_get_soc_config(context, &g_soc_config))
1039 return 1;
1040 if (if_bct_is_t114_get_soc_config(context, &g_soc_config))
1041 return 1;
1042 if (if_bct_is_t124_get_soc_config(context, &g_soc_config))
1043 return 1;
1044 if (if_bct_is_t132_get_soc_config(context, &g_soc_config))
1045 return 1;
1046 if (if_bct_is_t210_get_soc_config(context, &g_soc_config))
1047 return 1;
1048
1049 return 0;
1050}
1051
1052int get_bct_size_from_image(build_image_context *context)
1053{
1054 uint8_t buffer[NVBOOT_CONFIG_TABLE_SIZE_MIN4080];
1055 uint32_t bct_size = 0;
1056 FILE *fp;
1057
1058 fp = fopen(context->input_image_filename, "r");
1059 if (!fp)
1060 return -ENODATA61;
1061
1062 if (fread(buffer, 1, NVBOOT_CONFIG_TABLE_SIZE_MIN4080, fp) != NVBOOT_CONFIG_TABLE_SIZE_MIN4080) {
1063 fclose(fp);
1064 return -ENODATA61;
1065 }
1066
1067 context->bct = buffer;
1068 if (data_is_valid_bct(context) && g_soc_config->get_bct_size)
1069 bct_size = g_soc_config->get_bct_size();
1070
1071 fclose(fp);
1072 context->bct = 0;
1073 return bct_size;
1074}
1075
1076int resign_bl(build_image_context *context)
1077{
1078 int ret;
1079 uint8_t *buffer, *image;
1080 uint32_t image_instance = 0; /* support only one instance */
1081 uint32_t image_actual_size; /* In bytes */
1082 uint32_t bl_length;
1083 uint32_t pages_in_image;
1084 uint32_t blk_size, page_size, current_blk, current_page;
1085 uint32_t offset;
1086
1087 /* read in bl from image */
1088 g_soc_config->get_value(token_block_size, &blk_size, context->bct);
1089 g_soc_config->get_value(token_page_size, &page_size, context->bct);
1090
1091 GET_BL_FIELD(image_instance, start_blk, &current_blk)g_soc_config->getbl_param(image_instance, token_bl_start_blk
, &current_blk, context->bct);
;
1092 GET_BL_FIELD(image_instance, start_page, &current_page)g_soc_config->getbl_param(image_instance, token_bl_start_page
, &current_page, context->bct);
;
1093 GET_BL_FIELD(image_instance, length, &bl_length)g_soc_config->getbl_param(image_instance, token_bl_length,
&bl_length, context->bct);
;
1094
1095 offset = current_blk * blk_size +
1096 current_page * page_size;
1097
1098 if (read_from_image(context->input_image_filename,
1099 offset, bl_length,
1100 &image, &image_actual_size, file_type_bin)) {
1101 printf("Error reading image file %s.\n",
1102 context->input_image_filename);
1103 return -ENOMEM12;
1104 }
1105
1106 pages_in_image = ICEIL(image_actual_size, page_size)(((image_actual_size) + (page_size) - 1)/(page_size));
1107
1108 /* Create a local copy of the bl */
1109 if ((buffer = malloc(pages_in_image * page_size)) == NULL((void*)0)) {
1110 ret = -ENOMEM12;
1111 goto fail;
1112 }
1113
1114 memset(buffer, 0, pages_in_image * page_size);
1115 memcpy(buffer, image, image_actual_size);
1116
1117 insert_padding(buffer, image_actual_size);
1118
1119 /* sign bl */
1120 ret = sign_bl(context, buffer, image_actual_size, image_instance);
1121 free (buffer);
1122 fail:
1123 free (image);
1124 return ret;
1125}