Beispiel #1
0
static void
arm_linux_store_inferior_registers (struct target_ops *ops,
				    struct regcache *regcache, int regno)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

  if (-1 == regno)
    {
      store_regs (regcache);
      store_fpregs (regcache);
      if (tdep->have_wmmx_registers)
	store_wmmx_regs (regcache);
      if (tdep->vfp_register_count > 0)
	store_vfp_regs (regcache);
    }
  else
    {
      if (regno < ARM_F0_REGNUM || regno == ARM_PS_REGNUM)
	store_regs (regcache);
      else if ((regno >= ARM_F0_REGNUM) && (regno <= ARM_FPS_REGNUM))
	store_fpregs (regcache);
      else if (tdep->have_wmmx_registers
	       && regno >= ARM_WR0_REGNUM && regno <= ARM_WCGR7_REGNUM)
	store_wmmx_regs (regcache);
      else if (tdep->vfp_register_count > 0
	       && regno >= ARM_D0_REGNUM
	       && regno <= ARM_D0_REGNUM + tdep->vfp_register_count)
	store_vfp_regs (regcache);
    }
}
/* Store register REGNO back into the child process.  If REGNO is -1,
   do this for all registers (including the floating point and SSE
   registers).  */
static void
i386_linux_store_inferior_registers (struct target_ops *ops,
				     struct regcache *regcache, int regno)
{
  int tid;

  /* Use the old method of poking around in `struct user' if the
     SETREGS request isn't available.  */
  if (!have_ptrace_getregs)
    {
      int i;

      for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
	if (regno == -1 || regno == i)
	  store_register (regcache, i);

      return;
    }

  /* GNU/Linux LWP ID's are process ID's.  */
  tid = TIDGET (inferior_ptid);
  if (tid == 0)
    tid = PIDGET (inferior_ptid); /* Not a threaded program.  */

  /* Use the PTRACE_SETFPXREGS requests whenever possible, since it
     transfers more registers in one system call.  But remember that
     store_fpxregs can fail, and return zero.  */
  if (regno == -1)
    {
      store_regs (regcache, tid, regno);
      if (store_fpxregs (regcache, tid, regno))
	return;
      store_fpregs (regcache, tid, regno);
      return;
    }

  if (GETREGS_SUPPLIES (regno))
    {
      store_regs (regcache, tid, regno);
      return;
    }

  if (GETFPXREGS_SUPPLIES (regno))
    {
      if (store_fpxregs (regcache, tid, regno))
	return;

      /* Either our processor or our kernel doesn't support the SSE
	 registers, so just write the FP registers in the traditional
	 way.  */
      store_fpregs (regcache, tid, regno);
      return;
    }

  internal_error (__FILE__, __LINE__,
		  _("Got request to store bad register number %d."), regno);
}
Beispiel #3
0
static void
arm_linux_store_inferior_registers (struct target_ops *ops,
				    struct regcache *regcache, int regno)
{
  if (-1 == regno)
    {
      store_regs (regcache);
      store_fpregs (regcache);
      if (arm_linux_has_wmmx_registers)
	store_wmmx_regs (regcache);
      if (arm_linux_vfp_register_count > 0)
	store_vfp_regs (regcache);
    }
  else
    {
      if (regno < ARM_F0_REGNUM || regno == ARM_PS_REGNUM)
        store_register (regcache, regno);
      else if ((regno >= ARM_F0_REGNUM) && (regno <= ARM_FPS_REGNUM))
        store_fpregister (regcache, regno);
      else if (arm_linux_has_wmmx_registers
	       && regno >= ARM_WR0_REGNUM && regno <= ARM_WCGR7_REGNUM)
	store_wmmx_regs (regcache);
      else if (arm_linux_vfp_register_count > 0
	       && regno >= ARM_D0_REGNUM
	       && regno <= ARM_D0_REGNUM + arm_linux_vfp_register_count)
	store_vfp_regs (regcache);
    }
}
/* Store register REGNO back into the child process.  If REGNO is -1,
   do this for all registers (including the floating point and SSE
   registers).  */
static void
m68k_linux_store_inferior_registers (struct target_ops *ops,
				     struct regcache *regcache, int regno)
{
  int tid;

  /* Use the old method of poking around in `struct user' if the
     SETREGS request isn't available.  */
  if (! have_ptrace_getregs)
    {
      old_store_inferior_registers (regcache, regno);
      return;
    }

  /* GNU/Linux LWP ID's are process ID's.  */
  tid = TIDGET (inferior_ptid);
  if (tid == 0)
    tid = PIDGET (inferior_ptid);	/* Not a threaded program.  */

  /* Use the PTRACE_SETFPREGS requests whenever possible, since it
     transfers more registers in one system call.  But remember that
     store_fpregs can fail, and return zero.  */
  if (regno == -1)
    {
      store_regs (regcache, tid, regno);
      store_fpregs (regcache, tid, regno);
      return;
    }

  if (getregs_supplies (regno))
    {
      store_regs (regcache, tid, regno);
      return;
    }

  if (getfpregs_supplies (regno))
    {
      store_fpregs (regcache, tid, regno);
      return;
    }

  internal_error (__FILE__, __LINE__,
		  _("Got request to store bad register number %d."), regno);
}
Beispiel #5
0
/* Store register REGNUM back into the child process.  If REGNUM is
   -1, do this for all registers.  */
void
store_inferior_registers (int regnum)
{
  int tid = s390_inferior_tid ();

  if (regnum == -1 
      || (regnum < S390_NUM_REGS && regmap_gregset[regnum] != -1))
    store_regs (tid, regnum);

  if (regnum == -1 
      || (regnum < S390_NUM_REGS && regmap_fpregset[regnum] != -1))
    store_fpregs (tid, regnum);
}
/* Store register REGNUM back into the child process.  If REGNUM is
   -1, do this for all registers.  */
static void
s390_linux_store_inferior_registers (struct regcache *regcache, int regnum)
{
  int tid = s390_inferior_tid ();

  if (regnum == -1 
      || (regnum < S390_NUM_REGS && regmap_gregset[regnum] != -1))
    store_regs (regcache, tid, regnum);

  if (regnum == -1 
      || (regnum < S390_NUM_REGS && regmap_fpregset[regnum] != -1))
    store_fpregs (regcache, tid, regnum);
}
Beispiel #7
0
void
store_inferior_registers (int regno)
{
  if (regno >= 0)
    {
      if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
	store_register (regno);
      else
	store_fp_register (regno);
    }
  else
    {
      store_regs ();
      store_fp_regs ();
    }
}
Beispiel #8
0
void
store_inferior_registers (int regno)
{
  if (-1 == regno)
    {
      store_regs ();
      store_fpregs ();
    }
  else
    {
      if ((regno < F0_REGNUM) || (regno > FPS_REGNUM))
        store_register (regno);

      if ((regno >= F0_REGNUM) && (regno <= FPS_REGNUM))
        store_fpregister (regno);
    }
}
Beispiel #9
0
static void
armnbsd_store_registers (struct target_ops *ops,
			 struct regcache *regcache, int regno)
{
  if (regno >= 0)
    {
      if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
	store_register (regcache, regno);
      else
	store_fp_register (regcache, regno);
    }
  else
    {
      store_regs (regcache);
      store_fp_regs (regcache);
    }
}
struct compile_module *
compile_object_load (const char *object_file, const char *source_file,
		     enum compile_i_scope_types scope, void *scope_data)
{
  struct cleanup *cleanups, *cleanups_free_objfile;
  bfd *abfd;
  struct setup_sections_data setup_sections_data;
  CORE_ADDR addr, regs_addr, out_value_addr = 0;
  struct symbol *func_sym;
  struct type *func_type;
  struct bound_minimal_symbol bmsym;
  long storage_needed;
  asymbol **symbol_table, **symp;
  long number_of_symbols, missing_symbols;
  struct type *dptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
  unsigned dptr_type_len = TYPE_LENGTH (dptr_type);
  struct compile_module *retval;
  struct type *regs_type, *out_value_type = NULL;
  char *filename, **matching;
  struct objfile *objfile;
  int expect_parameters;
  struct type *expect_return_type;
  struct munmap_list *munmap_list_head = NULL;

  filename = tilde_expand (object_file);
  cleanups = make_cleanup (xfree, filename);

  abfd = gdb_bfd_open (filename, gnutarget, -1);
  if (abfd == NULL)
    error (_("\"%s\": could not open as compiled module: %s"),
          filename, bfd_errmsg (bfd_get_error ()));
  make_cleanup_bfd_unref (abfd);

  if (!bfd_check_format_matches (abfd, bfd_object, &matching))
    error (_("\"%s\": not in loadable format: %s"),
          filename, gdb_bfd_errmsg (bfd_get_error (), matching));

  if ((bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC)) != 0)
    error (_("\"%s\": not in object format."), filename);

  setup_sections_data.last_size = 0;
  setup_sections_data.last_section_first = abfd->sections;
  setup_sections_data.last_prot = -1;
  setup_sections_data.last_max_alignment = 1;
  setup_sections_data.munmap_list_headp = &munmap_list_head;
  make_cleanup (munmap_listp_free_cleanup, &munmap_list_head);
  bfd_map_over_sections (abfd, setup_sections, &setup_sections_data);
  setup_sections (abfd, NULL, &setup_sections_data);

  storage_needed = bfd_get_symtab_upper_bound (abfd);
  if (storage_needed < 0)
    error (_("Cannot read symbols of compiled module \"%s\": %s"),
          filename, bfd_errmsg (bfd_get_error ()));

  /* SYMFILE_VERBOSE is not passed even if FROM_TTY, user is not interested in
     "Reading symbols from ..." message for automatically generated file.  */
  objfile = symbol_file_add_from_bfd (abfd, filename, 0, NULL, 0, NULL);
  cleanups_free_objfile = make_cleanup_free_objfile (objfile);

  func_sym = lookup_global_symbol_from_objfile (objfile,
						GCC_FE_WRAPPER_FUNCTION,
						VAR_DOMAIN).symbol;
  if (func_sym == NULL)
    error (_("Cannot find function \"%s\" in compiled module \"%s\"."),
	   GCC_FE_WRAPPER_FUNCTION, objfile_name (objfile));
  func_type = SYMBOL_TYPE (func_sym);
  if (TYPE_CODE (func_type) != TYPE_CODE_FUNC)
    error (_("Invalid type code %d of function \"%s\" in compiled "
	     "module \"%s\"."),
	   TYPE_CODE (func_type), GCC_FE_WRAPPER_FUNCTION,
	   objfile_name (objfile));

  switch (scope)
    {
    case COMPILE_I_SIMPLE_SCOPE:
      expect_parameters = 1;
      expect_return_type = builtin_type (target_gdbarch ())->builtin_void;
      break;
    case COMPILE_I_RAW_SCOPE:
      expect_parameters = 0;
      expect_return_type = builtin_type (target_gdbarch ())->builtin_void;
      break;
    case COMPILE_I_PRINT_ADDRESS_SCOPE:
    case COMPILE_I_PRINT_VALUE_SCOPE:
      expect_parameters = 2;
      expect_return_type = builtin_type (target_gdbarch ())->builtin_void;
      break;
    default:
      internal_error (__FILE__, __LINE__, _("invalid scope %d"), scope);
    }
  if (TYPE_NFIELDS (func_type) != expect_parameters)
    error (_("Invalid %d parameters of function \"%s\" in compiled "
	     "module \"%s\"."),
	   TYPE_NFIELDS (func_type), GCC_FE_WRAPPER_FUNCTION,
	   objfile_name (objfile));
  if (!types_deeply_equal (expect_return_type, TYPE_TARGET_TYPE (func_type)))
    error (_("Invalid return type of function \"%s\" in compiled "
	    "module \"%s\"."),
	  GCC_FE_WRAPPER_FUNCTION, objfile_name (objfile));

  /* The memory may be later needed
     by bfd_generic_get_relocated_section_contents
     called from default_symfile_relocate.  */
  symbol_table = obstack_alloc (&objfile->objfile_obstack, storage_needed);
  number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
  if (number_of_symbols < 0)
    error (_("Cannot parse symbols of compiled module \"%s\": %s"),
          filename, bfd_errmsg (bfd_get_error ()));

  missing_symbols = 0;
  for (symp = symbol_table; symp < symbol_table + number_of_symbols; symp++)
    {
      asymbol *sym = *symp;

      if (sym->flags != 0)
	continue;
      sym->flags = BSF_GLOBAL;
      sym->section = bfd_abs_section_ptr;
      if (strcmp (sym->name, "_GLOBAL_OFFSET_TABLE_") == 0)
	{
	  if (compile_debug)
	    fprintf_unfiltered (gdb_stdlog,
				"ELF symbol \"%s\" relocated to zero\n",
				sym->name);

	  /* It seems to be a GCC bug, with -mcmodel=large there should be no
	     need for _GLOBAL_OFFSET_TABLE_.  Together with -fPIE the data
	     remain PC-relative even with _GLOBAL_OFFSET_TABLE_ as zero.  */
	  sym->value = 0;
	  continue;
	}
      bmsym = lookup_minimal_symbol (sym->name, NULL, NULL);
      switch (bmsym.minsym == NULL
	      ? mst_unknown : MSYMBOL_TYPE (bmsym.minsym))
	{
	case mst_text:
	  sym->value = BMSYMBOL_VALUE_ADDRESS (bmsym);
	  if (compile_debug)
	    fprintf_unfiltered (gdb_stdlog,
				"ELF mst_text symbol \"%s\" relocated to %s\n",
				sym->name,
				paddress (target_gdbarch (), sym->value));
	  break;
	case mst_text_gnu_ifunc:
	  sym->value = gnu_ifunc_resolve_addr (target_gdbarch (),
					       BMSYMBOL_VALUE_ADDRESS (bmsym));
	  if (compile_debug)
	    fprintf_unfiltered (gdb_stdlog,
				"ELF mst_text_gnu_ifunc symbol \"%s\" "
				"relocated to %s\n",
				sym->name,
				paddress (target_gdbarch (), sym->value));
	  break;
	default:
	  warning (_("Could not find symbol \"%s\" "
		     "for compiled module \"%s\"."),
		   sym->name, filename);
	  missing_symbols++;
	}
    }
  if (missing_symbols)
    error (_("%ld symbols were missing, cannot continue."), missing_symbols);

  bfd_map_over_sections (abfd, copy_sections, symbol_table);

  regs_type = get_regs_type (func_sym, objfile);
  if (regs_type == NULL)
    regs_addr = 0;
  else
    {
      /* Use read-only non-executable memory protection.  */
      regs_addr = gdbarch_infcall_mmap (target_gdbarch (),
					TYPE_LENGTH (regs_type),
					GDB_MMAP_PROT_READ);
      gdb_assert (regs_addr != 0);
      munmap_list_add (&munmap_list_head, regs_addr, TYPE_LENGTH (regs_type));
      if (compile_debug)
	fprintf_unfiltered (gdb_stdlog,
			    "allocated %s bytes at %s for registers\n",
			    paddress (target_gdbarch (),
				      TYPE_LENGTH (regs_type)),
			    paddress (target_gdbarch (), regs_addr));
      store_regs (regs_type, regs_addr);
    }

  if (scope == COMPILE_I_PRINT_ADDRESS_SCOPE
      || scope == COMPILE_I_PRINT_VALUE_SCOPE)
    {
      out_value_type = get_out_value_type (func_sym, objfile, scope);
      if (out_value_type == NULL)
	{
	  do_cleanups (cleanups);
	  return NULL;
	}
      check_typedef (out_value_type);
      out_value_addr = gdbarch_infcall_mmap (target_gdbarch (),
					     TYPE_LENGTH (out_value_type),
					     (GDB_MMAP_PROT_READ
					      | GDB_MMAP_PROT_WRITE));
      gdb_assert (out_value_addr != 0);
      munmap_list_add (&munmap_list_head, out_value_addr,
		       TYPE_LENGTH (out_value_type));
      if (compile_debug)
	fprintf_unfiltered (gdb_stdlog,
			    "allocated %s bytes at %s for printed value\n",
			    paddress (target_gdbarch (),
				      TYPE_LENGTH (out_value_type)),
			    paddress (target_gdbarch (), out_value_addr));
    }

  discard_cleanups (cleanups_free_objfile);

  retval = xmalloc (sizeof (*retval));
  retval->objfile = objfile;
  retval->source_file = xstrdup (source_file);
  retval->func_sym = func_sym;
  retval->regs_addr = regs_addr;
  retval->scope = scope;
  retval->scope_data = scope_data;
  retval->out_value_type = out_value_type;
  retval->out_value_addr = out_value_addr;

  /* CLEANUPS will free MUNMAP_LIST_HEAD.  */
  retval->munmap_list_head = munmap_list_head;
  munmap_list_head = NULL;

  do_cleanups (cleanups);

  return retval;
}
Beispiel #11
0
void vmx_handle_task_switch(CPUState *cpu, x68_segment_selector tss_sel, int reason, bool gate_valid, uint8_t gate, uint64_t gate_type)
{
    uint64_t rip = rreg(cpu->hvf_fd, HV_X86_RIP);
    if (!gate_valid || (gate_type != VMCS_INTR_T_HWEXCEPTION &&
                        gate_type != VMCS_INTR_T_HWINTR &&
                        gate_type != VMCS_INTR_T_NMI)) {
        int ins_len = rvmcs(cpu->hvf_fd, VMCS_EXIT_INSTRUCTION_LENGTH);
        macvm_set_rip(cpu, rip + ins_len);
        return;
    }

    load_regs(cpu);

    struct x86_segment_descriptor curr_tss_desc, next_tss_desc;
    int ret;
    x68_segment_selector old_tss_sel = vmx_read_segment_selector(cpu, R_TR);
    uint64_t old_tss_base = vmx_read_segment_base(cpu, R_TR);
    uint32_t desc_limit;
    struct x86_call_gate task_gate_desc;
    struct vmx_segment vmx_seg;

    X86CPU *x86_cpu = X86_CPU(cpu);
    CPUX86State *env = &x86_cpu->env;

    x86_read_segment_descriptor(cpu, &next_tss_desc, tss_sel);
    x86_read_segment_descriptor(cpu, &curr_tss_desc, old_tss_sel);

    if (reason == TSR_IDT_GATE && gate_valid) {
        int dpl;

        ret = x86_read_call_gate(cpu, &task_gate_desc, gate);

        dpl = task_gate_desc.dpl;
        x68_segment_selector cs = vmx_read_segment_selector(cpu, R_CS);
        if (tss_sel.rpl > dpl || cs.rpl > dpl)
            ;//DPRINTF("emulate_gp");
    }

    desc_limit = x86_segment_limit(&next_tss_desc);
    if (!next_tss_desc.p || ((desc_limit < 0x67 && (next_tss_desc.type & 8)) || desc_limit < 0x2b)) {
        VM_PANIC("emulate_ts");
    }

    if (reason == TSR_IRET || reason == TSR_JMP) {
        curr_tss_desc.type &= ~(1 << 1); /* clear busy flag */
        x86_write_segment_descriptor(cpu, &curr_tss_desc, old_tss_sel);
    }

    if (reason == TSR_IRET)
        EFLAGS(env) &= ~RFLAGS_NT;

    if (reason != TSR_CALL && reason != TSR_IDT_GATE)
        old_tss_sel.sel = 0xffff;

    if (reason != TSR_IRET) {
        next_tss_desc.type |= (1 << 1); /* set busy flag */
        x86_write_segment_descriptor(cpu, &next_tss_desc, tss_sel);
    }

    if (next_tss_desc.type & 8)
        ret = task_switch_32(cpu, tss_sel, old_tss_sel, old_tss_base, &next_tss_desc);
    else
        //ret = task_switch_16(cpu, tss_sel, old_tss_sel, old_tss_base, &next_tss_desc);
        VM_PANIC("task_switch_16");

    macvm_set_cr0(cpu->hvf_fd, rvmcs(cpu->hvf_fd, VMCS_GUEST_CR0) | CR0_TS);
    x86_segment_descriptor_to_vmx(cpu, tss_sel, &next_tss_desc, &vmx_seg);
    vmx_write_segment_descriptor(cpu, &vmx_seg, R_TR);

    store_regs(cpu);

    hv_vcpu_invalidate_tlb(cpu->hvf_fd);
    hv_vcpu_flush(cpu->hvf_fd);
}
struct compile_module *
compile_object_load (const char *object_file, const char *source_file)
{
  struct cleanup *cleanups, *cleanups_free_objfile;
  bfd *abfd;
  struct setup_sections_data setup_sections_data;
  CORE_ADDR addr, func_addr, regs_addr;
  struct bound_minimal_symbol bmsym;
  long storage_needed;
  asymbol **symbol_table, **symp;
  long number_of_symbols, missing_symbols;
  struct type *dptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
  unsigned dptr_type_len = TYPE_LENGTH (dptr_type);
  struct compile_module *retval;
  struct type *regs_type;
  char *filename, **matching;
  struct objfile *objfile;

  filename = tilde_expand (object_file);
  cleanups = make_cleanup (xfree, filename);

  abfd = gdb_bfd_open (filename, gnutarget, -1);
  if (abfd == NULL)
    error (_("\"%s\": could not open as compiled module: %s"),
          filename, bfd_errmsg (bfd_get_error ()));
  make_cleanup_bfd_unref (abfd);

  if (!bfd_check_format_matches (abfd, bfd_object, &matching))
    error (_("\"%s\": not in loadable format: %s"),
          filename, gdb_bfd_errmsg (bfd_get_error (), matching));

  if ((bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC)) != 0)
    error (_("\"%s\": not in object format."), filename);

  setup_sections_data.last_size = 0;
  setup_sections_data.last_section_first = abfd->sections;
  setup_sections_data.last_prot = -1;
  setup_sections_data.last_max_alignment = 1;
  bfd_map_over_sections (abfd, setup_sections, &setup_sections_data);
  setup_sections (abfd, NULL, &setup_sections_data);

  storage_needed = bfd_get_symtab_upper_bound (abfd);
  if (storage_needed < 0)
    error (_("Cannot read symbols of compiled module \"%s\": %s"),
          filename, bfd_errmsg (bfd_get_error ()));

  /* SYMFILE_VERBOSE is not passed even if FROM_TTY, user is not interested in
     "Reading symbols from ..." message for automatically generated file.  */
  objfile = symbol_file_add_from_bfd (abfd, filename, 0, NULL, 0, NULL);
  cleanups_free_objfile = make_cleanup_free_objfile (objfile);

  bmsym = lookup_minimal_symbol_text (GCC_FE_WRAPPER_FUNCTION, objfile);
  if (bmsym.minsym == NULL || MSYMBOL_TYPE (bmsym.minsym) == mst_file_text)
    error (_("Could not find symbol \"%s\" of compiled module \"%s\"."),
	   GCC_FE_WRAPPER_FUNCTION, filename);
  func_addr = BMSYMBOL_VALUE_ADDRESS (bmsym);

  /* The memory may be later needed
     by bfd_generic_get_relocated_section_contents
     called from default_symfile_relocate.  */
  symbol_table = obstack_alloc (&objfile->objfile_obstack, storage_needed);
  number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
  if (number_of_symbols < 0)
    error (_("Cannot parse symbols of compiled module \"%s\": %s"),
          filename, bfd_errmsg (bfd_get_error ()));

  missing_symbols = 0;
  for (symp = symbol_table; symp < symbol_table + number_of_symbols; symp++)
    {
      asymbol *sym = *symp;

      if (sym->flags != 0)
	continue;
      if (compile_debug)
	fprintf_unfiltered (gdb_stdout,
			    "lookup undefined ELF symbol \"%s\"\n",
			    sym->name);
      sym->flags = BSF_GLOBAL;
      sym->section = bfd_abs_section_ptr;
      if (strcmp (sym->name, "_GLOBAL_OFFSET_TABLE_") == 0)
	{
	  sym->value = 0;
	  continue;
	}
      bmsym = lookup_minimal_symbol (sym->name, NULL, NULL);
      switch (bmsym.minsym == NULL
	      ? mst_unknown : MSYMBOL_TYPE (bmsym.minsym))
	{
	case mst_text:
	  sym->value = BMSYMBOL_VALUE_ADDRESS (bmsym);
	  break;
	default:
	  warning (_("Could not find symbol \"%s\" "
		     "for compiled module \"%s\"."),
		   sym->name, filename);
	  missing_symbols++;
	}
    }
  if (missing_symbols)
    error (_("%ld symbols were missing, cannot continue."), missing_symbols);

  bfd_map_over_sections (abfd, copy_sections, symbol_table);

  regs_type = get_regs_type (objfile);
  if (regs_type == NULL)
    regs_addr = 0;
  else
    {
      /* Use read-only non-executable memory protection.  */
      regs_addr = gdbarch_infcall_mmap (target_gdbarch (),
					TYPE_LENGTH (regs_type),
					GDB_MMAP_PROT_READ);
      gdb_assert (regs_addr != 0);
      store_regs (regs_type, regs_addr);
    }

  discard_cleanups (cleanups_free_objfile);
  do_cleanups (cleanups);

  retval = xmalloc (sizeof (*retval));
  retval->objfile = objfile;
  retval->source_file = xstrdup (source_file);
  retval->func_addr = func_addr;
  retval->regs_addr = regs_addr;
  return retval;
}