summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2008-04-01 02:30:05 +0000
committerRoland McGrath <roland@redhat.com>2008-04-01 02:30:05 +0000
commit13b69609bcd5638e6194d940855fea3dd0519605 (patch)
treeffaa63b3cd050285d68ebc6c437c012edb59ddf9
parentd11f9cbecac4a5ac3848a68597028d1924f3ff6b (diff)
downloadelfutils-13b69609bcd5638e6194d940855fea3dd0519605.tar.gz
backends/
* sparc_symbol.c (sparc_symbol_type_name): New function. (sparc_dynamic_tag_name): New function. (sparc_dynamic_tag_check): New function. * sparc_init.c (sparc_init): Initialize those hooks. libebl/ * ebldynamictagname.c (ebl_dynamic_tag_name): Use hex for unknown tag.
-rw-r--r--backends/ChangeLog10
-rw-r--r--backends/sparc_init.c6
-rw-r--r--backends/sparc_symbol.c80
-rw-r--r--libebl/ChangeLog11
-rw-r--r--libebl/Makefile.am3
-rw-r--r--libebl/ebl-hooks.h8
-rw-r--r--libebl/ebl_check_special_section.c65
-rw-r--r--libebl/ebldynamictagname.c4
-rw-r--r--libebl/eblopenbackend.c12
-rw-r--r--libebl/libebl.h6
-rw-r--r--libelf/ChangeLog4
-rw-r--r--libelf/elf32_offscn.c12
-rw-r--r--src/ChangeLog11
-rw-r--r--src/elflint.c72
-rw-r--r--tests/ChangeLog7
-rw-r--r--tests/Makefile.am8
-rw-r--r--tests/early-offscn.c60
-rwxr-xr-xtests/run-early-offscn.sh32
18 files changed, 400 insertions, 11 deletions
diff --git a/backends/ChangeLog b/backends/ChangeLog
index 681ba94c..c72c2384 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -1,3 +1,13 @@
+2008-03-31 Roland McGrath <roland@redhat.com>
+
+ * sparc_symbol.c (sparc_symbol_type_name): New function.
+ (sparc_dynamic_tag_name): New function.
+ (sparc_dynamic_tag_check): New function.
+ * sparc_init.c (sparc_init): Initialize those hooks.
+
+ * sparc_symbol.c (sparc_check_special_section): New function.
+ * sparc_init.c (sparc_init): Initialize check_special_section hook.
+
2008-02-20 Roland McGrath <roland@redhat.com>
* ppc_attrs.c: New file.
diff --git a/backends/sparc_init.c b/backends/sparc_init.c
index 8da845e2..856bd48c 100644
--- a/backends/sparc_init.c
+++ b/backends/sparc_init.c
@@ -1,5 +1,5 @@
/* Initialization of SPARC specific backend library.
- Copyright (C) 2002, 2005, 2006, 2007 Red Hat, Inc.
+ Copyright (C) 2002, 2005, 2006, 2007, 2008 Red Hat, Inc.
This file is part of Red Hat elfutils.
Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -57,6 +57,10 @@ sparc_init (elf, machine, eh, ehlen)
sparc_init_reloc (eh);
HOOK (eh, reloc_simple_type);
HOOK (eh, machine_flag_check);
+ HOOK (eh, check_special_section);
+ HOOK (eh, symbol_type_name);
+ HOOK (eh, dynamic_tag_name);
+ HOOK (eh, dynamic_tag_check);
if (eh->class == ELFCLASS64)
eh->core_note = sparc64_core_note;
else
diff --git a/backends/sparc_symbol.c b/backends/sparc_symbol.c
index 237620c9..27de54c0 100644
--- a/backends/sparc_symbol.c
+++ b/backends/sparc_symbol.c
@@ -1,5 +1,5 @@
/* SPARC specific symbolic name handling.
- Copyright (C) 2002, 2003, 2005, 2007 Red Hat, Inc.
+ Copyright (C) 2002, 2003, 2005, 2007, 2008 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Jakub Jelinek <jakub@redhat.com>, 2002.
@@ -66,3 +66,81 @@ sparc_machine_flag_check (GElf_Word flags)
| EF_SPARC_SUN_US1
| EF_SPARC_SUN_US3)) == 0);
}
+
+bool
+sparc_check_special_section (Ebl *ebl,
+ int ndx __attribute__ ((unused)),
+ const GElf_Shdr *shdr,
+ const char *sname __attribute__ ((unused)))
+{
+ ebl=ebl;
+ if ((shdr->sh_flags & (SHF_WRITE | SHF_EXECINSTR))
+ == (SHF_WRITE | SHF_EXECINSTR))
+ {
+ /* This is ordinarily flagged, but is valid for a PLT on SPARC.
+
+ Look for the SHT_DYNAMIC section and the DT_PLTGOT tag in it.
+ Its d_ptr should match the .plt section's sh_addr. */
+
+ Elf_Scn *scn = NULL;
+ while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+ {
+ GElf_Shdr scn_shdr;
+ if (likely (gelf_getshdr (scn, &scn_shdr) != NULL)
+ && scn_shdr.sh_type == SHT_DYNAMIC
+ && scn_shdr.sh_entsize != 0)
+ {
+ Elf_Data *data = elf_getdata (scn, NULL);
+ if (data != NULL)
+ for (size_t i = 0; i < data->d_size / scn_shdr.sh_entsize; ++i)
+ {
+ GElf_Dyn dyn;
+ if (unlikely (gelf_getdyn (data, i, &dyn) == NULL))
+ break;
+ if (dyn.d_tag == DT_PLTGOT)
+ return dyn.d_un.d_ptr == shdr->sh_addr;
+ }
+ break;
+ }
+ }
+ }
+
+ return false;
+}
+
+const char *
+sparc_symbol_type_name (int type,
+ char *buf __attribute__ ((unused)),
+ size_t len __attribute__ ((unused)))
+{
+ switch (type)
+ {
+ case STT_SPARC_REGISTER:
+ return "SPARC_REGISTER";
+ }
+ return NULL;
+}
+
+const char *
+sparc_dynamic_tag_name (int64_t tag,
+ char *buf __attribute__ ((unused)),
+ size_t len __attribute__ ((unused)))
+{
+ switch (tag)
+ {
+ case DT_SPARC_REGISTER:
+ return "SPARC_REGISTER";
+ }
+ return NULL;
+}
+
+bool
+sparc_dynamic_tag_check (int64_t tag)
+{
+ switch (tag)
+ {
+ case DT_SPARC_REGISTER:
+ return true;
+ }
+ return false;
+}
diff --git a/libebl/ChangeLog b/libebl/ChangeLog
index 8ebc6c19..9838727a 100644
--- a/libebl/ChangeLog
+++ b/libebl/ChangeLog
@@ -1,3 +1,14 @@
+2008-03-31 Roland McGrath <roland@redhat.com>
+
+ * ebldynamictagname.c (ebl_dynamic_tag_name): Use hex for unknown tag.
+
+ * ebl-hooks.h: Add check_special_section hook.
+ * eblopenbackend.c (fill_defaults): Set new hook to ...
+ (default_check_special_section): ... this, new function.
+ * ebl_check_special_section.c: New file.
+ * Makefile.am (gen_SOURCES): Add it.
+ * libebl.h: Declare it.
+
2008-02-20 Roland McGrath <roland@redhat.com>
* libebl.h: Declare ebl_check_object_attribute.
diff --git a/libebl/Makefile.am b/libebl/Makefile.am
index 1e36b334..0d06a859 100644
--- a/libebl/Makefile.am
+++ b/libebl/Makefile.am
@@ -58,7 +58,8 @@ gen_SOURCES = eblopenbackend.c eblclosebackend.c eblstrtab.c \
eblelfclass.c eblelfdata.c eblelfmachine.c \
ebl_check_special_symbol.c eblbsspltp.c eblretval.c \
eblreginfo.c eblnonerelocp.c eblrelativerelocp.c \
- eblsysvhashentrysize.c eblauxvinfo.c eblcheckobjattr.c
+ eblsysvhashentrysize.c eblauxvinfo.c eblcheckobjattr.c \
+ ebl_check_special_section.c
libebl_a_SOURCES = $(gen_SOURCES)
diff --git a/libebl/ebl-hooks.h b/libebl/ebl-hooks.h
index c236b35e..9f6c8d2c 100644
--- a/libebl/ebl-hooks.h
+++ b/libebl/ebl-hooks.h
@@ -1,5 +1,5 @@
/* Backend hook signatures internal interface for libebl.
- Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006, 2007 Red Hat, Inc.
+ Copyright (C) 2000,2001,2002,2004,2005,2006,2007,2008 Red Hat, Inc.
This file is part of Red Hat elfutils.
Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -83,6 +83,12 @@ bool EBLHOOK(machine_flag_check) (GElf_Word);
/* Check whether SHF_MASKPROC flag bits are valid. */
bool EBLHOOK(machine_section_flag_check) (GElf_Xword);
+/* Check whether the section with the given index, header, and name
+ is a special machine section that is valid despite a combination
+ of flags or other details that are not generically valid. */
+bool EBLHOOK(check_special_section) (Ebl *, int,
+ const GElf_Shdr *, const char *);
+
/* Return symbolic representation of symbol type. */
const char *EBLHOOK(symbol_type_name) (int, char *, size_t);
diff --git a/libebl/ebl_check_special_section.c b/libebl/ebl_check_special_section.c
new file mode 100644
index 00000000..d1f3c6e3
--- /dev/null
+++ b/libebl/ebl_check_special_section.c
@@ -0,0 +1,65 @@
+/* Check for a special section allowed to violate generic constraints.
+ Copyright (C) 2008 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 <libeblP.h>
+
+
+bool
+ebl_check_special_section (ebl, ndx, shdr, sname)
+ Ebl *ebl;
+ int ndx;
+ const GElf_Shdr *shdr;
+ const char *sname;
+{
+ return ebl != NULL && ebl->check_special_section (ebl, ndx, shdr, sname);
+}
diff --git a/libebl/ebldynamictagname.c b/libebl/ebldynamictagname.c
index d9aa7df0..e0972ede 100644
--- a/libebl/ebldynamictagname.c
+++ b/libebl/ebldynamictagname.c
@@ -1,5 +1,5 @@
/* Return dynamic tag name.
- Copyright (C) 2001, 2002, 2006 Red Hat, Inc.
+ Copyright (C) 2001, 2002, 2006, 2008 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2001.
@@ -123,7 +123,7 @@ ebl_dynamic_tag_name (ebl, tag, buf, len)
res = "FILTER";
else
{
- snprintf (buf, len, gettext ("<unknown>: %" PRId64), tag);
+ snprintf (buf, len, gettext ("<unknown>: %#" PRIx64), tag);
res = buf;
diff --git a/libebl/eblopenbackend.c b/libebl/eblopenbackend.c
index 08817f66..672e834b 100644
--- a/libebl/eblopenbackend.c
+++ b/libebl/eblopenbackend.c
@@ -202,6 +202,8 @@ static bool default_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr,
const GElf_Sym *sym,
const char *name,
const GElf_Shdr *destshdr);
+static bool default_check_special_section (Ebl *, int,
+ const GElf_Shdr *, const char *);
static bool default_bss_plt_p (Elf *elf, GElf_Ehdr *ehdr);
static int default_return_value_location (Dwarf_Die *functypedie,
const Dwarf_Op **locops);
@@ -231,6 +233,7 @@ fill_defaults (Ebl *result)
result->machine_flag_name = default_machine_flag_name;
result->machine_flag_check = default_machine_flag_check;
result->machine_section_flag_check = default_machine_section_flag_check;
+ result->check_special_section = default_check_special_section;
result->symbol_type_name = default_symbol_type_name;
result->symbol_binding_name = default_symbol_binding_name;
result->dynamic_tag_name = default_dynamic_tag_name;
@@ -521,6 +524,15 @@ default_machine_section_flag_check (GElf_Xword flags)
return flags == 0;
}
+static bool
+default_check_special_section (Ebl *ebl __attribute__ ((unused)),
+ int ndx __attribute__ ((unused)),
+ const GElf_Shdr *shdr __attribute__ ((unused)),
+ const char *sname __attribute__ ((unused)))
+{
+ return false;
+}
+
static const char *
default_symbol_type_name (int ignore __attribute__ ((unused)),
char *buf __attribute__ ((unused)),
diff --git a/libebl/libebl.h b/libebl/libebl.h
index 083de03a..118ae7e7 100644
--- a/libebl/libebl.h
+++ b/libebl/libebl.h
@@ -141,6 +141,12 @@ extern bool ebl_machine_flag_check (Ebl *ebl, GElf_Word flags);
/* Check whether SHF_MASKPROC flags are valid. */
extern bool ebl_machine_section_flag_check (Ebl *ebl, GElf_Xword flags);
+/* Check whether the section with the given index, header, and name
+ is a special machine section that is valid despite a combination
+ of flags or other details that are not generically valid. */
+extern bool ebl_check_special_section (Ebl *ebl, int ndx,
+ const GElf_Shdr *shdr, const char *name);
+
/* Return symbol type name. */
extern const char *ebl_symbol_type_name (Ebl *ebl, int symbol,
char *buf, size_t len);
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index ef7b37a1..f646c06b 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,7 @@
+2008-03-31 Roland McGrath <roland@redhat.com>
+
+ * elf32_offscn.c: Make sure shdrs have been read in.
+
2008-02-19 Roland McGrath <roland@redhat.com>
* elf.h: Update from glibc.
diff --git a/libelf/elf32_offscn.c b/libelf/elf32_offscn.c
index cdfdfad7..86eff8b1 100644
--- a/libelf/elf32_offscn.c
+++ b/libelf/elf32_offscn.c
@@ -1,5 +1,5 @@
/* Get section at specific index.
- Copyright (C) 2005 Red Hat, Inc.
+ Copyright (C) 2005, 2008 Red Hat, Inc.
This file is part of Red Hat elfutils.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2005.
@@ -77,12 +77,20 @@ elfw2(LIBELFBITS,offscn) (elf, offset)
return NULL;
}
+ Elf_ScnList *runp = &elf->state.ELFW(elf,LIBELFBITS).scns;
+
+ /* If we have not looked at section headers before,
+ we might need to read them in first. */
+ if (runp->cnt > 0
+ && unlikely (runp->data[0].shdr.ELFW(e,LIBELFBITS) == NULL)
+ && unlikely (elfw2(LIBELFBITS,getshdr) (&runp->data[0]) == NULL))
+ return NULL;
+
rwlock_rdlock (elf->lock);
Elf_Scn *result = NULL;
/* Find the section in the list. */
- Elf_ScnList *runp = &elf->state.ELFW(elf,LIBELFBITS).scns;
while (1)
{
for (unsigned int i = 0; i < runp->cnt; ++i)
diff --git a/src/ChangeLog b/src/ChangeLog
index 37127f56..41267ea0 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,14 @@
+2008-03-31 Roland McGrath <roland@redhat.com>
+
+ * elflint.c (check_sections): Add checks on SHF_EXECINSTR sections:
+ must be SHT_PROGBITS, must not be SHF_WRITE. Let backend hook
+ excuse a special section.
+
+2008-03-27 Roland McGrath <roland@redhat.com>
+
+ * elflint.c (check_sections): Check that executability and writability
+ of sections is reflected in segment p_flags.
+
2008-03-26 Roland McGrath <roland@redhat.com>
* elflint.c (check_program_header): Accept PT_GNU_RELRO p_flags
diff --git a/src/elflint.c b/src/elflint.c
index 4448eef1..b13dfdb5 100644
--- a/src/elflint.c
+++ b/src/elflint.c
@@ -3399,6 +3399,8 @@ zeroth section has nonzero size value while ELF header has nonzero shnum value\n
zeroth section has nonzero link value while ELF header does not signal overflow in shstrndx\n"));
}
+ int *segment_flags = xcalloc (ehdr->e_phnum, sizeof segment_flags[0]);
+
bool dot_interp_section = false;
size_t hash_idx = 0;
@@ -3627,6 +3629,31 @@ section [%2zu] '%s': merge flag set but entry size is zero\n"),
if (shdr->sh_flags & SHF_GROUP)
check_scn_group (ebl, cnt);
+ if (shdr->sh_flags & SHF_EXECINSTR)
+ {
+ switch (shdr->sh_type)
+ {
+ case SHT_PROGBITS:
+ break;
+
+ case SHT_NOBITS:
+ if (is_debuginfo)
+ break;
+ default:
+ ERROR (gettext ("\
+section [%2zu] '%s' has unexpected type %d for an executable section\n"),
+ cnt, section_name (ebl, cnt), shdr->sh_type);
+ break;
+ }
+
+ if ((shdr->sh_flags & SHF_WRITE)
+ && !ebl_check_special_section (ebl, cnt, shdr,
+ section_name (ebl, cnt)))
+ ERROR (gettext ("\
+section [%2zu] '%s' is both executable and writable\n"),
+ cnt, section_name (ebl, cnt));
+ }
+
if (ehdr->e_type != ET_REL && (shdr->sh_flags & SHF_ALLOC) != 0)
{
/* Make sure the section is contained in a loaded segment
@@ -3671,6 +3698,28 @@ section [%2zu] '%s' has not type NOBITS but is not read from the file in segment
cnt, section_name (ebl, cnt), pcnt);
}
+ if (shdr->sh_type != SHT_NOBITS)
+ {
+ if ((shdr->sh_flags & SHF_EXECINSTR) != 0)
+ {
+ segment_flags[pcnt] |= PF_X;
+ if ((phdr->p_flags & PF_X) == 0)
+ ERROR (gettext ("\
+section [%2zu] '%s' is executable in nonexecutable segment %d\n"),
+ cnt, section_name (ebl, cnt), pcnt);
+ }
+
+ if ((shdr->sh_flags & SHF_WRITE) != 0)
+ {
+ segment_flags[pcnt] |= PF_W;
+ if (0 /* XXX vdso images have this */
+ && (phdr->p_flags & PF_W) == 0)
+ ERROR (gettext ("\
+section [%2zu] '%s' is writable in unwritable segment %d\n"),
+ cnt, section_name (ebl, cnt), pcnt);
+ }
+ }
+
break;
}
@@ -3765,6 +3814,29 @@ section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"),
if (has_interp_segment && !dot_interp_section)
ERROR (gettext ("INTERP program header entry but no .interp section\n"));
+ if (!is_debuginfo)
+ for (int pcnt = 0; pcnt < ehdr->e_phnum; ++pcnt)
+ {
+ GElf_Phdr phdr_mem;
+ GElf_Phdr *phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem);
+ if (phdr != NULL && (phdr->p_type == PT_LOAD || phdr->p_type == PT_TLS))
+ {
+ if ((phdr->p_flags & PF_X) != 0
+ && (segment_flags[pcnt] & PF_X) == 0)
+ ERROR (gettext ("\
+loadable segment [%u] is executable but contains no executable sections\n"),
+ pcnt);
+
+ if ((phdr->p_flags & PF_W) != 0
+ && (segment_flags[pcnt] & PF_W) == 0)
+ ERROR (gettext ("\
+loadable segment [%u] is writable but contains no writable sections\n"),
+ pcnt);
+ }
+ }
+
+ free (segment_flags);
+
if (version_namelist != NULL)
{
if (versym_scnndx == 0)
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 502d0ab3..d9d74692 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,10 @@
+2008-03-31 Roland McGrath <roland@redhat.com>
+
+ * run-early-offscn.sh: New file.
+ * early-offscn.c: New file.
+ * Makefile.am (noinst_PROGRAMS, TESTS, EXTRA_DIST): Add them.
+ (early_offscn_LDADD): New variable.
+
2008-03-19 Roland McGrath <roland@redhat.com>
* run-addrname-test.sh: Add a new case.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index a058e589..f0b20e9d 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -59,7 +59,7 @@ noinst_PROGRAMS = arextract arsymtest newfile saridx scnnames sectiondump \
show-abbrev hash newscn ecp dwflmodtest \
find-prologues funcretval allregs rdwrmmap \
dwfl-bug-addr-overflow arls dwfl-bug-fd-leak \
- dwfl-addr-sect dwfl-bug-report
+ dwfl-addr-sect dwfl-bug-report early-offscn
# get-ciefde
asm_TESTS = asm-tst1 asm-tst2 asm-tst3 asm-tst4 asm-tst5 \
asm-tst6 asm-tst7 asm-tst8 asm-tst9
@@ -84,7 +84,8 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \
dwfl-bug-addr-overflow run-addrname-test.sh \
dwfl-bug-fd-leak dwfl-bug-report \
run-dwfl-bug-offline-rel.sh run-dwfl-addr-sect.sh \
- run-disasm-x86.sh run-disasm-x86-64.sh
+ run-disasm-x86.sh run-disasm-x86-64.sh \
+ run-early-offscn.sh
# run-show-ciefde.sh
if !STANDALONE
@@ -115,7 +116,7 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
run-addrscopes.sh run-strings-test.sh run-funcscopes.sh \
run-find-prologues.sh run-allregs.sh run-native-test.sh \
run-addrname-test.sh run-dwfl-bug-offline-rel.sh \
- run-dwfl-addr-sect.sh \
+ run-dwfl-addr-sect.sh run-early-offscn.sh \
testfile15.bz2 testfile15.debug.bz2 \
testfile16.bz2 testfile16.debug.bz2 \
testfile17.bz2 testfile17.debug.bz2 \
@@ -190,6 +191,7 @@ hash_LDADD = $(libelf) $(libmudflap)
test_nlist_LDADD = $(libelf) $(libmudflap)
msg_tst_LDADD = $(libelf) $(libmudflap)
newscn_LDADD = $(libelf) $(libmudflap)
+early_offscn_LDADD = $(libelf) $(libmudflap)
ecp_LDADD = $(libelf) $(libmudflap)
update1_LDADD = $(libelf) $(libmudflap)
update2_LDADD = $(libelf) $(libmudflap)
diff --git a/tests/early-offscn.c b/tests/early-offscn.c
new file mode 100644
index 00000000..8778d506
--- /dev/null
+++ b/tests/early-offscn.c
@@ -0,0 +1,60 @@
+/* Copyright (C) 2008 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.
+
+ 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 <errno.h>
+#include <error.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main (int argc, char *argv[])
+{
+ if (argc < 2)
+ error (1, 0, "Usage: %s FILE OFFSET", argv[0]);
+
+ /* Set the ELF version. */
+ elf_version (EV_CURRENT);
+
+ /* Open the archive. */
+ int fd = open (argv[1], O_RDONLY);
+ if (fd < 0)
+ error (1, errno, "cannot open '%s'", argv[1]);
+
+ Elf *elf = elf_begin (fd, ELF_C_READ, NULL);
+ if (elf == NULL)
+ error (2, 0, "elf_begin: %s", elf_errmsg (-1));
+
+ Elf_Scn *scn = gelf_offscn (elf, strtoull (argv[2], NULL, 0));
+ if (scn == NULL)
+ error (3, 0, "gelf_offscn: %s", elf_errmsg (-1));
+
+ elf_end (elf);
+ return 0;
+}
diff --git a/tests/run-early-offscn.sh b/tests/run-early-offscn.sh
new file mode 100755
index 00000000..70be2192
--- /dev/null
+++ b/tests/run-early-offscn.sh
@@ -0,0 +1,32 @@
+#! /bin/sh
+# Copyright (C) 2008 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.
+#
+# 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>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile
+
+testrun ./early-offscn testfile 0x500
+
+exit 0