123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- /*
- * cfg_maker.c
- *
- * 配置目标文件转换程序
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include "elf.c"
- typedef struct
- {
- char* obj_file;
- char* bin_file;
- int major_ver;
- int minor_ver;
- int cfg_id_start;
- } cfg_maker_t;
- typedef struct
- {
- u8_t format[4];
- u8_t magic [4];
- u16_t user_version;
- u8_t minor_version;
- u8_t major_version;
- u16_t total_size;
- u16_t num_cfgs;
- } config_header_t;
- typedef struct
- {
- u8_t cfg_id;
- u8_t sub_pos;
- u8_t cfg_size;
- } config_info_t;
- typedef struct
- {
- u32_t cfg_id:8;
- u32_t sub_pos:12;
- u32_t cfg_size:12;
- } config_info_new_t;
- static cfg_maker_t cfg_maker;
- u32_t config_item_max_size;
- static int get_args(int argc, char* argv[])
- {
- cfg_maker_t* p = &cfg_maker;
- if (!(argc == 5 || argc == 6))
- goto err;
- p->obj_file = argv[1];
- p->bin_file = argv[2];
- p->major_ver = atoi(argv[3]);
- p->minor_ver = atoi(argv[4]);
- if (argc == 6) {
- p->cfg_id_start = strtol(argv[5], NULL, 16);
- }
- if (p->major_ver >= 0x20)
- {
- config_item_max_size = 0xFFF;
- }
- else
- {
- config_item_max_size = 0xFF;
- }
- return 0;
- err:
- printf(" usage: cfg_maker.exe obj_file bin_file major_ver minor_ver [id]\n");
- return -1;
- }
- static int get_config_id(elf_obj_t* obj, Elf_Sym* sym, int* fixed_size)
- {
- int cfg_id = -1;
- char* name;
- if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT ||
- ELF_ST_BIND(sym->st_info) != STB_GLOBAL)
- return -1;
- if (sym->st_shndx == SHN_UNDEF)
- return -1;
- name = &obj->strtab[sym->st_name];
- if (strncmp(name, "ID_", 3) != 0)
- return -1;
- if (sscanf(&name[3], "%x", &cfg_id) != 1)
- return -1;
- if (fixed_size != NULL)
- {
- int len = (int)strlen(name);
- if (strncmp(&name[len - 6], "_FS_", 4) == 0)
- {
- *fixed_size = strtol(&name[len - 2], NULL, 16);
- }
- else
- {
- *fixed_size = 0;
- }
- }
- return cfg_id;
- }
- static int get_config_data(elf_obj_t* obj, int cfg_id, void* cfg_data)
- {
- Elf_Sym* sym;
- Elf_Shdr* shdr;
- int fixed_size;
- int i;
- for (i = 0; i < obj->num_syms; i++)
- {
- sym = &obj->symtab[i];
- if (get_config_id(obj, sym, &fixed_size) == cfg_id)
- break;
- }
- if (i >= obj->num_syms)
- goto err;
- if (sym->st_size > config_item_max_size)
- {
- printf(" failed: sizeof(%s) > %d\n", &obj->strtab[sym->st_name], config_item_max_size);
- goto err;
- }
- if (fixed_size > 0 &&
- sym->st_size > fixed_size)
- {
- printf(" failed: sizeof(%s) > %d\n", &obj->strtab[sym->st_name], fixed_size);
- goto err;
- }
- memset(cfg_data, 0, sym->st_size);
- shdr = &obj->shdrtab[sym->st_shndx];
- if (shdr->sh_type == SHT_NOBITS)
- {
- return (fixed_size > 0) ? fixed_size : sym->st_size;
- }
- if (shdr->sh_type != SHT_PROGBITS)
- goto err;
- fseek(obj->file, shdr->sh_offset + sym->st_value, SEEK_SET);
- fread(cfg_data, 1, sym->st_size, obj->file);
- return (fixed_size > 0) ? fixed_size : sym->st_size;
- err:
- printf(" failed %s: ID_%02X\n", __FUNCTION__, cfg_id);
- return -1;
- }
- static int get_config_num(elf_obj_t* obj)
- {
- int num = 0;
- int i;
- for (i = 0; i < obj->num_syms; i++)
- {
- Elf_Sym* sym = &obj->symtab[i];
- if (get_config_id(obj, sym, NULL) > 0)
- num += 1;
- }
- return num;
- }
- static int make_config_bin(void)
- {
- cfg_maker_t* p = &cfg_maker;
- elf_obj_t* obj;
- static char bin_data[0x10000];
- config_header_t* cfg_hdr;
- config_info_t* cfg_info;
- config_info_new_t* new_cfg_info;
- FILE* file;
- int i;
- if ((obj = elf_obj_load(p->obj_file)) == NULL)
- goto err;
- cfg_hdr = (config_header_t*)&bin_data[0];
- cfg_info = (config_info_t*)&bin_data[sizeof(config_header_t)];
- new_cfg_info = (config_info_new_t*)&bin_data[sizeof(config_header_t)];
- memcpy(cfg_hdr->format, "CFG", 4);
- memcpy(cfg_hdr->magic, "VER", 4);
- cfg_hdr->user_version = p->minor_ver | (p->major_ver << 8);
- cfg_hdr->minor_version = p->minor_ver;
- cfg_hdr->major_version = p->major_ver;
- cfg_hdr->num_cfgs = get_config_num(obj);
- if (p->major_ver >= 0x20)
- {
- cfg_hdr->total_size = sizeof(config_header_t) + cfg_hdr->num_cfgs * sizeof(config_info_new_t);
- }
- else
- {
- cfg_hdr->total_size = sizeof(config_header_t) + cfg_hdr->num_cfgs * sizeof(config_info_t);
- }
- for (i = 0; i < cfg_hdr->num_cfgs; i++)
- {
- void* cfg_data = &bin_data[cfg_hdr->total_size];
- int cfg_size;
- int cfg_id = (i + 1);
- if (p->cfg_id_start > 0)
- cfg_id = p->cfg_id_start + i;
- if ((cfg_size = get_config_data(obj, cfg_id, cfg_data)) < 0)
- goto err;
- if (p->major_ver >= 0x20)
- {
- new_cfg_info[i].cfg_id = cfg_id;
- new_cfg_info[i].sub_pos = 0;
- new_cfg_info[i].cfg_size = cfg_size;
- }
- else
- {
- cfg_info[i].cfg_id = cfg_id;
- cfg_info[i].sub_pos = 0;
- cfg_info[i].cfg_size = cfg_size;
- }
- cfg_hdr->total_size += cfg_size;
- }
- if ((file = fopen(p->bin_file, "wb")) == NULL)
- goto err;
- fwrite(bin_data, 1, cfg_hdr->total_size, file);
- fclose(file);
- return 0;
- err:
- printf(" failed %s\n", __FUNCTION__);
- return -1;
- }
- int main(int argc, char* argv[])
- {
- if (get_args(argc, argv) < 0)
- goto err;
- if (make_config_bin() < 0)
- goto err;
- return 0;
- err:
- return -1;
- }
|