1
2 /*--------------------------------------------------------------------*/
3 /*--- User-mode execve() for ELF executables m_ume_elf.c ---*/
4 /*--------------------------------------------------------------------*/
5
6 /*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
10 Copyright (C) 2000-2011 Julian Seward
11 jseward@acm.org
12
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29 */
30
31 #if defined(VGO_linux)
32
33 #include "pub_core_basics.h"
34 #include "pub_core_vki.h"
35
36 #include "pub_core_aspacemgr.h" // various mapping fns
37 #include "pub_core_debuglog.h"
38 #include "pub_core_libcassert.h" // VG_(exit), vg_assert
39 #include "pub_core_libcbase.h" // VG_(memcmp), etc
40 #include "pub_core_libcprint.h"
41 #include "pub_core_libcfile.h" // VG_(open) et al
42 #include "pub_core_machine.h" // VG_ELF_CLASS (XXX: which should be moved)
43 #include "pub_core_mallocfree.h" // VG_(malloc), VG_(free)
44 #include "pub_core_syscall.h" // VG_(strerror)
45 #include "pub_core_ume.h" // self
46 #include "pub_tool_libcproc.h" // VG_(getenv)
47
48 #include "priv_ume.h"
49
50 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
51 #define _GNU_SOURCE
52 #define _FILE_OFFSET_BITS 64
53 /* This is for ELF types etc, and also the AT_ constants. */
54 #include <elf.h>
55 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
56
57
58 #if VG_WORDSIZE == 8
59 #define ESZ(x) Elf64_##x
60 #elif VG_WORDSIZE == 4
61 #define ESZ(x) Elf32_##x
62 #else
63 #error VG_WORDSIZE needs to ==4 or ==8
64 #endif
65
66 struct elfinfo
67 {
68 ESZ(Ehdr) e;
69 ESZ(Phdr) *p;
70 Int fd;
71 };
72
check_mmap(SysRes res,Addr base,SizeT len)73 static void check_mmap(SysRes res, Addr base, SizeT len)
74 {
75 if (sr_isError(res)) {
76 VG_(printf)("valgrind: mmap(0x%llx, %lld) failed in UME "
77 "with error %lu (%s).\n",
78 (ULong)base, (Long)len,
79 sr_Err(res), VG_(strerror)(sr_Err(res)) );
80 if (sr_Err(res) == VKI_EINVAL) {
81 VG_(printf)("valgrind: this can be caused by executables with "
82 "very large text, data or bss segments.\n");
83 }
84 VG_(exit)(1);
85 }
86 }
87
88 /*------------------------------------------------------------*/
89 /*--- Loading ELF files ---*/
90 /*------------------------------------------------------------*/
91
92 static
readelf(Int fd,const char * filename)93 struct elfinfo *readelf(Int fd, const char *filename)
94 {
95 SysRes sres;
96 struct elfinfo *e = VG_(malloc)("ume.re.1", sizeof(*e));
97 Int phsz;
98
99 vg_assert(e);
100 e->fd = fd;
101
102 sres = VG_(pread)(fd, &e->e, sizeof(e->e), 0);
103 if (sr_isError(sres) || sr_Res(sres) != sizeof(e->e)) {
104 VG_(printf)("valgrind: %s: can't read ELF header: %s\n",
105 filename, VG_(strerror)(sr_Err(sres)));
106 goto bad;
107 }
108
109 if (VG_(memcmp)(&e->e.e_ident[0], ELFMAG, SELFMAG) != 0) {
110 VG_(printf)("valgrind: %s: bad ELF magic number\n", filename);
111 goto bad;
112 }
113 if (e->e.e_ident[EI_CLASS] != VG_ELF_CLASS) {
114 VG_(printf)("valgrind: wrong ELF executable class "
115 "(eg. 32-bit instead of 64-bit)\n");
116 goto bad;
117 }
118 if (e->e.e_ident[EI_DATA] != VG_ELF_DATA2XXX) {
119 VG_(printf)("valgrind: executable has wrong endian-ness\n");
120 goto bad;
121 }
122 if (!(e->e.e_type == ET_EXEC || e->e.e_type == ET_DYN)) {
123 VG_(printf)("valgrind: this is not an executable\n");
124 goto bad;
125 }
126
127 if (e->e.e_machine != VG_ELF_MACHINE) {
128 VG_(printf)("valgrind: executable is not for "
129 "this architecture\n");
130 goto bad;
131 }
132
133 if (e->e.e_phentsize != sizeof(ESZ(Phdr))) {
134 VG_(printf)("valgrind: sizeof ELF Phdr wrong\n");
135 goto bad;
136 }
137
138 phsz = sizeof(ESZ(Phdr)) * e->e.e_phnum;
139 e->p = VG_(malloc)("ume.re.2", phsz);
140 vg_assert(e->p);
141
142 sres = VG_(pread)(fd, e->p, phsz, e->e.e_phoff);
143 if (sr_isError(sres) || sr_Res(sres) != phsz) {
144 VG_(printf)("valgrind: can't read phdr: %s\n",
145 VG_(strerror)(sr_Err(sres)));
146 VG_(free)(e->p);
147 goto bad;
148 }
149
150 return e;
151
152 bad:
153 VG_(free)(e);
154 return NULL;
155 }
156
157 /* Map an ELF file. Returns the brk address. */
158 static
mapelf(struct elfinfo * e,ESZ (Addr)base)159 ESZ(Addr) mapelf(struct elfinfo *e, ESZ(Addr) base)
160 {
161 Int i;
162 SysRes res;
163 ESZ(Addr) elfbrk = 0;
164
165 for (i = 0; i < e->e.e_phnum; i++) {
166 ESZ(Phdr) *ph = &e->p[i];
167 ESZ(Addr) addr, brkaddr;
168 ESZ(Word) memsz;
169
170 if (ph->p_type != PT_LOAD)
171 continue;
172
173 addr = ph->p_vaddr+base;
174 memsz = ph->p_memsz;
175 brkaddr = addr+memsz;
176
177 if (brkaddr > elfbrk)
178 elfbrk = brkaddr;
179 }
180
181 for (i = 0; i < e->e.e_phnum; i++) {
182 ESZ(Phdr) *ph = &e->p[i];
183 ESZ(Addr) addr, bss, brkaddr;
184 ESZ(Off) off;
185 ESZ(Word) filesz;
186 ESZ(Word) memsz;
187 unsigned prot = 0;
188
189 if (ph->p_type != PT_LOAD)
190 continue;
191
192 if (ph->p_flags & PF_X) prot |= VKI_PROT_EXEC;
193 if (ph->p_flags & PF_W) prot |= VKI_PROT_WRITE;
194 if (ph->p_flags & PF_R) prot |= VKI_PROT_READ;
195
196 addr = ph->p_vaddr+base;
197 off = ph->p_offset;
198 filesz = ph->p_filesz;
199 bss = addr+filesz;
200 memsz = ph->p_memsz;
201 brkaddr = addr+memsz;
202
203 // Tom says: In the following, do what the Linux kernel does and only
204 // map the pages that are required instead of rounding everything to
205 // the specified alignment (ph->p_align). (AMD64 doesn't work if you
206 // use ph->p_align -- part of stage2's memory gets trashed somehow.)
207 //
208 // The condition handles the case of a zero-length segment.
209 if (VG_PGROUNDUP(bss)-VG_PGROUNDDN(addr) > 0) {
210 if (0) VG_(debugLog)(0,"ume","mmap_file_fixed_client #1\n");
211 res = VG_(am_mmap_file_fixed_client)(
212 VG_PGROUNDDN(addr),
213 VG_PGROUNDUP(bss)-VG_PGROUNDDN(addr),
214 prot, /*VKI_MAP_FIXED|VKI_MAP_PRIVATE, */
215 e->fd, VG_PGROUNDDN(off)
216 );
217 if (0) VG_(am_show_nsegments)(0,"after #1");
218 check_mmap(res, VG_PGROUNDDN(addr),
219 VG_PGROUNDUP(bss)-VG_PGROUNDDN(addr));
220 }
221
222 // if memsz > filesz, fill the remainder with zeroed pages
223 if (memsz > filesz) {
224 UInt bytes;
225
226 bytes = VG_PGROUNDUP(brkaddr)-VG_PGROUNDUP(bss);
227 if (bytes > 0) {
228 if (0) VG_(debugLog)(0,"ume","mmap_anon_fixed_client #2\n");
229 res = VG_(am_mmap_anon_fixed_client)(
230 VG_PGROUNDUP(bss), bytes,
231 prot
232 );
233 if (0) VG_(am_show_nsegments)(0,"after #2");
234 check_mmap(res, VG_PGROUNDUP(bss), bytes);
235 }
236
237 bytes = bss & (VKI_PAGE_SIZE - 1);
238
239 // The 'prot' condition allows for a read-only bss
240 if ((prot & VKI_PROT_WRITE) && (bytes > 0)) {
241 bytes = VKI_PAGE_SIZE - bytes;
242 VG_(memset)((char *)bss, 0, bytes);
243 }
244 }
245 }
246
247 return elfbrk;
248 }
249
VG_(match_ELF)250 Bool VG_(match_ELF)(Char *hdr, Int len)
251 {
252 ESZ(Ehdr) *e = (ESZ(Ehdr) *)hdr;
253 return (len > sizeof(*e)) && VG_(memcmp)(&e->e_ident[0], ELFMAG, SELFMAG) == 0;
254 }
255
256
257 /* load_ELF pulls an ELF executable into the address space, prepares
258 it for execution, and writes info about it into INFO. In
259 particular it fills in .init_eip, which is the starting point.
260
261 Returns zero on success, non-zero (a VKI_E.. value) on failure.
262
263 The sequence of activities is roughly as follows:
264
265 - use readelf() to extract program header info from the exe file.
266
267 - scan the program header, collecting info (not sure what all those
268 info-> fields are, or whether they are used, but still) and in
269 particular looking out fo the PT_INTERP header, which describes
270 the interpreter. If such a field is found, the space needed to
271 hold the interpreter is computed into interp_size.
272
273 - map the executable in, by calling mapelf(). This maps in all
274 loadable sections, and I _think_ also creates any .bss areas
275 required. mapelf() returns the address just beyond the end of
276 the furthest-along mapping it creates. The executable is mapped
277 starting at EBASE, which is usually read from it (eg, 0x8048000
278 etc) except if it's a PIE, in which case I'm not sure what
279 happens.
280
281 The returned address is recorded in info->brkbase as the start
282 point of the brk (data) segment, as it is traditional to place
283 the data segment just after the executable. Neither load_ELF nor
284 mapelf creates the brk segment, though: that is for the caller of
285 load_ELF to attend to.
286
287 - If the initial phdr scan didn't find any mention of an
288 interpreter (interp == NULL), this must be a statically linked
289 executable, and we're pretty much done.
290
291 - Otherwise, we need to use mapelf() a second time to load the
292 interpreter. The interpreter can go anywhere, but mapelf() wants
293 to be told a specific address to put it at. So an advisory query
294 is passed to aspacem, asking where it would put an anonymous
295 client mapping of size INTERP_SIZE. That address is then used
296 as the mapping address for the interpreter.
297
298 - The entry point in INFO is set to the interpreter's entry point,
299 and we're done. */
VG_(load_ELF)300 Int VG_(load_ELF)(Int fd, const HChar* name, /*MOD*/ExeInfo* info)
301 {
302 SysRes sres;
303 struct elfinfo *e;
304 struct elfinfo *interp = NULL;
305 ESZ(Addr) minaddr = ~0; /* lowest mapped address */
306 ESZ(Addr) maxaddr = 0; /* highest mapped address */
307 ESZ(Addr) interp_addr = 0; /* interpreter (ld.so) address */
308 ESZ(Word) interp_size = 0; /* interpreter size */
309 /* ESZ(Word) interp_align = VKI_PAGE_SIZE; */ /* UNUSED */
310 Int i;
311 void *entry;
312 ESZ(Addr) ebase = 0;
313
314 /* The difference between where the interpreter got mapped and
315 where it asked to be mapped. Needed for computing the ppc64 ELF
316 entry point and initial tocptr (R2) value. */
317 ESZ(Word) interp_offset = 0;
318
319 #ifdef HAVE_PIE
320 ebase = info->exe_base;
321 #endif
322
323 e = readelf(fd, name);
324
325 if (e == NULL)
326 return VKI_ENOEXEC;
327
328 /* The kernel maps position-independent executables at TASK_SIZE*2/3;
329 duplicate this behavior as close as we can. */
330 if (e->e.e_type == ET_DYN && ebase == 0) {
331 ebase = VG_PGROUNDDN(info->exe_base
332 + (info->exe_end - info->exe_base) * 2 / 3);
333 /* We really don't want to load PIEs at zero or too close. It
334 works, but it's unrobust (NULL pointer reads and writes
335 become legit, which is really bad) and causes problems for
336 exp-ptrcheck, which assumes all numbers below 1MB are
337 nonpointers. So, hackily, move it above 1MB. */
338 /* Later .. is appears ppc32-linux tries to put [vdso] at 1MB,
339 which totally screws things up, because nothing else can go
340 there. So bump the hacky load addess along by 0x8000, to
341 0x108000. */
342 if (ebase < 0x108000)
343 ebase = 0x108000;
344 }
345
346 info->phnum = e->e.e_phnum;
347 info->entry = e->e.e_entry + ebase;
348 info->phdr = 0;
349
350 for (i = 0; i < e->e.e_phnum; i++) {
351 ESZ(Phdr) *ph = &e->p[i];
352
353 switch(ph->p_type) {
354 case PT_PHDR:
355 info->phdr = ph->p_vaddr + ebase;
356 break;
357
358 case PT_LOAD:
359 if (ph->p_vaddr < minaddr)
360 minaddr = ph->p_vaddr;
361 if (ph->p_vaddr+ph->p_memsz > maxaddr)
362 maxaddr = ph->p_vaddr+ph->p_memsz;
363 break;
364
365 case PT_INTERP: {
366 HChar *buf = VG_(malloc)("ume.LE.1", ph->p_filesz+1);
367 Int j;
368 Int intfd;
369 Int baseaddr_set;
370
371 vg_assert(buf);
372 VG_(pread)(fd, buf, ph->p_filesz, ph->p_offset);
373 buf[ph->p_filesz] = '\0';
374
375 sres = VG_(open)(buf, VKI_O_RDONLY, 0);
376 if (sr_isError(sres)) {
377 VG_(printf)("valgrind: m_ume.c: can't open interpreter\n");
378 VG_(exit)(1);
379 }
380 intfd = sr_Res(sres);
381
382 interp = readelf(intfd, buf);
383 if (interp == NULL) {
384 VG_(printf)("valgrind: m_ume.c: can't read interpreter\n");
385 return 1;
386 }
387 VG_(free)(buf);
388
389 baseaddr_set = 0;
390 for (j = 0; j < interp->e.e_phnum; j++) {
391 ESZ(Phdr) *iph = &interp->p[j];
392 ESZ(Addr) end;
393
394 if (iph->p_type != PT_LOAD || iph->p_memsz == 0)
395 continue;
396
397 #ifdef ANDROID
398 // On older versions of Android, the first LOAD segment of
399 // /system/bin/linker has vaddr=0, memsz=0, but subsequent
400 // segments start at 0xb0001000.
401 //
402 // On newer versions of Android, the linker is ET_DYN and
403 // we don't have to worry about iph->p_vaddr
404 if (!baseaddr_set
405 && (iph->p_vaddr || (interp->e.e_type == ET_DYN))) {
406 #else
407 if (!baseaddr_set) {
408 #endif
409 interp_addr = iph->p_vaddr;
410 /* interp_align = iph->p_align; */ /* UNUSED */
411 baseaddr_set = 1;
412 }
413
414 /* assumes that all segments in the interp are close */
415 end = (iph->p_vaddr - interp_addr) + iph->p_memsz;
416
417 if (end > interp_size)
418 interp_size = end;
419 }
420 break;
421
422 default:
423 // do nothing
424 break;
425 }
426 }
427 }
428
429 if (info->phdr == 0)
430 info->phdr = minaddr + ebase + e->e.e_phoff;
431
432 if (info->exe_base != info->exe_end) {
433 if (minaddr >= maxaddr ||
434 (minaddr + ebase < info->exe_base ||
435 maxaddr + ebase > info->exe_end)) {
436 VG_(printf)("Executable range %p-%p is outside the\n"
437 "acceptable range %p-%p\n",
438 (char *)minaddr + ebase, (char *)maxaddr + ebase,
439 (char *)info->exe_base, (char *)info->exe_end);
440 return VKI_ENOMEM;
441 }
442 }
443
444 info->brkbase = mapelf(e, ebase); /* map the executable */
445
446 if (info->brkbase == 0)
447 return VKI_ENOMEM;
448
449 if (interp != NULL) {
450 /* reserve a chunk of address space for interpreter */
451 MapRequest mreq;
452 Addr advised;
453 Bool ok;
454
455 /* Don't actually reserve the space. Just get an advisory
456 indicating where it would be allocated, and pass that to
457 mapelf(), which in turn asks aspacem to do some fixed maps at
458 the specified address. This is a bit of hack, but it should
459 work because there should be no intervening transactions with
460 aspacem which could cause those fixed maps to fail.
461
462 Placement policy is:
463
464 if the interpreter asks to be loaded at zero
465 ignore that and put it wherever we like (mappings at zero
466 are bad news)
467 else
468 try and put it where it asks for, but if that doesn't work,
469 just put it anywhere.
470 */
471 if (interp_addr == 0) {
472 mreq.rkind = MAny;
473 mreq.start = 0;
474 mreq.len = interp_size;
475 } else {
476 mreq.rkind = MHint;
477 mreq.start = interp_addr;
478 mreq.len = interp_size;
479 }
480
481 advised = VG_(am_get_advisory)( &mreq, True/*client*/, &ok );
482
483 if (!ok) {
484 /* bomb out */
485 SysRes res = VG_(mk_SysRes_Error)(VKI_EINVAL);
486 if (0) VG_(printf)("reserve for interp: failed\n");
487 check_mmap(res, (Addr)interp_addr, interp_size);
488 /*NOTREACHED*/
489 }
490
491 (void)mapelf(interp, (ESZ(Addr))advised - interp_addr);
492
493 VG_(close)(interp->fd);
494
495 entry = (void *)(advised - interp_addr + interp->e.e_entry);
496 info->interp_base = (ESZ(Addr))advised;
497 interp_offset = advised - interp_addr;
498
499 VG_(free)(interp->p);
500 VG_(free)(interp);
501 } else {
502 Char *exit_if_static = VG_(getenv)("VALGRIND_EXIT_IF_STATIC");
503 if (exit_if_static && VG_(strcmp)(exit_if_static, "0") != 0) {
504 VG_(printf)("******* You are running Valgrind on a static binary: %s\n",
505 name);
506 VG_(printf)("******* This is not supported, exiting\n");
507 VG_(exit)(1);
508 }
509 entry = (void *)(ebase + e->e.e_entry);
510 }
511
512 info->exe_base = minaddr + ebase;
513 info->exe_end = maxaddr + ebase;
514
515 #if defined(VGP_ppc64_linux)
516 /* On PPC64, a func ptr is represented by a TOC entry ptr. This
517 TOC entry contains three words; the first word is the function
518 address, the second word is the TOC ptr (r2), and the third word
519 is the static chain value. */
520 info->init_ip = ((ULong*)entry)[0];
521 info->init_toc = ((ULong*)entry)[1];
522 info->init_ip += interp_offset;
523 info->init_toc += interp_offset;
524 #else
525 info->init_ip = (Addr)entry;
526 info->init_toc = 0; /* meaningless on this platform */
527 (void) interp_offset; /* stop gcc complaining it is unused */
528 #endif
529 VG_(free)(e->p);
530 VG_(free)(e);
531
532 return 0;
533 }
534
535 #endif // defined(VGO_linux)
536
537 /*--------------------------------------------------------------------*/
538 /*--- end ---*/
539 /*--------------------------------------------------------------------*/
540