Exemplo n.º 1
0
/* Print a natural-language description of SYMBOL to STREAM.  */
static int
locexpr_describe_location (struct symbol *symbol, struct ui_file *stream)
{
  /* FIXME: be more extensive.  */
  struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
  int addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu);

  if (dlbaton->size == 1
      && dlbaton->data[0] >= DW_OP_reg0
      && dlbaton->data[0] <= DW_OP_reg31)
    {
      struct objfile *objfile = dwarf2_per_cu_objfile (dlbaton->per_cu);
      struct gdbarch *gdbarch = get_objfile_arch (objfile);
      int regno = gdbarch_dwarf2_reg_to_regnum (gdbarch,
						dlbaton->data[0] - DW_OP_reg0);
      fprintf_filtered (stream,
			"a variable in register %s",
			gdbarch_register_name (gdbarch, regno));
      return 1;
    }

  /* The location expression for a TLS variable looks like this (on a
     64-bit LE machine):

     DW_AT_location    : 10 byte block: 3 4 0 0 0 0 0 0 0 e0
                        (DW_OP_addr: 4; DW_OP_GNU_push_tls_address)
     
     0x3 is the encoding for DW_OP_addr, which has an operand as long
     as the size of an address on the target machine (here is 8
     bytes).  0xe0 is the encoding for DW_OP_GNU_push_tls_address.
     The operand represents the offset at which the variable is within
     the thread local storage.  */

  if (dlbaton->size > 1 
      && dlbaton->data[dlbaton->size - 1] == DW_OP_GNU_push_tls_address)
    if (dlbaton->data[0] == DW_OP_addr)
      {
	struct objfile *objfile = dwarf2_per_cu_objfile (dlbaton->per_cu);
	struct gdbarch *gdbarch = get_objfile_arch (objfile);
	CORE_ADDR offset = dwarf2_read_address (gdbarch,
						&dlbaton->data[1],
						&dlbaton->data[dlbaton->size - 1],
						addr_size);
	fprintf_filtered (stream, 
			  "a thread-local variable at offset %s in the "
			  "thread-local storage for `%s'",
			  paddr_nz (offset), objfile->name);
	return 1;
      }
  

  fprintf_filtered (stream,
		    "a variable with complex or multiple locations (DWARF2)");
  return 1;
}
Exemplo n.º 2
0
static struct gdbarch *
get_class_arch (struct type *domain)
{
  gdb_assert (TYPE_CODE (domain) == TYPE_CODE_CLASS);
  gdb_assert (TYPE_OBJFILE (domain) != NULL);
  return get_objfile_arch (TYPE_OBJFILE (domain));
}
Exemplo n.º 3
0
static gdb_byte *
find_location_expression (struct dwarf2_loclist_baton *baton,
			  size_t *locexpr_length, CORE_ADDR pc)
{
  CORE_ADDR low, high;
  gdb_byte *loc_ptr, *buf_end;
  int length;
  struct objfile *objfile = dwarf2_per_cu_objfile (baton->per_cu);
  struct gdbarch *gdbarch = get_objfile_arch (objfile);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  unsigned int addr_size = dwarf2_per_cu_addr_size (baton->per_cu);
  CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
  /* Adjust base_address for relocatable objects.  */
  CORE_ADDR base_offset = ANOFFSET (objfile->section_offsets,
				    SECT_OFF_TEXT (objfile));
  CORE_ADDR base_address = baton->base_address + base_offset;

  loc_ptr = baton->data;
  buf_end = baton->data + baton->size;

  while (1)
    {
      if (buf_end - loc_ptr < 2 * addr_size)
	error (_("find_location_expression: Corrupted DWARF expression."));

      low = extract_unsigned_integer (loc_ptr, addr_size, byte_order);
      loc_ptr += addr_size;

      /* A base-address-selection entry.  */
      if (low == base_mask)
	{
	  base_address = dwarf2_read_address (gdbarch,
					      loc_ptr, buf_end, addr_size);
	  loc_ptr += addr_size;
	  continue;
	}

      high = extract_unsigned_integer (loc_ptr, addr_size, byte_order);
      loc_ptr += addr_size;

      /* An end-of-list entry.  */
      if (low == 0 && high == 0)
	return NULL;

      /* Otherwise, a location expression entry.  */
      low += base_address;
      high += base_address;

      length = extract_unsigned_integer (loc_ptr, 2, byte_order);
      loc_ptr += 2;

      if (pc >= low && pc < high)
	{
	  *locexpr_length = length;
	  return loc_ptr;
	}

      loc_ptr += length;
    }
}
Exemplo n.º 4
0
/* Function to ensure that the source and/or disassemly windows
   reflect the input address.  */
void
tui_update_source_windows_with_line (struct symtab *s, int line)
{
  struct gdbarch *gdbarch;
  CORE_ADDR pc;
  struct tui_line_or_address l;

  if (!s)
    return;

  gdbarch = get_objfile_arch (SYMTAB_OBJFILE (s));

  switch (tui_current_layout ())
    {
    case DISASSEM_COMMAND:
    case DISASSEM_DATA_COMMAND:
      find_line_pc (s, line, &pc);
      tui_update_source_windows_with_addr (gdbarch, pc);
      break;
    default:
      l.loa = LOA_LINE;
      l.u.line_no = line;
      tui_show_symtab_source (gdbarch, s, l, FALSE);
      if (tui_current_layout () == SRC_DISASSEM_COMMAND)
	{
	  find_line_pc (s, line, &pc);
	  tui_show_disassem (gdbarch, pc);
	}
      break;
    }

  return;
}
Exemplo n.º 5
0
bool
msymbol_is_function (struct objfile *objfile, minimal_symbol *minsym,
		     CORE_ADDR *func_address_p)
{
  CORE_ADDR msym_addr = MSYMBOL_VALUE_ADDRESS (objfile, minsym);

  switch (minsym->type)
    {
    case mst_slot_got_plt:
    case mst_data:
    case mst_bss:
    case mst_abs:
    case mst_file_data:
    case mst_file_bss:
    case mst_data_gnu_ifunc:
      {
	struct gdbarch *gdbarch = get_objfile_arch (objfile);
	CORE_ADDR pc
	  = gdbarch_convert_from_func_ptr_addr (gdbarch, msym_addr,
						current_top_target ());
	if (pc != msym_addr)
	  {
	    if (func_address_p != NULL)
	      *func_address_p = pc;
	    return true;
	  }
	return false;
      }
    default:
      if (func_address_p != NULL)
	*func_address_p = msym_addr;
      return true;
    }
}
Exemplo n.º 6
0
static void
python_new_objfile (struct objfile *objfile)
{
  struct cleanup *cleanup;

  if (!gdb_python_initialized)
    return;

  cleanup = ensure_python_env (objfile != NULL
			       ? get_objfile_arch (objfile)
			       : target_gdbarch (),
			       current_language);

  if (objfile == NULL)
    {
      if (emit_clear_objfiles_event () < 0)
	gdbpy_print_stack ();
    }
  else
    {
      if (emit_new_objfile_event (objfile) < 0)
	gdbpy_print_stack ();
    }

  do_cleanups (cleanup);
}
Exemplo n.º 7
0
/* Enable shared library breakpoint for the
   OpenCL runtime running on the SPU.  */
static void
ocl_enable_break (struct objfile *objfile)
{
  struct bound_minimal_symbol event_sym;
  struct bound_minimal_symbol addr_sym;

  /* The OpenCL runtime on the SPU will call __opencl_program_update_event
     whenever an OpenCL program is loaded.  */
  event_sym = lookup_minimal_symbol ("__opencl_program_update_event", NULL,
				     objfile);
  /* The PPU address of the OpenCL program can be found
     at opencl_elf_image_address.  */
  addr_sym = lookup_minimal_symbol ("opencl_elf_image_address", NULL, objfile);

  if (event_sym.minsym && addr_sym.minsym)
    {
      /* Place a solib_event breakpoint on the symbol.  */
      CORE_ADDR event_addr = BMSYMBOL_VALUE_ADDRESS (event_sym);
      create_solib_event_breakpoint (get_objfile_arch (objfile), event_addr);

      /* Store the address of the symbol that will point to OpenCL program
         using the per-objfile private data mechanism.  */
      if (objfile_data (objfile, ocl_program_data_key) == NULL)
        {
          CORE_ADDR *ocl_program_addr_base = OBSTACK_CALLOC (
		  &objfile->objfile_obstack,
		  objfile->sections_end - objfile->sections,
		  CORE_ADDR);
	  *ocl_program_addr_base = BMSYMBOL_VALUE_ADDRESS (addr_sym);
	  set_objfile_data (objfile, ocl_program_data_key,
			    ocl_program_addr_base);
        }
    }
}
Exemplo n.º 8
0
static void
add_class_symtab_symbol (struct symbol *sym)
{
  struct symtab *symtab
    = get_java_class_symtab (get_objfile_arch (SYMBOL_SYMTAB (sym)->objfile));
  struct blockvector *bv = BLOCKVECTOR (symtab);

  dict_add_symbol (BLOCK_DICT (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)), sym);
}
Exemplo n.º 9
0
/* Clear the OBJFILE pointer in an Objfile object and remove the
   reference.  */
static void
py_free_objfile (struct objfile *objfile, void *datum)
{
    struct cleanup *cleanup;
    objfile_object *object = datum;

    cleanup = ensure_python_env (get_objfile_arch (objfile), current_language);
    object->objfile = NULL;
    Py_DECREF ((PyObject *) object);
    do_cleanups (cleanup);
}
Exemplo n.º 10
0
static void
python_new_objfile (struct objfile *objfile)
{
  struct cleanup *cleanup;

  if (objfile == NULL)
    return;

  if (!gdb_python_initialized)
    return;

  cleanup = ensure_python_env (get_objfile_arch (objfile), current_language);

  if (emit_new_objfile_event (objfile) < 0)
    gdbpy_print_stack ();

  do_cleanups (cleanup);
}
Exemplo n.º 11
0
static bfd_vma
call_target_sbrk (int sbrk_arg)
{
  struct objfile *sbrk_objf;
  struct gdbarch *gdbarch;
  bfd_vma top_of_heap;
  struct value *target_sbrk_arg;
  struct value *sbrk_fn, *ret;
  bfd_vma tmp;

  if (lookup_minimal_symbol ("sbrk", NULL, NULL) != NULL)
    {
      sbrk_fn = find_function_in_inferior ("sbrk", &sbrk_objf);
      if (sbrk_fn == NULL)
	return (bfd_vma) 0;
    }
  else if (lookup_minimal_symbol ("_sbrk", NULL, NULL) != NULL)
    {
      sbrk_fn = find_function_in_inferior ("_sbrk", &sbrk_objf);
      if (sbrk_fn == NULL)
	return (bfd_vma) 0;
    }
  else
    return (bfd_vma) 0;

  gdbarch = get_objfile_arch (sbrk_objf);
  target_sbrk_arg = value_from_longest (builtin_type (gdbarch)->builtin_int, 
					sbrk_arg);
  gdb_assert (target_sbrk_arg);
  ret = call_function_by_hand (sbrk_fn, 1, &target_sbrk_arg);
  if (ret == NULL)
    return (bfd_vma) 0;

  tmp = value_as_long (ret);
  if ((LONGEST) tmp <= 0 || (LONGEST) tmp == 0xffffffff)
    return (bfd_vma) 0;

  top_of_heap = tmp;
  return top_of_heap;
}
Exemplo n.º 12
0
static int
dwarf2_loc_desc_needs_frame (gdb_byte *data, unsigned short size,
			     struct dwarf2_per_cu_data *per_cu)
{
  struct needs_frame_baton baton;
  struct dwarf_expr_context *ctx;
  int in_reg;

  baton.needs_frame = 0;

  ctx = new_dwarf_expr_context ();
  ctx->gdbarch = get_objfile_arch (dwarf2_per_cu_objfile (per_cu));
  ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
  ctx->baton = &baton;
  ctx->read_reg = needs_frame_read_reg;
  ctx->read_mem = needs_frame_read_mem;
  ctx->get_frame_base = needs_frame_frame_base;
  ctx->get_tls_address = needs_frame_tls_address;

  dwarf_expr_eval (ctx, data, size);

  in_reg = ctx->in_reg;

  if (ctx->num_pieces > 0)
    {
      int i;

      /* If the location has several pieces, and any of them are in
         registers, then we will need a frame to fetch them from.  */
      for (i = 0; i < ctx->num_pieces; i++)
        if (ctx->pieces[i].in_reg)
          in_reg = 1;
    }

  free_dwarf_expr_context (ctx);

  return baton.needs_frame || in_reg;
}
Exemplo n.º 13
0
void
mi_cmd_symbol_list_lines (char *command, char **argv, int argc)
{
  struct gdbarch *gdbarch;
  char *filename;
  struct symtab *s;
  int i;
  struct cleanup *cleanup_stack, *cleanup_tuple;
  struct ui_out *uiout = current_uiout;

  if (argc != 1)
    error (_("-symbol-list-lines: Usage: SOURCE_FILENAME"));

  filename = argv[0];
  s = lookup_symtab (filename);

  if (s == NULL)
    error (_("-symbol-list-lines: Unknown source file name."));

  /* Now, dump the associated line table.  The pc addresses are
     already sorted by increasing values in the symbol table, so no
     need to perform any other sorting.  */

  gdbarch = get_objfile_arch (s->objfile);
  cleanup_stack = make_cleanup_ui_out_list_begin_end (uiout, "lines");

  if (LINETABLE (s) != NULL && LINETABLE (s)->nitems > 0)
    for (i = 0; i < LINETABLE (s)->nitems; i++)
    {
      cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
      ui_out_field_core_addr (uiout, "pc", gdbarch, LINETABLE (s)->item[i].pc);
      ui_out_field_int (uiout, "line", LINETABLE (s)->item[i].line);
      do_cleanups (cleanup_tuple);
    }

  do_cleanups (cleanup_stack);
}
Exemplo n.º 14
0
static void
macho_add_oso_symfile (oso_el *oso, const gdb_bfd_ref_ptr &abfd,
		       const char *name,
                       struct objfile *main_objfile,
		       symfile_add_flags symfile_flags)
{
  int storage;
  int i;
  asymbol **symbol_table;
  asymbol **symp;
  struct bfd_hash_table table;
  int nbr_sections;

  /* Per section flag to mark which section have been rebased.  */
  unsigned char *sections_rebased;

  if (mach_o_debug_level > 0)
    printf_unfiltered
      (_("Loading debugging symbols from oso: %s\n"), oso->name);

  if (!bfd_check_format (abfd.get (), bfd_object))
    {
      warning (_("`%s': can't read symbols: %s."), oso->name,
               bfd_errmsg (bfd_get_error ()));
      return;
    }

  if (abfd->my_archive == NULL && oso->mtime != bfd_get_mtime (abfd.get ()))
    {
      warning (_("`%s': file time stamp mismatch."), oso->name);
      return;
    }

  if (!bfd_hash_table_init_n (&table, macho_sym_hash_newfunc,
                              sizeof (struct macho_sym_hash_entry),
                              oso->nbr_syms))
    {
      warning (_("`%s': can't create hash table"), oso->name);
      return;
    }

  bfd_set_cacheable (abfd.get (), 1);

  /* Read symbols table.  */
  storage = bfd_get_symtab_upper_bound (abfd.get ());
  symbol_table = (asymbol **) xmalloc (storage);
  bfd_canonicalize_symtab (abfd.get (), symbol_table);

  /* Init section flags.  */
  nbr_sections = bfd_count_sections (abfd.get ());
  sections_rebased = (unsigned char *) alloca (nbr_sections);
  for (i = 0; i < nbr_sections; i++)
    sections_rebased[i] = 0;

  /* Put symbols for the OSO file in the hash table.  */
  for (symp = oso->oso_sym; symp != oso->end_sym; symp++)
    {
      const asymbol *sym = *symp;
      bfd_mach_o_asymbol *mach_o_sym = (bfd_mach_o_asymbol *)sym;

      switch (mach_o_sym->n_type)
        {
        case N_ENSYM:
        case N_BNSYM:
        case N_GSYM:
          sym = NULL;
          break;
        case N_FUN:
          if (sym->name == NULL || sym->name[0] == 0)
            sym = NULL;
          break;
        case N_STSYM:
          break;
        default:
          sym = NULL;
          break;
        }
      if (sym != NULL)
        {
          struct macho_sym_hash_entry *ent;

          ent = (struct macho_sym_hash_entry *)
            bfd_hash_lookup (&table, sym->name, TRUE, FALSE);
          if (ent->sym != NULL)
            complaint (_("Duplicated symbol %s in symbol table"), sym->name);
          else
            {
              if (mach_o_debug_level > 4)
                {
                  struct gdbarch *arch = get_objfile_arch (main_objfile);
                  printf_unfiltered
                    (_("Adding symbol %s (addr: %s)\n"),
                     sym->name, paddress (arch, sym->value));
                }
              ent->sym = sym;
            }
        }
    }

  /* Relocate symbols of the OSO.  */
  for (i = 0; symbol_table[i]; i++)
    {
      asymbol *sym = symbol_table[i];
      bfd_mach_o_asymbol *mach_o_sym = (bfd_mach_o_asymbol *)sym;

      if (mach_o_sym->n_type & BFD_MACH_O_N_STAB)
        continue;
      if ((mach_o_sym->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_UNDF
           && sym->value != 0)
        {
          /* For common symbol use the min symtab and modify the OSO
             symbol table.  */
          CORE_ADDR res;

          res = macho_resolve_oso_sym_with_minsym (main_objfile, sym);
          if (res != 0)
            {
              sym->section = bfd_com_section_ptr;
              sym->value = res;
            }
        }
      else if ((mach_o_sym->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_SECT)
        {
          /* Normal symbol.  */
          asection *sec = sym->section;
          bfd_mach_o_section *msec;
          unsigned int sec_type;

          /* Skip buggy ones.  */
          if (sec == NULL || sections_rebased[sec->index] != 0)
            continue;

          /* Only consider regular, non-debugging sections.  */
          msec = bfd_mach_o_get_mach_o_section (sec);
          sec_type = msec->flags & BFD_MACH_O_SECTION_TYPE_MASK;
          if ((sec_type == BFD_MACH_O_S_REGULAR
               || sec_type == BFD_MACH_O_S_ZEROFILL)
              && (msec->flags & BFD_MACH_O_S_ATTR_DEBUG) == 0)
            {
              CORE_ADDR addr = 0;

              if ((mach_o_sym->n_type & BFD_MACH_O_N_EXT) != 0)
                {
                  /* Use the min symtab for global symbols.  */
                  addr = macho_resolve_oso_sym_with_minsym (main_objfile, sym);
                }
              else
                {
                  struct macho_sym_hash_entry *ent;

                  ent = (struct macho_sym_hash_entry *)
                    bfd_hash_lookup (&table, sym->name, FALSE, FALSE);
                  if (ent != NULL)
                    addr = bfd_asymbol_value (ent->sym);
                }

              /* Adjust the section.  */
              if (addr != 0)
                {
                  CORE_ADDR res = addr - sym->value;

                  if (mach_o_debug_level > 3)
                    {
                      struct gdbarch *arch = get_objfile_arch (main_objfile);
                      printf_unfiltered
                        (_("resolve sect %s with %s (set to %s)\n"),
                         sec->name, sym->name,
                         paddress (arch, res));
                    }
                  bfd_set_section_vma (abfd.get (), sec, res);
                  sections_rebased[sec->index] = 1;
                }
            }
          else
            {
              /* Mark the section as never rebased.  */
              sections_rebased[sec->index] = 2;
            }
        }
    }

  bfd_hash_table_free (&table);

  /* We need to clear SYMFILE_MAINLINE to avoid interractive question
     from symfile.c:symbol_file_add_with_addrs_or_offsets.  */
  symbol_file_add_from_bfd
    (abfd.get (), name, symfile_flags & ~(SYMFILE_MAINLINE | SYMFILE_VERBOSE),
     NULL,
     main_objfile->flags & (OBJF_REORDERED | OBJF_SHARED
			    | OBJF_READNOW | OBJF_USERLOADED),
     main_objfile);
}
Exemplo n.º 15
0
static int
derive_heap_segment (bfd *abfd, bfd_vma *bottom, bfd_vma *top)
{
  struct objfile *sbrk_objf;
  struct gdbarch *gdbarch;
  bfd_vma top_of_data_memory = 0;
  bfd_vma top_of_heap = 0;
  bfd_size_type sec_size;
  struct value *zero, *sbrk;
  bfd_vma sec_vaddr;
  asection *sec;

  gdb_assert (bottom);
  gdb_assert (top);

  /* This function depends on being able to call a function in the
     inferior.  */
  if (!target_has_execution)
    return 0;

  /* The following code assumes that the link map is arranged as
     follows (low to high addresses):

     ---------------------------------
     | text sections                 |
     ---------------------------------
     | data sections (including bss) |
     ---------------------------------
     | heap                          |
     --------------------------------- */

  for (sec = abfd->sections; sec; sec = sec->next)
    {
      if (bfd_get_section_flags (abfd, sec) & SEC_DATA
	  || strcmp (".bss", bfd_section_name (abfd, sec)) == 0)
	{
	  sec_vaddr = bfd_get_section_vma (abfd, sec);
	  sec_size = bfd_get_section_size (sec);
	  if (sec_vaddr + sec_size > top_of_data_memory)
	    top_of_data_memory = sec_vaddr + sec_size;
	}
    }

  /* Now get the top-of-heap by calling sbrk in the inferior.  */
  if (lookup_minimal_symbol ("sbrk", NULL, NULL) != NULL)
    {
      sbrk = find_function_in_inferior ("sbrk", &sbrk_objf);
      if (sbrk == NULL)
	return 0;
    }
  else if (lookup_minimal_symbol ("_sbrk", NULL, NULL) != NULL)
    {
      sbrk = find_function_in_inferior ("_sbrk", &sbrk_objf);
      if (sbrk == NULL)
	return 0;
    }
  else
    return 0;

  gdbarch = get_objfile_arch (sbrk_objf);
  zero = value_from_longest (builtin_type (gdbarch)->builtin_int, 0);
  gdb_assert (zero);
  sbrk = call_function_by_hand (sbrk, 1, &zero);
  if (sbrk == NULL)
    return 0;
  top_of_heap = value_as_long (sbrk);

  /* Return results.  */
  if (top_of_heap > top_of_data_memory)
    {
      *bottom = top_of_data_memory;
      *top = top_of_heap;
      return 1;
    }

  /* No additional heap space needs to be saved.  */
  return 0;
}
Exemplo n.º 16
0
static void
som_symtab_read (bfd *abfd, struct objfile *objfile,
		 struct section_offsets *section_offsets)
{
  struct cleanup *cleanup;
  struct gdbarch *gdbarch = get_objfile_arch (objfile);
  unsigned int number_of_symbols;
  int val, dynamic;
  char *stringtab;
  asection *shlib_info;
  struct som_external_symbol_dictionary_record *buf, *bufp, *endbufp;
  char *symname;
  CONST int symsize = sizeof (struct som_external_symbol_dictionary_record);


#define text_offset ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile))
#define data_offset ANOFFSET (section_offsets, SECT_OFF_DATA (objfile))

  number_of_symbols = bfd_get_symcount (abfd);

  /* Allocate a buffer to read in the debug info.
     We avoid using alloca because the memory size could be so large
     that we could hit the stack size limit.  */
  buf = xmalloc (symsize * number_of_symbols);
  cleanup = make_cleanup (xfree, buf);
  bfd_seek (abfd, obj_som_sym_filepos (abfd), SEEK_SET);
  val = bfd_bread (buf, symsize * number_of_symbols, abfd);
  if (val != symsize * number_of_symbols)
    error (_("Couldn't read symbol dictionary!"));

  /* Allocate a buffer to read in the som stringtab section of
     the debugging info.  Again, we avoid using alloca because
     the data could be so large that we could potentially hit
     the stack size limitat.  */
  stringtab = xmalloc (obj_som_stringtab_size (abfd));
  make_cleanup (xfree, stringtab);
  bfd_seek (abfd, obj_som_str_filepos (abfd), SEEK_SET);
  val = bfd_bread (stringtab, obj_som_stringtab_size (abfd), abfd);
  if (val != obj_som_stringtab_size (abfd))
    error (_("Can't read in HP string table."));

  /* We need to determine if objfile is a dynamic executable (so we
     can do the right thing for ST_ENTRY vs ST_CODE symbols).

     There's nothing in the header which easily allows us to do
     this.

     This code used to rely upon the existence of a $SHLIB_INFO$
     section to make this determination.  HP claims that it is
     more accurate to check for a nonzero text offset, but they
     have not provided any information about why that test is
     more accurate.  */
  dynamic = (text_offset != 0);

  endbufp = buf + number_of_symbols;
  for (bufp = buf; bufp < endbufp; ++bufp)
    {
      enum minimal_symbol_type ms_type;
      unsigned int flags = bfd_getb32 (bufp->flags);
      unsigned int symbol_type
	= (flags >> SOM_SYMBOL_TYPE_SH) & SOM_SYMBOL_TYPE_MASK;
      unsigned int symbol_scope
	= (flags >> SOM_SYMBOL_SCOPE_SH) & SOM_SYMBOL_SCOPE_MASK;
      CORE_ADDR symbol_value = bfd_getb32 (bufp->symbol_value);
      asection *section = NULL;

      QUIT;

      /* Compute the section.  */
      switch (symbol_scope)
	{
	case SS_EXTERNAL:
	  if (symbol_type != ST_STORAGE)
	    section = bfd_und_section_ptr;
	  else
	    section = bfd_com_section_ptr;
	  break;

	case SS_UNSAT:
	  if (symbol_type != ST_STORAGE)
	    section = bfd_und_section_ptr;
	  else
	    section = bfd_com_section_ptr;
	  break;

	case SS_UNIVERSAL:
	  section = bfd_section_from_som_symbol (abfd, bufp);
	  break;

	case SS_LOCAL:
	  section = bfd_section_from_som_symbol (abfd, bufp);
	  break;
	}

      switch (symbol_scope)
	{
	case SS_UNIVERSAL:
	case SS_EXTERNAL:
	  switch (symbol_type)
	    {
	    case ST_SYM_EXT:
	    case ST_ARG_EXT:
	      continue;

	    case ST_CODE:
	    case ST_PRI_PROG:
	    case ST_SEC_PROG:
	    case ST_MILLICODE:
	      symname = bfd_getb32 (bufp->name) + stringtab;
	      ms_type = mst_text;
	      symbol_value += text_offset;
	      symbol_value = gdbarch_addr_bits_remove (gdbarch, symbol_value);
	      break;

	    case ST_ENTRY:
	      symname = bfd_getb32 (bufp->name) + stringtab;
	      /* For a dynamic executable, ST_ENTRY symbols are
	         the stubs, while the ST_CODE symbol is the real
	         function.  */
	      if (dynamic)
		ms_type = mst_solib_trampoline;
	      else
		ms_type = mst_text;
	      symbol_value += text_offset;
	      symbol_value = gdbarch_addr_bits_remove (gdbarch, symbol_value);
	      break;

	    case ST_STUB:
	      symname = bfd_getb32 (bufp->name) + stringtab;
	      ms_type = mst_solib_trampoline;
	      symbol_value += text_offset;
	      symbol_value = gdbarch_addr_bits_remove (gdbarch, symbol_value);
	      break;

	    case ST_DATA:
	      symname = bfd_getb32 (bufp->name) + stringtab;
	      symbol_value += data_offset;
	      ms_type = mst_data;
	      break;
	    default:
	      continue;
	    }
	  break;

#if 0
	  /* SS_GLOBAL and SS_LOCAL are two names for the same thing (!).  */
	case SS_GLOBAL:
#endif
	case SS_LOCAL:
	  switch (symbol_type)
	    {
	    case ST_SYM_EXT:
	    case ST_ARG_EXT:
	      continue;

	    case ST_CODE:
	      symname = bfd_getb32 (bufp->name) + stringtab;
	      ms_type = mst_file_text;
	      symbol_value += text_offset;
	      symbol_value = gdbarch_addr_bits_remove (gdbarch, symbol_value);

	    check_strange_names:
	      /* Utah GCC 2.5, FSF GCC 2.6 and later generate correct local
	         label prefixes for stabs, constant data, etc.  So we need
	         only filter out L$ symbols which are left in due to
	         limitations in how GAS generates SOM relocations.

	         When linking in the HPUX C-library the HP linker has
	         the nasty habit of placing section symbols from the literal
	         subspaces in the middle of the program's text.  Filter
	         those out as best we can.  Check for first and last character
	         being '$'.

	         And finally, the newer HP compilers emit crud like $PIC_foo$N
	         in some circumstance (PIC code I guess).  It's also claimed
	         that they emit D$ symbols too.  What stupidity.  */
	      if ((symname[0] == 'L' && symname[1] == '$')
	      || (symname[0] == '$' && symname[strlen (symname) - 1] == '$')
		  || (symname[0] == 'D' && symname[1] == '$')
		  || (strncmp (symname, "L0\001", 3) == 0)
		  || (strncmp (symname, "$PIC", 4) == 0))
		continue;
	      break;

	    case ST_PRI_PROG:
	    case ST_SEC_PROG:
	    case ST_MILLICODE:
	      symname = bfd_getb32 (bufp->name) + stringtab;
	      ms_type = mst_file_text;
	      symbol_value += text_offset;
	      symbol_value = gdbarch_addr_bits_remove (gdbarch, symbol_value);
	      break;

	    case ST_ENTRY:
	      symname = bfd_getb32 (bufp->name) + stringtab;
	      /* SS_LOCAL symbols in a shared library do not have
		 export stubs, so we do not have to worry about
		 using mst_file_text vs mst_solib_trampoline here like
		 we do for SS_UNIVERSAL and SS_EXTERNAL symbols above.  */
	      ms_type = mst_file_text;
	      symbol_value += text_offset;
	      symbol_value = gdbarch_addr_bits_remove (gdbarch, symbol_value);
	      break;

	    case ST_STUB:
	      symname = bfd_getb32 (bufp->name) + stringtab;
	      ms_type = mst_solib_trampoline;
	      symbol_value += text_offset;
	      symbol_value = gdbarch_addr_bits_remove (gdbarch, symbol_value);
	      break;


	    case ST_DATA:
	      symname = bfd_getb32 (bufp->name) + stringtab;
	      symbol_value += data_offset;
	      ms_type = mst_file_data;
	      goto check_strange_names;

	    default:
	      continue;
	    }
	  break;

	  /* This can happen for common symbols when -E is passed to the
	     final link.  No idea _why_ that would make the linker force
	     common symbols to have an SS_UNSAT scope, but it does.

	     This also happens for weak symbols, but their type is
	     ST_DATA.  */
	case SS_UNSAT:
	  switch (symbol_type)
	    {
	    case ST_STORAGE:
	    case ST_DATA:
	      symname = bfd_getb32 (bufp->name) + stringtab;
	      symbol_value += data_offset;
	      ms_type = mst_data;
	      break;

	    default:
	      continue;
	    }
	  break;

	default:
	  continue;
	}

      if (bfd_getb32 (bufp->name) > obj_som_stringtab_size (abfd))
	error (_("Invalid symbol data; bad HP string table offset: %s"),
	       plongest (bfd_getb32 (bufp->name)));

      if (bfd_is_const_section (section))
	{
	  struct obj_section *iter;

	  ALL_OBJFILE_OSECTIONS (objfile, iter)
	    {
	      if (bfd_is_const_section (iter->the_bfd_section))
		continue;

	      if (obj_section_addr (iter) <= symbol_value
		  && symbol_value < obj_section_endaddr (iter))
		{
		  section = iter->the_bfd_section;
		  break;
		}
	    }
	}

      prim_record_minimal_symbol_and_info (symname, symbol_value, ms_type,
					   gdb_bfd_section_index (objfile->obfd,
								  section),
					   objfile);
    }

  do_cleanups (cleanup);
}
Exemplo n.º 17
0
/* Function to display source in the source window.  */
enum tui_status
tui_set_source_content (struct symtab *s, 
			int line_no,
			int noerror)
{
  enum tui_status ret = TUI_FAILURE;

  if (s != (struct symtab *) NULL)
    {
      FILE *stream;
      int i, desc, c, line_width, nlines;
      char *src_line = 0;

      if ((ret = tui_alloc_source_buffer (TUI_SRC_WIN)) == TUI_SUCCESS)
	{
	  line_width = TUI_SRC_WIN->generic.width - 1;
	  /* Take hilite (window border) into account, when
	     calculating the number of lines.  */
	  nlines = (line_no + (TUI_SRC_WIN->generic.height - 2)) - line_no;
	  desc = open_source_file (s);
	  if (desc < 0)
	    {
	      if (!noerror)
		{
		  char *name = alloca (strlen (s->filename) + 100);

		  sprintf (name, "%s:%d", s->filename, line_no);
		  print_sys_errmsg (name, errno);
		}
	      ret = TUI_FAILURE;
	    }
	  else
	    {
	      if (s->line_charpos == 0)
		find_source_lines (s, desc);

	      if (line_no < 1 || line_no > s->nlines)
		{
		  close (desc);
		  printf_unfiltered (
			  "Line number %d out of range; %s has %d lines.\n",
				      line_no, s->filename, s->nlines);
		}
	      else if (lseek (desc, s->line_charpos[line_no - 1], 0) < 0)
		{
		  close (desc);
		  perror_with_name (s->filename);
		}
	      else
		{
		  int offset, cur_line_no, cur_line, cur_len, threshold;
		  struct tui_gen_win_info *locator
		    = tui_locator_win_info_ptr ();
                  struct tui_source_info *src
		    = &TUI_SRC_WIN->detail.source_info;

                  if (TUI_SRC_WIN->generic.title)
                    xfree (TUI_SRC_WIN->generic.title);
                  TUI_SRC_WIN->generic.title = xstrdup (s->filename);

                  if (src->filename)
                    xfree (src->filename);
                  src->filename = xstrdup (s->filename);

		  /* Determine the threshold for the length of the
                     line and the offset to start the display.  */
		  offset = src->horizontal_offset;
		  threshold = (line_width - 1) + offset;
		  stream = fdopen (desc, FOPEN_RT);
		  clearerr (stream);
		  cur_line = 0;
		  src->gdbarch = get_objfile_arch (s->objfile);
		  src->start_line_or_addr.loa = LOA_LINE;
		  cur_line_no = src->start_line_or_addr.u.line_no = line_no;
		  if (offset > 0)
		    src_line = (char *) xmalloc (
					   (threshold + 1) * sizeof (char));
		  while (cur_line < nlines)
		    {
		      struct tui_win_element *element
			= (struct tui_win_element *)
			TUI_SRC_WIN->generic.content[cur_line];

		      /* Get the first character in the line.  */
		      c = fgetc (stream);

		      if (offset == 0)
			src_line = ((struct tui_win_element *)
				   TUI_SRC_WIN->generic.content[
					cur_line])->which_element.source.line;
		      /* Init the line with the line number.  */
		      sprintf (src_line, "%-6d", cur_line_no);
		      cur_len = strlen (src_line);
		      i = cur_len - ((cur_len / tui_default_tab_len ())
				     * tui_default_tab_len ());
		      while (i < tui_default_tab_len ())
			{
			  src_line[cur_len] = ' ';
			  i++;
			  cur_len++;
			}
		      src_line[cur_len] = (char) 0;

		      /* Set whether element is the execution point
		         and whether there is a break point on it.  */
		      element->which_element.source.line_or_addr.loa =
			LOA_LINE;
		      element->which_element.source.line_or_addr.u.line_no =
			cur_line_no;
		      element->which_element.source.is_exec_point =
			(filename_cmp (((struct tui_win_element *)
				       locator->content[0])->which_element.locator.file_name,
				       s->filename) == 0
			 && cur_line_no == ((struct tui_win_element *)
					    locator->content[0])->which_element.locator.line_no);
		      if (c != EOF)
			{
			  i = strlen (src_line) - 1;
			  do
			    {
			      if ((c != '\n') && (c != '\r') 
				  && (++i < threshold))
				{
				  if (c < 040 && c != '\t')
				    {
				      src_line[i++] = '^';
				      src_line[i] = c + 0100;
				    }
				  else if (c == 0177)
				    {
				      src_line[i++] = '^';
				      src_line[i] = '?';
				    }
				  else
				    { /* Store the charcter in the
					 line buffer.  If it is a tab,
					 then translate to the correct
					 number of chars so we don't
					 overwrite our buffer.  */
				      if (c == '\t')
					{
					  int j, max_tab_len
					    = tui_default_tab_len ();

					  for (j = i - ((i / max_tab_len)
							* max_tab_len);
					       j < max_tab_len
						 && i < threshold;
					       i++, j++)
					    src_line[i] = ' ';
					  i--;
					}
				      else
					src_line[i] = c;
				    }
				  src_line[i + 1] = 0;
				}
			      else
				{ /* If we have not reached EOL, then
				     eat chars until we do.  */
				  while (c != EOF && c != '\n' && c != '\r')
				    c = fgetc (stream);
				  /* Handle non-'\n' end-of-line.  */
				  if (c == '\r' 
				      && (c = fgetc (stream)) != '\n' 
				      && c != EOF)
				    {
				       ungetc (c, stream);
				       c = '\r';
				    }
				  
				}
			    }
			  while (c != EOF && c != '\n' && c != '\r' 
				 && i < threshold 
				 && (c = fgetc (stream)));
			}
		      /* Now copy the line taking the offset into
			 account.  */
		      if (strlen (src_line) > offset)
			strcpy (((struct tui_win_element *)
				 TUI_SRC_WIN->generic.content[cur_line])->which_element.source.line,
				&src_line[offset]);
		      else
			((struct tui_win_element *)
			 TUI_SRC_WIN->generic.content[
			  cur_line])->which_element.source.line[0] = (char) 0;
		      cur_line++;
		      cur_line_no++;
		    }
		  if (offset > 0)
		    xfree (src_line);
		  fclose (stream);
		  TUI_SRC_WIN->generic.content_size = nlines;
		  ret = TUI_SUCCESS;
		}
	    }
	}
    }
  return ret;
}
Exemplo n.º 18
0
/* Evaluate a location description, starting at DATA and with length
   SIZE, to find the current location of variable VAR in the context
   of FRAME.  */
static struct value *
dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
			  gdb_byte *data, unsigned short size,
			  struct dwarf2_per_cu_data *per_cu)
{
  struct value *retval;
  struct dwarf_expr_baton baton;
  struct dwarf_expr_context *ctx;

  if (size == 0)
    {
      retval = allocate_value (SYMBOL_TYPE (var));
      VALUE_LVAL (retval) = not_lval;
      set_value_optimized_out (retval, 1);
      return retval;
    }

  baton.frame = frame;
  baton.objfile = dwarf2_per_cu_objfile (per_cu);

  ctx = new_dwarf_expr_context ();
  ctx->gdbarch = get_objfile_arch (baton.objfile);
  ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
  ctx->baton = &baton;
  ctx->read_reg = dwarf_expr_read_reg;
  ctx->read_mem = dwarf_expr_read_mem;
  ctx->get_frame_base = dwarf_expr_frame_base;
  ctx->get_tls_address = dwarf_expr_tls_address;

  dwarf_expr_eval (ctx, data, size);
  if (ctx->num_pieces > 0)
    {
      int i;
      long offset = 0;
      bfd_byte *contents;

      retval = allocate_value (SYMBOL_TYPE (var));
      contents = value_contents_raw (retval);
      for (i = 0; i < ctx->num_pieces; i++)
	{
	  struct dwarf_expr_piece *p = &ctx->pieces[i];
	  if (p->in_reg)
	    {
	      struct gdbarch *arch = get_frame_arch (frame);
	      bfd_byte regval[MAX_REGISTER_SIZE];
	      int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->value);
	      get_frame_register (frame, gdb_regnum, regval);
	      memcpy (contents + offset, regval, p->size);
	    }
	  else /* In memory?  */
	    {
	      read_memory (p->value, contents + offset, p->size);
	    }
	  offset += p->size;
	}
    }
  else if (ctx->in_reg)
    {
      struct gdbarch *arch = get_frame_arch (frame);
      CORE_ADDR dwarf_regnum = dwarf_expr_fetch (ctx, 0);
      int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, dwarf_regnum);
      retval = value_from_register (SYMBOL_TYPE (var), gdb_regnum, frame);
    }
  else
    {
      CORE_ADDR address = dwarf_expr_fetch (ctx, 0);

      retval = allocate_value (SYMBOL_TYPE (var));
      VALUE_LVAL (retval) = lval_memory;
      set_value_lazy (retval, 1);
      set_value_address (retval, address);
    }

  set_value_initialized (retval, ctx->initialized);

  free_dwarf_expr_context (ctx);

  return retval;
}