/* * This is where we actually parse the memory map lines. */ static int mem_map_add_string(target_context_t *tc, const char *desc) { mem_region_t *mr = NULL; char *ptr = NULL, *s = NULL, *tok; int i = 0; mr = region_new(); /* strtok_r modifies its first argument, so we duplicate 'desc' before using it */ for (s = xstrdup(desc); #ifndef WIN32 (tok = strtok_r(ptr ? NULL : s, " \t\n", &ptr)); #else (tok = strtok(ptr ? NULL : s, " \t\n")); #endif /* nada */) { #ifdef WIN32 ptr = (ptr ? ptr : s) + strlen (tok) + 1; #endif /* order of tokens is fixed */ switch (i++) { case 0: if (parse_addrs(mr, tok) < 0) goto failure; break; case 1: mr->type = region_type(tok); if (mr->type == MEMTYPE_INVALID) goto failure; break; case 2: /* name is always valid */ mr->name = xstrdup(tok); break; default: /* there can be any number of options */ if (parse_opt(mr, tok) < 0) goto failure; } } if (i < 3) goto failure; mem_map_add(tc, mr); free(s); return 0; failure: if (tok) bad_desc(desc, desc + (tok - s)); else bad_desc(desc, desc + strlen(desc)); free(mr); free(s); return -1; }
int monte_load_linux_initrd(struct monte_boot_t *boot, const void *buffer, long size) { long initrd_addr; void *ramdisk_data; struct monte_region_t *region; /*--- XXX Disgusting hack --------------------------------------------- * We can't tell how big memory is very easily from user space. * /proc/meminfo is close but a pain to read. In stead we just * stat /proc/kcore. This seems easiest and comes closest to the * correct answer. What a mess. *-------------------------------------------------------------------*/ struct stat buf; if (stat("/proc/kcore", &buf) == -1) { buf.st_size = 32*1024*1024; /* a random guess if /proc isn't mounted.*/ } initrd_addr = ((buf.st_size/4)*3) & PAGE_MASK; /* Next problem: We don't know how big this ram disk image is a * head of time so just start loading a page at a time :P */ region = region_new(boot, (void *) initrd_addr); ramdisk_data = region_size(region, size); memcpy(ramdisk_data, buffer, size); printf("monte: initial ramdisk: %8ld bytes at %p\n", size, (void *)initrd_addr); /* Put the right bits in RAM so the kernel will find the initrd */ #if defined(__i386__) boot->setup->ramdisk = initrd_addr; boot->setup->ramdisk_size = size; #elif defined(__alpha__) region = region_new(boot, (void *) __pa(boot->param.entrypoint - 0x6000)); ramdisk_data = region_size(region, PAGE_SIZE); ramdisk_data += 0x100; ((long*)ramdisk_data)[0] = __va(initrd_addr); ((long*)ramdisk_data)[1] = size; #else #error No initrd argument placement code for this architecture. #endif return 0; }
static int calculate_highlight_region (Window wp, Region *rp) { if ((wp != cur_wp && !get_variable_bool ("highlight-nonselected-windows")) || get_buffer_mark (get_window_bp (wp)) == NULL || !get_buffer_mark_active (get_window_bp (wp))) return false; *rp = region_new (window_o (wp), get_marker_o (get_buffer_mark (get_window_bp (wp)))); return true; }
region_table_t *parse_regions(char *input_regions, int as_positions, const char *url, const char *species, const char *version) { region_table_t *regions_table = new_region_table_from_ws(url, species, version); char *saveptr, *token; size_t token_len; int num_regions; char **regions_data = split(input_regions, ",", &num_regions); region_t *regions[num_regions]; for (int i = 0; i < num_regions; i++) { // Set chromosome token = strtok_r(regions_data[i], ":", &saveptr); token_len = strlen(token); char *chromosome = strndup(token, token_len); // Set start position token = strtok_r(NULL, "-", &saveptr); size_t start_position, end_position; start_position = (token != NULL) ? atol(token) : 1; // Set end position token = strtok_r(NULL, "-", &saveptr); if (token != NULL) { end_position = atol(token); } else { if (as_positions) { end_position = start_position; } else { end_position = UINT_MAX; } } regions[i] = region_new(chromosome, start_position, end_position, NULL, NULL); LOG_DEBUG_F("region '%s:%u-%u'\n", regions[i]->chromosome, regions[i]->start_position, regions[i]->end_position); } insert_regions(regions, num_regions, regions_table); finish_region_table_loading(regions_table); for (int i = 0; i < num_regions; i++) { free(regions_data[i]); free(regions[i]); } free(regions_data); return regions_table; }
int monte_load_linux_command_line(struct monte_boot_t *boot, char *cmdline) { struct monte_region_t *region; char *cmd_line; /* Setup the kernel command line */ region = region_new(boot, (void *) MONTE_CMDLINE_BEGIN); cmd_line = region_size(region, PAGE_SIZE); boot->setup->cmd_line_ptr = MONTE_CMDLINE_BEGIN; boot->setup->cmd_magic = CMDLINE_MAGIC; boot->setup->cmd_offset = MONTE_CMDLINE_BEGIN - MONTE_SETUP_BEGIN; strcpy(cmd_line, cmdline); printf("monte: command line : \"%s\"\n", cmdline); return 0; }
int monte_load_linux_command_line(struct monte_boot_t *boot, char *cmdline) { struct monte_region_t *region; char *cmd_line; /* Setup the kernel command line */ /* On alpha, the command line sits in the zero page at address * ?0a000 which is in the region before the kernel entry * point... Also, one page should be enough for it.*/ region = region_new(boot, (void *) __pa(boot->param.entrypoint - 0x6000)); cmd_line = region_size(region, PAGE_SIZE); strcpy(cmd_line, cmdline); printf("monte: command line : \"%s\"\n", cmdline); return 0; }
// Picks a language and perform string initialization based on the chosen language. void nov_region_init(const char *language) { ASSERT(language != NULL, "Crash in nov_region_init() due to empty parameters being passed. This should not happen!"); // Detect supported languages. region_new(); region_scan(); bool b = region_set_language(language); if(b) { game_log_write( str_printf( NULL, "Language successfully set to %s", _chr(region_get_language()) ) ); } localized_init(); }
static int load_elf_image(struct monte_boot_t *boot, const void *buffer, long size) { int i; Elf64_Ehdr *ehdr; Elf64_Phdr *phdr; struct monte_region_t *region; void *kernimage; /* Super simple ELF loader that makes gobs of assumptions that * won't be valid anywhere except Linux ELF kernel images */ ehdr = (Elf64_Ehdr *) buffer; if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0) { fprintf(stderr, "not an ELF file.\n"); return -1; } if (ehdr->e_ident[EI_CLASS] != ELFCLASS64) { fprintf(stderr, "ELF object is not an ELF64 object.\n"); return -1; } phdr = (Elf64_Phdr *)(buffer + ehdr->e_phoff); for (i=0; i < ehdr->e_phnum; i++) { /* Load a program section */ /* Setup a region for this thing */ region = region_new(boot, (void*)__pa(phdr[i].p_vaddr)); kernimage = region_size(region, phdr[i].p_memsz+(1024*PAGE_SIZE)); /* Load data and zero the rest (BSS) */ printf("monte: kernel code : %8ld bytes at %p\n", phdr[i].p_filesz, (void*) __pa(phdr[i].p_vaddr)); memcpy(kernimage, buffer + phdr[i].p_offset, phdr[i].p_filesz); memset(kernimage + phdr[i].p_filesz, 0, phdr[i].p_memsz - phdr[i].p_filesz); } boot->param.entrypoint = ehdr->e_entry; printf("monte: entry point : %p\n", (void*)boot->param.entrypoint); return 0; }
region_table_t *parse_regions_from_gff_file(char *filename, const char *url, const char *species, const char *version) { gff_file_t *file = gff_open(filename); if (file == NULL) { return NULL; } region_table_t *regions_table = new_region_table_from_ws(url, species, version); int ret_code = 0; size_t max_batches = 20, batch_size = 2000; list_t *read_list = (list_t*) malloc (sizeof(list_t)); list_init("batches", 1, max_batches, read_list); #pragma omp parallel sections { // The producer reads the GFF file #pragma omp section { LOG_DEBUG_F("Thread %d reads the GFF file\n", omp_get_thread_num()); ret_code = gff_read_batches(read_list, batch_size, file); list_decr_writers(read_list); if (ret_code) { LOG_FATAL_F("Error while reading GFF file %s (%d)\n", filename, ret_code); } } // The consumer inserts regions in the structure #pragma omp section { list_item_t *item = NULL; gff_batch_t *batch; gff_record_t *record; region_t *regions_batch[REGIONS_CHUNKSIZE]; int avail_regions = 0; while ( item = list_remove_item(read_list) ) { batch = item->data_p; // For each record in the batch, generate a new region for (int i = 0; i < batch->records->size; i++) { record = batch->records->items[i]; region_t *region = region_new(strndup(record->sequence, record->sequence_len), record->start, record->end, record->strand ? strndup(&record->strand, 1) : NULL, record->feature ? strndup(record->feature, record->feature_len) : NULL); LOG_DEBUG_F("region '%s:%u-%u'\n", region->chromosome, region->start_position, region->end_position); regions_batch[avail_regions++] = region; // Save when the recommended size is reached if (avail_regions == REGIONS_CHUNKSIZE) { insert_regions(regions_batch, avail_regions, regions_table); for (int i = 0; i < avail_regions; i++) { free(regions_batch[i]); } avail_regions = 0; } } gff_batch_free(batch); list_item_free(item); } // Save the remaining regions that did not fill a batch if (avail_regions > 0) { insert_regions(regions_batch, avail_regions, regions_table); for (int i = 0; i < avail_regions; i++) { free(regions_batch[i]); } avail_regions = 0; } } } finish_region_table_loading(regions_table); list_free_deep(read_list, NULL); gff_close(file, 1); return regions_table; }
int monte_load_linux_kernel(struct monte_boot_t *boot, const void *buffer, long size){ void *setup_data, *kernel_data; struct monte_region_t *region; struct kernel_setup_t *stmp; stmp = (struct kernel_setup_t *)buffer; /* Sanity check */ /* Check for the kernel setup signature */ if (stmp->boot_flag != BS_SIG_VAL) { fprintf(stderr, "monte: Boot signature not found.\n"); return -1; } /* Sanity check number of sectors */ if (stmp->setup_sects > MAX_SETUP_SECTS) { fprintf(stderr, "monte: number of setup sectors too large: %d" " (max %d)\n",(int) stmp->setup_sects, MAX_SETUP_SECTS); return -1; } /* Check for that setup signature. */ if (strncmp(stmp->signature, SETUP_SIG_VAL, strlen(SETUP_SIG_VAL)) != 0) { fprintf(stderr, "monte: Kernel image setup signature not found.\n"); return -1; } /* Setup the region for the setup code */ region = region_new(boot, (void *)MONTE_SETUP_BEGIN); setup_data = region_size(region, (stmp->setup_sects+1)*512); boot->setup = setup_data; memcpy(setup_data, buffer, (stmp->setup_sects+1)*512); printf("monte: kernel setup : %8d bytes at %p\n", ((int) stmp->setup_sects)*512, (void*)MONTE_SETUP_BEGIN); buffer += (stmp->setup_sects+1)*512; /* update buffer pointers */ size -= (stmp->setup_sects+1)*512; /* The number of kernel "paragraphs" is getting overflowed by * todays kernels. Ignore it and just load the rest of the data * we have. */ region = region_new(boot, (void*)boot->setup->start); kernel_data = region_size(region, size); memcpy(kernel_data, buffer, size); printf("monte: kernel code : %8d bytes at %p\n", (int) size, (void *) boot->setup->start); if (boot->param.flags & MONTE_PROTECTED) { if (save_old_setup(boot)) return -1; boot->param.entrypoint = boot->setup->start; } else boot->param.entrypoint = 0x90200000; /* Real mode 9020:0000 */ /* XXXXX FIX ME XXXXXX THIS IS A HACK!!! XXXXXX */ if (boot->param.entrypoint == 0) { printf("monte: Forcing entry point to 0x100000\n"); boot->param.entrypoint = 0x100000; } /* XXXXX FIX ME XXXXXX THIS IS A HACK!!! XXXXXX */ boot->setup->loader = 0x50; /* Set the loader type. */ boot->setup->ramdisk = 0; boot->setup->ramdisk_size = 0; boot->setup->cmd_magic = 0; boot->setup->cmd_offset = 0; return 0; }
/* * Flash map is a string like "2x16K/l,6x16K,63x128K", where "2x16K" * means "two blocks of size 16 Kbytes each", and the "/l" is a flag * meaning "locked" (used for boot blocks which can't be programmed * without special intervention). Possible size suffixes are none * (bytes), "K" (kilobytes), and "M" (megabytes). Parse with a little * state machine, and add the blocks as a mem_region_t chain that's a * child of the given one. */ int flash_parse_map(mem_region_t *mr, const char *map) { enum state { S_NBLOCKS, S_SIZE, S_FLAGS, S_END } state = S_NBLOCKS; mem_region_t *cur = mr; int nblocks = 0; tsize_t size = 0; taddr_t vma, lma; unsigned flags = 0; const char *p; assert(mr); vma = mr->vma; lma = mr->lma; assert(map); /* clear out prior flash blocks */ region_destroy(mr->children); mr->children = NULL; p = map; goto loop; do { ++p; loop: if (isspace(*p)) continue; switch (state) { case S_NBLOCKS: if (isdigit(*p)) { nblocks = (nblocks * 10) + (*p - '0'); } else if (*p == 'x') { state = S_SIZE; } else { bad_map(map, p); goto failure; } break; case S_SIZE: switch (*p) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': size = (size * 10) + (*p - '0'); break; case 'K': size *= 1024; break; case 'M': size *= (1024 * 1024); break; case '/': state = S_FLAGS; break; case ',': case '\0': state = S_END; break; default: bad_map(map, p); goto failure; } break; case S_FLAGS: switch (*p) { case 'l': flags |= MRF_LOCKED; break; case ',': case '\0': state = S_END; break; default: bad_map(map, p); goto failure; } break; default: assert(0); } if (state == S_END) { /* * Create one mem_region_t for each flash * block, and link them into a chain. */ while (nblocks--) { mem_region_t *tmp = region_new(); tmp->name = xstrdup("(anonymous flash block)"); tmp->type = MEMTYPE_FLASH; tmp->size = size; tmp->flags = flags; tmp->bufsize = mr->bufsize; tmp->vma = vma; vma += size; tmp->lma = lma; lma += size; if (cur == mr) { mr->children = tmp; cur = tmp; } else { cur->next = tmp; cur = tmp; } } if(flags != 0) mr->flags |= flags; state = S_NBLOCKS; nblocks = 0; size = 0; flags = 0; } } while (*p); return 0; failure: region_destroy(mr->children); mr->children = NULL; return -1; }