]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
backends/
authorRoland McGrath <roland@redhat.com>
Tue, 1 Apr 2008 02:30:05 +0000 (02:30 +0000)
committerRoland McGrath <roland@redhat.com>
Tue, 1 Apr 2008 02:30:05 +0000 (02:30 +0000)
* 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.

18 files changed:
backends/ChangeLog
backends/sparc_init.c
backends/sparc_symbol.c
libebl/ChangeLog
libebl/Makefile.am
libebl/ebl-hooks.h
libebl/ebl_check_special_section.c [new file with mode: 0644]
libebl/ebldynamictagname.c
libebl/eblopenbackend.c
libebl/libebl.h
libelf/ChangeLog
libelf/elf32_offscn.c
src/ChangeLog
src/elflint.c
tests/ChangeLog
tests/Makefile.am
tests/early-offscn.c [new file with mode: 0644]
tests/run-early-offscn.sh [new file with mode: 0755]

index 681ba94c36a7f4d034375df7ebab40a86f184cf6..c72c238417a83fa1ff9b93531781c43a56d9ba44 100644 (file)
@@ -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.
index 8da845e2953a4bb29777a16600380540943c8afc..856bd48cb4c092f25d1d70eac9deefe930ae23e6 100644 (file)
@@ -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
index 237620c9195729dea5496c0a731bc973e47d7e61..27de54c04cfe4b538e4dc159a86984a06822f606 100644 (file)
@@ -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;
+}
index 8ebc6c19ce96f5e64cadbe34b3f9faf937a77a1c..9838727a81563b2c533ad4c61963cf781f800fe7 100644 (file)
@@ -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.
index 1e36b3340db7f544757d2e6453802c217f66d2fc..0d06a85973c99b9711bbe57135cb17ceb984bf4c 100644 (file)
@@ -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)
 
index c236b35e380a9562397833e1f208eeb5edcfe563..9f6c8d2cd6649a7d0abcb6842cfeb81091583b8f 100644 (file)
@@ -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 (file)
index 0000000..d1f3c6e
--- /dev/null
@@ -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);
+}
index d9aa7df06fe5153298287359f139cfb3e72a555a..e0972eded6d1b234a2313c7e2e8d6b7cf41f5484 100644 (file)
@@ -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;
 
index 08817f666f10538c12400743936cfc0003c1ab0e..672e834b1587d58bb6b20096a310ce72c823f0bb 100644 (file)
@@ -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)),
index 083de03ab355e071cd346e7c5257c75e48b91787..118ae7e79368e8d852f9a59470ae5701e9649b6a 100644 (file)
@@ -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);
index ef7b37a102ca5c1329765aaa1c3b403f288800b3..f646c06ba48f3c0bf020e43d664609ef26611d8a 100644 (file)
@@ -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.
index cdfdfad75b42513c2b3722d9c934e0a5a919264e..86eff8b10b97a7b51979d4ec1cc54dbc999b1fac 100644 (file)
@@ -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)
index 37127f560c6ee43357554be278c3b73928c089af..41267ea0fd5241f93278c5f9798ce3e96a34380f 100644 (file)
@@ -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
index 4448eef19870d4d281dbfab52d82ec7a1af9f276..b13dfdb5f3e74d5cb8e4bc395eef255209e85b5d 100644 (file)
@@ -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)
index 502d0ab3869dcec02fff87ca8ecf78d151b12a79..d9d7469217d114b0fc497408d70deace3819fae8 100644 (file)
@@ -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.
index a058e58909defe67d170bffe77aaa78fa94e4183..f0b20e9dc2eb745aadc83e810764d9df81e3ca86 100644 (file)
@@ -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 (file)
index 0000000..8778d50
--- /dev/null
@@ -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 (executable)
index 0000000..70be219
--- /dev/null
@@ -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