]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libebl: Fix reading GNU_PROPERTY_STACK_SIZE reading from 32bit notes.
authorMark Wielaard <mark@klomp.org>
Sun, 2 Dec 2018 23:03:39 +0000 (00:03 +0100)
committerMark Wielaard <mark@klomp.org>
Sun, 2 Dec 2018 23:03:39 +0000 (00:03 +0100)
When reading a GNU_PROPERTY_STACK_SIZE we need to use the proper data
type. GElf_Addr is 64bit always and when reading a 32bit size part of
it would not be initialized. Use either Elf32_Addr or Elf64_Addr to
read and print the data.

Add 32bit and 64bit, little and big endian testcases.

Signed-off-by: Mark Wielaard <mark@klomp.org>
libebl/ChangeLog
libebl/eblobjnote.c
tests/ChangeLog
tests/Makefile.am
tests/run-readelf-n.sh
tests/testfile_gnu_props.32be.o.bz2 [new file with mode: 0644]
tests/testfile_gnu_props.32le.o.bz2 [new file with mode: 0644]
tests/testfile_gnu_props.64be.o.bz2 [new file with mode: 0644]
tests/testfile_gnu_props.64le.o.bz2 [new file with mode: 0644]

index a2f89562fc9670319610f6d9b08c2d611e80ad89..0174f331a051afd71647ade700079247f3cacd3b 100644 (file)
@@ -1,3 +1,8 @@
+2018-12-02  Mark Wielaard  <mark@klomp.org>
+
+       * eblobjnte.c (ebl_object_note): For GNU_PROPERTY_STACK_SIZE use
+       an Elf32_Addr or Elf64_Addr to read and print the size.
+
 2018-11-15  Mark Wielaard  <mark@klomp.org>
 
        * eblobjnotetypename.c (ebl_object_note_type_name): Don't update
index 58ac86d7e92316551b2bb4a31cacbf07602e9635..c19ea37fc14090b75b919b5ee2bf8eec42e840db 100644 (file)
@@ -360,15 +360,22 @@ ebl_object_note (Ebl *ebl, uint32_t namesz, const char *name, uint32_t type,
                  if (prop.pr_type == GNU_PROPERTY_STACK_SIZE)
                    {
                      printf ("STACK_SIZE ");
-                     if (prop.pr_datasz == 4 || prop.pr_datasz == 8)
+                     union
+                       {
+                         Elf64_Addr a64;
+                         Elf32_Addr a32;
+                       } addr;
+                     if ((elfclass == ELFCLASS32 && prop.pr_datasz == 4)
+                         || (elfclass == ELFCLASS64 && prop.pr_datasz == 8))
                        {
-                         GElf_Addr addr;
                          in.d_type = ELF_T_ADDR;
                          out.d_type = ELF_T_ADDR;
                          in.d_size = prop.pr_datasz;
-                         out.d_size = sizeof (addr);
+                         out.d_size = prop.pr_datasz;
                          in.d_buf = (void *) desc;
-                         out.d_buf = (void *) &addr;
+                         out.d_buf = (elfclass == ELFCLASS32
+                                      ? (void *) &addr.a32
+                                      : (void *) &addr.a64);
 
                          if (gelf_xlatetom (ebl->elf, &out, &in,
                                             elfident[EI_DATA]) == NULL)
@@ -376,7 +383,10 @@ ebl_object_note (Ebl *ebl, uint32_t namesz, const char *name, uint32_t type,
                              printf ("%s\n", elf_errmsg (-1));
                              return;
                            }
-                         printf ("%#" PRIx64 "\n", addr);
+                         if (elfclass == ELFCLASS32)
+                           printf ("%#" PRIx32 "\n", addr.a32);
+                         else
+                           printf ("%#" PRIx64 "\n", addr.a64);
                        }
                      else
                        printf (" (garbage datasz: %" PRIx32 ")\n",
index 225a51d5ce09b0cc305152b3250fb10c46e2c406..1382e40af1bcd8af8d2fbefa025bd4fd19b9c7c9 100644 (file)
@@ -1,3 +1,12 @@
+2018-12-02  Mark Wielaard  <mark@klomp.org>
+
+       * testfile_gnu_props.32le.o.bz2: New testfile.
+       * testfile_gnu_props.64le.o.bz2: Likewise.
+       * testfile_gnu_props.32be.o.bz2: Likewise.
+       * testfile_gnu_props.64be.o.bz2: Likewise.
+       * Makefile (EXTRA_DIST): Add new testfiles.
+       * run-readelf-n.sh: Run tests on new testfiles.
+
 2018-11-28  Mark Wielaard  <mark@klomp.org>
 
        * backtrace-data.c (main): Improve error message.
index 3ca0e1c22aa28c8a4d9da69e6371a93aedad362e..bc8c19a63c6033c50e3c4ff8f1a86edd9f19dfa6 100644 (file)
@@ -278,6 +278,10 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \
             run-readelf-types.sh \
             run-readelf-n.sh \
             testfile-gnu-property-note.bz2 testfile-gnu-property-note.o.bz2 \
+            testfile_gnu_props.32le.o.bz2 \
+            testfile_gnu_props.64le.o.bz2 \
+            testfile_gnu_props.32be.o.bz2 \
+            testfile_gnu_props.64be.o.bz2 \
             run-allfcts-multi.sh \
             test-offset-loop.bz2 test-offset-loop.alt.bz2 \
             run-prelink-addr-test.sh \
index c2db2ce2a710f80befe5e2539f0bae2f105da108..cc7d7f66affb57fd87f29323efc4301188cf6307 100755 (executable)
@@ -125,3 +125,104 @@ Note section [22] '.note.gnu.property' of 48 bytes at offset 0x40c:
     X86 0xc0000000 data: 00 00 00 00
     X86 0xc0000001 data: 00 00 00 00
 EOF
+
+#
+# = gnu_props.S
+#
+# #define NT_GNU_PROPERTY_TYPE_0 5
+# #define GNU_PROPERTY_STACK_SIZE 1
+# #define GNU_PROPERTY_NO_COPY_ON_PROTECTED 2
+
+# /* Normal notes always have alignment and padding of 4 bytes,
+#    but GNU Property notes use 4 byte words, with 8 byte padding
+#    for ELFCLASS64.  */
+# #if __SIZEOF_PTRDIFF_T__  == 8
+# # define ALIGN 3
+# #elif __SIZEOF_PTRDIFF_T__  == 4
+# # define ALIGN 2
+# #endif
+#
+#      .section ".note.gnu.property", "a"
+#      .p2align ALIGN
+#      /* First note.  */
+#      .long 1f - 0f                   /* name length.  */
+#      .long 4f - 2f                   /* data length.  */
+#      .long NT_GNU_PROPERTY_TYPE_0    /* note type.  */
+# 0:
+#      .asciz "GNU"                    /* vendor name.  */
+# 1:
+#      .p2align ALIGN                  /* Padding.  */
+# 2:
+#      .long GNU_PROPERTY_STACK_SIZE   /* pr_type.  */
+#      .long 4f - 3f                   /* pr_datasz.  */
+# 3:
+#      .dc.a 0x280000                  /* Stack size.  */
+# 4:
+#      .p2align ALIGN
+#
+#      /* Second note.  */
+#      .long 6f - 5f                           /* name length.  */
+#      .long 8f - 7f                           /* data length.  */
+#      .long NT_GNU_PROPERTY_TYPE_0            /* note type.  */
+# 5:
+#      .asciz "GNU"                            /* vendor name.  */
+# 6:
+#      .p2align ALIGN                          /* Padding.  */
+# 7:
+#      .long GNU_PROPERTY_NO_COPY_ON_PROTECTED /* pr_type.  */
+#      .long 0                                 /* pr_datasz.  */
+#      /* No data.  */
+# 8:
+#      .p2align ALIGN
+#
+# On x86_64
+# gcc -m64 -c -o testfile_gnu_props_64le.o gnu_props.S
+# gcc -m32 -c -o testfile_gnu_props_32le.o gnu_props.S
+
+testfiles testfile_gnu_props.32le.o testfile_gnu_props.64le.o
+
+testrun_compare ${abs_top_builddir}/src/readelf -n testfile_gnu_props.32le.o << EOF
+
+Note section [ 4] '.note.gnu.property' of 52 bytes at offset 0x34:
+  Owner          Data size  Type
+  GNU                   12  GNU_PROPERTY_TYPE_0
+    STACK_SIZE 0x280000
+  GNU                    8  GNU_PROPERTY_TYPE_0
+    NO_COPY_ON_PROTECTION
+EOF
+
+testrun_compare ${abs_top_builddir}/src/readelf -n testfile_gnu_props.64le.o << EOF
+
+Note section [ 4] '.note.gnu.property' of 56 bytes at offset 0x40:
+  Owner          Data size  Type
+  GNU                   16  GNU_PROPERTY_TYPE_0
+    STACK_SIZE 0x280000
+  GNU                    8  GNU_PROPERTY_TYPE_0
+    NO_COPY_ON_PROTECTION
+EOF
+
+# On ppc64
+# gcc -m32 -c -o testfile_gnu_props.32be.o gnu_props.S
+# gcc -m64 -c -o testfile_gnu_props.64be.o gnu_props.S
+
+testfiles testfile_gnu_props.32be.o testfile_gnu_props.64be.o
+
+testrun_compare ${abs_top_builddir}/src/readelf -n testfile_gnu_props.32be.o << EOF
+
+Note section [ 4] '.note.gnu.property' of 52 bytes at offset 0x34:
+  Owner          Data size  Type
+  GNU                   12  GNU_PROPERTY_TYPE_0
+    STACK_SIZE 0x280000
+  GNU                    8  GNU_PROPERTY_TYPE_0
+    NO_COPY_ON_PROTECTION
+EOF
+
+testrun_compare ${abs_top_builddir}/src/readelf -n testfile_gnu_props.64be.o << EOF
+
+Note section [ 4] '.note.gnu.property' of 56 bytes at offset 0x40:
+  Owner          Data size  Type
+  GNU                   16  GNU_PROPERTY_TYPE_0
+    STACK_SIZE 0x280000
+  GNU                    8  GNU_PROPERTY_TYPE_0
+    NO_COPY_ON_PROTECTION
+EOF
diff --git a/tests/testfile_gnu_props.32be.o.bz2 b/tests/testfile_gnu_props.32be.o.bz2
new file mode 100644 (file)
index 0000000..60a39fe
Binary files /dev/null and b/tests/testfile_gnu_props.32be.o.bz2 differ
diff --git a/tests/testfile_gnu_props.32le.o.bz2 b/tests/testfile_gnu_props.32le.o.bz2
new file mode 100644 (file)
index 0000000..cb5d23c
Binary files /dev/null and b/tests/testfile_gnu_props.32le.o.bz2 differ
diff --git a/tests/testfile_gnu_props.64be.o.bz2 b/tests/testfile_gnu_props.64be.o.bz2
new file mode 100644 (file)
index 0000000..784c98b
Binary files /dev/null and b/tests/testfile_gnu_props.64be.o.bz2 differ
diff --git a/tests/testfile_gnu_props.64le.o.bz2 b/tests/testfile_gnu_props.64le.o.bz2
new file mode 100644 (file)
index 0000000..09df3d1
Binary files /dev/null and b/tests/testfile_gnu_props.64le.o.bz2 differ