/*
 * 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;
}
示例#2
0
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;
}
示例#3
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;
}
示例#4
0
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;
}
示例#5
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 */
    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;
}
示例#6
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;
}
示例#7
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();
}
示例#8
0
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;
}
示例#9
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;
}
示例#10
0
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;
}