Exemplo n.º 1
0
void debugger(void)
{
    extern u_int history[3];
    extern int irq0_pending;
    static int in_debugger = 0;
    char buf[80], buf2[80], reg[4];
    u_int i, j, k;

    if (in_debugger)
	return;
    in_debugger ++;
    no_exceptions = 1;

#if 0
    char *textbuf;
    textbuf = (char*)malloc(TEXT_SIZE);
    if (!textbuf) {
	leaveemu(ERR_MEM);
    }
    memcpy(textbuf, SCR_STATE.virt_address, TEXT_SIZE);
#endif

    push_debug_flags();
    DEBUG_OFF();

    for(;;) {
	printf("\ndbg> ");
	if (fgets(buf, 80, stdin) == NULL)
	    leaveemu(0);
	buf[strlen(buf)-1] = 0;  /* kill \n */
	
	if (*buf==0) {
	    continue;
	} else if (!strcmp(buf, "help")) {
	    usage();
	} else if (!strcmp(buf, "r")) {
	    show_regs(0, 0);
	} else if (!strcmp(buf, "logue")) {
	    printf("prologue:  0x%08x\n", UAREA.u_entprologue);
	    printf("epilogue:  0x%08x\n", UAREA.u_entepilogue);
	} else if (!strcmp(buf, "exc")) {
	    printf("current exception:       #0x%x, 0x%x\n", vm86s.trapno, vm86s.err);
	    printf("pending guest exception: ");
	    if (vmstate.exc)
		printf("#0x%x, 0x%x\n", vmstate.exc_vect, vmstate.exc_erc);
	    else
		printf("none\n");
	} else if (!strcmp(buf, "cr")) {
	    show_cregs();
	} else if (!strcmp(buf, "g")) {
	    REG(eflags) &= ~TF_MASK;
	    break;
	} else if (!strcmp(buf, "q") || !strcmp(buf, "quit")) {
	    leaveemu(0);
	} else if (!strcmp(buf, "disks")) {
	    print_disks();
	} else if (!strcmp(buf, "ptmap")) {
	    /* everything is in k to avoid overflows */
	    u_int granularity = 4*1024;
	    u_int width = 64;
	    printf("granularity:  0x%08x\n", granularity*1024);

	    for (i=0; i < (4*1024*1024)/(width*granularity); i++) {
		u_int start = i*width*granularity;
		printf("0x%08x  ", start*1024);
		for (j=0; j<width; j++) {
		    int gp = 0, hp = 0;
		    for (k=0; k < granularity/NBPG; k++) {
			u_int pte, err=0;
			pte = sys_read_pte(k*NBPG + (j*granularity + i*width*granularity)*1024, 0, vmstate.eid, &err);
			if (err == -E_NOT_FOUND) {
			    err = pte = 0;
			}			    
			if (err == 0) {
			    if (pte&1) {
				if (pte & PG_GUEST)
				    gp = 1;
				else
				    hp = 1;
			    }
			}
		    }
		    if (!gp && !hp)
			printf("-");
		    else if (gp && hp)
			printf("+");
		    else if (gp && !hp)
			printf("g");
		    else
			printf("h");
		}
		printf("\n");
	    }
#if 0
	} else if (!strcmp(buf, "memmap")) {
	    memcheck_dump();
#endif
	} else if (sscanf(buf, "port %x", &i) == 1) {
	    print_port(i);
	} else if (sscanf(buf, "int %x", &i) == 1) {
	    pop_debug_flags();
	    push_debug_flags();
	    no_exceptions = 0;
	    do_int(i);
	    no_exceptions = 1;
	    DEBUG_OFF();
	} else if (sscanf(buf, "gdt %x", &i) == 1) {
	    struct descr *sd;
	    if (set_get_any(&vmstate.g_gdt_base, (u_int*)&sd)) {
		printf("no gdt is defined\n");
		continue;
	    }
	    print_dt_entry(i, sd);
	} else if (sscanf(buf, "idt %x", &i) == 1) {
	    print_dt_entry(i, (struct descr *)vmstate.g_idt_base);
	} else if (sscanf(buf, "ro %x", &i) == 1) {
	    protect_range(PGROUNDDOWN(i), NBPG);
	} else if (sscanf(buf, "rw %x", &i) == 1) {
	    unprotect_range(PGROUNDDOWN(i), NBPG);
	} else if (!strcmp(buf, "history")) {
	    printf("most recent trap eip:  %x  %x  %x\n", history[2], history[1], history[0]);
	} else if (!strcmp(buf, "irq")) {
	    struct gate_descr *sg = (struct gate_descr *)vmstate.g_idt_base + hardware_irq_number(0);
	    for (i=0; i<16; i++) {
		printf("irq %2d %s, handled by idt[%2d], function @ 0x%08x\n", i, irq_disabled(i) ? "disabled" : " enabled",
		       hardware_irq_number(i), GATE_OFFSET(sg+i));
	    }	    
	} else if (sscanf(buf, "dump %x:%x %x", &i, &j, &k) == 2) {
	    dump_memory((i<<4)+j, k);
	} else if (sscanf(buf, "dump %x:%x", &i, &j) == 2) {
	    dump_memory((i<<4)+j, 0x80);
	} else if (sscanf(buf, "dump %x %x", &i, &j) == 2) {
	    dump_memory(i, j);
	} else if (sscanf(buf, "dump %x", &i) == 1) {
	    dump_memory(i, 0x80);
	} else if (!strcmp(buf, "dump")) {
	    dump_memory(dump_offset, 0x80);
	} else if (sscanf(buf, "search %x %79s", &i, buf2) == 2) {
	    search_memory(i, buf2);
	} else if (!strcmp(buf, "debug on")) {
	    pop_debug_flags();
	    DEBUG_ON();
	    push_debug_flags();
	} else if (!strcmp(buf, "debug off")) {
	    pop_debug_flags();
	    DEBUG_OFF();
	    push_debug_flags();
	} else if (sscanf(buf, "pte %x", &i) == 1) {
	    Bit32u host_pte = 0;
	    
	    if (! (vmstate.cr[0] & PG_MASK)) {
	    	printf("guest paging not enabled\n");
		printf("guest_phys_to_host_phys(0x%08x) = 0x%08x\n", i, guest_phys_to_host_phys(i));
	    } else {
		Bit32u gpte = guest_pte(i);
		
		printf("guest cr3           0x%08x\n", vmstate.cr[3]);
		printf("guest 0x%08x -> 0x%08x\n", i, gpte);
		printf("guest_phys_to_host_phys(0x%08x) = 0x%08x\n", gpte & ~PGMASK, guest_phys_to_host_phys(gpte & ~PGMASK));
	    }
	    get_host_pte(i, &host_pte);
	    printf("host  0x%08x -> 0x%08x\n", i, host_pte);
	} else if (sscanf(buf, "gp2hp %x", &i) == 1) {
	    printf("&vmstate.gp2hp[0] = %p, 0x%x mappings\n", vmstate.gp2hp, vmstate.ppages);
	    if (i<vmstate.ppages)
		printf("gp2hp[%x] = 0x%08x\n", i, vmstate.gp2hp[i]);
	} else if (!strcmp(buf, "cr3")) {
	    u_int cr3;
	    Set *set = &vmstate.cr3;

	    printf("cr3 register:  0x%08x\n", vmstate.cr[3]);
	    printf("cr3 set     :  ");
	    for(set_iter_init(set); set_iter_get(set, &cr3); set_iter_next(set)) {
		printf("0x%08x ", cr3);
	    }
	    printf("\n");
	} else if (!strcmp(buf, "dt")) {
	    print_dt_mappings();
	    printf("h gdt base:lim  0x%08x:0x%04x\n", vmstate.h_gdt_base, vmstate.h_gdt_limit);
	    printf("h idt base:lim  0x%08x:0x%04x\n", vmstate.h_idt_base, vmstate.h_idt_limit);
	} else if (!strcmp(buf, "memory")) {
	    printf("0x%08x real physical pages (%3d megs)\n", PHYSICAL_PAGES, PHYSICAL_MEGS_RAM);
	    printf("0x%08x fake physical pages (%3d megs)\n", vmstate.ppages, config.phys_mem_size/1024);
#if 0
	    printf("Eavesdropping on Linux:\n");
	    printf("RAM               %dk\n",   *((Bit32u*)0x901e0));
	    printf("pointing device?  0x%x\n",  *((Bit16u*)0x901ff));
	    printf("APM?              0x%x\n",  *((Bit16u*)0x90040));
#endif
	    ASSERT(vmstate.ppages == config.phys_mem_size*1024/NBPG);
	} else if (sscanf(buf, "%2s=%x", reg, &i) == 2 || 
		   sscanf(buf, "%3s=%x", reg, &i) == 2) {
	    int r = reg_s2i(reg);
	    if (r == -1) {
		printf("unknown register\n");
	    } else if (r==14) {
		REG(eip) = i;
	    } else if (r<=REGNO_EDI) {
		set_reg(r, i, 4);  /* normal regs */
	    } else {
		set_reg(r, i, 2);  /* segment regs */
	    }
	} else {
	    printf("huh?\n");
	}
    }

    pop_debug_flags();

#if 0
    if (debug_flags == 0)
	memcpy(SCR_STATE.virt_address, textbuf, TEXT_SIZE);
    free(textbuf);
#endif

    REG(eflags) |= RF;

    in_debugger --;
    no_exceptions = 0;
    irq0_pending = 0;
}
Exemplo n.º 2
0
/* load an EXOS_MAGIC binary */
int
__do_simple_load (int fd, struct Env *e)
{
  // struct Uenv cu;

  u_int start_text_addr, start_text_pg;
  struct exec hdr;
  u_int text_size, data_size, bss_size, overlap_size;
  u_int envid = e->env_id;


  /* read a.out headers */
  if (lseek(fd, 0, SEEK_SET) == -1 ||
      read(fd, &hdr, sizeof(hdr)) != sizeof(hdr) ||
      lseek(fd, sizeof(hdr) + hdr.a_text, SEEK_SET) == -1 ||
      read(fd, &start_text_addr, sizeof(start_text_addr)) != 
          sizeof(start_text_addr)) 
  {
    errornf("Invalid executable format.\n");
  }

  start_text_pg = PGROUNDDOWN(start_text_addr);
  text_size = hdr.a_text + sizeof(hdr);
  data_size = hdr.a_data;
  if (text_size % NBPG) {
    data_size += text_size % NBPG;
    text_size = PGROUNDDOWN(text_size);
  }
  bss_size = hdr.a_bss;
  
  
  if (!(data_size % NBPG))
    overlap_size = 0;
  else
  {
    /* read in the page that contains both bss and inited data */
    u_int temp_page;
     
    temp_page = (u_int)__malloc(NBPG);
    overlap_size = NBPG;
   
    if (temp_page == 0 || 
	lseek(fd, text_size + PGROUNDDOWN(data_size), SEEK_SET) == -1 ||
        read(fd, (void*)temp_page, data_size % NBPG) != data_size % NBPG ||
        _exos_insert_pte
	  (0, vpt[PGNO(temp_page)], start_text_pg + text_size +
	   PGROUNDDOWN(data_size), 0, envid, 0, NULL) != 0) 
    {
      _exos_self_unmap_page(0, temp_page);
      error("Error mmaping text segment\n");
    }
    
    bzero((void*)temp_page + (data_size % NBPG),
          NBPG - (data_size % NBPG));
    _exos_self_unmap_page(0, temp_page);
    __free((void*)temp_page);
    bss_size -= NBPG - (data_size % NBPG);
    bss_size = PGROUNDUP(bss_size);
    data_size = PGROUNDDOWN(data_size);

  }


  /* mmap the text segment readonly */
  if ((u_int)__mmap((void*)start_text_pg, text_size, PROT_READ  | PROT_EXEC, 
		    MAP_FILE | MAP_FIXED | MAP_COPY, fd, (off_t)0, 0, envid)
	!= start_text_pg) 
  {
    errornf("Error mmaping text segment\n");
  }

  /* mmap the data segment read/write */
  if ((u_int)__mmap((void*)(start_text_pg + text_size), data_size,
		    PROT_READ | PROT_WRITE | PROT_EXEC,
		    MAP_FILE | MAP_FIXED | MAP_COPY,
		    fd, text_size, (off_t)0, envid)
	!= start_text_pg + text_size) 
  {
    errornf("Error mmaping data segment\n");
  }

#if 0 /* we set up a stack page later on when setting up arguments */
  /* allocate a stack page */
  if (_exos_insert_pte (0, PG_U|PG_W|PG_P, USTACKTOP-NBPG, 0, envid, 0,
			NULL) < 0) 
  {
    errornf("could not allocate stack\n");
  }
#endif

  /* set the entry point */
  assert(e->env_id == envid);
  e->env_tf.tf_eip = start_text_addr;

  return 1;
}
Exemplo n.º 3
0
//PAGEBREAK: 41
void
trap(struct trapframe *tf)
{
  if(tf->trapno == T_SYSCALL){
    if(proc->killed)
      exit();
    proc->tf = tf;
    syscall();
    if(proc->killed)
      exit();
    return;
  }
  
  switch(tf->trapno){
  case T_IRQ0 + IRQ_TIMER:
    if(cpu->id == 0){
      acquire(&tickslock);
      ticks++;
      wakeup(&ticks);
      release(&tickslock);
    }
    lapiceoi();
    break;
  case T_IRQ0 + IRQ_IDE:
    ideintr();
    lapiceoi();
    break;
  case T_IRQ0 + IRQ_IDE+1:
    // Bochs generates spurious IDE1 interrupts.
    break;
  case T_IRQ0 + IRQ_KBD:
    kbdintr();
    lapiceoi();
    break;
  case T_IRQ0 + IRQ_COM1:
    uartintr();
    lapiceoi();
    break;
  case T_IRQ0 + 7:
  case T_IRQ0 + IRQ_SPURIOUS:
    cprintf("cpu%d: spurious interrupt at %x:%x\n",
            cpu->id, tf->cs, tf->eip);
    lapiceoi();
    break;
    
  //PAGEBREAK: 13
  default:
    if(proc == 0 || (tf->cs&3) == 0){
      // In kernel, it must be our mistake.
      
      cprintf("unexpected trap %d from cpu %d eip %x (cr2=0x%x)\n",
              tf->trapno, cpu->id, tf->eip, rcr2());
      panic("trap");
    }
    
    if(tf->trapno == T_PGFLT){
      
      char * mem;
      uint a;
      a = PGROUNDDOWN(rcr2());
      if(a >= KERNBASE){
	proc->killed = 1;
	break;
      }
      if(proc->sz >= KERNBASE){
	return 0;
      }
      if(proc->sz < proc->old_sz)
	return proc->old_sz;
      
      mem = kalloc();
      if(mem == 0){
	cprintf("trap - pagefault: out of memory\n");
	deallocuvm(proc->pgdir, proc->old_sz,proc->sz);
	break;
      }
      
      //clean the page
      memset(mem, 0, PGSIZE);
      
      
      
      mappages(proc->pgdir, (char*) a, PGSIZE, v2p(mem), PTE_W | PTE_U);
      break; 
    }
    
    // In user space, assume process misbehaved.
    cprintf("pid %d %s: trap %d err %d on cpu %d "
            "eip 0x%x addr 0x%x--kill proc\n",
            proc->pid, proc->name, tf->trapno, tf->err, cpu->id, tf->eip, 
            rcr2());
    proc->killed = 1;
  }

  // Force process exit if it has been killed and is in user space.
  // (If it is still executing in the kernel, let it keep running 
  // until it gets to the regular system call return.)
  if(proc && proc->killed && (tf->cs&3) == DPL_USER)
    exit();

  // Force process to give up CPU on clock tick.
  // If interrupts were on while locks held, would need to check nlock.
  if(proc && proc->state == RUNNING && tf->trapno == T_IRQ0+IRQ_TIMER)
    yield();

  // Check if the process has been killed since we yielded
  if(proc && proc->killed && (tf->cs&3) == DPL_USER)
    exit();
}
Exemplo n.º 4
0
u_int
__load_prog_fd(int fd, int _static, u_int envid)
{
  u_int start_text_addr;
  struct exec hdr;
  u_int text_size, data_size, bss_size, overlap_size;
  u_int dynamic, start_text_pg;

  /* read a.out headers */
  if (lseek(fd, 0, SEEK_SET) == -1 ||
      read(fd, &hdr, sizeof(hdr)) != sizeof(hdr) ||
      lseek(fd, sizeof(hdr) + hdr.a_text, SEEK_SET) == -1 ||
      read(fd, &dynamic, sizeof(dynamic)) != sizeof(dynamic) ||
      read(fd, &start_text_addr, sizeof(start_text_addr)) !=
      sizeof(start_text_addr)) {
    fprintf(stderr,"Invalid executable format.\n");
    errno = ENOEXEC;
    goto err;
  }
  start_text_pg = PGROUNDDOWN(start_text_addr);
  text_size = hdr.a_text + sizeof(hdr);
  data_size = hdr.a_data;
  if (text_size % NBPG) {
    data_size += text_size % NBPG;
    text_size = PGROUNDDOWN(text_size);
  }
  bss_size = hdr.a_bss;
  if (_static) {
    if (!(data_size % NBPG))
      overlap_size = 0;
    else
      {
	/* read in the page that contains both bss and inited data */
	u_int temp_page;
	
	temp_page = (u_int)__malloc(NBPG);
	overlap_size = NBPG;
	if (temp_page == 0 ||
	    lseek(fd, text_size + PGROUNDDOWN(data_size),
		  SEEK_SET) == -1 ||
	    read(fd, (void*)temp_page, data_size % NBPG) !=
	    data_size % NBPG ||
	    _exos_insert_pte(0, vpt[PGNO(temp_page)],
			     start_text_pg + text_size +
			     PGROUNDDOWN(data_size), 0, envid, 0, NULL) != 0) {
	  _exos_self_unmap_page(0, temp_page);
	  __free((void*)temp_page);
	  fprintf(stderr,"Error mmaping text segment\n");
	  goto err;
	}
	bzero((void*)temp_page + (data_size % NBPG),
	      NBPG - (data_size % NBPG));
	_exos_self_unmap_page(0, temp_page);
	__free((void*)temp_page);
	bss_size -= NBPG - (data_size % NBPG);
	bss_size = PGROUNDUP(bss_size);
	data_size = PGROUNDDOWN(data_size);
      }
    /* mmap the text segment readonly */
    if ((u_int)__mmap((void*)start_text_pg, text_size,
		      PROT_READ  | PROT_EXEC, 
		      MAP_FILE | MAP_FIXED | MAP_COPY, fd, (off_t)0, 0,
		      envid)
	!= start_text_pg) {
      fprintf(stderr,"Error mmaping text segment\n");
      goto err;
    }
    /* mmap the data segment read/write */
    if ((u_int)__mmap((void*)(start_text_pg + text_size), data_size,
		      PROT_READ | PROT_WRITE | PROT_EXEC,
		      MAP_FILE | MAP_FIXED | MAP_COPY,
		      fd, text_size, (off_t)0, envid)
	!= start_text_pg + text_size) {
      fprintf(stderr,"Error mmaping data segment\n");
      goto err;
    }
  } else {
    /* if dynamic... */
    u_int mflags;
    if (!(data_size % NBPG))
      overlap_size = 0;
    else
      {
	/* read in the page that contains both bss and inited data */
	overlap_size = NBPG;
	if (_exos_self_insert_pte(0, PG_P | PG_W | PG_U,
				  start_text_pg + text_size +
				  PGROUNDDOWN(data_size), 0, NULL) < 0 ||
	    lseek(fd, text_size + PGROUNDDOWN(data_size),
		  SEEK_SET) == -1 ||
	    read(fd, (void*)(start_text_pg + text_size +
			     PGROUNDDOWN(data_size)),
		 data_size % NBPG) != data_size % NBPG) {
	  fprintf(stderr,"Error mmaping text segment\n");
	  goto err;
	}
	bzero((void*)(start_text_pg + text_size + data_size),
	      NBPG - (data_size % NBPG));
	bss_size -= NBPG - (data_size % NBPG);
	bss_size = PGROUNDUP(bss_size);
	data_size = PGROUNDDOWN(data_size);
      }
    /* mmap the text segment readonly */
    mflags = MAP_FILE | MAP_FIXED;
    if (getenv("NO_DEMAND_LOAD"))
      mflags |= MAP_COPY;
    else
      mflags |= MAP_SHARED;
    if ((u_int)mmap((void*)start_text_pg, text_size,
		    PROT_READ | PROT_EXEC, 
		    mflags, fd, (off_t)0) != start_text_pg) {
      fprintf(stderr,"Error mmaping text segment\n");
      goto err;
    }
    /* mmap the data segment read/write */
    if (!(mflags & MAP_COPY)) mflags = MAP_FILE | MAP_FIXED | MAP_PRIVATE;
    if ((u_int)mmap((void*)(start_text_pg + text_size), data_size,
		    PROT_READ | PROT_WRITE | PROT_EXEC, mflags, fd,
		    (off_t)text_size) != start_text_pg + text_size) {
      fprintf(stderr,"Error mmaping data segment: %d\n", errno);
      goto err;
    }
    /* mmap the bss as demand zero'd */
    if ((u_int)mmap((void*)(start_text_pg + text_size + data_size +
			    overlap_size),
		    bss_size, PROT_READ | PROT_WRITE | PROT_EXEC,
		    MAP_ANON | MAP_FIXED | MAP_PRIVATE,
		    (off_t)-1, 0) !=
	start_text_pg + text_size + data_size + overlap_size) {
      fprintf(stderr,"Error mmaping bss\n");
      goto err;
    }
  }

  return start_text_addr;

err:
  return 0;
}