示例#1
0
// 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;
}
示例#2
0
/* Create a dummy BFD.  */
bfd *
plugin_get_ir_dummy_bfd (const char *name, bfd *srctemplate)
{
  bfd *abfd;

  bfd_use_reserved_id = 1;
  abfd = bfd_create (concat (name, IRONLY_SUFFIX, (const char *) NULL),
		     srctemplate);
  if (abfd != NULL)
    {
      abfd->flags |= BFD_LINKER_CREATED | BFD_PLUGIN;
      bfd_set_arch_info (abfd, bfd_get_arch_info (srctemplate));
      bfd_set_gp_size (abfd, bfd_get_gp_size (srctemplate));
      if (bfd_make_writable (abfd)
	  && bfd_copy_private_bfd_data (srctemplate, abfd))
	{
	  flagword flags;

	  /* Create section to own the symbols.  */
	  flags = (SEC_CODE | SEC_HAS_CONTENTS | SEC_READONLY
		   | SEC_ALLOC | SEC_LOAD | SEC_KEEP | SEC_EXCLUDE);
	  if (bfd_make_section_anyway_with_flags (abfd, ".text", flags))
	    return abfd;
	}
    }
  einfo (_("could not create dummy IR bfd: %F%E\n"));
  return NULL;
}
示例#3
0
/* 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;
}
示例#4
0
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;
    }
}
示例#5
0
文件: interp.c 项目: ChrisG0x20/gdb
static void
bfin_user_init (SIM_DESC sd, SIM_CPU *cpu, struct bfd *abfd,
		const char * const *argv, const char * const *env)
{
  /* XXX: Missing host -> target endian ...  */
  /* Linux starts the user app with the stack:
       argc
       argv[0]          -- pointers to the actual strings
       argv[1..N]
       NULL
       env[0]
       env[1..N]
       NULL
       auxvt[0].type    -- ELF Auxiliary Vector Table
       auxvt[0].value
       auxvt[1..N]
       AT_NULL
       0
       argv[0..N][0..M] -- actual argv/env strings
       env[0..N][0..M]
       FDPIC loadmaps   -- for FDPIC apps
     So set things up the same way.  */
  int i, argc, envc;
  bu32 argv_flat, env_flat;

  bu32 sp, sp_flat;

  /* start, at_phdr, at_phnum, at_base, at_entry, pt_dynamic  */
  bu32 elf_addrs[6];
  bu32 auxvt;
  bu32 exec_loadmap, ldso_loadmap;
  char *ldso_path;

  unsigned char null[4] = { 0, 0, 0, 0 };

  host_callback *cb = STATE_CALLBACK (sd);

  elf_addrs[0] = elf_addrs[4] = bfd_get_start_address (abfd);
  elf_addrs[1] = elf_addrs[2] = elf_addrs[3] = elf_addrs[5] = 0;

  /* Keep the load addresses consistent between runs.  Also make sure we make
     space for the fixed code region (part of the Blackfin Linux ABI).  */
  fdpic_load_offset = 0x1000;

  /* First try to load this as an FDPIC executable.  */
  sp = SPREG;
  if (!bfin_fdpic_load (sd, cpu, STATE_PROG_BFD (sd), &sp, elf_addrs, &ldso_path))
    goto skip_fdpic_init;
  exec_loadmap = sp;

  /* If that worked, then load the fixed code region.  We only do this for
     FDPIC ELFs atm because they are PIEs and let us relocate them without
     manual fixups.  FLAT files however require location processing which
     we do not do ourselves, and they link with a VMA of 0.  */
  sim_write (sd, 0x400, bfin_linux_fixed_code, sizeof (bfin_linux_fixed_code));

  /* If the FDPIC needs an interpreter, then load it up too.  */
  if (ldso_path)
    {
      const char *ldso_full_path = concat (simulator_sysroot, ldso_path, NULL);
      struct bfd *ldso_bfd;

      ldso_bfd = bfd_openr (ldso_full_path, STATE_TARGET (sd));
      if (!ldso_bfd)
	{
	  sim_io_eprintf (sd, "bfin-sim: bfd open failed: %s\n", ldso_full_path);
	  goto static_fdpic;
	}
      if (!bfd_check_format (ldso_bfd, bfd_object))
	sim_io_eprintf (sd, "bfin-sim: bfd format not valid: %s\n", ldso_full_path);
      bfd_set_arch_info (ldso_bfd, STATE_ARCHITECTURE (sd));

      if (!bfin_fdpic_load (sd, cpu, ldso_bfd, &sp, elf_addrs, &ldso_path))
	sim_io_eprintf (sd, "bfin-sim: FDPIC ldso failed to load: %s\n", ldso_full_path);
      if (ldso_path)
	sim_io_eprintf (sd, "bfin-sim: FDPIC ldso (%s) needs an interpreter (%s) !?\n",
			ldso_full_path, ldso_path);

      ldso_loadmap = sp;
    }
  else
 static_fdpic:
    ldso_loadmap = 0;

  /* Finally setup the registers required by the FDPIC ABI.  */
  SET_DREG (7, 0); /* Zero out FINI funcptr -- ldso will set this up.  */
  SET_PREG (0, exec_loadmap); /* Exec loadmap addr.  */
  SET_PREG (1, ldso_loadmap); /* Interp loadmap addr.  */
  SET_PREG (2, elf_addrs[5]); /* PT_DYNAMIC map addr.  */

  auxvt = 1;
  SET_SPREG (sp);
 skip_fdpic_init:
  sim_pc_set (cpu, elf_addrs[0]);

  /* Figure out how much storage the argv/env strings need.  */
  argc = count_argc (argv);
  if (argc == -1)
    argc = 0;
  argv_flat = argc; /* NUL bytes  */
  for (i = 0; i < argc; ++i)
    argv_flat += strlen (argv[i]);

  if (!env)
    env = simple_env;
  envc = count_argc (env);
  env_flat = envc; /* NUL bytes  */
  for (i = 0; i < envc; ++i)
    env_flat += strlen (env[i]);

  /* Push the Auxiliary Vector Table between argv/env and actual strings.  */
  sp_flat = sp = ALIGN (SPREG - argv_flat - env_flat - 4, 4);
  if (auxvt)
    {
# define AT_PUSH(at, val) \
  auxvt_size += 8; \
  sp -= 4; \
  auxvt = (val); \
  sim_write (sd, sp, (void *)&auxvt, 4); \
  sp -= 4; \
  auxvt = (at); \
  sim_write (sd, sp, (void *)&auxvt, 4)
      unsigned int egid = getegid (), gid = getgid ();
      unsigned int euid = geteuid (), uid = getuid ();
      bu32 auxvt_size = 0;
      AT_PUSH (AT_NULL, 0);
      AT_PUSH (AT_SECURE, egid != gid || euid != uid);
      AT_PUSH (AT_EGID, egid);
      AT_PUSH (AT_GID, gid);
      AT_PUSH (AT_EUID, euid);
      AT_PUSH (AT_UID, uid);
      AT_PUSH (AT_ENTRY, elf_addrs[4]);
      AT_PUSH (AT_FLAGS, 0);
      AT_PUSH (AT_BASE, elf_addrs[3]);
      AT_PUSH (AT_PHNUM, elf_addrs[2]);
      AT_PUSH (AT_PHENT, sizeof (Elf32_External_Phdr));
      AT_PUSH (AT_PHDR, elf_addrs[1]);
      AT_PUSH (AT_CLKTCK, 100); /* XXX: This ever not 100 ?  */
      AT_PUSH (AT_PAGESZ, 4096);
      AT_PUSH (AT_HWCAP, 0);
#undef AT_PUSH
    }
  SET_SPREG (sp);

  /* Push the argc/argv/env after the auxvt.  */
  sp -= ((1 + argc + 1 + envc + 1) * 4);
  SET_SPREG (sp);

  /* First push the argc value.  */
  sim_write (sd, sp, (void *)&argc, 4);
  sp += 4;

  /* Then the actual argv strings so we know where to point argv[].  */
  for (i = 0; i < argc; ++i)
    {
      unsigned len = strlen (argv[i]) + 1;
      sim_write (sd, sp_flat, (void *)argv[i], len);
      sim_write (sd, sp, (void *)&sp_flat, 4);
      sp_flat += len;
      sp += 4;
    }
  sim_write (sd, sp, null, 4);
  sp += 4;

  /* Then the actual env strings so we know where to point env[].  */
  for (i = 0; i < envc; ++i)
    {
      unsigned len = strlen (env[i]) + 1;
      sim_write (sd, sp_flat, (void *)env[i], len);
      sim_write (sd, sp, (void *)&sp_flat, 4);
      sp_flat += len;
      sp += 4;
    }

  /* Set some callbacks.  */
  cb->syscall_map = cb_linux_syscall_map;
  cb->errno_map = cb_linux_errno_map;
  cb->open_map = cb_linux_open_map;
  cb->signal_map = cb_linux_signal_map;
  cb->stat_map = stat_map_32 = cb_linux_stat_map_32;
  stat_map_64 = cb_linux_stat_map_64;
}
示例#6
0
文件: bfd.c 项目: jirislaby/pb173-bin
void replace_hello(const char *input_path, const char *output_path)
{
    bfd_init();

    bfd *ibfd = bfd_openr(input_path, NULL);

    if (ibfd == NULL)
        errx(1, bfd_errmsg(bfd_get_error()));

    if (!bfd_check_format(ibfd, bfd_object)) {
        bfd_close_all_done(ibfd);
        errx(1, "Input file is not a valid object file.");
    }

    bfd *obfd = bfd_openw(output_path, bfd_get_target(ibfd));

    if (obfd == NULL) {
        bfd_close_all_done(ibfd);
        errx(1, bfd_errmsg(bfd_get_error()));
    }

    if (!bfd_set_format(obfd, bfd_get_format(ibfd))) {
        bfd_close_all_done(ibfd);
        bfd_close_all_done(obfd);
        errx(1, "Setting obfd format failed: %s\n", bfd_errmsg(bfd_get_error()));
    }

    bfd_set_arch_info(obfd, bfd_get_arch_info(ibfd));

    // Create sections for .data
    asection *section = bfd_get_section_by_name(ibfd, ".data");
    while (section != NULL) {
        if (section->flags & SEC_HAS_CONTENTS) {
            char *section_contents = (char *)malloc(section->size);
            bfd_get_section_contents(ibfd, section, section_contents, 0, section->size);

            char *hello_pos = (char *)memmem(section_contents, section->size, "hello", 5);
            if (hello_pos != NULL) {
                if (bfd_make_section_anyway_with_flags(obfd, ".data", section->flags) == NULL) {
                    free(section_contents);
                    bfd_close_all_done(ibfd);
                    bfd_close_all_done(obfd);
                    errx(1, bfd_errmsg(bfd_get_error()));
                }
            }

            free(section_contents);
        }

        section = bfd_get_next_section_by_name(ibfd, section);
    }

    asection *comment_section = bfd_make_section_anyway_with_flags(obfd, ".comment.my_objcopy", SEC_HAS_CONTENTS);
    if (comment_section == NULL) {
        bfd_close_all_done(ibfd);
        bfd_close_all_done(obfd);
        errx(1, bfd_errmsg(bfd_get_error()));
    }

    if (!bfd_set_section_size(obfd, comment_section, 3)) {
        bfd_close_all_done(ibfd);
        bfd_close_all_done(obfd);
        errx(1, bfd_errmsg(bfd_get_error()));
    }

    if (!bfd_set_section_contents(obfd, comment_section, "moo", 0, 3)) {
        bfd_close_all_done(ibfd);
        bfd_close_all_done(obfd);
        errx(1, bfd_errmsg(bfd_get_error()));
    }

    // section = bfd_get_section_by_name(ibfd, ".data");
    // asection *osection = bfd_get_section_by_name(obfd, ".data");
    // if (osection == NULL) {
    // 	bfd_close_all_done(ibfd);
    // 	bfd_close_all_done(obfd);
    // 	errx(1, bfd_errmsg(bfd_get_error()));
    // }
    // while (section != NULL) {
    // 	if (section->flags & SEC_HAS_CONTENTS) {
    // 		char *section_contents = (char *)malloc(section->size);
    // 		bfd_get_section_contents(ibfd, section, section_contents, 0, section->size);
    //
    // 		char *hello_pos = (char *)memmem(section_contents, section->size, "hello", 5);
    // 		if (hello_pos != NULL) {
    // 			hello_pos[1] = 'o';
    // 			hello_pos[4] = 'a';
    // 			if (bfd_set_section_contents(obfd, osection, section_contents, 0, section->size)) {
    // 				free(section_contents);
    // 				bfd_close_all_done(ibfd);
    // 				bfd_close_all_done(obfd);
    // 				errx(1, bfd_errmsg(bfd_get_error()));
    // 			}
    // 		}
    //
    // 		free(section_contents);
    // 		osection = bfd_get_next_section_by_name(obfd, osection);
    // 	}
    //
    // 	section = bfd_get_next_section_by_name(ibfd, section);
    // }

    if (!bfd_close(obfd))
        errx(1, "Closing obfd failed: %s\n", bfd_errmsg(bfd_get_error()));

    if (!bfd_close(ibfd))
        errx(1, "Closing ibfd failed: %s\n", bfd_errmsg(bfd_get_error()));
}