From: Mark Wielaard Date: Sun, 24 Apr 2011 15:53:38 +0000 (+0200) Subject: Add support for printing SDT elf notes. X-Git-Tag: elfutils-0.153~46^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=bb9d1b4bf225a604ceb69130f5a54a66f95b525d;p=thirdparty%2Felfutils.git 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. --- diff --git a/libebl/ChangeLog b/libebl/ChangeLog index 97315f008..ac2160de9 100644 --- a/libebl/ChangeLog +++ b/libebl/ChangeLog @@ -1,3 +1,12 @@ +2011-04-26 Mark Wielaard + + * 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 * ebldynamictagname.c: Fix typo in TLSDESC_GOT. diff --git a/libebl/ebl-hooks.h b/libebl/ebl-hooks.h index 82c6c6400..a04b3db01 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 b56c6cbc0..ec5bb7daf 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 , 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 8e99dbb41..0ceb5a87a 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 , 2002. @@ -54,20 +54,28 @@ #include #include +#include #include 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 24f472ce3..60e7f84a5 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 b4307282d..3a3340242 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 956cce2a5..290bf1296 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2011-04-26 Mark Wielaard + + * readelf.c (handle_notes_data): Call ebl_object_note_type_name + with note name. + 2011-03-24 Petr Machata * readelf.c (print_debug_line_section): Emit initial space for all diff --git a/src/readelf.c b/src/readelf.c index f2c48007f..efc3571c5 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. */