This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
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