void darwin_check_osabi (darwin_inferior *inf, thread_t thread) { if (gdbarch_osabi (target_gdbarch) == GDB_OSABI_UNKNOWN) { /* Attaching to a process. Let's figure out what kind it is. */ x86_thread_state_t gp_regs; struct gdbarch_info info; unsigned int gp_count = x86_THREAD_STATE_COUNT; kern_return_t ret; ret = thread_get_state (thread, x86_THREAD_STATE, (thread_state_t) &gp_regs, &gp_count); if (ret != KERN_SUCCESS) { MACH_CHECK_ERROR (ret); return; } gdbarch_info_init (&info); gdbarch_info_fill (&info); info.byte_order = gdbarch_byte_order (target_gdbarch); info.osabi = GDB_OSABI_DARWIN; if (gp_regs.tsh.flavor == x86_THREAD_STATE64) info.bfd_arch_info = bfd_lookup_arch (bfd_arch_i386, bfd_mach_x86_64); else info.bfd_arch_info = bfd_lookup_arch (bfd_arch_i386, bfd_mach_i386_i386); gdbarch_update_p (info); } }
// Returns a fake asm_program_t for use when disassembling bits out of memory asm_program_t* fake_prog_for_arch(enum bfd_architecture arch) { int machine = 0; // TODO: pick based on arch asm_program_t *prog = new asm_program_t; prog->abfd = bfd_openw("/dev/null", NULL); assert(prog->abfd); bfd_set_arch_info(prog->abfd, bfd_lookup_arch(arch, machine)); //not in .h bfd_default_set_arch_mach(prog->abfd, arch, machine); bfd_set_arch_info(prog->abfd, bfd_lookup_arch(arch, machine)); init_disasm_info(prog); return prog; }
void gdbarch_register_osabi (enum bfd_architecture arch, unsigned long machine, enum gdb_osabi osabi, void (*init_osabi)(struct gdbarch_info, struct gdbarch *)) { struct gdb_osabi_handler **handler_p; const struct bfd_arch_info *arch_info = bfd_lookup_arch (arch, machine); const char **name_ptr; /* Registering an OS ABI handler for "unknown" is not allowed. */ if (osabi == GDB_OSABI_UNKNOWN) { internal_error (__FILE__, __LINE__, _("gdbarch_register_osabi: An attempt to register a handler for " "OS ABI \"%s\" for architecture %s was made. The handler will " "not be registered"), gdbarch_osabi_name (osabi), bfd_printable_arch_mach (arch, machine)); return; } gdb_assert (arch_info); for (handler_p = &gdb_osabi_handler_list; *handler_p != NULL; handler_p = &(*handler_p)->next) { if ((*handler_p)->arch_info == arch_info && (*handler_p)->osabi == osabi) { internal_error (__FILE__, __LINE__, _("gdbarch_register_osabi: A handler for OS ABI \"%s\" " "has already been registered for architecture %s"), gdbarch_osabi_name (osabi), arch_info->printable_name); /* If user wants to continue, override previous definition. */ (*handler_p)->init_osabi = init_osabi; return; } } (*handler_p) = (struct gdb_osabi_handler *) xmalloc (sizeof (struct gdb_osabi_handler)); (*handler_p)->next = NULL; (*handler_p)->arch_info = arch_info; (*handler_p)->osabi = osabi; (*handler_p)->init_osabi = init_osabi; /* Add this OS ABI to the list of enum values for "set osabi", if it isn't already there. */ for (name_ptr = gdb_osabi_available_names; *name_ptr; name_ptr ++) { if (*name_ptr == gdbarch_osabi_name (osabi)) return; } *name_ptr++ = gdbarch_osabi_name (osabi); *name_ptr = NULL; }
const char * bfd_printable_arch_mach (enum bfd_architecture arch, unsigned long machine) { const bfd_arch_info_type *ap = bfd_lookup_arch (arch, machine); if (ap) return ap->printable_name; return "UNKNOWN!"; }
unsigned int bfd_arch_mach_octets_per_byte (enum bfd_architecture arch, unsigned long mach) { const bfd_arch_info_type *ap = bfd_lookup_arch (arch, mach); if (ap) return ap->bits_per_byte / 8; return 1; }
/* Find gdbarch for SPU context SPUFS_FD. */ static struct gdbarch * spu_gdbarch (int spufs_fd) { struct gdbarch_info info; gdbarch_info_init (&info); info.bfd_arch_info = bfd_lookup_arch (bfd_arch_spu, bfd_mach_spu); info.byte_order = BFD_ENDIAN_BIG; info.osabi = GDB_OSABI_LINUX; info.tdep_info = (struct gdbarch_tdep_info *)&spufs_fd; return gdbarch_find_by_info (info); }
bfd_boolean bfd_default_set_arch_mach (bfd *abfd, enum bfd_architecture arch, unsigned long mach) { abfd->arch_info = bfd_lookup_arch (arch, mach); if (abfd->arch_info != NULL) return TRUE; abfd->arch_info = &bfd_default_arch_struct; bfd_set_error (bfd_error_bad_value); return FALSE; }
static void sh3e_open (char *args, int from_tty) { char *serial_port_name = args; char *parallel_port_name = 0; if (args) { char *cursor = serial_port_name = xstrdup (args); while (*cursor && *cursor != ' ') cursor++; if (*cursor) *cursor++ = 0; while (*cursor == ' ') cursor++; if (*cursor) parallel_port_name = cursor; } /* Set up the SH-3E monitor commands structure. */ memcpy (&sh3e_cmds, &sh3_cmds, sizeof (struct monitor_ops)); sh3e_cmds.target = &sh3e_ops; sh3e_cmds.regnames = sh3e_regnames; monitor_open (serial_port_name, &sh3e_cmds, from_tty); if (parallel_port_name) { parallel = serial_open (parallel_port_name); if (!parallel) perror_with_name (_("Unable to open parallel port.")); parallel_in_use = 1; } /* If we connected successfully, we know the processor is an SH3E. */ { struct gdbarch_info info; gdbarch_info_init (&info); info.bfd_arch_info = bfd_lookup_arch (bfd_arch_sh, bfd_mach_sh3); if (!gdbarch_update_p (info)) error (_("Target is not an SH3")); } }
void _initialize_mips_linux_tdep (void) { const struct bfd_arch_info *arch_info; for (arch_info = bfd_lookup_arch (bfd_arch_mips, 0); arch_info != NULL; arch_info = arch_info->next) { gdbarch_register_osabi (bfd_arch_mips, arch_info->mach, GDB_OSABI_LINUX, mips_linux_init_abi); } }
void set_architecture_from_arch_mach (enum bfd_architecture arch, unsigned long mach) { const struct bfd_arch_info *wanted = bfd_lookup_arch (arch, mach); if (GDB_MULTI_ARCH) internal_error (__FILE__, __LINE__, "set_architecture_from_arch_mach: not multi-arched"); if (wanted != NULL) set_arch (wanted, set_arch_manual); else internal_error (__FILE__, __LINE__, "gdbarch: hardwired architecture/machine not recognized"); }
/* Uses trace_read_memory, which assumes set_trace_bytes is used to update for each instruction. */ asm_program_t* asmir_trace_asmp_for_arch(enum bfd_architecture arch) { int machine = 0; // TODO: pick based on arch asm_program_t *prog = malloc(sizeof(asm_program_t)); assert(prog); prog->abfd = bfd_openw("/dev/null", NULL); if (!prog->abfd) { bfd_perror("Unable to open fake bfd"); } assert(prog->abfd); bfd_set_arch_info(prog->abfd, bfd_lookup_arch(arch, machine)); //not in .h bfd_default_set_arch_mach(prog->abfd, arch, machine); bfd_set_arch_info(prog->abfd, bfd_lookup_arch(arch, machine)); init_disasm_info(prog); // Use a special read memory function prog->disasm_info.read_memory_func = trace_read_memory; return prog; }
void _initialize_arm_macosx_tdep () { struct cmd_list_element *cmd = NULL; /* This is already done in arm-tdep.c. I wonder if we shouldn't move this code into there so we can be sure all the initializations happen in the right order, etc. */ /* register_gdbarch_init (bfd_arch_arm, arm_gdbarch_init); */ gdbarch_register_osabi_sniffer (bfd_arch_unknown, bfd_target_mach_o_flavour, arm_mach_o_osabi_sniffer); gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_DARWIN, arm_macosx_init_abi); gdbarch_register_osabi ((bfd_lookup_arch (bfd_arch_arm, bfd_mach_arm_6))->arch, bfd_mach_arm_6, GDB_OSABI_DARWINV6, arm_macosx_init_abi_v6); }
static struct bfd* new_bfd_internal( const char* filename, int arch, int machine ) { char** matching; enum bfd_architecture _arch = (enum bfd_architecture) arch; struct bfd* p = bfd_openr( filename, DEFAULT_TARGET ); const bfd_arch_info_type* info; if ( !p ) error_exit( "failure: bfd_openr" ); if ( _arch == bfd_arch_unknown ) { if ( bfd_check_format( p, bfd_archive ) ) { // TODO: add archive handling code bfd_close_all_done( p ); error_exit( "currently not supported." ); } if ( bfd_check_format_matches( p, bfd_object, &matching ) ) { return p; } if ( bfd_get_error() == bfd_error_file_ambiguously_recognized ) { bfd_close_all_done( p ); error_exit( "file format is ambiguosly matched" ); } if ( bfd_get_error() != bfd_error_file_not_recognized ) { bfd_close_all_done( p ); error_exit( "file is not recognized" ); } if ( bfd_check_format_matches( p, bfd_core, &matching ) ) { return p; } error_exit( "failed to load the given file" ); return NULL; /* this will never be called */ } else { info = bfd_lookup_arch( _arch, machine ); if ( !info ) error_exit( "failed to lookup archicture" ); bfd_set_arch_info( p, info ); return p; } }
static const bfd_arch_info_type * bfd_m68k_compatible (const bfd_arch_info_type *a, const bfd_arch_info_type *b) { if (a->arch != b->arch) return NULL; if (a->bits_per_word != b->bits_per_word) return NULL; if (!a->mach) return b; if (!b->mach) return a; if (a->mach <= bfd_mach_m68060 && b->mach <= bfd_mach_m68060) /* Merge m68k machine. */ return a->mach > b->mach ? a : b; else if (a->mach >= bfd_mach_mcf_isa_a_nodiv && b->mach >= bfd_mach_mcf_isa_a_nodiv) { /* Merge cf machine. */ unsigned features = (bfd_m68k_mach_to_features (a->mach) | bfd_m68k_mach_to_features (b->mach)); /* ISA A+ and ISA B are incompatible. */ if ((~features & (mcfisa_aa | mcfisa_b)) == 0) return NULL; /* MAC and EMAC code cannot be merged. */ if ((~features & (mcfmac | mcfemac)) == 0) return NULL; return bfd_lookup_arch (a->arch, bfd_m68k_features_to_mach (features)); } else /* They are incompatible. */ return NULL; }
void fetch_inferior_registers (int regno) { int current_pid; thread_t current_thread; int fetched = 0; current_pid = ptid_get_pid (inferior_ptid); current_thread = ptid_get_tid (inferior_ptid); /* ifdef the following code so that gdb doesn't send the new GDB_x86_THREAD_STATE constant when built on an older x86 MacOS X 10.4 system that won't recognize it. In Leopard this is unnecessary. */ if (TARGET_OSABI == GDB_OSABI_UNKNOWN) { /* Attaching to a process. Let's figure out what kind it is. */ gdb_x86_thread_state_t gp_regs; struct gdbarch_info info; unsigned int gp_count = GDB_x86_THREAD_STATE_COUNT; kern_return_t ret = thread_get_state (current_thread, GDB_x86_THREAD_STATE, (thread_state_t) & gp_regs, &gp_count); if (ret != KERN_SUCCESS) { printf_unfiltered ("Error calling thread_get_state for GP registers for thread 0x%x\n", (int) current_thread); MACH_CHECK_ERROR (ret); } gdbarch_info_init (&info); gdbarch_info_fill (current_gdbarch, &info); info.byte_order = gdbarch_byte_order (current_gdbarch); if (gp_regs.tsh.flavor == GDB_x86_THREAD_STATE64) { info.osabi = GDB_OSABI_DARWIN64; info.bfd_arch_info = bfd_lookup_arch (bfd_arch_i386, bfd_mach_x86_64); } else { info.osabi = GDB_OSABI_DARWIN; info.bfd_arch_info = bfd_lookup_arch (bfd_arch_i386, bfd_mach_i386_i386); } gdbarch_update_p (info); } if (TARGET_OSABI == GDB_OSABI_DARWIN64) { if ((regno == -1) || IS_GP_REGNUM_64 (regno)) { gdb_x86_thread_state_t gp_regs; unsigned int gp_count = GDB_x86_THREAD_STATE_COUNT; kern_return_t ret = thread_get_state (current_thread, GDB_x86_THREAD_STATE, (thread_state_t) & gp_regs, &gp_count); if (ret != KERN_SUCCESS) { printf_unfiltered ("Error calling thread_get_state for GP registers for thread 0x%x\n", (int) current_thread); MACH_CHECK_ERROR (ret); } x86_64_macosx_fetch_gp_registers (&gp_regs.uts.ts64); fetched++; } if ((regno == -1) || IS_FP_REGNUM_64 (regno) || IS_VP_REGNUM_64 (regno) || regno == REGS_64_MXCSR) { gdb_x86_float_state_t fp_regs; unsigned int fp_count = GDB_x86_FLOAT_STATE_COUNT; kern_return_t ret = thread_get_state (current_thread, GDB_x86_FLOAT_STATE, (thread_state_t) & fp_regs, &fp_count); if (ret != KERN_SUCCESS) { printf_unfiltered ("Error calling thread_get_state for float registers for thread 0x%x\n", (int) current_thread); MACH_CHECK_ERROR (ret); } x86_64_macosx_fetch_fp_registers (&fp_regs.ufs.fs64); fetched++; } } else { if ((regno == -1) || IS_GP_REGNUM (regno)) { gdb_x86_thread_state_t gp_regs; unsigned int gp_count = GDB_x86_THREAD_STATE_COUNT; kern_return_t ret = thread_get_state (current_thread, GDB_x86_THREAD_STATE, (thread_state_t) & gp_regs, &gp_count); if (ret != KERN_SUCCESS) { printf_unfiltered ("Error calling thread_get_state for GP registers for thread 0x%x\n", (int) current_thread); MACH_CHECK_ERROR (ret); } i386_macosx_fetch_gp_registers (&(gp_regs.uts.ts32)); fetched++; } if ((regno == -1) || IS_FP_REGNUM (regno) || i386_sse_regnum_p (current_gdbarch, regno) || i386_mxcsr_regnum_p (current_gdbarch, regno)) { gdb_i386_float_state_t fp_regs; unsigned int fp_count = GDB_i386_FLOAT_STATE_COUNT; kern_return_t ret = thread_get_state (current_thread, GDB_i386_FLOAT_STATE, (thread_state_t) & fp_regs, &fp_count); if (ret != KERN_SUCCESS) { printf_unfiltered ("Error calling thread_get_state for float registers for thread 0x%x\n", (int) current_thread); MACH_CHECK_ERROR (ret); } i386_macosx_fetch_fp_registers (&fp_regs); fetched++; } } if (! fetched) { warning ("unknown register %d", regno); regcache_raw_supply (current_regcache, regno, NULL); } }
static const bfd_arch_info_type * bfd_m68k_compatible (const bfd_arch_info_type *a, const bfd_arch_info_type *b) { if (a->arch != b->arch) return NULL; if (a->bits_per_word != b->bits_per_word) return NULL; if (!a->mach) return b; if (!b->mach) return a; if (a->mach <= bfd_mach_m68060 && b->mach <= bfd_mach_m68060) /* Merge m68k machine. */ return a->mach > b->mach ? a : b; else if (a->mach >= bfd_mach_cpu32 && b->mach >= bfd_mach_cpu32) { /* Merge the machine features. */ unsigned features = (bfd_m68k_mach_to_features (a->mach) | bfd_m68k_mach_to_features (b->mach)); /* CPU32 and Coldfire are incompatible. */ if ((~features & (cpu32 | mcfisa_a)) == 0) return NULL; /* Fido and Coldfire are incompatible. */ if ((~features & (fido_a | mcfisa_a)) == 0) return NULL; /* ISA A+ and ISA B are incompatible. */ if ((~features & (mcfisa_aa | mcfisa_b)) == 0) return NULL; /* ISA B and ISA C are incompatible. */ if ((~features & (mcfisa_b | mcfisa_c)) == 0) return NULL; /* MAC and EMAC code cannot be merged. */ if ((~features & (mcfmac | mcfemac)) == 0) return NULL; /* CPU32 is compatible with Fido except that Fido does not support tbl instructions. Warn when the user wants to mix the two. */ if ((a->mach == bfd_mach_cpu32 && b->mach == bfd_mach_fido) || (a->mach == bfd_mach_fido && b->mach == bfd_mach_cpu32)) { static int cpu32_fido_mix_warning; if (!cpu32_fido_mix_warning) { cpu32_fido_mix_warning = 1; (*_bfd_error_handler) ("warning: linking CPU32 objects with fido objects"); } return bfd_lookup_arch (a->arch, bfd_m68k_features_to_mach (fido_a | m68881)); } return bfd_lookup_arch (a->arch, bfd_m68k_features_to_mach (features)); } else /* They are incompatible. */ return NULL; }