module_to_binary.c 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. /* Define the file handles. */
  5. FILE *source_file;
  6. FILE *binary_file;
  7. #define ELF_ID_STRING_SIZE 16
  8. #define ELF_ARM_MACHINE_TYPE 40
  9. #define ELF_EXECUTABLE 2
  10. typedef struct ELF_HEADER_STRUCT
  11. {
  12. unsigned char elf_header_id_string[ELF_ID_STRING_SIZE];
  13. unsigned short elf_header_file_type;
  14. unsigned short elf_header_machinge_type;
  15. unsigned long elf_header_version;
  16. unsigned long elf_header_entry_address;
  17. unsigned long elf_header_program_header_offset;
  18. unsigned long elf_header_section_header_offset;
  19. unsigned long elf_header_processor_flags;
  20. unsigned short elf_header_size;
  21. unsigned short elf_header_program_header_size;
  22. unsigned short elf_header_program_header_entries;
  23. unsigned short elf_header_section_header_size;
  24. unsigned short elf_header_section_header_entries;
  25. unsigned short elf_header_section_string_index;
  26. } ELF_HEADER;
  27. typedef struct ELF_PROGRAM_HEADER_STRUCT
  28. {
  29. unsigned long elf_program_header_type;
  30. unsigned long elf_program_header_offset;
  31. unsigned long elf_program_header_virtual_address;
  32. unsigned long elf_program_header_physical_address;
  33. unsigned long elf_program_header_file_size;
  34. unsigned long elf_program_header_memory_size;
  35. unsigned long elf_program_header_flags;
  36. unsigned long elf_program_header_alignment;
  37. } ELF_PROGRAM_HEADER;
  38. typedef struct ELF_SECTION_HEADER_STRUCT
  39. {
  40. unsigned long elf_section_header_name;
  41. unsigned long elf_section_header_type;
  42. unsigned long elf_section_header_flags;
  43. unsigned long elf_section_header_address;
  44. unsigned long elf_section_header_offset;
  45. unsigned long elf_section_header_size;
  46. unsigned long elf_section_header_link;
  47. unsigned long elf_section_header_info;
  48. unsigned long elf_section_header_alignment;
  49. unsigned long elf_section_header_entry_size;
  50. } ELF_SECTION_HEADER;
  51. typedef struct ELF_SYMBOL_TABLE_ENTRY_STRUCT
  52. {
  53. unsigned long elf_symbol_table_entry_name;
  54. unsigned long elf_symbol_table_entry_address;
  55. unsigned long elf_symbol_table_entry_size;
  56. unsigned char elf_symbol_table_entry_info;
  57. unsigned char elf_symbol_table_entry_other;
  58. unsigned short elf_symbol_table_entry_shndx;
  59. } ELF_SYMBOL_TABLE_ENTRY;
  60. typedef struct CODE_SECTION_ENTRY_STRUCT
  61. {
  62. unsigned long code_section_index;
  63. unsigned long code_section_address;
  64. unsigned long code_section_size;
  65. } CODE_SECTION_ENTRY;
  66. /* Define global variables. */
  67. ELF_HEADER header;
  68. ELF_PROGRAM_HEADER *program_header;
  69. ELF_SECTION_HEADER *section_header;
  70. unsigned char *section_string_table;
  71. unsigned char *main_string_table;
  72. unsigned long total_symbols;
  73. ELF_SYMBOL_TABLE_ENTRY *symbol_table;
  74. unsigned long total_functions;
  75. ELF_SYMBOL_TABLE_ENTRY *function_table;
  76. CODE_SECTION_ENTRY *code_section_array;
  77. /* Define helper functions. */
  78. int elf_object_read(unsigned long offset, void *object_address, int object_size)
  79. {
  80. int i;
  81. int alpha;
  82. unsigned char *buffer;
  83. /* Setup the buffer pointer. */
  84. buffer = (unsigned char *) object_address;
  85. /* Seek to the proper position in the file. */
  86. fseek(source_file, offset, SEEK_SET);
  87. /* Read the ELF object. */
  88. for (i = 0; i < object_size; i++)
  89. {
  90. alpha = fgetc(source_file);
  91. if (alpha == EOF)
  92. return(1);
  93. buffer[i] = (unsigned char) alpha;
  94. }
  95. /* Return success. */
  96. return(0);
  97. }
  98. int main(int argc, char* argv[])
  99. {
  100. unsigned long i, j;
  101. unsigned long current_total;
  102. unsigned long address;
  103. unsigned long size;
  104. unsigned char *code_buffer;
  105. unsigned long code_section_index;
  106. CODE_SECTION_ENTRY code_section_temp;
  107. unsigned char zero_value;
  108. /* Determine if the proper number of files are provided. */
  109. if (argc != 3)
  110. {
  111. /* Print an error message out and wait for user key hit. */
  112. printf("module_to_binary.exe - Copyright (c) Microsoft Corporation v5.8\n");
  113. printf("**** Error: invalid input parameter for module_to_binary.exe **** \n");
  114. printf(" Command Line Should be:\n\n");
  115. printf(" > module_to_binary source_elf_file c_binary_file <cr> \n\n");
  116. return(1);
  117. }
  118. /* Attempt to open the source file for reading. */
  119. source_file = fopen(argv[1], "rb");
  120. /* Determine if the source file was opened properly. */
  121. if (source_file == NULL)
  122. {
  123. /* Print an error message out. */
  124. printf("**** Error: open failed on source elf file **** \n");
  125. printf(" File: %s ", argv[1]);
  126. return(2);
  127. }
  128. /* Attempt to open the binary file for writing. */
  129. binary_file = fopen(argv[2], "wb");
  130. /* Determine if the binary file was opened properly. */
  131. if (binary_file == NULL)
  132. {
  133. /* Print an error message out and wait for user key hit. */
  134. printf("**** Error: open failed on binary output file **** \n");
  135. printf(" File: %s ", argv[2]);
  136. return(3);
  137. }
  138. /* Read the ELF header. */
  139. elf_object_read(0, &header, sizeof(header));
  140. /* Allocate memory for the program header(s). */
  141. program_header = malloc(sizeof(ELF_PROGRAM_HEADER)*header.elf_header_program_header_entries);
  142. /* Read the program header(s). */
  143. elf_object_read(header.elf_header_program_header_offset, program_header, (sizeof(ELF_PROGRAM_HEADER)*header.elf_header_program_header_entries));
  144. /* Allocate memory for the section header(s). */
  145. section_header = malloc(sizeof(ELF_SECTION_HEADER)*header.elf_header_section_header_entries);
  146. /* Read the section header(s). */
  147. elf_object_read(header.elf_header_section_header_offset, section_header, (sizeof(ELF_SECTION_HEADER)*header.elf_header_section_header_entries));
  148. /* Alocate memory for the section string table. */
  149. section_string_table = malloc(section_header[header.elf_header_section_string_index].elf_section_header_size);
  150. /* Read the section string table. */
  151. 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);
  152. /* Allocate memory for the code section array. */
  153. code_section_array = malloc(sizeof(CODE_SECTION_ENTRY)*header.elf_header_section_header_entries);
  154. code_section_index = 0;
  155. /* Print out the section header(s). */
  156. for (i = 0; i < header.elf_header_section_header_entries; i++)
  157. {
  158. /* Determine if this section is a code section and there is a size. */
  159. if ((section_header[i].elf_section_header_type == 1) && (section_header[i].elf_section_header_size))
  160. {
  161. /* Check for an-instruction area. */
  162. if ((section_header[i].elf_section_header_flags & 0x4) || (section_header[i].elf_section_header_flags & 0x2))
  163. {
  164. /* Determine if this new section overlaps with an existing section. */
  165. for (j = 0; j < code_section_index; j++)
  166. {
  167. /* Is there an overlap? */
  168. if ((section_header[i].elf_section_header_address >= code_section_array[j].code_section_address) &&
  169. ((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)))
  170. {
  171. /* New section is within a current section, just disregard it. */
  172. break;
  173. }
  174. }
  175. /* Determine if we have an overlap. */
  176. if (j == code_section_index)
  177. {
  178. /* Yes, we have a code section... save it! */
  179. code_section_array[code_section_index].code_section_index = i;
  180. code_section_array[code_section_index].code_section_address = section_header[i].elf_section_header_address;
  181. code_section_array[code_section_index].code_section_size = section_header[i].elf_section_header_size;
  182. /* Move to next code section. */
  183. code_section_index++;
  184. }
  185. }
  186. }
  187. }
  188. /* Check for no code sections. */
  189. if (code_section_index == 0)
  190. {
  191. /* Close files. */
  192. fclose(source_file);
  193. fclose(binary_file);
  194. return(4);
  195. }
  196. /* One or more code sections have been found... let's put them in the correct order by address. */
  197. i = 0;
  198. while (i+1 < code_section_index)
  199. {
  200. /* Make the "ith" entry the lowest address. */
  201. j = i + 1;
  202. do
  203. {
  204. /* Is there a new lowest address? */
  205. if (code_section_array[j].code_section_address < code_section_array[i].code_section_address)
  206. {
  207. /* Yes, swap them! */
  208. code_section_temp = code_section_array[i];
  209. code_section_array[i] = code_section_array[j];
  210. code_section_array[j] = code_section_temp;
  211. }
  212. /* Move the inner index. */
  213. j++;
  214. } while (j < code_section_index);
  215. /* Move top index. */
  216. i++;
  217. }
  218. address = code_section_array[0].code_section_address;
  219. zero_value = 0;
  220. for (i = 0; i < code_section_index; i++)
  221. {
  222. /* Determine if there is any fill characters between sections. */
  223. while (address < code_section_array[i].code_section_address)
  224. {
  225. /* Write a zero value. */
  226. fwrite(&zero_value, 1, 1, binary_file);
  227. /* Move address forward. */
  228. address++;
  229. }
  230. /* Now allocate memory for the code section. */
  231. code_buffer = malloc(code_section_array[i].code_section_size);
  232. /* Read in the code area. */
  233. j = code_section_array[i].code_section_index;
  234. elf_object_read(section_header[j].elf_section_header_offset, code_buffer, code_section_array[i].code_section_size);
  235. /* Write out the contents of this program area. */
  236. size = code_section_array[i].code_section_size;
  237. j = 0;
  238. while (size)
  239. {
  240. /* Print out a byte. */
  241. fwrite(&code_buffer[j], 1, 1, binary_file);
  242. /* Move address forward. */
  243. address++;
  244. /* Decrement size. */
  245. size--;
  246. /* Move index into buffer. */
  247. j++;
  248. }
  249. }
  250. /* Close files. */
  251. fclose(source_file);
  252. fclose(binary_file);
  253. return 0;
  254. }