Ejemplo n.º 1
0
static bfd_boolean
s390_elf_create_ifunc_sections (bfd *abfd, struct bfd_link_info *info)
{
  flagword flags;
  asection *s;
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  struct elf_link_hash_table *htab = elf_hash_table (info);

  if (htab->iplt != NULL)
    return TRUE;

  flags = bed->dynamic_sec_flags;

  if (bfd_link_pic (info))
    {
      s = bfd_make_section_with_flags (abfd, ".rela.ifunc",
				       flags | SEC_READONLY);
      if (s == NULL
	  || ! bfd_set_section_alignment (abfd, s,
					  bed->s->log_file_align))
	return FALSE;
      htab->irelifunc = s;
    }

  /* Create .iplt, .rel[a].iplt, and .igot.plt.  */
  s = bfd_make_section_with_flags (abfd, ".iplt",
				   flags | SEC_CODE | SEC_READONLY);
  if (s == NULL
      || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
    return FALSE;
  htab->iplt = s;

  s = bfd_make_section_with_flags (abfd, ".rela.iplt", flags | SEC_READONLY);
  if (s == NULL
      || ! bfd_set_section_alignment (abfd, s,
				      bed->s->log_file_align))
    return FALSE;
  htab->irelplt = s;

  s = bfd_make_section_with_flags (abfd, ".igot.plt", flags);
  if (s == NULL
      || !bfd_set_section_alignment (abfd, s,
				     bed->s->log_file_align))
    return FALSE;
  htab->igotplt = s;

  return TRUE;
}
Ejemplo n.º 2
0
static asection *
make_bfd_asection (bfd *abfd,
		   const char *name,
		   flagword flags,
		   bfd_size_type size,
		   bfd_vma vma,
		   file_ptr filepos)
{
  asection *asect;
  char *newname;

  newname = bfd_alloc (abfd, (bfd_size_type) strlen (name) + 1);
  if (!newname)
    return NULL;

  strcpy (newname, name);

  asect = bfd_make_section_with_flags (abfd, newname, flags);
  if (!asect)
    return NULL;

  asect->size = size;
  asect->vma = vma;
  asect->filepos = filepos;
  asect->alignment_power = 2;

  return asect;
}
Ejemplo n.º 3
0
/* Write resource file */
void
write_res_file (const char *fn,const rc_res_directory *resdir)
{
    asection *sec;
    rc_uint_type language;
    bfd *abfd;
    windres_bfd wrbfd;
    unsigned long sec_length = 0,sec_length_wrote;
    static const bfd_byte sign[] =
    {   0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };

    filename = fn;

    abfd = windres_open_as_binary (filename, 0);
    sec = bfd_make_section_with_flags (abfd, ".data",
                                       (SEC_HAS_CONTENTS | SEC_ALLOC
                                        | SEC_LOAD | SEC_DATA));
    if (sec == NULL)
        bfd_fatal ("bfd_make_section");
    /* Requiring this is probably a bug in BFD.  */
    sec->output_section = sec;

    set_windres_bfd (&wrbfd, abfd, sec,
                     (target_is_bigendian ? WR_KIND_BFD_BIN_B
                      : WR_KIND_BFD_BIN_L));

    language = -1;
    sec_length = write_res_directory ((windres_bfd *) NULL, 0x20UL, resdir,
                                      (const rc_res_id *) NULL,
                                      (const rc_res_id *) NULL, &language, 1);
    if (! bfd_set_section_size (abfd, sec, (sec_length + 3) & ~3))
        bfd_fatal ("bfd_set_section_size");
    if ((sec_length & 3) != 0)
        set_windres_bfd_content (&wrbfd, sign, sec_length, 4-(sec_length & 3));
    set_windres_bfd_content (&wrbfd, sign, 0, sizeof (sign));
    language = -1;
    sec_length_wrote = write_res_directory (&wrbfd, 0x20UL, resdir,
                                            (const rc_res_id *) NULL,
                                            (const rc_res_id *) NULL,
                                            &language, 1);
    if (sec_length != sec_length_wrote)
        fatal ("res write failed with different sizes (%lu/%lu).",
               (unsigned long) sec_length, (unsigned long) sec_length_wrote);

    bfd_close (abfd);
    return;
}
Ejemplo n.º 4
0
static asection *
make_bfd_asection (bfd *abfd,
		   const char *name,
		   flagword flags,
		   bfd_size_type size,
		   file_ptr offset,
		   unsigned int alignment_power)
{
  asection *asect;

  asect = bfd_make_section_with_flags (abfd, name, flags);
  if (!asect)
    return NULL;

  asect->size = size;
  asect->filepos = offset;
  asect->alignment_power = alignment_power;

  return asect;
}
Ejemplo n.º 5
0
static const bfd_target *
aout_adobe_callback (bfd *abfd)
{
  struct internal_exec *execp = exec_hdr (abfd);
  asection *sect;
  struct external_segdesc ext[1];
  char *section_name;
  char try_again[30];	/* Name and number.  */
  char *newname;
  int trynum;
  flagword flags;

  /* Architecture and machine type -- unknown in this format.  */
  bfd_set_arch_mach (abfd, bfd_arch_unknown, 0L);

  /* The positions of the string table and symbol table.  */
  obj_str_filepos (abfd) = N_STROFF (*execp);
  obj_sym_filepos (abfd) = N_SYMOFF (*execp);

  /* Suck up the section information from the file, one section at a time.  */
  for (;;)
    {
      bfd_size_type amt = sizeof (*ext);
      if (bfd_bread ( ext, amt, abfd) != amt)
	{
	  if (bfd_get_error () != bfd_error_system_call)
	    bfd_set_error (bfd_error_wrong_format);

	  return NULL;
	}
      switch (ext->e_type[0])
	{
	case N_TEXT:
	  section_name = ".text";
	  flags = SEC_CODE | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS;
	  break;

	case N_DATA:
	  section_name = ".data";
	  flags = SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS;
	  break;

	case N_BSS:
	  section_name = ".bss";
	  flags = SEC_DATA | SEC_HAS_CONTENTS;
	  break;

	case 0:
	  goto no_more_sections;

	default:
	  (*_bfd_error_handler)
	    (_("%B: Unknown section type in a.out.adobe file: %x\n"),
	     abfd, ext->e_type[0]);
	  goto no_more_sections;
	}

      /* First one is called ".text" or whatever; subsequent ones are
	 ".text1", ".text2", ...  */
      bfd_set_error (bfd_error_no_error);
      sect = bfd_make_section_with_flags (abfd, section_name, flags);
      trynum = 0;

      while (!sect)
	{
	  if (bfd_get_error () != bfd_error_no_error)
	    /* Some other error -- slide into the sunset.  */
	    return NULL;
	  sprintf (try_again, "%s%d", section_name, ++trynum);
	  sect = bfd_make_section_with_flags (abfd, try_again, flags);
	}

      /* Fix the name, if it is a sprintf'd name.  */
      if (sect->name == try_again)
	{
	  amt = strlen (sect->name);
	  newname = bfd_zalloc (abfd, amt);
	  if (newname == NULL)
	    return NULL;
	  strcpy (newname, sect->name);
	  sect->name = newname;
	}

      /* Assumed big-endian.  */
      sect->size = ((ext->e_size[0] << 8)
		    | ext->e_size[1] << 8
		    | ext->e_size[2]);
      sect->vma = H_GET_32 (abfd, ext->e_virtbase);
      sect->filepos = H_GET_32 (abfd, ext->e_filebase);
      /* FIXME XXX alignment?  */

      /* Set relocation information for first section of each type.  */
      if (trynum == 0)
	switch (ext->e_type[0])
	  {
	  case N_TEXT:
	    sect->rel_filepos = N_TRELOFF (*execp);
	    sect->reloc_count = execp->a_trsize;
	    break;

	  case N_DATA:
	    sect->rel_filepos = N_DRELOFF (*execp);
	    sect->reloc_count = execp->a_drsize;
	    break;

	  default:
	    break;
	  }
    }
 no_more_sections:

  adata (abfd).reloc_entry_size = sizeof (struct reloc_std_external);
  adata (abfd).symbol_entry_size = sizeof (struct external_nlist);
  adata (abfd).page_size = 1; /* Not applicable.  */
  adata (abfd).segment_size = 1; /* Not applicable.  */
  adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;

  return abfd->xvec;
}
Ejemplo n.º 6
0
bfd_boolean
_bfd_cgc_create_ifunc_sections (bfd *abfd, struct bfd_link_info *info)
{
  flagword flags, pltflags;
  asection *s;
  const struct cgc_backend_data *bed = get_cgc_backend_data (abfd);
  struct cgc_link_hash_table *htab = cgc_hash_table (info);

  if (htab->irelifunc != NULL || htab->iplt != NULL)
    return TRUE;

  flags = bed->dynamic_sec_flags;
  pltflags = flags;
  if (bed->plt_not_loaded)
    /* We do not clear SEC_ALLOC here because we still want the OS to
       allocate space for the section; it's just that there's nothing
       to read in from the object file.  */
    pltflags &= ~ (SEC_CODE | SEC_LOAD | SEC_HAS_CONTENTS);
  else
    pltflags |= SEC_ALLOC | SEC_CODE | SEC_LOAD;
  if (bed->plt_readonly)
    pltflags |= SEC_READONLY;

  if (info->shared)
    {
      /* We need to create .rel[a].ifunc for shared objects.  */
      const char *rel_sec = (bed->rela_plts_and_copies_p
			     ? ".rela.ifunc" : ".rel.ifunc");

      s = bfd_make_section_with_flags (abfd, rel_sec,
				       flags | SEC_READONLY);
      if (s == NULL
	  || ! bfd_set_section_alignment (abfd, s,
					  bed->s->log_file_align))
	return FALSE;
      htab->irelifunc = s;
    }
  else
    {
      /* We need to create .iplt, .rel[a].iplt, .igot and .igot.plt
	 for static executables.   */
      s = bfd_make_section_with_flags (abfd, ".iplt", pltflags);
      if (s == NULL
	  || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
	return FALSE;
      htab->iplt = s;

      s = bfd_make_section_with_flags (abfd,
				       (bed->rela_plts_and_copies_p
					? ".rela.iplt" : ".rel.iplt"),
				       flags | SEC_READONLY);
      if (s == NULL
	  || ! bfd_set_section_alignment (abfd, s,
					  bed->s->log_file_align))
	return FALSE;
      htab->irelplt = s;

      /* We don't need the .igot section if we have the .igot.plt
	 section.  */
      if (bed->want_got_plt)
	s = bfd_make_section_with_flags (abfd, ".igot.plt", flags);
      else
	s = bfd_make_section_with_flags (abfd, ".igot", flags);
      if (s == NULL
	  || !bfd_set_section_alignment (abfd, s,
					 bed->s->log_file_align))
	return FALSE;
      htab->igotplt = s;
    }

  return TRUE;
}
Ejemplo n.º 7
0
asection *
bfd_make_section (bfd *abfd, const char *name)
{
  return bfd_make_section_with_flags (abfd, name, 0);
}
Ejemplo n.º 8
0
   know the size of the section, but that's OK - we just need to
   create it for now.  */

static bfd_boolean
linux_link_create_dynamic_sections (bfd *abfd,
				    struct bfd_link_info *info ATTRIBUTE_UNUSED)
{
  flagword flags;
  asection *s;

  /* Note that we set the SEC_IN_MEMORY flag.  */
  flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;

  /* We choose to use the name ".linux-dynamic" for the fixup table.
     Why not? */
  s = bfd_make_section_with_flags (abfd, ".linux-dynamic", flags);
  if (s == NULL
      || ! bfd_set_section_alignment (abfd, s, 2))
    return FALSE;
  s->size = 0;
  s->contents = 0;

  return TRUE;
}

/* Function to add a single symbol to the linker hash table.  This is
   a wrapper around _bfd_generic_link_add_one_symbol which handles the
   tweaking needed for dynamic linking support.  */

static bfd_boolean
linux_add_one_symbol (struct bfd_link_info *info,
Ejemplo n.º 9
0
static bfd_boolean
wasm_scan_name_function_section (bfd *abfd, sec_ptr asect)
{
  bfd_byte *p;
  bfd_byte *end;
  bfd_vma payload_size;
  bfd_vma symcount = 0;
  tdata_type *tdata = abfd->tdata.any;
  asymbol *symbols = NULL;
  sec_ptr space_function_index;

  if (! asect)
    return FALSE;

  if (strcmp (asect->name, WASM_NAME_SECTION) != 0)
    return FALSE;

  p = asect->contents;
  end = asect->contents + asect->size;

  if (! p)
    return FALSE;

  while (p < end)
    {
      bfd_byte subsection_code = *p++;
      if (subsection_code == WASM_FUNCTION_SUBSECTION)
	break;

      /* subsection_code is documented to be a varuint7, meaning that
	 it has to be a single byte in the 0 - 127 range.  If it isn't,
	 the spec must have changed underneath us, so give up.  */
      if (subsection_code & 0x80)
	return FALSE;

      READ_LEB128 (payload_size, p, end);

      if (p > p + payload_size)
	return FALSE;

      p += payload_size;
    }

  if (p >= end)
    return FALSE;

  READ_LEB128 (payload_size, p, end);

  if (p > p + payload_size)
    return FALSE;

  if (p + payload_size > end)
    return FALSE;

  end = p + payload_size;

  READ_LEB128 (symcount, p, end);

  /* Sanity check: each symbol has at least two bytes.  */
  if (symcount > payload_size/2)
    return FALSE;

  tdata->symcount = symcount;

  space_function_index = bfd_make_section_with_flags
    (abfd, WASM_SECTION_FUNCTION_INDEX, SEC_READONLY | SEC_CODE);

  if (! space_function_index)
    space_function_index = bfd_get_section_by_name (abfd, WASM_SECTION_FUNCTION_INDEX);

  if (! space_function_index)
    return FALSE;

  symbols = bfd_zalloc (abfd, tdata->symcount * sizeof (asymbol));
  if (! symbols)
    return FALSE;

  for (symcount = 0; p < end && symcount < tdata->symcount; symcount++)
    {
      bfd_vma idx;
      bfd_vma len;
      char *name;
      asymbol *sym;

      READ_LEB128 (idx, p, end);
      READ_LEB128 (len, p, end);

      if (p + len < p || p + len > end)
	goto error_return;

      name = bfd_zalloc (abfd, len + 1);
      if (! name)
	goto error_return;

      memcpy (name, p, len);
      p += len;

      sym = &symbols[symcount];
      sym->the_bfd = abfd;
      sym->name = name;
      sym->value = idx;
      sym->flags = BSF_GLOBAL | BSF_FUNCTION;
      sym->section = space_function_index;
      sym->udata.p = NULL;
    }

  if (symcount < tdata->symcount)
    goto error_return;

  tdata->symbols = symbols;
  abfd->symcount = symcount;

  return TRUE;

 error_return:
  while (symcount)
    bfd_release (abfd, (void *)symbols[--symcount].name);
  bfd_release (abfd, symbols);
  return FALSE;
}