/*
** rel.c for elfsh
** 
** Started on  Fri Nov  2 15:19:19 2001 mayhem
** Last update Sun Mar 24 12:18:30 2002 mayhem
*/
#include "elfsh.h"




/* Display relocation entries */
int            display_rel(Elfsh32_Obj *file, argv_t *args)
{
  Elfsh32_Sect	*sect;
  Elf32_Rel	*rel;
  regex_t	*tmp;
  char		*type;
  char		*typeshort;
  Elf32_Sym	*sym;
  char		*name;
  u_int		index;
  u_int		index2;
  u_int		typenum;
  int		offset;
  char		off[30];
  char		buff[256];

  tmp = (REGX_IS_USED(args->rel_use_regx) ? &args->rel_regx : 
	 REGX_IS_USED(args->gl_use_regx)  ? &args->gl_regx  : NULL);

  puts("\n[RELOCATION TABLES]");
  
  off[0] = 0;

  for (index2 = 0; (sect = elfsh_get_reloc(file, index2, NULL, NULL)); index2++)
    {
      
      printf(" {Section %s} \n", elfsh_get_section_name(file, sect->shdr));
      
      for (index = 0, rel = sect->data; index < sect->nbr; index++)
	{
	  
	  sym = elfsh_get_symbol_from_reloc(file, rel + index);


	  name = elfsh_reverse_symbol(file, sym->st_value, &offset);
	  if (!name)
	    name = elfsh_reverse_dynsymbol(file, sym->st_value, &offset);
	  else if (off)
	    snprintf(off, sizeof(off), " %c %5u", 
		     (offset < 0 ? '-' : '+'), 
		     (offset > 0 ? offset : offset - offset - offset));

	  typenum = elfsh_get_reloc_type(rel + index);
	  type = (typenum > RELOC_MAX ? NULL : elfsh_rel_type[typenum]);
	  typeshort = (typenum > RELOC_MAX ? NULL : elfsh_rel_type_short[typenum]);
	  
	  snprintf(buff, sizeof(buff), "\t [%02u] %s \t %-10p \t Symbol: %40s%s %-10p \t => %s",
		   index, typeshort, (void *) elfsh_get_reloffset(file, rel + index), 
		   (name ? name : "?"), (name && offset ? off : "\t"), (void *) sym->st_value, type);

	  if (!tmp || (tmp && name && !regexec(tmp, buff, 0, 0, 0)))
	    puts(buff);

	}
      
      puts("");
    }

  puts("");
  return (0);
}
