summaryrefslogtreecommitdiffstats
path: root/libelf
diff options
context:
space:
mode:
authorRoland McGrath <[email protected]>2007-09-27 07:31:33 +0000
committerRoland McGrath <[email protected]>2007-09-27 07:31:33 +0000
commitc76f0b05676f6207affbfd85e75063db3b6eeccf (patch)
tree8ccc124a5908a03d34113a7dcdeb2abad7d71522 /libelf
parentcb6d865011ad98a8ac2018f072f396a2268739ca (diff)
2007-09-27 Roland McGrath <[email protected]>
* alpha_retval.c: Use dwarf_attr_integrate and dwarf_hasattr_integrate. * i386_retval.c: Likewise. * ia64_retval.c: Likewise. * ppc64_retval.c: Likewise. * ppc_retval.c: Likewise. * s390_retval.c: Likewise. * sparc_retval.c: Likewise. * x86_64_retval.c: Likewise.
Diffstat (limited to 'libelf')
-rw-r--r--libelf/ChangeLog15
-rw-r--r--libelf/Makefile.am3
-rw-r--r--libelf/elf_getdata.c4
-rw-r--r--libelf/gelf.h8
-rw-r--r--libelf/gelf_getnote.c119
-rw-r--r--libelf/gelf_xlate.c3
-rw-r--r--libelf/libelf.map1
-rw-r--r--libelf/libelfP.h3
-rw-r--r--libelf/note_xlate.h80
9 files changed, 233 insertions, 3 deletions
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 4962c30a..c879aede 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,18 @@
+2007-08-24 Roland McGrath <[email protected]>
+
+ * gelf_getnote.c: New file.
+ * Makefile.am (libelf_a_SOURCES): Add it.
+ * gelf.h: Declare gelf_getnote.
+ * libelf.map (ELFUTILS_1.3): Add gelf_getnote.
+
+ * libelfP.h (NOTE_ALIGN): New macro.
+ * note_xlate.h: New file.
+ * Makefile.am (noinst_HEADERS): Add it.
+ * gelf_xlate.c: Include it.
+ (__elf_xfctstom): Use elf_cvt_note.
+ * elf_getdata.c (shtype_map, __libelf_type_align): Handle SHT_NOTE.
+ (__libelf_set_rawdata): Likewise.
+
2007-08-19 Roland McGrath <[email protected]>
* gelf_update_auxv.c: New file.
diff --git a/libelf/Makefile.am b/libelf/Makefile.am
index 3e8322e9..3e52bcec 100644
--- a/libelf/Makefile.am
+++ b/libelf/Makefile.am
@@ -84,6 +84,7 @@ libelf_a_SOURCES = elf_version.c elf_hash.c elf_error.c elf_fill.c \
gelf_getmove.c gelf_update_move.c \
gelf_getsyminfo.c gelf_update_syminfo.c \
gelf_getauxv.c gelf_update_auxv.c \
+ gelf_getnote.c \
gelf_xlatetof.c gelf_xlatetom.c \
nlist.c \
gelf_getsymshndx.c gelf_update_symshndx.c \
@@ -133,7 +134,7 @@ uninstall: uninstall-am
endif
noinst_HEADERS = elf.h abstract.h common.h exttypes.h gelf_xlate.h libelfP.h \
- version_xlate.h gnuhash_xlate.h dl-hash.h
+ version_xlate.h gnuhash_xlate.h note_xlate.h dl-hash.h
EXTRA_DIST = libelf.map
CLEANFILES = $(am_libelf_pic_a_OBJECTS) *.gcno *.gcda libelf.so.$(VERSION)
diff --git a/libelf/elf_getdata.c b/libelf/elf_getdata.c
index 9d4b83e4..ae5b41df 100644
--- a/libelf/elf_getdata.c
+++ b/libelf/elf_getdata.c
@@ -86,6 +86,7 @@ static const Elf_Type shtype_map[EV_NUM - 1][TYPEIDX (SHT_HISUNW) + 1] =
[SHT_PREINIT_ARRAY] = ELF_T_ADDR,
[SHT_GROUP] = ELF_T_WORD,
[SHT_SYMTAB_SHNDX] = ELF_T_WORD,
+ [SHT_NOTE] = ELF_T_NHDR,
[TYPEIDX (SHT_GNU_verdef)] = ELF_T_VDEF,
[TYPEIDX (SHT_GNU_verneed)] = ELF_T_VNEED,
[TYPEIDX (SHT_GNU_versym)] = ELF_T_HALF,
@@ -116,6 +117,7 @@ const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM]
[ELF_T_VNAUX] = __alignof__ (ElfW2(Bits,Vernaux)), \
[ELF_T_MOVE] = __alignof__ (ElfW2(Bits,Move)), \
[ELF_T_LIB] = __alignof__ (ElfW2(Bits,Lib)), \
+ [ELF_T_NHDR] = __alignof__ (ElfW2(Bits,Nhdr)), \
}
[EV_CURRENT - 1] =
{
@@ -238,7 +240,7 @@ __libelf_set_rawdata (Elf_Scn *scn)
else
{
Elf_Type t = shtype_map[LIBELF_EV_IDX][TYPEIDX (type)];
- if (t == ELF_T_VDEF
+ if (t == ELF_T_VDEF || t == ELF_T_NHDR
|| (t == ELF_T_GNUHASH && elf->class == ELFCLASS64))
entsize = 1;
else
diff --git a/libelf/gelf.h b/libelf/gelf.h
index b985c1c0..9f81b7e9 100644
--- a/libelf/gelf.h
+++ b/libelf/gelf.h
@@ -335,6 +335,14 @@ extern GElf_auxv_t *gelf_getauxv (Elf_Data *__data, int __ndx,
extern int gelf_update_auxv (Elf_Data *__data, int __ndx, GElf_auxv_t *__src);
+/* Get note header at the given offset into the data, and the offsets of
+ the note's name and descriptor data. Returns the offset of the next
+ note header, or 0 for an invalid offset or corrupt note header. */
+extern size_t gelf_getnote (Elf_Data *__data, size_t __offset,
+ GElf_Nhdr *__result,
+ size_t *__name_offset, size_t *__desc_offset);
+
+
/* Retrieve uninterpreted chunk of the file contents. */
extern char *gelf_rawchunk (Elf *__elf, GElf_Off __offset, GElf_Word __size);
diff --git a/libelf/gelf_getnote.c b/libelf/gelf_getnote.c
new file mode 100644
index 00000000..e4900185
--- /dev/null
+++ b/libelf/gelf_getnote.c
@@ -0,0 +1,119 @@
+/* Get note information at the supplied offset.
+ Copyright (C) 2007 Red Hat, Inc.
+ This file is part of Red Hat elfutils.
+
+ Red Hat elfutils is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by the
+ Free Software Foundation; version 2 of the License.
+
+ Red Hat elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with Red Hat elfutils; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
+
+ In addition, as a special exception, Red Hat, Inc. gives You the
+ additional right to link the code of Red Hat elfutils with code licensed
+ under any Open Source Initiative certified open source license
+ (http://www.opensource.org/licenses/index.php) which requires the
+ distribution of source code with any binary distribution and to
+ distribute linked combinations of the two. Non-GPL Code permitted under
+ this exception must only link to the code of Red Hat elfutils through
+ those well defined interfaces identified in the file named EXCEPTION
+ found in the source code files (the "Approved Interfaces"). The files
+ of Non-GPL Code may instantiate templates or use macros or inline
+ functions from the Approved Interfaces without causing the resulting
+ work to be covered by the GNU General Public License. Only Red Hat,
+ Inc. may make changes or additions to the list of Approved Interfaces.
+ Red Hat's grant of this exception is conditioned upon your not adding
+ any new exceptions. If you wish to add a new Approved Interface or
+ exception, please contact Red Hat. You must obey the GNU General Public
+ License in all respects for all of the Red Hat elfutils code and other
+ code used in conjunction with Red Hat elfutils except the Non-GPL Code
+ covered by this exception. If you modify this file, you may extend this
+ exception to your version of the file, but you are not obligated to do
+ so. If you do not wish to provide this exception without modification,
+ you must delete this exception statement from your version and license
+ this file solely under the GPL without exception.
+
+ Red Hat elfutils is an included package of the Open Invention Network.
+ An included package of the Open Invention Network is a package for which
+ Open Invention Network licensees cross-license their patents. No patent
+ license is granted, either expressly or impliedly, by designation as an
+ included package. Should you wish to participate in the Open Invention
+ Network licensing program, please visit www.openinventionnetwork.com
+ <http://www.openinventionnetwork.com>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+size_t
+gelf_getnote (data, offset, result, name_offset, desc_offset)
+ Elf_Data *data;
+ size_t offset;
+ GElf_Nhdr *result;
+ size_t *name_offset;
+ size_t *desc_offset;
+{
+ if (data == NULL)
+ return 0;
+
+ if (unlikely (data->d_type != ELF_T_NHDR))
+ {
+ __libelf_seterrno (ELF_E_INVALID_HANDLE);
+ return 0;
+ }
+
+ /* It's easy to handle this type. It has the same size for 32 and
+ 64 bit objects. */
+ assert (sizeof (GElf_Nhdr) == sizeof (Elf32_Nhdr));
+ assert (sizeof (GElf_Nhdr) == sizeof (Elf64_Nhdr));
+
+ rwlock_rdlock (((Elf_Data_Scn *) data)->s->elf->lock);
+
+ /* The data is already in the correct form. Just make sure the
+ offset is OK. */
+ if (unlikely (offset + sizeof (GElf_Nhdr) > data->d_size))
+ {
+ __libelf_seterrno (ELF_E_OFFSET_RANGE);
+ offset = 0;
+ }
+ else
+ {
+ const GElf_Nhdr *n = data->d_buf + offset;
+ offset += sizeof *n;
+
+ GElf_Word namesz = NOTE_ALIGN (n->n_namesz);
+ GElf_Word descsz = NOTE_ALIGN (n->n_descsz);
+
+ if (unlikely (data->d_size - offset < namesz))
+ offset = 0;
+ else
+ {
+ *name_offset = offset;
+ offset += namesz;
+ if (unlikely (data->d_size - offset < descsz))
+ offset = 0;
+ else
+ {
+ *desc_offset = offset;
+ offset += descsz;
+ *result = *n;
+ }
+ }
+ }
+
+ rwlock_unlock (((Elf_Data_Scn *) data)->s->elf->lock);
+
+ return offset;
+}
diff --git a/libelf/gelf_xlate.c b/libelf/gelf_xlate.c
index 080474fd..a4134c30 100644
--- a/libelf/gelf_xlate.c
+++ b/libelf/gelf_xlate.c
@@ -185,6 +185,7 @@ union unaligned
do not contain records of only one type. */
#include "version_xlate.h"
#include "gnuhash_xlate.h"
+#include "note_xlate.h"
/* Now the externally visible table with the function pointers. */
@@ -213,7 +214,7 @@ const xfct_t __elf_xfctstom[EV_NUM - 1][EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM]
[ELF_T_VDAUX] = elf_cvt_Verdef, \
[ELF_T_VNEED] = elf_cvt_Verneed, \
[ELF_T_VNAUX] = elf_cvt_Verneed, \
- [ELF_T_NHDR] = ElfW2(Bits, cvt_Nhdr), \
+ [ELF_T_NHDR] = elf_cvt_note, \
[ELF_T_SYMINFO] = ElfW2(Bits, cvt_Syminfo), \
[ELF_T_MOVE] = ElfW2(Bits, cvt_Move), \
[ELF_T_LIB] = ElfW2(Bits, cvt_Lib), \
diff --git a/libelf/libelf.map b/libelf/libelf.map
index bc597c6f..9453c438 100644
--- a/libelf/libelf.map
+++ b/libelf/libelf.map
@@ -122,4 +122,5 @@ ELFUTILS_1.3 {
global:
gelf_getauxv;
gelf_update_auxv;
+ gelf_getnote;
};
diff --git a/libelf/libelfP.h b/libelf/libelfP.h
index f06252d7..291206ca 100644
--- a/libelf/libelfP.h
+++ b/libelf/libelfP.h
@@ -574,4 +574,7 @@ extern uint32_t __libelf_crc32 (uint32_t crc, unsigned char *buf, size_t len)
} \
} while (0)
+/* Align offset to 4 bytes as needed for note name and descriptor data. */
+#define NOTE_ALIGN(n) (((n) + 3) & -4U)
+
#endif /* libelfP.h */
diff --git a/libelf/note_xlate.h b/libelf/note_xlate.h
new file mode 100644
index 00000000..6e8b78c6
--- /dev/null
+++ b/libelf/note_xlate.h
@@ -0,0 +1,80 @@
+/* Conversion functions for notes.
+ Copyright (C) 2007 Red Hat, Inc.
+ This file is part of Red Hat elfutils.
+
+ Red Hat elfutils is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by the
+ Free Software Foundation; version 2 of the License.
+
+ Red Hat elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with Red Hat elfutils; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
+
+ In addition, as a special exception, Red Hat, Inc. gives You the
+ additional right to link the code of Red Hat elfutils with code licensed
+ under any Open Source Initiative certified open source license
+ (http://www.opensource.org/licenses/index.php) which requires the
+ distribution of source code with any binary distribution and to
+ distribute linked combinations of the two. Non-GPL Code permitted under
+ this exception must only link to the code of Red Hat elfutils through
+ those well defined interfaces identified in the file named EXCEPTION
+ found in the source code files (the "Approved Interfaces"). The files
+ of Non-GPL Code may instantiate templates or use macros or inline
+ functions from the Approved Interfaces without causing the resulting
+ work to be covered by the GNU General Public License. Only Red Hat,
+ Inc. may make changes or additions to the list of Approved Interfaces.
+ Red Hat's grant of this exception is conditioned upon your not adding
+ any new exceptions. If you wish to add a new Approved Interface or
+ exception, please contact Red Hat. You must obey the GNU General Public
+ License in all respects for all of the Red Hat elfutils code and other
+ code used in conjunction with Red Hat elfutils except the Non-GPL Code
+ covered by this exception. If you modify this file, you may extend this
+ exception to your version of the file, but you are not obligated to do
+ so. If you do not wish to provide this exception without modification,
+ you must delete this exception statement from your version and license
+ this file solely under the GPL without exception.
+
+ Red Hat elfutils is an included package of the Open Invention Network.
+ An included package of the Open Invention Network is a package for which
+ Open Invention Network licensees cross-license their patents. No patent
+ license is granted, either expressly or impliedly, by designation as an
+ included package. Should you wish to participate in the Open Invention
+ Network licensing program, please visit www.openinventionnetwork.com
+ <http://www.openinventionnetwork.com>. */
+
+static void
+elf_cvt_note (void *dest, const void *src, size_t len, int encode)
+{
+ assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr));
+
+ while (len > 0)
+ {
+ (1 ? Elf32_cvt_Nhdr : Elf64_cvt_Nhdr) (dest, src, sizeof (Elf32_Nhdr),
+ encode);
+ const Elf32_Nhdr *n = encode ? src : dest;
+ Elf32_Word namesz = NOTE_ALIGN (n->n_namesz);
+ Elf32_Word descsz = NOTE_ALIGN (n->n_descsz);
+
+ len -= sizeof *n;
+ src += sizeof *n;
+ dest += sizeof *n;
+
+ if (namesz > len)
+ break;
+ len -= namesz;
+ if (descsz > len)
+ break;
+ len -= descsz;
+
+ if (src != dest)
+ memcpy (dest, src, namesz + descsz);
+
+ src += namesz + descsz;
+ dest += namesz + descsz;
+ }
+}