This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 6/6] libelf: Make elf_strptr index correctly into compressed section data.


elf_strptr indexes into the section data. This is defined as index into
the uncompressed data of the section. If the section is compressed make
sure the uncompressed data is available, but don't really decompress the
section header (elf_getdata will still return compressed data).

Signed-off-by: Mark Wielaard <mjw@redhat.com>
---
 libelf/ChangeLog         |  10 +++
 libelf/elf_compress.c    |  93 ++++++++++++++++----------
 libelf/elf_strptr.c      |  50 ++++++++++++--
 libelf/libelfP.h         |   6 ++
 tests/ChangeLog          |  11 ++++
 tests/Makefile.am        |   8 ++-
 tests/elfputzdata.c      |  15 +++--
 tests/run-elfputzdata.sh |  16 ++---
 tests/run-zstrptr.sh     | 167 +++++++++++++++++++++++++++++++++++++++++++++++
 tests/zstrptr.c          | 124 +++++++++++++++++++++++++++++++++++
 10 files changed, 443 insertions(+), 57 deletions(-)
 create mode 100755 tests/run-zstrptr.sh
 create mode 100644 tests/zstrptr.c

diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 35221a6..9507075 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,13 @@
+2015-11-26  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_compress.c (__libelf_decompress_elf): New function, extracted
+	from...
+	(elf_compress): here. Check zdata_base use __libelf_decompress_elf.
+	* elf_strptr.c (elf_strptr): If SHF_COMPRESSED check, uncompress and
+	use zdata.
+	* libelfP.h (struct Elf_Scn): Add zdata_size and zdata_align.
+	(__libelf_decompress_elf): New internal function definition.
+
 2015-10-21  Mark Wielaard  <mjw@redhat.com>
 
 	* Makefile.am (libelf_a_SOURCES): Add elf_compress.c and
diff --git a/libelf/elf_compress.c b/libelf/elf_compress.c
index 6a26c7c..4be9200 100644
--- a/libelf/elf_compress.c
+++ b/libelf/elf_compress.c
@@ -217,6 +217,47 @@ __libelf_decompress (void *buf_in, size_t size_in, size_t size_out)
   return buf_out;
 }
 
+void *
+internal_function
+__libelf_decompress_elf (Elf_Scn *scn, size_t *size_out, size_t *addralign)
+{
+  GElf_Chdr chdr;
+  if (gelf_getchdr (scn, &chdr) == NULL)
+    return NULL;
+
+  if (chdr.ch_type != ELFCOMPRESS_ZLIB)
+    {
+      __libelf_seterrno (ELF_E_UNKNOWN_COMPRESSION_TYPE);
+      return NULL;
+    }
+
+  if (! powerof2 (chdr.ch_addralign))
+    {
+      __libelf_seterrno (ELF_E_INVALID_ALIGN);
+      return NULL;
+    }
+
+  /* Take the in-memory representation, so we can even handle a
+     section that has just been constructed (maybe it was copied
+     over from some other ELF file first with elf_newdata).  This
+     is slightly inefficient when the raw data needs to be
+     converted since then we'll be converting the whole buffer and
+     not just Chdr.  */
+  Elf_Data *data = elf_getdata (scn, NULL);
+  if (data == NULL)
+    return NULL;
+
+  int elfclass = scn->elf->class;
+  size_t hsize = (elfclass == ELFCLASS32
+		  ? sizeof (Elf32_Chdr) : sizeof (Elf64_Chdr));
+  size_t size_in = data->d_size - hsize;
+  void *buf_in = data->d_buf + hsize;
+  void *buf_out = __libelf_decompress (buf_in, size_in, chdr.ch_size);
+  *size_out = chdr.ch_size;
+  *addralign = chdr.ch_addralign;
+  return buf_out;
+}
+
 void
 internal_function
 __libelf_reset_rawdata (Elf_Scn *scn, void *buf, size_t size, size_t align,
@@ -337,53 +378,33 @@ elf_compress (Elf_Scn *scn, int type)
 	  return -1;
 	}
 
-      GElf_Chdr chdr;
-      if (gelf_getchdr (scn, &chdr) == NULL)
-	return -1;
-
-      if (chdr.ch_type != ELFCOMPRESS_ZLIB)
+      /* If the data is already decompressed (by elf_strptr), then we
+	 only need to setup the rawdata and section header. XXX what
+	 about elf_newdata?  */
+      if (scn->zdata_base == NULL)
 	{
-	  __libelf_seterrno (ELF_E_UNKNOWN_COMPRESSION_TYPE);
-	  return -1;
+	  size_t size_out, addralign;
+	  void *buf_out = __libelf_decompress_elf (scn, &size_out, &addralign);
+	  if (buf_out == NULL)
+	    return -1;
+
+	  scn->zdata_base = buf_out;
+	  scn->zdata_size = size_out;
+	  scn->zdata_align = addralign;
 	}
 
-      if (! powerof2 (chdr.ch_addralign))
-	{
-	  __libelf_seterrno (ELF_E_INVALID_ALIGN);
-	  return -1;
-	}
-
-      /* Take the in-memory representation, so we can even handle a
-	 section that has just been constructed (maybe it was copied
-	 over from some other ELF file first with elf_newdata).  This
-	 is slightly inefficient when the raw data needs to be
-	 converted since then we'll be converting the whole buffer and
-	 not just Chdr.  */
-      Elf_Data *data = elf_getdata (scn, NULL);
-      if (data == NULL)
-	return -1;
-
-      size_t hsize = (elfclass == ELFCLASS32
-		      ? sizeof (Elf32_Chdr) : sizeof (Elf64_Chdr));
-      size_t size_in = data->d_size - hsize;
-      void *buf_in = data->d_buf + hsize;
-      void *buf_out = __libelf_decompress (buf_in, size_in, chdr.ch_size);
-      if (buf_out == NULL)
-	return -1;
-
       /* Note we keep the sh_entsize as is, we assume it is setup
 	 correctly and ignored when SHF_COMPRESSED is set.  */
-      shdr.sh_size = chdr.ch_size;
-      shdr.sh_addralign = chdr.ch_addralign;
+      shdr.sh_size = scn->zdata_size;
+      shdr.sh_addralign = scn->zdata_align;
       shdr.sh_flags &= ~SHF_COMPRESSED;
       // XXX Don't! this sets dirty flag...
       gelf_update_shdr (scn, &shdr);
 
-      __libelf_reset_rawdata (scn, buf_out, chdr.ch_size, chdr.ch_addralign,
+      __libelf_reset_rawdata (scn, scn->zdata_base,
+			      scn->zdata_size, scn->zdata_align,
 			      __libelf_data_type (elf, shdr.sh_type));
 
-      scn->zdata_base = buf_out;
-
       return 0;
     }
   else
diff --git a/libelf/elf_strptr.c b/libelf/elf_strptr.c
index c5138dc..e3b5876 100644
--- a/libelf/elf_strptr.c
+++ b/libelf/elf_strptr.c
@@ -83,6 +83,20 @@ elf_strptr (Elf *elf, size_t idx, size_t offset)
 	}
     }
 
+  void *get_zdata (void)
+  {
+    size_t zsize, zalign;
+    void *zdata = __libelf_decompress_elf (strscn, &zsize, &zalign);
+    if (zdata == NULL)
+      return NULL;
+
+    strscn->zdata_base = zdata;
+    strscn->zdata_size = zsize;
+    strscn->zdata_align = zalign;
+
+    return zdata;
+  }
+
   size_t sh_size = 0;
   if (elf->class == ELFCLASS32)
     {
@@ -94,8 +108,16 @@ elf_strptr (Elf *elf, size_t idx, size_t offset)
 	  goto out;
 	}
 
-      sh_size = shdr->sh_size;
-      if (unlikely (offset >= shdr->sh_size))
+      if ((shdr->sh_flags & SHF_COMPRESSED) == 0)
+	sh_size = shdr->sh_size;
+      else
+	{
+	  if (strscn->zdata_base == NULL && get_zdata () == NULL)
+	    goto out;
+	  sh_size = strscn->zdata_size;
+	}
+
+      if (unlikely (offset >= sh_size))
 	{
 	  /* The given offset is too big, it is beyond this section.  */
 	  __libelf_seterrno (ELF_E_OFFSET_RANGE);
@@ -112,8 +134,16 @@ elf_strptr (Elf *elf, size_t idx, size_t offset)
 	  goto out;
 	}
 
-      sh_size = shdr->sh_size;
-      if (unlikely (offset >= shdr->sh_size))
+      if ((shdr->sh_flags & SHF_COMPRESSED) == 0)
+	sh_size = shdr->sh_size;
+      else
+	{
+	  if (strscn->zdata_base == NULL && get_zdata () == NULL)
+	    goto out;
+	  sh_size = strscn->zdata_size;
+	}
+
+      if (unlikely (offset >= sh_size))
 	{
 	  /* The given offset is too big, it is beyond this section.  */
 	  __libelf_seterrno (ELF_E_OFFSET_RANGE);
@@ -131,7 +161,17 @@ elf_strptr (Elf *elf, size_t idx, size_t offset)
 	goto out;
     }
 
-  if (likely (strscn->data_list_rear == NULL))
+  if (unlikely (strscn->zdata_base != NULL))
+    {
+      /* Make sure the string is NUL terminated.  Start from the end,
+         which very likely is a NUL char.  */
+      if (likely (memrchr (&strscn->zdata_base[offset],
+			   '\0', sh_size - offset) != NULL))
+        result = &strscn->zdata_base[offset];
+      else
+        __libelf_seterrno (ELF_E_INVALID_INDEX);
+    }
+  else if (likely (strscn->data_list_rear == NULL))
     {
       // XXX The above is currently correct since elf_newdata will
       // make sure to convert the rawdata into the datalist if
diff --git a/libelf/libelfP.h b/libelf/libelfP.h
index b58f3fe..326c624 100644
--- a/libelf/libelfP.h
+++ b/libelf/libelfP.h
@@ -236,6 +236,8 @@ struct Elf_Scn
   char *data_base;		/* The converted data of the section.  */
 
   char *zdata_base;		/* The uncompressed data of the section.  */
+  size_t zdata_size;		/* If zdata_base != NULL, the size of data.  */
+  size_t zdata_align;		/* If zdata_base != NULL, the addralign.  */
 
   struct Elf_ScnList *list;	/* Pointer to the section list element the
 				   data is in.  */
@@ -597,6 +599,10 @@ extern void * __libelf_compress (Elf_Scn *scn, size_t hsize, int ei_data,
 
 extern void * __libelf_decompress (void *buf_in, size_t size_in,
 				   size_t size_out) internal_function;
+extern void * __libelf_decompress_elf (Elf_Scn *scn,
+				       size_t *size_out, size_t *addralign)
+     internal_function;
+
 
 extern void __libelf_reset_rawdata (Elf_Scn *scn, void *buf, size_t size,
 				    size_t align, Elf_Type type)
diff --git a/tests/ChangeLog b/tests/ChangeLog
index b061364..141ebf1 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,14 @@
+2015-11-26  Mark Wielaard  <mjw@redhat.com>
+
+	* zstrptr.c: New file.
+	* run-zstrptr.sh: New test.
+	* elfputzdata.c (main): (re)compress .shstrtab.
+	* run-elfputzdata.sh: Expect .shstrtab compression.
+	* Makefile.am (check_PROGRAMS): Add zstrptr.
+	(TESTS): Add run-zstrptr.sh.
+	(EXTRA_DIST): Likewise.
+	(zstrptr_LDADD): New variable.
+
 2015-10-20  Mark Wielaard  <mjw@redhat.com>
 
 	* run-readelf-zx.sh: New test.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 0f56f9d..928ee53 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -53,7 +53,7 @@ check_PROGRAMS = arextract arsymtest newfile saridx scnnames sectiondump \
 		  buildid deleted deleted-lib.so aggregate_size vdsosyms \
 		  getsrc_die strptr newdata elfstrtab dwfl-proc-attach \
 		  elfshphehdr elfstrmerge dwelfgnucompressed elfgetchdr \
-		  elfgetzdata elfputzdata
+		  elfgetzdata elfputzdata zstrptr
 
 asm_TESTS = asm-tst1 asm-tst2 asm-tst3 asm-tst4 asm-tst5 \
 	    asm-tst6 asm-tst7 asm-tst8 asm-tst9
@@ -123,7 +123,7 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \
 	run-getsrc-die.sh run-strptr.sh newdata elfstrtab dwfl-proc-attach \
 	elfshphehdr run-lfs-symbols.sh run-dwelfgnucompressed.sh \
 	run-elfgetchdr.sh \
-	run-elfgetzdata.sh run-elfputzdata.sh
+	run-elfgetzdata.sh run-elfputzdata.sh run-zstrptr.sh
 
 if !BIARCH
 export ELFUTILS_DISABLE_BIARCH = 1
@@ -315,7 +315,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
 	     run-dwelfgnucompressed.sh \
 	     testfile-zgabi32.bz2 testfile-zgabi64.bz2 \
 	     testfile-zgabi32be.bz2 testfile-zgabi64be.bz2 \
-	     run-elfgetchdr.sh run-elfgetzdata.sh run-elfputzdata.sh
+	     run-elfgetchdr.sh run-elfgetzdata.sh run-elfputzdata.sh \
+	     run-zstrptr.sh
 
 if USE_VALGRIND
 valgrind_cmd='valgrind -q --error-exitcode=1 --run-libc-freeres=no'
@@ -468,6 +469,7 @@ dwelfgnucompressed_LDADD = $(libelf) $(libdw)
 elfgetchdr_LDADD = $(libelf) $(libdw)
 elfgetzdata_LDADD = $(libelf)
 elfputzdata_LDADD = $(libelf)
+zstrptr_LDADD = $(libelf)
 
 if GCOV
 check: check-am coverage
diff --git a/tests/elfputzdata.c b/tests/elfputzdata.c
index e2083ac..aaa4b8f 100644
--- a/tests/elfputzdata.c
+++ b/tests/elfputzdata.c
@@ -76,11 +76,7 @@ main (int argc, char *argv[])
 	  GElf_Shdr mem;
 	  GElf_Shdr *shdr = gelf_getshdr (scn, &mem);
 	  const char *name = elf_strptr (elf, strndx, shdr->sh_name);
-	  if (idx == strndx)
-	    {
-	      printf ("Not compressing section string table %zd\n", idx);
-	    }
-	  else if (shdr->sh_type == SHT_NOBITS
+	  if (shdr->sh_type == SHT_NOBITS
 	      || (shdr->sh_flags & SHF_ALLOC) != 0)
 	    {
 	      printf ("Cannot compress %zd %s\n", idx, name);
@@ -190,6 +186,15 @@ main (int argc, char *argv[])
 		  return -1;
 		}
 	      free (orig_buf);
+	      // Recompress the string table, just to make sure
+	      // everything keeps working. See elf_strptr above.
+	      if (! gnu && idx == strndx
+		  && elf_compress (scn, ELFCOMPRESS_ZLIB) != 0)
+		{
+		  printf ("couldn't recompress section header strings: %s\n",
+			  elf_errmsg (-1));
+		  return -1;
+		}
 	    }
 	}
 
diff --git a/tests/run-elfputzdata.sh b/tests/run-elfputzdata.sh
index e9a352e..b882b3f 100755
--- a/tests/run-elfputzdata.sh
+++ b/tests/run-elfputzdata.sh
@@ -53,7 +53,7 @@ Lets compress 29 .debug_info, size: 960
 Lets compress 30 .debug_abbrev, size: 405
 Lets compress 31 .debug_line, size: 189
 Lets compress 32 .note, size: 240
-Not compressing section string table 33
+Lets compress 33 .shstrtab, size: 320
 Lets compress 34 .symtab, size: 5488
 Lets compress 35 .strtab, size: 5727
 EOF
@@ -91,7 +91,7 @@ Lets compress 29 .debug_info, size: 960
 Lets compress 30 .debug_abbrev, size: 405
 Lets compress 31 .debug_line, size: 189
 Lets compress 32 .note, size: 240
-Not compressing section string table 33
+Lets compress 33 .shstrtab, size: 320
 Lets compress 34 .symtab, size: 5488
 Lets compress 35 .strtab, size: 5727
 EOF
@@ -130,7 +130,7 @@ Lets compress 27 .debug_line, size: 709
 Lets compress 28 .debug_frame, size: 56
 Lets compress 29 .debug_str, size: 2235
 Lets compress 30 .debug_macinfo, size: 10518
-Not compressing section string table 31
+Lets compress 31 .shstrtab, size: 308
 Lets compress 32 .symtab, size: 1944
 Lets compress 33 .strtab, size: 757
 EOF
@@ -166,7 +166,7 @@ Lets compress 27 .debug_line, size: 709
 Lets compress 28 .debug_frame, size: 56
 Lets compress 29 .debug_str, size: 2235
 Lets compress 30 .debug_macinfo, size: 10518
-Not compressing section string table 31
+Lets compress 31 .shstrtab, size: 308
 Lets compress 32 .symtab, size: 1944
 Lets compress 33 .strtab, size: 757
 EOF
@@ -208,7 +208,7 @@ Lets compress 30 .debug_frame, size: 96
 Lets compress 31 .debug_str, size: 174
 Lets compress 32 .debug_loc, size: 171
 Lets compress 33 .debug_ranges, size: 32
-Not compressing section string table 34
+Lets compress 34 .shstrtab, size: 352
 Lets compress 35 .symtab, size: 1800
 Lets compress 36 .strtab, size: 602
 EOF
@@ -247,7 +247,7 @@ Lets compress 30 .debug_frame, size: 96
 Lets compress 31 .debug_str, size: 174
 Lets compress 32 .debug_loc, size: 171
 Lets compress 33 .debug_ranges, size: 32
-Not compressing section string table 34
+Lets compress 34 .shstrtab, size: 352
 Lets compress 35 .symtab, size: 1800
 Lets compress 36 .strtab, size: 602
 EOF
@@ -291,7 +291,7 @@ Lets compress 32 .debug_frame, size: 64
 Lets compress 33 .debug_str, size: 179
 Lets compress 34 .debug_loc, size: 99
 Lets compress 35 .debug_ranges, size: 16
-Not compressing section string table 36
+Lets compress 36 .shstrtab, size: 370
 Lets compress 37 .symtab, size: 1232
 Lets compress 38 .strtab, size: 569
 EOF
@@ -332,7 +332,7 @@ Lets compress 32 .debug_frame, size: 64
 Lets compress 33 .debug_str, size: 179
 Lets compress 34 .debug_loc, size: 99
 Lets compress 35 .debug_ranges, size: 16
-Not compressing section string table 36
+Lets compress 36 .shstrtab, size: 370
 Lets compress 37 .symtab, size: 1232
 Lets compress 38 .strtab, size: 569
 EOF
diff --git a/tests/run-zstrptr.sh b/tests/run-zstrptr.sh
new file mode 100755
index 0000000..254dcd8
--- /dev/null
+++ b/tests/run-zstrptr.sh
@@ -0,0 +1,167 @@
+#! /bin/sh
+# Copyright (C) 2015 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# A random 32bit and 64bit testfile
+testfiles testfile testfile10
+
+testrun_compare ${abs_top_builddir}/tests/zstrptr testfile <<\EOF
+Strings in section 32 (compressed):
+[0] ''
+[1] '.symtab'
+[9] '.strtab'
+[11] '.shstrtab'
+[1b] '.interp'
+[23] '.note.ABI-tag'
+[31] '.hash'
+[37] '.dynsym'
+[3f] '.dynstr'
+[47] '.gnu.version'
+[54] '.gnu.version_r'
+[63] '.rel.got'
+[6c] '.rel.plt'
+[75] '.init'
+[7b] '.plt'
+[80] '.text'
+[86] '.fini'
+[8c] '.rodata'
+[94] '.data'
+[9a] '.eh_frame'
+[a4] '.ctors'
+[ab] '.dtors'
+[b2] '.got'
+[b7] '.dynamic'
+[c0] '.sbss'
+[c6] '.bss'
+[cb] '.stab'
+[d1] '.stabstr'
+[da] '.comment'
+[e3] '.debug_aranges'
+[f2] '.debug_pubnames'
+[102] '.debug_info'
+[10e] '.debug_abbrev'
+[11c] '.debug_line'
+[128] '.note'
+Strings in section 32 (uncompressed):
+[0] ''
+[1] '.symtab'
+[9] '.strtab'
+[11] '.shstrtab'
+[1b] '.interp'
+[23] '.note.ABI-tag'
+[31] '.hash'
+[37] '.dynsym'
+[3f] '.dynstr'
+[47] '.gnu.version'
+[54] '.gnu.version_r'
+[63] '.rel.got'
+[6c] '.rel.plt'
+[75] '.init'
+[7b] '.plt'
+[80] '.text'
+[86] '.fini'
+[8c] '.rodata'
+[94] '.data'
+[9a] '.eh_frame'
+[a4] '.ctors'
+[ab] '.dtors'
+[b2] '.got'
+[b7] '.dynamic'
+[c0] '.sbss'
+[c6] '.bss'
+[cb] '.stab'
+[d1] '.stabstr'
+[da] '.comment'
+[e3] '.debug_aranges'
+[f2] '.debug_pubnames'
+[102] '.debug_info'
+[10e] '.debug_abbrev'
+[11c] '.debug_line'
+[128] '.note'
+EOF
+
+testrun_compare ${abs_top_builddir}/tests/zstrptr testfile10 <<\EOF
+Strings in section 30 (compressed):
+[0] ''
+[1] '.symtab'
+[9] '.strtab'
+[11] '.shstrtab'
+[1b] '.hash'
+[21] '.dynsym'
+[29] '.dynstr'
+[31] '.gnu.version'
+[3e] '.gnu.version_r'
+[4d] '.rela.dyn'
+[57] '.init'
+[5d] '.text'
+[63] '.fini'
+[69] '.eh_frame'
+[73] '.data'
+[79] '.dynamic'
+[82] '.ctors'
+[89] '.dtors'
+[90] '.jcr'
+[95] '.plt'
+[9a] '.got'
+[9f] '.sdata'
+[a6] '.sbss'
+[ac] '.bss'
+[b1] '.comment'
+[ba] '.debug_aranges'
+[c9] '.debug_pubnames'
+[d9] '.debug_abbrev'
+[e7] '.debug_line'
+[f3] '.debug_frame'
+[100] '.debug_str'
+[10b] '.rela.debug_info'
+Strings in section 30 (uncompressed):
+[0] ''
+[1] '.symtab'
+[9] '.strtab'
+[11] '.shstrtab'
+[1b] '.hash'
+[21] '.dynsym'
+[29] '.dynstr'
+[31] '.gnu.version'
+[3e] '.gnu.version_r'
+[4d] '.rela.dyn'
+[57] '.init'
+[5d] '.text'
+[63] '.fini'
+[69] '.eh_frame'
+[73] '.data'
+[79] '.dynamic'
+[82] '.ctors'
+[89] '.dtors'
+[90] '.jcr'
+[95] '.plt'
+[9a] '.got'
+[9f] '.sdata'
+[a6] '.sbss'
+[ac] '.bss'
+[b1] '.comment'
+[ba] '.debug_aranges'
+[c9] '.debug_pubnames'
+[d9] '.debug_abbrev'
+[e7] '.debug_line'
+[f3] '.debug_frame'
+[100] '.debug_str'
+[10b] '.rela.debug_info'
+EOF
+
+exit 0
diff --git a/tests/zstrptr.c b/tests/zstrptr.c
new file mode 100644
index 0000000..2bc9e50
--- /dev/null
+++ b/tests/zstrptr.c
@@ -0,0 +1,124 @@
+/* Test program for elf_strptr function.
+   Copyright (C) 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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; either version 3 of the License, or
+   (at your option) any later version.
+
+   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 this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include ELFUTILS_HEADER(elf)
+#include <gelf.h>
+
+int
+main (int argc, char *argv[])
+{
+  if (argc != 2)
+    {
+      printf ("No ELF file given as argument");
+      exit (1);
+    }
+
+  const char *fname = argv[1];
+
+  // Initialize libelf.
+  elf_version (EV_CURRENT);
+
+  /* Read the ELF from disk now.  */
+  int fd = open (fname, O_RDONLY);
+  if (fd == -1)
+    {
+      printf ("cannot open `%s' read-only: %s\n", fname, strerror (errno));
+      exit (1);
+    }
+
+  Elf *elf = elf_begin (fd, ELF_C_READ, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot create ELF descriptor read-only: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  size_t ndx;
+  if (elf_getshdrstrndx (elf, &ndx) != 0)
+    {
+      printf ("cannot get section header table index: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  if (ndx == SHN_UNDEF)
+    {
+      printf ("ELF file `%s' doesn't have a section header table index", fname);
+      exit (1);
+    }
+
+  Elf_Scn *scn = elf_getscn (elf, ndx);
+  if (scn == NULL)
+    {
+      printf ("Couldn't get section %zd: %s\n", ndx, elf_errmsg (-1));
+      exit (1);
+    }
+
+  void print_strings (void)
+  {
+    GElf_Shdr shdr_mem;
+    GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+
+    printf ("Strings in section %zd (%s):\n", ndx,
+	    ((shdr->sh_flags & SHF_COMPRESSED) != 0
+	     ? "compressed" : "uncompressed"));
+
+    size_t off = 0;
+    const char *str = elf_strptr (elf, ndx, off);
+    while (str != NULL)
+      {
+	printf ("[%zx] '%s'\n", off, str);
+	off += strlen (str) + 1;
+	str = elf_strptr (elf, ndx, off);
+      }
+  }
+
+  if (elf_compress (scn, ELFCOMPRESS_ZLIB) != 0)
+    {
+      printf ("Couldn't compress section %zd: %s\n", ndx, elf_errmsg (-1));
+      exit (1);
+    }
+  print_strings ();
+
+  if (elf_compress (scn, 0) != 0)
+    {
+      printf ("Couldn't decompress section %zd: %s\n", ndx, elf_errmsg (-1));
+      exit (1);
+    }
+  print_strings ();
+
+  if (elf_end (elf) != 0)
+    {
+      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  close (fd);
+
+  return 0;
+}
-- 
1.8.3.1

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]