summaryrefslogtreecommitdiffstats
path: root/libelf
diff options
context:
space:
mode:
authorUlrich Drepper <[email protected]>2008-01-02 17:44:39 +0000
committerUlrich Drepper <[email protected]>2008-01-02 17:44:39 +0000
commit3cbdd387c752999255aea91600b5cfdefbeac7d0 (patch)
tree50c18bd26f8cd31f4c1aa3ce1d78bb98548659ba /libelf
parentad024afc93dcd0f4797b3e80bfb6b80c34da5c12 (diff)
propagate from branch 'com.redhat.elfutils.disasm' (head d15b4eb794e81e477f9896fe82a74cb5ecf4514c)
to branch 'com.redhat.elfutils' (head eaacbf01f8cc89d043ec6eca9b5e35cb5c4cde06)
Diffstat (limited to 'libelf')
-rw-r--r--libelf/ChangeLog11
-rw-r--r--libelf/Makefile.am3
-rw-r--r--libelf/elf32_getshdr.c14
-rw-r--r--libelf/elf_begin.c26
-rw-r--r--libelf/elf_scnshndx.c71
-rw-r--r--libelf/libelf.h4
-rw-r--r--libelf/libelf.map7
-rw-r--r--libelf/libelfP.h6
8 files changed, 139 insertions, 3 deletions
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 57a40d90..daa78e4c 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,14 @@
+2007-12-20 Ulrich Drepper <[email protected]>
+
+ * Makefile.am (libelf_a_SOURCES): Add elf_scnshndx.
+ * libelfP.h (struct Elf_Scn): Add shndx_index field.
+ Declare __elf_scnshndx_internal.
+ * elf32_getshdr.c: Record location of extended section header.
+ * elf_begin.c (file_read_elf): Likewise.
+ * elf_scnshndx.c: New file.
+ * libelf.h: Declare elf_scnshndx.
+ * libelf.map: Add elf_scnshndx to version ELFUTILS_1.4.
+
2007-11-12 Roland McGrath <[email protected]>
* libelf.h: Replace off64_t with loff_t throughout.
diff --git a/libelf/Makefile.am b/libelf/Makefile.am
index 58c9b5a8..3cb858df 100644
--- a/libelf/Makefile.am
+++ b/libelf/Makefile.am
@@ -99,7 +99,8 @@ libelf_a_SOURCES = elf_version.c elf_hash.c elf_error.c elf_fill.c \
gelf_getlib.c gelf_update_lib.c \
elf32_offscn.c elf64_offscn.c gelf_offscn.c \
elf_getaroff.c \
- elf_gnu_hash.c
+ elf_gnu_hash.c \
+ elf_scnshndx.c
if !MUDFLAP
libelf_pic_a_SOURCES =
diff --git a/libelf/elf32_getshdr.c b/libelf/elf32_getshdr.c
index cafb1d4f..c7f75bbb 100644
--- a/libelf/elf32_getshdr.c
+++ b/libelf/elf32_getshdr.c
@@ -165,6 +165,20 @@ elfw2(LIBELFBITS,getshdr) (scn)
CONVERT_TO (shdr[cnt].sh_addralign,
notcvt[cnt].sh_addralign);
CONVERT_TO (shdr[cnt].sh_entsize, notcvt[cnt].sh_entsize);
+
+ /* If this is a section with an extended index add a
+ reference in the section which uses the extended
+ index. */
+ if (shdr[cnt].sh_type == SHT_SYMTAB_SHNDX
+ && shdr[cnt].sh_link < shnum)
+ elf->state.ELFW(elf,LIBELFBITS).scns.data[shdr[cnt].sh_link].shndx_index
+ = cnt;
+
+ /* Set the own shndx_index field in case it has not yet
+ been set. */
+ if (elf->state.ELFW(elf,LIBELFBITS).scns.data[cnt].shndx_index == 0)
+ elf->state.ELFW(elf,LIBELFBITS).scns.data[cnt].shndx_index
+ = -1;
}
}
}
diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c
index 13f965f7..d84f9047 100644
--- a/libelf/elf_begin.c
+++ b/libelf/elf_begin.c
@@ -327,6 +327,19 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident,
((char *) map_address + offset
+ elf->state.elf32.shdr[cnt].sh_offset);
elf->state.elf32.scns.data[cnt].list = &elf->state.elf32.scns;
+
+ /* If this is a section with an extended index add a
+ reference in the section which uses the extended
+ index. */
+ if (elf->state.elf32.shdr[cnt].sh_type == SHT_SYMTAB_SHNDX
+ && elf->state.elf32.shdr[cnt].sh_link < scncnt)
+ elf->state.elf32.scns.data[elf->state.elf32.shdr[cnt].sh_link].shndx_index
+ = cnt;
+
+ /* Set the own shndx_index field in case it has not yet
+ been set. */
+ if (elf->state.elf32.scns.data[cnt].shndx_index == 0)
+ elf->state.elf32.scns.data[cnt].shndx_index = -1;
}
}
else
@@ -402,6 +415,19 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident,
((char *) map_address + offset
+ elf->state.elf64.shdr[cnt].sh_offset);
elf->state.elf64.scns.data[cnt].list = &elf->state.elf64.scns;
+
+ /* If this is a section with an extended index add a
+ reference in the section which uses the extended
+ index. */
+ if (elf->state.elf64.shdr[cnt].sh_type == SHT_SYMTAB_SHNDX
+ && elf->state.elf64.shdr[cnt].sh_link < scncnt)
+ elf->state.elf64.scns.data[elf->state.elf64.shdr[cnt].sh_link].shndx_index
+ = cnt;
+
+ /* Set the own shndx_index field in case it has not yet
+ been set. */
+ if (elf->state.elf64.scns.data[cnt].shndx_index == 0)
+ elf->state.elf64.scns.data[cnt].shndx_index = -1;
}
}
else
diff --git a/libelf/elf_scnshndx.c b/libelf/elf_scnshndx.c
new file mode 100644
index 00000000..987d23e4
--- /dev/null
+++ b/libelf/elf_scnshndx.c
@@ -0,0 +1,71 @@
+/* Get the section index of the extended section index table.
+ Copyright (C) 2007 Red Hat, Inc.
+ This file is part of Red Hat elfutils.
+ Contributed by Ulrich Drepper <[email protected]>, 2007.
+
+ 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 "libelfP.h"
+
+
+int
+elf_scnshndx (Elf_Scn *scn)
+{
+ if (unlikely (scn->shndx_index == 0))
+ {
+ /* We do not have the value yet. We get it as a side effect of
+ getting a section header. */
+ GElf_Shdr shdr_mem;
+ (void) INTUSE(gelf_getshdr) (scn, &shdr_mem);
+ }
+
+ return scn->shndx_index;
+}
+INTDEF(elf_scnshndx)
diff --git a/libelf/libelf.h b/libelf/libelf.h
index 90a588ee..54271228 100644
--- a/libelf/libelf.h
+++ b/libelf/libelf.h
@@ -248,6 +248,10 @@ extern Elf_Scn *elf_nextscn (Elf *__elf, Elf_Scn *__scn);
/* Create a new section and append it at the end of the table. */
extern Elf_Scn *elf_newscn (Elf *__elf);
+/* Get the section index of the extended section index table for the
+ given symbol table. */
+extern int elf_scnshndx (Elf_Scn *__scn);
+
/* Get the number of sections in the ELF file. If the file uses more
sections than can be represented in the e_shnum field of the ELF
header the information from the sh_size field in the zeroth section
diff --git a/libelf/libelf.map b/libelf/libelf.map
index aaaf9164..c2537774 100644
--- a/libelf/libelf.map
+++ b/libelf/libelf.map
@@ -122,4 +122,9 @@ ELFUTILS_1.3 {
gelf_getauxv;
gelf_update_auxv;
gelf_getnote;
-};
+} ELFUTILS_1.2;
+
+ELFUTILS_1.4 {
+ global:
+ elf_scnshndx;
+} ELFUTILS_1.3;
diff --git a/libelf/libelfP.h b/libelf/libelfP.h
index 7e6305cd..5e3d57cb 100644
--- a/libelf/libelfP.h
+++ b/libelf/libelfP.h
@@ -1,5 +1,5 @@
/* Internal interfaces for libelf.
- Copyright (C) 1998,1999,2000,2001,2002,2003,2005,2006,2007 Red Hat, Inc.
+ Copyright (C) 1998-2003, 2005, 2006, 2007 Red Hat, Inc.
This file is part of Red Hat elfutils.
Contributed by Ulrich Drepper <[email protected]>, 1998.
@@ -224,6 +224,9 @@ struct Elf_Scn
int data_read; /* Nonzero if the section was created by the
user or if the data from the file/memory
is read. */
+ int shndx_index; /* Index of the extended section index
+ table for this symbol table (if this
+ section is a symbol table). */
size_t index; /* Index of this section. */
struct Elf *elf; /* The underlying ELF file. */
@@ -532,6 +535,7 @@ extern Elf_Scn *__elf_getscn_internal (Elf *__elf, size_t __index)
attribute_hidden;
extern Elf_Scn *__elf_nextscn_internal (Elf *__elf, Elf_Scn *__scn)
attribute_hidden;
+extern int __elf_scnshndx_internal (Elf_Scn *__scn) attribute_hidden;
extern Elf_Data *__elf_getdata_internal (Elf_Scn *__scn, Elf_Data *__data)
attribute_hidden;
extern Elf_Data *__elf_rawdata_internal (Elf_Scn *__scn, Elf_Data *__data)