diff options
Diffstat (limited to 'common_modules/module_manager/utilities/module_to_c_array.c')
| -rw-r--r-- | common_modules/module_manager/utilities/module_to_c_array.c | 238 |
1 files changed, 217 insertions, 21 deletions
diff --git a/common_modules/module_manager/utilities/module_to_c_array.c b/common_modules/module_manager/utilities/module_to_c_array.c index d3472416..72e87de0 100644 --- a/common_modules/module_manager/utilities/module_to_c_array.c +++ b/common_modules/module_manager/utilities/module_to_c_array.c @@ -9,11 +9,25 @@ /* SPDX-License-Identifier: MIT */ /***************************************************************************/ +// Portions of this file were generated with AI assistance. + #include <stdio.h> #include <stdlib.h> #include <string.h> +/* MISRA C:2012 Rule 21.3 and Dir 4.12 deviation: dynamic memory is used in this + file. This is a host-side conversion utility executed on the development + machine, not ThreadX runtime code, and the ELF areas being read have sizes + that are only known at run time. Every allocation result is checked for NULL + and every buffer is released before its pointer is reused. */ + +/* MISRA C:2012 Rule 15.5 (advisory) deviation: main() returns from several + error paths instead of having a single point of exit. The project forbids + goto, so an early return is the only way to abandon the conversion, and this + matches the style already used by the parameter and file open checks. */ + + /* Define the file handles. */ FILE *source_file; @@ -137,13 +151,52 @@ unsigned char *buffer; } +/* Close the files and release the ELF areas allocated by main(). This is called + from every exit path taken after the files have been opened, so it must + tolerate being called with resources that were never acquired. The areas it + releases are the file scope pointers declared above. */ + +static void converter_cleanup(void) +{ + + /* Determine if the source file is open. */ + if (source_file != NULL) + { + + /* Close it. */ + fclose(source_file); + source_file = NULL; + } + + /* Determine if the C array output file is open. */ + if (array_file != NULL) + { + + /* Close it. */ + fclose(array_file); + array_file = NULL; + } + + /* Release the ELF areas. Note that free() is defined to do nothing when it + is supplied a NULL pointer, so no test is required here. */ + free(program_header); + program_header = NULL; + free(section_header); + section_header = NULL; + free(section_string_table); + section_string_table = NULL; + free(code_section_array); + code_section_array = NULL; +} + + int main(int argc, char* argv[]) { unsigned long i, j, k; -unsigned long current_total; unsigned long address; unsigned long size; +unsigned long allocation_size; unsigned long column; unsigned char *code_buffer; unsigned long code_section_index; @@ -155,8 +208,11 @@ CODE_SECTION_ENTRY code_section_temp; { /* Print an error message out and wait for user key hit. */ - printf("module_to_c_array.exe - Copyright (c) Microsoft Corporation v5.8\n"); - printf("**** Error: invalid input parameter for module_to_c_array.exe **** \n"); + printf("module_to_c_array\n"); + printf("(c) 2024 Microsoft Corp\n"); + printf("(c) 2026 Eclipse ThreadX contributors\n"); + printf("v6.5.2.202603\n"); + printf("**** Error: invalid input parameter for module_to_c_array **** \n"); printf(" Command Line Should be:\n\n"); printf(" > module_to_c_array source_elf_file c_array_file <cr> \n\n"); return(1); @@ -189,11 +245,23 @@ CODE_SECTION_ENTRY code_section_temp; } /* Read the ELF header. */ - elf_object_read(0, &header, sizeof(header)); + if (elf_object_read(0, &header, sizeof(header)) != 0) + { + + /* Print an error message out. */ + printf("**** Error: read failed on the ELF header **** \n"); + + /* Close the files and release the ELF areas. */ + converter_cleanup(); + + return(6); + } fprintf(array_file, "/**************************** Module-to-C-array Utility *****************************************/\n"); fprintf(array_file, "/* */\n"); - fprintf(array_file, "/* Copyright (c) Microsoft Corporation Version 5.8, build date: 03-01-2018 */\n"); + fprintf(array_file, "/* Copyright (c) 2024 Microsoft Corp */\n"); + fprintf(array_file, "/* Copyright (c) 2026 Eclipse ThreadX contributors */\n"); + fprintf(array_file, "/* v6.5.2.202603 */\n"); fprintf(array_file, "/* */\n"); fprintf(array_file, "/************************************************************************************************/\n\n"); fprintf(array_file, "/* \n"); @@ -202,26 +270,127 @@ CODE_SECTION_ENTRY code_section_temp; fprintf(array_file, "*/\n\n"); /* Allocate memory for the program header(s). */ - program_header = malloc(sizeof(ELF_PROGRAM_HEADER)*header.elf_header_program_header_entries); + allocation_size = sizeof(ELF_PROGRAM_HEADER)*header.elf_header_program_header_entries; + program_header = malloc(allocation_size); + + /* Determine if the memory allocation was successful. Note that an empty area + is not an error, since malloc() is permitted to return NULL for it. */ + if ((program_header == NULL) && (allocation_size != 0)) + { + + /* Print an error message out. */ + printf("**** Error: memory allocation failed for the program header(s) **** \n"); + + /* Close the files and release the ELF areas. */ + converter_cleanup(); + + return(5); + } /* Read the program header(s). */ - elf_object_read(header.elf_header_program_header_offset, program_header, (sizeof(ELF_PROGRAM_HEADER)*header.elf_header_program_header_entries)); + if (elf_object_read(header.elf_header_program_header_offset, program_header, allocation_size) != 0) + { + + /* Print an error message out. */ + printf("**** Error: read failed on the program header(s) **** \n"); + + /* Close the files and release the ELF areas. */ + converter_cleanup(); + + return(6); + } /* Allocate memory for the section header(s). */ - section_header = malloc(sizeof(ELF_SECTION_HEADER)*header.elf_header_section_header_entries); + allocation_size = sizeof(ELF_SECTION_HEADER)*header.elf_header_section_header_entries; + section_header = malloc(allocation_size); + + /* Determine if the memory allocation was successful. */ + if ((section_header == NULL) && (allocation_size != 0)) + { + + /* Print an error message out. */ + printf("**** Error: memory allocation failed for the section header(s) **** \n"); + + /* Close the files and release the ELF areas. */ + converter_cleanup(); + + return(5); + } /* Read the section header(s). */ - elf_object_read(header.elf_header_section_header_offset, section_header, (sizeof(ELF_SECTION_HEADER)*header.elf_header_section_header_entries)); + if (elf_object_read(header.elf_header_section_header_offset, section_header, allocation_size) != 0) + { + /* Print an error message out. */ + printf("**** Error: read failed on the section header(s) **** \n"); + + /* Close the files and release the ELF areas. */ + converter_cleanup(); + + return(6); + } + + /* Determine if the section string table index supplied by the ELF header is + inside the section header area that was just read. */ + if (header.elf_header_section_string_index >= header.elf_header_section_header_entries) + { + + /* Print an error message out. */ + printf("**** Error: invalid section string table index in the ELF header **** \n"); + + /* Close the files and release the ELF areas. */ + converter_cleanup(); + + return(6); + } /* Alocate memory for the section string table. */ - section_string_table = malloc(section_header[header.elf_header_section_string_index].elf_section_header_size); + allocation_size = section_header[header.elf_header_section_string_index].elf_section_header_size; + section_string_table = malloc(allocation_size); + + /* Determine if the memory allocation was successful. */ + if ((section_string_table == NULL) && (allocation_size != 0)) + { + + /* Print an error message out. */ + printf("**** Error: memory allocation failed for the section string table **** \n"); + + /* Close the files and release the ELF areas. */ + converter_cleanup(); + + return(5); + } /* Read the section string table. */ - elf_object_read(section_header[header.elf_header_section_string_index].elf_section_header_offset, section_string_table, section_header[header.elf_header_section_string_index].elf_section_header_size); + if (elf_object_read(section_header[header.elf_header_section_string_index].elf_section_header_offset, section_string_table, allocation_size) != 0) + { + + /* Print an error message out. */ + printf("**** Error: read failed on the section string table **** \n"); + + /* Close the files and release the ELF areas. */ + converter_cleanup(); + + return(6); + } /* Allocate memory for the code section array. */ - code_section_array = malloc(sizeof(CODE_SECTION_ENTRY)*header.elf_header_section_header_entries); + allocation_size = sizeof(CODE_SECTION_ENTRY)*header.elf_header_section_header_entries; + code_section_array = malloc(allocation_size); + + /* Determine if the memory allocation was successful. */ + if ((code_section_array == NULL) && (allocation_size != 0)) + { + + /* Print an error message out. */ + printf("**** Error: memory allocation failed for the code section array **** \n"); + + /* Close the files and release the ELF areas. */ + converter_cleanup(); + + return(5); + } + code_section_index = 0; /* Print out the section header(s). */ @@ -272,9 +441,8 @@ CODE_SECTION_ENTRY code_section_temp; fprintf(array_file, "unsigned char module_code[] = {0x00};\n\n"); - /* Close files. */ - fclose(source_file); - fclose(array_file); + /* Close the files and release the ELF areas. */ + converter_cleanup(); return(4); } @@ -321,7 +489,7 @@ CODE_SECTION_ENTRY code_section_temp; /* Print out a character with a leading comma, except on the first character. */ if (column == 0) - fprintf(array_file, "/* 0x%08X */ 0x00", address); + fprintf(array_file, "/* 0x%08lX */ 0x00", address); else fprintf(array_file, ", 0x00"); @@ -342,9 +510,34 @@ CODE_SECTION_ENTRY code_section_temp; /* Now allocate memory for the code section. */ code_buffer = malloc(code_section_array[i].code_section_size); + /* Determine if the memory allocation was successful. */ + if (code_buffer == NULL) + { + + /* Print an error message out. */ + printf("**** Error: memory allocation failed for code section **** \n"); + + /* Close the files and release the ELF areas. */ + converter_cleanup(); + + return(5); + } + /* Read in the code area. */ j = code_section_array[i].code_section_index; - elf_object_read(section_header[j].elf_section_header_offset, code_buffer, code_section_array[i].code_section_size); + if (elf_object_read(section_header[j].elf_section_header_offset, code_buffer, code_section_array[i].code_section_size) != 0) + { + + /* Print an error message out. */ + printf("**** Error: read failed on a code section **** \n"); + + /* Release the code section buffer, then close the files and release + the ELF areas. */ + free(code_buffer); + converter_cleanup(); + + return(6); + } /* Write out the contents of this program area. */ size = code_section_array[i].code_section_size; @@ -356,7 +549,7 @@ CODE_SECTION_ENTRY code_section_temp; /* Print out a character with a leading comma, except on the first character. */ if (column == 0) - fprintf(array_file, "/* 0x%08X */ 0x%02X", address, (unsigned int) code_buffer[j]); + fprintf(array_file, "/* 0x%08lX */ 0x%02X", address, (unsigned int) code_buffer[j]); else fprintf(array_file, ", 0x%02X", (unsigned int) code_buffer[j]); @@ -390,14 +583,17 @@ CODE_SECTION_ENTRY code_section_temp; /* Move index into buffer. */ j++; } + + /* Release the code section buffer before the next section is read. */ + free(code_buffer); + code_buffer = NULL; } /* Finally, finish the C array containing the module code. */ fprintf(array_file, "};\n\n"); - /* Close files. */ - fclose(source_file); - fclose(array_file); + /* Close the files and release the ELF areas. */ + converter_cleanup(); return 0; } |
