/*
** raw.c for libelfsh
** 
** Started on  Wed Feb 27 19:41:45 2002 mayhem
** Last update Sun Mar 10 01:05:43 2002 mayhem
*/
#include "libelfsh.h"



/* Perform a raw write on the object cache data */
int		elfsh_raw_write(Elfsh32_Obj *file, u_int foffset, void *src_buff, int len)
{
  Elfsh32_Sect	*sect;
  int		sect_off;
  void		*dst;

  sect = elfsh_get_parent_section_by_foffset(file, foffset, NULL);
  if (!sect)
    ELFSH_SETERROR("libelfsh: Invalid virtual address .", -1);

  sect_off = foffset - sect->shdr->sh_offset;
  if (sect_off + len > sect->shdr->sh_size)
    ELFSH_SETERROR("libelfsh: Section too short to write the whole buffer .", -1);

  dst = elfsh_get_anonymous_section(file, sect);
  if (!dst)
    return (0);

  memcpy(dst + sect_off, src_buff, len);
  return (len);
}







/* Perform a raw read on the object cache data */
int		elfsh_raw_read(Elfsh32_Obj *file, u_int foffset, void *dest_buff, int len)
{
  Elfsh32_Sect	*sect;
  void		*src;
  int		sect_off;

  sect = elfsh_get_parent_section_by_foffset(file, foffset, NULL);
  if (sect == NULL)
    ELFSH_SETERROR("libelfsh: Invalid virtual address .", -1);

  sect_off = foffset - sect->shdr->sh_offset;

  if (sect_off + len > sect->shdr->sh_size)
    len -= (sect_off + len - sect->shdr->sh_size);

  src = elfsh_get_anonymous_section(file, sect);
  if (!src)
    return (0);

  memcpy(dest_buff, src + sect_off, len);
  return (len);

}





/* Retreive the file offset from the virtual address */
int		elfsh_get_foffset_from_vaddr(Elfsh32_Obj *file, u_int vaddr)
{
  Elfsh32_Sect	*actual;

  for (actual = file->sections; actual; actual = actual->next)
    if (INTERVAL(actual->shdr->sh_addr, vaddr, actual->shdr->sh_addr + actual->shdr->sh_size))
      return (actual->shdr->sh_offset + (vaddr - actual->shdr->sh_addr));
  return (-1);
}
