Ejemplo n.º 1
0
static bfd_boolean
mcore_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
{
  flagword old_flags;
  flagword new_flags;

  /* Check if we have the same endianess.  */
  if (! _bfd_generic_verify_endian_match (ibfd, obfd))
    return FALSE;

  if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
    return TRUE;

  new_flags = elf_elfheader (ibfd)->e_flags;
  old_flags = elf_elfheader (obfd)->e_flags;

  if (! elf_flags_init (obfd))
    {
      	/* First call, no flags set.  */
      elf_flags_init (obfd) = TRUE;
      elf_elfheader (obfd)->e_flags = new_flags;
    }
  else if (new_flags == old_flags)
    /* Compatible flags are OK.  */
    ;
  else
    {
      /* FIXME */
    }

  return TRUE;
}
Ejemplo n.º 2
0
Archivo: rddbg.c Proyecto: CromFr/gdb
void *
read_debugging_info (bfd *abfd, asymbol **syms, long symcount, bfd_boolean no_messages)
{
  void *dhandle;
  bfd_boolean found;

  dhandle = debug_init ();
  if (dhandle == NULL)
    return NULL;

  if (! read_section_stabs_debugging_info (abfd, syms, symcount, dhandle,
					   &found))
    return NULL;

  if (bfd_get_flavour (abfd) == bfd_target_aout_flavour)
    {
      if (! read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle,
					      &found))
	return NULL;
    }

  if (bfd_get_flavour (abfd) == bfd_target_ieee_flavour)
    {
      if (! read_ieee_debugging_info (abfd, dhandle, &found))
	return NULL;
    }

  /* Try reading the COFF symbols if we didn't find any stabs in COFF
     sections.  */
  if (! found
      && bfd_get_flavour (abfd) == bfd_target_coff_flavour
      && symcount > 0)
    {
      if (! parse_coff (abfd, syms, symcount, dhandle))
	return NULL;
      found = TRUE;
    }

  if (! found)
    {
      if (! no_messages)
	non_fatal (_("%s: no recognized debugging information"),
		   bfd_get_filename (abfd));
      return NULL;
    }

  return dhandle;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
void setup()
{
   bfdformat = bfd_object;
   if (bfd_check_format(abfd, bfdformat) == false)
   {
      (void)fprintf(stderr, "error: only object files are supported\n\n");
      exit(ERROR);
   }

   bfdflavour = bfd_get_flavour(abfd);
   if (bfdflavour == ERROR)
   {
      bfderror("[bfd_get_flavour] error");
      exit(ERROR);
   }

   /* ---------------------------------------------------- */

   if ((bfdflavour == bfd_target_unknown_flavour) ||
       ((bfdflavour != bfd_target_aout_flavour) &&
        (bfdflavour != bfd_target_coff_flavour) &&
        (bfdflavour != bfd_target_elf_flavour) &&
        (bfdflavour != bfd_target_msdos_flavour)))
   {
      (void)fprintf(stderr, "Only current supported formats (flavours): "
                            "ELF, COFF, AOUT, and MS-DOS\n");

      exit(ERROR);
   }
}
Ejemplo n.º 5
0
/* Read inferior memory at ADDR to find the header of a loaded object file
   and read its in-core symbols out of inferior memory.  TEMPL is a bfd
   representing the target's format.  NAME is the name to use for this
   symbol file in messages; it can be NULL or a malloc-allocated string
   which will be attached to the BFD.  */
static struct objfile *
symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr, char *name,
			     int from_tty)
{
  struct objfile *objf;
  struct bfd *nbfd;
  struct bfd_section *sec;
  bfd_vma loadbase;
  struct section_addr_info *sai;
  unsigned int i;
  struct cleanup *cleanup;

  if (bfd_get_flavour (templ) != bfd_target_elf_flavour)
    error (_("add-symbol-file-from-memory not supported for this target"));

  nbfd = bfd_elf_bfd_from_remote_memory (templ, addr, &loadbase,
					 target_read_memory_bfd);
  if (nbfd == NULL)
    error (_("Failed to read a valid object file image from memory."));

  gdb_bfd_ref (nbfd);
  if (name == NULL)
    nbfd->filename = "shared object read from target memory";
  else
    {
      nbfd->filename = name;
      gdb_bfd_stash_filename (nbfd);
      xfree (name);
    }

  cleanup = make_cleanup_bfd_unref (nbfd);

  if (!bfd_check_format (nbfd, bfd_object))
    error (_("Got object file from memory but can't read symbols: %s."),
	   bfd_errmsg (bfd_get_error ()));

  sai = alloc_section_addr_info (bfd_count_sections (nbfd));
  make_cleanup (xfree, sai);
  i = 0;
  for (sec = nbfd->sections; sec != NULL; sec = sec->next)
    if ((bfd_get_section_flags (nbfd, sec) & (SEC_ALLOC|SEC_LOAD)) != 0)
      {
	sai->other[i].addr = bfd_get_section_vma (nbfd, sec) + loadbase;
	sai->other[i].name = (char *) bfd_get_section_name (nbfd, sec);
	sai->other[i].sectindex = sec->index;
	++i;
      }
  sai->num_sections = i;

  objf = symbol_file_add_from_bfd (nbfd, bfd_get_filename (nbfd),
				   from_tty ? SYMFILE_VERBOSE : 0,
                                   sai, OBJF_SHARED, NULL);

  /* This might change our ideas about frames already looked at.  */
  reinit_frame_cache ();

  do_cleanups (cleanup);
  return objf;
}
Ejemplo n.º 6
0
static bfd_boolean
elf32_sparc_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
{
  bfd *obfd = info->output_bfd;
  bfd_boolean error;
  unsigned long ibfd_mach;
  /* FIXME: This should not be static.  */
  static unsigned long previous_ibfd_e_flags = (unsigned long) -1;

  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
    return TRUE;

  error = FALSE;

  ibfd_mach = bfd_get_mach (ibfd);
  if (bfd_mach_sparc_64bit_p (ibfd_mach))
    {
      error = TRUE;
      _bfd_error_handler
	(_("%B: compiled for a 64 bit system and target is 32 bit"), ibfd);
    }
  else if ((ibfd->flags & DYNAMIC) == 0)
    {
      if (bfd_get_mach (obfd) < ibfd_mach)
	bfd_set_arch_mach (obfd, bfd_arch_sparc, ibfd_mach);
    }

  if (((elf_elfheader (ibfd)->e_flags & EF_SPARC_LEDATA)
       != previous_ibfd_e_flags)
      && previous_ibfd_e_flags != (unsigned long) -1)
    {
      _bfd_error_handler
	(_("%B: linking little endian files with big endian files"), ibfd);
      error = TRUE;
    }
  previous_ibfd_e_flags = elf_elfheader (ibfd)->e_flags & EF_SPARC_LEDATA;

  if (error)
    {
      bfd_set_error (bfd_error_bad_value);
      return FALSE;
    }

  return _bfd_sparc_elf_merge_private_bfd_data (ibfd, info);
}
Ejemplo n.º 7
0
bfd_boolean
plugin_should_reload (bfd *abfd)
{
  return ((abfd->flags & DYNAMIC) != 0
	  && bfd_get_flavour (abfd) == bfd_target_elf_flavour
	  && bfd_get_format (abfd) == bfd_object
	  && (elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0);
}
Ejemplo n.º 8
0
int
default_core_sniffer (struct core_fns *our_fns, bfd *abfd)
{
  int result;

  result = (bfd_get_flavour (abfd) == our_fns -> core_flavour);
  return (result);
}
Ejemplo n.º 9
0
int
bfd_get_sign_extend_vma (bfd *abfd)
{
  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
    return get_elf_backend_data (abfd)->sign_extend_vma;

  bfd_set_error (bfd_error_wrong_format);
  return -1;
}
Ejemplo n.º 10
0
static enum gdb_osabi
rs6000_aix_osabi_sniffer (bfd *abfd)
{
  
  if (bfd_get_flavour (abfd) == bfd_target_xcoff_flavour);
    return GDB_OSABI_AIX;

  return GDB_OSABI_UNKNOWN;
}
Ejemplo n.º 11
0
static int
sim_prepare_for_program (SIM_DESC sd, bfd* abfd)
{
  sim_cpu *cpu;
  int elf_flags = 0;

  cpu = STATE_CPU (sd, 0);

  if (abfd != NULL)
    {
      asection *s;

      if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
        elf_flags = elf_elfheader (abfd)->e_flags;

      cpu->cpu_elf_start = bfd_get_start_address (abfd);
      /* See if any section sets the reset address */
      cpu->cpu_use_elf_start = 1;
      for (s = abfd->sections; s && cpu->cpu_use_elf_start; s = s->next) 
        {
          if (s->flags & SEC_LOAD)
            {
              bfd_size_type size;

              size = bfd_get_section_size (s);
              if (size > 0)
                {
                  bfd_vma lma;

                  if (STATE_LOAD_AT_LMA_P (sd))
                    lma = bfd_section_lma (abfd, s);
                  else
                    lma = bfd_section_vma (abfd, s);

                  if (lma <= 0xFFFE && lma+size >= 0x10000)
                    cpu->cpu_use_elf_start = 0;
                }
            }
        }

      if (elf_flags & E_M68HC12_BANKS)
        {
          if (sim_get_bank_parameters (sd, abfd) != 0)
            sim_io_eprintf (sd, "Memory bank parameters are not initialized\n");
        }
    }

  if (!sim_hw_configure (sd))
    return SIM_RC_FAIL;

  /* reset all state information */
  sim_board_reset (sd);

  return SIM_RC_OK;
}
Ejemplo n.º 12
0
/* Read inferior memory at ADDR to find the header of a loaded object file
   and read its in-core symbols out of inferior memory.  TEMPL is a bfd
   representing the target's format.  NAME is the name to use for this
   symbol file in messages; it can be NULL or a malloc-allocated string
   which will be attached to the BFD.  */
static struct objfile *
symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr, char *name,
			     int from_tty)
{
  struct objfile *objf;
  struct bfd *nbfd;
  struct bfd_section *sec;
  bfd_vma loadbase;
  struct section_addr_info *sai;
  unsigned int i;

  if (bfd_get_flavour (templ) != bfd_target_elf_flavour)
    error (_("add-symbol-file-from-memory not supported for this target"));

  nbfd = bfd_elf_bfd_from_remote_memory (templ, addr, &loadbase,
					 target_read_memory);
  if (nbfd == NULL)
    error (_("Failed to read a valid object file image from memory."));

  if (name == NULL)
    nbfd->filename = xstrdup ("shared object read from target memory");
  else
    nbfd->filename = name;

  if (!bfd_check_format (nbfd, bfd_object))
    {
      /* FIXME: should be checking for errors from bfd_close (for one thing,
         on error it does not free all the storage associated with the
         bfd).  */
      bfd_close (nbfd);
      error (_("Got object file from memory but can't read symbols: %s."),
	     bfd_errmsg (bfd_get_error ()));
    }

  sai = alloc_section_addr_info (bfd_count_sections (nbfd));
  make_cleanup (xfree, sai);
  i = 0;
  for (sec = nbfd->sections; sec != NULL; sec = sec->next)
    if ((bfd_get_section_flags (nbfd, sec) & (SEC_ALLOC|SEC_LOAD)) != 0)
      {
	sai->other[i].addr = bfd_get_section_vma (nbfd, sec) + loadbase;
	sai->other[i].name = (char *) bfd_get_section_name (nbfd, sec);
	sai->other[i].sectindex = sec->index;
	++i;
      }

  objf = symbol_file_add_from_bfd (nbfd, from_tty ? SYMFILE_VERBOSE : 0,
                                   sai, OBJF_SHARED);

  /* This might change our ideas about frames already looked at.  */
  reinit_frame_cache ();

  return objf;
}
Ejemplo n.º 13
0
bfd_vma asmir_get_base_address(asm_program_t *prog) {
#if SIZEOF_BFD_VMA == 4
  bfd_vma lowest = LONG_MAX;
#else
  bfd_vma lowest = LLONG_MAX;
#endif
  assert(prog);
  bfd *abfd = prog->abfd;
  asection *section;

  if (bfd_get_flavour(abfd) ==  bfd_target_elf_flavour) {

    /* BFD has some issues with ELF files.  ELF files have both
       sections and segments ("program headers").  We really care
       about the lowest address of program segments, but BFD only
       shows sections when an ELF file contains both. So, we need to
       use ELF-specific functions to learn the segment address, which
       is typically different than the section address. */
      int i, is_nice;
      size_t ubound = bfd_get_elf_phdr_upper_bound(abfd);
      Elf_Internal_Phdr *phdrs = bfd_alloc(abfd, ubound);
      if (phdrs == NULL) { bfd_perror(NULL); assert(0); }
      int n = bfd_get_elf_phdrs(abfd, phdrs);
      if (n == -1) { bfd_perror(NULL); assert(0); }

      for (i = 0; i < n; i++) {
        /*
        fprintf(stderr, "VA: %#" BFD_VMA_FMT "x Align: %#" BFD_VMA_FMT "x Aligned: %#" BFD_VMA_FMT "x p_flags: %#" BFD_VMA_FMT "x p_type: %#"BFD_VMA_FMT "x\n", 
            phdrs[i].p_vaddr, 
            phdrs[i].p_align, 
            phdrs[i].p_vaddr & (~(phdrs[i].p_align)), 
            phdrs[i].p_flags, 
            phdrs[i].p_type);
        */
        bfd_vma aligned = phdrs[i].p_vaddr & (~(phdrs[i].p_align));
        /* STACK segment has vaddr=paddr=0. If we don't ignore it, imagebase=0*/
        is_nice = (phdrs[i].p_flags & SHT_PROGBITS) && 
                (phdrs[i].p_type != PT_GNU_STACK);
        if (is_nice && aligned < lowest) { lowest = aligned; }
      }
    } else {

      /* Non-ELF files */
      for (section = abfd->sections; section; section = section->next) {
        /* fprintf(stderr, "Section %s, vma %Lx\n", section->name, section->vma); */
        if ((section->vma < lowest) && (section->flags & SEC_LOAD)) { lowest = section->vma; }
      }
    }

  //fprintf(stderr, "Lowest section is %#" BFD_VMA_FMT "x\n", lowest);
  //fprintf(stderr, "Adjusting by %Lx\n", offset);

  return lowest;
}
Ejemplo n.º 14
0
static bfd_boolean
is32bit (bfd *abfd)
{
  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
    {
      const struct elf_backend_data *bed = get_elf_backend_data (abfd);
      return bed->s->elfclass == ELFCLASS32;
    }

  /* For non-ELF targets, use architecture information.  */
  return bfd_arch_bits_per_address (abfd) <= 32;
}
Ejemplo n.º 15
0
/* Read inferior memory at ADDR to find the header of a loaded object file
   and read its in-core symbols out of inferior memory.  SIZE, if
   non-zero, is the known size of the object.  TEMPL is a bfd
   representing the target's format.  NAME is the name to use for this
   symbol file in messages; it can be NULL or a malloc-allocated string
   which will be attached to the BFD.  */
static struct objfile *
symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr,
			     size_t size, char *name, int from_tty)
{
  struct objfile *objf;
  struct bfd *nbfd;
  struct bfd_section *sec;
  bfd_vma loadbase;
  symfile_add_flags add_flags = 0;

  if (bfd_get_flavour (templ) != bfd_target_elf_flavour)
    error (_("add-symbol-file-from-memory not supported for this target"));

  nbfd = bfd_elf_bfd_from_remote_memory (templ, addr, size, &loadbase,
					 target_read_memory_bfd);
  if (nbfd == NULL)
    error (_("Failed to read a valid object file image from memory."));

  /* Manage the new reference for the duration of this function.  */
  gdb_bfd_ref_ptr nbfd_holder = gdb_bfd_ref_ptr::new_reference (nbfd);

  xfree (bfd_get_filename (nbfd));
  if (name == NULL)
    nbfd->filename = xstrdup ("shared object read from target memory");
  else
    nbfd->filename = name;

  if (!bfd_check_format (nbfd, bfd_object))
    error (_("Got object file from memory but can't read symbols: %s."),
	   bfd_errmsg (bfd_get_error ()));

  section_addr_info sai;
  for (sec = nbfd->sections; sec != NULL; sec = sec->next)
    if ((bfd_get_section_flags (nbfd, sec) & (SEC_ALLOC|SEC_LOAD)) != 0)
      sai.emplace_back (bfd_get_section_vma (nbfd, sec) + loadbase,
			bfd_get_section_name (nbfd, sec),
			sec->index);

  if (from_tty)
    add_flags |= SYMFILE_VERBOSE;

  objf = symbol_file_add_from_bfd (nbfd, bfd_get_filename (nbfd),
				   add_flags, &sai, OBJF_SHARED, NULL);

  add_target_sections_of_objfile (objf);

  /* This might change our ideas about frames already looked at.  */
  reinit_frame_cache ();

  return objf;
}
Ejemplo n.º 16
0
enum sh64_elf_cr_type
sh64_get_contents_type (asection *sec, bfd_vma addr, sh64_elf_crange *rangep)
{
  asection *cranges;

  /* Fill in the range with the boundaries of the section as a default.  */
  if (bfd_get_flavour (sec->owner) == bfd_target_elf_flavour
      && elf_elfheader (sec->owner)->e_type == ET_EXEC)
    {
      rangep->cr_addr = bfd_get_section_vma (sec->owner, sec);
      rangep->cr_size = sec->size;
      rangep->cr_type = CRT_NONE;
    }
  else
    return FALSE;

  /* If none of the pertinent bits are set, then it's a SHcompact (or at
     least not SHmedia).  */
  if ((elf_section_data (sec)->this_hdr.sh_flags
       & (SHF_SH5_ISA32 | SHF_SH5_ISA32_MIXED)) == 0)
    {
      enum sh64_elf_cr_type cr_type
	= ((bfd_get_section_flags (sec->owner, sec) & SEC_CODE) != 0
	   ? CRT_SH5_ISA16 : CRT_DATA);
      rangep->cr_type = cr_type;
      return cr_type;
    }

  /* If only the SHF_SH5_ISA32 bit is set, then we have SHmedia.  */
  if ((elf_section_data (sec)->this_hdr.sh_flags
       & (SHF_SH5_ISA32 | SHF_SH5_ISA32_MIXED)) == SHF_SH5_ISA32)
    {
      rangep->cr_type = CRT_SH5_ISA32;
      return CRT_SH5_ISA32;
    }

  /* Otherwise, we have to look up the .cranges section.  */
  cranges = bfd_get_section_by_name (sec->owner, SH64_CRANGES_SECTION_NAME);

  if (cranges == NULL)
    /* A mixed section but there's no .cranges section.  This is probably
       bad input; it does not comply to specs.  */
    return CRT_NONE;

  /* If this call fails, we will still have CRT_NONE in rangep->cr_type
     and that will be suitable to return.  */
  sh64_address_in_cranges (cranges, addr, rangep);

  return rangep->cr_type;
}
Ejemplo n.º 17
0
static const struct elf_build_id *
build_id_bfd_get (bfd *abfd)
{
  if (!bfd_check_format (abfd, bfd_object)
      || bfd_get_flavour (abfd) != bfd_target_elf_flavour
      /* Although this is ELF_specific, it is safe to do in generic
	 code because it does not rely on any ELF-specific symbols at
	 link time, and if the ELF code is not available in BFD, then
	 ABFD will not have the ELF flavour.  */
      || elf_tdata (abfd)->build_id == NULL)
    return NULL;

  return elf_tdata (abfd)->build_id;
}
Ejemplo n.º 18
0
static enum gdb_osabi
rs6000_lynx178_osabi_sniffer (bfd *abfd)
{
  if (bfd_get_flavour (abfd) != bfd_target_xcoff_flavour)
    return GDB_OSABI_UNKNOWN;

  /* The only noticeable difference between Lynx178 XCOFF files and
     AIX XCOFF files comes from the fact that there are no shared
     libraries on Lynx178.  So if the number of import files is
     different from zero, it cannot be a Lynx178 binary.  */
  if (xcoff_get_n_import_files (abfd) != 0)
    return GDB_OSABI_UNKNOWN;

  return GDB_OSABI_LYNXOS178;
}
Ejemplo n.º 19
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;
}
Ejemplo n.º 20
0
elf_property *
_bfd_elf_get_property (bfd *abfd, unsigned int type, unsigned int datasz)
{
  elf_property_list *p, **lastp;

  if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
    {
      /* Never should happen.  */
      abort ();
    }

  /* Keep the property list in order of type.  */
  lastp = &elf_properties (abfd);
  for (p = *lastp; p; p = p->next)
    {
      /* Reuse the existing entry.  */
      if (type == p->property.pr_type)
	{
	  if (datasz > p->property.pr_datasz)
	    {
	      /* This can happen when mixing 32-bit and 64-bit objects.  */
	      p->property.pr_datasz = datasz;
	    }
	  return &p->property;
	}
      else if (type < p->property.pr_type)
	break;
      lastp = &p->next;
    }
  p = (elf_property_list *) bfd_alloc (abfd, sizeof (*p));
  if (p == NULL)
    {
      _bfd_error_handler (_("%pB: out of memory in _bfd_elf_get_property"),
			  abfd);
      _exit (EXIT_FAILURE);
    }
  memset (p, 0, sizeof (*p));
  p->property.pr_type = type;
  p->property.pr_datasz = datasz;
  p->next = *lastp;
  *lastp = p;
  return &p->property;
}
Ejemplo n.º 21
0
/* Return TRUE if a defined symbol might be reachable from outside the
   universe of claimed objects.  */
static inline bfd_boolean
is_visible_from_outside (struct ld_plugin_symbol *lsym,
			 struct bfd_link_hash_entry *blhe)
{
  struct bfd_sym_chain *sym;

  if (link_info.relocatable)
    return TRUE;
  if (link_info.export_dynamic || !link_info.executable)
    {
      /* Check if symbol is hidden by version script.  */
      if (bfd_hide_sym_by_version (link_info.version_info,
				   blhe->root.string))
	return FALSE;
      /* Only ELF symbols really have visibility.  */
      if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour)
	{
	  struct elf_link_hash_entry *el = (struct elf_link_hash_entry *)blhe;
	  int vis = ELF_ST_VISIBILITY (el->other);
	  return vis == STV_DEFAULT || vis == STV_PROTECTED;
	}
      /* On non-ELF targets, we can safely make inferences by considering
	 what visibility the plugin would have liked to apply when it first
	 sent us the symbol.  During ELF symbol processing, visibility only
	 ever becomes more restrictive, not less, when symbols are merged,
	 so this is a conservative estimate; it may give false positives,
	 declaring something visible from outside when it in fact would
	 not have been, but this will only lead to missed optimisation
	 opportunities during LTRANS at worst; it will not give false
	 negatives, which can lead to the disastrous conclusion that the
	 related symbol is IRONLY.  (See GCC PR46319 for an example.)  */
      return (lsym->visibility == LDPV_DEFAULT
	      || lsym->visibility == LDPV_PROTECTED);
    }

  for (sym = &entry_symbol; sym != NULL; sym = sym->next)
    if (sym->name
	&& strcmp (sym->name, blhe->root.string) == 0)
      return TRUE;

  return FALSE;
}
Ejemplo n.º 22
0
bfd_boolean
bfd_record_phdr (bfd *abfd,
		 unsigned long type,
		 bfd_boolean flags_valid,
		 flagword flags,
		 bfd_boolean at_valid,
		 bfd_vma at,
		 bfd_boolean includes_filehdr,
		 bfd_boolean includes_phdrs,
		 unsigned int count,
		 asection **secs)
{
  struct elf_segment_map *m, **pm;
  bfd_size_type amt;

  if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
    return TRUE;

  amt = sizeof (struct elf_segment_map);
  amt += ((bfd_size_type) count - 1) * sizeof (asection *);
  m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
  if (m == NULL)
    return FALSE;

  m->p_type = type;
  m->p_flags = flags;
  m->p_paddr = at;
  m->p_flags_valid = flags_valid;
  m->p_paddr_valid = at_valid;
  m->includes_filehdr = includes_filehdr;
  m->includes_phdrs = includes_phdrs;
  m->count = count;
  if (count > 0)
    memcpy (m->sections, secs, count * sizeof (asection *));

  for (pm = &elf_seg_map (abfd); *pm != NULL; pm = &(*pm)->next)
    ;
  *pm = m;

  return TRUE;
}
Ejemplo n.º 23
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;
}
Ejemplo n.º 24
0
enum gdb_osabi
gdbarch_lookup_osabi (bfd *abfd)
{
  struct gdb_osabi_sniffer *sniffer;
  enum gdb_osabi osabi, match;
  int match_specific;

  match = GDB_OSABI_UNKNOWN;
  match_specific = 0;

  for (sniffer = gdb_osabi_sniffer_list; sniffer != NULL;
       sniffer = sniffer->next)
    {
      if ((sniffer->arch == bfd_arch_unknown /* wildcard */
	   || sniffer->arch == bfd_get_arch (abfd))
	  && sniffer->flavour == bfd_get_flavour (abfd))
	{
	  osabi = (*sniffer->sniffer) (abfd);
	  if (osabi < GDB_OSABI_UNKNOWN || osabi >= GDB_OSABI_INVALID)
	    {
	      internal_error
		(__FILE__, __LINE__,
		 "gdbarch_lookup_osabi: invalid OS ABI (%d) from sniffer "
		 "for architecture %s flavour %d",
		 (int) osabi,
		 bfd_printable_arch_mach (bfd_get_arch (abfd), 0),
		 (int) bfd_get_flavour (abfd));
	    }
	  else if (osabi != GDB_OSABI_UNKNOWN)
	    {
	      /* A specific sniffer always overrides a generic sniffer.
		 Croak on multiple match if the two matches are of the
		 same class.  If the user wishes to continue, we'll use
		 the first match.  */
	      if (match != GDB_OSABI_UNKNOWN)
		{
		  if ((match_specific && sniffer->arch != bfd_arch_unknown)
		   || (!match_specific && sniffer->arch == bfd_arch_unknown))
		    {
		      internal_error
		        (__FILE__, __LINE__,
		         "gdbarch_lookup_osabi: multiple %sspecific OS ABI "
			 "match for architecture %s flavour %d: first "
			 "match \"%s\", second match \"%s\"",
			 match_specific ? "" : "non-",
		         bfd_printable_arch_mach (bfd_get_arch (abfd), 0),
		         (int) bfd_get_flavour (abfd),
		         gdbarch_osabi_name (match),
		         gdbarch_osabi_name (osabi));
		    }
		  else if (sniffer->arch != bfd_arch_unknown)
		    {
		      match = osabi;
		      match_specific = 1;
		    }
		}
	      else
		{
		  match = osabi;
		  if (sniffer->arch != bfd_arch_unknown)
		    match_specific = 1;
		}
	    }
	}
    }

  return match;
}
Ejemplo n.º 25
0
enum gdb_osabi
gdbarch_lookup_osabi (bfd *abfd)
{
  struct gdb_osabi_sniffer *sniffer;
  enum gdb_osabi osabi, match;
  int match_specific;

  /* If we aren't in "auto" mode, return the specified OS ABI.  */
  if (user_osabi_state == osabi_user)
    return user_selected_osabi;

  /* If we don't have a binary, just return unknown.  The caller may
     have other sources the OSABI can be extracted from, e.g., the
     target description.  */
  if (abfd == NULL) 
    return GDB_OSABI_UNKNOWN;

  match = GDB_OSABI_UNKNOWN;
  match_specific = 0;

  for (sniffer = gdb_osabi_sniffer_list; sniffer != NULL;
       sniffer = sniffer->next)
    {
      if ((sniffer->arch == bfd_arch_unknown /* wildcard */
	   || sniffer->arch == bfd_get_arch (abfd))
	  && sniffer->flavour == bfd_get_flavour (abfd))
	{
	  osabi = (*sniffer->sniffer) (abfd);
	  if (osabi < GDB_OSABI_UNKNOWN || osabi >= GDB_OSABI_INVALID)
	    {
	      internal_error
		(__FILE__, __LINE__,
		 _("gdbarch_lookup_osabi: invalid OS ABI (%d) from sniffer "
		 "for architecture %s flavour %d"),
		 (int) osabi,
		 bfd_printable_arch_mach (bfd_get_arch (abfd), 0),
		 (int) bfd_get_flavour (abfd));
	    }
	  else if (osabi != GDB_OSABI_UNKNOWN)
	    {
	      /* A specific sniffer always overrides a generic sniffer.
		 Croak on multiple match if the two matches are of the
		 same class.  If the user wishes to continue, we'll use
		 the first match.  */
	      if (match != GDB_OSABI_UNKNOWN)
		{
		  if ((match_specific && sniffer->arch != bfd_arch_unknown)
		   || (!match_specific && sniffer->arch == bfd_arch_unknown))
		    {
		      internal_error
		        (__FILE__, __LINE__,
		         _("gdbarch_lookup_osabi: multiple %sspecific OS ABI "
			 "match for architecture %s flavour %d: first "
			 "match \"%s\", second match \"%s\""),
			 match_specific ? "" : "non-",
		         bfd_printable_arch_mach (bfd_get_arch (abfd), 0),
		         (int) bfd_get_flavour (abfd),
		         gdbarch_osabi_name (match),
		         gdbarch_osabi_name (osabi));
		    }
		  else if (sniffer->arch != bfd_arch_unknown)
		    {
		      match = osabi;
		      match_specific = 1;
		    }
		}
	      else
		{
		  match = osabi;
		  if (sniffer->arch != bfd_arch_unknown)
		    match_specific = 1;
		}
	    }
	}
    }

  return match;
}
Ejemplo n.º 26
0
/* Helpers to convert between BFD and GOLD symbol formats.  */
static enum ld_plugin_status
asymbol_from_plugin_symbol (bfd *abfd, asymbol *asym,
			    const struct ld_plugin_symbol *ldsym)
{
  flagword flags = BSF_NO_FLAGS;
  struct bfd_section *section;

  asym->the_bfd = abfd;
  asym->name = (ldsym->version
		? concat (ldsym->name, "@", ldsym->version, (const char *) NULL)
		: ldsym->name);
  asym->value = 0;
  switch (ldsym->def)
    {
    case LDPK_WEAKDEF:
      flags = BSF_WEAK;
      /* FALLTHRU */
    case LDPK_DEF:
      flags |= BSF_GLOBAL;
      if (ldsym->comdat_key)
	{
	  char *name = concat (".gnu.linkonce.t.", ldsym->comdat_key,
			       (const char *) NULL);
	  section = bfd_get_section_by_name (abfd, name);
	  if (section != NULL)
	    free (name);
	  else
	    {
	      flagword sflags;

	      sflags = (SEC_CODE | SEC_HAS_CONTENTS | SEC_READONLY
			| SEC_ALLOC | SEC_LOAD | SEC_KEEP | SEC_EXCLUDE
			| SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD);
	      section = bfd_make_section_anyway_with_flags (abfd, name, sflags);
	      if (section == NULL)
		return LDPS_ERR;
	    }
	}
      else
	section = bfd_get_section_by_name (abfd, ".text");
      break;

    case LDPK_WEAKUNDEF:
      flags = BSF_WEAK;
      /* FALLTHRU */
    case LDPK_UNDEF:
      section = bfd_und_section_ptr;
      break;

    case LDPK_COMMON:
      flags = BSF_GLOBAL;
      section = bfd_com_section_ptr;
      asym->value = ldsym->size;
      /* For ELF targets, set alignment of common symbol to 1.  */
      if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
	{
	  ((elf_symbol_type *) asym)->internal_elf_sym.st_shndx = SHN_COMMON;
	  ((elf_symbol_type *) asym)->internal_elf_sym.st_value = 1;
	}
      break;

    default:
      return LDPS_ERR;
    }
  asym->flags = flags;
  asym->section = section;

  /* Visibility only applies on ELF targets.  */
  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
    {
      elf_symbol_type *elfsym = elf_symbol_from (abfd, asym);
      unsigned char visibility;

      if (!elfsym)
	einfo (_("%P%F: %s: non-ELF symbol in ELF BFD!\n"), asym->name);
      switch (ldsym->visibility)
	{
	default:
	  einfo (_("%P%F: unknown ELF symbol visibility: %d!\n"),
		 ldsym->visibility);
	case LDPV_DEFAULT:
	  visibility = STV_DEFAULT;
	  break;
	case LDPV_PROTECTED:
	  visibility = STV_PROTECTED;
	  break;
	case LDPV_INTERNAL:
	  visibility = STV_INTERNAL;
	  break;
	case LDPV_HIDDEN:
	  visibility = STV_HIDDEN;
	  break;
	}
      elfsym->internal_elf_sym.st_other
	= (visibility | (elfsym->internal_elf_sym.st_other
			 & ~ELF_ST_VISIBILITY (-1)));
    }

  return LDPS_OK;
}
Ejemplo n.º 27
0
void
vfinfo (FILE *fp, const char *fmt, va_list ap, bfd_boolean is_warning)
{
  bfd_boolean fatal = FALSE;
  const char *scan;
  int arg_type;
  unsigned int arg_count = 0;
  unsigned int arg_no;
  union vfinfo_args
  {
    int i;
    long l;
    void *p;
    bfd_vma v;
    struct {
      bfd *abfd;
      asection *sec;
      bfd_vma off;
    } reladdr;
    enum
      {
	Bad,
	Int,
	Long,
	Ptr,
	Vma,
	RelAddr
      } type;
  } args[9];

  for (arg_no = 0; arg_no < sizeof (args) / sizeof (args[0]); arg_no++)
    args[arg_no].type = Bad;

  arg_count = 0;
  scan = fmt;
  while (*scan != '\0')
    {
      while (*scan != '%' && *scan != '\0')
	scan++;

      if (*scan == '%')
	{
	  scan++;

	  arg_no = arg_count;
	  if (*scan != '0' && ISDIGIT (*scan) && scan[1] == '$')
	    {
	      arg_no = *scan - '1';
	      scan += 2;
	    }

	  arg_type = Bad;
	  switch (*scan++)
	    {
	    case '\0':
	      --scan;
	      break;

	    case 'V':
	    case 'v':
	    case 'W':
	      arg_type = Vma;
	      break;

	    case 's':
	      arg_type = Ptr;
	      break;

	    case 'p':
	      if (*scan == 'A' || *scan == 'B' || *scan == 'I'
		  || *scan == 'R' || *scan == 'S' || *scan ==  'T')
		scan++;
	      arg_type = Ptr;
	      break;

	    case 'C':
	    case 'D':
	    case 'G':
	    case 'H':
	      arg_type = RelAddr;
	      break;

	    case 'd':
	    case 'u':
	      arg_type = Int;
	      break;

	    case 'l':
	      if (*scan == 'd' || *scan == 'u')
		{
		  ++scan;
		  arg_type = Long;
		}
	      break;

	    default:
	      break;
	    }
	  if (arg_type != Bad)
	    {
	      if (arg_no >= sizeof (args) / sizeof (args[0]))
		abort ();
	      args[arg_no].type = arg_type;
	      ++arg_count;
	    }
	}
    }

  for (arg_no = 0; arg_no < arg_count; arg_no++)
    {
      switch (args[arg_no].type)
	{
	case Int:
	  args[arg_no].i = va_arg (ap, int);
	  break;
	case Long:
	  args[arg_no].l = va_arg (ap, long);
	  break;
	case Ptr:
	  args[arg_no].p = va_arg (ap, void *);
	  break;
	case Vma:
	  args[arg_no].v = va_arg (ap, bfd_vma);
	  break;
	case RelAddr:
	  args[arg_no].reladdr.abfd = va_arg (ap, bfd *);
	  args[arg_no].reladdr.sec = va_arg (ap, asection *);
	  args[arg_no].reladdr.off = va_arg (ap, bfd_vma);
	  break;
	default:
	  abort ();
	}
    }

  arg_count = 0;
  while (*fmt != '\0')
    {
      const char *str = fmt;
      while (*fmt != '%' && *fmt != '\0')
	fmt++;
      if (fmt != str)
	if (fwrite (str, 1, fmt - str, fp))
	  {
	    /* Ignore.  */
	  }

      if (*fmt == '%')
	{
	  fmt++;

	  arg_no = arg_count;
	  if (*fmt != '0' && ISDIGIT (*fmt) && fmt[1] == '$')
	    {
	      arg_no = *fmt - '1';
	      fmt += 2;
	    }

	  switch (*fmt++)
	    {
	    case '\0':
	      --fmt;
	      /* Fall through.  */

	    case '%':
	      /* literal % */
	      putc ('%', fp);
	      break;

	    case 'X':
	      /* no object output, fail return */
	      config.make_executable = FALSE;
	      break;

	    case 'V':
	      /* hex bfd_vma */
	      {
		bfd_vma value = args[arg_no].v;
		++arg_count;
		fprintf_vma (fp, value);
	      }
	      break;

	    case 'v':
	      /* hex bfd_vma, no leading zeros */
	      {
		char buf[100];
		char *p = buf;
		bfd_vma value = args[arg_no].v;
		++arg_count;
		sprintf_vma (p, value);
		while (*p == '0')
		  p++;
		if (!*p)
		  p--;
		fputs (p, fp);
	      }
	      break;

	    case 'W':
	      /* hex bfd_vma with 0x with no leading zeroes taking up
		 8 spaces.  */
	      {
		char buf[100];
		bfd_vma value;
		char *p;
		int len;

		value = args[arg_no].v;
		++arg_count;
		sprintf_vma (buf, value);
		for (p = buf; *p == '0'; ++p)
		  ;
		if (*p == '\0')
		  --p;
		len = strlen (p);
		while (len < 8)
		  {
		    putc (' ', fp);
		    ++len;
		  }
		fprintf (fp, "0x%s", p);
	      }
	      break;

	    case 'F':
	      /* Error is fatal.  */
	      fatal = TRUE;
	      break;

	    case 'P':
	      /* Print program name.  */
	      fprintf (fp, "%s", program_name);
	      break;

	    case 'E':
	      /* current bfd error or errno */
	      fprintf (fp, "%s", bfd_errmsg (bfd_get_error ()));
	      break;

	    case 'C':
	    case 'D':
	    case 'G':
	    case 'H':
	      /* Clever filename:linenumber with function name if possible.
		 The arguments are a BFD, a section, and an offset.  */
	      {
		static bfd *last_bfd;
		static char *last_file;
		static char *last_function;
		bfd *abfd;
		asection *section;
		bfd_vma offset;
		asymbol **asymbols = NULL;
		const char *filename;
		const char *functionname;
		unsigned int linenumber;
		bfd_boolean discard_last;
		bfd_boolean done;

		abfd = args[arg_no].reladdr.abfd;
		section = args[arg_no].reladdr.sec;
		offset = args[arg_no].reladdr.off;
		++arg_count;

		if (abfd != NULL)
		  {
		    if (!bfd_generic_link_read_symbols (abfd))
		      einfo (_("%F%P: %pB: could not read symbols: %E\n"), abfd);

		    asymbols = bfd_get_outsymbols (abfd);
		  }

		/* The GNU Coding Standard requires that error messages
		   be of the form:

		     source-file-name:lineno: message

		   We do not always have a line number available so if
		   we cannot find them we print out the section name and
		   offset instead.  */
		discard_last = TRUE;
		if (abfd != NULL
		    && bfd_find_nearest_line (abfd, section, asymbols, offset,
					      &filename, &functionname,
					      &linenumber))
		  {
		    if (functionname != NULL
			&& (fmt[-1] == 'C' || fmt[-1] == 'H'))
		      {
			/* Detect the case where we are printing out a
			   message for the same function as the last
			   call to vinfo ("%C").  In this situation do
			   not print out the ABFD filename or the
			   function name again.  Note - we do still
			   print out the source filename, as this will
			   allow programs that parse the linker's output
			   (eg emacs) to correctly locate multiple
			   errors in the same source file.  */
			if (last_bfd == NULL
			    || last_function == NULL
			    || last_bfd != abfd
			    || (last_file == NULL) != (filename == NULL)
			    || (filename != NULL
				&& filename_cmp (last_file, filename) != 0)
			    || strcmp (last_function, functionname) != 0)
			  {
			    lfinfo (fp, _("%pB: in function `%pT':\n"),
				    abfd, functionname);

			    last_bfd = abfd;
			    if (last_file != NULL)
			      free (last_file);
			    last_file = NULL;
			    if (filename)
			      last_file = xstrdup (filename);
			    if (last_function != NULL)
			      free (last_function);
			    last_function = xstrdup (functionname);
			  }
			discard_last = FALSE;
		      }
		    else
		      lfinfo (fp, "%pB:", abfd);

		    if (filename != NULL)
		      fprintf (fp, "%s:", filename);

		    done = fmt[-1] != 'H';
		    if (functionname != NULL && fmt[-1] == 'G')
		      lfinfo (fp, "%pT", functionname);
		    else if (filename != NULL && linenumber != 0)
		      fprintf (fp, "%u%s", linenumber, done ? "" : ":");
		    else
		      done = FALSE;
		  }
		else
		  {
		    lfinfo (fp, "%pB:", abfd);
		    done = FALSE;
		  }
		if (!done)
		  lfinfo (fp, "(%pA+0x%v)", section, offset);

		if (discard_last)
		  {
		    last_bfd = NULL;
		    if (last_file != NULL)
		      {
			free (last_file);
			last_file = NULL;
		      }
		    if (last_function != NULL)
		      {
			free (last_function);
			last_function = NULL;
		      }
		  }
	      }
	      break;

	    case 'p':
	      if (*fmt == 'A')
		{
		  /* section name from a section */
		  asection *sec;
		  bfd *abfd;
		  const char *group = NULL;
		  struct coff_comdat_info *ci;

		  fmt++;
		  sec = (asection *) args[arg_no].p;
		  ++arg_count;
		  abfd = sec->owner;
		  fprintf (fp, "%s", sec->name);
		  if (abfd != NULL
		      && bfd_get_flavour (abfd) == bfd_target_elf_flavour
		      && elf_next_in_group (sec) != NULL
		      && (sec->flags & SEC_GROUP) == 0)
		    group = elf_group_name (sec);
		  else if (abfd != NULL
			   && bfd_get_flavour (abfd) == bfd_target_coff_flavour
			   && (ci = bfd_coff_get_comdat_section (sec->owner,
								 sec)) != NULL)
		    group = ci->name;
		  if (group != NULL)
		    fprintf (fp, "[%s]", group);
		}
	      else if (*fmt == 'B')
		{
		  /* filename from a bfd */
		  bfd *abfd = (bfd *) args[arg_no].p;

		  fmt++;
		  ++arg_count;
		  if (abfd == NULL)
		    fprintf (fp, "%s generated", program_name);
		  else if (abfd->my_archive != NULL
			   && !bfd_is_thin_archive (abfd->my_archive))
		    fprintf (fp, "%s(%s)", abfd->my_archive->filename,
			     abfd->filename);
		  else
		    fprintf (fp, "%s", abfd->filename);
		}
	      else if (*fmt == 'I')
		{
		  /* filename from a lang_input_statement_type */
		  lang_input_statement_type *i;

		  fmt++;
		  i = (lang_input_statement_type *) args[arg_no].p;
		  ++arg_count;
		  if (i->the_bfd != NULL
		      && i->the_bfd->my_archive != NULL
		      && !bfd_is_thin_archive (i->the_bfd->my_archive))
		    fprintf (fp, "(%s)%s", i->the_bfd->my_archive->filename,
			     i->local_sym_name);
		  else
		    fprintf (fp, "%s", i->filename);
		}
	      else if (*fmt == 'R')
		{
		  /* Print all that's interesting about a relent.  */
		  arelent *relent = (arelent *) args[arg_no].p;

		  fmt++;
		  ++arg_count;
		  lfinfo (fp, "%s+0x%v (type %s)",
			  (*(relent->sym_ptr_ptr))->name,
			  relent->addend,
			  relent->howto->name);
		}
	      else if (*fmt == 'S')
		{
		  /* Print script file and linenumber.  */
		  etree_type node;
		  etree_type *tp = (etree_type *) args[arg_no].p;

		  fmt++;
		  ++arg_count;
		  if (tp == NULL)
		    {
		      tp = &node;
		      tp->type.filename = ldlex_filename ();
		      tp->type.lineno = lineno;
		    }
		  if (tp->type.filename != NULL)
		    fprintf (fp, "%s:%u", tp->type.filename, tp->type.lineno);
		}
	      else if (*fmt == 'T')
		{
		  /* Symbol name.  */
		  const char *name = (const char *) args[arg_no].p;

		  fmt++;
		  ++arg_count;
		  if (name == NULL || *name == 0)
		    {
		      fprintf (fp, _("no symbol"));
		      break;
		    }
		  else if (demangling)
		    {
		      char *demangled;

		      demangled = bfd_demangle (link_info.output_bfd, name,
						DMGL_ANSI | DMGL_PARAMS);
		      if (demangled != NULL)
			{
			  fprintf (fp, "%s", demangled);
			  free (demangled);
			  break;
			}
		    }
		  fprintf (fp, "%s", name);
		}
	      else
		{
		  /* native (host) void* pointer, like printf */
		  fprintf (fp, "%p", args[arg_no].p);
		  ++arg_count;
		}
	      break;

	    case 's':
	      /* arbitrary string, like printf */
	      fprintf (fp, "%s", (char *) args[arg_no].p);
	      ++arg_count;
	      break;

	    case 'd':
	      /* integer, like printf */
	      fprintf (fp, "%d", args[arg_no].i);
	      ++arg_count;
	      break;

	    case 'u':
	      /* unsigned integer, like printf */
	      fprintf (fp, "%u", args[arg_no].i);
	      ++arg_count;
	      break;

	    case 'l':
	      if (*fmt == 'd')
		{
		  fprintf (fp, "%ld", args[arg_no].l);
		  ++arg_count;
		  ++fmt;
		  break;
		}
	      else if (*fmt == 'u')
		{
		  fprintf (fp, "%lu", args[arg_no].l);
		  ++arg_count;
		  ++fmt;
		  break;
		}
	      /* Fallthru */

	    default:
	      fprintf (fp, "%%%c", fmt[-1]);
	      break;
	    }
	}
    }

  if (is_warning && config.fatal_warnings)
    config.make_executable = FALSE;

  if (fatal)
    xexit (1);
}
Ejemplo n.º 28
0
bfd *
_bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info)
{
  bfd *abfd, *first_pbfd = NULL;
  elf_property_list *list;
  asection *sec;
  bfd_boolean has_properties = FALSE;
  const struct elf_backend_data *bed
    = get_elf_backend_data (info->output_bfd);
  unsigned int elfclass = bed->s->elfclass;
  int elf_machine_code = bed->elf_machine_code;

  /* Find the first relocatable ELF input with GNU properties.  */
  for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next)
    if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
	&& (abfd->flags & DYNAMIC) == 0
	&& elf_properties (abfd) != NULL)
      {
	has_properties = TRUE;

	/* Ignore GNU properties from ELF objects with different machine
	   code or class.  Also skip objects without a GNU_PROPERTY note
	   section.  */
	if ((elf_machine_code
	     == get_elf_backend_data (abfd)->elf_machine_code)
	    && (elfclass
		== get_elf_backend_data (abfd)->s->elfclass)
	    && bfd_get_section_by_name (abfd,
					NOTE_GNU_PROPERTY_SECTION_NAME) != NULL
	    )
	  {
	    /* Keep .note.gnu.property section in FIRST_PBFD.  */
	    first_pbfd = abfd;
	    break;
	  }
      }

  /* Do nothing if there is no .note.gnu.property section.  */
  if (!has_properties)
    return NULL;

  /* Merge .note.gnu.property sections.  */
  for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next)
    if (abfd != first_pbfd && (abfd->flags & DYNAMIC) == 0)
      {
	elf_property_list *null_ptr = NULL;
	elf_property_list **listp = &null_ptr;

	/* Merge .note.gnu.property section in relocatable ELF input.  */
	if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
	  {
	    list = elf_properties (abfd);

	    /* Ignore GNU properties from ELF objects with different
	       machine code.  */
	    if (list != NULL
		&& (elf_machine_code
		    == get_elf_backend_data (abfd)->elf_machine_code))
	      listp = &elf_properties (abfd);
	  }
	else
	  list = NULL;

	/* Merge properties with FIRST_PBFD.  FIRST_PBFD can be NULL
	   when all properties are from ELF objects with different
	   machine code or class.  */
	if (first_pbfd != NULL)
	  elf_merge_gnu_property_list (info, first_pbfd, listp);

	if (list != NULL)
	  {
	    /* Discard the .note.gnu.property section in this bfd.  */
	    sec = bfd_get_section_by_name (abfd,
					   NOTE_GNU_PROPERTY_SECTION_NAME);
	    if (sec != NULL)
	      sec->output_section = bfd_abs_section_ptr;
	  }
      }

  /* Rewrite .note.gnu.property section so that GNU properties are
     always sorted by type even if input GNU properties aren't sorted.  */
  if (first_pbfd != NULL)
    {
      bfd_size_type size;
      bfd_byte *contents;
      unsigned int align_size = elfclass == ELFCLASS64 ? 8 : 4;

      sec = bfd_get_section_by_name (first_pbfd,
				     NOTE_GNU_PROPERTY_SECTION_NAME);
      BFD_ASSERT (sec != NULL);

      /* Update stack size in .note.gnu.property with -z stack-size=N
	 if N > 0.  */
      if (info->stacksize > 0)
	{
	  elf_property *p;
	  bfd_vma stacksize = info->stacksize;

	  p = _bfd_elf_get_property (first_pbfd, GNU_PROPERTY_STACK_SIZE,
				     align_size);
	  if (p->pr_kind == property_unknown)
	    {
	      /* Create GNU_PROPERTY_STACK_SIZE.  */
	      p->u.number = stacksize;
	      p->pr_kind = property_number;
	    }
	  else if (stacksize > p->u.number)
	    p->u.number = stacksize;
	}
      else if (elf_properties (first_pbfd) == NULL)
	{
	  /* Discard .note.gnu.property section if all properties have
	     been removed.  */
	  sec->output_section = bfd_abs_section_ptr;
	  return NULL;
	}

      /* Fix up GNU properties.  */
      if (bed->fixup_gnu_properties)
	bed->fixup_gnu_properties (info, &elf_properties (first_pbfd));

      if (elf_properties (first_pbfd) == NULL)
	{
	  /* Discard .note.gnu.property section if all properties have
	     been removed.  */
	  sec->output_section = bfd_abs_section_ptr;
	  return NULL;
	}

      /* Compute the section size.  */
      list = elf_properties (first_pbfd);
      size = elf_get_gnu_property_section_size (list, align_size);

      /* Update .note.gnu.property section now.  */
      sec->size = size;
      contents = (bfd_byte *) bfd_zalloc (first_pbfd, size);

      elf_write_gnu_properties (first_pbfd, contents, list, size,
				align_size);

      /* Cache the section contents for elf_link_input_bfd.  */
      elf_section_data (sec)->this_hdr.contents = contents;

      /* If GNU_PROPERTY_NO_COPY_ON_PROTECTED is set, protected data
	 symbol is defined in the shared object.  */
      if (elf_has_no_copy_on_protected (first_pbfd))
	info->extern_protected_data = FALSE;
    }

  return first_pbfd;
}
Ejemplo n.º 29
0
static void
mips_elf32_after_open()
{
  /* Call the standard elf routine.  */
  gldelf32ltsmip_after_open ();

#ifdef SUPPORT_EMBEDDED_RELOCS
  if (command_line.embedded_relocs && (! link_info.relocateable))
    {  
      bfd *abfd;

      /* In the embedded relocs mode we create a .rel.sdata section for
	 each input file with a .sdata section which has has
	 relocations.  The BFD backend will fill in these sections
	 with magic numbers which can be used to relocate the data
	 section at run time.  */
      for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link_next)
        {
          asection *datasec;

	  /* As first-order business, make sure that each input BFD is
	     ELF.  We need to call a special BFD backend function to
	     generate the embedded relocs, and we have that function
	     only for ELF */

          if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
	    einfo ("%F%B: all input objects must be ELF for --embedded-relocs\n");

	  if (bfd_get_arch_size (abfd) != 32)
	    einfo ("%F%B: all input objects must be 32-bit ELF for --embedded-relocs\n");

          datasec = bfd_get_section_by_name (abfd, ".sdata");
  
          /* Note that we assume that the reloc_count field has already
             been set up.  We could call bfd_get_reloc_upper_bound, but
             that returns the size of a memory buffer rather than a reloc
             count.  We do not want to call bfd_canonicalize_reloc,
             because although it would always work it would force us to
             read in the relocs into BFD canonical form, which would waste
             a significant amount of time and memory.  */

          if (datasec != NULL && datasec->reloc_count > 0)
 	    {
              asection *relsec;
 
	      relsec = bfd_make_section (abfd, ".rel.sdata");
	      if (relsec == NULL
	          || ! bfd_set_section_flags (abfd, relsec,
					      (SEC_ALLOC
					       | SEC_LOAD
					       | SEC_HAS_CONTENTS
					       | SEC_IN_MEMORY))
                  || ! bfd_set_section_alignment (abfd, relsec,
						  (32 == 32) ? 2 : 3)
	          || ! bfd_set_section_size (abfd, relsec,
		  			     datasec->reloc_count
					     * ((32 / 8) + 8)))
	        einfo ("%F%B: cannot create .rel.sdata section: %E\n");
	    }

          /* Double check that all other data sections have no relocs,
             as is required for embedded PIC code.  */
          bfd_map_over_sections (abfd, mips_elf32_check_sections,
				 (PTR) datasec);
        }
    }
#endif /* SUPPORT_EMBEDDED_RELOCS */
}
Ejemplo n.º 30
0
static void BFDmanager_loadBFDdata (char *file, bfd **image, asymbol ***symbols,
	unsigned *nDataSymbols, data_symbol_t **DataSymbols)
{
	bfd *bfdImage = NULL;
	asymbol **bfdSymbols = NULL;

	if (nDataSymbols)
		*nDataSymbols = 0;
	if (DataSymbols)
		*DataSymbols = NULL;

	/* Open the binary file in read-only mode */
	bfdImage = bfd_openr (file, NULL);
	if (bfdImage == NULL)
	{
		const char *errmsg = bfd_errmsg (bfd_get_error());
		fprintf (stderr, "mpi2prv: WARNING! Cannot open binary file '%s': %s.\n"
		                "         Addresses will not be translated into source code references\n",
		  file, errmsg);
		return;
	}

	/* Check the binary file format */
	if (!bfd_check_format (bfdImage, bfd_object))
	{
		const char *errmsg = bfd_errmsg( bfd_get_error() );
		fprintf (stderr, "mpi2prv: WARNING! Binary file format does not match for file '%s' : %s\n"
		                "         Addresses will not be translated into source code references\n",
		  file, errmsg);
	}

	/* Load the mini-Symbol Table */
	if (bfd_get_file_flags (bfdImage) & HAS_SYMS)
	{
		long symcount;
		size_t size = bfd_get_symtab_upper_bound (bfdImage);
		if (size > 0)
		{
#if defined(BFD_MANAGER_GENERATE_ADDRESSES)
			long s;
			unsigned nDataSyms = 0;
			data_symbol_t *DataSyms = NULL;
#endif

			bfdSymbols = (asymbol**) malloc (size);
			if (bfdSymbols == NULL)
				FATAL_ERROR ("Cannot allocate memory to translate addresses into source code references\n");

#if 0
			/* HSG This is supposed to be space-efficient, but showed some errors .... :( */
			symcount = bfd_read_minisymbols (bfdImage, FALSE, (PTR) bfdSymbols, &usize);
			if (symcount == 0) 
				symcount = bfd_read_minisymbols (bfdImage, TRUE, (PTR) bfdSymbols, &usize);
#else
			symcount = bfd_canonicalize_symtab (bfdImage, bfdSymbols);

# if defined(BFD_MANAGER_GENERATE_ADDRESSES)
			if (nDataSymbols && DataSymbols)
			{
				for (s = 0; s < symcount; s++)
				{
					symbol_info syminfo;
					bfd_get_symbol_info (bfdImage, bfdSymbols[s], &syminfo);
					if (((bfdSymbols[s]->flags & BSF_DEBUGGING) == 0) &&
					    (syminfo.type == 'R' || syminfo.type == 'r' || /* read-only data */
					    syminfo.type == 'B' || syminfo.type == 'b' || /* uninited data */
					    syminfo.type == 'G' || syminfo.type == 'g' || /* inited data */ 
					    syminfo.type == 'C')) /* common data*/
					{
						unsigned long long sz = 0;
						if (bfd_get_flavour(bfdImage) == bfd_target_elf_flavour)
							sz = ((elf_symbol_type*) bfdSymbols[s])->internal_elf_sym.st_size;

						DataSyms = (data_symbol_t*) realloc (DataSyms, sizeof(data_symbol_t)*(nDataSyms+1));
						if (DataSyms == NULL)
							FATAL_ERROR ("Cannot allocate memory to allocate data symbols\n");
						DataSyms[nDataSyms].name = strdup (syminfo.name);
						DataSyms[nDataSyms].address = (void*) syminfo.value;
						DataSyms[nDataSyms].size = sz;
						nDataSyms++;
					}
				}

				*nDataSymbols = nDataSyms;
				*DataSymbols = DataSyms;
			}
# endif
#endif

			if (symcount < 0) 
			{
				/* There aren't symbols! */
				const char *errmsg = bfd_errmsg( bfd_get_error() );
				fprintf(stderr, "mpi2prv: WARNING! Cannot read symbol table for file '%s' : %s\n"
		                "         Addresses will not be translated into source code references\n",
				  file, errmsg);
			}
		}
	}

	*image = bfdImage;
	*symbols = bfdSymbols;

#if defined(DEBUG)
	printf ("BFD file=%s bfdImage = %p bfdSymbols = %p\n",
	  file, bfdImage, bfdSymbols);
#endif

}