If d_align isn't explicitly set in elf_newdata it will default to
zero. This confuses elf_update when more than one Elf_Data has been
added to a (new) Elf_Section. Only the last will appear to be added.
ELF_T_BYTE happens to be zero and so d_type did appear to be setup
correctly. Also set it explicitly to show the defaults.

The elf_newdata test happened to pass because it set d_align to 1
explicitly. But would fail if it wouldn't set it. Add some extra
checks.

Also update the elf_newdata man page with the new defaults.

        * libelf/elf_newdata.c (elf_newdata): Explicitly set d_type
        and d_align.
        * tests/newdata.c (add_section_data): Check d_buf, d_size,
        d_type, d_align and d_version default values.
        * doc/elf_newdata.3: Document d_align defaults to one.

Signed-off-by: Mark Wielaard <[email protected]>
---
 doc/elf_newdata.3    |  5 ++---
 libelf/elf_newdata.c |  2 ++
 tests/newdata.c      | 33 ++++++++++++++++++++++++++++++---
 3 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/doc/elf_newdata.3 b/doc/elf_newdata.3
index 0522bc15c235..1530dfb7fbcd 100644
--- a/doc/elf_newdata.3
+++ b/doc/elf_newdata.3
@@ -42,12 +42,11 @@ set to
 .I d_version
 set to
 .BR EV_CURRENT ,
-and
 .IR d_size ,
 .IR d_off ,
-and
+set to zero, and
 .IR d_align
-set to zero.
+set to one.
 
 .SH PARAMETERS
 .TP
diff --git a/libelf/elf_newdata.c b/libelf/elf_newdata.c
index 0063d599180f..b59b87ecfc0a 100644
--- a/libelf/elf_newdata.c
+++ b/libelf/elf_newdata.c
@@ -118,6 +118,8 @@ elf_newdata (Elf_Scn *scn)
 
   /* Set the predefined values.  */
   result->data.d.d_version = EV_CURRENT;
+  result->data.d.d_type = ELF_T_BYTE;
+  result->data.d.d_align = 1;
 
   result->data.s = scn;
 
diff --git a/tests/newdata.c b/tests/newdata.c
index fcf26acf8cb9..5b7da8d61b14 100644
--- a/tests/newdata.c
+++ b/tests/newdata.c
@@ -54,11 +54,38 @@ add_section_data (Elf *elf, char *buf, size_t len)
       exit (1);
     }
 
+  if (data->d_buf != NULL)
+    {
+      printf ("newdata d_buf isn't NULL\n");
+      exit (1);
+    }
+
+  if (data->d_size != 0)
+    {
+      printf ("newdata d_size isn't 0\n");
+      exit (1);
+    }
+
+  if (data->d_type != ELF_T_BYTE)
+    {
+      printf ("newdata d_type isn't ELF_T_BYTE\n");
+      exit (1);
+    }
+
+  if (data->d_align != 1)
+    {
+      printf ("newdata d_align isn't 1\n");
+      exit (1);
+    }
+
+  if (data->d_version != EV_CURRENT)
+    {
+      printf ("newdata d_version isn't EV_CURRENT\n");
+      exit (1);
+    }
+
   data->d_buf = buf;
-  data->d_type = ELF_T_BYTE;
   data->d_size = len;
-  data->d_align = 1;
-  data->d_version = EV_CURRENT;
 
   // Let the library compute the internal structure information.
   if (elf_update (elf, ELF_C_NULL) < 0)
-- 
2.53.0

Reply via email to