psim_tree(void) { device *root = tree_parse(NULL, "core"); tree_parse(root, "/aliases"); tree_parse(root, "/options"); tree_parse(root, "/chosen"); tree_parse(root, "/packages"); tree_parse(root, "/cpus"); tree_parse(root, "/openprom"); tree_parse(root, "/openprom/init"); tree_parse(root, "/openprom/trace"); tree_parse(root, "/openprom/options"); return root; }
INLINE_EMUL_GENERIC void emul_add_tree_hardware(device *root) { int i; int nr_cpus = tree_find_integer_property(root, "/openprom/options/smp"); /* sanity check the number of processors */ if (nr_cpus > MAX_NR_PROCESSORS) error("Specified number of processors (%d) exceeds the number configured (%d).\n", nr_cpus, MAX_NR_PROCESSORS); /* set the number of address cells (1 or 2) */ tree_parse(root, "#address-cells %d", WITH_TARGET_WORD_BITSIZE / 32); /* add some memory */ if (tree_find_device(root, "/memory") == NULL) { unsigned_word memory_size = tree_find_integer_property(root, "/openprom/options/oea-memory-size"); const unsigned_word avail_start = 0x3000; tree_parse(root, "/memory@0/reg 0x0 0x%lx", (unsigned long)memory_size); /* reserve the first 0x3000 for the PowerPC interrupt table */ tree_parse(root, "/memory@0/available 0x%lx 0x%lx", (unsigned long)avail_start, (unsigned long)memory_size - avail_start); } /* our processors */ for (i = 0; i < nr_cpus; i++) { tree_parse(root, "/cpus/cpu@%d/cpu-nr %d", i, i); } /* the debugging pal - hide it in the openprom and don't attach it to any bus */ tree_parse(root, "/openprom/pal"); /* chosen etc */ tree_parse(root, "/chosen/stdin */openprom/pal"); tree_parse(root, "/chosen/stdout !/chosen/stdin"); tree_parse(root, "/chosen/memory */memory"); }
static void create_ppc_chirp_bootargs(device *me, char **argv) { /* concat the arguments */ char args[1024]; char **chp = argv + 1; args[0] = '\0'; while (*chp != NULL) { if (strlen(args) > 0) strcat(args, " "); if (strlen(args) + strlen(*chp) >= sizeof(args)) device_error(me, "buffer overflow"); strcat(args, *chp); chp++; } /* set the arguments property */ tree_parse(me, "/chosen/bootargs \"%s", args); }
static os_emul_data * emul_netbsd_create(device *root, bfd *image, const char *name) { unsigned_word top_of_stack; unsigned stack_size; int elf_binary; os_emul_data *bsd_data; device *vm; char *filename; /* check that this emulation is really for us */ if (name != NULL && strcmp(name, "netbsd") != 0) return NULL; if (image == NULL) return NULL; /* merge any emulation specific entries into the device tree */ /* establish a few defaults */ if (image->xvec->flavour == bfd_target_elf_flavour) { elf_binary = 1; top_of_stack = 0xe0000000; stack_size = 0x00100000; } else { elf_binary = 0; top_of_stack = 0x20000000; stack_size = 0x00100000; } /* options */ emul_add_tree_options(root, image, "netbsd", (WITH_ENVIRONMENT == USER_ENVIRONMENT ? "user" : "virtual"), 0 /*oea-interrupt-prefix*/); /* virtual memory - handles growth of stack/heap */ vm = tree_parse(root, "/openprom/vm"); tree_parse(vm, "./stack-base 0x%lx", (unsigned long)(top_of_stack - stack_size)); tree_parse(vm, "./nr-bytes 0x%x", stack_size); filename = tree_quote_property (bfd_get_filename(image)); tree_parse(root, "/openprom/vm/map-binary/file-name %s", filename); free (filename); /* finish the init */ tree_parse(root, "/openprom/init/register/pc 0x%lx", (unsigned long)bfd_get_start_address(image)); tree_parse(root, "/openprom/init/register/sp 0x%lx", (unsigned long)top_of_stack); tree_parse(root, "/openprom/init/register/msr 0x%x", ((tree_find_boolean_property(root, "/options/little-endian?") ? msr_little_endian_mode : 0) | (tree_find_boolean_property(root, "/openprom/options/floating-point?") ? (msr_floating_point_available | msr_floating_point_exception_mode_0 | msr_floating_point_exception_mode_1) : 0))); tree_parse(root, "/openprom/init/stack/stack-type %s", (elf_binary ? "ppc-elf" : "ppc-xcoff")); /* finally our emulation data */ bsd_data = ZALLOC(os_emul_data); bsd_data->vm = vm; bsd_data->syscalls = &emul_netbsd_syscalls; return bsd_data; }
/* * parse a buffer. * * NOTE: parse() should not be called recusively by any other functions! */ int parse(aClient *cptr, char *pbuffer, char *bufend) { aClient *from = cptr; char *ch; char *s; size_t i; char* numeric = 0; unsigned int paramcount; struct Message *mptr; Debug((DEBUG_DEBUG, "Parsing %s: %s", get_client_name(cptr, TRUE), pbuffer)); if (IsDead(cptr)) return -1; s = sender; *s = '\0'; for (ch = pbuffer; *ch == ' '; ch++) /* skip spaces */ /* null statement */ ; para[0] = from->name; if (*ch == ':') { ch++; /* ** Copy the prefix to 'sender' assuming it terminates ** with SPACE (or NULL, which is an error, though). */ for (i = 0; *ch && *ch != ' '; i++ ) { if (i < (sizeof(sender)-1)) *s++ = *ch; /* leave room for NULL */ ch++; } *s = '\0'; i = 0; /* ** Actually, only messages coming from servers can have ** the prefix--prefix silently ignored, if coming from ** a user client... ** ** ...sigh, the current release "v2.2PL1" generates also ** null prefixes, at least to NOTIFY messages (e.g. it ** puts "sptr->nickname" as prefix from server structures ** where it's null--the following will handle this case ** as "no prefix" at all --msa (": NOTICE nick ...") */ if (*sender && IsServer(cptr)) { from = find_client(sender, (aClient *) NULL); if (!from || !match(from->name, sender)) from = find_server(sender); para[0] = sender; /* Hmm! If the client corresponding to the * prefix is not found--what is the correct * action??? Now, I will ignore the message * (old IRC just let it through as if the * prefix just wasn't there...) --msa */ if (!from) { sendto_ops_flag_butone(cptr, UMODE_DEBUG, "Unknown prefix (%s) from (%s)", sender, cptr->name); Debug((DEBUG_ERROR, "Unknown prefix (%s)(%s) from (%s)", sender, pbuffer, cptr->name)); ServerStats->is_unpf++; remove_unknown(cptr, sender, pbuffer); return -1; } if (from->from != cptr) { ServerStats->is_wrdi++; Debug((DEBUG_ERROR, "Message (%s) coming from (%s)", buffer, cptr->name)); sendto_ops_flag_butone(cptr, UMODE_DEBUG, "Message coming from (%s), but %s is at %s", cptr->name, from->name, from->from->name); return cancel_clients(cptr, from, pbuffer); } } while (*ch == ' ') ch++; } if (*ch == '\0') { ServerStats->is_empt++; Debug((DEBUG_NOTICE, "Empty message from host %s:%s", cptr->name, from->name)); if (IsServer(cptr)) sendto_ops_flag_butone(cptr, UMODE_DEBUG, "Empty message from %s:%s", cptr->name, from->name); return(-1); } /* ** Extract the command code from the packet. Point s to the end ** of the command code and calculate the length using pointer ** arithmetic. Note: only need length for numerics and *all* ** numerics must have parameters and thus a space after the command ** code. -avalon * * ummm???? - Dianora */ if( *(ch + 3) == ' ' && /* ok, lets see if its a possible numeric.. */ IsDigit(*ch) && IsDigit(*(ch + 1)) && IsDigit(*(ch + 2)) ) { mptr = (struct Message *)NULL; numeric = ch; paramcount = MAXPARA; ServerStats->is_num++; s = ch + 3; /* I know this is ' ' from above if */ *s++ = '\0'; /* blow away the ' ', and point s to next part */ } else { s = strchr(ch, ' '); /* moved from above,now need it here */ if (s) *s++ = '\0'; mptr = tree_parse(ch); if (!mptr || !mptr->cmd) { /* * Note: Give error message *only* to recognized * persons. It's a nightmare situation to have * two programs sending "Unknown command"'s or * equivalent to each other at full blast.... * If it has got to person state, it at least * seems to be well behaving. Perhaps this message * should never be generated, though... --msa * Hm, when is the buffer empty -- if a command * code has been found ?? -Armin * * Same thing goes for remote commands. If their local * server accepted it, then we should not be sending * a warning message. */ if (pbuffer[0] != '\0') { if (IsPerson(from) && MyClient(from)) sendto_one(from, ":%s %d %s %s :Unknown command", me.name, ERR_UNKNOWNCOMMAND, from->name, ch); Debug((DEBUG_ERROR,"Unknown (%s) from %s", ch, get_client_name(cptr, TRUE))); } ServerStats->is_unco++; return(-1); } paramcount = mptr->parameters; i = bufend - ((s) ? s : ch); mptr->bytes += i; /* Allow only 1 msg per 2 seconds * (on average) to prevent dumping. * to keep the response rate up, * bursts of up to 5 msgs are allowed * -SRB * Opers can send 1 msg per second, burst of ~20 * -Taner */ if ((mptr->flags & 1) && !(IsServer(cptr))) { #ifdef NO_OPER_FLOOD #ifndef TRUE_NO_OPER_FLOOD /* note: both have to be defined for the real no-flood */ if (NoFloodProtection(cptr)) /* "randomly" (weighted) increase the since */ cptr->since += (cptr->receiveM % 5) ? 1 : 0; else #else if (!NoFloodProtection(cptr)) #endif #endif cptr->since += (2 + i / 120); } } /* ** Must the following loop really be so devious? On ** surface it splits the message to parameters from ** blank spaces. But, if paramcount has been reached, ** the rest of the message goes into this last parameter ** (about same effect as ":" has...) --msa */ /* Note initially true: s==NULL || *(s-1) == '\0' !! */ /* ZZZ hmmmmmmmm whats this then? */ #if 0 if (me.user) para[0] = sender; #endif i = 1; if (s) { if (paramcount > MAXPARA) paramcount = MAXPARA; for (;;) { while(*s == ' ') /* tabs are not considered space */ *s++ = '\0'; if(!*s) break; if (*s == ':') { /* ** The rest is single parameter--can ** include blanks also. */ para[i++] = s + 1; break; } else { para[i++] = s; if (i > paramcount) { break; } /* scan for end of string, either ' ' or '\0' */ while (IsNonEOS(*s)) s++; } } } para[i] = NULL; if (mptr == (struct Message *)NULL) return (do_numeric(numeric, cptr, from, i, para)); mptr->count++; /* patch to avoid server flooding from unregistered connects */ /* check allow_unregistered_use flag I've set up instead of function comparing *yech* - Dianora */ if (!IsRegistered(cptr) && !mptr->allow_unregistered_use ) { /* if its from a possible server connection * ignore it.. more than likely its a header thats sneaked through */ if(IsHandshake(cptr) || IsConnecting(cptr) || IsServer(cptr)) return -1; sendto_one(from, ":%s %d %s %s :Register first.", me.name, ERR_NOTREGISTERED, BadPtr(from->name) ? "*" : from->name, ch); return -1; } /* Silently drop the messages that can't be used in the honeypot */ if (IsHoneypot(cptr) && !mptr->allow_honeypot) return -1; /* Again, instead of function address comparing, see if * this function resets idle time as given from mptr * if IDLE_FROM_MSG is undefined, the sense of the flag is reversed. * i.e. if the flag is 0, then reset idle time, otherwise don't reset it. * * - Dianora */ if (IsRegisteredUser(from) && mptr->reset_idle) { /* If a local registered user, propagate anti-idle updates as needed */ if (MyClient(from) && from->user && ((from->user->last_sent + MAX_IDLE_DESYNC) < CurrentTime)) { #if 0 /* Note the misnamed message, this indicates that they are NOT idle */ #ifdef HAVE_LONG_LONG sendto_serv_butone(NULL, ":%s IDLE %s %.1lld", cptr->name, from->name, (long long)CurrentTime); #else sendto_serv_butone(NULL, ":%s IDLE %s %.1ld", cptr->name, from->name, (long)CurrentTime); #endif #endif from->user->last_sent = CurrentTime; } from->user->last = CurrentTime; } /* don't allow other commands while a list is blocked. since we treat them specially with respect to sendq. */ if ((IsDoingList(cptr)) && (*mptr->func != m_list)) return -1; return (*mptr->func)(cptr, from, i, para); }
int parse(aClient *cptr, char *buffer, char *bufend) { aClient *from = cptr; char *ch, *s; int i, numeric = 0, paramcount; struct Message *mptr; #ifdef DUMP_DEBUG if(dumpfp!=NULL) { fprintf(dumpfp, "<- %s: %s\n", (cptr->name ? cptr->name : "*"), buffer); fflush(dumpfp); } #endif Debug((DEBUG_DEBUG, "Parsing %s: %s", get_client_name(cptr, TRUE), buffer)); if (IsDead(cptr)) return -1; s = sender; *s = '\0'; for (ch = buffer; *ch == ' '; ch++); /* skip spaces */ para[0] = from->name; if (*ch == ':') { /* * Copy the prefix to 'sender' assuming it terminates with * SPACE (or NULL, which is an error, though). */ for (++ch; *ch && *ch != ' '; ++ch) if (s < (sender + HOSTLEN)) *s++ = *ch; *s = '\0'; /* * Actually, only messages coming from servers can have the * prefix--prefix silently ignored, if coming from a user * client... * * ...sigh, the current release "v2.2PL1" generates also null * prefixes, at least to NOTIFY messages (e.g. it puts * "sptr->nickname" as prefix from server structures where it's * null--the following will handle this case as "no prefix" at * all --msa (": NOTICE nick ...") */ if (*sender && IsServer(cptr)) { from = find_client(sender, (aClient *) NULL); /* * okay, this doesn't seem to do much here. * from->name _MUST_ be equal to sender. * That's what find_client does. * find_client will find servers too, and since we don't use server * masking, the find server call is useless (and very wasteful). * now, there HAS to be a from and from->name and * sender have to be the same * for us to get to the next if. but the next if * starts out with if(!from) * so this is UNREACHABLE CODE! AGH! - lucas * * if (!from || mycmp(from->name, sender)) * from = find_server(sender, (aClient *) NULL); * else if (!from && strchr(sender, '@')) * from = find_nickserv(sender, (aClient *) NULL); */ para[0] = sender; /* * Hmm! If the client corresponding to the prefix is not * found--what is the correct action??? Now, I will ignore the * message (old IRC just let it through as if the prefix just * wasn't there...) --msa */ if (!from) { Debug((DEBUG_ERROR, "Unknown prefix (%s)(%s) from (%s)", sender, buffer, cptr->name)); ircstp->is_unpf++; remove_unknown(cptr, sender, buffer); return -1; } if (from->from != cptr) { ircstp->is_wrdi++; Debug((DEBUG_ERROR, "Message (%s) coming from (%s)", buffer, cptr->name)); return cancel_clients(cptr, from, buffer); } } while (*ch == ' ') ch++; } if (*ch == '\0') { ircstp->is_empt++; Debug((DEBUG_NOTICE, "Empty message from host %s:%s", cptr->name, from->name)); return (-1); } /* * Extract the command code from the packet. Point s to the end * of the command code and calculate the length using pointer * arithmetic. Note: only need length for numerics and *all* * numerics must have parameters and thus a space after the command * code. -avalon * * ummm???? - Dianora */ /* Reparse point for /msg raw - Tux` */ reparse: /* check for numeric */ if (*(ch + 3) == ' ' && IsDigit(*ch) && IsDigit(*(ch + 1)) && IsDigit(*(ch + 2))) { mptr = (struct Message *) NULL; numeric = (*ch - '0') * 100 + (*(ch + 1) - '0') * 10 + (*(ch + 2) - '0'); paramcount = MAXPARA; ircstp->is_num++; s = ch + 3; *s++ = '\0'; } else { s = strchr(ch, ' '); if (s) *s++ = '\0'; mptr = tree_parse(ch); if ((mptr && mptr->func == m_private) && (s && !strncasecmp(s, "raw ", 4))) { ch = index(s, ':'); if (ch++) goto reparse; } else if (!mptr || !mptr->cmd) { /* * only send error messages to things that actually sent * buffers to us and only people, too. */ if (buffer[0] != '\0') { if (IsPerson(from)) sendto_one(from, ":%s %d %s %s :Unknown command", me.name, ERR_UNKNOWNCOMMAND, from->name, ch); Debug((DEBUG_ERROR, "Unknown (%s) from %s", ch, get_client_name(cptr, TRUE))); } ircstp->is_unco++; return -1; } paramcount = mptr->parameters; i = bufend - ((s) ? s : ch); mptr->bytes += i; /* * Allow only 1 msg per 2 seconds (on average) to prevent * dumping. to keep the response rate up, bursts of up to 5 msgs * are allowed -SRB Opers can send 1 msg per second, burst of ~20 * -Taner */ if (!IsServer(cptr)) { if (!NoMsgThrottle(cptr)) { #ifdef NO_OPER_FLOOD if (IsAnOper(cptr)) /* "randomly" (weighted) increase the since */ cptr->since += (cptr->receiveM % 10) ? 1 : 0; else #endif cptr->since += (2 + i / 120); } } } /* * Must the following loop really be so devious? On surface it * splits the message to parameters from blank spaces. But, if * paramcount has been reached, the rest of the message goes into * this last parameter (about same effect as ":" has...) --msa */ /* Note initially true: s==NULL || *(s-1) == '\0' !! */ i = 1; if (s) { if (paramcount > MAXPARA) paramcount = MAXPARA; for (;;) { while (*s == ' ') *s++ = '\0'; if (*s == '\0') break; if (*s == ':') { /* The rest is a single parameter */ para[i++] = s + 1; break; } para[i++] = s; if (i >= paramcount) { if(paramcount == MAXPARA && strchr(s, ' ')) { sendto_realops_lev(DEBUG_LEV, "Overflowed MAXPARA on %s from %s", mptr ? mptr->cmd : "numeric", get_client_name(cptr, (IsServer(cptr) ? HIDEME : FALSE))); } break; } while(*s && *s != ' ') s++; } } para[i] = NULL; if (mptr == (struct Message *) NULL) return (do_numeric(numeric, cptr, from, i, para)); mptr->count++; /* patch to avoid server flooding from unregistered connects */ if (!IsRegistered(cptr) && !(mptr->flags & MF_UNREG)) { sendto_one(from, ":%s %d %s %s :Register first.", me.name, ERR_NOTREGISTERED, from->name, ch); return -1; } if (IsRegisteredUser(cptr) && (mptr->flags & MF_RIDLE)) from->user->last = timeofday; if (mptr->flags & MF_ALIAS) return mptr->func(cptr, from, i, para, &aliastab[mptr->aliasidx]); return (*mptr->func) (cptr, from, i, para); }
INLINE_EMUL_GENERIC void emul_add_tree_options(device *tree, bfd *image, const char *emul, const char *env, int oea_interrupt_prefix) { int little_endian = 0; /* sort out little endian */ if (tree_find_property(tree, "/options/little-endian?")) little_endian = tree_find_boolean_property(tree, "/options/little-endian?"); else { #ifdef bfd_little_endian /* new bfd */ little_endian = (image != NULL && bfd_little_endian(image)); #else little_endian = (image != NULL && !image->xvec->byteorder_big_p); #endif tree_parse(tree, "/options/little-endian? %s", little_endian ? "true" : "false"); } /* misc other stuff */ tree_parse(tree, "/openprom/options/oea-memory-size 0x%x", OEA_MEMORY_SIZE); tree_parse(tree, "/openprom/options/oea-interrupt-prefix %d", oea_interrupt_prefix); tree_parse(tree, "/openprom/options/smp 1"); tree_parse(tree, "/openprom/options/env %s", env); tree_parse(tree, "/openprom/options/os-emul %s", emul); tree_parse(tree, "/openprom/options/strict-alignment? %s", (WITH_ALIGNMENT == STRICT_ALIGNMENT) ? "true" : "false"); tree_parse(tree, "/openprom/options/floating-point? %s", WITH_FLOATING_POINT ? "true" : "false"); tree_parse(tree, "/openprom/options/use-stdio? %s", ((WITH_STDIO == DO_USE_STDIO || WITH_STDIO == 0) ? "true" : "false")); tree_parse(tree, "/openprom/options/model \"%s", model_name[WITH_DEFAULT_MODEL]); tree_parse(tree, "/openprom/options/model-issue %d", MODEL_ISSUE_IGNORE); /* useful options */ }
static os_emul_data * emul_bugapi_create(device *root, bfd *image, const char *name) { device *node; os_emul_data *bugapi; char *filename; /* check it really is for us */ if (name != NULL && strcmp(name, "bugapi") != 0 && strcmp(name, "bug") != 0) return NULL; if (image != NULL && name == NULL && bfd_get_start_address(image) >= BUGAPI_END_ADDRESS) return NULL; bugapi = ZALLOC(os_emul_data); /* options */ emul_add_tree_options(root, image, "bug", "oea", 1 /*oea-interrupt-prefix*/); /* add some real hardware, include eeprom memory for the eeprom trap addresses */ emul_add_tree_hardware(root); node = tree_parse(root, "/openprom/memory@0xfff00000"); tree_parse(node, "./psim,description \"eeprom trap addresses"); tree_parse(node, "./reg 0xfff00000 0x3000"); bugapi->root = root; bugapi->memory_size = tree_find_integer_property(root, "/openprom/options/oea-memory-size"); bugapi->interrupt_prefix = tree_find_integer_property(root, "/openprom/options/oea-interrupt-prefix"); bugapi->interrupt_vector_address = (bugapi->interrupt_prefix ? MASK(0, 43) : 0); bugapi->system_call_address = (bugapi->interrupt_vector_address + 0x00c00); bugapi->stall_cpu_loop_address = (bugapi->system_call_address + 0x000f0); bugapi->top_of_stack = bugapi->memory_size - 0x1000; bugapi->little_endian = tree_find_boolean_property(root, "/options/little-endian?"); bugapi->floating_point_available = tree_find_boolean_property(root, "/openprom/options/floating-point?"); bugapi->input = NULL; bugapi->output = NULL; /* initialization */ if (image != NULL) tree_parse(root, "/openprom/init/register/0.pc 0x%lx", (unsigned long)bfd_get_start_address(image)); tree_parse(root, "/openprom/init/register/pc 0x%lx", (unsigned long)bugapi->stall_cpu_loop_address); tree_parse(root, "/openprom/init/register/sp 0x%lx", (unsigned long)(bugapi->top_of_stack - 16)); tree_parse(root, "/openprom/init/register/msr 0x%x", (msr_recoverable_interrupt | (bugapi->little_endian ? (msr_little_endian_mode | msr_interrupt_little_endian_mode) : 0) | (bugapi->floating_point_available ? msr_floating_point_available : 0) | (bugapi->interrupt_prefix ? msr_interrupt_prefix : 0) )); /* patch the system call instruction to call this emulation and then do an rfi */ node = tree_parse(root, "/openprom/init/data@0x%lx", (unsigned long)bugapi->system_call_address); tree_parse(node, "./psim,description \"system-call trap instruction"); tree_parse(node, "./real-address 0x%lx", (unsigned long)bugapi->system_call_address); tree_parse(node, "./data 0x%x", emul_call_instruction); node = tree_parse(root, "/openprom/init/data@0x%lx", (unsigned long)bugapi->system_call_address + 4); tree_parse(node, "./psim,description \"return from interrupt instruction"); tree_parse(node, "./real-address 0x%lx", (unsigned long)bugapi->system_call_address + 4); tree_parse(node, "./data 0x%x", emul_rfi_instruction); /* patch the end of the system call instruction so that it contains a loop to self instruction and point all the cpu's at this */ node = tree_parse(root, "/openprom/init/data@0x%lx", (unsigned long)bugapi->stall_cpu_loop_address); tree_parse(node, "./psim,description \"cpu-loop instruction"); tree_parse(node, "./real-address 0x%lx", (unsigned long)bugapi->stall_cpu_loop_address); tree_parse(node, "./data 0x%lx", (unsigned long)emul_loop_instruction); if (image != NULL) tree_parse(root, "/openprom/init/stack/stack-type %s", (image->xvec->flavour == bfd_target_elf_flavour ? "ppc-elf" : "ppc-xcoff")); if (image != NULL) { filename = tree_quote_property (bfd_get_filename(image)); tree_parse(root, "/openprom/init/load-binary/file-name %s", filename); free (filename); } return bugapi; }
psim_options(device *root, char **argv) { device *current = root; int argp; if (argv == NULL) return NULL; argp = 0; while (argv[argp] != NULL && argv[argp][0] == '-') { char *p = argv[argp] + 1; char *param; while (*p != '\0') { switch (*p) { default: psim_usage(0); error (""); break; case 'c': param = find_arg("Missing <count> option for -c (max-iterations)\n", &argp, argv); tree_parse(root, "/openprom/options/max-iterations %s", param); break; case 'e': param = find_arg("Missing <emul> option for -e (os-emul)\n", &argp, argv); tree_parse(root, "/openprom/options/os-emul %s", param); break; case 'E': /* endian spec, ignored for now */ param = find_arg("Missing <endian> option for -E (target-endian)\n", &argp, argv); if (strcmp (param, "big") == 0) tree_parse (root, "/options/little-endian? false"); else if (strcmp (param, "little") == 0) tree_parse (root, "/options/little-endian? true"); else { printf_filtered ("Invalid <endian> option for -E (target-endian)\n"); psim_usage (0); } break; case 'f': param = find_arg("Missing <file> option for -f\n", &argp, argv); psim_merge_device_file(root, param); break; case 'h': case '?': psim_usage(1); break; case 'H': psim_usage(2); break; case 'i': if (isdigit(p[1])) { tree_parse(root, "/openprom/trace/print-info %c", p[1]); p++; } else { tree_parse(root, "/openprom/trace/print-info 1"); } break; case 'I': tree_parse(root, "/openprom/trace/print-info 2"); tree_parse(root, "/openprom/options/model-issue %d", MODEL_ISSUE_PROCESS); break; case 'm': param = find_arg("Missing <model> option for -m (model)\n", &argp, argv); tree_parse(root, "/openprom/options/model \"%s", param); break; case 'n': param = find_arg("Missing <nr-smp> option for -n (smp)\n", &argp, argv); tree_parse(root, "/openprom/options/smp %s", param); break; case 'o': param = find_arg("Missing <dev-spec> option for -o\n", &argp, argv); if (memcmp(param, "mpc860c0", 8) == 0) { if (param[8] == '\0') tree_parse(root, "/options/mpc860c0 5"); else if (param[8] == '=' && is_num(param+9, 1, 10, 0)) { tree_parse(root, "/options/mpc860c0 %s", param+9); } else error("Invalid mpc860c0 option for -o\n"); } else current = tree_parse(current, "%s", param); break; case 'r': param = find_arg("Missing <ram-size> option for -r (oea-memory-size)\n", &argp, argv); tree_parse(root, "/openprom/options/oea-memory-size %s", param); break; case 't': param = find_arg("Missing <trace> option for -t (trace/*)\n", &argp, argv); if (param[0] == '!') tree_parse(root, "/openprom/trace/%s 0", param+1); else tree_parse(root, "/openprom/trace/%s 1", param); break; case '-': /* it's a long option of the form --optionname=optionvalue. Such options can be passed through if we are invoked by gdb. */ if (strstr(argv[argp], "architecture") != NULL) { /* we must consume the argument here, so that we get out of the loop. */ p = argv[argp] + strlen(argv[argp]) - 1; printf_filtered("Warning - architecture parameter ignored\n"); } else error("Unrecognized option"); break; } p += 1; } argp += 1; } /* force the trace node to process its options now *before* the tree initialization occures */ device_ioctl(tree_find_device(root, "/openprom/trace"), NULL, 0, device_ioctl_set_trace); { void semantic_init(device* root); semantic_init(root); } /* return where the options end */ return argv + argp; }
void build_tree(struct bu_list *br, struct region *rp) { tree_parse(br, rp->reg_treetop); }