PKUOS - Pintos
Pintos source browser for PKU Operating System course
Data Structures | Macros | Typedefs | Functions | Variables
process.c File Reference
#include "userprog/process.h"
#include <debug.h>
#include <inttypes.h>
#include <round.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "userprog/gdt.h"
#include "userprog/pagedir.h"
#include "userprog/tss.h"
#include "filesys/directory.h"
#include "filesys/file.h"
#include "filesys/filesys.h"
#include "threads/flags.h"
#include "threads/init.h"
#include "threads/interrupt.h"
#include "threads/palloc.h"
#include "threads/thread.h"
#include "threads/vaddr.h"
Include dependency graph for process.c:

Go to the source code of this file.

Data Structures

struct  Elf32_Ehdr
 Executable header. More...
 
struct  Elf32_Phdr
 Program header. More...
 

Macros

#define PE32Wx   PRIx32
 For use with ELF types in printf(). More...
 
#define PE32Ax   PRIx32
 Print Elf32_Addr in hexadecimal. More...
 
#define PE32Ox   PRIx32
 Print Elf32_Off in hexadecimal. More...
 
#define PE32Hx   PRIx16
 Print Elf32_Half in hexadecimal. More...
 
#define PT_NULL   0
 Values for p_type. More...
 
#define PT_LOAD   1
 Loadable segment. More...
 
#define PT_DYNAMIC   2
 Dynamic linking info. More...
 
#define PT_INTERP   3
 Name of dynamic loader. More...
 
#define PT_NOTE   4
 Auxiliary info. More...
 
#define PT_SHLIB   5
 Reserved. More...
 
#define PT_PHDR   6
 Program header table. More...
 
#define PT_STACK   0x6474e551
 Stack segment. More...
 
#define PF_X   1
 Flags for p_flags. More...
 
#define PF_W   2
 Writable. More...
 
#define PF_R   4
 Readable. More...
 

Typedefs

typedef uint32_t Elf32_Word
 We load ELF binaries. More...
 
typedef uint32_t Elf32_Addr
 
typedef uint32_t Elf32_Off
 
typedef uint16_t Elf32_Half
 

Functions

static bool load (const char *file_name, void(**eip)(void), void **esp)
 Loads an ELF executable from FILE_NAME into the current thread. More...
 
tid_t process_execute (const char *file_name)
 Starts a new thread running a user program loaded from FILENAME. More...
 
static void start_process (void *file_name_)
 A thread function that loads a user process and starts it running. More...
 
int process_wait (tid_t child_tid UNUSED)
 Waits for thread TID to die and returns its exit status. More...
 
void process_exit (void)
 Free the current process's resources. More...
 
void process_activate (void)
 Sets up the CPU for running user code in the current thread. More...
 
static bool setup_stack (void **esp)
 Create a minimal stack by mapping a zeroed page at the top of user virtual memory. More...
 
static bool validate_segment (const struct Elf32_Phdr *phdr, struct file *file)
 Checks whether PHDR describes a valid, loadable segment in FILE and returns true if so, false otherwise. More...
 
static bool load_segment (struct file *file, off_t ofs, uint8_t *upage, uint32_t read_bytes, uint32_t zero_bytes, bool writable)
 Loads a segment starting at offset OFS in FILE at address UPAGE. More...
 
static bool install_page (void *upage, void *kpage, bool writable)
 load() helpers. More...
 

Variables

static thread_func start_process NO_RETURN
 

Macro Definition Documentation

◆ PE32Ax

#define PE32Ax   PRIx32

Print Elf32_Addr in hexadecimal.

Definition at line 144 of file process.c.

◆ PE32Hx

#define PE32Hx   PRIx16

Print Elf32_Half in hexadecimal.

Definition at line 146 of file process.c.

◆ PE32Ox

#define PE32Ox   PRIx32

Print Elf32_Off in hexadecimal.

Definition at line 145 of file process.c.

◆ PE32Wx

#define PE32Wx   PRIx32

For use with ELF types in printf().

Print Elf32_Word in hexadecimal.

Definition at line 143 of file process.c.

◆ PF_R

#define PF_R   4

Readable.

Definition at line 196 of file process.c.

◆ PF_W

#define PF_W   2

Writable.

Definition at line 195 of file process.c.

◆ PF_X

#define PF_X   1

Flags for p_flags.

See [ELF3] 2-3 and 2-4. Executable.

Definition at line 194 of file process.c.

◆ PT_DYNAMIC

#define PT_DYNAMIC   2

Dynamic linking info.

Definition at line 186 of file process.c.

◆ PT_INTERP

#define PT_INTERP   3

Name of dynamic loader.

Definition at line 187 of file process.c.

◆ PT_LOAD

#define PT_LOAD   1

Loadable segment.

Definition at line 185 of file process.c.

◆ PT_NOTE

#define PT_NOTE   4

Auxiliary info.

Definition at line 188 of file process.c.

◆ PT_NULL

#define PT_NULL   0

Values for p_type.

See [ELF1] 2-3. Ignore.

Definition at line 184 of file process.c.

◆ PT_PHDR

#define PT_PHDR   6

Program header table.

Definition at line 190 of file process.c.

◆ PT_SHLIB

#define PT_SHLIB   5

Reserved.

Definition at line 189 of file process.c.

◆ PT_STACK

#define PT_STACK   0x6474e551

Stack segment.

Definition at line 191 of file process.c.

Typedef Documentation

◆ Elf32_Addr

Definition at line 139 of file process.c.

◆ Elf32_Half

Definition at line 140 of file process.c.

◆ Elf32_Off

Definition at line 139 of file process.c.

◆ Elf32_Word

We load ELF binaries.

The following definitions are taken from the ELF specification, [ELF1], more-or-less verbatim.
ELF types. See [ELF1] 1-2.

Definition at line 139 of file process.c.

Function Documentation

◆ install_page()

static bool install_page ( void *  upage,
void *  kpage,
bool  writable 
)
static

load() helpers.

Adds a mapping from user virtual address UPAGE to kernel virtual address KPAGE to the page table.

If WRITABLE is true, the user process may modify the page; otherwise, it is read-only. UPAGE must not already be mapped. KPAGE should probably be a page obtained from the user pool with palloc_get_page(). Returns true on success, false if UPAGE is already mapped or if memory allocation fails.

Definition at line 457 of file process.c.

References NULL, pagedir_get_page(), pagedir_set_page(), and thread_current().

Referenced by load_segment(), and setup_stack().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ load()

bool load ( const char *  file_name,
void(**)(void)  eip,
void **  esp 
)
static

Loads an ELF executable from FILE_NAME into the current thread.

Stores the executable's entry point into *EIP and its initial stack pointer into *ESP. Returns true if successful, false otherwise.

Definition at line 209 of file process.c.

References Elf32_Ehdr::e_entry, Elf32_Ehdr::e_ident, Elf32_Ehdr::e_machine, Elf32_Ehdr::e_phentsize, Elf32_Ehdr::e_phnum, Elf32_Ehdr::e_phoff, Elf32_Ehdr::e_type, Elf32_Ehdr::e_version, file_close(), file_length(), file_name, file_read(), file_seek(), filesys_open(), load_segment(), memcmp(), NULL, Elf32_Phdr::p_filesz, Elf32_Phdr::p_flags, Elf32_Phdr::p_memsz, Elf32_Phdr::p_offset, Elf32_Phdr::p_type, Elf32_Phdr::p_vaddr, pagedir_create(), PF_W, PGMASK, PGSIZE, printf(), process_activate(), PT_DYNAMIC, PT_INTERP, PT_LOAD, PT_NOTE, PT_NULL, PT_PHDR, PT_SHLIB, PT_STACK, ROUND_UP, setup_stack(), thread_current(), and validate_segment().

Referenced by start_process().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ load_segment()

static bool load_segment ( struct file file,
off_t  ofs,
uint8_t upage,
uint32_t  read_bytes,
uint32_t  zero_bytes,
bool  writable 
)
static

Loads a segment starting at offset OFS in FILE at address UPAGE.

In total, READ_BYTES + ZERO_BYTES bytes of virtual memory are initialized, as follows:

 - READ_BYTES bytes at UPAGE must be read from FILE
   starting at offset OFS.

 - ZERO_BYTES bytes at UPAGE + READ_BYTES must be zeroed.

The pages initialized by this function must be writable by the user process if WRITABLE is true, read-only otherwise.

Return true if successful, false if a memory allocation error or disk read error occurs.

Definition at line 383 of file process.c.

References ASSERT, file_read(), file_seek(), install_page(), memset(), NULL, PAL_USER, palloc_free_page(), palloc_get_page(), pg_ofs(), and PGSIZE.

Referenced by load().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_activate()

void process_activate ( void  )

Sets up the CPU for running user code in the current thread.

userprog/process.h

This function is called on every context switch.

Definition at line 123 of file process.c.

References pagedir_activate(), thread_current(), and tss_update().

Referenced by load(), and thread_schedule_tail().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_execute()

tid_t process_execute ( const char *  file_name)

Starts a new thread running a user program loaded from FILENAME.

The new thread may be scheduled (and may even exit) before process_execute() returns. Returns the new process's thread id, or TID_ERROR if the thread cannot be created.

Definition at line 29 of file process.c.

References file_name, NULL, palloc_free_page(), palloc_get_page(), PGSIZE, PRI_DEFAULT, start_process(), strlcpy(), thread_create(), and TID_ERROR.

Referenced by run_task().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_exit()

void process_exit ( void  )

Free the current process's resources.

Definition at line 96 of file process.c.

References NULL, pagedir_activate(), pagedir_destroy(), and thread_current().

Referenced by thread_exit().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_wait()

int process_wait ( tid_t child_tid  UNUSED)

Waits for thread TID to die and returns its exit status.

If it was terminated by the kernel (i.e. killed due to an exception), returns -1. If TID is invalid or if it was not a child of the calling process, or if process_wait() has already been successfully called for the given TID, returns -1 immediately, without waiting.

This function will be implemented in problem 2-2. For now, it does nothing.

Definition at line 89 of file process.c.

Referenced by run_task().

Here is the caller graph for this function:

◆ setup_stack()

static bool setup_stack ( void **  esp)
static

Create a minimal stack by mapping a zeroed page at the top of user virtual memory.

Definition at line 430 of file process.c.

References install_page(), NULL, PAL_USER, PAL_ZERO, palloc_free_page(), palloc_get_page(), PGSIZE, and PHYS_BASE.

Referenced by load().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ start_process()

static void start_process ( void *  file_name_)
static

A thread function that loads a user process and starts it running.

Definition at line 51 of file process.c.

References intr_frame::cs, intr_frame::ds, intr_frame::eflags, intr_frame::eip, intr_frame::es, intr_frame::esp, file_name, FLAG_IF, FLAG_MBS, intr_frame::fs, intr_frame::gs, load(), memset(), NOT_REACHED, palloc_free_page(), SEL_UCSEG, SEL_UDSEG, intr_frame::ss, and thread_exit().

Referenced by process_execute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ validate_segment()

static bool validate_segment ( const struct Elf32_Phdr phdr,
struct file file 
)
static

Checks whether PHDR describes a valid, loadable segment in FILE and returns true if so, false otherwise.

Definition at line 326 of file process.c.

References file_length(), is_user_vaddr(), Elf32_Phdr::p_filesz, Elf32_Phdr::p_memsz, Elf32_Phdr::p_offset, Elf32_Phdr::p_vaddr, PGMASK, and PGSIZE.

Referenced by load().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ NO_RETURN

thread_func start_process NO_RETURN
static

Definition at line 21 of file process.c.