1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | #include <alloca.h> |
26 | #include <mach/machine/vm_types.h> |
27 | #include <mach/exec/elf.h> |
28 | #include <mach/exec/exec.h> |
29 | |
30 | int exec_load(exec_read_func_t *read, exec_read_exec_func_t *read_exec, |
31 | void *handle, exec_info_t *out_info) |
32 | { |
33 | vm_size_t actual; |
34 | Elf32_Ehdr x; |
35 | Elf32_Phdr *phdr, *ph; |
36 | vm_size_t phsize; |
37 | int i; |
38 | int result; |
39 | |
40 | |
41 | if ((result = (*read)(handle, 0, &x, sizeof(x), &actual)) != 0) |
42 | return result; |
43 | if (actual < sizeof(x)) |
44 | return EX_NOT_EXECUTABLE6000; |
45 | |
46 | if ((x.e_ident[EI_MAG00] != ELFMAG00x7f) || |
47 | (x.e_ident[EI_MAG11] != ELFMAG1'E') || |
48 | (x.e_ident[EI_MAG22] != ELFMAG2'L') || |
49 | (x.e_ident[EI_MAG33] != ELFMAG3'F')) |
50 | return EX_NOT_EXECUTABLE6000; |
51 | |
52 | |
53 | if ((x.e_ident[EI_CLASS4] != ELFCLASS321) || |
54 | (x.e_ident[EI_DATA5] != MY_EI_DATA1) || |
55 | (x.e_machine != MY_E_MACHINE3)) |
56 | return EX_WRONG_ARCH6001; |
57 | |
58 | |
59 | out_info->entry = (vm_offset_t) x.e_entry; |
60 | |
61 | phsize = x.e_phnum * x.e_phentsize; |
62 | phdr = (Elf32_Phdr *)alloca(phsize)__builtin_alloca(phsize); |
63 | |
64 | result = (*read)(handle, x.e_phoff, phdr, phsize, &actual); |
65 | if (result) |
66 | return result; |
67 | if (actual < phsize) |
68 | return EX_CORRUPT6002; |
69 | |
70 | for (i = 0; i < x.e_phnum; i++) |
71 | { |
72 | ph = (Elf32_Phdr *)((vm_offset_t)phdr + i * x.e_phentsize); |
73 | if (ph->p_type == PT_LOAD1) |
74 | { |
75 | exec_sectype_t type = EXEC_SECTYPE_ALLOC((exec_sectype_t)0x000100) | |
76 | EXEC_SECTYPE_LOAD((exec_sectype_t)0x000200); |
77 | if (ph->p_flags & PF_R0x4) type |= EXEC_SECTYPE_READ((vm_prot_t) 0x01); |
78 | if (ph->p_flags & PF_W0x2) type |= EXEC_SECTYPE_WRITE((vm_prot_t) 0x02); |
79 | if (ph->p_flags & PF_X0x1) type |= EXEC_SECTYPE_EXECUTE((vm_prot_t) 0x04); |
80 | result = (*read_exec)(handle, |
| Value stored to 'result' is never read |
81 | ph->p_offset, ph->p_filesz, |
82 | ph->p_vaddr, ph->p_memsz, type); |
83 | } |
84 | } |
85 | |
86 | return 0; |
87 | } |
88 | |