/*
** elf.c for libelfsh
** 
** Started on  Mon Feb 26 04:09:38 2001 mayhem
** Last update Sat Mar 23 13:01:27 2002 mayhem
*/
#include "libelfsh.h"





/* Change the section header table file offset */
void		elfsh_set_sht_offset(Elfsh32_Obj *file, int num)
{
  file->hdr->e_shoff = num;
}


/* Change the section header table entry count */
void		elfsh_set_sht_nbr(Elfsh32_Obj *file, int num)
{
  file->hdr->e_shnum = num;
}

/* Change the program header table file offset */
void		elfsh_set_pht_offset(Elfsh32_Obj *file, int num)
{
  file->hdr->e_phoff = num;
}

/* Change the program header table entry count */
void	elfsh_set_pht_nbr(Elfsh32_Obj *file, int num)
{
  file->hdr->e_phnum = num;
}

/* Change the program entry point */
void		elfsh_set_entry_point(Elfsh32_Obj *file, int addr)
{
  file->hdr->e_entry = addr;
}




/* Load the ELF header */
int		elfsh_load_hdr(Elfsh32_Obj *file)
{
  int	len;
  
  if (file->hdr)
    return (sizeof(Elf32_Ehdr));
  
  XALLOC(file->hdr, sizeof(Elf32_Ehdr), -1);
  
  if ((len = read(file->fd, file->hdr, sizeof(Elf32_Ehdr))) <= 0)
    ELFSH_SETERROR(ELFSH_ERR_ARRAY, len);

  return (len);
}



/* Return the machine type giving its e_arch field */
u_int	elfsh_get_arch(Elf32_Ehdr *e)
{
  return (e->e_machine);
}



/* Return the ELF object type giving its e_type field */
u_int	elfsh_get_objtype(Elf32_Ehdr *e)
{
  return (e->e_type);
}



/* Return a ptr on the ELF header (load it before if not done yet) */
void	*elfsh_get_hdr(Elfsh32_Obj *file)
{
  char	*h;

  if (file->hdr)
    return (file->hdr);
  else if (elfsh_load_hdr(file) <= 0)
    return (NULL);
  
  h = (char *) file->hdr;
  if (h[0] != ELFMAG0 || h[1] != ELFMAG1 || h[2] != ELFMAG2 || h[3] != ELFMAG3)
    ELFSH_SETERROR("libelfsh: Bad ELF MAGIC .", NULL);
  if (h[4] != 1)
    ELFSH_SETERROR("libelfsh: Only ELF32 binaries are supported .", NULL);
  
  return (file->hdr);
}



/*
** - Open the file 'name' and store the descriptor in the Elfsh32_Obj
** - Return a pointer on Elfsh32_Obj
** -> Return NULL if failed
*/
Elfsh32_Obj		*elfsh_load_obj(char *name)
{
  Elfsh32_Obj	*file;

  XALLOC(file, sizeof(Elfsh32_Obj), NULL);
  XOPEN(file->fd, name, O_RDONLY, 0, NULL);
  file->name = name;
  if ((file->hdr = elfsh_get_hdr(file)) == NULL)
    return (NULL);

  return (file);
}







/* Free the ELF descriptor and its fields */
void		elfsh_unload_obj(Elfsh32_Obj *file)
{
  Elfsh32_Sect	*sect;
  Elfsh32_Sect	*next;

  free(file->pht);
  free(file->sht);

  for (sect = file->sections; sect; sect = next)
    {
      free(sect->data);
      free(sect->name);

      next = sect->next;
      free(sect);
    }

  close(file->fd);
  free(file);
}










