aboutsummaryrefslogtreecommitdiffstats
path: root/exec/exec.c
diff options
context:
space:
mode:
authorPo Lu2023-04-30 21:37:19 +0800
committerPo Lu2023-04-30 21:37:19 +0800
commit368f6f3942a1f8b9483763a6ac24b3b3021e92bf (patch)
tree284ff92e18076ed7a8be3d2775ee450922b3166d /exec/exec.c
parent4289ed6cffdb5ea758a78037fe385fd7c4e23677 (diff)
downloademacs-368f6f3942a1f8b9483763a6ac24b3b3021e92bf.tar.gz
emacs-368f6f3942a1f8b9483763a6ac24b3b3021e92bf.zip
Add helper binary `exec1'
* .gitignore: New files. * Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile exists. * autogen.sh (do_git): Autoreconf in exec as well. * configure.ac: Configure libexec on Android. * exec/Makefile.in: * exec/README: * exec/config-mips.m4.in: * exec/config.guess: * exec/config.h.in: * exec/config.sub: * exec/configure: * exec/configure.ac: * exec/deps.mk: * exec/exec.c (MIN, struct exec_open_command) (struct exec_map_command, struct exec_jump_command) (write_open_command, write_load_command, process_interpreter_1) (process_interpreter, process_program_header, insert_args) (exec_0): * exec/exec.h (_EXEC_H_, struct elf_header_32) (struct program_header_32, struct dt_entry_32) (struct elf_header_64, struct program_header_64) (struct dt_entry_64, struct exec_tracee): * exec/exec1.c (main): * exec/install-sh (scriptversion): * exec/loader-aarch64.s (_start): * exec/loader-armeabi.s (_start): * exec/loader-mips64el.s (__start): * exec/loader-mipsel.s (__start): * exec/loader-x86.s (_start): * exec/loader-x86_64.s (_start): * exec/mipsel-user.h (_MIPSEL_USER_H_): * exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p) (fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode): * exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0): * exec/test.c (print_usage, main): * exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory) (user_alloca, user_copy, remove_tracee, handle_clone) (syscall_trap_p, handle_exec, process_system_call, tracing_execve) (after_fork, find_tracee, exec_waitpid, exec_init): New files. * java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and loader. ($(CROSS_EXEC_BINS) &): New target.
Diffstat (limited to 'exec/exec.c')
-rw-r--r--exec/exec.c1016
1 files changed, 1016 insertions, 0 deletions
diff --git a/exec/exec.c b/exec/exec.c
new file mode 100644
index 00000000000..e890179a9ab
--- /dev/null
+++ b/exec/exec.c
@@ -0,0 +1,1016 @@
1/* Program execution for Emacs.
2
3Copyright (C) 2023 Free Software Foundation, Inc.
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 3 of the License, or (at
10your option) any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
19
20#include <config.h>
21
22#include <errno.h>
23#include <unistd.h>
24#include <string.h>
25#include <fcntl.h>
26#include <assert.h>
27#include <string.h>
28#include <ctype.h>
29
30#include <sys/ptrace.h>
31#include <sys/param.h>
32#include <sys/mman.h>
33
34#ifndef MIN
35#define MIN(a, b) ((a) < (b) ? (a) : (b))
36#endif /* MIN */
37
38#ifndef MAX
39#define MAX(a, b) ((a) < (b) ? (b) : (a))
40#endif /* MAX */
41
42#include "exec.h"
43
44#if defined __mips__ && !defined MIPS_NABI
45#include "mipsfpu.h"
46#endif /* defined __mips__ && !defined MIPS_NABI */
47
48
49
50/* Executable reading functions.
51 These functions extract information from an executable that is
52 about to be loaded.
53
54 `exec_0' takes the name of the program, determines whether or not
55 its format is correct, and if so, returns the list of actions that
56 the loader should perform.
57
58 The actions include:
59
60 - Making the stack executable, if PT_GNU_STACK.
61 - Mapping PT_LOAD sections into the executable with the correct
62 memory protection.
63 - On MIPS, setting the floating point register size.
64 - Transferring control to the interpreter or executable. */
65
66
67/* Check whether or not FD starts with a #!, and return the executable
68 to load if it does. Value is NAME if no interpreter character was
69 found, or the interpreter otherwise. Value is NULL upon an IO
70 error.
71
72 If an additional command line argument is specified, place it in
73 *EXTRA. */
74
75static const char *
76check_interpreter (const char *name, int fd, const char **extra)
77{
78 static char buffer[PATH_MAX], *start;
79 char first[2], *end, *ws;
80 ssize_t rc;
81
82 /* Read the first character. */
83 rc = read (fd, &first, 2);
84
85 if (rc != 2)
86 goto fail;
87
88 if (first[0] != '#' || first[1] != '!')
89 goto nomatch;
90
91 rc = read (fd, buffer, PATH_MAX);
92
93 if (rc < 0)
94 goto fail;
95
96 /* Strip leading whitespace. */
97 start = buffer;
98 while (*start && *start < 128 && isspace (*start))
99 ++start;
100
101 /* Look for a newline character. */
102 end = memchr (start, '\n', rc);
103
104 if (!end)
105 goto fail;
106
107 /* The string containing the interpreter is now in start. NULL
108 terminate it. */
109 *end = '\0';
110
111 /* Now look for any whitespace characters. */
112 ws = strchr (start, ' ');
113
114 /* If there's no whitespace, return the entire start. */
115
116 if (!ws)
117 {
118 if (lseek (fd, 0, SEEK_SET))
119 goto fail;
120
121 return start;
122 }
123
124 /* Otherwise, split the string at the whitespace and return the
125 additional argument. */
126 *ws = '\0';
127
128 if (lseek (fd, 0, SEEK_SET))
129 goto fail;
130
131 *extra = ws + 1;
132 return start;
133
134 nomatch:
135 /* There's no interpreter. */
136 if (lseek (fd, 0, SEEK_SET))
137 goto fail;
138
139 return name;
140
141 fail:
142 errno = ENOEXEC;
143 return NULL;
144}
145
146/* Static area used to store data placed on the loader's stack. */
147static char loader_area[65536];
148
149/* Number of bytes used in that area. */
150static int loader_area_used;
151
152
153
154/* Structure definitions for commands placed in the loader area.
155 Arrange these so that each member is naturally aligned. */
156
157struct exec_open_command
158{
159 /* Word identifying the type of this command. */
160 USER_WORD command;
161
162 /* NULL-terminated file name follows, padded to the size of a user
163 word. */
164};
165
166struct exec_map_command
167{
168 /* Word identifying the type of this command. */
169 USER_WORD command;
170
171 /* Where the file will be mapped. */
172 USER_WORD vm_address;
173
174 /* Offset into the file to map from. */
175 USER_WORD file_offset;
176
177 /* Memory protection for mprotect. */
178 USER_WORD protection;
179
180 /* Number of bytes to be mapped. */
181 USER_WORD length;
182
183 /* Flags for mmap. */
184 USER_WORD flags;
185
186 /* Number of bytes to clear at the end of this mapping. */
187 USER_WORD clear;
188};
189
190struct exec_jump_command
191{
192 /* Word identifying the type of this command. */
193 USER_WORD command;
194
195 /* Address to jump to. */
196 USER_WORD entry;
197
198 /* The value of AT_ENTRY inside the aux vector. */
199 USER_WORD at_entry;
200
201 /* The value of AT_PHENT inside the aux vector. */
202 USER_WORD at_phent;
203
204 /* The value of AT_PHNUM inside the aux vector. */
205 USER_WORD at_phnum;
206
207 /* The value of AT_PHDR inside the aux vector. */
208 USER_WORD at_phdr;
209
210 /* The value of AT_BASE inside the aux vector. */
211 USER_WORD at_base;
212
213#if defined __mips__ && !defined MIPS_NABI
214 /* The FPU mode to apply. */
215 USER_WORD fpu_mode;
216#endif /* defined __mips__ && !defined MIPS_NABI */
217};
218
219
220
221/* Write a command to open the file NAME to the loader area.
222 If ALTERNATE is true, then use the command code 16 instead
223 of 0. Value is 1 upon failure, else 0. */
224
225static int
226write_open_command (const char *name, bool alternate)
227{
228 struct exec_open_command command;
229 size_t size;
230
231 /* First, write the command to open NAME. This is followed by NAME
232 itself, padded to sizeof (USER_WORD) bytes. */
233
234 command.command = alternate ? 16 : 0;
235 if (sizeof loader_area - loader_area_used < sizeof command)
236 return 1;
237 memcpy (loader_area + loader_area_used, &command, sizeof command);
238 loader_area_used += sizeof command;
239
240 /* Calculate the length of NAME. */
241 size = strlen (name) + 1;
242
243 /* Round it up. */
244 size = ((size + (sizeof (USER_WORD) - 1))
245 & ~(sizeof (USER_WORD) - 1));
246
247 if (sizeof loader_area - loader_area_used < size)
248 return 1;
249
250 /* Now copy name to the loader area, filling the padding with NULL
251 bytes. */
252 strncpy (loader_area + loader_area_used, name, size);
253
254 /* Increase loader_area_used. */
255 loader_area_used += size;
256 return 0;
257}
258
259/* Write the commands necessary to map the executable file into memory
260 for the given PT_LOAD program HEADER. Value is 1 upon failure,
261 else 0. If USE_ALTERNATE, use the command code 17 instead of
262 1.
263
264 Apply the given OFFSET to virtual addresses that will be mapped. */
265
266static int
267write_load_command (program_header *header, bool use_alternate,
268 USER_WORD offset)
269{
270 struct exec_map_command command;
271 struct exec_map_command command1;
272 USER_WORD start, end;
273 bool need_command1;
274 static long pagesize;
275
276 /* First, write the commands necessary to map the specified segment
277 itself.
278
279 This is the area between header->p_vaddr and header->p_filesz,
280 rounded up to the page size. */
281
282#ifndef PAGE_MASK
283 /* This system doesn't define a fixed page size. */
284
285#ifdef HAVE_GETPAGESIZE
286 if (!pagesize)
287 pagesize = getpagesize ();
288#else /* HAVE_GETPAGESIZE */
289 if (!pagesize)
290 pagesize = sysconf (_SC_PAGESIZE);
291
292#define PAGE_MASK (~(pagesize - 1))
293#define PAGE_SIZE (pagesize)
294#endif /* HAVE_GETPAGESIZE */
295#endif /* PAGE_MASK */
296
297 start = header->p_vaddr & PAGE_MASK;
298 end = ((header->p_vaddr + header->p_filesz
299 + PAGE_SIZE)
300 & PAGE_MASK);
301
302 command.command = use_alternate ? 17 : 1;
303 command.vm_address = start;
304 command.file_offset = header->p_offset & PAGE_MASK;
305 command.protection = 0;
306 command.length = end - start;
307 command.clear = 0;
308 command.flags = MAP_PRIVATE | MAP_FIXED;
309
310 /* Apply the memory protection specified in the header. */
311
312 if (header->p_flags & 4) /* PF_R */
313 command.protection |= PROT_READ;
314
315 if (header->p_flags & 2) /* PF_W */
316 command.protection |= PROT_WRITE;
317
318 if (header->p_flags & 1) /* PF_X */
319 command.protection |= PROT_EXEC;
320
321 /* Next, write any command necessary to map pages in the area
322 between p_filesz and p_memsz. */
323 need_command1 = false;
324
325 if (header->p_memsz > header->p_filesz)
326 {
327 /* If there are bytes after end which need to be initialized, do
328 that now. */
329 command.clear = end - header->p_vaddr - header->p_filesz;
330 start = end;
331 end = header->p_vaddr + header->p_memsz + PAGE_SIZE;
332 end &= PAGE_MASK;
333
334 if (end > start)
335 {
336 command1.command = 4;
337 command1.vm_address = start;
338 command1.file_offset = 0;
339 command1.length = end - start;
340 command1.clear = 0;
341 command1.protection = command.protection;
342 command1.flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED;
343 need_command1 = true;
344 }
345 }
346
347 /* Apply the offset to both commands if necessary. */
348
349 if (offset)
350 {
351 if (need_command1)
352 command1.vm_address += offset;
353
354 command.vm_address += offset;
355 }
356
357 /* Write both commands. */
358
359 if (sizeof loader_area - loader_area_used < sizeof command)
360 return 1;
361
362 memcpy (loader_area + loader_area_used, &command,
363 sizeof command);
364 loader_area_used += sizeof command;
365
366 if (!need_command1)
367 return 0;
368
369 if (sizeof loader_area - loader_area_used < sizeof command1)
370 return 1;
371
372 memcpy (loader_area + loader_area_used, &command1,
373 sizeof command1);
374 loader_area_used += sizeof command1;
375
376 return 0;
377}
378
379#if defined __mips__ && !defined MIPS_NABI
380
381/* Static storage used for MIPS ABI flags. */
382static struct mips_elf_abi_flags exec_abi, interpreter_abi;
383
384/* Static storage for interpreter headers. */
385static elf_header exec_interpreter_header;
386
387/* Pointer to the ELF header of this executable's interpreter. */
388static elf_header *interpreter_header;
389
390/* Pointer to any PT_MIPS_ABIFLAGS program header found in the
391 executable itself. */
392static struct mips_elf_abi_flags *exec_abiflags;
393
394/* Pointer to any PT_MIPS_ABIFLAGS program header found in the
395 executable's ELF interpreter. */
396static struct mips_elf_abi_flags *interpreter_abiflags;
397
398#endif /* defined __mips__ && !defined MIPS_NABI */
399
400/* Process the specified program HEADER; HEADER is from the ELF
401 interpreter of another executable. FD is the executable file from
402 which it is being read, NAME is its file name, and ELF_HEADER is
403 its header.
404
405 If ELF_HEADER->e_type is ET_DYN, add the base address for position
406 independent interpreter code to virtual addresses.
407
408 Value is 1 upon failure, else 0. */
409
410static int
411process_interpreter_1 (const char *name, int fd,
412 program_header *header,
413 elf_header *elf_header)
414{
415 int rc;
416#if defined __mips__ && !defined MIPS_NABI
417 ssize_t rc1;
418#endif /* defined __mips__ && !defined MIPS_NABI */
419
420 switch (header->p_type)
421 {
422 default: /* PT_NULL, PT_NOTE, PT_DYNAMIC, PT_INTERP, et cetera */
423 rc = 0;
424 break;
425
426 case 1: /* PT_LOAD */
427 /* This describes a segment in the file that must be loaded.
428 Write the appropriate load command. */
429
430 if (elf_header->e_type == 3) /* ET_DYN */
431 rc = write_load_command (header, true,
432 INTERPRETER_BASE);
433 else
434 rc = write_load_command (header, true, 0);
435
436 break;
437
438#if defined __mips__ && !defined MIPS_NABI
439 case 0x70000003: /* PT_MIPS_ABIFLAGS */
440 /* Record this header for later use. */
441 rc1 = pread (fd, &interpreter_abi, sizeof interpreter_abi,
442 header->p_offset);
443
444 if (rc1 != sizeof interpreter_abi)
445 return 1;
446
447 interpreter_abiflags = &interpreter_abi;
448 rc = 0;
449#endif /* defined __mips__ && !defined MIPS_NABI */
450 }
451
452 return rc;
453}
454
455/* Read the ELF interpreter specified in the given program header from
456 FD, and append the commands necessary to load it to the load area.
457 Then, return the interpreter entry point in *ENTRY.
458
459 Value is 1 upon failure, else 0. */
460
461static int
462process_interpreter (int fd, program_header *prog_header,
463 USER_WORD *entry)
464{
465 char buffer[PATH_MAX + 1];
466 int rc, size, i;
467 elf_header header;
468 program_header program;
469
470 /* Read the interpreter name. */
471 size = MIN (prog_header->p_filesz, PATH_MAX);
472 rc = pread (fd, buffer, size, prog_header->p_offset);
473 if (rc < size)
474 return 1;
475
476 /* Make sure the name is NULL terminated. */
477 buffer[size] = '\0';
478
479 /* Check if the file is executable. This is unfortunately not
480 atomic. */
481
482 if (access (buffer, X_OK))
483 return 1;
484
485 /* Read the interpreter's header much like exec_0.
486
487 However, use special command codes in `process_program_header' if
488 it is position independent. That way, the loader knows it should
489 use the open interpreter instead. */
490
491 fd = open (buffer, O_RDONLY);
492
493 if (fd < 0)
494 return 1;
495
496 rc = read (fd, &header, sizeof header);
497
498 if (rc < sizeof header)
499 goto fail;
500
501#if defined __mips__ && !defined MIPS_NABI
502 /* Record this interpreter's header for later use determining the
503 floating point ABI. */
504 exec_interpreter_header = header;
505 interpreter_header = &exec_interpreter_header;
506#endif /* defined __mips__ && !defined MIPS_NABI */
507
508 /* Verify that this is indeed an ELF file. */
509
510 if (header.e_ident[0] != 0x7f
511 || header.e_ident[1] != 'E'
512 || header.e_ident[2] != 'L'
513 || header.e_ident[3] != 'F')
514 goto fail;
515
516 /* Now check that the class is correct. */
517#ifdef EXEC_64
518 if (header.e_ident[4] != 2)
519 goto fail;
520#else /* !EXEC_64 */
521 if (header.e_ident[4] != 1)
522 goto fail;
523#endif /* EXEC_64 */
524
525 /* And the endianness. */
526#ifndef WORDS_BIGENDIAN
527 if (header.e_ident[5] != 1)
528 goto fail;
529#else /* WORDS_BIGENDIAN */
530 if (header.e_ident[5] != 2)
531 goto fail;
532#endif /* EXEC_64 */
533
534 /* Check that this is an executable. */
535 if (header.e_type != 2 && header.e_type != 3)
536 goto fail;
537
538 /* Now check that the ELF program header makes sense. */
539 if (header.e_phnum > 0xffff
540 || (header.e_phentsize
541 != sizeof (program_header)))
542 goto fail;
543
544 if (write_open_command (buffer, true))
545 goto fail;
546
547 for (i = 0; i < header.e_phnum; ++i)
548 {
549 rc = read (fd, &program, sizeof program);
550 if (rc < sizeof program)
551 goto fail;
552
553 if (process_interpreter_1 (buffer, fd, &program,
554 &header))
555 goto fail;
556 }
557
558 if (header.e_type == 3) /* ET_DYN */
559 *entry = header.e_entry + INTERPRETER_BASE;
560 else
561 *entry = header.e_entry;
562
563 close (fd);
564 return 0;
565
566 fail:
567 close (fd);
568 return 1;
569}
570
571/* Process the specified program HEADER. FD is the executable file
572 from which it is being read, NAME is its file name, and ELF_HEADER
573 is its header.
574
575 If ELF_HEADER->e_type is ET_DYN, add the base address for position
576 independent code to virtual addresses.
577
578 If OFFSET is non-NULL, and *OFFSET is -1, write the virtual address
579 of HEADER if it describes a PT_LOAD segment.
580
581 If an interpreter is found, set *ENTRY to its entry point.
582
583 Value is 1 upon failure, else 0. */
584
585static int
586process_program_header (const char *name, int fd,
587 program_header *header,
588 elf_header *elf_header,
589 USER_WORD *entry,
590 USER_WORD *offset)
591{
592 int rc;
593#if defined __mips__ && !defined MIPS_NABI
594 ssize_t rc1;
595#endif /* defined __mips__ && !defined MIPS_NABI */
596
597 switch (header->p_type)
598 {
599 default: /* PT_NULL, PT_NOTE, PT_DYNAMIC, et cetera */
600 rc = 0;
601 break;
602
603 case 1: /* PT_LOAD */
604 /* This describes a segment in the file that must be loaded.
605 Write the appropriate load command. */
606
607 if (elf_header->e_type == 3) /* ET_DYN */
608 {
609 rc = write_load_command (header, false,
610 EXECUTABLE_BASE);
611
612 if (!rc && offset && *offset == (USER_WORD) -1)
613 *offset = EXECUTABLE_BASE + header->p_vaddr;
614 }
615 else
616 {
617 rc = write_load_command (header, false, 0);
618
619 if (!rc && offset && *offset == (USER_WORD) -1)
620 *offset = header->p_vaddr;
621 }
622
623 break;
624
625 case 3: /* PT_INTERP */
626 /* This describes another executable that must be loaded.
627 Open the interpreter and process each of its headers
628 as well. */
629 rc = process_interpreter (fd, header, entry);
630 break;
631
632 case 1685382481: /* PT_GNU_STACK */
633 /* TODO */
634 rc = 0;
635 break;
636
637#if defined __mips__ && !defined MIPS_NABI
638 case 0x70000003: /* PT_MIPS_ABIFLAGS */
639 /* Record this header for later use. */
640 rc1 = pread (fd, &exec_abi, sizeof exec_abi,
641 header->p_offset);
642
643 if (rc1 != sizeof exec_abi)
644 return 1;
645
646 exec_abiflags = &exec_abi;
647 rc = 0;
648#endif /* defined __mips__ && !defined MIPS_NABI */
649 }
650
651 return rc;
652}
653
654/* Prepend one or two extra arguments ARG1 and ARG2 to a pending
655 execve system call. TRACEE is the tracee performing the system
656 call, and REGS are its current user registers. Value is 1 upon
657 failure, else 0. */
658
659static int
660insert_args (struct exec_tracee *tracee, USER_REGS_STRUCT *regs,
661 const char *arg1, const char *arg2)
662{
663 USER_WORD argv, argc, word, new;
664 USER_WORD new1, new2;
665 size_t text_size, effective_size;
666 USER_REGS_STRUCT original;
667
668 /* First, get a pointer to the current argument vector. */
669 argv = regs->SYSCALL_ARG1_REG;
670
671 /* Now figure out how many arguments there are. */
672 argc = 0;
673 while (true)
674 {
675 /* Clear errno. PTRACE_PEEKDATA returns the word read the same
676 way failure indications are returned, so the only way to
677 catch IO errors is by clearing errno before the call to
678 ptrace and checking it afterwards. */
679
680 errno = 0;
681 word = ptrace (PTRACE_PEEKDATA, tracee->pid,
682 (void *) argv, NULL);
683 argv += sizeof (USER_WORD);
684
685 if (errno)
686 return 1;
687
688 if (!word)
689 break;
690
691 ++argc;
692 };
693
694 /* Allocate enough to hold that many arguments, alongside the argc
695 text. */
696
697 text_size = (strlen (arg1) + 1
698 + (arg2 ? strlen (arg2) + 1 : 0));
699
700 /* Round it up to the user word size. */
701 text_size += sizeof (USER_WORD) - 1;
702 text_size &= ~(sizeof (USER_WORD) - 1);
703
704 /* Now allocate the new argv. */
705
706 effective_size = sizeof word * (argc + 2) + text_size;
707
708 if (arg2)
709 effective_size += sizeof word;
710
711 /* Copy regs to original so that user_alloca knows it should append
712 the ABI red zone. */
713
714 memcpy (&original, regs, sizeof *regs);
715 new = user_alloca (tracee, &original, regs,
716 effective_size);
717
718 if (!new)
719 goto fail;
720
721 /* Figure out where argv starts. */
722
723 new2 = new + text_size;
724
725 /* Now write the two strings. */
726
727 new1 = new + strlen (arg1) + 1;
728 if (user_copy (tracee, (const unsigned char *) arg1,
729 new, new1 - new))
730 goto fail;
731
732 if (arg2 && user_copy (tracee, (const unsigned char *) arg2,
733 new1, new2 - new1))
734 goto fail;
735
736 /* Start copying argv back to new2. First, write the one or two new
737 arguments. */
738
739 if (ptrace (PTRACE_POKETEXT, tracee->pid,
740 (void *) new2, (void *) new))
741 goto fail;
742
743 new2 += sizeof new2;
744
745 if (arg2 && ptrace (PTRACE_POKETEXT, tracee->pid,
746 (void *) new2, (void *) new1))
747 goto fail;
748 else if (arg2)
749 new2 += sizeof new2;
750
751 /* Copy the remaining arguments back. */
752
753 argv = regs->SYSCALL_ARG1_REG;
754
755 /* Make sure the trailing NULL is included. */
756 argc += 1;
757
758 while (argc)
759 {
760 /* Read one argument. */
761 word = ptrace (PTRACE_PEEKDATA, tracee->pid,
762 (void *) argv, NULL);
763 argv += sizeof argv;
764 argc--;
765
766 /* Write one argument, then increment new2. */
767
768 if (ptrace (PTRACE_POKETEXT, tracee->pid,
769 (void *) new2, (void *) word))
770 goto fail;
771
772 new2 += sizeof new2;
773 }
774
775 /* Assert that new2 is not out of bounds. */
776 assert (new2 == new + effective_size);
777
778 /* And that it is properly aligned. */
779 assert (!(new2 & (sizeof new2 - 2)));
780
781 /* Now modify the system call argument to point to new +
782 text_size. */
783
784 regs->SYSCALL_ARG1_REG = new + text_size;
785
786#ifdef __aarch64__
787 if (aarch64_set_regs (tracee->pid, regs, false))
788 goto fail;
789#else /* !__aarch64__ */
790 if (ptrace (PTRACE_SETREGS, tracee->pid, NULL, regs))
791 goto fail;
792#endif /* __aarch64__ */
793
794 /* Success. */
795
796 return 0;
797
798 fail:
799 /* Restore the original stack pointer. */
800#ifdef __aarch64__
801 aarch64_set_regs (tracee->pid, &original, false);
802#else /* !__aarch64__ */
803 ptrace (PTRACE_SETREGS, tracee->pid, NULL, &original);
804#endif /* __aarch64__ */
805 errno = ENOMEM;
806 return 1;
807}
808
809
810
811/* Return a sequence of actions required to load the executable under
812 the file NAME for the given TRACEE. First, see if the file starts
813 with #!; in that case, find the program to open and use that
814 instead.
815
816 Next, read the executable header, and add the necessary memory
817 mappings for each file. Finally, return the action data and its
818 size in *SIZE.
819
820 Finally, use REGS to add the required interpreter arguments to the
821 caller's argv.
822
823 Value is NULL upon failure, with errno set accordingly. */
824
825char *
826exec_0 (const char *name, struct exec_tracee *tracee,
827 size_t *size, USER_REGS_STRUCT *regs)
828{
829 int fd, rc, i;
830 elf_header header;
831 const char *interpreter_name, *extra;
832 program_header program;
833 USER_WORD entry, program_entry, offset;
834 USER_WORD header_offset;
835 struct exec_jump_command jump;
836#if defined __mips__ && !defined MIPS_NABI
837 int fpu_mode;
838#endif /* defined __mips__ && !defined MIPS_NABI */
839
840 fd = open (name, O_RDONLY);
841 if (fd < 0)
842 return NULL;
843
844 /* Now read the header. */
845
846 extra = NULL;
847 interpreter_name = check_interpreter (name, fd, &extra);
848 if (!interpreter_name)
849 goto fail;
850
851 /* Open the interpreter instead, if necessary. */
852 if (interpreter_name != name)
853 {
854 close (fd);
855 fd = open (interpreter_name, O_RDONLY);
856 if (fd < 0)
857 return NULL;
858
859 /* Now, rewrite the argument list to include `interpreter_name'
860 and perhaps `extra'. */
861
862 if (insert_args (tracee, regs, interpreter_name,
863 extra))
864 goto fail1;
865 }
866
867 rc = read (fd, &header, sizeof header);
868
869 if (rc < sizeof header)
870 goto fail1;
871
872 /* Verify that this is indeed an ELF file. */
873
874 if (header.e_ident[0] != 0x7f
875 || header.e_ident[1] != 'E'
876 || header.e_ident[2] != 'L'
877 || header.e_ident[3] != 'F')
878 goto fail1;
879
880 /* Now check that the class is correct. */
881#ifdef EXEC_64
882 if (header.e_ident[4] != 2)
883 goto fail1;
884#else /* !EXEC_64 */
885 if (header.e_ident[4] != 1)
886 goto fail1;
887#endif /* EXEC_64 */
888
889 /* And the endianness. */
890#ifndef WORDS_BIGENDIAN
891 if (header.e_ident[5] != 1)
892 goto fail1;
893#else /* WORDS_BIGENDIAN */
894 if (header.e_ident[5] != 2)
895 goto fail1;
896#endif /* EXEC_64 */
897
898 /* Check that this is an executable. */
899 if (header.e_type != 2 && header.e_type != 3)
900 goto fail1;
901
902 /* Now check that the ELF program header makes sense. */
903 if (header.e_phnum > 0xffff
904 || (header.e_phentsize
905 != sizeof (program_header)))
906 goto fail1;
907
908 /* Seek to the first program header and read each one. */
909 rc = lseek (fd, header.e_phoff, SEEK_SET);
910 if (rc < 0)
911 goto fail1;
912 loader_area_used = 0;
913
914 /* Write the command used to open the executable. */
915 if (write_open_command (interpreter_name, false))
916 goto fail1;
917
918 /* Apply base addresses for PIC code. */
919
920 if (header.e_type == 3) /* ET_DYN */
921 offset = EXECUTABLE_BASE;
922 else
923 offset = 0;
924
925 /* entry and program_entry are initially the same, but entry may be
926 set to that of the interpreter if one is present. */
927
928 entry = header.e_entry + offset;
929 program_entry = header.e_entry;
930
931#if defined __mips__ && !defined MIPS_NABI
932 /* Clear MIPS ABI flags. */
933 exec_abiflags = NULL;
934 interpreter_abiflags = NULL;
935 interpreter_header = NULL;
936#endif /* defined __mips__ && !defined MIPS_NABI */
937
938 /* Set header_offset to -1; `process_program_header' then updates it
939 to that of the first mapping. */
940 header_offset = -1;
941
942 for (i = 0; i < header.e_phnum; ++i)
943 {
944 rc = read (fd, &program, sizeof program);
945 if (rc < sizeof program)
946 goto fail1;
947
948 if (process_program_header (interpreter_name, fd,
949 &program, &header,
950 &entry, &header_offset))
951 goto fail1;
952 }
953
954 /* Write the entry point and program entry. */
955
956 jump.command = 3;
957 jump.entry = entry;
958
959 /* Now calculate values for the aux vector. */
960
961 jump.at_entry = program_entry + offset;
962 jump.at_phent = header.e_phentsize;
963 jump.at_phnum = header.e_phnum;
964 jump.at_base = (entry == header.e_entry + offset
965 ? EXECUTABLE_BASE
966 : INTERPRETER_BASE);
967
968#if defined __mips__ && !defined MIPS_NABI
969 /* Finally, calculate the FPU mode wanted by the executable. */
970
971 if (determine_fpu_mode (&header, interpreter_header,
972 &fpu_mode, exec_abiflags,
973 interpreter_abiflags))
974 /* N.B. that `determine_fpu_mode' sets errno. */
975 goto fail;
976
977 /* If the processor is too new to support FR0 operation, place the
978 executable in floating point emulation mode. */
979
980 if (fpu_mode == FP_FR0 && !cpu_supports_fr0_p ())
981 fpu_mode = FP_FRE;
982
983 jump.fpu_mode = fpu_mode;
984#endif /* defined __mips__ && !defined MIPS_NABI */
985
986 /* The offset used for at_phdr should be that of the first
987 mapping. */
988
989 if (header_offset == (USER_WORD) -1)
990 header_offset = 0;
991
992 jump.at_phdr = header.e_phoff + header_offset;
993
994 if (sizeof loader_area - loader_area_used < sizeof jump)
995 goto fail1;
996
997 memcpy (loader_area + loader_area_used, &jump,
998 sizeof jump);
999 loader_area_used += sizeof jump;
1000
1001 /* Close the file descriptor and return the number of bytes
1002 used. */
1003
1004 close (fd);
1005 *size = loader_area_used;
1006
1007 /* Make sure the loader area is properly aligned. */
1008 assert (!(loader_area_used & (sizeof (USER_WORD) - 1)));
1009 return loader_area;
1010
1011 fail1:
1012 errno = ENOEXEC;
1013 fail:
1014 close (fd);
1015 return NULL;
1016}