You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

208 lines
5.1 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2014-2020. All rights reserved.
* Description: mksym
* Author: SmartMedia_BSP
* Create: 2014-06-04
*/
#include <securec.h>
#include <stdio.h>
#include <string.h>
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;
}