static SCM vlscm_unop (enum valscm_unary_opcode opcode, SCM x, const char *func_name) { struct gdbarch *gdbarch = get_current_arch (); const struct language_defn *language = current_language; struct value *arg1; SCM result = SCM_BOOL_F; struct value *res_val = NULL; SCM except_scm; struct cleanup *cleanups; cleanups = make_cleanup_value_free_to_mark (value_mark ()); arg1 = vlscm_convert_value_from_scheme (func_name, SCM_ARG1, x, &except_scm, gdbarch, language); if (arg1 == NULL) { do_cleanups (cleanups); gdbscm_throw (except_scm); } TRY { switch (opcode) { case VALSCM_NOT: /* Alas gdb and guile use the opposite meaning for "logical not". */ { struct type *type = language_bool_type (language, gdbarch); res_val = value_from_longest (type, (LONGEST) value_logical_not (arg1)); } break; case VALSCM_NEG: res_val = value_neg (arg1); break; case VALSCM_NOP: /* Seemingly a no-op, but if X was a Scheme value it is now a <gdb:value> object. */ res_val = arg1; break; case VALSCM_ABS: if (value_less (arg1, value_zero (value_type (arg1), not_lval))) res_val = value_neg (arg1); else res_val = arg1; break; case VALSCM_LOGNOT: res_val = value_complement (arg1); break; default: gdb_assert_not_reached ("unsupported operation"); } } CATCH (except, RETURN_MASK_ALL) { GDBSCM_HANDLE_GDB_EXCEPTION_WITH_CLEANUPS (except, cleanups); }
static SCM gdbscm_arch_disassemble (SCM self, SCM start_scm, SCM rest) { arch_smob *a_smob = arscm_get_arch_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); struct gdbarch *gdbarch = arscm_get_gdbarch (a_smob); const SCM keywords[] = { port_keyword, offset_keyword, size_keyword, count_keyword, SCM_BOOL_F }; int port_arg_pos = -1, offset_arg_pos = -1; int size_arg_pos = -1, count_arg_pos = -1; SCM port = SCM_BOOL_F; ULONGEST offset = 0; unsigned int count = 1; unsigned int size; ULONGEST start_arg; CORE_ADDR start, end; CORE_ADDR pc; unsigned int i; int using_port; SCM result; gdbscm_parse_function_args (FUNC_NAME, SCM_ARG2, keywords, "U#OUuu", start_scm, &start_arg, rest, &port_arg_pos, &port, &offset_arg_pos, &offset, &size_arg_pos, &size, &count_arg_pos, &count); /* START is first stored in a ULONGEST because we don't have a format char for CORE_ADDR, and it's not really worth it to have one yet. */ start = start_arg; if (port_arg_pos > 0) { SCM_ASSERT_TYPE (gdbscm_is_false (port) || gdbscm_is_true (scm_input_port_p (port)), port, port_arg_pos, FUNC_NAME, _("input port")); } using_port = gdbscm_is_true (port); if (offset_arg_pos > 0 && (port_arg_pos < 0 || gdbscm_is_false (port))) { gdbscm_out_of_range_error (FUNC_NAME, offset_arg_pos, gdbscm_scm_from_ulongest (offset), _("offset provided but port is missing")); } if (size_arg_pos > 0) { if (size == 0) return SCM_EOL; /* For now be strict about start+size overflowing. If it becomes a nuisance we can relax things later. */ if (start + size < start) { gdbscm_out_of_range_error (FUNC_NAME, 0, scm_list_2 (gdbscm_scm_from_ulongest (start), gdbscm_scm_from_ulongest (size)), _("start+size overflows")); } end = start + size - 1; } else end = ~(CORE_ADDR) 0; if (count == 0) return SCM_EOL; result = SCM_EOL; for (pc = start, i = 0; pc <= end && i < count; ) { int insn_len = 0; struct ui_file *memfile = mem_fileopen (); struct cleanup *cleanups = make_cleanup_ui_file_delete (memfile); TRY { if (using_port) { insn_len = gdbscm_print_insn_from_port (gdbarch, port, offset, pc, memfile, NULL); } else insn_len = gdb_print_insn (gdbarch, pc, memfile, NULL); } CATCH (except, RETURN_MASK_ALL) { GDBSCM_HANDLE_GDB_EXCEPTION_WITH_CLEANUPS (except, cleanups); } END_CATCH std::string as = ui_file_as_string (memfile); result = scm_cons (dascm_make_insn (pc, as.c_str (), insn_len), result); pc += insn_len; i++; do_cleanups (cleanups); }