libdwfl: Handle unaligned Phdr in dwfl_segment_report_module

Message ID 20211220004015.1048276-1-mark@klomp.org
State Committed
Headers
Series libdwfl: Handle unaligned Phdr in dwfl_segment_report_module |

Commit Message

Mark Wielaard Dec. 20, 2021, 12:40 a.m. UTC
  The xlate functions only handle correctly aligned buffers. But they do
handle src == dest. So if the source buffer isn't aligned correctly
just copy it first into the destination (which is already correctly
aligned).

Signed-off-by: Mark Wielaard <mark@klomp.org>
---
 libdwfl/ChangeLog                    |  5 +++++
 libdwfl/dwfl_segment_report_module.c | 12 ++++++++++++
 2 files changed, 17 insertions(+)
  

Patch

diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index ac0fbe0f..6015f6b7 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,8 @@ 
+2021-12-19  Mark Wielaard  <mark@klomp.org>
+
+	* dwfl_segment_report_module.c (dwfl_segment_report_module): Copy
+	data and set xlatefrom.d_buf to notes when data is not aligned.
+
 2021-12-19  Mark Wielaard  <mark@klomp.org>
 
 	* dwfl_segment_report_module.c (dwfl_segment_report_module): Copy
diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c
index de190e90..72c85070 100644
--- a/libdwfl/dwfl_segment_report_module.c
+++ b/libdwfl/dwfl_segment_report_module.c
@@ -573,6 +573,18 @@  dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
                   xlatefrom.d_size = filesz;
                   xlateto.d_buf = notes;
                   xlateto.d_size = filesz;
+
+		  /* data may be unaligned, in which case xlatetom would not work.
+		     xlatetom does work when the in and out d_buf are equal (but not
+		     for any other overlap).  */
+		  if ((uintptr_t) data != (align == 8
+					   ? NOTE_ALIGN8 ((uintptr_t) data)
+					   : NOTE_ALIGN4 ((uintptr_t) data)))
+		    {
+		      memcpy (notes, data, filesz);
+		      xlatefrom.d_buf = notes;
+		    }
+
                   if (elf32_xlatetom (&xlateto, &xlatefrom, xencoding) == NULL)
                     {
                       free (notes);