sc_retval create_segment(const sc_string &s) { sc_segment *seg = map_segment(s); if (seg) return RV_OK; return create_dirent(s,false)?RV_OK:RV_ERR_GEN; }
sc_retval create_segment(const sc_string &s, sc_segment_base *custom_seg) { sc_segment *seg = map_segment(s); if (seg) return RV_OK; return create_dirent(s, false, custom_seg) ? RV_OK : RV_ERR_GEN; }
void check_map_large(){ //These variable created for compiling sake Seq_T SEG_MEMORY = Seq_new(100); Seq_T UNMAP_SEQ = Seq_new(10); Umsegment_Id one = map_segment(6); Umsegment_Id two = map_segment(6); Umsegment_Id three = map_segment(8000); Umsegment_Id four = map_segment(6); int size = UArray_length(Seq_get(SEG_MEMORY, three)); if (size != 8000) fprintf(stderr, "Big segment is incorrect size %d.\n", size); unmap_segment(one); unmap_segment(two); unmap_segment(three); unmap_segment(four); Seq_free(&SEG_MEMORY); Seq_free(&UNMAP_SEQ); }
void check_unmap(){ //These variable created for compiling sake Seq_T SEG_MEMORY = Seq_new(100); Seq_T UNMAP_SEQ = Seq_new(10); Umsegment_Id one = map_segment(10); Umsegment_Id two = map_segment(15); Umsegment_Id three = map_segment(20); Umsegment_Id four = map_segment(25); unmap_segment(two); if ((Umsegment_Id)(uintptr_t)Seq_remhi(UNMAP_SEQ) != 15) fprintf(stderr, "Unmapped id was not found in sequence"); Umsegment_Id five = map_segment(5); if(five != two) fprintf(stderr, "Unmapped id was not used"); unmap_segment(one); unmap_segment(five); unmap_segment(three); unmap_segment(four); Seq_free(&SEG_MEMORY); Seq_free(&UNMAP_SEQ); }
/* Input: a file pointer * Output: a Mem_T structure * Purpose: Initializes the Mem_T memory structure. Stores 32 bit words from * input into segment 0 in memory. This is location which holds the * instructions that the um will execute */ Mem_T Mem_new(FILE *input) { long unsigned lSize; uint32_t *buffer; size_t buffer_size; assert(input != NULL); Mem_T memory = malloc(sizeof(*memory)); assert(memory!=NULL); memory->segment_seq = Seq_new(0); memory->reusable_indices = Seq_new(0); /* determines length of input file */ fseek(input, 0, SEEK_END); lSize = ftell(input); rewind(input); /* creates buffer that will grab words from input*/ buffer = malloc(sizeof(uint32_t) * lSize/4); assert(buffer != NULL); buffer_size = fread(buffer, 4, lSize / 4, input); if(buffer_size != lSize/4){ fprintf(stderr, "Reading error\n"); } /* Program index will be 0*/ int programIndex = map_segment(memory, buffer_size); /*transfers instructions from buffer to segment 0 in memory*/ for(unsigned i = 0; i < 3; i++){ uint32_t word = buffer[i]; word = flip_word(word); fprintf(stderr, "word: %x\n", word); store_word(memory, word, programIndex, i); } free(buffer); return memory; }
void check_map_capcity(){ //These variable created for compiling sake Seq_T SEG_MEMORY = Seq_new(100); Seq_T UNMAP_SEQ = Seq_new(10); for (int i = 0; i < 2000; i++){ int size = rand() % 20; Umsegment_Id id = map_segment(size); (void) id; if (Seq_get(SEG_MEMORY, i) == NULL) fprintf(stderr, "Segment %d not mapped.\n", size); i++; } for (int j = 1999; j >= 0; j--){ unmap_segment((Umsegment_Id) j); if (Seq_get(SEG_MEMORY, j) != NULL) fprintf(stderr, "Segment %d not unmapped.\n", j); } Seq_free(&SEG_MEMORY); Seq_free(&UNMAP_SEQ); }
// Spawn a child process from a program image loaded from the file system. // prog: the pathname of the program to run. // argv: pointer to null-terminated array of pointers to strings, // which will be passed to the child as its command-line arguments. // Returns child envid on success, < 0 on failure. int spawn(const char *prog, const char **argv) { unsigned char elf_buf[512]; struct Trapframe child_tf; envid_t child; int fd, i, r; struct Elf *elf; struct Proghdr *ph; int perm; // This code follows this procedure: // // - Open the program file. // // - Read the ELF header, as you have before, and sanity check its // magic number. (Check out your load_icode!) // // - Use sys_exofork() to create a new environment. // // - Set child_tf to an initial struct Trapframe for the child. // // - Call the init_stack() function above to set up // the initial stack page for the child environment. // // - Map all of the program's segments that are of p_type // ELF_PROG_LOAD into the new environment's address space. // Use the p_flags field in the Proghdr for each segment // to determine how to map the segment: // // * If the ELF flags do not include ELF_PROG_FLAG_WRITE, // then the segment contains text and read-only data. // Use read_map() to read the contents of this segment, // and map the pages it returns directly into the child // so that multiple instances of the same program // will share the same copy of the program text. // Be sure to map the program text read-only in the child. // Read_map is like read but returns a pointer to the data in // *blk rather than copying the data into another buffer. // // * If the ELF segment flags DO include ELF_PROG_FLAG_WRITE, // then the segment contains read/write data and bss. // As with load_icode() in Lab 3, such an ELF segment // occupies p_memsz bytes in memory, but only the FIRST // p_filesz bytes of the segment are actually loaded // from the executable file - you must clear the rest to zero. // For each page to be mapped for a read/write segment, // allocate a page in the parent temporarily at UTEMP, // read() the appropriate portion of the file into that page // and/or use memset() to zero non-loaded portions. // (You can avoid calling memset(), if you like, if // page_alloc() returns zeroed pages already.) // Then insert the page mapping into the child. // Look at init_stack() for inspiration. // Be sure you understand why you can't use read_map() here. // // Note: None of the segment addresses or lengths above // are guaranteed to be page-aligned, so you must deal with // these non-page-aligned values appropriately. // The ELF linker does, however, guarantee that no two segments // will overlap on the same page; and it guarantees that // PGOFF(ph->p_offset) == PGOFF(ph->p_va). // // - Call sys_env_set_trapframe(child, &child_tf) to set up the // correct initial eip and esp values in the child. // // - Start the child process running with sys_env_set_status(). if ((r = open(prog, O_RDONLY)) < 0) return r; fd = r; // Read elf header elf = (struct Elf*) elf_buf; if (readn(fd, elf_buf, sizeof(elf_buf)) != sizeof(elf_buf) || elf->e_magic != ELF_MAGIC) { close(fd); cprintf("elf magic %08x want %08x\n", elf->e_magic, ELF_MAGIC); return -E_NOT_EXEC; } // Create new child environment if ((r = sys_exofork()) < 0) return r; child = r; // Set up trap frame, including initial stack. child_tf = envs[ENVX(child)].env_tf; child_tf.tf_eip = elf->e_entry; if ((r = init_stack(child, argv, &child_tf.tf_esp)) < 0) return r; // Set up program segments as defined in ELF header. ph = (struct Proghdr*) (elf_buf + elf->e_phoff); for (i = 0; i < elf->e_phnum; i++, ph++) { if (ph->p_type != ELF_PROG_LOAD) continue; perm = PTE_P | PTE_U; if (ph->p_flags & ELF_PROG_FLAG_WRITE) perm |= PTE_W; if ((r = map_segment(child, ph->p_va, ph->p_memsz, fd, ph->p_filesz, ph->p_offset, perm)) < 0) goto error; } close(fd); fd = -1; // Copy shared library state. if ((r = copy_shared_pages(child)) < 0) panic("copy_shared_pages: %e", r); if ((r = sys_env_set_trapframe(child, &child_tf)) < 0) panic("sys_env_set_trapframe: %e", r); if ((r = sys_env_set_status(child, ENV_RUNNABLE)) < 0) panic("sys_env_set_status: %e", r); return child; error: sys_env_destroy(child); close(fd); return r; }
extern void map(void *machine_p, unsigned B, unsigned C) { map_segment(machine_p, B, C); }
// Spawn a child process from a program image loaded from the file system. // prog: the pathname of the program to run. // argv: pointer to null-terminated array of pointers to strings, // which will be passed to the child as its command-line arguments. // Returns child envid on success, < 0 on failure. int spawn(const char *prog, const char **argv) { unsigned char elf_buf[512]; struct Trapframe child_tf; envid_t child; int fd, i, r; struct Elf *elf; struct Proghdr *ph; int perm; if ((r = open(prog, O_RDONLY)) < 0) return r; fd = r; // Read elf header elf = (struct Elf*) elf_buf; if (read(fd, elf_buf, sizeof(elf_buf)) != sizeof(elf_buf) || elf->e_magic != ELF_MAGIC) { close(fd); cprintf("elf magic %08x want %08x\n", elf->e_magic, ELF_MAGIC); return -E_NOT_EXEC; } // Create new child environment if ((r = sys_exofork()) < 0) return r; child = r; // Set up trap frame, including initial stack. child_tf = envs[ENVX(child)].env_tf; child_tf.tf_eip = elf->e_entry; if ((r = init_stack(child, argv, &child_tf.tf_esp)) < 0) return r; // Set up program segments as defined in ELF header. ph = (struct Proghdr*) (elf_buf + elf->e_phoff); for (i = 0; i < elf->e_phnum; i++, ph++) { if (ph->p_type != ELF_PROG_LOAD) continue; perm = PTE_P | PTE_U; if (ph->p_flags & ELF_PROG_FLAG_WRITE) perm |= PTE_W; if ((r = map_segment(child, ph->p_va, ph->p_memsz,fd, ph->p_filesz, ph->p_offset, perm)) < 0) goto error; //memset((void *)(ph->p_va+ph->p_filesz), 0, //(ph->p_memsz-ph->p_filesz)); } close(fd); fd = -1; if ((r = sys_env_set_trapframe(child, &child_tf)) < 0) panic("sys_env_set_trapframe: %e", r); if ((r = sys_env_set_status(child, ENV_RUNNABLE)) < 0) panic("sys_env_set_status: %e", r); return child; error: sys_env_destroy(child); close(fd); return r; }