void objdump(const char *path) { bfd_init(); bfd *abfd = bfd_openr(path, NULL); if (abfd == NULL) errx(1, bfd_errmsg(bfd_get_error())); if (!bfd_check_format(abfd, bfd_object)) { bfd_close_all_done(abfd); errx(1, "File is not a valid object file."); } printf("%s: file format %s\n", path, bfd_get_target(abfd)); printf("architecture: %s, flags: 0x%08x\n", bfd_printable_arch_mach(bfd_get_arch(abfd), bfd_get_mach(abfd)), abfd->flags); printf("start address 0x%016lx", bfd_get_start_address(abfd)); printf("\n"); printf("Sections:\n"); printf("Idx Name Size VMA LMA File off Algn\n"); printf(" Flags Content\n"); object_stats stats = { FALSE, FALSE }; bfd_map_over_sections(abfd, (void (*)(bfd *, asection *, void *))print_section, &stats); if (stats.contains_hello && stats.contains_world) printf("\nThis file might be a hello world program!\n"); bfd_close(abfd); }
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; }
void gdbarch_register_osabi (enum bfd_architecture arch, enum gdb_osabi osabi, void (*init_osabi)(struct gdbarch_info, struct gdbarch *)) { struct gdb_osabi_handler **handler_p; /* 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, 0)); return; } for (handler_p = &gdb_osabi_handler_list; *handler_p != NULL; handler_p = &(*handler_p)->next) { if ((*handler_p)->arch == arch && (*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), bfd_printable_arch_mach (arch, 0)); /* 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 = arch; (*handler_p)->osabi = osabi; (*handler_p)->init_osabi = init_osabi; }
static void fill_arch_info( const struct bfd_arch_info * info, VALUE * hash ) { rb_hash_aset( *hash, str_to_sym(AINFO_MEMBER_BPW), INT2NUM(info->bits_per_word) ); rb_hash_aset( *hash, str_to_sym(AINFO_MEMBER_BPA), INT2NUM(info->bits_per_address) ); rb_hash_aset( *hash, str_to_sym(AINFO_MEMBER_BPB), INT2NUM(info->bits_per_byte) ); rb_hash_aset( *hash, str_to_sym(AINFO_MEMBER_ALIGN), INT2NUM(info->section_align_power) ); rb_hash_aset( *hash, str_to_sym(AINFO_MEMBER_ARCH), rb_str_new_cstr(bfd_printable_arch_mach(info->arch, info->mach)) ); }
void gdbarch_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch, enum gdb_osabi osabi) { struct gdb_osabi_handler *handler; bfd *abfd = info.abfd; const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (gdbarch); if (osabi == GDB_OSABI_UNKNOWN) { /* Don't complain about an unknown OSABI. Assume the user knows what they are doing. */ return; } for (handler = gdb_osabi_handler_list; handler != NULL; handler = handler->next) { if (handler->arch == bfd_get_arch (abfd) && handler->osabi == osabi) { (*handler->init_osabi) (info, gdbarch); return; } } /* We assume that if GDB_MULTI_ARCH is less than GDB_MULTI_ARCH_TM that an ABI variant can be supported by overriding definitions in the tm-file. */ if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) fprintf_filtered (gdb_stderr, "A handler for the OS ABI \"%s\" is not built into this " "configuration of GDB. " "Attempting to continue with the default %s settings", gdbarch_osabi_name (osabi), bfd_printable_arch_mach (arch_info->arch, arch_info->mach)); }
enum gdb_osabi gdbarch_lookup_osabi (bfd *abfd) { struct gdb_osabi_sniffer *sniffer; enum gdb_osabi osabi, match; int match_specific; /* If we aren't in "auto" mode, return the specified OS ABI. */ if (user_osabi_state == osabi_user) return user_selected_osabi; /* If we don't have a binary, just return unknown. The caller may have other sources the OSABI can be extracted from, e.g., the target description. */ if (abfd == NULL) return GDB_OSABI_UNKNOWN; match = GDB_OSABI_UNKNOWN; match_specific = 0; for (sniffer = gdb_osabi_sniffer_list; sniffer != NULL; sniffer = sniffer->next) { if ((sniffer->arch == bfd_arch_unknown /* wildcard */ || sniffer->arch == bfd_get_arch (abfd)) && sniffer->flavour == bfd_get_flavour (abfd)) { osabi = (*sniffer->sniffer) (abfd); if (osabi < GDB_OSABI_UNKNOWN || osabi >= GDB_OSABI_INVALID) { internal_error (__FILE__, __LINE__, _("gdbarch_lookup_osabi: invalid OS ABI (%d) from sniffer " "for architecture %s flavour %d"), (int) osabi, bfd_printable_arch_mach (bfd_get_arch (abfd), 0), (int) bfd_get_flavour (abfd)); } else if (osabi != GDB_OSABI_UNKNOWN) { /* A specific sniffer always overrides a generic sniffer. Croak on multiple match if the two matches are of the same class. If the user wishes to continue, we'll use the first match. */ if (match != GDB_OSABI_UNKNOWN) { if ((match_specific && sniffer->arch != bfd_arch_unknown) || (!match_specific && sniffer->arch == bfd_arch_unknown)) { internal_error (__FILE__, __LINE__, _("gdbarch_lookup_osabi: multiple %sspecific OS ABI " "match for architecture %s flavour %d: first " "match \"%s\", second match \"%s\""), match_specific ? "" : "non-", bfd_printable_arch_mach (bfd_get_arch (abfd), 0), (int) bfd_get_flavour (abfd), gdbarch_osabi_name (match), gdbarch_osabi_name (osabi)); } else if (sniffer->arch != bfd_arch_unknown) { match = osabi; match_specific = 1; } } else { match = osabi; if (sniffer->arch != bfd_arch_unknown) match_specific = 1; } } } } return match; }
enum gdb_osabi gdbarch_lookup_osabi (bfd *abfd) { struct gdb_osabi_sniffer *sniffer; enum gdb_osabi osabi, match; int match_specific; match = GDB_OSABI_UNKNOWN; match_specific = 0; for (sniffer = gdb_osabi_sniffer_list; sniffer != NULL; sniffer = sniffer->next) { if ((sniffer->arch == bfd_arch_unknown /* wildcard */ || sniffer->arch == bfd_get_arch (abfd)) && sniffer->flavour == bfd_get_flavour (abfd)) { osabi = (*sniffer->sniffer) (abfd); if (osabi < GDB_OSABI_UNKNOWN || osabi >= GDB_OSABI_INVALID) { internal_error (__FILE__, __LINE__, "gdbarch_lookup_osabi: invalid OS ABI (%d) from sniffer " "for architecture %s flavour %d", (int) osabi, bfd_printable_arch_mach (bfd_get_arch (abfd), 0), (int) bfd_get_flavour (abfd)); } else if (osabi != GDB_OSABI_UNKNOWN) { /* A specific sniffer always overrides a generic sniffer. Croak on multiple match if the two matches are of the same class. If the user wishes to continue, we'll use the first match. */ if (match != GDB_OSABI_UNKNOWN) { if ((match_specific && sniffer->arch != bfd_arch_unknown) || (!match_specific && sniffer->arch == bfd_arch_unknown)) { internal_error (__FILE__, __LINE__, "gdbarch_lookup_osabi: multiple %sspecific OS ABI " "match for architecture %s flavour %d: first " "match \"%s\", second match \"%s\"", match_specific ? "" : "non-", bfd_printable_arch_mach (bfd_get_arch (abfd), 0), (int) bfd_get_flavour (abfd), gdbarch_osabi_name (match), gdbarch_osabi_name (osabi)); } else if (sniffer->arch != bfd_arch_unknown) { match = osabi; match_specific = 1; } } else { match = osabi; if (sniffer->arch != bfd_arch_unknown) match_specific = 1; } } } } return match; }
void init_disassemble(){ abfd = malloc(sizeof(bfd)); init_disassemble_info (&disasm_info, stdout, (fprintf_ftype) fprintf); disasm_info.print_address_func = objdump_print_address; disasm_info.symbol_at_address_func = objdump_symbol_at_address; /* * choose arch infor since we will select different disassemble function. */ generic_arch_t* arch_instance = get_arch_instance(""); machine = arch_instance->arch_name; const bfd_arch_info_type *info = bfd_scan_arch (machine); if (info == NULL){ //fatal (_("Can't use supplied machine %s"), machine); printf("Can't use supplied machine %s\n", machine); return; } abfd->arch_info = info; /* * endian selection */ if (endian != BFD_ENDIAN_UNKNOWN) { struct bfd_target *xvec; xvec = xmalloc (sizeof (struct bfd_target)); //memcpy (xvec, abfd->xvec, sizeof (struct bfd_target)); xvec->byteorder = endian; abfd->xvec = xvec; } /* Get a disassemble function according to the arch and endian of abfd */ disassemble_fn = disassembler (abfd); if(!disassemble_fn) { /* non_fatal (_("Can't disassemble for architecture %s\n"), bfd_printable_arch_mach (bfd_get_arch (abfd), 0)); */ printf("Can't disassemble for architecture %s\n", bfd_printable_arch_mach (bfd_get_arch (abfd), 0)); exit_status = 1; return; } disasm_info.flavour = bfd_get_flavour (abfd); disasm_info.arch = bfd_get_arch (abfd); disasm_info.mach = bfd_get_mach (abfd); disasm_info.disassembler_options = disassembler_options; disasm_info.octets_per_byte = bfd_octets_per_byte (abfd); disasm_info.skip_zeroes = DEFAULT_SKIP_ZEROES; disasm_info.skip_zeroes_at_end = DEFAULT_SKIP_ZEROES_AT_END; disasm_info.disassembler_needs_relocs = FALSE; #if 1 if (bfd_big_endian (abfd)) disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_BIG; else if (bfd_little_endian (abfd)) disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_LITTLE; else /* ??? Aborting here seems too drastic. We could default to big or little instead. */ disasm_info.endian = BFD_ENDIAN_UNKNOWN; #endif /* set the default endianess is BFD_ENDIAN_LITTLE */ disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_LITTLE; disasm_info.symtab = sorted_syms; disasm_info.symtab_size = sorted_symcount; disasm_info.read_memory_func = disasm_read_memory; free (sorted_syms); }