LispExpression *lisp_context_find(LispContext *ctx, char *symbol) { int found = 0; LispExpression *expr = symbol_table_lookup(ctx->symbols, symbol, &found); if(! found) { if(ctx->parent) { return lisp_context_find(ctx->parent, symbol); } else { lisp_throw(make_lisp_exception("NameError", "Symbol not defined: %s", symbol)); return NULL; // never reached (but -Wall will complain about this) } } else { return expr; } }
/* * symbol_find_or_make() * * If a symbol name does not exist, create it as undefined, and insert * it into the symbol table. Return a pointer to it. */ symbolS * symbol_find_or_make( char *name) { register symbolS * symbolP; symbolP = symbol_table_lookup (name); if (symbolP == NULL) { symbolP = symbol_new (name, N_UNDF, 0, 0, 0, & zero_address_frag); symbol_table_insert (symbolP); } return (symbolP); }
void TTR_set_ident_data_type( Symbol_Table *table, TTR_Node *identifier, int type) { TTR_Node *sym_node; assert(table != NULL); assert(identifier != NULL); assert(N_TYPE(identifier) == N_IDENTIFIER || N_TYPE(identifier) == N_FUNCDEF); sym_node = symbol_table_lookup(table, N_STR(identifier)); if (sym_node == NULL) { N_DTYPE(identifier) = type; symbol_table_add(table, N_STR(identifier), identifier); } else { if (N_DTYPE(sym_node) == UNDEFINED_T) { N_DTYPE(identifier) = type; N_DTYPE(sym_node) = type; } else { N_DTYPE(identifier) = N_DTYPE(sym_node); } } }
int unwind_backtrace_with_ptrace_x86(int tfd, pid_t pid, mapinfo *map, bool at_fault) { struct pt_regs_x86 r; unsigned int stack_level = 0; unsigned int stack_depth = 0; unsigned int rel_pc; unsigned int stack_ptr; unsigned int stack_content; if(ptrace(PTRACE_GETREGS, pid, 0, &r)) return 0; unsigned int eip = (unsigned int)r.eip; unsigned int ebp = (unsigned int)r.ebp; unsigned int cur_sp = (unsigned int)r.esp; const mapinfo *mi; const struct symbol* sym = 0; //ebp==0, it indicates that the stack is poped to the bottom or there is no stack at all. while (ebp) { mi = pc_to_mapinfo(map, eip, &rel_pc); /* See if we can determine what symbol this stack frame resides in */ if (mi != 0 && mi->symbols != 0) { sym = symbol_table_lookup(mi->symbols, rel_pc); } if (sym) { _LOG(tfd, !at_fault, " #%02d eip: %08x %s (%s)\n", stack_level, eip, mi ? mi->name : "", sym->name); } else { _LOG(tfd, !at_fault, " #%02d eip: %08x %s\n", stack_level, eip, mi ? mi->name : ""); } stack_level++; if (stack_level >= STACK_DEPTH || eip == 0) break; eip = ptrace(PTRACE_PEEKTEXT, pid, (void*)(ebp + 4), NULL); ebp = ptrace(PTRACE_PEEKTEXT, pid, (void*)ebp, NULL); } ebp = (unsigned int)r.ebp; stack_depth = stack_level; stack_level = 0; if (ebp) _LOG(tfd, !at_fault, "stack: \n"); while (ebp) { stack_ptr = cur_sp; while((int)(ebp - stack_ptr) >= 0) { stack_content = ptrace(PTRACE_PEEKTEXT, pid, (void*)stack_ptr, NULL); mi = pc_to_mapinfo(map, stack_content, &rel_pc); /* See if we can determine what symbol this stack frame resides in */ if (mi != 0 && mi->symbols != 0) { sym = symbol_table_lookup(mi->symbols, rel_pc); } if (sym) { _LOG(tfd, !at_fault, " #%02d %08x %08x %s (%s)\n", stack_level, stack_ptr, stack_content, mi ? mi->name : "", sym->name); } else { _LOG(tfd, !at_fault, " #%02d %08x %08x %s\n", stack_level, stack_ptr, stack_content, mi ? mi->name : ""); } stack_ptr = stack_ptr + 4; //the stack frame may be very deep. if((int)(stack_ptr - cur_sp) >= STACK_FRAME_DEPTH) { _LOG(tfd, !at_fault, " ...... ...... \n"); break; } } cur_sp = ebp + 4; stack_level++; if (stack_level >= STACK_DEPTH || stack_level >= stack_depth) break; ebp = ptrace(PTRACE_PEEKTEXT, pid, (void*)ebp, NULL); } return stack_depth; }
void colon( /* just seen "x:" - rattle symbols & frags */ char *sym_name) /* symbol name, as a cannonical string */ /* We copy this string: OK to alter later. */ { register struct symbol * symbolP; /* symbol we are working with */ if (frchain_now == NULL) { know(flagseen['n']); as_fatal("with -n a section directive must be seen before assembly " "can begin"); } if ((symbolP = symbol_table_lookup( sym_name ))) { /* * Now check for undefined symbols */ if ((symbolP -> sy_type & N_TYPE) == N_UNDF) { temp = symbolP->sy_desc; if( symbolP -> sy_other == 0 /* bug #50416 -O causes this not to work for: && ((symbolP->sy_desc) & (~REFERENCE_TYPE)) == 0 */ && (temp & (~(REFERENCE_TYPE | N_WEAK_REF | N_WEAK_DEF | N_ARM_THUMB_DEF | N_NO_DEAD_STRIP | REFERENCED_DYNAMICALLY))) == 0 && symbolP -> sy_value == 0) { symbolP -> sy_frag = frag_now; symbolP -> sy_value = obstack_next_free(& frags) - frag_now -> fr_literal; know( N_UNDF == 0 ); symbolP -> sy_type |= N_SECT; /* keep N_EXT bit */ symbolP -> sy_other = frchain_now->frch_nsect; symbolP -> sy_desc &= ~REFERENCE_TYPE; symbolP -> sy_desc &= ~N_WEAK_REF; symbol_assign_index(symbolP); if((symbolP->sy_desc & N_WEAK_DEF) == N_WEAK_DEF && (frchain_now->frch_section.flags & S_COALESCED) != S_COALESCED) as_fatal("symbol: %s can't be a weak_definition (currently " "only supported in section of type coalesced)", sym_name); #ifdef NeXT_MOD /* generate stabs for debugging assembly code */ if(flagseen['g']) make_stab_for_symbol(symbolP); #endif } else { as_fatal( "Symbol \"%s\" is already defined as \"%s\"/%d.%d." TA_DFMT ".", sym_name, seg_name [(int) N_TYPE_seg [symbolP -> sy_type & N_TYPE]], symbolP -> sy_other, symbolP -> sy_desc, TA_DFT_CAST(symbolP -> sy_value)); } } else { as_fatal("Symbol %s already defined.",sym_name); } } else { symbolP = symbol_new (sym_name, N_SECT, frchain_now->frch_nsect, 0, (valueT)(obstack_next_free(&frags)-frag_now->fr_literal), frag_now); symbol_table_insert (symbolP); symbol_assign_index (symbolP); #ifdef NeXT_MOD /* generate stabs for debugging assembly code */ if(flagseen['g']) make_stab_for_symbol(symbolP); #endif } #ifdef tc_frob_label tc_frob_label(symbolP); #endif }
/* * Summary of operand(). * * in: Input_line_pointer points to 1st char of operand, which may * be a space. * * out: A expressionS. X_seg determines how to understand the rest of the * expressionS. * The operand may have been empty: in this case X_seg == SEG_NONE. * Input_line_pointer -> (next non-blank) char after operand. * */ static segT operand( expressionS *expressionP) { char c, q; char *name; /* points to name of symbol */ struct symbol *symbolP; /* Points to symbol */ SKIP_WHITESPACE(); /* Leading whitespace is part of operand. */ c = *input_line_pointer++;/* Input_line_pointer -> past char in c. */ if(isdigit(c)){ signed_expr_t number; /* offset or (absolute) value */ int digit; /* value of next digit in current radix */ /* invented for humans only, hope */ /* optimising compiler flushes it! */ int radix; /* 8, 10 or 16 */ /* 0 means we saw start of a floating- */ /* point constant. */ int maxdig; /* Highest permitted digit value. */ int too_many_digits;/* If we see >= this number of */ /* digits, assume it is a bignum. */ char *digit_2; /* -> 2nd digit of number. */ int small; /* TRUE if fits in 32 bits. */ int force_bignum; /* TRUE if number is 0xb... */ force_bignum = FALSE; /* * These two initiaizations are to shut up compiler warning as the * may be used with out being set. There used only if radix != 0 * when the number is not a floating-point number. */ maxdig = 0; too_many_digits = 0; if(c == '0'){ /* non-decimal radix */ c = *input_line_pointer++; if(c == 'x' || c=='X'){ c = *input_line_pointer++; /* read past "0x" or "0X" */ maxdig = 16; radix = 16; too_many_digits = 9; } /* * If we have "0b" and some hex digits then treat it as a hex * number and return a bignum. This is for hex immediate * bit-patterns for floating-point immediate constants. */ else if((c == 'b' || c == 'B') && (*input_line_pointer != '\0') && strchr("0123456789abcdefABCDEF", *input_line_pointer) != NULL){ force_bignum = TRUE; c = *input_line_pointer++; /* read past "0b" or "0B" */ maxdig = 16; radix = 16; too_many_digits = 9; } else{ /* * If it says '0f' and the line ends or it DOESN'T look like * a floating point #, its a local label ref. */ if(c == 'f' && (*input_line_pointer == '\0' || (strchr("+-.0123456789", *input_line_pointer) == NULL && strchr(md_EXP_CHARS, *input_line_pointer) == NULL) )){ maxdig = 10; radix = 10; too_many_digits = 11; c = '0'; input_line_pointer -= 2; } else if(c != '\0' && strchr(md_FLT_CHARS, c) != NULL){ radix = 0;/* Start of floating-point constant. */ /* input_line_pointer -> 1st char of number */ expressionP->X_add_number = - (isupper(c) ? tolower(c) : c); } else{ /* By elimination, assume octal radix. */ radix = 8; maxdig = 10; /* Un*x sux. Compatibility. */ too_many_digits = 11; } } /* c == char after "0" or "0x" or "0X" or "0e" etc.*/ } else{ maxdig = 10; radix = 10; too_many_digits = 11; } /* * Expressions are now evaluated as 64-bit values so the number * digits allowed is twice that for 32-bit expressions. */ too_many_digits *= 2; if(radix != 0){ /* Fixed-point integer constant. */ /* May be bignum, or may fit in 32 bits. */ /* * Most numbers fit into 32 bits, and we want this case to be * fast. So we pretend it will fit into 32 bits. If, after * making up a 32 bit number, we realize that we have scanned * more digits than comfortably fit into 32 bits, we re-scan the * digits coding them into a bignum. For decimal and octal * numbers we are conservative: some numbers may be assumed * bignums when in fact they do fit into 32 bits. Numbers of * any radix can have excess leading zeros: we strive to * recognise this and cast them back into 32 bits. We must * check that the bignum really is more than 32 bits, and * change it back to a 32-bit number if it fits. The number we * are looking for is expected to be positive, but if it fits * into 32 bits as an unsigned number, we let it be a 32-bit * number. The cavalier approach is for speed in ordinary cases. */ digit_2 = input_line_pointer; for(number = 0; (digit = hex_value[(int)c]) < maxdig; c = *input_line_pointer++){ number = number * radix + digit; } /* c contains character after number. */ /* Input_line_pointer -> char after c. */ small = input_line_pointer - digit_2 < too_many_digits; if(force_bignum == TRUE) small = FALSE; if(small == FALSE){ /* * Manufacture a bignum. */ /* -> high order littlenum of the bignum. */ LITTLENUM_TYPE *leader; /* -> littlenum we are frobbing now. */ LITTLENUM_TYPE *pointer; long carry; leader = generic_bignum; generic_bignum [0] = 0; /* We could just use digit_2, but lets be mnemonic. */ input_line_pointer = --digit_2; /* -> 1st digit. */ c = *input_line_pointer++; for( ; (carry = hex_value[(int)c]) < maxdig; c = * input_line_pointer++){ for(pointer = generic_bignum; pointer <= leader; pointer++){ long work; work = carry + radix * *pointer; *pointer = work & LITTLENUM_MASK; carry = work >> LITTLENUM_NUMBER_OF_BITS; } if(carry){ if(leader < generic_bignum + SIZE_OF_LARGE_NUMBER - 1){ /* Room to grow a longer bignum. */ *++leader = carry; } } } /* Again, C is char after number, */ /* input_line_pointer -> after C. */ /* know(BITS_PER_INT == 32); */ know(LITTLENUM_NUMBER_OF_BITS == 16); /* Hence the constant "2" in the next line. */ if(leader < generic_bignum + 2 && force_bignum == FALSE) { /* Will fit into 32 bits. */ number = ((generic_bignum[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS) | (generic_bignum[0] & LITTLENUM_MASK); small = TRUE; } else{ /* Number of littlenums in the bignum. */ number = leader - generic_bignum + 1; } } if(small){ /* * Here with number, in correct radix. c is the next char. * Note that unlike Un*x, we allow "011f" "0x9f" to both * mean the same as the (conventional) "9f". This is simply * easier than checking for strict canonical form. */ if(number < 10){ if(c == 'b'){ /* * Backward ref to local label. * Because it is backward, expect it to be DEFINED. */ /* * Construct a local label. */ name = local_label_name((int)number, 0); symbolP = symbol_table_lookup(name); if((symbolP != NULL) && (symbolP->sy_type & N_TYPE) != N_UNDF){ /* Expected path: symbol defined. */ /* Local labels are never absolute. Don't waste time checking absoluteness. */ know((symbolP->sy_type & N_TYPE) == N_SECT); expressionP->X_add_symbol = symbolP; expressionP->X_add_number = 0; expressionP->X_seg = SEG_SECT; } else{ /* Either not seen or not defined. */ as_warn("Backw. ref to unknown label \"%lld\"," "0 assumed.", number); expressionP->X_add_number = 0; expressionP->X_seg = SEG_ABSOLUTE; } } else if(c == 'f'){ /* * Forward reference. Expect symbol to be * undefined or unknown. Undefined: seen it * before. Unknown: never seen it in this pass. * Construct a local label name, then an * undefined symbol. Don't create a XSEG frag * for it: caller may do that. * Just return it as never seen before. */ name = local_label_name((int)number, 1); symbolP = symbol_table_lookup(name); if(symbolP != NULL){ /* We have no need to check symbol properties. */ know((symbolP->sy_type & N_TYPE) == N_UNDF || (symbolP->sy_type & N_TYPE) == N_SECT); } else{ symbolP = symbol_new(name, N_UNDF, 0,0,0, &zero_address_frag); symbol_table_insert(symbolP); } expressionP->X_add_symbol = symbolP; expressionP->X_seg = SEG_UNKNOWN; expressionP->X_subtract_symbol = NULL; expressionP->X_add_number = 0; } else{ /* Really a number, not a local label. */ ignore_c_ll_or_ull(c); expressionP->X_add_number = number; expressionP->X_seg = SEG_ABSOLUTE; input_line_pointer--; /* restore following char */ } } else{ /* a number >= 10 */ ignore_c_ll_or_ull(c); expressionP->X_add_number = number; expressionP->X_seg = SEG_ABSOLUTE; input_line_pointer--; /* restore following char */ } } /* not a small number encode returning a bignum */ else{ ignore_c_ll_or_ull(c); expressionP->X_add_number = number; expressionP->X_seg = SEG_BIG; input_line_pointer--; /* -> char following number. */ } /* if (small) */ } /* (If integer constant) */