Exemplo n.º 1
0
static void
insert_offheap(ErlOffHeap *oh, int type, Eterm id)
{
    union erl_off_heap_ptr u;
    struct insert_offheap2_arg a;
    a.type = BIN_REF;

    for (u.hdr = oh->first; u.hdr; u.hdr = u.hdr->next) {
	switch (thing_subtag(u.hdr->thing_word)) {
	case REFC_BINARY_SUBTAG:
	    if(IsMatchProgBinary(u.pb->val)) {
		InsertedBin *ib;
		int insert_bin = 1;
		for (ib = inserted_bins; ib; ib = ib->next)
		    if(ib->bin_val == u.pb->val) {
			insert_bin = 0;
			break;
		    }
		if (insert_bin) {
#if HALFWORD_HEAP
		    UWord val = (UWord) u.pb->val;
		    DeclareTmpHeapNoproc(id_heap,BIG_UINT_HEAP_SIZE*2); /* extra place allocated */
#else
		    DeclareTmpHeapNoproc(id_heap,BIG_UINT_HEAP_SIZE);
#endif
		    Uint *hp = &id_heap[0];
		    InsertedBin *nib;
#if HALFWORD_HEAP
		    int actual_need = BIG_UWORD_HEAP_SIZE(val);
		    ASSERT(actual_need <= (BIG_UINT_HEAP_SIZE*2));
		    UseTmpHeapNoproc(actual_need);
		    a.id = erts_bld_uword(&hp, NULL, (UWord) val);
#else
		    UseTmpHeapNoproc(BIG_UINT_HEAP_SIZE);
		    a.id = erts_bld_uint(&hp, NULL, (Uint) u.pb->val);
#endif
		    erts_match_prog_foreach_offheap(u.pb->val,
						    insert_offheap2,
						    (void *) &a);
		    nib = erts_alloc(ERTS_ALC_T_NC_TMP, sizeof(InsertedBin));
		    nib->bin_val = u.pb->val;
		    nib->next = inserted_bins;
		    inserted_bins = nib;
#if HALFWORD_HEAP
		    UnUseTmpHeapNoproc(actual_need);
#else
		    UnUseTmpHeapNoproc(BIG_UINT_HEAP_SIZE);
#endif
		}
	    }		
	    break;
	case FUN_SUBTAG:
	    break; /* No need to */
	default:
	    ASSERT(is_external_header(u.hdr->thing_word));
	    insert_node(u.ext->node, type, id);
	    break;
	}
    }
}
Exemplo n.º 2
0
BIF_RETTYPE
erts_debug_disassemble_1(BIF_ALIST_1)
{
    Process* p = BIF_P;
    Eterm addr = BIF_ARG_1;
    erts_dsprintf_buf_t *dsbufp;
    Eterm* hp;
    Eterm* tp;
    Eterm bin;
    Eterm mfa;
    ErtsCodeMFA *cmfa = NULL;
    BeamCodeHeader* code_hdr;
    BeamInstr *code_ptr;
    BeamInstr instr;
    BeamInstr uaddr;
    Uint hsz;
    int i;

    if (term_to_UWord(addr, &uaddr)) {
	code_ptr = (BeamInstr *) uaddr;
	if ((cmfa = find_function_from_pc(code_ptr)) == NULL) {
	    BIF_RET(am_false);
	}
    } else if (is_tuple(addr)) {
	ErtsCodeIndex code_ix;
	Module* modp;
	Eterm mod;
	Eterm name;
	Export* ep;
	Sint arity;
	int n;

	tp = tuple_val(addr);
	if (tp[0] != make_arityval(3)) {
	error:
	    BIF_ERROR(p, BADARG);
	}
	mod = tp[1];
	name = tp[2];
	if (!is_atom(mod) || !is_atom(name) || !is_small(tp[3])) {
	    goto error;
	}
	arity = signed_val(tp[3]);
	code_ix = erts_active_code_ix();
	modp = erts_get_module(mod, code_ix);

	/*
	 * Try the export entry first to allow disassembly of special functions
	 * such as erts_debug:apply/4.  Then search for it in the module.
	 */
	if ((ep = erts_find_function(mod, name, arity, code_ix)) != NULL) {
	    /* XXX: add "&& ep->address != ep->code" condition?
	     * Consider a traced function.
	     * Its ep will have ep->address == ep->code.
	     * erts_find_function() will return the non-NULL ep.
	     * Below we'll try to derive a code_ptr from ep->address.
	     * But this code_ptr will point to the start of the Export,
	     * not the function's func_info instruction. BOOM !?
	     */
	    cmfa = erts_code_to_codemfa(ep->addressv[code_ix]);
	} else if (modp == NULL || (code_hdr = modp->curr.code_hdr) == NULL) {
	    BIF_RET(am_undef);
	} else {
	    n = code_hdr->num_functions;
	    for (i = 0; i < n; i++) {
		cmfa = &code_hdr->functions[i]->mfa;
		if (cmfa->function == name && cmfa->arity == arity) {
		    break;
		}
	    }
	    if (i == n) {
		BIF_RET(am_undef);
	    }
	}
        code_ptr = (BeamInstr*)erts_code_to_codeinfo(erts_codemfa_to_code(cmfa));
    } else {
	goto error;
    }

    dsbufp = erts_create_tmp_dsbuf(0);
    erts_print(ERTS_PRINT_DSBUF, (void *) dsbufp, HEXF ": ", code_ptr);
    instr = (BeamInstr) code_ptr[0];
    for (i = 0; i < NUM_SPECIFIC_OPS; i++) {
	if (BeamIsOpCode(instr, i) && opc[i].name[0] != '\0') {
	    code_ptr += print_op(ERTS_PRINT_DSBUF, (void *) dsbufp,
				 i, opc[i].sz-1, code_ptr) + 1;
	    break;
	}
    }
    if (i >= NUM_SPECIFIC_OPS) {
	erts_print(ERTS_PRINT_DSBUF, (void *) dsbufp,
		   "unknown " HEXF "\n", instr);
	code_ptr++;
    }
    bin = new_binary(p, (byte *) dsbufp->str, dsbufp->str_len);
    erts_destroy_tmp_dsbuf(dsbufp);
    hsz = 4+4;
    (void) erts_bld_uword(NULL, &hsz, (BeamInstr) code_ptr);
    hp = HAlloc(p, hsz);
    addr = erts_bld_uword(&hp, NULL, (BeamInstr) code_ptr);
    ASSERT(is_atom(cmfa->module) || is_nil(cmfa->module));
    ASSERT(is_atom(cmfa->function) || is_nil(cmfa->function));
    mfa = TUPLE3(hp, cmfa->module, cmfa->function,
                 make_small(cmfa->arity));
    hp += 4;
    return TUPLE3(hp, addr, bin, mfa);
}