summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2011-04-24 17:53:38 +0200
committerMark Wielaard <mjw@redhat.com>2011-04-26 14:15:27 +0200
commitbb9d1b4bf225a604ceb69130f5a54a66f95b525d (patch)
treea5b40850d9404510d6e56f26240d18073979895c
parented52618203ac78179e3a0cf36db5bdca8958da1d (diff)
downloadandroid_external_elfutils-bb9d1b4bf225a604ceb69130f5a54a66f95b525d.tar.gz
android_external_elfutils-bb9d1b4bf225a604ceb69130f5a54a66f95b525d.tar.bz2
android_external_elfutils-bb9d1b4bf225a604ceb69130f5a54a66f95b525d.zip
Add support for printing SDT elf notes.
libebl/ * libebl.h (ebl_object_note_type_name): Add const char *name arg. * eblhooks.h (object_note_type_name): Likewise. * eblopenbackend.c (default_object_note_type_name): Likewise. * eblobjnotetypename.c (ebl_object_note_type_name): Likewise. And print version if name is "stapsdt". * eblobjnote.c (ebl_object_note): Add output for "stapsdt" notes. src/ * readelf.c (handle_notes_data): Call ebl_object_note_type_name with note name.
-rw-r--r--libebl/ChangeLog9
-rw-r--r--libebl/ebl-hooks.h3
-rw-r--r--libebl/eblobjnote.c90
-rw-r--r--libebl/eblobjnotetypename.c14
-rw-r--r--libebl/eblopenbackend.c7
-rw-r--r--libebl/libebl.h5
-rw-r--r--src/ChangeLog5
-rw-r--r--src/readelf.c2
8 files changed, 124 insertions, 11 deletions
diff --git a/libebl/ChangeLog b/libebl/ChangeLog
index 97315f00..ac2160de 100644
--- a/libebl/ChangeLog
+++ b/libebl/ChangeLog
@@ -1,3 +1,12 @@
+2011-04-26 Mark Wielaard <mjw@redhat.com>
+
+ * libebl.h (ebl_object_note_type_name): Add const char *name arg.
+ * eblhooks.h (object_note_type_name): Likewise.
+ * eblopenbackend.c (default_object_note_type_name): Likewise.
+ * eblobjnotetypename.c (ebl_object_note_type_name): Likewise.
+ And print version if name is "stapsdt".
+ * eblobjnote.c (ebl_object_note): Add output for "stapsdt" notes.
+
2011-03-21 Marek Polacek <mpolacek@redhat.com>
* ebldynamictagname.c: Fix typo in TLSDESC_GOT.
diff --git a/libebl/ebl-hooks.h b/libebl/ebl-hooks.h
index 82c6c640..a04b3db0 100644
--- a/libebl/ebl-hooks.h
+++ b/libebl/ebl-hooks.h
@@ -111,7 +111,8 @@ const char *EBLHOOK(osabi_name) (int, char *, size_t);
const char *EBLHOOK(core_note_type_name) (uint32_t, char *, size_t);
/* Name of a note entry type for object files. */
-const char *EBLHOOK(object_note_type_name) (uint32_t, char *, size_t);
+const char *EBLHOOK(object_note_type_name) (const char *, uint32_t,
+ char *, size_t);
/* Describe core note format. */
int EBLHOOK(core_note) (const GElf_Nhdr *, const char *,
diff --git a/libebl/eblobjnote.c b/libebl/eblobjnote.c
index b56c6cbc..ec5bb7da 100644
--- a/libebl/eblobjnote.c
+++ b/libebl/eblobjnote.c
@@ -1,5 +1,5 @@
/* Print contents of object file note.
- Copyright (C) 2002, 2007, 2009 Red Hat, Inc.
+ Copyright (C) 2002, 2007, 2009, 2011 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -68,6 +68,94 @@ ebl_object_note (ebl, name, type, descsz, desc)
{
if (! ebl->object_note (name, type, descsz, desc))
/* The machine specific function did not know this type. */
+
+ if (strcmp ("stapsdt", name) == 0)
+ {
+ if (type != 3)
+ {
+ printf (gettext ("unknown SDT version %u\n"), type);
+ return;
+ }
+
+ /* Descriptor starts with three addresses, pc, base ref and
+ semaphore. Then three zero terminated strings provider,
+ name and arguments. */
+
+ union
+ {
+ Elf64_Addr a64[3];
+ Elf32_Addr a32[3];
+ } addrs;
+
+ size_t addrs_size = gelf_fsize (ebl->elf, ELF_T_ADDR, 3, EV_CURRENT);
+ if (descsz < addrs_size + 3)
+ {
+ invalid_sdt:
+ printf (gettext ("invalid SDT probe descriptor\n"));
+ return;
+ }
+
+ Elf_Data src =
+ {
+ .d_type = ELF_T_ADDR, .d_version = EV_CURRENT,
+ .d_buf = (void *) desc, .d_size = addrs_size
+ };
+
+ Elf_Data dst =
+ {
+ .d_type = ELF_T_ADDR, .d_version = EV_CURRENT,
+ .d_buf = &addrs, .d_size = addrs_size
+ };
+
+ if (gelf_xlatetom (ebl->elf, &dst, &src,
+ elf_getident (ebl->elf, NULL)[EI_DATA]) == NULL)
+ {
+ printf ("%s\n", elf_errmsg (-1));
+ return;
+ }
+
+ const char *provider = desc + addrs_size;
+ const char *pname = memchr (provider, '\0', desc + descsz - provider);
+ if (pname == NULL)
+ goto invalid_sdt;
+
+ ++pname;
+ const char *args = memchr (pname, '\0', desc + descsz - pname);
+ if (args == NULL ||
+ memchr (++args, '\0', desc + descsz - pname) != desc + descsz - 1)
+ goto invalid_sdt;
+
+ GElf_Addr pc;
+ GElf_Addr base;
+ GElf_Addr sem;
+ if (gelf_getclass (ebl->elf) == ELFCLASS32)
+ {
+ pc = addrs.a32[0];
+ base = addrs.a32[1];
+ sem = addrs.a32[2];
+ }
+ else
+ {
+ pc = addrs.a64[0];
+ base = addrs.a64[1];
+ sem = addrs.a64[2];
+ }
+
+ printf (gettext (" PC: "));
+ printf ("%#" PRIx64 ",", pc);
+ printf (gettext (" Base: "));
+ printf ("%#" PRIx64 ",", base);
+ printf (gettext (" Semaphore: "));
+ printf ("%#" PRIx64 "\n", sem);
+ printf (gettext (" Provider: "));
+ printf ("%s,", provider);
+ printf (gettext (" Name: "));
+ printf ("%s,", pname);
+ printf (gettext (" Args: "));
+ printf ("'%s'\n", args);
+ return;
+ }
+
switch (type)
{
case NT_GNU_BUILD_ID:
diff --git a/libebl/eblobjnotetypename.c b/libebl/eblobjnotetypename.c
index 8e99dbb4..0ceb5a87 100644
--- a/libebl/eblobjnotetypename.c
+++ b/libebl/eblobjnotetypename.c
@@ -1,5 +1,5 @@
/* Return note type name.
- Copyright (C) 2002, 2007, 2009 Red Hat, Inc.
+ Copyright (C) 2002, 2007, 2009, 2011 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -54,20 +54,28 @@
#include <inttypes.h>
#include <stdio.h>
+#include <string.h>
#include <libeblP.h>
const char *
-ebl_object_note_type_name (ebl, type, buf, len)
+ebl_object_note_type_name (ebl, name, type, buf, len)
Ebl *ebl;
+ const char *name;
uint32_t type;
char *buf;
size_t len;
{
- const char *res = ebl->object_note_type_name (type, buf, len);
+ const char *res = ebl->object_note_type_name (name, type, buf, len);
if (res == NULL)
{
+ if (strcmp (name, "stapsdt") == 0)
+ {
+ snprintf (buf, len, "Version: %" PRIu32, type);
+ return buf;
+ }
+
static const char *knowntypes[] =
{
#define KNOWNSTYPE(name) [NT_##name] = #name
diff --git a/libebl/eblopenbackend.c b/libebl/eblopenbackend.c
index 24f472ce..60e7f84a 100644
--- a/libebl/eblopenbackend.c
+++ b/libebl/eblopenbackend.c
@@ -184,8 +184,8 @@ static const char *default_osabi_name (int ignore, char *buf, size_t len);
static void default_destr (struct ebl *ignore);
static const char *default_core_note_type_name (uint32_t, char *buf,
size_t len);
-static const char *default_object_note_type_name (uint32_t, char *buf,
- size_t len);
+static const char *default_object_note_type_name (const char *name, uint32_t,
+ char *buf, size_t len);
static int default_core_note (const GElf_Nhdr *nhdr, const char *name,
GElf_Word *regs_offset, size_t *nregloc,
const Ebl_Register_Location **reglocs,
@@ -619,7 +619,8 @@ default_core_note (const GElf_Nhdr *nhdr __attribute__ ((unused)),
}
static const char *
-default_object_note_type_name (uint32_t ignore __attribute__ ((unused)),
+default_object_note_type_name (const char *name __attribute__ ((unused)),
+ uint32_t ignore __attribute__ ((unused)),
char *buf __attribute__ ((unused)),
size_t len __attribute__ ((unused)))
{
diff --git a/libebl/libebl.h b/libebl/libebl.h
index b4307282..3a334024 100644
--- a/libebl/libebl.h
+++ b/libebl/libebl.h
@@ -184,8 +184,9 @@ extern const char *ebl_core_note_type_name (Ebl *ebl, uint32_t type, char *buf,
size_t len);
/* Return name of the note section type for an object file. */
-extern const char *ebl_object_note_type_name (Ebl *ebl, uint32_t type,
- char *buf, size_t len);
+extern const char *ebl_object_note_type_name (Ebl *ebl, const char *name,
+ uint32_t type, char *buf,
+ size_t len);
/* Print information about object note if available. */
extern void ebl_object_note (Ebl *ebl, const char *name, uint32_t type,
diff --git a/src/ChangeLog b/src/ChangeLog
index 956cce2a..290bf129 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+2011-04-26 Mark Wielaard <mjw@redhat.com>
+
+ * readelf.c (handle_notes_data): Call ebl_object_note_type_name
+ with note name.
+
2011-03-24 Petr Machata <pmachata@redhat.com>
* readelf.c (print_debug_line_section): Emit initial space for all
diff --git a/src/readelf.c b/src/readelf.c
index f2c48007..efc3571c 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -7904,7 +7904,7 @@ handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
ehdr->e_type == ET_CORE
? ebl_core_note_type_name (ebl, nhdr.n_type,
buf, sizeof (buf))
- : ebl_object_note_type_name (ebl, nhdr.n_type,
+ : ebl_object_note_type_name (ebl, name, nhdr.n_type,
buf2, sizeof (buf2)));
/* Filter out invalid entries. */