blob: c54c1b9984b474e1f8963507254b561cf12a4ea0 [file] [log] [blame]
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001/* Reconstruct an ELF file by reading the segments out of remote memory.
Mark Wielaard9202fe12015-05-19 13:39:39 +02002 Copyright (C) 2005-2011, 2014, 2015 Red Hat, Inc.
Mark Wielaardde2ed972012-06-05 17:15:16 +02003 This file is part of elfutils.
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00004
Mark Wielaardde2ed972012-06-05 17:15:16 +02005 This file is free software; you can redistribute it and/or modify
6 it under the terms of either
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00007
Mark Wielaardde2ed972012-06-05 17:15:16 +02008 * 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
Ulrich Drepper361df7d2006-04-04 21:38:57 +000021 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
Mark Wielaardde2ed972012-06-05 17:15:16 +020025 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/>. */
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000028
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
Mark Wielaardf15bcda2014-03-03 11:43:43 +010051 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. */
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000055
56Elf *
57elf_from_remote_memory (GElf_Addr ehdr_vma,
Mark Wielaardf15bcda2014-03-03 11:43:43 +010058 GElf_Xword pagesize,
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000059 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{
Mark Wielaard9202fe12015-05-19 13:39:39 +020066 /* We might have to reserve some memory for the phdrs. Set to NULL
67 here so we can always safely free it. */
68 void *phdrsp = NULL;
69
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000070 /* First read in the file header and check its sanity. */
71
72 const size_t initial_bufsize = 256;
73 unsigned char *buffer = malloc (initial_bufsize);
Mark Wielaard9202fe12015-05-19 13:39:39 +020074 if (unlikely (buffer == NULL))
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000075 {
76 no_memory:
77 __libdwfl_seterrno (DWFL_E_NOMEM);
78 return NULL;
79 }
80
81 ssize_t nread = (*read_memory) (arg, buffer, ehdr_vma,
82 sizeof (Elf32_Ehdr), initial_bufsize);
83 if (nread <= 0)
84 {
85 read_error:
86 free (buffer);
Mark Wielaard9202fe12015-05-19 13:39:39 +020087 free (phdrsp);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000088 __libdwfl_seterrno (nread < 0 ? DWFL_E_ERRNO : DWFL_E_TRUNCATED);
89 return NULL;
90 }
91
92 if (memcmp (buffer, ELFMAG, SELFMAG) != 0)
93 {
94 bad_elf:
Mark Wielaardf15bcda2014-03-03 11:43:43 +010095 free (buffer);
Mark Wielaard9202fe12015-05-19 13:39:39 +020096 free (phdrsp);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000097 __libdwfl_seterrno (DWFL_E_BADELF);
98 return NULL;
99 }
100
101 /* Extract the information we need from the file header. */
102
103 union
104 {
105 Elf32_Ehdr e32;
106 Elf64_Ehdr e64;
107 } ehdr;
108 Elf_Data xlatefrom =
109 {
110 .d_type = ELF_T_EHDR,
111 .d_buf = buffer,
112 .d_version = EV_CURRENT,
113 };
114 Elf_Data xlateto =
115 {
116 .d_type = ELF_T_EHDR,
117 .d_buf = &ehdr,
118 .d_size = sizeof ehdr,
119 .d_version = EV_CURRENT,
120 };
121
122 GElf_Off phoff;
123 uint_fast16_t phnum;
124 uint_fast16_t phentsize;
125 GElf_Off shdrs_end;
126
127 switch (buffer[EI_CLASS])
128 {
129 case ELFCLASS32:
130 xlatefrom.d_size = sizeof (Elf32_Ehdr);
131 if (elf32_xlatetom (&xlateto, &xlatefrom, buffer[EI_DATA]) == NULL)
132 {
133 libelf_error:
134 __libdwfl_seterrno (DWFL_E_LIBELF);
135 return NULL;
136 }
137 phoff = ehdr.e32.e_phoff;
138 phnum = ehdr.e32.e_phnum;
139 phentsize = ehdr.e32.e_phentsize;
140 if (phentsize != sizeof (Elf32_Phdr) || phnum == 0)
141 goto bad_elf;
Mark Wielaardeab0cf42018-08-04 22:36:48 +0200142 /* NOTE if the number of sections is > 0xff00 then e_shnum
143 is zero and the actual number would come from the section
144 zero sh_size field. We ignore this here because getting shdrs
145 is just a nice bonus (see below where we trim the last phdrs
146 PT_LOAD segment). */
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000147 shdrs_end = ehdr.e32.e_shoff + ehdr.e32.e_shnum * ehdr.e32.e_shentsize;
148 break;
149
150 case ELFCLASS64:
151 xlatefrom.d_size = sizeof (Elf64_Ehdr);
Ulrich Drepper6258e742007-03-13 06:22:40 +0000152 if (elf64_xlatetom (&xlateto, &xlatefrom, buffer[EI_DATA]) == NULL)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000153 goto libelf_error;
154 phoff = ehdr.e64.e_phoff;
155 phnum = ehdr.e64.e_phnum;
156 phentsize = ehdr.e64.e_phentsize;
157 if (phentsize != sizeof (Elf64_Phdr) || phnum == 0)
158 goto bad_elf;
Mark Wielaardeab0cf42018-08-04 22:36:48 +0200159 /* See the NOTE above for shdrs_end and ehdr.e32.e_shnum. */
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000160 shdrs_end = ehdr.e64.e_shoff + ehdr.e64.e_shnum * ehdr.e64.e_shentsize;
161 break;
162
163 default:
164 goto bad_elf;
165 }
166
167
168 /* The file header tells where to find the program headers.
169 These are what we use to actually choose what to read. */
170
171 xlatefrom.d_type = xlateto.d_type = ELF_T_PHDR;
172 xlatefrom.d_size = phnum * phentsize;
173
174 if ((size_t) nread >= phoff + phnum * phentsize)
175 /* We already have all the phdrs from the initial read. */
176 xlatefrom.d_buf = buffer + phoff;
177 else
178 {
179 /* Read in the program headers. */
180
Ulf Hermannd6655d92017-04-20 16:40:30 +0200181 if (initial_bufsize < (size_t)phnum * phentsize)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000182 {
183 unsigned char *newbuf = realloc (buffer, phnum * phentsize);
184 if (newbuf == NULL)
185 {
186 free (buffer);
Mark Wielaard9202fe12015-05-19 13:39:39 +0200187 free (phdrsp);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000188 goto no_memory;
189 }
190 buffer = newbuf;
191 }
192 nread = (*read_memory) (arg, buffer, ehdr_vma + phoff,
193 phnum * phentsize, phnum * phentsize);
194 if (nread <= 0)
195 goto read_error;
196
197 xlatefrom.d_buf = buffer;
198 }
199
Mark Wielaard86ed7f72015-10-08 00:16:03 +0200200 bool class32 = ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32;
201 size_t phdr_size = class32 ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr);
202 if (unlikely (phnum > SIZE_MAX / phdr_size))
Chih-Hung Hsieh7eff36d2015-10-06 15:53:15 -0700203 {
204 free (buffer);
205 goto no_memory;
206 }
Mark Wielaard86ed7f72015-10-08 00:16:03 +0200207 const size_t phdrsp_bytes = phnum * phdr_size;
Chih-Hung Hsieh7eff36d2015-10-06 15:53:15 -0700208 phdrsp = malloc (phdrsp_bytes);
Mark Wielaard9202fe12015-05-19 13:39:39 +0200209 if (unlikely (phdrsp == NULL))
210 {
211 free (buffer);
212 goto no_memory;
213 }
Mark Wielaard9202fe12015-05-19 13:39:39 +0200214
Chih-Hung Hsieh7eff36d2015-10-06 15:53:15 -0700215 xlateto.d_buf = phdrsp;
216 xlateto.d_size = phdrsp_bytes;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000217
218 /* Scan for PT_LOAD segments to find the total size of the file image. */
219 size_t contents_size = 0;
220 GElf_Off segments_end = 0;
Mark Wielaarddd64d4a2014-03-03 15:07:31 +0100221 GElf_Off segments_end_mem = 0;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000222 GElf_Addr loadbase = ehdr_vma;
Roland McGrath099dd522007-08-13 22:58:36 +0000223 bool found_base = false;
Mark Wielaard86ed7f72015-10-08 00:16:03 +0200224 Elf32_Phdr (*p32)[phnum] = phdrsp;
225 Elf64_Phdr (*p64)[phnum] = phdrsp;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000226 switch (ehdr.e32.e_ident[EI_CLASS])
227 {
Mark Wielaardf15bcda2014-03-03 11:43:43 +0100228 /* Sanity checks segments and calculates segment_end,
229 segments_end, segments_end_mem and loadbase (if not
230 found_base yet). Returns true if sanity checking failed,
231 false otherwise. */
232 inline bool handle_segment (GElf_Addr vaddr, GElf_Off offset,
Mark Wielaard32b6c6a2014-12-19 15:40:16 +0100233 GElf_Xword filesz, GElf_Xword memsz)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000234 {
Mark Wielaard32b6c6a2014-12-19 15:40:16 +0100235 /* Sanity check the segment load aligns with the pagesize. */
236 if (((vaddr - offset) & (pagesize - 1)) != 0)
Mark Wielaardf15bcda2014-03-03 11:43:43 +0100237 return true;
238
239 GElf_Off segment_end = ((offset + filesz + pagesize - 1)
240 & -pagesize);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000241
242 if (segment_end > (GElf_Off) contents_size)
243 contents_size = segment_end;
244
Mark Wielaardf15bcda2014-03-03 11:43:43 +0100245 if (!found_base && (offset & -pagesize) == 0)
Roland McGrath099dd522007-08-13 22:58:36 +0000246 {
Mark Wielaardf15bcda2014-03-03 11:43:43 +0100247 loadbase = ehdr_vma - (vaddr & -pagesize);
Roland McGrath099dd522007-08-13 22:58:36 +0000248 found_base = true;
249 }
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000250
251 segments_end = offset + filesz;
Mark Wielaarddd64d4a2014-03-03 15:07:31 +0100252 segments_end_mem = offset + memsz;
Mark Wielaardf15bcda2014-03-03 11:43:43 +0100253 return false;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000254 }
255
256 case ELFCLASS32:
257 if (elf32_xlatetom (&xlateto, &xlatefrom,
258 ehdr.e32.e_ident[EI_DATA]) == NULL)
259 goto libelf_error;
260 for (uint_fast16_t i = 0; i < phnum; ++i)
Chih-Hung Hsieh7eff36d2015-10-06 15:53:15 -0700261 if ((*p32)[i].p_type == PT_LOAD)
262 if (handle_segment ((*p32)[i].p_vaddr, (*p32)[i].p_offset,
263 (*p32)[i].p_filesz, (*p32)[i].p_memsz))
Mark Wielaardf15bcda2014-03-03 11:43:43 +0100264 goto bad_elf;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000265 break;
266
267 case ELFCLASS64:
Roland McGrath01fef9d2011-12-02 09:45:53 -0800268 if (elf64_xlatetom (&xlateto, &xlatefrom,
269 ehdr.e64.e_ident[EI_DATA]) == NULL)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000270 goto libelf_error;
271 for (uint_fast16_t i = 0; i < phnum; ++i)
Chih-Hung Hsieh7eff36d2015-10-06 15:53:15 -0700272 if ((*p64)[i].p_type == PT_LOAD)
273 if (handle_segment ((*p64)[i].p_vaddr, (*p64)[i].p_offset,
274 (*p64)[i].p_filesz, (*p64)[i].p_memsz))
Mark Wielaardf15bcda2014-03-03 11:43:43 +0100275 goto bad_elf;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000276 break;
277
278 default:
279 abort ();
280 break;
281 }
282
283 /* Trim the last segment so we don't bother with zeros in the last page
284 that are off the end of the file. However, if the extra bit in that
Mark Wielaarddd64d4a2014-03-03 15:07:31 +0100285 page includes the section headers and the memory isn't extended (which
286 might indicate it will have been reused otherwise), keep them. */
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000287 if ((GElf_Off) contents_size > segments_end
Mark Wielaarddd64d4a2014-03-03 15:07:31 +0100288 && (GElf_Off) contents_size >= shdrs_end
289 && segments_end == segments_end_mem)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000290 {
291 contents_size = segments_end;
292 if ((GElf_Off) contents_size < shdrs_end)
293 contents_size = shdrs_end;
294 }
295 else
296 contents_size = segments_end;
297
298 free (buffer);
299
300 /* Now we know the size of the whole image we want read in. */
301 buffer = calloc (1, contents_size);
302 if (buffer == NULL)
Mark Wielaard9202fe12015-05-19 13:39:39 +0200303 {
304 free (phdrsp);
305 goto no_memory;
306 }
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000307
308 switch (ehdr.e32.e_ident[EI_CLASS])
309 {
Mark Wielaardf15bcda2014-03-03 11:43:43 +0100310 /* Reads the given segment. Returns true if reading fails,
311 false otherwise. */
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000312 inline bool handle_segment (GElf_Addr vaddr, GElf_Off offset,
Mark Wielaardf15bcda2014-03-03 11:43:43 +0100313 GElf_Xword filesz)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000314 {
Mark Wielaardf15bcda2014-03-03 11:43:43 +0100315 GElf_Off start = offset & -pagesize;
316 GElf_Off end = (offset + filesz + pagesize - 1) & -pagesize;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000317 if (end > (GElf_Off) contents_size)
318 end = contents_size;
319 nread = (*read_memory) (arg, buffer + start,
Mark Wielaardf15bcda2014-03-03 11:43:43 +0100320 (loadbase + vaddr) & -pagesize,
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000321 end - start, end - start);
322 return nread <= 0;
323 }
324
325 case ELFCLASS32:
326 for (uint_fast16_t i = 0; i < phnum; ++i)
Chih-Hung Hsieh7eff36d2015-10-06 15:53:15 -0700327 if ((*p32)[i].p_type == PT_LOAD)
328 if (handle_segment ((*p32)[i].p_vaddr, (*p32)[i].p_offset,
329 (*p32)[i].p_filesz))
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000330 goto read_error;
331
332 /* If the segments visible in memory didn't include the section
333 headers, then clear them from the file header. */
334 if (contents_size < shdrs_end)
335 {
336 ehdr.e32.e_shoff = 0;
337 ehdr.e32.e_shnum = 0;
338 ehdr.e32.e_shstrndx = 0;
339 }
340
341 /* This will normally have been in the first PT_LOAD segment. But it
342 conceivably could be missing, and we might have just changed it. */
343 xlatefrom.d_type = xlateto.d_type = ELF_T_EHDR;
344 xlatefrom.d_size = xlateto.d_size = sizeof ehdr.e32;
345 xlatefrom.d_buf = &ehdr.e32;
346 xlateto.d_buf = buffer;
347 if (elf32_xlatetof (&xlateto, &xlatefrom,
348 ehdr.e32.e_ident[EI_DATA]) == NULL)
349 goto libelf_error;
350 break;
351
352 case ELFCLASS64:
353 for (uint_fast16_t i = 0; i < phnum; ++i)
Chih-Hung Hsieh7eff36d2015-10-06 15:53:15 -0700354 if ((*p64)[i].p_type == PT_LOAD)
355 if (handle_segment ((*p64)[i].p_vaddr, (*p64)[i].p_offset,
356 (*p64)[i].p_filesz))
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000357 goto read_error;
358
359 /* If the segments visible in memory didn't include the section
360 headers, then clear them from the file header. */
361 if (contents_size < shdrs_end)
362 {
363 ehdr.e64.e_shoff = 0;
364 ehdr.e64.e_shnum = 0;
365 ehdr.e64.e_shstrndx = 0;
366 }
367
368 /* This will normally have been in the first PT_LOAD segment. But it
369 conceivably could be missing, and we might have just changed it. */
370 xlatefrom.d_type = xlateto.d_type = ELF_T_EHDR;
371 xlatefrom.d_size = xlateto.d_size = sizeof ehdr.e64;
372 xlatefrom.d_buf = &ehdr.e64;
373 xlateto.d_buf = buffer;
Ulrich Drepperd5a75192006-06-15 03:07:46 +0000374 if (elf64_xlatetof (&xlateto, &xlatefrom,
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000375 ehdr.e64.e_ident[EI_DATA]) == NULL)
376 goto libelf_error;
377 break;
378
379 default:
380 abort ();
381 break;
382 }
383
Mark Wielaard9202fe12015-05-19 13:39:39 +0200384 free (phdrsp);
Chih-Hung Hsieh7eff36d2015-10-06 15:53:15 -0700385 phdrsp = NULL;
Mark Wielaard9202fe12015-05-19 13:39:39 +0200386
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000387 /* Now we have the image. Open libelf on it. */
388
389 Elf *elf = elf_memory ((char *) buffer, contents_size);
390 if (elf == NULL)
391 {
392 free (buffer);
Ulrich Drepperd5a75192006-06-15 03:07:46 +0000393 goto libelf_error;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000394 }
395
396 elf->flags |= ELF_F_MALLOCED;
397 if (loadbasep != NULL)
398 *loadbasep = loadbase;
399 return elf;
400}