/*
** elfsh.h for elfsh
** 
** Started on  Thu Feb 22 07:19:04 2001 mayhem
** Last update Sun Mar 24 12:15:01 2002 mayhem
*/

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <regex.h>
#include <libelfsh.h>




#if defined(__NetBSD__)
#include <readline.h>
#elif defined(__linux__) || defined(__FreeBSD__) | defined(sun)
#include <readline/readline.h>
#endif


#define REGX_IS_USED(a) a







/*
** Externs . These arrays are used to store ascii description for different
** structures types in data.c
*/

extern char	*elfsh_seg_type[7];
extern char	*elfsh_seg_type_short[7];
extern char	*elfsh_sh_type[12];
extern char	*elfsh_obj_type[5];
extern char	*elfsh_sym_bind[16];
extern char	*elfsh_sym_type[5];
extern char	*elfsh_arch_type[55];
extern char	*elfsh_dynentry_type[29];
extern char	*elfsh_dynentry_type_short[29];
extern char	*elfsh_rel_type[11];
extern char	*elfsh_rel_type_short[11];
extern char	*elfsh_stab_type[256];


#define		SEGTYPE_MAX	(sizeof(elfsh_seg_type) - 1)
#define		SHTYPE_MAX	(sizeof(elfsh_sh_type) - 1)
#define		OBJTYPE_MAX	(sizeof(elfsh_obj_type) - 1)
#define		SYMBIND_MAX	(sizeof(elfsh_sym_bind) - 1)
#define		SYMTYPE_MAX	(sizeof(elfsh_sym_type) - 1)
#define		ARCHTYPE_MAX	(sizeof(elfsh_arch_type) - 1)
#define		DYNAMIC_MAX	(sizeof(elfsh_dynentry_type) - 1)
#define		RELOC_MAX	(sizeof(elfsh_rel_type) - 1)
#define		STAB_MAX	(sizeof(elfsh_stab_type) - 1)




/* Linked list basic structure */
typedef struct		s_list
{
  regex_t		name;
  struct s_list		*next;
}			list_t;




/* Thats the command line options structure */
typedef struct		s_args
{
  char			sym;
  regex_t		sym_regx;
  char			sym_use_regx;

  char			dynsym;
  regex_t		dynsym_regx;
  char			dynsym_use_regx;

  char			sht;
  regex_t		sht_regx;
  char			sht_use_regx;

  char			stab;
  regex_t		stab_regx;
  char			stab_use_regx;

  char			dyn;
  regex_t		dyn_regx;
  char			dyn_use_regx;

  char			rel;
  regex_t		rel_regx;
  char			rel_use_regx;

  char			notes;
  regex_t		notes_regx;
  char			notes_use_regx;

  char			got;
  regex_t		got_regx;
  char			got_use_regx;

  char			ctors;
  regex_t		ctors_regx;
  char			ctors_use_regx;

  char			dtors;
  regex_t		dtors_regx;
  char			dtors_use_regx;

  regex_t		gl_regx;
  char			gl_use_regx;

  list_t		*disasm;
  list_t		*hexa;

  char			*sort;
  char			*filename;
  char			elf;
  char			interp;
  char			pht;

}			argv_t;








/* Command line parsing marcros */
#define		GETALLOPT()						\
do									\
{									\
  cmdarg->rel    = 1;							\
  cmdarg->elf    = 1;							\
  cmdarg->stab   = 1;							\
  cmdarg->pht    = 1;							\
  cmdarg->sht    = 1;							\
  cmdarg->dynsym = 1;							\
  cmdarg->dyn    = 1;							\
  cmdarg->sym    = 1;							\
  cmdarg->got    = 1;							\
  cmdarg->notes  = 1;							\
  cmdarg->interp = 1;							\
  cmdarg->ctors  = 1;							\
  cmdarg->dtors  = 1;							\
  if ((index + 1) < argc && argv[index + 1][0] != MINUS)		\
    {									\
      if (regcomp(&cmdarg->gl_regx, argv[++index], REG_EXTENDED) < 0)	\
	usage(argv[0]);							\
      else								\
	cmdarg->gl_use_regx = 1;					\
    }									\
}									\
while (0)




#define		ADD_DISASM_ENTRY()					\
do									\
{									\
  list_t	*new;							\
									\
  if (argv[index + 1] == NULL)						\
    usage(argv[0]);							\
  if ((new = calloc(sizeof(list_t), 1)) == NULL)			\
    FATAL("calloc");							\
  if (regcomp(&new->name, argv[++index], REG_EXTENDED) < 0)	        \
    usage(argv[0]);							\
  new->next = cmdarg->disasm;						\
  cmdarg->disasm = new;							\
}									\
while (0)




#define		ADD_HEXA_ENTRY()					\
do									\
{									\
  list_t	*new;							\
									\
  if (argv[index + 1] == NULL)						\
    usage(argv[0]);							\
  if ((new = calloc(sizeof(list_t), 1)) == NULL)			\
    FATAL("calloc");							\
  if (regcomp(&new->name, argv[++index], REG_EXTENDED) < 0)	        \
    usage(argv[0]);							\
  new->next = cmdarg->hexa;						\
  cmdarg->hexa = new;							\
}									\
while (0)







/*
** Get the option 
** Fill the option regx related entry to the next argument if one 
*/
#define GETOPT(a)							\
do									\
{									\
  a = 1;								\
  if ((index + 1) < argc && argv[index + 1][0] != MINUS)		\
     {									\
       if (regcomp(&a##_regx, argv[++index], REG_EXTENDED) < 0)		\
	 usage(argv[0]);						\
       else								\
	 a##_use_regx = 1;						\
     }									\
}									\
while (0)






/* Get the option from the command line but dont pass it to the regex machine */
#define GETOPTION(a)				\
do						\
  if ((index + 1) >= argc)			\
    usage(argv[0]);				\
  else						\
    a = argv[++index];				\
while (0)




/* Check if the a option is active, if yes call the display function */
#define CHECK_OPTION(a)				\
do						\
  if (args.a)					\
    display_##a(file, &args);			\
while (0)


/* General usage macros */
#define FATAL(a)		{ perror(a);     exit(-1);    }
#define QUIT(a)			{ elfsh_error(); exit(a);    }
#define RET(a)			{ elfsh_error(); return (a); }
#define RETERR(a)		{ fprintf(stderr, "%s \n", a); return (-1); }
#define	PRINTABLE(c)		(c >= 32 && c <= 126)





#define PROMPT			"ELFsh-0.3> "
#define MINUS			'-'

#define DISASM			"-disasm"
#define	DISASM2			"-D"
#define MODE			"-m"
#define BINFILE			"-f"
#define REL			"-rel"
#define REL2			"-r"
#define DYNAMIC			"-dyn"
#define	DYNAMIC2		"-d"
#define SYM			"-sym"
#define	SYM2			"-syms"
#define DYNSYM			"-dynsym"
#define DYNSYM2			"-ds"
#define SHT			"-shdr"
#define SHT2			"-s"
#define PHT			"-phdr"
#define PHT2			"-p"
#define STAB			"-stab"
#define STAB2			"-st"
#define DWARF			"-dwarf"
#define DWARF2			"-dw"
#define REGX			"-filter"
#define ELF			"-elf"
#define ELF2			"-e"
#define	INTERP			"-interp"
#define	INTERP2			"-i"
#define	NOTE			"-notes"
#define	NOTE2			"-n"
#define	GOT			"-got"
#define	GOT2			"-g"
#define	CTORS			"-ctors"
#define	CTORS2			"-ct"
#define	DTORS			"-dtors"
#define	DTORS2			"-dt"
#define	HEXA			"-hexa"
#define	HEXA2			"-X"

#define ALL			"-all"
#define ALL2			"-a"
#define	SORT			"-sort"
#define	SORT2			"-sr"





/* Prototypes */

int		display_dyn(Elfsh32_Obj *, argv_t *);
int		display_sht(Elfsh32_Obj *, argv_t *);
int		display_rel(Elfsh32_Obj *, argv_t *);
int		display_dynsym(Elfsh32_Obj *, argv_t *);
int		display_symtab(Elfsh32_Obj *, argv_t *);
int		display_pht(Elfsh32_Obj *, argv_t *);
int		display_got(Elfsh32_Obj *, argv_t *);
int		display_dtors(Elfsh32_Obj *, argv_t *);
int		display_ctors(Elfsh32_Obj *, argv_t *);
int		display_elf(Elfsh32_Obj *, argv_t *);
int		display_interp(Elfsh32_Obj *, argv_t *);
int		display_list(Elfsh32_Obj *, argv_t *);
int		display_notes(Elfsh32_Obj *file, argv_t *args);
int		display_sym(Elfsh32_Obj *file, argv_t *args);
int		display_stab(Elfsh32_Obj *file, argv_t *args);

int             display_hexa(Elfsh32_Obj *file, argv_t *av);
int             display_disasm(Elfsh32_Obj *file, argv_t *av);

void		imode();
void		get_options(int argc, char **argv, argv_t *);
void		usage(char *str);
void            __display_sym(Elfsh32_Obj *, void *, int, regex_t *, 
			      argv_t *, char *(*f)(Elfsh32_Obj *, Elf32_Sym *));














