void StreamVm::build_bss() { alloc_bss(); uint8_t * p=(uint8_t *)m_bss; if ( m_is_random_var ){ *((uint32_t*)p)=rand(); p+=sizeof(uint32_t); } for (auto inst : m_inst_list) { if ( inst->get_instruction_type() == StreamVmInstruction::itFLOW_MAN ){ StreamVmInstructionFlowMan * ins_man=(StreamVmInstructionFlowMan *)inst; switch (ins_man->m_size_bytes) { case 1: *p=(uint8_t)ins_man->get_bss_init_value(); p+=1; break; case 2: *((uint16_t*)p)=(uint16_t)ins_man->get_bss_init_value(); p+=2; break; case 4: *((uint32_t*)p)=(uint32_t)ins_man->get_bss_init_value(); p+=4; break; case 8: *((uint64_t*)p)=(uint64_t)ins_man->get_bss_init_value(); p+=8; break; default: assert(0); } } if ( inst->get_instruction_type() == StreamVmInstruction::itFLOW_CLIENT ){ StreamVmInstructionFlowClient * ins_man=(StreamVmInstructionFlowClient *)inst; if (ins_man->m_client_min>0) { *((uint32_t*)p)=(uint32_t)(ins_man->m_client_min-1); }else{ *((uint32_t*)p)=(uint32_t)ins_man->m_client_min; } p+=4; if (ins_man->is_unlimited_flows() ) { *((uint16_t*)p)=StreamDPOpClientsUnLimit::CLIENT_UNLIMITED_MIN_PORT; }else{ *((uint16_t*)p)=(uint16_t)ins_man->m_port_min; } p+=2; *((uint32_t*)p)=0; p+=4; } } }
void elf_load_file(char* name, FILE* elf, char** argv) { //find file size fseek(elf, 0, SEEK_END); uint32_t binary_size = ftell(elf); fseek(elf, 0, SEEK_SET); char* filebuf = kmalloc(binary_size); for (uint32_t i = 0; i < binary_size; i++) { filebuf[i] = fgetc(elf); } elf_header* hdr = (elf_header*)filebuf; if (!elf_validate_header(hdr)) { return; } uint32_t new_dir_phys = 0; page_directory_t* new_dir = kmalloc_ap(sizeof(page_directory_t), &new_dir_phys); memset((uint8_t*)new_dir, 0, sizeof(page_directory_t)); //get offset of tablesPhysical from start of page_directory_t uint32_t offset = (uint32_t)new_dir->tablesPhysical - (uint32_t)new_dir; new_dir->physicalAddr = new_dir_phys + offset; for (int i = 0; i < 1024; i++) { new_dir->tables[i] = page_dir_kern()->tables[i]; new_dir->tablesPhysical[i] = page_dir_kern()->tablesPhysical[i] & ~4; } char* string_table = elf_get_string_table(hdr, binary_size); uint32_t prog_break = 0; uint32_t bss_loc = 0; for (int x = 0; x < hdr->shentsize * hdr->shnum; x += hdr->shentsize) { if (hdr->shoff + x > binary_size) { printf("Tried to read beyond the end of the file.\n"); return; } elf_s_header* shdr = (elf_s_header*)((uintptr_t)filebuf + (hdr->shoff + x)); char* section_name = (char*)((uintptr_t)string_table + shdr->name); //alloc memory for .bss segment if (!strcmp(section_name, ".bss")) { alloc_bss(new_dir, shdr, (int*)&prog_break, (int*)&bss_loc); } } uint32_t entry = elf_load_small(new_dir, (unsigned char*)filebuf); kfree(filebuf); //alloc stack space uint32_t stack_addr = 0x10000000; //give user program a 128kb stack for (int i = 0; i < 32; i++) { page_t* stacktop = get_page(stack_addr, 1, new_dir); //user, writeable alloc_frame(stacktop, 0, 1); stack_addr += PAGE_SIZE; } stack_addr -= PAGE_SIZE; //calculate argc count int argc = 0; while (argv[argc] != NULL) { argc++; } if (entry) { become_first_responder(); kernel_begin_critical(); task_t* elf = task_with_pid(getpid()); elf->prog_break = prog_break; elf->bss_loc = bss_loc; elf->name = strdup(name); elf->esp = elf->ebp = stack_addr; elf->eip = entry; elf->page_dir = new_dir; void goto_pid(int id, bool x); goto_pid(elf->id, false); /* int(*elf_main)(int, char**) = (int(*)(int, char**))entry; become_first_responder(); //calculate argc count int argc = 0; char* tmp = argv[argc]; while (argv[argc] != NULL) { argc++; } //jump to ELF entry point! int ret = elf_main(argc, argv); */ //binary should have called _exit() //if we got to this point, something went catastrophically wrong ASSERT(0, "ELF binary returned execution to loader!"); } else { printf_err("ELF wasn't loadable!"); return; } }