/*
** dtors.c for libelfsh
** 
** Started on  Tue Feb 26 22:12:38 2002 mayhem
** Last update Sun Mar 10 02:47:46 2002 mayhem
*/
#include "libelfsh.h"



/* Read the destructor array in .dtors */
void		*elfsh_get_dtors(Elfsh32_Obj *file, int *num)
{
  Elfsh32_Sect	*new;

  new = elfsh_get_section_by_name(file, ELFSH_SECTION_NAME_DTORS, NULL, NULL, NULL);
  if (!new)
    return (NULL);

  new->nbr = new->shdr->sh_size / 4;

  new->data = elfsh_load_section(file, new->shdr);
  if (!new->data)
    return (NULL);

  file->dtors = new;

  if (num)
    *num = new->nbr;

  return (new->data);
}






/* Modify a DTORS entry */
int		elfsh_set_dtors_entry_by_index(Elfsh32_Obj *file, int index, int new_addr)
{
  int		nbr;
  int		*dtors;
  
  dtors = elfsh_get_dtors(file, &nbr);
  if (!dtors)
    return (-1);
  if (index >= file->dtors->nbr)
    ELFSH_SETERROR("libelfsh: index too big . \n", -1);
  dtors[index] = new_addr;
  return (0);
}





/* Modify a DTORS entry using its name */
int		elfsh_set_dtors_entry_by_name(Elfsh32_Obj *file, char *name, int new_addr)
{
  int		nbr;
  int		*dtors;
  Elf32_Sym	*sym;
  int		index;

  dtors = elfsh_get_dtors(file, &nbr);
  if (!dtors)
    return (-1);

  sym = elfsh_get_symbol_by_name(file, name);
  if (!sym)
    return (-1);

  for (index = 0; index < nbr; index++)
    if (dtors[index] == sym->st_value)
      {
	dtors[index] = new_addr;
	return (0);
      }
  
  ELFSH_SETERROR("libelfsh: Cant find dtors entry for this symbol . \n", -1);
}












