AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
binfmt.c
Go to the documentation of this file.
1
9
10#include <core/arch.h>
11#include <sys/binfmt.h>
12#include <sys/elf.h>
13#include <mm/vm.h>
14
15static struct binfmt binfmt_list[] = {
17};
18
19#define NR_BINFMT ((sizeof(binfmt_list)/sizeof(binfmt_list[0])))
20
28static int binfmt_fmt_load(struct proc *proc, const char *path, struct vnode *vnode, struct binfmt *binfmt, struct proc **ref)
29{
30 int err = 0;
31
32 /* the point of no return: after this the old program is gone, and on
33 * failure the address space is left empty. The other threads, which
34 * run in it, end first */
37
38 if ((err = binfmt->load(proc, path, vnode)))
39 goto error;
40
41 char *name = strdup(path);
42
43 if (!name) {
44 err = -ENOMEM;
45 goto error;
46 }
47
48 kfree(proc->name);
49 proc->name = name;
50
51 /* the heap starts on a page boundary after the program */
54
55 /* the heap's mapping, empty: sbrk() grows it */
56 struct vm_entry *heap_vm = kmalloc(sizeof(struct vm_entry), &M_VM_ENTRY, M_ZERO);
57 if (!heap_vm) {
58 err = -ENOMEM;
59 goto error;
60 }
61
62 heap_vm->base = proc->heap_start;
63 heap_vm->size = 0;
64 heap_vm->flags = VM_URW;
65
66 if (!(heap_vm->qnode = enqueue(&proc->vm_space.vm_entries, heap_vm))) {
67 kfree(heap_vm);
68 err = -ENOMEM;
69 goto error;
70 }
71
72 heap_vm->vm_object = NULL;
73
74 proc->heap_vm = heap_vm;
75
76 /* the stack's mapping */
77 struct vm_entry *stack_vm = kmalloc(sizeof(struct vm_entry), &M_VM_ENTRY, M_ZERO);
78 if (!stack_vm) {
79 err = -ENOMEM;
80 goto error;
81 }
82
83 stack_vm->base = USER_STACK_BASE;
84 stack_vm->size = USER_STACK_SIZE;
85 stack_vm->flags = VM_URW;
86
87 if (!(stack_vm->qnode = enqueue(&proc->vm_space.vm_entries, stack_vm))) {
88 kfree(stack_vm);
89 err = -ENOMEM;
90 goto error;
91 }
92
93 stack_vm->vm_object = NULL;
94
95 proc->stack_vm = stack_vm;
96
97 /* the sigcode page: signal handlers return into it */
98 if ((err = arch_sigcode_map(proc)))
99 goto error;
100
101 struct thread *thread = (struct thread *) proc->threads.head->value;
104
105 return 0;
106
107error:
108 /* drop whatever was loaded so far */
110 return err;
111}
112
124int binfmt_load(struct proc *proc, const char *path, struct proc **ref)
125{
126 struct vnode *vnode = NULL;
127 int err = 0;
128
129 struct uio uio;
130 memset(&uio, 0, sizeof(struct uio));
131
132 if (proc) {
133 uio = PROC_UIO(proc);
134 }
135
136 if ((err = vfs_lookup(path, &uio, &vnode)))
137 return err;
138
139 if (!vnode)
140 return -ENOENT;
141
142 /* it must be a regular file that the process may execute */
143 if (!S_ISREG(vnode->mode)) {
144 err = -EACCES;
145 goto done;
146 }
147
148 if ((err = vfs_access(vnode, &uio, VFS_X)))
149 goto done;
150
151 err = -ENOEXEC;
152
153 for (size_t i = 0; i < NR_BINFMT; ++i) {
154 if (!binfmt_list[i].check(vnode)) {
155 err = binfmt_fmt_load(proc, path, vnode, &binfmt_list[i], ref);
156 break;
157 }
158 }
159
160done:
161 /* drop the lookup's reference: the program's mappings hold their own */
163 return err;
164}
#define USER_STACK_BASE
Definition arch.h:61
int arch_sigcode_map(struct proc *proc)
Maps the page with the code that calls sigreturn() (the sigcode) into a process's new address space.
Definition signal.c:107
static int binfmt_fmt_load(struct proc *proc, const char *path, struct vnode *vnode, struct binfmt *binfmt, struct proc **ref)
Replaces a process's memory with a program, loaded by a format: the process's other threads end,...
Definition binfmt.c:28
#define NR_BINFMT
Definition binfmt.c:19
static struct binfmt binfmt_list[]
Definition binfmt.c:15
int binfmt_elf_check(struct vnode *vnode)
Says whether a file is an ELF program this kernel can run: its magic number, class and machine.
Definition elf.c:199
int binfmt_elf_load(struct proc *proc, const char *path, struct vnode *vnode)
Loads an ELF program into a process.
Definition elf.c:227
int binfmt_load(struct proc *proc, const char *path, struct proc **ref)
Loads a program into a process, for execve().
Definition binfmt.c:124
int vfs_close(struct vnode *vnode)
Drops a reference to a vnode.
Definition close.c:18
#define USER_STACK_SIZE
Definition config.h:49
#define PAGE_ROUND(ptr)
Definition mm.h:10
void * kmalloc(size_t size, struct malloc_type *type, int flags)
Allocates memory for one of the kernel's structures.
Definition kvmem.c:123
#define M_ZERO
Definition kvmem.h:26
void kfree(void *)
Frees an object that kmalloc() gave.
Definition kvmem.c:146
void * memset(void *dst, int c, size_t n)
Sets n bytes to c.
Definition libc.c:23
int vfs_lookup(const char *path, struct uio *uio, struct vnode **ref)
Finds the vnode a path names.
Definition lookup.c:349
void proc_threads_exec(struct proc *proc)
Ends every thread of a process but the current one, for execve() (POSIX: they run in the program that...
Definition proc.c:358
#define PROC_UIO(proc)
Definition proc.h:210
#define NULL
Definition stddef.h:27
A format of executable files: says whether a file is one, and loads it into a process (sys/binfmt/).
Definition binfmt.h:10
int(*) load(struct proc *proc, const char *path, struct vnode *vnode)
Definition binfmt.h:12
A process.
Definition proc.h:75
struct vm_space vm_space
its address space
Definition proc.h:129
struct vm_entry * stack_vm
Definition proc.h:133
uintptr_t heap_start
where its heap starts, and where it ends now (sbrk())
Definition proc.h:122
struct vm_entry * heap_vm
its heap's and its stack's mappings
Definition proc.h:132
uintptr_t heap
Definition proc.h:123
char * name
its name: the program it runs
Definition proc.h:84
struct queue threads
its threads
Definition proc.h:136
void * value
Definition queue.h:20
struct qnode * head
Definition queue.h:31
A thread.
Definition thread.h:23
uintptr_t stack_base
Definition thread.h:40
size_t stack_size
Definition thread.h:41
Who does a filesystem operation: where its paths start, and its credentials and umask.
Definition vfs.h:60
A mapping (map entry): a range of an address space, its permissions, and where its pages come from.
Definition vm.h:66
uint32_t flags
its permissions and flags (VM_*)
Definition vm.h:78
vaddr_t base
where the mapping starts in its address space
Definition vm.h:72
struct vm_object * vm_object
its object: what its other pages come from (a file)
Definition vm.h:84
struct qnode * qnode
its node in its address space's list of mappings
Definition vm.h:90
size_t size
its size
Definition vm.h:75
struct queue vm_entries
its mappings (map entries), in address order
Definition vm.h:30
A file in memory (a vnode): what its inode says, and the kernel's own state.
Definition vfs.h:113
mode_t mode
Definition vfs.h:118
int vfs_access(struct vnode *vnode, struct uio *uio, int mode)
Checks whether a user may access a vnode in a way: the owner's permissions apply to its owner,...
Definition vfs.c:114
#define VFS_X
Definition vfs.h:297
#define VM_URW
user read/write
Definition vm.h:53
void vm_space_destroy(struct vm_space *vm_space)
Removes all the mappings of an address space: its entries are released and freed, and its page tables...
Definition vm_space.c:124