elf-from-memory.c revision dd64d4a9268b822b035f8c59c2b8f55a65f80819
1/* Reconstruct an ELF file by reading the segments out of remote memory.
2   Copyright (C) 2005-2011, 2014 Red Hat, Inc.
3   This file is part of elfutils.
4
5   This file is free software; you can redistribute it and/or modify
6   it under the terms of either
7
8     * the GNU Lesser General Public License as published by the Free
9       Software Foundation; either version 3 of the License, or (at
10       your option) any later version
11
12   or
13
14     * the GNU General Public License as published by the Free
15       Software Foundation; either version 2 of the License, or (at
16       your option) any later version
17
18   or both in parallel, as here.
19
20   elfutils is distributed in the hope that it will be useful, but
21   WITHOUT ANY WARRANTY; without even the implied warranty of
22   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23   General Public License for more details.
24
25   You should have received copies of the GNU General Public License and
26   the GNU Lesser General Public License along with this program.  If
27   not, see <http://www.gnu.org/licenses/>.  */
28
29#include <config.h>
30#include "../libelf/libelfP.h"
31#undef _
32
33#include "libdwflP.h"
34
35#include <gelf.h>
36#include <sys/types.h>
37#include <stdbool.h>
38#include <stdlib.h>
39#include <string.h>
40
41/* Reconstruct an ELF file by reading the segments out of remote memory
42   based on the ELF file header at EHDR_VMA and the ELF program headers it
43   points to.  If not null, *LOADBASEP is filled in with the difference
44   between the addresses from which the segments were read, and the
45   addresses the file headers put them at.
46
47   The function READ_MEMORY is called to copy at least MINREAD and at most
48   MAXREAD bytes from the remote memory at target address ADDRESS into the
49   local buffer at DATA; it should return -1 for errors (with code in
50   `errno'), 0 if it failed to read at least MINREAD bytes due to EOF, or
51   the number of bytes read if >= MINREAD.  ARG is passed through.
52
53   PAGESIZE is the minimum page size and alignment used for the PT_LOAD
54   segments.  */
55
56Elf *
57elf_from_remote_memory (GElf_Addr ehdr_vma,
58			GElf_Xword pagesize,
59			GElf_Addr *loadbasep,
60			ssize_t (*read_memory) (void *arg, void *data,
61						GElf_Addr address,
62						size_t minread,
63						size_t maxread),
64			void *arg)
65{
66  /* First read in the file header and check its sanity.  */
67
68  const size_t initial_bufsize = 256;
69  unsigned char *buffer = malloc (initial_bufsize);
70  if (buffer == NULL)
71    {
72    no_memory:
73      __libdwfl_seterrno (DWFL_E_NOMEM);
74      return NULL;
75    }
76
77  ssize_t nread = (*read_memory) (arg, buffer, ehdr_vma,
78				  sizeof (Elf32_Ehdr), initial_bufsize);
79  if (nread <= 0)
80    {
81    read_error:
82      free (buffer);
83      __libdwfl_seterrno (nread < 0 ? DWFL_E_ERRNO : DWFL_E_TRUNCATED);
84      return NULL;
85    }
86
87  if (memcmp (buffer, ELFMAG, SELFMAG) != 0)
88    {
89    bad_elf:
90      free (buffer);
91      __libdwfl_seterrno (DWFL_E_BADELF);
92      return NULL;
93    }
94
95  /* Extract the information we need from the file header.  */
96
97  union
98  {
99    Elf32_Ehdr e32;
100    Elf64_Ehdr e64;
101  } ehdr;
102  Elf_Data xlatefrom =
103    {
104      .d_type = ELF_T_EHDR,
105      .d_buf = buffer,
106      .d_version = EV_CURRENT,
107    };
108  Elf_Data xlateto =
109    {
110      .d_type = ELF_T_EHDR,
111      .d_buf = &ehdr,
112      .d_size = sizeof ehdr,
113      .d_version = EV_CURRENT,
114    };
115
116  GElf_Off phoff;
117  uint_fast16_t phnum;
118  uint_fast16_t phentsize;
119  GElf_Off shdrs_end;
120
121  switch (buffer[EI_CLASS])
122    {
123    case ELFCLASS32:
124      xlatefrom.d_size = sizeof (Elf32_Ehdr);
125      if (elf32_xlatetom (&xlateto, &xlatefrom, buffer[EI_DATA]) == NULL)
126	{
127	libelf_error:
128	  __libdwfl_seterrno (DWFL_E_LIBELF);
129	  return NULL;
130	}
131      phoff = ehdr.e32.e_phoff;
132      phnum = ehdr.e32.e_phnum;
133      phentsize = ehdr.e32.e_phentsize;
134      if (phentsize != sizeof (Elf32_Phdr) || phnum == 0)
135	goto bad_elf;
136      shdrs_end = ehdr.e32.e_shoff + ehdr.e32.e_shnum * ehdr.e32.e_shentsize;
137      break;
138
139    case ELFCLASS64:
140      xlatefrom.d_size = sizeof (Elf64_Ehdr);
141      if (elf64_xlatetom (&xlateto, &xlatefrom, buffer[EI_DATA]) == NULL)
142	goto libelf_error;
143      phoff = ehdr.e64.e_phoff;
144      phnum = ehdr.e64.e_phnum;
145      phentsize = ehdr.e64.e_phentsize;
146      if (phentsize != sizeof (Elf64_Phdr) || phnum == 0)
147	goto bad_elf;
148      shdrs_end = ehdr.e64.e_shoff + ehdr.e64.e_shnum * ehdr.e64.e_shentsize;
149      break;
150
151    default:
152      goto bad_elf;
153    }
154
155
156  /* The file header tells where to find the program headers.
157     These are what we use to actually choose what to read.  */
158
159  xlatefrom.d_type = xlateto.d_type = ELF_T_PHDR;
160  xlatefrom.d_size = phnum * phentsize;
161
162  if ((size_t) nread >= phoff + phnum * phentsize)
163    /* We already have all the phdrs from the initial read.  */
164    xlatefrom.d_buf = buffer + phoff;
165  else
166    {
167      /* Read in the program headers.  */
168
169      if (initial_bufsize < phnum * phentsize)
170	{
171	  unsigned char *newbuf = realloc (buffer, phnum * phentsize);
172	  if (newbuf == NULL)
173	    {
174	      free (buffer);
175	      goto no_memory;
176	    }
177	  buffer = newbuf;
178	}
179      nread = (*read_memory) (arg, buffer, ehdr_vma + phoff,
180			      phnum * phentsize, phnum * phentsize);
181      if (nread <= 0)
182	goto read_error;
183
184      xlatefrom.d_buf = buffer;
185    }
186
187  union
188  {
189    Elf32_Phdr p32[phnum];
190    Elf64_Phdr p64[phnum];
191  } phdrs;
192
193  xlateto.d_buf = &phdrs;
194  xlateto.d_size = sizeof phdrs;
195
196  /* Scan for PT_LOAD segments to find the total size of the file image.  */
197  size_t contents_size = 0;
198  GElf_Off segments_end = 0;
199  GElf_Off segments_end_mem = 0;
200  GElf_Addr loadbase = ehdr_vma;
201  bool found_base = false;
202  switch (ehdr.e32.e_ident[EI_CLASS])
203    {
204      /* Sanity checks segments and calculates segment_end,
205	 segments_end, segments_end_mem and loadbase (if not
206	 found_base yet).  Returns true if sanity checking failed,
207	 false otherwise.  */
208      inline bool handle_segment (GElf_Addr vaddr, GElf_Off offset,
209				  GElf_Xword filesz, GElf_Xword memsz,
210				  GElf_Xword palign)
211	{
212	  /* Sanity check the alignment requirements.  */
213	  if ((palign & (pagesize - 1)) != 0
214	      || ((vaddr - offset) & (palign - 1)) != 0)
215	    return true;
216
217	  GElf_Off segment_end = ((offset + filesz + pagesize - 1)
218				  & -pagesize);
219
220	  if (segment_end > (GElf_Off) contents_size)
221	    contents_size = segment_end;
222
223	  if (!found_base && (offset & -pagesize) == 0)
224	    {
225	      loadbase = ehdr_vma - (vaddr & -pagesize);
226	      found_base = true;
227	    }
228
229	  segments_end = offset + filesz;
230	  segments_end_mem = offset + memsz;
231	  return false;
232	}
233
234    case ELFCLASS32:
235      if (elf32_xlatetom (&xlateto, &xlatefrom,
236			  ehdr.e32.e_ident[EI_DATA]) == NULL)
237	goto libelf_error;
238      for (uint_fast16_t i = 0; i < phnum; ++i)
239	if (phdrs.p32[i].p_type == PT_LOAD)
240	  if (handle_segment (phdrs.p32[i].p_vaddr, phdrs.p32[i].p_offset,
241			      phdrs.p32[i].p_filesz, phdrs.p32[i].p_memsz,
242			      phdrs.p32[i].p_align))
243	    goto bad_elf;
244      break;
245
246    case ELFCLASS64:
247      if (elf64_xlatetom (&xlateto, &xlatefrom,
248			  ehdr.e64.e_ident[EI_DATA]) == NULL)
249	goto libelf_error;
250      for (uint_fast16_t i = 0; i < phnum; ++i)
251	if (phdrs.p64[i].p_type == PT_LOAD)
252	  if (handle_segment (phdrs.p64[i].p_vaddr, phdrs.p64[i].p_offset,
253			      phdrs.p64[i].p_filesz, phdrs.p64[i].p_memsz,
254			      phdrs.p64[i].p_align))
255	    goto bad_elf;
256      break;
257
258    default:
259      abort ();
260      break;
261    }
262
263  /* Trim the last segment so we don't bother with zeros in the last page
264     that are off the end of the file.  However, if the extra bit in that
265     page includes the section headers and the memory isn't extended (which
266     might indicate it will have been reused otherwise), keep them.  */
267  if ((GElf_Off) contents_size > segments_end
268      && (GElf_Off) contents_size >= shdrs_end
269      && segments_end == segments_end_mem)
270    {
271      contents_size = segments_end;
272      if ((GElf_Off) contents_size < shdrs_end)
273	contents_size = shdrs_end;
274    }
275  else
276    contents_size = segments_end;
277
278  free (buffer);
279
280  /* Now we know the size of the whole image we want read in.  */
281  buffer = calloc (1, contents_size);
282  if (buffer == NULL)
283    goto no_memory;
284
285  switch (ehdr.e32.e_ident[EI_CLASS])
286    {
287      /* Reads the given segment.  Returns true if reading fails,
288	 false otherwise.  */
289      inline bool handle_segment (GElf_Addr vaddr, GElf_Off offset,
290				  GElf_Xword filesz)
291	{
292	  GElf_Off start = offset & -pagesize;
293	  GElf_Off end = (offset + filesz + pagesize - 1) & -pagesize;
294	  if (end > (GElf_Off) contents_size)
295	    end = contents_size;
296	  nread = (*read_memory) (arg, buffer + start,
297				  (loadbase + vaddr) & -pagesize,
298				  end - start, end - start);
299	  return nread <= 0;
300	}
301
302    case ELFCLASS32:
303      for (uint_fast16_t i = 0; i < phnum; ++i)
304	if (phdrs.p32[i].p_type == PT_LOAD)
305	  if (handle_segment (phdrs.p32[i].p_vaddr, phdrs.p32[i].p_offset,
306			      phdrs.p32[i].p_filesz))
307	    goto read_error;
308
309      /* If the segments visible in memory didn't include the section
310	 headers, then clear them from the file header.  */
311      if (contents_size < shdrs_end)
312	{
313	  ehdr.e32.e_shoff = 0;
314	  ehdr.e32.e_shnum = 0;
315	  ehdr.e32.e_shstrndx = 0;
316	}
317
318      /* This will normally have been in the first PT_LOAD segment.  But it
319	 conceivably could be missing, and we might have just changed it.  */
320      xlatefrom.d_type = xlateto.d_type = ELF_T_EHDR;
321      xlatefrom.d_size = xlateto.d_size = sizeof ehdr.e32;
322      xlatefrom.d_buf = &ehdr.e32;
323      xlateto.d_buf = buffer;
324      if (elf32_xlatetof (&xlateto, &xlatefrom,
325			  ehdr.e32.e_ident[EI_DATA]) == NULL)
326	goto libelf_error;
327      break;
328
329    case ELFCLASS64:
330      for (uint_fast16_t i = 0; i < phnum; ++i)
331	if (phdrs.p64[i].p_type == PT_LOAD)
332	  if (handle_segment (phdrs.p64[i].p_vaddr, phdrs.p64[i].p_offset,
333			      phdrs.p64[i].p_filesz))
334	    goto read_error;
335
336      /* If the segments visible in memory didn't include the section
337	 headers, then clear them from the file header.  */
338      if (contents_size < shdrs_end)
339	{
340	  ehdr.e64.e_shoff = 0;
341	  ehdr.e64.e_shnum = 0;
342	  ehdr.e64.e_shstrndx = 0;
343	}
344
345      /* This will normally have been in the first PT_LOAD segment.  But it
346	 conceivably could be missing, and we might have just changed it.  */
347      xlatefrom.d_type = xlateto.d_type = ELF_T_EHDR;
348      xlatefrom.d_size = xlateto.d_size = sizeof ehdr.e64;
349      xlatefrom.d_buf = &ehdr.e64;
350      xlateto.d_buf = buffer;
351      if (elf64_xlatetof (&xlateto, &xlatefrom,
352			  ehdr.e64.e_ident[EI_DATA]) == NULL)
353	goto libelf_error;
354      break;
355
356    default:
357      abort ();
358      break;
359    }
360
361  /* Now we have the image.  Open libelf on it.  */
362
363  Elf *elf = elf_memory ((char *) buffer, contents_size);
364  if (elf == NULL)
365    {
366      free (buffer);
367      goto libelf_error;
368    }
369
370  elf->flags |= ELF_F_MALLOCED;
371  if (loadbasep != NULL)
372    *loadbasep = loadbase;
373  return elf;
374}
375