/* * Copyright (c) Hisilicon Technologies Co., Ltd. 2014-2020. All rights reserved. * Description: mksym * Author: SmartMedia_BSP * Create: 2014-06-04 */ #include #include #include struct sym_t { unsigned int entry; unsigned int size; char *name; }; struct symtbl_t { struct sym_t *syms; unsigned int max_sym; unsigned int of_sym; char *buf; unsigned int max_buf; unsigned int of_buf; }; #define MAX_SYMBOL_NAME 512 static int read_symbol(FILE *fin, struct symtbl_t *symtbl) { int ret; char type; struct sym_t *sym; /* 8050b694 00000014 T udp_send 8050b6a8 00000328 T udp_input 8050b9d0 0000006c t etharp_free_entry 8050ba3c 00000248 t etharp_find_entry 8050bc84 0000009c T etharp_find_addr 8050bd20 00000050 T etharp_cleanup_netif */ sym = &symtbl->syms[symtbl->of_sym]; sym->name = symtbl->buf + symtbl->of_buf; ret = fscanf_s(fin, "%x %x %c %511s\n", &sym->entry, &sym->size, &type, sizeof(char), sym->name, MAX_SYMBOL_NAME); if (ret != 4) { /* 4 parameters */ if (ret != EOF && fgets(sym->name, MAX_SYMBOL_NAME, fin) == NULL) { fprintf(stderr, "Read error or end of file.\n"); } return -1; } if (type != 'T' && type != 't') { return 1; } symtbl->of_sym++; symtbl->of_buf += strlen(sym->name) + 1; return 0; } static int alloc_symbol_buf(struct symtbl_t *symtbl) { int ret; struct sym_t *sym = NULL; symtbl->max_sym += 100; /* 100: increase step */ sym = (struct sym_t *)malloc(symtbl->max_sym * sizeof(struct sym_t)); if (sym == NULL) { fprintf(stderr, "out of memory.\n"); return -1; } if (symtbl->syms != NULL && symtbl->of_sym != 0) { ret = memcpy_s(sym, symtbl->max_sym * sizeof(struct sym_t), symtbl->syms, symtbl->of_sym * sizeof(struct sym_t)); if (ret != EOK) { fprintf(stderr, "mempcy error\n"); free(sym); return -1; } } if (symtbl->syms != NULL) { free(symtbl->syms); } symtbl->syms = sym; return 0; } static int alloc_data_buf(struct symtbl_t *symtbl) { char *buf = NULL; symtbl->max_buf += MAX_SYMBOL_NAME * 100; /* 100: increase step */ buf = malloc(symtbl->max_buf); if (buf == NULL) { fprintf(stderr, "out of memory.\n"); return -1; } if (symtbl->buf != NULL && symtbl->of_buf != 0) { if (memcpy_s(buf, symtbl->max_buf, symtbl->buf, symtbl->of_buf) != EOK) { fprintf(stderr, "mempcy error\n"); free(buf); return -1; } } if (symtbl->buf != NULL) { free(symtbl->buf); } symtbl->buf = buf; return 0; } static int read_map(FILE *fin, struct symtbl_t *symtbl) { int ret; while (!feof(fin)) { if (symtbl->of_sym >= symtbl->max_sym) { ret = alloc_symbol_buf(symtbl); if (ret != 0) { fprintf(stderr, "alloc symbolbuf failed\n"); return -1; } } if (symtbl->of_buf + MAX_SYMBOL_NAME > symtbl->max_buf) { ret = alloc_data_buf(symtbl); if (ret != 0) { fprintf(stderr, "alloc data buf failed\n"); return -1; } } read_symbol(fin, symtbl); } return 0; } static void export_symbol(char *buf, unsigned int sz_buf) { unsigned int *ptr = (unsigned int *)buf; sz_buf += 3; /* 3: 3 bytes */ printf(".section .symbol,#alloc\n"); printf(".global __symbol_start; __symbol_start:\n"); while (sz_buf >= 4) { /* 4 bytes */ printf(".word 0x%08x\n", *ptr); sz_buf -= 4; /* 4 bytes */ ptr++; } printf(".global __symbol_end; __symbol_end:\n"); } static void dump_symbol(FILE *fout, const struct symtbl_t *symtbl) { int ix; unsigned int *paddr = NULL; char *pbuf = NULL; char *data = NULL; unsigned int sz_data; int ret; struct sym_t *sym = NULL; sz_data = (symtbl->of_sym + 1) * sizeof(struct sym_t) + symtbl->of_buf; data = (char *)malloc(sz_data + 4); /* 4 bytes */ if (data == NULL) { fprintf(stderr, "out of memory.\n"); return; } (void)memset_s(data, sz_data + 4, 0, sz_data + 4); /* 4 bytes */ paddr = (unsigned int *)data; pbuf = data + (symtbl->of_sym + 1) * sizeof(struct sym_t); for (ix = 0; ix < symtbl->of_sym; ix++) { sym = &symtbl->syms[ix]; *paddr++ = sym->entry; *paddr++ = sym->size; *paddr++ = (unsigned int)(pbuf - data); ret = sprintf_s(pbuf, sz_data - ((symtbl->of_sym + 1) * sizeof(struct sym_t)), "%s", sym->name) + 1; if (ret < 0) { fprintf(stderr, "sprintf_s failed\n"); free(data); return; } pbuf += ret; } export_symbol(data, sz_data); free(symtbl->buf); free(symtbl->syms); free(data); } int main(int argc, const char *argv[]) { struct symtbl_t symtbl = {0}; read_map(stdin, &symtbl); dump_symbol(stdout, &symtbl); return 0; }