/*
 * Copyright 1999 Silicon Graphics, Inc. All rights reserved.
 * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH,
 *                    IBM Corporation
 */

/* The syment struct contains information about kernel symbols (text,
 * data, etc.). The first field in syment_t is a btnode_s sruct. This
 * allows the generic binary search tree routines, insert_tnode() and
 * find_tnode(), to be used.
 */
typedef struct syment_s {
	btnode_t		s_bt;	 /* Must be first */
	struct syment_s        *s_next;  /* For linked lists */ 
	kaddr_t			s_addr;  /* vaddr of symbol */
	int			s_type;  /* text, data */
	struct syment_s		*s_forward; /* For linked lists */
} syment_t;

#define s_name s_bt.bt_key

#define SYM_GLOBAL_TEXT	1
#define SYM_LOCAL_TEXT	2
#define SYM_LOCORE_TEXT	3
#define SYM_GLOBAL_DATA	4
#define SYM_LOCAL_DATA	5
#define SYM_ABS 	6
#define SYM_UNK 	9
#define SYM_KSYM 	10

#define SYM_MAP_FILE 	0
#define SYM_MAP_KSYM 	1
#define KL_KSYMTAB        "__ksymtab__"
#define KL_KERNEL_MODULE  "kernel_module"
#define KL_S_BSS          ".bss.start"
#define KL_E_BSS          ".bss.end"
#define KL_S_DATA         ".data.start"
#define KL_E_DATA         ".data.end"
#define KL_S_RODATA       ".rodata.start"
#define KL_E_RODATA       ".rodata.end"
#define KL_S_TEXT         ".text.start"
#define KL_E_TEXT         ".text.end"
#define KL_SYM_END        "__end__"


#define KL_SYMBOL_NAME_LEN 256

/*
 * Struct containing symbol table information
 */
typedef struct symtab_s {
	int		  symcnt;	/* Number of symbols */
	syment_t	**symaddrs;	/* Table of symbols by address */ 
	btnode_t	 *symnames;	/* tree of symbols by name */
	syment_t	 *text_list;	/* Linked list of text symbols */
	syment_t	 *data_list;	/* Linked list of data symbols */
} symtab_t;


/* support of further mapfiles besides System.map */
typedef struct maplist_s {
	struct maplist_s   *next;
	int                maplist_type;  /* type of maplist */
	char               *mapfile;      /* name of mapfile */
	char               *objname;      /* name of kernel module, optional */
	size_t             text_off;      /* offset to ELF text section */
	size_t             data_off;      /* offset to ELF data section */
	size_t             rodata_off;    /* offset to ELF rodata section */
	size_t             bss_off;       /* offset to ELF bss section */
	size_t             text_len;      /* length of ELF text section */
	size_t             data_len;      /* length of ELF data section */
	size_t             rodata_len;    /* length of ELF rodata section */
	size_t             bss_len;       /* length of ELF bss section */
	size_t             size;          /* object size (e.g. size of module)*/
	symtab_t           *syminfo;
} maplist_t;

/* API Function prototypes
 */
maplist_t *kl_init_syminfo(char *, int);
int kl_init_ksyms(int);
int kl_read_syminfo(char *, maplist_t *, int);
void kl_free_syminfo(char *);
syment_t *kl_get_similar_name(char *, char *, int *, int *);
syment_t *kl_lkup_symname(char *);
syment_t *_kl_lkup_symname(char *, int, size_t len);
#define KL_LKUP_SYMNAME(NAME, TYPE, LEN) _kl_lkup_symname(NAME, TYPE, LEN)
syment_t *kl_lkup_symaddr(kaddr_t);
syment_t *_kl_lkup_symaddr(kaddr_t, int);
#define KL_LKUP_SYMADDR(KADDR, TYPE) _kl_lkup_symaddr(KADDR, TYPE)
kaddr_t kl_symaddr(char * 	/* symbol name */);
kaddr_t kl_symptr(char *	/* symbol name */);
char *kl_funcname(kaddr_t	/* pc value */);
kaddr_t kl_funcaddr(kaddr_t     /* pc value */);
int kl_funcsize(kaddr_t         /* pc value */);
