cfg_maker.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. /*
  2. * cfg_maker.c
  3. *
  4. * 配置目标文件转换程序
  5. */
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <ctype.h>
  10. #include "elf.c"
  11. typedef struct
  12. {
  13. char* obj_file;
  14. char* bin_file;
  15. int major_ver;
  16. int minor_ver;
  17. int cfg_id_start;
  18. } cfg_maker_t;
  19. typedef struct
  20. {
  21. u8_t format[4];
  22. u8_t magic [4];
  23. u16_t user_version;
  24. u8_t minor_version;
  25. u8_t major_version;
  26. u16_t total_size;
  27. u16_t num_cfgs;
  28. } config_header_t;
  29. typedef struct
  30. {
  31. u8_t cfg_id;
  32. u8_t sub_pos;
  33. u8_t cfg_size;
  34. } config_info_t;
  35. typedef struct
  36. {
  37. u32_t cfg_id:8;
  38. u32_t sub_pos:12;
  39. u32_t cfg_size:12;
  40. } config_info_new_t;
  41. static cfg_maker_t cfg_maker;
  42. u32_t config_item_max_size;
  43. static int get_args(int argc, char* argv[])
  44. {
  45. cfg_maker_t* p = &cfg_maker;
  46. if (!(argc == 5 || argc == 6))
  47. goto err;
  48. p->obj_file = argv[1];
  49. p->bin_file = argv[2];
  50. p->major_ver = atoi(argv[3]);
  51. p->minor_ver = atoi(argv[4]);
  52. if (argc == 6) {
  53. p->cfg_id_start = strtol(argv[5], NULL, 16);
  54. }
  55. if (p->major_ver >= 0x20)
  56. {
  57. config_item_max_size = 0xFFF;
  58. }
  59. else
  60. {
  61. config_item_max_size = 0xFF;
  62. }
  63. return 0;
  64. err:
  65. printf(" usage: cfg_maker.exe obj_file bin_file major_ver minor_ver [id]\n");
  66. return -1;
  67. }
  68. static int get_config_id(elf_obj_t* obj, Elf_Sym* sym, int* fixed_size)
  69. {
  70. int cfg_id = -1;
  71. char* name;
  72. if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT ||
  73. ELF_ST_BIND(sym->st_info) != STB_GLOBAL)
  74. return -1;
  75. if (sym->st_shndx == SHN_UNDEF)
  76. return -1;
  77. name = &obj->strtab[sym->st_name];
  78. if (strncmp(name, "ID_", 3) != 0)
  79. return -1;
  80. if (sscanf(&name[3], "%x", &cfg_id) != 1)
  81. return -1;
  82. if (fixed_size != NULL)
  83. {
  84. int len = (int)strlen(name);
  85. if (strncmp(&name[len - 6], "_FS_", 4) == 0)
  86. {
  87. *fixed_size = strtol(&name[len - 2], NULL, 16);
  88. }
  89. else
  90. {
  91. *fixed_size = 0;
  92. }
  93. }
  94. return cfg_id;
  95. }
  96. static int get_config_data(elf_obj_t* obj, int cfg_id, void* cfg_data)
  97. {
  98. Elf_Sym* sym;
  99. Elf_Shdr* shdr;
  100. int fixed_size;
  101. int i;
  102. for (i = 0; i < obj->num_syms; i++)
  103. {
  104. sym = &obj->symtab[i];
  105. if (get_config_id(obj, sym, &fixed_size) == cfg_id)
  106. break;
  107. }
  108. if (i >= obj->num_syms)
  109. goto err;
  110. if (sym->st_size > config_item_max_size)
  111. {
  112. printf(" failed: sizeof(%s) > %d\n", &obj->strtab[sym->st_name], config_item_max_size);
  113. goto err;
  114. }
  115. if (fixed_size > 0 &&
  116. sym->st_size > fixed_size)
  117. {
  118. printf(" failed: sizeof(%s) > %d\n", &obj->strtab[sym->st_name], fixed_size);
  119. goto err;
  120. }
  121. memset(cfg_data, 0, sym->st_size);
  122. shdr = &obj->shdrtab[sym->st_shndx];
  123. if (shdr->sh_type == SHT_NOBITS)
  124. {
  125. return (fixed_size > 0) ? fixed_size : sym->st_size;
  126. }
  127. if (shdr->sh_type != SHT_PROGBITS)
  128. goto err;
  129. fseek(obj->file, shdr->sh_offset + sym->st_value, SEEK_SET);
  130. fread(cfg_data, 1, sym->st_size, obj->file);
  131. return (fixed_size > 0) ? fixed_size : sym->st_size;
  132. err:
  133. printf(" failed %s: ID_%02X\n", __FUNCTION__, cfg_id);
  134. return -1;
  135. }
  136. static int get_config_num(elf_obj_t* obj)
  137. {
  138. int num = 0;
  139. int i;
  140. for (i = 0; i < obj->num_syms; i++)
  141. {
  142. Elf_Sym* sym = &obj->symtab[i];
  143. if (get_config_id(obj, sym, NULL) > 0)
  144. num += 1;
  145. }
  146. return num;
  147. }
  148. static int make_config_bin(void)
  149. {
  150. cfg_maker_t* p = &cfg_maker;
  151. elf_obj_t* obj;
  152. static char bin_data[0x10000];
  153. config_header_t* cfg_hdr;
  154. config_info_t* cfg_info;
  155. config_info_new_t* new_cfg_info;
  156. FILE* file;
  157. int i;
  158. if ((obj = elf_obj_load(p->obj_file)) == NULL)
  159. goto err;
  160. cfg_hdr = (config_header_t*)&bin_data[0];
  161. cfg_info = (config_info_t*)&bin_data[sizeof(config_header_t)];
  162. new_cfg_info = (config_info_new_t*)&bin_data[sizeof(config_header_t)];
  163. memcpy(cfg_hdr->format, "CFG", 4);
  164. memcpy(cfg_hdr->magic, "VER", 4);
  165. cfg_hdr->user_version = p->minor_ver | (p->major_ver << 8);
  166. cfg_hdr->minor_version = p->minor_ver;
  167. cfg_hdr->major_version = p->major_ver;
  168. cfg_hdr->num_cfgs = get_config_num(obj);
  169. if (p->major_ver >= 0x20)
  170. {
  171. cfg_hdr->total_size = sizeof(config_header_t) + cfg_hdr->num_cfgs * sizeof(config_info_new_t);
  172. }
  173. else
  174. {
  175. cfg_hdr->total_size = sizeof(config_header_t) + cfg_hdr->num_cfgs * sizeof(config_info_t);
  176. }
  177. for (i = 0; i < cfg_hdr->num_cfgs; i++)
  178. {
  179. void* cfg_data = &bin_data[cfg_hdr->total_size];
  180. int cfg_size;
  181. int cfg_id = (i + 1);
  182. if (p->cfg_id_start > 0)
  183. cfg_id = p->cfg_id_start + i;
  184. if ((cfg_size = get_config_data(obj, cfg_id, cfg_data)) < 0)
  185. goto err;
  186. if (p->major_ver >= 0x20)
  187. {
  188. new_cfg_info[i].cfg_id = cfg_id;
  189. new_cfg_info[i].sub_pos = 0;
  190. new_cfg_info[i].cfg_size = cfg_size;
  191. }
  192. else
  193. {
  194. cfg_info[i].cfg_id = cfg_id;
  195. cfg_info[i].sub_pos = 0;
  196. cfg_info[i].cfg_size = cfg_size;
  197. }
  198. cfg_hdr->total_size += cfg_size;
  199. }
  200. if ((file = fopen(p->bin_file, "wb")) == NULL)
  201. goto err;
  202. fwrite(bin_data, 1, cfg_hdr->total_size, file);
  203. fclose(file);
  204. return 0;
  205. err:
  206. printf(" failed %s\n", __FUNCTION__);
  207. return -1;
  208. }
  209. int main(int argc, char* argv[])
  210. {
  211. if (get_args(argc, argv) < 0)
  212. goto err;
  213. if (make_config_bin() < 0)
  214. goto err;
  215. return 0;
  216. err:
  217. return -1;
  218. }