Example #1
0
File: dojump.c Project: 0mp/freebsd
void
do_pending_stack_adjust (void)
{
  if (inhibit_defer_pop == 0)
    {
      if (pending_stack_adjust != 0)
        adjust_stack (GEN_INT (pending_stack_adjust));
      pending_stack_adjust = 0;
    }
}
Example #2
0
void load(int r, SValue* sv)
{
  int fr,ft,fc;
  int length;
  int align;
  int v,sign,t;
  SValue v1;
  pr("; load %d\n",r);
  pr("; type %d reg 0x%x extra 0x%x\n",sv->type.t,sv->r,sv->type.extra);
  fr = sv->r;
  ft = sv->type.t;
  fc = sv->c.ul;
  
  length = type_size(&sv->type, &align);
  if((ft & VT_BTYPE) == VT_LLONG) length = 2; // long longs are handled word-wise
  if(ll_workaround) length = 4;

  //pr("; load r 0x%x fr 0x%x ft 0x%x fc 0x%x\n",r,fr,ft,fc);

#if 0
  // FIXME: Does that make sense?
  if(fc>0) sign=0;
  else {
    sign = 1;
    fc = -fc;
  }
#endif
  
  int base = -1;
  v = fr & VT_VALMASK;
  if(fr & VT_LVAL) {
    if(v == VT_LLOCAL) {
      v1.type.t = VT_PTR;
      v1.r = VT_LOCAL | VT_LVAL;
      v1.c.ul = sv->c.ul;
      load(base=10 /* lr */, &v1);
      fc=sign=0;
      v=VT_LOCAL;
    }
    else if(v == VT_CONST) {
      if(fr & VT_SYM) {	// deref symbol + displacement
        char* sy = get_sym_str(sv->sym);
        if(is_float(ft)) {
          pr("; fld%d [%s + %d], tcc__f%d\n", length, sy, fc, r - TREG_F0);
          switch(length) {
          case 4: pr("lda.l %s + %d\nsta.b tcc__f%d\nlda.l %s + %d + 2\nsta.b tcc__f%dh\n", sy, fc, r - TREG_F0, sy, fc, r - TREG_F0); break;
          default: error("ICE 1");
          }
        }
        else {
          pr("; ld%d [%s + %d], tcc__r%d\n", length, sy, fc, r);
          // FIXME: This implementation is moronic
          if(fc > 65535) error("index too big");
          switch(length) {
          case 1:
            pr("lda.w #0\nsep #$20\nlda.l %s + %d\nrep #$20\n", sy, fc);
            if(!(ft & VT_UNSIGNED)) pr("xba\nxba\nbpl +\nora.w #$ff00\n+\n");
            pr("sta.b tcc__r%d\n", r);
            break;
          //case 2: pr("stz.b tcc__r%dh\nldx #%d\nlda.l %s,x\nsta.b tcc__r%d\n", r, fc, sy, r); break;
          case 2: pr("lda.l %s + %d\nsta.b tcc__r%d\n", sy, fc, r); break;
          case 4: pr("lda.l %s + %d\nsta.b tcc__r%d\nlda.l %s + %d + 2\nsta.b tcc__r%dh\n", sy, fc, r, sy, fc, r); break;
          default: error("ICE 1");
          }
        }
      }
      else {	// deref constant pointer
        //error("ld [%d],tcc__r%d\n",fc,r);
        pr("; deref constant ptr ld [%d],tcc__r%d\n", fc, r);
        if(is_float(ft)) {
          error("dereferencing constant float pointers unimplemented\n");
        }
        else {
          switch(length) {
          case 1:
            pr("lda.w #0\nsep #$20\nlda.l %d\nrep #$20\n", fc);
            if(!(ft & VT_UNSIGNED)) pr("xba\nxba\nbpl +\nora.w #$ff00\n+\n");
            pr("sta.b tcc__r%d\n", r);
            break;
          case 2: pr("lda.l %d\nsta.b tcc__r%d\n", fc, r); break;
          case 4: pr("lda.l %d\nsta.b tcc__r%d\nlda.l %d + 2\nsta.b tcc__r%dh\n", fc, r, fc, r); break;
          default: error("ICE 1");
          }
        }
      }
      return;
    }
    else if(v < VT_CONST) { // deref pointer in register
      base = v;
      fc = sign = 0;
      v = VT_LOCAL;
    }
    
    if(v == VT_LOCAL) {
      if(is_float(ft)) {
        if(base == -1) {
          pr("; fld%d [sp,%d],tcc__f%d\n", length, fc, r - TREG_F0);
          if(length != 4) error("ICE 2f");
          fc = adjust_stack(fc, args_size + 2);
          pr("lda %d + __%s_locals + 1,s\nsta.b tcc__f%d\nlda %d + __%s_locals + 1,s\nsta.b tcc__f%dh\n", fc+args_size, current_fn, r - TREG_F0, fc+args_size+2, current_fn, r - TREG_F0);
          fc = restore_stack(fc);
        }
        else {
          pr("; fld%d [tcc__r%d,%d],tcc__f%d\n", length, base, fc, r - TREG_F0);
          if(length != 4) error("ICE 3f");
          pr("ldy #%d\nlda.b [tcc__r%d],y\nsta.b tcc__f%d\niny\niny\nlda.b [tcc__r%d], y\nsta.b tcc__f%dh\n", fc, base, r - TREG_F0, base, r - TREG_F0);
        }
      }
      else {
        if(base == -1) {	// value of local at fc
          pr("; ld%d [sp,%d],tcc__r%d\n",length,fc,r);
          //if(length == 2 && fc == -88 && r == 0) asm("int $3");
          fc = adjust_stack(fc, args_size + 2);
          switch(length) {
            case 1:
              pr("lda.w #0\nsep #$20\nlda %d + __%s_locals + 1,s\nrep #$20\n", fc+args_size, current_fn);
              if(!(ft & VT_UNSIGNED)) pr("xba\nxba\nbpl +\nora.w #$ff00\n+\n");
              pr("sta.b tcc__r%d\n", r);
              break;
            //case 2: pr("stz.b tcc__r%dh\nlda %d + __%s_locals + 1,s\nsta.b tcc__r%d\n", r, fc+args_size, current_fn, r); break;
            case 2: pr("lda %d + __%s_locals + 1,s\nsta.b tcc__r%d\n", fc+args_size, current_fn, r); break;
            case 4: pr("lda %d + __%s_locals + 1,s\nsta.b tcc__r%d\nlda %d + __%s_locals + 1,s\nsta.b tcc__r%dh\n", fc+args_size, current_fn, r, fc+args_size + 2, current_fn, r); break;
            default: error("ICE 2"); break;
          }
          fc = restore_stack(fc);
        }
        else {	// value of array member r[fc]
          pr("; ld%d [tcc__r%d,%d],tcc__r%d\n",length, base, fc, r);
          switch(length) {
            case 1:
              pr("lda.w #0\n");
              if(!fc) pr("sep #$20\nlda.b [tcc__r%d]\nrep #$20\n", base);
              else pr("ldy #%d\nsep #$20\nlda.b [tcc__r%d],y\nrep #$20\n", fc, base);
              if(!(ft & VT_UNSIGNED)) pr("xba\nxba\nbpl +\nora.w #$ff00\n+\n");
              pr("sta.b tcc__r%d\n", r);
              break;
            //case 2: pr("stz.b tcc__r%dh\nldy #%d\nlda.b [tcc__r%d],y\nsta.b tcc__r%d\n", r, fc, base, r); break;
            case 2:
              if(!fc) pr("lda.b [tcc__r%d]\nsta.b tcc__r%d\n", base, r);
              else pr("ldy #%d\nlda.b [tcc__r%d],y\nsta.b tcc__r%d\n", fc, base, r);
              break;
            case 4: pr("ldy #%d\nlda.b [tcc__r%d],y\nsta.b tcc__r%d\niny\niny\nlda.b [tcc__r%d],y\nsta.b tcc__r%dh\n", fc, base, r, base, r); break;
            default: error("ICE 3"); break;
          }
        }
      }
      return;
    }
  } else {	// VT_LVAL
    if(v == VT_CONST) {
      if(fr & VT_SYM) {	// symbolic constant
        //greloc(cur_text_section, sv->sym, ind, R_DATA_32);
        char* sy = get_sym_str(sv->sym);
        pr("; ld%d #%s + %d, tcc__r%d (type 0x%x)\n", length,sy, fc, r, ft);
        if(length != PTR_SIZE) pr("; FISHY! length <> PTR_SIZE! (may be an array)\n");
        pr("lda.w #:%s\nsta.b tcc__r%dh\nlda.w #%s + %d\nsta.b tcc__r%d\n", sy, r, sy, fc, r);
      }
      else {	// numeric constant
        pr("; ld%d #%d,tcc__r%d\n",length,sv->c.ul,r);
        if((ft & VT_BTYPE) == VT_BOOL) {
          sv->c.ul = sv->c.ul? 1: 0;
        }
        switch(length) {
          case 1:
            if (ft & VT_UNSIGNED) {
              pr("lda.w #%d\n", sv->c.ul & 0xff);
            }
            else {
              pr("lda.w #%d\n", ((short)((sv->c.ul & 0xff) << 8)) >> 8);
            }
            pr("sta.b tcc__r%d\n", r);
            break;
          //case 2: pr("stz.b tcc__r%dh\nlda.w #%d\nsta.b tcc__r%d\n", r, sv->c.ul & 0xffff, r); break;
          case 2: pr("lda.w #%d\nsta.b tcc__r%d\n", sv->c.ul & 0xffff, r); break;
          case 4: pr("lda.w #%d\nsta.b tcc__r%d\nlda.w #%d\nsta.b tcc__r%dh\n", sv->c.ul & 0xffff, r, sv->c.ul >> 16, r); break;
          default: error("ICE 4");
        }
      }
      return;
    }
    else if(v == VT_LOCAL) {
      if(fr & VT_SYM) {
        error("symbol");
        char* sy = get_sym_str(sv->sym);
        pr("; LOCAL ld%d #%s, tcc__r%d (type 0x%x)\n", length,sy, r, ft);
      }
      else {	// local pointer
        pr("; ld%d #(sp) + %d,tcc__r%d (fr 0x%x ft 0x%x fc 0x%x)\n",length,sv->c.ul,r,fr,ft,fc);
        // pointer; have to ensure the upper word is correct (page 0)
        pr("stz.b tcc__r%dh\ntsa\nclc\nadc #(%d + __%s_locals + 1)\nsta.b tcc__r%d\n", r, sv->c.ul + args_size, current_fn, r);
      }
      return;
    }
    else if(v == VT_CMP) {
      error("cmp");
      return;
    }
    else if(v == VT_JMP || v == VT_JMPI) {
      t = v & 1; // inverted or not
      pr("; jmpr(i) v 0x%x r 0x%x fc 0x%x\n",v,r,fc);
      pr("lda #%d\nbra +\n", t);
      gsym(fc);
      //pr("lda #%d\n+ stz tcc__r%dh\nsta tcc__r%d\n", t^1, r,r);
      pr("lda #%d\n+\nsta.b tcc__r%d\n", t^1, r);	// stz rXh seems to be unnecessary (we only look at the lower word)
      return;
    }
    else if(v < VT_CONST) {	// register value
      if(is_float(ft)) {
        //error("float 1");
        v -= TREG_F0;
        r -= TREG_F0;
        pr("; fmov tcc__f%d, tcc__f%d\n", v, r);
        pr("lda.b tcc__f%d\nsta.b tcc__f%d\nlda.b tcc__f%dh\nsta.b tcc__f%dh\n", v, r, v, r);
      }
      else {
        pr("; mov tcc__r%d, tcc__r%d\n",v,r);
        pr("lda.b tcc__r%d\nsta.b tcc__r%d\nlda.b tcc__r%dh\nsta.b tcc__r%dh\n", v, r, v, r);
      }
      return;
    }
  }
Example #3
0
int dumpcore(pid_t pid)
{
	int r, seg, fd;
	vir_bytes len;
	off_t off, seg_off;
	long data;
	struct mem_map segs[NR_LOCAL_SEGS];
	struct proc procentry;
	ssize_t w;
	char core_name[PATH_MAX];

	/* Get the process table entry for this process. */
	len = sizeof(struct proc) / sizeof(long);
	for (off = 0; off < len; off++)
	{
		errno = 0;
		data = ptrace(T_GETUSER, pid, off * sizeof(long), 0);
		if  (data == -1 && errno != 0) 
		{
			perror("ptrace(T_GETUSER)");
			return 1;
		}

		((long *) &procentry)[off] = data;
	}

	memcpy(segs, procentry.p_memmap, sizeof(segs));

	/* Correct and reduce the stack segment. */
	r = adjust_stack(pid, &segs[S]);
	if (r != 0)
		goto error;

	/* Create a core file with a temporary, unique name. */
	sprintf(core_name, "core.%d", pid);

	if((fd = open(core_name, O_CREAT|O_EXCL|O_WRONLY, 0600)) < 0) {
		fprintf(stderr, "couldn't open %s (%s)\n", core_name,
			strerror(errno));
		return 1;
	}

	/* Write out the process's segments. */
	if((w=write(fd, segs, sizeof(segs))) != sizeof(segs)) {
		if(w < 0) printf("write error: %s\n", strerror(errno));
		printf( "segs write failed: %d/%d\n", w, sizeof(segs));
		goto error;
	}

	/* Write out the whole kernel process table entry to get the regs. */
	if((w=write(fd, &procentry, sizeof(procentry))) != sizeof(procentry)) {
		if(w < 0) printf("write error: %s\n", strerror(errno));
		printf( "proc write failed: %d/%d\n", w, sizeof(procentry));
		goto error;
	}

	/* Loop through segments and write the segments themselves out. */
	for (seg = 0; seg < NR_LOCAL_SEGS; seg++) {
		len= segs[seg].mem_len << CLICK_SHIFT;
		seg_off= segs[seg].mem_vir << CLICK_SHIFT;
		r= write_seg(fd, pid, seg, seg_off, len);
		if (r != 0)
			goto error;
	}

	/* Give the core file its final name. */ 
	if (rename(core_name, "core")) {
		perror("rename");
		goto error;
	}

	close(fd);

	return 0;

error:
	close(fd);

	unlink(core_name);

	return 1;
}