This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC PATCH] Synthetize some symbols for objdump -d


On Wed, Apr 21, 2004 at 07:17:37AM +0200, Jakub Jelinek wrote:
> On Wed, Apr 21, 2004 at 01:15:51PM +0930, Alan Modra wrote:
> > I think it would be a good idea to define a backend function to process
> > each plt reloc.  Given a pointer to the plt section, and a pointer to
> > the reloc, it could return the value of the sym or -1 if the reloc
> > should be ignored.  That should be general enough to work even with
> > something like the sparc plt, and you won't need plt_entry_size or
> > reserved_plt_size.
> 
> I'll rework the patch so that the backend function is called in the loop
> for each PLT, not to handle everything.
> I still think plt_entry_size/reserved_plt_size is needed, adding the same
> routine on 15 targets which have fixed size PLT entries seems unnecessary
> to me.  Wouldn't a comment stating that they should be set only if the
> target has fixed size PLT entries and left out (== 0) otherwise be enough?

Well, the function will just look like:

static bfd_vma
plt_sym_val (bfd_vma plt_indx,
	     const asection *plt,
	     const arelent *rel ATTRIBUTE_UNUSED)
{
  return plt_indx * PLT_ENTRY_SIZE + PLT_FIRST_ENTRY_SIZE + plt->vma;
}

modulo variations in the macro names.  I think it's cleaner to duplicate
a small function like this in each backend rather than trying to make
the generic code clever.

long
_bfd_elf_create_synthetic_symtab (bfd *abfd, asymbol **dynsyms, asymbol **ret)
{
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  asection *relplt;
  asymbol *s;
  const char *relplt_name;
  bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
  arelent *p;
  long count, i, n;
  size_t size;
  Elf_Internal_Shdr *hdr;
  char *names;
  asection *plt;

  *ret = NULL;                                 
  if (!bed->plt_sym_val)
    return 0;

  relplt_name = bed->relplt_name;
  if (relplt_name == NULL)
    relplt_name = bed->default_use_rela_p ? ".rela.plt" : ".rel.plt";
  relplt = bfd_get_section_by_name (abfd, relplt_name);
  if (relplt == NULL)
    return 0;

  hdr = &elf_section_data (relplt)->this_hdr;
  if (hdr->sh_link != elf_dynsymtab (abfd)
      || (hdr->sh_type != SHT_REL && hdr->sh_type != SHT_RELA))
    return 0;

  plt = bfd_get_section_by_name (abfd, ".plt");
  if (plt == NULL)
    return 0;

  slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
  if (! (*slurp_relocs) (abfd, relplt, dynsyms, TRUE))
    return -1;

  count = relplt->_raw_size / hdr->sh_entsize;
  size = count * sizeof (asymbol);
  p = relplt->relocation;
  for (i = 0; i < count; i++, s++, p++)
    size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");

  s = *ret = bfd_malloc (size);
  if (s == NULL)
    return -1;

  names = (char *) (s + count);
  p = relplt->relocation;
  n = 0;
  for (i = 0; i < count; i++, s++, p++)
    {
      size_t len;
      bfd_vma addr;

      addr = bed->plt_sym_val (i, plt, p);
      if (addr == (bfd_vma) -1)
	continue;

      *s = **p->sym_ptr_ptr;
      s->section = plt;
      s->value = addr;
      s->name = names;
      len = strlen ((*p->sym_ptr_ptr)->name);
      memcpy (names, (*p->sym_ptr_ptr)->name, len);
      names += len;
      memcpy (names, "@plt", sizeof ("@plt"));
      names += sizeof ("@plt");
      ++n;
    }

  return n;
}


-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]