This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils 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]

readelf: display syms from .dynamic


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Hi,

I'm trying to add the '-D' option to readelf.  This would fulfil this
old request (binutils readelf already has it):

https://bugzilla.redhat.com/show_bug.cgi?id=444621

It is quite clear that we have to first search for the PT_DYNAMIC segment and
here find relevant DT_ symbols.  Well, this is so far not a problem.  But now
I don't know how to continue.  Let's say we're at DT_HASH symbol--this means, we
can obtain the virtual address of .hash section from d_ptr value.  Ok, we
could probably extract buckets and chains and somehow derive the symbol name,
but this doesn't sound like The Right Thing to do.

The point is to get the GElf_Sym structure filled--preferably with the
gelf_getsymshndx function, then just print the values (we don't need to care
about version infromation).  But it beats me how to use it.  I don't see how
to determine from the content of e.g. .hash which symbols from symtab appear
here.

If you think this effort is not worth it and we actually don't want this
feature, or this would be too dramatic change, just tell me.  Thanks,

	Marek

And here's roughly where I am at:

static void
handle_syms_dyn (Ebl *ebl)
{
  /* Do this exactly once.  */
  static bool dyn_syms_done;

  if (dyn_syms_done)
    return;

  dyn_syms_done = true;

  for (size_t i = 0; i < phnum; ++i)
    {
      GElf_Phdr phdr_mem;
      GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);

	/* Find the dynamic segment.  */
      if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
	{
	  Elf_Data *data = elf_getdata_rawchunk (ebl->elf,
						 phdr->p_offset, phdr->p_filesz,
						 ELF_T_DYN);
	  if (data == NULL)
	    return;

	  const size_t n = data->d_size / gelf_fsize (ebl->elf,
						ELF_T_DYN, 1, EV_CURRENT);
	  for (size_t j = 0; j < n; ++j)
	    {
	      GElf_Dyn dyn_mem;
	      GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem);
	      if (dyn != NULL)
		switch (dyn->d_tag)
		  {
		  case DT_HASH:
		    printf ("DT_HASH: %#lx\n", dyn->d_un.d_ptr);
		    continue;

		  case DT_SYMTAB:
		    printf ("DT_SYMTAB: %#lx\n", dyn->d_un.d_ptr);
		    continue;

		  case DT_GNU_HASH:
		    printf ("DT_GNU_HASH: %#lx\n", dyn->d_un.d_ptr);
		    continue;

		  case DT_STRTAB:
		    printf ("DT_STRTAB: %#lx\n", dyn->d_un.d_ptr);
		    continue;

		  default:
		    continue;

		  case DT_NULL:
		    break;
		  }
	      break;
	    }
	}
    }
}

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.14 (GNU/Linux)

iF4EAREIAAYFAk2aH18ACgkQt3gKtVPE8IIe3gD/X7EuRyaYaT5YProIjrDcv4Wr
YtGHvPbgIVihpfI59ZkBAIQEC7CJRS/TGCf4hvh2dvb4xldPvCETnWMDEBO+0hPr
=YJaK
-----END PGP SIGNATURE-----

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