//*************************************************************
//
// Parse the GPS buffer and store information in the struct.
//
// You may notice this: (index%BUFFERSIZE) in multiple places.
// If our index exceeds our BUFFERSIZE then the modulus will
// allow us to wrap around and start at the beginning of our
// circular array.
//
//*************************************************************
void parse_gps_data(void)
{
  uint32_t index = 0;

  char *buffer = gps_buffer;

  while (index <= BUFFERSIZE){

    if (*(buffer + index) != '$'){
      index++;
      continue;
    }
    parse_code(buffer, ++index);
//    break;
  }
}
示例#2
0
int generate_for_item(Pool *pool, FILE *out, AstFor *p, ListNode *item, int *need_comma)
{
  Scope *scope = scope_new(pool, p->scope);
  ListBuilder code = list_builder_init(pool);

  if (dynamic_ok(p->filter) &&
    !test_filter(p->filter, ast_to_outline_item(item->d)))
    return 1;

  if (p->list && *need_comma)
    CHECK(file_putc(out, ','));
  *need_comma = 1;

  scope_add(scope, pool, p->item, item->d);
  CHECK(parse_code(pool, &p->code, scope, out_list_builder(&code)));
  CHECK(generate_code(pool, out, code.first));
  return 1;
}
示例#3
0
文件: parser.cpp 项目: kdt3rd/gecko
void parser::parse_text( std::istream &in )
{
	while ( !in.eof() && in )
	{
		int c = in.get();
		if ( std::char_traits<char>::not_eof( c ) )
		{
			if ( c == '[' )
			{
				switch ( in.peek() )
				{
					case '[':
						_func.push_text();
						parse_expr( in );
						break;

					case '%':
						_func.push_text( true );
						parse_code( in );
						break;

					case '#':
						_func.push_text( true );
						parse_directive( in );
						break;

					case '/':
						_func.push_text( true );
						parse_comment( in );
						break;

					default:
						_func.add( static_cast<char>( c ) );
						break;
				}
			}
			else
				_func.add( static_cast<char>( c ) );
		}
	}
	_func.push_text();
}
示例#4
0
int main(int argc, char* argv[])
{
        int input_len;
        char *code;
        bool code_ok;

        code = argv[1];

        code_ok = validate_code_input(code);
        if (!code_ok) {
                exit(EXIT_FAILURE);
        }

        // This does it for both code length and program length
        input_len = strlen(code);

        cmd_t *program = parse_code(argv[1], input_len);
        execute_program(program, input_len);

        return 0;
}
示例#5
0
int generate_macro_call(Pool *pool, FILE *out, AstMacroCall *p)
{
  ListNode *call_input;
  ListNode *macro_input;
  Scope *scope = scope_new(pool, p->macro->scope);
  ListBuilder code = list_builder_init(pool);

  /* Assign values to all inputs: */
  macro_input = p->macro->inputs;
  call_input = p->inputs;
  while (macro_input && call_input) {
    AstCodeText *name = macro_input->d.p;
    scope_add(scope, pool, name->code, call_input->d);

    macro_input = macro_input->next;
    call_input = call_input->next;
  }

  CHECK(parse_code(pool, &p->macro->code, scope, out_list_builder(&code)));
  CHECK(generate_code(pool, out, code.first));
  return 1;
}
示例#6
0
static error_t parse_opt(int k, char *arg, struct argp_state *state)
{
	char *p;
	long key;
	int rc;

	switch (k) {
	case 'v':
		debug++;
		break;
	case 't':
		test++;
		break;
	case 'c':
		clear++;
		break;
	case 'D':
		delay = atoi(arg);
		break;
	case 'P':
		period = atoi(arg);
		break;
	case 'd':
		devicename = arg;
		break;
	case 's':
		devclass = arg;
		break;
	case 'r':
		readtable++;
		break;
	case 'w': {
		char *name = NULL;

		rc = parse_keyfile(arg, &name);
		if (rc)
			goto err_inval;
		if (name)
			fprintf(stderr, "Read %s table\n", name);
		break;
	}
	case 'a': {
		rc = parse_cfgfile(arg);
		if (rc)
			goto err_inval;
		break;
	}
	case 'k':
		p = strtok(arg, ":=");
		do {
			if (!p)
				goto err_inval;
			nextkey->codes[0] = strtoul(p, NULL, 0);
			if (errno)
				goto err_inval;

			p = strtok(NULL, ",;");
			if (!p)
				goto err_inval;
			key = parse_code(p);
			if (key == -1) {
				key = strtol(p, NULL, 0);
				if (errno)
					goto err_inval;
			}
			nextkey->codes[1] = key;

			if (debug)
				fprintf(stderr, "scancode 0x%04x=%u\n",
					nextkey->codes[0], nextkey->codes[1]);

			nextkey->next = calloc(1, sizeof(keys));
			if (!nextkey->next) {
				perror("No memory!\n");
				return ENOMEM;
			}
			nextkey = nextkey->next;

			p = strtok(NULL, ":=");
		} while (p);
		break;
	case 'p':
		p = strtok(arg, ",;");
		do {
			if (!p)
				goto err_inval;
			if (!strcasecmp(p,"rc5") || !strcasecmp(p,"rc-5"))
				ch_proto |= RC_5;
			else if (!strcasecmp(p,"rc6") || !strcasecmp(p,"rc-6"))
				ch_proto |= RC_6;
			else if (!strcasecmp(p,"nec"))
				ch_proto |= NEC;
			else if (!strcasecmp(p,"jvc"))
				ch_proto |= JVC;
			else if (!strcasecmp(p,"sony"))
				ch_proto |= SONY;
			else if (!strcasecmp(p,"sanyo"))
				ch_proto |= SANYO;
			else if (!strcasecmp(p,"lirc"))
				ch_proto |= LIRC;
			else if (!strcasecmp(p,"rc-5-sz"))
				ch_proto |= RC_5_SZ;
			else if (!strcasecmp(p,"sharp"))
				ch_proto |= RC_5_SZ;
			else if (!strcasecmp(p,"mce-kbd"))
				ch_proto |= RC_5_SZ;
			else if (!strcasecmp(p,"xmp"))
				ch_proto |= XMP;
			else if (!strcasecmp(p,"all"))
				ch_proto |= ~0;
			else
				goto err_inval;
			p = strtok(NULL, ",;");
		} while (p);
		break;
	default:
		return ARGP_ERR_UNKNOWN;
	}
	return 0;

err_inval:
	fprintf(stderr, "Invalid parameter(s)\n");
	return ARGP_ERR_UNKNOWN;

}
示例#7
0
static error_t parse_keyfile(char *fname, char **table)
{
	FILE *fin;
	int value, line = 0;
	char *scancode, *keycode, s[2048];

	*table = NULL;

	if (debug)
		fprintf(stderr, "Parsing %s keycode file\n", fname);

	fin = fopen(fname, "r");
	if (!fin) {
		return errno;
	}

	while (fgets(s, sizeof(s), fin)) {
		char *p = s;

		line++;
		while (*p == ' ' || *p == '\t')
			p++;
		if (line==1 && p[0] == '#') {
			p++;
			p = strtok(p, "\n\t =:");
			do {
				if (!p)
					goto err_einval;
				if (!strcmp(p, "table")) {
					p = strtok(NULL,"\n, ");
					if (!p)
						goto err_einval;
					*table = malloc(strlen(p) + 1);
					strcpy(*table, p);
				} else if (!strcmp(p, "type")) {
					p = strtok(NULL, " ,\n");
					do {
						if (!p)
							goto err_einval;
						if (!strcasecmp(p,"rc5") || !strcasecmp(p,"rc-5"))
							ch_proto |= RC_5;
						else if (!strcasecmp(p,"rc6") || !strcasecmp(p,"rc-6"))
							ch_proto |= RC_6;
						else if (!strcasecmp(p,"nec"))
							ch_proto |= NEC;
						else if (!strcasecmp(p,"jvc"))
							ch_proto |= JVC;
						else if (!strcasecmp(p,"sony"))
							ch_proto |= SONY;
						else if (!strcasecmp(p,"sanyo"))
							ch_proto |= SANYO;
						else if (!strcasecmp(p,"rc-5-sz"))
							ch_proto |= RC_5_SZ;
						else if (!strcasecmp(p,"sharp"))
							ch_proto |= SHARP;
						else if (!strcasecmp(p,"mce-kbd"))
							ch_proto |= MCE_KBD;
						else if (!strcasecmp(p,"xmp"))
							ch_proto |= XMP;
						else if (!strcasecmp(p,"other") || !strcasecmp(p,"unknown"))
							ch_proto |= OTHER;
						else {
							fprintf(stderr, "Protocol %s invalid\n", p);
							goto err_einval;
						}
						p = strtok(NULL, " ,\n");
					} while (p);
				} else {
					goto err_einval;
				}
				p = strtok(NULL, "\n\t =:");
			} while (p);
			continue;
		}

		if (*p == '\n' || *p == '#')
			continue;

		scancode = strtok(p, "\n\t =:");
		if (!scancode)
			goto err_einval;
		if (!strcasecmp(scancode, "scancode")) {
			scancode = strtok(NULL, "\n\t =:");
			if (!scancode)
				goto err_einval;
		}

		keycode = strtok(NULL, "\n\t =:(");
		if (!keycode)
			goto err_einval;

		if (debug)
			fprintf(stderr, "parsing %s=%s:", scancode, keycode);
		value = parse_code(keycode);
		if (debug)
			fprintf(stderr, "\tvalue=%d\n", value);

		if (value == -1) {
			value = strtol(keycode, NULL, 0);
			if (errno)
				perror("value");
		}

		nextkey->codes[0] = (unsigned) strtoul(scancode, NULL, 0);
		nextkey->codes[1] = (unsigned) value;
		nextkey->next = calloc(1, sizeof(*nextkey));
		if (!nextkey->next) {
			perror("parse_keyfile");
			return ENOMEM;
		}
		nextkey = nextkey->next;
	}
	fclose(fin);

	return 0;

err_einval:
	fprintf(stderr, "Invalid parameter on line %d of %s\n",
		line, fname);
	return EINVAL;

}
示例#8
0
文件: peg.c 项目: ctelfer/catlib
static int parse_primary(struct peg_grammar_parser *pgp, struct peg_cursor *pc,
			 int *prip)
{
	struct peg_grammar *peg = pgp->peg;
	int pri;
	int rv;
	int match = -1;
	struct peg_cursor npc = *pc;
	int prefix = PEG_ATTR_NONE;
	int suffix = PEG_ATTR_NONE;
	int action = PEG_ACT_NONE;
	struct raw r = { 0, NULL };
	struct peg_node *pn;

	if ( string_match(pgp, "&", &npc) )
		prefix = PEG_ATTR_AND;
	else if ( string_match(pgp, "!", &npc) )
		prefix = PEG_ATTR_NOT;

	if ( (rv = parse_id_and_not_arrow(pgp, &npc, &match)) != 0 ) {
		if ( rv < 0 )
			goto err;
	} else if ( (rv = parse_paren_expr(pgp, &npc, &match)) != 0 ) {
		if ( rv < 0 )
			goto err;
	} else if ( (rv = parse_literal(pgp, &npc, &match)) != 0 ) {
		if ( rv < 0 )
			goto err;
	} else if ( (rv = parse_class(pgp, &npc, &match)) != 0 ) {
		if ( rv < 0 )
			goto err;
	} else {
		if ( prefix == PEG_ATTR_NONE )
			return 0;
		pgp->err = PEG_ERR_BAD_PRIMARY;
		pgp->eloc = *pc;
		return -1;
	}

	pri = peg_node_new(peg, PEG_PRIMARY, pc->line);
	if ( pri < 0 ) {
		pgp->err = PEG_ERR_NOMEM;
		goto err;
	}

	if ( string_match(pgp, "?", &npc) )
		suffix = PEG_ATTR_QUESTION;
	else if ( string_match(pgp, "*", &npc) )
		suffix = PEG_ATTR_STAR;
	else if ( string_match(pgp, "+", &npc) )
		suffix = PEG_ATTR_PLUS;
	else
		suffix = PEG_ATTR_NONE;

	rv = parse_code(pgp, &npc, &r);
	if ( rv < 0 )
		goto err;
	if ( rv > 0 ) {
		action = PEG_ACT_CODE;
	} else {
		rv = parse_action_label(pgp, &npc, &r);
		if ( rv < 0 )
			goto err;
		if ( rv > 0 )
			action = PEG_ACT_LABEL;
	}

	pn = NODE(peg, pri);
	pn->pn_next = -1;
	pn->pp_match = match;
	pn->pp_prefix = prefix;
	pn->pp_suffix = suffix;
	pn->pp_action = action;
	pn->pn_action_cb = NULL;
	pn->pp_code = r;

	*pc = npc;
	*prip = pri;
	return 1;

err:
	peg_node_free(peg, match);
	return -1;
}
示例#9
0
/**
 * Program entry point. Constructs and launches the main program object.
 */
int main(int argc, char *argv[])
{
    Pool pool = pool_init(0x10000); /* 64K block size */
    Options opt = options_init();
    Source *in;
    Scope *scope = scope_new(&pool, 0);
    ListBuilder code = list_builder_init(&pool);

    /* Read the options: */
    if (!options_parse(&opt, argc, argv)) {
        options_usage(argv[0]);
        goto error;
    }

    /* Determine output file name: */
    if (!string_size(opt.name_out)) {
        if (string_rmatch(opt.name_in, string_from_k(".ol")) != 3) {
            fprintf(stderr, "error: If no output file is specified, the input file name must end with \".ol\".\n");
            goto error;
        }
        opt.name_out = string(opt.name_in.p, opt.name_in.end - 3);
    }

    /* Input stream: */
    in = source_load(&pool, opt.name_in);
    if (!in) {
        fprintf(stderr, "error: Could not open source file \"%s\"\n", opt.name_in.p);
        goto error;
    }

    /* Keywords: */
    scope_add(scope, &pool, string_from_k("macro"), dynamic(type_keyword,
              keyword_new(&pool, parse_macro)));
    scope_add(scope, &pool, string_from_k("outline"), dynamic(type_keyword,
              keyword_new(&pool, parse_outline)));
    scope_add(scope, &pool, string_from_k("union"), dynamic(type_keyword,
              keyword_new(&pool, parse_union)));
    scope_add(scope, &pool, string_from_k("map"), dynamic(type_keyword,
              keyword_new(&pool, parse_map)));
    scope_add(scope, &pool, string_from_k("for"), dynamic(type_keyword,
              keyword_new(&pool, parse_for)));
    scope_add(scope, &pool, string_from_k("include"), dynamic(type_keyword,
              keyword_new(&pool, parse_include)));

    /* Do outline2c stuff: */
    if (!parse_code(&pool, in, scope, out_list_builder(&code))) goto error;
    if (opt.debug) {
        printf("--- AST: ---\n");
        dump_code(code.first, 0);
        printf("\n");
    }
    if (!main_generate(&pool, code.first, &opt)) goto error;

    /* Clean up: */
    pool_free(&pool);
    return 0;

error:
    pool_free(&pool);
    return 1;
}
示例#10
0
文件: main.c 项目: interfector/llxcc
/* Creates the contents of the various parts of the object file.
 */
static int
populateparts(blueprint const *bp, int codetype, char const *filename )
{
    if (bp->parts[P_COMMENT].shtype)
    {
        bp->parts[P_COMMENT].shname = ".comment";
        bp->parts[P_COMMENT].size = sizeof comment;
        xstrndup(bp->parts[P_COMMENT].part, comment, sizeof comment);
    }

    if (bp->parts[P_SYMTAB].shtype)
        addtosymtab(bp->parts + P_SYMTAB, srcfilename, STB_LOCAL, STT_FILE, SHN_ABS);

    mach_buf = bp->parts[P_TEXT].part;
    mach_size = bp->parts[P_TEXT].size;

    parse_code( bp, filename  );

    bp->parts[P_TEXT].size = pos;
    bp->parts[P_TEXT].part = mach_buf;
    bp->parts[P_DATA].size = 1000;

    if (!(bp->parts[P_DATA].part = calloc(1000, 1)))
        return 0;

    bp->parts[P_DATA].part = mach_buf;

    addrelocations(bp, ET_EXEC, functionname);

    fillparts(bp);

    if (!computeoffsets(bp))
        return 0;

#ifdef _DEBUG
    printf("0x%x\n", bp->parts[P_TEXT].addr );
#endif

    int i, addr;
    char call[] = { 0xe8, 0xde, 0xad, 0xc0, 0xde };
    char mov[] = { 0xbf, 0xde, 0xad, 0xc0, 0xde };
    char* text = bp->parts[P_TEXT].part;

    for(i = 0; i < pos; i++) {
        if(!memcmp( text+i, call, 5 )) {
            addr = exec_table_pos - (i + 5);
            memcpy( text+i+1, &addr, sizeof(int));
        }
    }

    for(i = 0; i < pos; i++) {
        if(!memcmp( text+i, mov, 5 )) {
            addr = table_pos + bp->parts[P_TEXT].addr;
            memcpy( text+i+1, &addr, sizeof(int));
        }
    }

    for(i = 0; i < LEN; i++)
    {
        table[i] += bp->parts[P_TEXT].addr;

        memcpy( text + table_pos + (i*4), &table[i], sizeof(int));

#ifdef _DEBUG
        printf("table[%d]:\t0x%x\n", i, table[i] );
#endif
    }

    createfixups(bp, codetype, functionname);

    completeparts(bp);

    return 1;
}
示例#11
0
void parser_test()
{

		const wchar_t	*gmr_txt;
		cfgConfig_t		*cfg;

		char buf[1024];

		AR_printf(L"%ls\r\n", L"Please enter pattern path!");
		//__gets_chk(buf,1024);
                getchar();
    //gmr_txt = __load_txt(DEF_PAT_PATH);

		gmr_txt = __load_txt(buf);

		if(gmr_txt == NULL)
		{
				AR_abort();
		}


		cfg = CFG_CollectGrammarConfig(gmr_txt, &__g_report);


		if(cfg)
		{


#if(1)
				size_t i;

				AR_printf(L"----------------------\r\n");
				for(i = 0; i < cfg->name_cnt; ++i)
				{
						AR_printf(L"%ls : %ls : %d\r\n", cfg->name[i].name, cfg->name[i].regex, cfg->name[i].line);
/*
						if(!LEX_InsertName(tmp_lex, cfg->name[i].name, cfg->name[i].regex))
						{
								AR_abort();
						}
*/

				}
				AR_printf(L"----------------------\r\n");
				for(i = 0; i < cfg->tok_cnt; ++i)
				{
						lexAction_t act;
						act.is_skip = cfg->tok[i].is_skip;
						act.priority = cfg->tok[i].lex_prec;
						act.value = i + 256;

						AR_printf(L"%ls : %ls : %d : %d\r\n", cfg->tok[i].name, cfg->tok[i].regex, cfg->tok[i].lex_prec, cfg->tok[i].tokval);
/*
						if(!LEX_InsertRule(tmp_lex, cfg->tok[i].regex, &act))
						{
								AR_abort();
						}
		*/
				}
				AR_printf(L"----------------------\r\n");

				for(i = 0; i < cfg->prec_cnt; ++i)
				{
						size_t k;
						const cfgPrec_t	*prec = &cfg->prec[i];

						for(k = 0; k < prec->count; ++k)
						{
								AR_printf(L"name == %ls : tok_val == %d : prec_level == %d : assoc == %d \r\n", prec->prec_tok_set[k], prec->prec_tok_val[k],prec->prec_level, prec->assoc);
						}
				}

				AR_printf(L"----------------------\r\n");

				for(i = 0; i < cfg->rule_cnt; ++i)
				{
						AR_printf(L"%ls : %ls : %ls : %ls : line %d\r\n"
								, cfg->rule[i].lhs
								, cfg->rule[i].rhs
								, cfg->rule[i].prec_tok ? cfg->rule[i].prec_tok : L" "
								, cfg->rule[i].action_ins ? cfg->rule[i].action_ins : L" "
								,cfg->rule[i].line
								);
				}

				AR_printf(L"----------------------\r\n");

		//		arString_t *str = NULL;
		//		CFG_ConfigToCode(cfg, str);

#endif

				if(!cfg->has_error)
				{
                        char buf[1024];
                        AR_printf(L"%ls\r\n", "Please enter sources path");
                        //gets(buf);
                        //__gets_chk(buf,1024);

						//const wchar_t *input = __load_txt(DEF_SOUR_PATH);
						const wchar_t *input = __load_txt(buf);
						parse_code(cfg, input);

						AR_DEL(input);
				}
		}else
		{
				AR_abort();
		}


		if(cfg)CFG_DestroyGrammarConfig(cfg);

		AR_DEL(gmr_txt);
}
示例#12
0
void exec_image(char *image)
/* Get a Minix image into core, patch it up and execute. */
{
	int i;
	struct image_header hdr;
	char *buf;
	u32_t vsec, addr, limit, aout, n, totalmem = 0;
	struct process *procp;		/* Process under construction. */
	long a_text, a_data, a_bss, a_stack;
	int banner= 0;
	long processor= a2l(b_value("processor"));
	u16_t kmagic, mode;
	char *console;
	char params[SECTOR_SIZE];
	extern char *sbrk(int);
	char *verb;

	/* The stack is pretty deep here, so check if heap and stack collide. */
	(void) sbrk(0);

	if ((verb= b_value(VERBOSEBOOTVARNAME)) != nil)
		verboseboot = a2l(verb);

	printf("\nLoading ");
	pretty_image(image);
	printf(".\n");

	vsec= 0;			/* Load this sector from image next. */
	addr= mem[0].base;		/* Into this memory block. */
	limit= mem[0].base + mem[0].size;
	if (limit > caddr) limit= caddr;

	/* Allocate and clear the area where the headers will be placed. */
	aout = (limit -= PROCESS_MAX * A_MINHDR);

	/* Clear the area where the headers will be placed. */
	raw_clear(aout, PROCESS_MAX * A_MINHDR);

	/* Read the many different processes: */
	for (i= 0; vsec < image_size; i++) {
		u32_t startaddr;
		startaddr = addr;
		if (i == PROCESS_MAX) {
			printf("There are more then %d programs in %s\n",
				PROCESS_MAX, image);
			errno= 0;
			return;
		}
		procp= &process[i];

		/* Read header. */
		DEBUGEXTRA(("Reading header... "));
		for (;;) {
			if ((buf= get_sector(vsec++)) == nil) return;

			memcpy(&hdr, buf, sizeof(hdr));

			if (BADMAG(hdr.process)) { errno= ENOEXEC; return; }

			/* Check the optional label on the process. */
			if (selected(hdr.name)) break;

			/* Bad label, skip this process. */
			vsec+= proc_size(&hdr);
		}
		DEBUGEXTRA(("done\n"));

		/* Sanity check: an 8086 can't run a 386 kernel. */
		if (hdr.process.a_cpu == A_I80386 && processor < 386) {
			printf("You can't run a 386 kernel on this 80%ld\n",
				processor);
			errno= 0;
			return;
		}

		/* Get the click shift from the kernel text segment. */
		if (i == KERNEL_IDX) {
			if (!get_clickshift(vsec, &hdr)) return;
			addr= align(addr, click_size);

			/* big kernels must be loaded into extended memory */
			if (k_flags & K_KHIGH) {
				addr= mem[1].base;
				limit= mem[1].base + mem[1].size;
			}
		}

		/* Save a copy of the header for the kernel, with a_syms
		 * misused as the address where the process is loaded at.
		 */
		DEBUGEXTRA(("raw_copy(0x%x, 0x%lx, 0x%x)... ", 
			aout + i * A_MINHDR, mon2abs(&hdr.process), A_MINHDR));
		hdr.process.a_syms= addr;
		raw_copy(aout + i * A_MINHDR, mon2abs(&hdr.process), A_MINHDR);
		DEBUGEXTRA(("done\n"));

		if (!banner) {
			DEBUGBASIC(("     cs       ds     text     data      bss"));
			if (k_flags & K_CHMEM) DEBUGBASIC(("    stack"));
			DEBUGBASIC(("\n"));
			banner= 1;
		}

		/* Segment sizes. */
		DEBUGEXTRA(("a_text=0x%lx; a_data=0x%lx; a_bss=0x%lx; a_flags=0x%x)\n",
			hdr.process.a_text, hdr.process.a_data, 
			hdr.process.a_bss, hdr.process.a_flags));

		a_text= hdr.process.a_text;
		a_data= hdr.process.a_data;
		a_bss= hdr.process.a_bss;
		if (k_flags & K_CHMEM) {
			a_stack= hdr.process.a_total - a_data - a_bss;
			if (!(hdr.process.a_flags & A_SEP)) a_stack-= a_text;
		} else {
			a_stack= 0;
		}

		/* Collect info about the process to be. */
		procp->cs= addr;

		/* Process may be page aligned so that the text segment contains
		 * the header, or have an unmapped zero page against vaxisms.
		 */
		procp->entry= hdr.process.a_entry;
		if (hdr.process.a_flags & A_PAL) a_text+= hdr.process.a_hdrlen;
		if (hdr.process.a_flags & A_UZP) procp->cs-= click_size;

		/* Separate I&D: two segments.  Common I&D: only one. */
		if (hdr.process.a_flags & A_SEP) {
			/* Read the text segment. */
			DEBUGEXTRA(("get_segment(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
				vsec, a_text, addr, limit));
			if (!get_segment(&vsec, &a_text, &addr, limit)) return;
			DEBUGEXTRA(("get_segment done vsec=0x%lx a_text=0x%lx "
				"addr=0x%lx\n", 
				vsec, a_text, addr));

			/* The data segment follows. */
			procp->ds= addr;
			if (hdr.process.a_flags & A_UZP) procp->ds-= click_size;
			procp->data= addr;
		} else {
			/* Add text to data to form one segment. */
			procp->data= addr + a_text;
			procp->ds= procp->cs;
			a_data+= a_text;
		}

		/* Read the data segment. */
		DEBUGEXTRA(("get_segment(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n", 
			vsec, a_data, addr, limit));
		if (!get_segment(&vsec, &a_data, &addr, limit)) return;
		DEBUGEXTRA(("get_segment done vsec=0x%lx a_data=0x%lx "
			"addr=0x%lx\n", 
			vsec, a_data, addr));

		/* Make space for bss and stack unless... */
		if (i != KERNEL_IDX && (k_flags & K_CLAIM)) a_bss= a_stack= 0;

		DEBUGBASIC(("%07lx  %07lx %8ld %8ld %8ld",
			procp->cs, procp->ds, hdr.process.a_text,
			hdr.process.a_data, hdr.process.a_bss));
		if (k_flags & K_CHMEM) DEBUGBASIC((" %8ld", a_stack));

		/* Note that a_data may be negative now, but we can look at it
		 * as -a_data bss bytes.
		 */

		/* Compute the number of bss clicks left. */
		a_bss+= a_data;
		n= align(a_bss, click_size);
		a_bss-= n;

		/* Zero out bss. */
		DEBUGEXTRA(("\nraw_clear(0x%lx, 0x%lx); limit=0x%lx... ", addr, n, limit));
		if (addr + n > limit) { errno= ENOMEM; return; }
		raw_clear(addr, n);
		DEBUGEXTRA(("done\n"));
		addr+= n;

		/* And the number of stack clicks. */
		a_stack+= a_bss;
		n= align(a_stack, click_size);
		a_stack-= n;

		/* Add space for the stack. */
		addr+= n;

		/* Process endpoint. */
		procp->end= addr;

		if (verboseboot >= VERBOSEBOOT_BASIC)
			printf("  %s\n", hdr.name);
		else {
			u32_t mem;
			mem = addr-startaddr;
			printf("%s ", hdr.name);
			totalmem += mem;
		}

		if (i == 0 && (k_flags & (K_HIGH | K_KHIGH)) == K_HIGH) {
			/* Load the rest in extended memory. */
			addr= mem[1].base;
			limit= mem[1].base + mem[1].size;
		}
	}

	if (verboseboot < VERBOSEBOOT_BASIC)
		printf("(%dk)\n", totalmem/1024);

	if ((n_procs= i) == 0) {
		printf("There are no programs in %s\n", image);
		errno= 0;
		return;
	}

	/* Check the kernel magic number. */
	raw_copy(mon2abs(&kmagic), 
		process[KERNEL_IDX].data + MAGIC_OFF, sizeof(kmagic));
	if (kmagic != KERNEL_D_MAGIC) {
		printf("Kernel magic number is incorrect (0x%x@0x%lx)\n", 
			kmagic, process[KERNEL_IDX].data + MAGIC_OFF);
		errno= 0;
		return;
	}

	/* Patch sizes, etc. into kernel data. */
	DEBUGEXTRA(("patch_sizes()... "));
	patch_sizes();
	DEBUGEXTRA(("done\n"));

#if !DOS
	if (!(k_flags & K_MEML)) {
		/* Copy the a.out headers to the old place. */
		raw_copy(HEADERPOS, aout, PROCESS_MAX * A_MINHDR);
	}
#endif

	/* Run the trailer function just before starting Minix. */
	DEBUGEXTRA(("run_trailer()... "));
	if (!run_trailer()) { errno= 0; return; }
	DEBUGEXTRA(("done\n"));

	/* Translate the boot parameters to what Minix likes best. */
	DEBUGEXTRA(("params2params(0x%x, 0x%x)... ", params, sizeof(params)));
	if (!params2params(params, sizeof(params))) { errno= 0; return; }
	DEBUGEXTRA(("done\n"));

	/* Set the video to the required mode. */
	if ((console= b_value("console")) == nil || (mode= a2x(console)) == 0) {
		mode= strcmp(b_value("chrome"), "color") == 0 ? COLOR_MODE :
								MONO_MODE;
	}
	DEBUGEXTRA(("set_mode(%d)... ", mode));
	set_mode(mode);
	DEBUGEXTRA(("done\n"));

	/* Close the disk. */
	DEBUGEXTRA(("dev_close()... "));
	(void) dev_close();
	DEBUGEXTRA(("done\n"));

	/* Minix. */
	DEBUGEXTRA(("minix(0x%lx, 0x%lx, 0x%lx, 0x%x, 0x%x, 0x%lx)\n", 
		process[KERNEL_IDX].entry, process[KERNEL_IDX].cs,
		process[KERNEL_IDX].ds, params, sizeof(params), aout));
	minix(process[KERNEL_IDX].entry, process[KERNEL_IDX].cs,
			process[KERNEL_IDX].ds, params, sizeof(params), aout);

	if (!(k_flags & K_BRET)) {
		extern u32_t reboot_code;
		raw_copy(mon2abs(params), reboot_code, sizeof(params));
	}
	parse_code(params);

	/* Return from Minix.  Things may have changed, so assume nothing. */
	fsok= -1;
	errno= 0;

	/* Read leftover character, if any. */
	scan_keyboard();

	/* Restore screen contents. */
	restore_screen();
}
示例#13
0
void exec_mb(char *kernel, char* modules)
/* Get a Minix image into core, patch it up and execute. */
{
	int i;
	static char hdr[SECTOR_SIZE];
	char *buf;
	u32_t vsec, addr, limit, n, totalmem = 0;
	u16_t kmagic, mode;
	char *console;
	char params[SECTOR_SIZE];
	extern char *sbrk(int);
	char *verb;
	u32_t text_vaddr, text_paddr, text_filebytes, text_membytes;
	u32_t data_vaddr, data_paddr, data_filebytes, data_membytes;
	u32_t pc;
	u32_t text_offset, data_offset;
	i32_t segsize;
	int r;
	u32_t cs, ds;
	char *modstring, *mod;
	multiboot_info_t *mbinfo;
	multiboot_module_t *mbmodinfo;
	u32_t mbinfo_size, mbmodinfo_size;
	char *memvar;
	memory *mp;
	u32_t mod_cmdline_start, kernel_cmdline_start;
	u32_t modstringlen;
	int modnr;

	/* The stack is pretty deep here, so check if heap and stack collide. */
	(void) sbrk(0);

	if ((verb= b_value(VERBOSEBOOTVARNAME)) != nil)
		verboseboot = a2l(verb);

	printf("\nLoading %s\n", kernel);

	vsec= 0;			/* Load this sector from kernel next. */
	addr= mem[0].base;		/* Into this memory block. */
	limit= mem[0].base + mem[0].size;
	if (limit > caddr) limit= caddr;

	/* set click size for get_segment */
	click_size = PAGE_SIZE;

	k_flags = K_KHIGH|K_BRET|K_MEML|K_INT86|K_RET|K_HDR
	    |K_HIGH|K_CHMEM|K_I386;

	/* big kernels must be loaded into extended memory */
	addr= mem[1].base;
	limit= mem[1].base + mem[1].size;

	/* Get first sector */
	DEBUGEXTRA(("get_sector\n"));
	if ((buf= get_sector(vsec++)) == nil) {
	    DEBUGEXTRA(("get_sector failed\n"));
	    return;
	}
	memcpy(hdr, buf, SECTOR_SIZE);

	/* Get ELF header */
	DEBUGEXTRA(("read_header_elf\n"));
	r = read_header_elf(hdr, &text_vaddr, &text_paddr,
			    &text_filebytes, &text_membytes,
			    &data_vaddr, &data_paddr,
			    &data_filebytes, &data_membytes,
			    &pc, &text_offset, &data_offset);
	if (r < 0) { errno= ENOEXEC; return; }

	/* Read the text segment. */
	addr = text_paddr;
	segsize = (i32_t) text_filebytes;
	vsec = text_offset / SECTOR_SIZE;
	DEBUGEXTRA(("get_segment(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
		    vsec, segsize, addr, limit));
	if (!get_segment(&vsec, &segsize, &addr, limit)) return;
	DEBUGEXTRA(("get_segment done vsec=0x%lx size=0x%lx "
		    "addr=0x%lx\n",
		    vsec, segsize, addr));

	/* Read the data segment. */
	addr = data_paddr;
	segsize = (i32_t) data_filebytes;
	vsec = data_offset / SECTOR_SIZE;

	DEBUGEXTRA(("get_segment(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
		    vsec, segsize, addr, limit));
	if (!get_segment(&vsec, &segsize, &addr, limit)) return;
	DEBUGEXTRA(("get_segment done vsec=0x%lx size=0x%lx "
		    "addr=0x%lx\n",
		    vsec, segsize, addr));

	n = data_membytes - align(data_filebytes, click_size);

	/* Zero out bss. */
	DEBUGEXTRA(("\nraw_clear(0x%lx, 0x%lx); limit=0x%lx... ", addr, n, limit));
	if (addr + n > limit) { errno= ENOMEM; return; }
	raw_clear(addr, n);
	DEBUGEXTRA(("done\n"));
	addr+= n;

	/* Check the kernel magic number. */
	raw_copy(mon2abs(&kmagic),
		 data_paddr + MAGIC_OFF, sizeof(kmagic));
	if (kmagic != KERNEL_D_MAGIC) {
		printf("Kernel magic number is incorrect (0x%x@0x%lx)\n",
			kmagic, data_paddr + MAGIC_OFF);
		errno= 0;
		return;
	}

	/* Translate the boot parameters to what Minix likes best. */
	DEBUGEXTRA(("params2params(0x%x, 0x%x)... ", params, sizeof(params)));
	if (!params2params(params, sizeof(params))) { errno= 0; return; }
	DEBUGEXTRA(("done\n"));

	/* Create multiboot info struct */
	mbinfo = malloc(sizeof(multiboot_info_t));
	if (mbinfo == nil) { errno= ENOMEM; return; }
	memset(mbinfo, 0, sizeof(multiboot_info_t));

	/* Module info structs start where kernel ends */
	mbinfo->mods_addr = addr;

	modstring = strdup(modules);
	if (modstring == nil) {errno = ENOMEM; return; }
	modstringlen = strlen(modules);
	mbinfo->mods_count = split_module_list(modules);

	mbmodinfo_size = sizeof(multiboot_module_t) * mbinfo->mods_count;
	mbmodinfo = malloc(mbmodinfo_size);
	if (mbmodinfo == nil) { errno= ENOMEM; return; }
	addr+= mbmodinfo_size;
	addr= align(addr, click_size);

	mod_cmdline_start = mbinfo->mods_addr + sizeof(multiboot_module_t) *
	    mbinfo->mods_count;

	raw_copy(mod_cmdline_start, mon2abs(modules),
		 modstringlen+1);

	mbmodinfo[0].cmdline = mod_cmdline_start;
	modnr = 1;
	for (i= 0; i < modstringlen; ++i) {
	    if (modules[i] == '\0') {
		mbmodinfo[modnr].cmdline = mod_cmdline_start + i + 1;
		++modnr;
	    }
	}

	kernel_cmdline_start = mod_cmdline_start + modstringlen + 1;
	mbinfo->cmdline = kernel_cmdline_start;
	raw_copy(kernel_cmdline_start, mon2abs(kernel),
		 strlen(kernel)+1);

	mbinfo->flags = MULTIBOOT_INFO_MODS|MULTIBOOT_INFO_CMDLINE|
	    MULTIBOOT_INFO_BOOTDEV|MULTIBOOT_INFO_MEMORY;

	mbinfo->boot_device = mbdev;
	mbinfo->mem_lower = mem[0].size/1024;
	mbinfo->mem_upper = mem[1].size/1024;

	for (i = 0, mod = strtok(modstring, " "); mod != nil;
	     mod = strtok(nil, " "), i++) {

		mod = select_image(mod);
		if (mod == nil) {errno = 0; return; }

		mbmodinfo[i].mod_start = addr;
		mbmodinfo[i].mod_end = addr + image_bytes;
		mbmodinfo[i].pad = 0;

		segsize= image_bytes;
		vsec= 0;
		DEBUGEXTRA(("get_segment(0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
		       vsec, segsize, addr, limit));
		if (!get_segment(&vsec, &segsize, &addr, limit)) return;
		DEBUGEXTRA(("get_segment done vsec=0x%lx size=0x%lx "
		       "addr=0x%lx\n",
		       vsec, segsize, addr));
		addr+= segsize;
		addr= align(addr, click_size);
	}
	free(modstring);

	DEBUGEXTRA(("modinfo raw_copy: dst 0x%lx src 0x%lx sz 0x%lx\n",
	    mbinfo->mods_addr, mon2abs(mbmodinfo),
	    mbmodinfo_size));
	raw_copy(mbinfo->mods_addr, mon2abs(mbmodinfo),
	    mbmodinfo_size);
	free(mbmodinfo);

	raw_copy(MULTIBOOT_INFO_ADDR, mon2abs(mbinfo),
		 sizeof(multiboot_info_t));
	free(mbinfo);

	/* Run the trailer function just before starting Minix. */
	DEBUGEXTRA(("run_trailer()... "));
	if (!run_trailer()) { errno= 0; return; }
	DEBUGEXTRA(("done\n"));

	/* Set the video to the required mode. */
	if ((console= b_value("console")) == nil || (mode= a2x(console)) == 0) {
		mode= strcmp(b_value("chrome"), "color") == 0 ? COLOR_MODE :
								MONO_MODE;
	}
	DEBUGEXTRA(("set_mode(%d)... ", mode));
	set_mode(mode);
	DEBUGEXTRA(("done\n"));

	/* Close the disk. */
	DEBUGEXTRA(("dev_close()... "));
	(void) dev_close();
	DEBUGEXTRA(("done\n"));

	/* Minix. */
	cs = ds = text_paddr;
	DEBUGEXTRA(("minix(0x%lx, 0x%lx, 0x%lx, 0x%x, 0x%x, 0x%lx)\n",
		pc, cs, ds, params, sizeof(params), 0));
	minix(pc, cs, ds, params, sizeof(params), 0);

	if (!(k_flags & K_BRET)) {
		extern u32_t reboot_code;
		raw_copy(mon2abs(params), reboot_code, sizeof(params));
	}
	parse_code(params);

	/* Return from Minix.  Things may have changed, so assume nothing. */
	fsok= -1;
	errno= 0;

	/* Read leftover character, if any. */
	scan_keyboard();

	/* Restore screen contents. */
	restore_screen();
}