1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 
5 
6 /* Define the file handles.  */
7 
8 FILE	*source_file;
9 FILE    *array_file;
10 
11 
12 #define ELF_ID_STRING_SIZE	    16
13 #define ELF_ARM_MACHINE_TYPE    40
14 #define ELF_EXECUTABLE          2
15 
16 
17 typedef struct ELF_HEADER_STRUCT
18 {
19     unsigned char   elf_header_id_string[ELF_ID_STRING_SIZE];
20     unsigned short  elf_header_file_type;
21     unsigned short  elf_header_machinge_type;
22     unsigned long   elf_header_version;
23     unsigned long   elf_header_entry_address;
24     unsigned long   elf_header_program_header_offset;
25     unsigned long   elf_header_section_header_offset;
26     unsigned long   elf_header_processor_flags;
27     unsigned short  elf_header_size;
28     unsigned short  elf_header_program_header_size;
29     unsigned short  elf_header_program_header_entries;
30     unsigned short  elf_header_section_header_size;
31     unsigned short  elf_header_section_header_entries;
32     unsigned short  elf_header_section_string_index;
33 } ELF_HEADER;
34 
35 
36 typedef struct ELF_PROGRAM_HEADER_STRUCT
37 {
38     unsigned long   elf_program_header_type;
39     unsigned long   elf_program_header_offset;
40     unsigned long   elf_program_header_virtual_address;
41     unsigned long   elf_program_header_physical_address;
42     unsigned long   elf_program_header_file_size;
43     unsigned long   elf_program_header_memory_size;
44     unsigned long   elf_program_header_flags;
45     unsigned long   elf_program_header_alignment;
46 } ELF_PROGRAM_HEADER;
47 
48 
49 typedef struct ELF_SECTION_HEADER_STRUCT
50 {
51     unsigned long   elf_section_header_name;
52     unsigned long   elf_section_header_type;
53     unsigned long   elf_section_header_flags;
54     unsigned long   elf_section_header_address;
55     unsigned long   elf_section_header_offset;
56     unsigned long   elf_section_header_size;
57     unsigned long   elf_section_header_link;
58     unsigned long   elf_section_header_info;
59     unsigned long   elf_section_header_alignment;
60     unsigned long   elf_section_header_entry_size;
61 } ELF_SECTION_HEADER;
62 
63 
64 typedef struct ELF_SYMBOL_TABLE_ENTRY_STRUCT
65 {
66     unsigned long   elf_symbol_table_entry_name;
67     unsigned long   elf_symbol_table_entry_address;
68     unsigned long   elf_symbol_table_entry_size;
69     unsigned char   elf_symbol_table_entry_info;
70     unsigned char   elf_symbol_table_entry_other;
71     unsigned short  elf_symbol_table_entry_shndx;
72 
73 } ELF_SYMBOL_TABLE_ENTRY;
74 
75 
76 typedef struct CODE_SECTION_ENTRY_STRUCT
77 {
78     unsigned long   code_section_index;
79     unsigned long   code_section_address;
80     unsigned long   code_section_size;
81 } CODE_SECTION_ENTRY;
82 
83 
84 /* Define global variables.  */
85 
86 ELF_HEADER              header;
87 ELF_PROGRAM_HEADER      *program_header;
88 ELF_SECTION_HEADER      *section_header;
89 unsigned char           *section_string_table;
90 unsigned char           *main_string_table;
91 unsigned long           total_symbols;
92 ELF_SYMBOL_TABLE_ENTRY  *symbol_table;
93 unsigned long           total_functions;
94 ELF_SYMBOL_TABLE_ENTRY  *function_table;
95 CODE_SECTION_ENTRY		*code_section_array;
96 
97 
98 /* Define helper functions.  */
99 
elf_object_read(unsigned long offset,void * object_address,int object_size)100 int elf_object_read(unsigned long offset, void *object_address, int object_size)
101 {
102 
103 int             i;
104 int             alpha;
105 unsigned char   *buffer;
106 
107     /* Setup the buffer pointer.  */
108     buffer =  (unsigned char *) object_address;
109 
110     /* Seek to the proper position in the file.  */
111     fseek(source_file, offset, SEEK_SET);
112 
113     /* Read the ELF object.  */
114     for (i = 0; i < object_size; i++)
115     {
116         alpha =  fgetc(source_file);
117 
118         if (alpha == EOF)
119             return(1);
120 
121         buffer[i] =  (unsigned char) alpha;
122     }
123 
124     /* Return success.  */
125     return(0);
126 }
127 
128 
main(int argc,char * argv[])129 int main(int argc, char* argv[])
130 {
131 
132 unsigned long           i, j, k;
133 unsigned long           current_total;
134 unsigned long           address;
135 unsigned long           size;
136 unsigned long           column;
137 unsigned char           *code_buffer;
138 unsigned long			code_section_index;
139 CODE_SECTION_ENTRY		code_section_temp;
140 
141 
142     /* Determine if the proper number of files are provided.  */
143     if (argc != 3)
144     {
145 
146         /* Print an error message out and wait for user key hit.  */
147 		printf("module_to_c_array.exe - Copyright (c) Microsoft Corporation v5.8\n");
148         printf("**** Error: invalid input parameter for module_to_c_array.exe **** \n");
149         printf("     Command Line Should be:\n\n");
150         printf("     > module_to_c_array source_elf_file c_array_file <cr> \n\n");
151         return(1);
152     }
153 
154     /* Attempt to open the source file for reading.  */
155     source_file =  fopen(argv[1], "rb");
156 
157     /* Determine if the source file was opened properly.  */
158     if (source_file == NULL)
159     {
160 
161         /* Print an error message out and wait for user key hit.  */
162         printf("**** Error: open failed on source elf file **** \n");
163         printf("            File: %s   ", argv[1]);
164         return(2);
165     }
166 
167     /* Attempt to open the dump file for writing.  */
168     array_file =  fopen(argv[2], "w");
169 
170     /* Determine if the dump file was opened properly.  */
171     if (array_file == NULL)
172     {
173 
174         /* Print an error message out and wait for user key hit.  */
175         printf("**** Error: open failed on C array file **** \n");
176         printf("            File: %s   ", argv[2]);
177         return(3);
178     }
179 
180     /* Read the ELF header.  */
181     elf_object_read(0, &header, sizeof(header));
182 
183     fprintf(array_file, "/**************************** Module-to-C-array Utility *****************************************/\n");
184 	fprintf(array_file, "/*                                                                                              */\n");
185 	fprintf(array_file, "/* Copyright (c) Microsoft Corporation                      Version 5.8, build date: 03-01-2018 */\n");
186 	fprintf(array_file, "/*                                                                                              */\n");
187 	fprintf(array_file, "/************************************************************************************************/\n\n");
188     fprintf(array_file, "/* \n");
189 	fprintf(array_file, "   Input ELF file:      %30s\n", argv[1]);
190 	fprintf(array_file, "   Output C Array file: %30s\n", argv[2]);
191 	fprintf(array_file, "*/\n\n");
192 
193     /* Allocate memory for the program header(s).  */
194     program_header =  malloc(sizeof(ELF_PROGRAM_HEADER)*header.elf_header_program_header_entries);
195 
196     /* Read the program header(s).  */
197     elf_object_read(header.elf_header_program_header_offset, program_header, (sizeof(ELF_PROGRAM_HEADER)*header.elf_header_program_header_entries));
198 
199     /* Allocate memory for the section header(s).  */
200     section_header =  malloc(sizeof(ELF_SECTION_HEADER)*header.elf_header_section_header_entries);
201 
202     /* Read the section header(s).  */
203     elf_object_read(header.elf_header_section_header_offset, section_header, (sizeof(ELF_SECTION_HEADER)*header.elf_header_section_header_entries));
204 
205 
206     /* Alocate memory for the section string table.  */
207     section_string_table =  malloc(section_header[header.elf_header_section_string_index].elf_section_header_size);
208 
209     /* Read the section string table.  */
210     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);
211 
212     /* Allocate memory for the code section array.  */
213     code_section_array =  malloc(sizeof(CODE_SECTION_ENTRY)*header.elf_header_section_header_entries);
214 	code_section_index =  0;
215 
216     /* Print out the section header(s).  */
217     for (i = 0; i < header.elf_header_section_header_entries; i++)
218     {
219 
220 		/* Determine if this section is a code section and there is a size.  */
221 		if ((section_header[i].elf_section_header_type == 1) && (section_header[i].elf_section_header_size))
222 		{
223 
224             /* Check for an-instruction area.  */
225             if ((section_header[i].elf_section_header_flags & 0x4) || (section_header[i].elf_section_header_flags & 0x2))
226 			{
227                 /* Determine if this new section overlaps with an existing section.  */
228 				for (j = 0; j < code_section_index; j++)
229 				{
230 					/* Is there an overlap?  */
231 					if ((section_header[i].elf_section_header_address >= code_section_array[j].code_section_address) &&
232 						((section_header[i].elf_section_header_address+section_header[i].elf_section_header_size + section_header[i].elf_section_header_offset) < (code_section_array[j].code_section_address+code_section_array[j].code_section_size)))
233 					{
234 						/* New section is within a current section, just disregard it.  */
235 						break;
236 					}
237 				}
238 
239 				/* Determine if we have an overlap.  */
240 				if (j == code_section_index)
241 				{
242 
243 				    /* Yes, we have a code section... save it!  */
244 				    code_section_array[code_section_index].code_section_index =  i;
245 				    code_section_array[code_section_index].code_section_address =  section_header[i].elf_section_header_address;
246 				    code_section_array[code_section_index].code_section_size =     section_header[i].elf_section_header_size;
247 
248 				    /* Move to next code section.  */
249 				    code_section_index++;
250 				}
251 			}
252 		}
253 	}
254 
255 	/* Check for no code sections.  */
256 	if (code_section_index == 0)
257 	{
258 
259         /* Print an error message out.  */
260         printf("**** Error: No code sections found! **** \n");
261 
262 		fprintf(array_file, "unsigned char  module_code[] = {0x00};\n\n");
263 
264 		/* Close files.  */
265 		fclose(source_file);
266 		fclose(array_file);
267 
268 		return(4);
269  	}
270 
271 	/* One or more code sections have been found... let's put them in the correct order by address.  */
272 	i = 0;
273 	while (i+1 < code_section_index)
274 	{
275 
276 		/* Make the "ith" entry the lowest address.  */
277 		j = i + 1;
278 		do
279 		{
280 			/* Is there a new lowest address?  */
281 			if (code_section_array[j].code_section_address < code_section_array[i].code_section_address)
282 			{
283 				/* Yes, swap them!  */
284 				code_section_temp =  code_section_array[i];
285 				code_section_array[i] =  code_section_array[j];
286 				code_section_array[j] = code_section_temp;
287 			}
288 
289 			/* Move the inner index.  */
290 			j++;
291 		} while (j < code_section_index);
292 
293 		/* Move top index.  */
294 		i++;
295 	}
296 
297 	/* Now print out the sections in a C array.  */
298 	fprintf(array_file, "unsigned char  module_code[] = {\n\n");
299 	fprintf(array_file, "/* Address                                            Contents                                        */\n\n");
300 
301 	address =  code_section_array[0].code_section_address;
302 	column =   0;
303 
304 	for (i = 0; i < code_section_index; i++)
305 	{
306 
307 		/* Determine if there is any fill characters between sections.  */
308 		while (address < code_section_array[i].code_section_address)
309 		{
310 
311 			/* Print out a character with a leading comma, except on the first character.  */
312 			if (column == 0)
313 				fprintf(array_file, "/* 0x%08X */   0x00", address);
314 			else
315   				fprintf(array_file, ", 0x00");
316 
317 			/* Move column forward.  */
318 			column++;
319 
320 			/* Are we at the end of the column?  */
321 			if (column >= 16)
322 			{
323 				fprintf(array_file, ",\n");
324 				column =  0;
325 			}
326 
327 			/* Move address forward.  */
328 			address++;
329 		}
330 
331 		/* Now allocate memory for the code section.  */
332 		code_buffer =  malloc(code_section_array[i].code_section_size);
333 
334 		/* Read in the code area.  */
335 		j =  code_section_array[i].code_section_index;
336 		elf_object_read(section_header[j].elf_section_header_offset, code_buffer, code_section_array[i].code_section_size);
337 
338 		/* Write out the contents of this program area.  */
339 		size =  code_section_array[i].code_section_size;
340 
341 		j =  0;
342 		k =  0;
343 		while (size)
344 		{
345 
346 			/* Print out a character with a leading comma, except on the first character.  */
347 			if (column == 0)
348 				fprintf(array_file, "/* 0x%08X */   0x%02X", address, (unsigned int) code_buffer[j]);
349 			else
350   				fprintf(array_file, ", 0x%02X", (unsigned int) code_buffer[j]);
351 
352 			/* Move column forward.  */
353 			column++;
354 
355 			/* Are we at the end of the column?  */
356 			if (column >= 16)
357 			{
358 
359 				/* Is this the last byte of the image?  */
360 				if ((size != 1) || (i+1 != code_section_index))
361 				{
362 					if (k == 0)
363 					{
364 						k = code_section_array[i].code_section_index;
365 					    fprintf(array_file, ",      /* SECTION: %s  */\n", &section_string_table[section_header[k].elf_section_header_name]);
366 					}
367 					else
368   					    fprintf(array_file, ",\n");
369 				}
370 				column =  0;
371 			}
372 
373 			/* Move address forward.  */
374 			address++;
375 
376 			/* Decrement size.  */
377 			size--;
378 
379 			/* Move index into buffer.  */
380 			j++;
381 		}
382 	}
383 
384 	/* Finally, finish the C array containing the module code.  */
385 	fprintf(array_file, "};\n\n");
386 
387 	/* Close files.  */
388 	fclose(source_file);
389     fclose(array_file);
390 
391 	return 0;
392 }
393