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
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;
|
|
}
|