1 /*
2 ** raw.c for libelfsh
3 **
4 ** Started on  Wed Feb 27 19:41:45 2002 mayhem
5 ** Last update Thu Mar 20 05:47:12 2003 mayhem
6 */
7 #include "libelfsh.h"
8 
9 
10 
11 /* Perform a raw write on the object cache data */
elfsh_raw_write(elfshobj_t * file,u_int foffset,void * src_buff,int len)12 int		elfsh_raw_write(elfshobj_t	*file,
13 				u_int		foffset,
14 				void		*src_buff,
15 				int		len)
16 {
17   elfshsect_t	*sect;
18   int		sect_off;
19   void		*dst;
20 
21   sect = elfsh_get_parent_section_by_foffset(file, foffset, NULL);
22   if (sect == NULL)
23     ELFSH_SETERROR("[libelfsh] Invalid virtual address\n", -1);
24 
25   sect_off = foffset - sect->shdr->sh_offset;
26   if (sect_off + len > sect->shdr->sh_size)
27     ELFSH_SETERROR("[libelfsh] Section too short\n", -1);
28 
29   dst = elfsh_get_anonymous_section(file, sect);
30   if (dst == NULL)
31     return (0);
32 
33   memcpy(dst + sect_off, src_buff, len);
34   return (len);
35 }
36 
37 
38 
39 /* Perform a raw read on the object cache data */
elfsh_raw_read(elfshobj_t * file,u_int foffset,void * dest_buff,int len)40 int		elfsh_raw_read(elfshobj_t *file, u_int foffset, void *dest_buff, int len)
41 {
42   elfshsect_t	*sect;
43   void		*src;
44   int		sect_off;
45 
46   sect = elfsh_get_parent_section_by_foffset(file, foffset, NULL);
47   if (sect == NULL)
48     ELFSH_SETERROR("[libelfsh] Invalid virtual address\n", -1);
49 
50   sect_off = foffset - sect->shdr->sh_offset;
51 
52   if (sect_off + len > sect->shdr->sh_size)
53     len -= (sect_off + len - sect->shdr->sh_size);
54 
55   src = elfsh_get_anonymous_section(file, sect);
56   if (src == NULL)
57     return (0);
58 
59   memcpy(dest_buff, src + sect_off, len);
60   return (len);
61 
62 }
63 
64 
65 /* Retreive the file offset from the virtual address */
elfsh_get_foffset_from_vaddr(elfshobj_t * file,u_int vaddr)66 int		elfsh_get_foffset_from_vaddr(elfshobj_t *file, u_int vaddr)
67 {
68   elfshsect_t	*actual;
69 
70   if (!vaddr)
71     return (0);
72   for (actual = file->sectlist; actual; actual = actual->next)
73     if (INTERVAL(actual->shdr->sh_addr, vaddr, actual->shdr->sh_addr + actual->shdr->sh_size))
74       return (actual->shdr->sh_offset + (vaddr - actual->shdr->sh_addr));
75   return (0);
76 }
77 
78 
79 /* Retreive the virtual address given the file offset */
elfsh_get_vaddr_from_foffset(elfshobj_t * file,u_int foffset)80 int		elfsh_get_vaddr_from_foffset(elfshobj_t *file, u_int foffset)
81 {
82   elfshsect_t	*root;
83 
84   root = elfsh_get_parent_section_by_foffset(file, foffset, NULL);
85   if (root)
86     return (root->shdr->sh_addr + (foffset - root->shdr->sh_offset));
87   return (0);
88 }
89