summaryrefslogtreecommitdiff
blob: 40885a04d8502a5b1224a22f33e781174ee88b46 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
From 1d00e5ce0fb069911c4b525ec38289fb5d9021b0 Mon Sep 17 00:00:00 2001
From: Paul Floyd <pjfloyd@wanadoo.fr>
Date: Sat, 18 Nov 2023 08:49:34 +0100
Subject: [PATCH 2/3] Bug 476548 - valgrind 3.22.0 fails on assertion when
 loading debuginfo file produced by mold

(cherry picked from commit 9ea4ae66707a4dcc6f4328e11911652e4418c585)
---
 NEWS                               |  2 ++
 coregrind/m_debuginfo/image.c      | 14 +++++++++
 coregrind/m_debuginfo/priv_image.h |  4 +++
 coregrind/m_debuginfo/readelf.c    | 49 ++++++++++++++++++++++++++++--
 4 files changed, 66 insertions(+), 3 deletions(-)

diff --git a/NEWS b/NEWS
index ee5b4ff11..6cd13429a 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,8 @@ Branch 3.22
 
 The following bugs have been fixed or resolved on this branch.
 
+476548  valgrind 3.22.0 fails on assertion when loading debuginfo
+        file produced by mold
 476708  valgrind-monitor.py regular expressions should use raw strings
 
 To see details of a given bug, visit
diff --git a/coregrind/m_debuginfo/image.c b/coregrind/m_debuginfo/image.c
index 02e509071..445f95555 100644
--- a/coregrind/m_debuginfo/image.c
+++ b/coregrind/m_debuginfo/image.c
@@ -1221,6 +1221,20 @@ Int ML_(img_strcmp_c)(DiImage* img, DiOffT off1, const HChar* str2)
    }
 }
 
+Int ML_(img_strcmp_n)(DiImage* img, DiOffT off1, const HChar* str2, Word n)
+{
+   ensure_valid(img, off1, 1, "ML_(img_strcmp_c)");
+   while (n) {
+      UChar c1 = get(img, off1);
+      UChar c2 = *(const UChar*)str2;
+      if (c1 < c2) return -1;
+      if (c1 > c2) return 1;
+      if (c1 == 0) return 0;
+      off1++; str2++; --n;
+   }
+   return 0;
+}
+
 UChar ML_(img_get_UChar)(DiImage* img, DiOffT offset)
 {
    ensure_valid(img, offset, 1, "ML_(img_get_UChar)");
diff --git a/coregrind/m_debuginfo/priv_image.h b/coregrind/m_debuginfo/priv_image.h
index a49846f14..c91e49f01 100644
--- a/coregrind/m_debuginfo/priv_image.h
+++ b/coregrind/m_debuginfo/priv_image.h
@@ -115,6 +115,10 @@ Int ML_(img_strcmp)(DiImage* img, DiOffT off1, DiOffT off2);
    cast to HChar before comparison. */
 Int ML_(img_strcmp_c)(DiImage* img, DiOffT off1, const HChar* str2);
 
+/* Do strncmp of a C string in the image vs a normal one.  Chars are
+   cast to HChar before comparison. */
+Int ML_(img_strcmp_n)(DiImage* img, DiOffT off1, const HChar* str2, Word n);
+
 /* Do strlen of a C string in the image. */
 SizeT ML_(img_strlen)(DiImage* img, DiOffT off);
 
diff --git a/coregrind/m_debuginfo/readelf.c b/coregrind/m_debuginfo/readelf.c
index fb64ed976..46f8c8343 100644
--- a/coregrind/m_debuginfo/readelf.c
+++ b/coregrind/m_debuginfo/readelf.c
@@ -2501,8 +2501,7 @@ Bool ML_(read_elf_object) ( struct _DebugInfo* di )
             di->rodata_avma += inrw1->bias;
             di->rodata_bias = inrw1->bias;
             di->rodata_debug_bias = inrw1->bias;
-         }
-         else {
+         } else {
             BAD(".rodata");  /* should not happen? */
          }
          di->rodata_present = True;
@@ -2977,6 +2976,46 @@ Bool ML_(read_elf_object) ( struct _DebugInfo* di )
    return retval;
 }
 
+static void find_rodata(Word i, Word shnum, DiImage* dimg, struct _DebugInfo* di, DiOffT shdr_dioff,
+                        UWord shdr_dent_szB, DiOffT shdr_strtab_dioff, PtrdiffT rw_dbias)
+{
+   ElfXX_Shdr a_shdr;
+   ElfXX_Shdr a_extra_shdr;
+   ML_(img_get)(&a_shdr, dimg,
+                INDEX_BIS(shdr_dioff, i, shdr_dent_szB),
+                sizeof(a_shdr));
+   if (di->rodata_present &&
+       0 == ML_(img_strcmp_c)(dimg, shdr_strtab_dioff
+                                    + a_shdr.sh_name, ".rodata")) {
+      Word sh_size = a_shdr.sh_size;
+      Word j;
+      Word next_addr = a_shdr.sh_addr + a_shdr.sh_size;
+      for (j = i  + 1; j < shnum; ++j) {
+         ML_(img_get)(&a_extra_shdr, dimg,
+                      INDEX_BIS(shdr_dioff, j, shdr_dent_szB),
+                      sizeof(a_shdr));
+         if (0 == ML_(img_strcmp_n)(dimg, shdr_strtab_dioff
+                                             + a_extra_shdr.sh_name, ".rodata", 7)) {
+            if (a_extra_shdr.sh_addr ==
+                VG_ROUNDUP(next_addr, a_extra_shdr.sh_addralign)) {
+               sh_size = VG_ROUNDUP(sh_size, a_extra_shdr.sh_addralign) + a_extra_shdr.sh_size;
+            }
+            next_addr = a_extra_shdr.sh_addr + a_extra_shdr.sh_size;
+         } else {
+            break;
+         }
+      }
+      vg_assert(di->rodata_size == sh_size);
+      vg_assert(di->rodata_avma +  a_shdr.sh_addr + rw_dbias);
+      di->rodata_debug_svma = a_shdr.sh_addr;
+      di->rodata_debug_bias = di->rodata_bias +
+                             di->rodata_svma - di->rodata_debug_svma;
+      TRACE_SYMTAB("acquiring .rodata  debug svma = %#lx .. %#lx\n",
+                   di->rodata_debug_svma,
+                   di->rodata_debug_svma + di->rodata_size - 1);
+      TRACE_SYMTAB("acquiring .rodata debug bias = %#lx\n", (UWord)di->rodata_debug_bias);
+   }
+}
 Bool ML_(read_elf_debug) ( struct _DebugInfo* di )
 {
    Word     i, j;
@@ -3391,7 +3430,11 @@ Bool ML_(read_elf_debug) ( struct _DebugInfo* di )
             FIND(text,   rx)
             FIND(data,   rw)
             FIND(sdata,  rw)
-            FIND(rodata, rw)
+            // https://bugs.kde.org/show_bug.cgi?id=476548
+            // special handling for rodata as adjacent
+            // rodata sections may have been merged in ML_(read_elf_object)
+            //FIND(rodata, rw)
+            find_rodata(i, ehdr_dimg.e_shnum, dimg, di, shdr_dioff, shdr_dent_szB, shdr_strtab_dioff, rw_dbias);
             FIND(bss,    rw)
             FIND(sbss,   rw)
 
-- 
2.43.0