Exemple #1
0
struct disassemble_info* new_disasm_info( struct bfd* abfd )
{
    struct disassemble_info *di =
      (struct disassemble_info *) malloc( sizeof(struct disassemble_info) );
    if ( !di )
        error_exit( "failed to allocate disassemble_info" );

    init_disassemble_info( di, stdout, (fprintf_ftype) fprintf );

    di->flavour = bfd_get_flavour( abfd );
    di->arch = bfd_get_arch( abfd );
    di->mach = bfd_get_mach( abfd );
    di->octets_per_byte = bfd_octets_per_byte( abfd );
    di->disassembler_needs_relocs = FALSE;

    di->buffer = NULL;
    di->symtab = NULL;

    if ( bfd_big_endian( abfd ) )
        di->display_endian = di->endian = BFD_ENDIAN_BIG;
    else if ( bfd_little_endian ( abfd ) )
        di->display_endian = di->endian = BFD_ENDIAN_LITTLE;

    disassemble_init_for_target( di );

    return di;
}
// disassemble one instruction at laddr relative to memory, but at most memory+byteSize
int
disassembleForAtInSize(void *cpu, ulong laddr,
			void *memory, ulong byteSize)
{
	gdblog_index = 0;
	// ignore the cpu

	disassemble_info* dis = (disassemble_info*) calloc(1, sizeof(disassemble_info));
	init_disassemble_info ( dis, NULL, gdb_log_printf);
	
	dis->arch = bfd_arch_arm;
	dis->mach = bfd_mach_arm_unknown;
	
	// sets some fields in the structure dis to architecture specific values
	disassemble_init_for_target( dis );
	
	dis->buffer_vma = 0;
	dis->buffer = memory;
	dis->buffer_length = byteSize;
	
	//prepend the address
	gdb_log_printf(NULL, "0x%p: ", laddr);
	
	//other possible functions are listed in opcodes/dissassemble.c
	unsigned int size = print_insn_little_arm((bfd_vma) laddr, dis);
	
	free(dis);
	// zero terminate the string
	gdb_log[gdblog_index+1] = 0;
	
	return size;
}
Exemple #3
0
static struct disassemble_info
gdb_disassemble_info (struct gdbarch *gdbarch, struct ui_file *file)
{
  struct disassemble_info di;
  init_disassemble_info (&di, file, fprintf_disasm);
  di.flavour = bfd_target_unknown_flavour;
  di.memory_error_func = dis_asm_memory_error;
  di.print_address_func = dis_asm_print_address;
  /* NOTE: cagney/2003-04-28: The original code, from the old Insight
     disassembler had a local optomization here.  By default it would
     access the executable file, instead of the target memory (there
     was a growing list of exceptions though).  Unfortunately, the
     heuristic was flawed.  Commands like "disassemble &variable"
     didn't work as they relied on the access going to the target.
     Further, it has been supperseeded by trust-read-only-sections
     (although that should be superseeded by target_trust..._p()).  */
  di.read_memory_func = dis_asm_read_memory;
  di.arch = gdbarch_bfd_arch_info (gdbarch)->arch;
  di.mach = gdbarch_bfd_arch_info (gdbarch)->mach;
  di.endian = gdbarch_byte_order (gdbarch);
  di.endian_code = gdbarch_byte_order_for_code (gdbarch);
  di.application_data = gdbarch;
  disassemble_init_for_target (&di);
  return di;
}
/* Initialize disassembler (libopcodes/libbfd) for given file.
 *
 * If the the function returns data with data.bfd_file = NULL,
 * then the function failed.
 */
static struct disasm_data disasm_init(const char *filename)
{
    asection *section;
    struct disasm_data data;

    static bool initialized = false;
    if (!initialized)
    {
        bfd_init();
        initialized = true;
    }

    data.bfd_file = bfd_openr(filename, NULL);
    if (data.bfd_file == NULL)
    {
        VERB1 log_bfd_error("bfd_openr", filename);
        return data;
    }

    if (!bfd_check_format(data.bfd_file, bfd_object))
    {
        VERB1 log_bfd_error("bfd_check_format", filename);
        goto ret_fail;
    }

    section = bfd_get_section_by_name(data.bfd_file, ".text");
    if (section == NULL)
    {
        VERB1 log_bfd_error("bfd_get_section_by_name", filename);
        goto ret_fail;
    }

    data.disassemble = disassembler(data.bfd_file);
    if (data.disassemble == NULL)
    {
        VERB1 log("Unable to find disassembler");
        goto ret_fail;
    }

    init_disassemble_info(&data.info, NULL, buffer_printf);
    data.info.arch = bfd_get_arch(data.bfd_file);
    data.info.mach = bfd_get_mach(data.bfd_file);
    data.info.buffer_vma = section->vma;
    data.info.buffer_length = section->size;
    data.info.section = section;
    /*TODO: memory error func*/
    bfd_malloc_and_get_section(data.bfd_file, section, &data.info.buffer);
    disassemble_init_for_target(&data.info);

    return data;

ret_fail:
    bfd_close(data.bfd_file);
    data.bfd_file = NULL;
    return data;
}
Exemple #5
0
void print_instruction(void *buf, unsigned long size)
{
  struct disassemble_info info;
  init_disassemble_info (&info, stdout, (fprintf_ftype)fprintf);
  info.mach = bfd_mach_x86_64;
  info.endian = BFD_ENDIAN_LITTLE;
  info.buffer = buf;
  info.buffer_length = size;
  printf("\033[35m");
  print_insn_i386(0, &info);
  printf("\033[0m");
  printf("\n");
}
Exemple #6
0
struct disassemble_info
gdb_disassemble_info (unsigned char *mem_buf, char *output_buf)
{
  struct disassemble_info di;
  init_disassemble_info (&di, output_buf, sprintf_disasm);
  di.buffer = mem_buf;
  di.buffer_length = UINT_MAX;
  di.print_address_func = dis_asm_sprint_address;
  di.flavour = bfd_target_unknown_flavour;
  di.arch = bfd_arch_m68k;
  di.mach = bfd_mach_m68000;
  di.endian = BFD_ENDIAN_BIG;
  disassemble_init_for_target (&di);
  return di;
}
Exemple #7
0
static void init_disasm_info(bfd *abfd, struct disassemble_info *disasm_info)
{
    init_disassemble_info (disasm_info, stdout, (fprintf_ftype) fprintf);
    disasm_info->flavour = bfd_get_flavour (abfd);
    disasm_info->arch = bfd_get_arch (abfd);
    disasm_info->mach = bfd_get_mach (abfd);
    disasm_info->octets_per_byte = bfd_octets_per_byte (abfd);
    disasm_info->disassembler_needs_relocs = FALSE;

    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;

    disassemble_init_for_target(disasm_info);
    disasm_info->read_memory_func = my_read_memory;
}
Exemple #8
0
void arch_bfdDisasm(pid_t pid, uint8_t * mem, size_t size, char *instr)
{
    while (pthread_mutex_lock(&arch_bfd_mutex)) ;

    bfd_init();

    char fname[PATH_MAX];
    snprintf(fname, sizeof(fname), "/proc/%d/exe", pid);
    bfd *bfdh = bfd_openr(fname, NULL);
    if (bfdh == NULL) {
        LOGMSG(l_WARN, "bfd_openr('/proc/%d/exe') failed", pid);
        goto out;
    }

    if (!bfd_check_format(bfdh, bfd_object)) {
        LOGMSG(l_WARN, "bfd_check_format() failed");
        goto out;
    }

    disassembler_ftype disassemble = disassembler(bfdh);
    if (disassemble == NULL) {
        LOGMSG(l_WARN, "disassembler() failed");
        goto out;
    }

    struct disassemble_info info;
    init_disassemble_info(&info, instr, arch_bfdFPrintF);
    info.arch = bfd_get_arch(bfdh);
    info.mach = bfd_get_mach(bfdh);
    info.buffer = mem;
    info.buffer_length = size;
    info.section = NULL;
    info.endian = bfd_little_endian(bfdh) ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
    disassemble_init_for_target(&info);

    strcpy(instr, "");
    if (disassemble(0, &info) <= 0) {
        snprintf(instr, _HF_INSTR_SZ, "[DIS-ASM_FAILURE]");
    }

 out:
    bfdh ? bfd_close_all_done(bfdh) : 0;

    while (pthread_mutex_unlock(&arch_bfd_mutex)) ;
    return;
}
int
main ()
  {
    unsigned int data[3] = {0xE3A01080, 
							0xE2810001,
							0xE1A01001};
    bfd_byte* buf = (bfd_byte*) &data[0];
    
    disassemble_info* c = (struct disassemble_info*) calloc(1, sizeof(disassemble_info));
    // void init_disassemble_info (struct disassemble_info *dinfo, void *stream, fprintf_ftype fprintf_func)
    init_disassemble_info ( c, stdout, my_fprintf);
    
    //c->application_data
    //c->memory_error_func
    
    // set architecture
    c->arch = bfd_arch_arm;
    // set the specific machine: unknown allows all instructions in the libraries database
    c->mach = bfd_mach_arm_unknown;
    
    // should set the disassembler field of c to the right function
    disassemble_init_for_target( c );
    // given a bfd, the disassembler can find the arch by itself.
    //disassemble = disassembler( c );
    
    c->buffer_vma = 0;
    c->buffer = buf;
    c->buffer_length = 12;
    
    // while-loop for calling single instruction decoding:
    unsigned int count = 0;
    size_t pos = 0;
    size_t length = c->buffer_length;
    size_t max_pos = c->buffer_vma+length;
    
    while(pos < max_pos)
      {
      	//disassembler-function: print_insn_big_arm
      	//other possible functions are listed in opcodes/dissassemble.c
      	unsigned int size = print_insn_little_arm((bfd_vma) pos, c);
      	pos += size;
      	count++;
      	fprintf(stdout, "\n");
      }
    return 0;
  }
Mnemonic::Mnemonic(pword buffer, bool att)
    : opcodeLength(0), assemblyString("")
{
    //NULL the opcode:
    memset(this->opcode, 0, MAX_INSTRUCTION_BYTES);

    //Open a memory stream:
    char stringBuffer[256];
    FILE* memStream = fmemopen(stringBuffer, 256, "w");

    if (!memStream)
    {
        throw runtime_error("Failed to open memory stream.");
    }

    //Prepare disassembly info (bfd):
    struct disassemble_info info;
    init_disassemble_info(&info, memStream, (fprintf_ftype)fprintf);

    //This is the same for all architectures:
    info.buffer = (bfd_byte*)buffer;
    info.buffer_length = MAX_INSTRUCTION_BYTES;

    //Discriminate between architectures:
#ifdef __i386__
    info.arch = bfd_arch_i386;
    info.mach = att ? bfd_mach_i386_i386 : bfd_mach_i386_i386_intel_syntax;
    info.endian = BFD_ENDIAN_LITTLE;
    this->opcodeLength = att ? print_insn_i386(0, &info) : print_insn_i386_intel(0, &info);
#elif __amd64__
    info.arch = bfd_arch_i386;
    info.mach = att ? bfd_mach_x86_64 : bfd_mach_x86_64_intel_syntax;
    info.endian = BFD_ENDIAN_LITTLE;
    this->opcodeLength = att ? print_insn_i386(0, &info) : print_insn_i386_intel(0, &info);
#endif

    //Close the stream:
    fclose(memStream);

    //Assign:
    this->assemblyString = stringBuffer;

    //Build the raw opcode buffer from the length:
    memcpy(this->opcode, buffer, this->opcodeLength);
}
Exemple #11
0
static void get_asm_insns(uint8_t *image, size_t len, unsigned long base,
			  int opcodes)
{
	int count, i, pc = 0;
	char tpath[256];
	struct disassemble_info info;
	disassembler_ftype disassemble;
	bfd *bfdf;

	memset(tpath, 0, sizeof(tpath));
	get_exec_path(tpath, sizeof(tpath));

	bfdf = bfd_openr(tpath, NULL);
	assert(bfdf);
	assert(bfd_check_format(bfdf, bfd_object));

	init_disassemble_info(&info, stdout, (fprintf_ftype) fprintf);
	info.arch = bfd_get_arch(bfdf);
	info.mach = bfd_get_mach(bfdf);
	info.buffer = image;
	info.buffer_length = len;

	disassemble_init_for_target(&info);

	disassemble = disassembler(bfdf);
	assert(disassemble);

	do {
		printf("%4x:\t", pc);

		count = disassemble(pc, &info);

		if (opcodes) {
			printf("\n\t");
			for (i = 0; i < count; ++i)
				printf("%02x ", (uint8_t) image[pc + i]);
		}
		printf("\n");

		pc += count;
	} while(count > 0 && pc < len);

	bfd_close(bfdf);
}
Exemple #12
0
void init_disasm_info(bfd *abfd, struct disassemble_info *disasm_info)
{
  init_disassemble_info (disasm_info, stdout, (fprintf_ftype) fprintf);
  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 (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;

  disassemble_init_for_target(disasm_info);

  disasm_info->read_memory_func = my_read_memory;
}
Exemple #13
0
static void
gdb_buffered_insn_length_init_dis (struct gdbarch *gdbarch,
				   struct disassemble_info *di,
				   const gdb_byte *insn, int max_len,
				   CORE_ADDR addr)
{
  init_disassemble_info (di, NULL, gdb_buffered_insn_length_fprintf);

  /* init_disassemble_info installs buffer_read_memory, etc.
     so we don't need to do that here.
     The cast is necessary until disassemble_info is const-ified.  */
  di->buffer = (gdb_byte *) insn;
  di->buffer_length = max_len;
  di->buffer_vma = addr;

  di->arch = gdbarch_bfd_arch_info (gdbarch)->arch;
  di->mach = gdbarch_bfd_arch_info (gdbarch)->mach;
  di->endian = gdbarch_byte_order (gdbarch);
  di->endian_code = gdbarch_byte_order_for_code (gdbarch);

  disassemble_init_for_target (di);
}
Exemple #14
0
bool disas_libopcode(FILE *fp_out, const char *machine, bool big_endian,
		     uint64_t addr, void *buf, size_t len)
{
	bfd *abfd = NULL;
	struct disassemble_info inf;
	const bfd_arch_info_type *arch_inf = bfd_scan_arch (machine);
	disassembler_ftype disas_fn;
	int size, pos;

	if (!arch_inf) {
		return false;
	}

	abfd = bfd_openr("/dev/null", "binary");
	abfd->arch_info = arch_inf;

	init_disassemble_info (&inf, fp_out, (fprintf_ftype) fprintf);
	inf.buffer = buf;
	inf.buffer_vma = addr;
	inf.buffer_length = len;
	inf.endian = big_endian ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE;
	inf.print_address_func = print_address;

	disassemble_init_for_target(&inf);

	disas_fn = disassembler (abfd);
	pos = 0;
	do {
		fprintf(fp_out, "%" PRIx64 "\t", addr + pos);
		size = disas_fn(addr + pos, &inf);
		pos += size;
		fputc('\n', fp_out);
	} while (pos < len);
	bfd_close(abfd);
	return true;
}
Exemple #15
0
int main(void) {
	disassembler_ftype disassemble_fn;
	disassemble_info info = {0};
	void *lib, *sym;
	lib_init_fn init_fn;

	init_disassemble_info(&info, stdout, (fprintf_ftype) fprintf);
	info.arch = bfd_arch_i386;			// * 
	info.mach = bfd_mach_i386_i386;			// *
	info.flavour = bfd_target_elf_flavour;		// * 
	info.endian = BFD_ENDIAN_LITTLE;		// *
	// not needed for this test code
	//info.read_memory_func = buffer_read_memory;
	//info.memory_error_func = perror_memory;
	//info.print_address_func = generic_print_address;
	//info.symbol_at_address_func = generic_symbol_at_address;
	//info.fprintf_func = disprintf; 
	//info.stream = stdout; 
	//info.symbols = NULL;
	//info.num_symbols = 0;
	info.display_endian = BFD_ENDIAN_LITTLE;	// *

	info.buffer = target_buf;
	info.buffer_length = sizeof(target_buf);
	info.buffer_vma = 0x1000;

	printf("x86 AT&T disassembly\n");
	disbuf(print_insn_i386_att, &info);		// *

	// test unknown-everything
	printf("x86 Intel disassembly\n");
	info.arch = bfd_arch_unknown;
	info.mach = bfd_arch_unknown;			// *
	info.flavour = bfd_target_unknown_flavour;
	disbuf(print_insn_i386_intel, &info);		// *

	lib = dlopen(ARM_BFD, RTLD_NOW | RTLD_GLOBAL );
	if (! lib ) {
		fprintf(stderr, "Unable to load %s: %s\n", ARM_PATH, dlerror());
	}

	lib = dlopen(ARM_PATH, RTLD_NOW | RTLD_GLOBAL ); // RTLD_LOCAL );
	if ( lib ) {
		sym = dlsym(lib, ARM_INIT);
		if (sym) {
			init_fn = (lib_init_fn) sym;
			(*init_fn)(&info, stdout, (fprintf_ftype) fprintf);
			info.arch = bfd_arch_arm;			// * 
			info.mach = bfd_mach_arm_5;			// *
			info.flavour = bfd_target_elf_flavour;		// * 
			info.endian = BFD_ENDIAN_LITTLE;		// *
			info.buffer = target_buf;
			info.buffer_length = sizeof(target_buf);
			info.buffer_vma = 0x1000;
		}

		sym = dlsym(lib, ARM_SYM);
		if (sym) {
			printf("ARM disassembly\n");
			disbuf(sym, &info);
		}
		dlclose(lib);
	} else {
		fprintf(stderr, "Unable to load %s: %s\n", ARM_PATH, dlerror());
	}

	// Try Intel again (make sure loaded BFD does not conflict)
	init_disassemble_info(&info, stdout, (fprintf_ftype) fprintf);
	info.display_endian = BFD_ENDIAN_LITTLE;	// *
	info.buffer = target_buf;
	info.buffer_length = sizeof(target_buf);
	info.buffer_vma = 0x1000;
	printf("(Post-ARM) x86 AT&T Disassembly\n");
	info.arch = bfd_arch_unknown;
	info.mach = bfd_arch_unknown;			// *
	info.flavour = bfd_target_unknown_flavour;
	/* test that overwriting print_address_func doesn't break anything */
	info.print_address_func = (void (*) (bfd_vma, struct disassemble_info *)) print_insn_i386_att;
	disbuf(print_insn_i386_att, &info);		// *

	return(0);
}
Exemple #16
0
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);
}
Exemple #17
0
struct sr_disasm_state *
sr_disasm_init(const char *file_name,
               char **error_message)
{
#if HAVE_LIBOPCODES
    struct sr_disasm_state *state =
        sr_malloc(sizeof(struct sr_disasm_state));

    state->bfd_file = bfd_openr(file_name, NULL);
    if (!state->bfd_file)
    {
        *error_message = sr_asprintf("Failed to open file %s: %s",
                                     file_name,
                                     bfd_errmsg(bfd_get_error()));
        free(state);
        return NULL;
    }

    if (!bfd_check_format(state->bfd_file, bfd_object))
    {
        *error_message = sr_asprintf("Invalid file format of %s: %s",
                                     file_name,
                                     bfd_errmsg(bfd_get_error()));
        bfd_close(state->bfd_file);
        free(state);
        return NULL;
    }

    asection *section =
        bfd_get_section_by_name(state->bfd_file, ".text");

    if (!section)
    {
        *error_message = sr_asprintf(
            "Failed to find .text section in %s: %s",
            file_name,
            bfd_errmsg(bfd_get_error()));

        bfd_close(state->bfd_file);
        free(state);
        return NULL;
    }

    state->disassembler = disassembler(state->bfd_file);
    if (!state->disassembler)
    {
        *error_message = sr_asprintf(
            "Unable to find disassembler for %s",
            file_name);

        bfd_close(state->bfd_file);
        free(state);
        return NULL;
    }

    init_disassemble_info(&state->info, NULL, buffer_printf);
    state->info.arch = bfd_get_arch(state->bfd_file);
    state->info.mach = bfd_get_mach(state->bfd_file);
    state->info.buffer_vma = section->vma;
    state->info.buffer_length = section->size;
    state->info.section = section;
    /* TODO: memory error func */
    bfd_malloc_and_get_section(state->bfd_file, section,
                               &state->info.buffer);

    disassemble_init_for_target(&state->info);
    return state;
#else // HAVE_LIBOPCODES
    *error_message = sr_asprintf("satyr compiled without libopcodes");
    return NULL;
#endif // HAVE_LIBOPCODES
}
uv_err_t UVDBfdInstructionIterator::init() {
    bfd *a_bfd = NULL;

    uv_assert_ret(m_obj);
    uv_assert_ret(m_obj->m_bfd);
    a_bfd = m_obj->m_bfd;

    //Needs to be an object or an archive
    if( !bfd_check_format(a_bfd, bfd_object)
            && !bfd_check_format(a_bfd, bfd_archive) )
    {
        //bfd_close(a_bfd);
        printf("bad file\n");
        return UV_DEBUG(UV_ERR_GENERAL);
    }
    printf("BFD open and is object\n");

    /*
    Standard disassemblers.  Disassemble one instruction at the given
    target address.  Return number of octets processed.
    typedef int (*disassembler_ftype) (bfd_vma, disassemble_info *);
    */
    g_disassembler_function = disassembler(a_bfd);
    if( !g_disassembler_function ) {
        printf("failed \n");
        return UV_DEBUG(UV_ERR_GENERAL);
    }

    memset(&m_disasm_info, 0, sizeof(m_disasm_info));
    init_disassemble_info(&m_disasm_info, stdout, (fprintf_ftype) fprintf);
    m_disasm_info.flavour = bfd_get_flavour (a_bfd);
    m_disasm_info.arch = bfd_get_arch (a_bfd);
    m_disasm_info.mach = bfd_get_mach (a_bfd);
    m_disasm_info.disassembler_options = NULL;
    m_disasm_info.octets_per_byte = bfd_octets_per_byte(a_bfd);
    m_disasm_info.skip_zeroes = 0;
    m_disasm_info.skip_zeroes_at_end = 0;
    m_disasm_info.disassembler_needs_relocs = FALSE;
    m_disasm_info.display_endian = m_disasm_info.endian = BFD_ENDIAN_BIG;

    //Don't care
    m_disasm_info.application_data = NULL;
    m_disasm_info.print_address_func = objdump_print_address;
    m_disasm_info.symbol_at_address_func = objdump_symbol_at_address;

    disassemble_init_for_target(&m_disasm_info);

    //Wonder if these can be NULL?
    m_disasm_info.symtab = NULL;
    m_disasm_info.symtab_size = 0;

    /*
    This won't work since we want to step on our own accord
    bfd_map_over_sections(a_bfd, disassemble_section, &disasm_info);
    */
#if 0
    void
    bfd_map_over_sections (bfd *abfd,
                           void (*operation) (bfd *, asection *, void *),
                           void *user_storage)
    {
        asection *sect;
        unsigned int i = 0;

        for (sect = abfd->sections; sect != NULL; i++, sect = sect->next)
            (*operation) (abfd, sect, user_storage);

        if (i != abfd->section_count)	/* Debugging */
            abort ();
    }