summaryrefslogtreecommitdiff
path: root/packages/binutils/2.37/0008-arc-Fix-potential-invalid-pointer-access-when-fixing.patch
blob: ade3180b357bfb1bfca47a03b412fd7ccf53c07c (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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
From 29d31b4ed96fcbc774740fac91ef77cb3d62a714 Mon Sep 17 00:00:00 2001
From: Claudiu Zissulescu <claziss@synopsys.com>
Date: Tue, 17 Aug 2021 13:44:17 +0300
Subject: [PATCH] arc: Fix potential invalid pointer access when fixing got
 symbols.

When statically linking, it can arrive to an undefined weak symbol of
which its value cannot be determined. However, we are having pieces of
code which doesn't take this situation into account, leading to access
a structure which may not be initialized. Fix this situation and add a
test.

bfd/
xxxx-xx-xx  Cupertino Miranda  <cmiranda@synopsys.com>
            Claudiu Zissulescu  <claziss@synopsys.com>

	* arc-got.h (arc_static_sym_data): New structure.
	(get_static_sym_data): New function.
	(relocate_fix_got_relocs_for_got_info): Move the computation fo
	symbol value and section to above introduced function, and use
	this new function.

ld/testsuite/
xxxx-xx-xx  Claudiu Zissulescu  <claziss@synopsys.com>

	* ld-arc/got-weak.d: New file.
	* ld-arc/got-weak.s: Likewise.

For all the gory details please refer to [1].
Original fix could be found here [2].

[1] https://github.com/foss-for-synopsys-dwc-arc-processors/toolchain/issues/402
[2] https://github.com/foss-for-synopsys-dwc-arc-processors/binutils-gdb/commit/29d31b4ed96fcbc774740fac91ef77cb3d62a714

Signed-off-by: Claudiu Zissulescu <claziss@synopsys.com>
[Added links to the origins]
Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
---
 bfd/arc-got.h                  |   94 ++++++++++++++++++++++++-----------------
 ld/testsuite/ld-arc/got-weak.d |   12 +++++
 ld/testsuite/ld-arc/got-weak.s |    7 +++
 3 files changed, 76 insertions(+), 37 deletions(-)
 create mode 100644 ld/testsuite/ld-arc/got-weak.d
 create mode 100644 ld/testsuite/ld-arc/got-weak.s

--- a/bfd/arc-got.h
+++ b/bfd/arc-got.h
@@ -262,6 +262,48 @@
   return true;
 }
 
+struct arc_static_sym_data {
+  bfd_vma sym_value;
+  const char *symbol_name;
+};
+
+static struct arc_static_sym_data
+get_static_sym_data (unsigned long  r_symndx,
+		     Elf_Internal_Sym  *local_syms,
+		     asection **local_sections,
+		     struct elf_link_hash_entry *h,
+		     struct arc_relocation_data *reloc_data)
+{
+  static const char local_name[] = "(local)";
+  struct arc_static_sym_data ret = { 0, NULL };
+
+  if (h != NULL)
+    {
+      BFD_ASSERT (h->root.type != bfd_link_hash_undefweak
+		  && h->root.type != bfd_link_hash_undefined);
+      /* TODO: This should not be here.  */
+      reloc_data->sym_value = h->root.u.def.value;
+      reloc_data->sym_section = h->root.u.def.section;
+
+      ret.sym_value = h->root.u.def.value
+	+ h->root.u.def.section->output_section->vma
+	+ h->root.u.def.section->output_offset;
+
+      ret.symbol_name = h->root.root.string;
+    }
+  else
+  {
+    Elf_Internal_Sym *sym = local_syms + r_symndx;
+    asection *sec = local_sections[r_symndx];
+
+    ret.sym_value = sym->st_value
+      + sec->output_section->vma
+      + sec->output_offset;
+
+    ret.symbol_name = local_name;
+  }
+  return ret;
+}
 
 static bfd_vma
 relocate_fix_got_relocs_for_got_info (struct got_entry **	   list_p,
@@ -290,38 +332,7 @@
 	      && SYMBOL_REFERENCES_LOCAL (info, h))))
     {
       const char ATTRIBUTE_UNUSED *symbol_name;
-      static const char local_name[] = "(local)";
-      asection *tls_sec = NULL;
-      bfd_vma sym_value = 0;
-
-      if (h != NULL)
-	{
-	  /* TODO: This should not be here.  */
-	  reloc_data->sym_value = h->root.u.def.value;
-	  reloc_data->sym_section = h->root.u.def.section;
-
-	  sym_value = h->root.u.def.value
-	    + h->root.u.def.section->output_section->vma
-	    + h->root.u.def.section->output_offset;
-
-	  tls_sec = elf_hash_table (info)->tls_sec;
-
-	  symbol_name = h->root.root.string;
-	}
-      else
-	{
-	  Elf_Internal_Sym *sym = local_syms + r_symndx;
-	  asection *sec = local_sections[r_symndx];
-
-	  sym_value = sym->st_value
-	    + sec->output_section->vma
-	    + sec->output_offset;
-
-	  tls_sec = elf_hash_table (info)->tls_sec;
-
-	  symbol_name = local_name;
-	}
-
+      asection *tls_sec = elf_hash_table (info)->tls_sec;
 
       if (entry && !entry->processed)
 	{
@@ -335,8 +346,12 @@
 		if (h == NULL || h->forced_local
 		   || !elf_hash_table (info)->dynamic_sections_created)
 		  {
+		    struct arc_static_sym_data tmp =
+		      get_static_sym_data (r_symndx, local_syms, local_sections,
+					   h, reloc_data);
+
 		    bfd_put_32 (output_bfd,
-			    sym_value - sec_vma
+			    tmp.sym_value - sec_vma
 			    + (elf_hash_table (info)->dynamic_sections_created
 			       ? 0
 			       : (align_power (0,
@@ -355,7 +370,7 @@
 			     + entry->offset
 			     + (entry->existing_entries == TLS_GOT_MOD_AND_OFF
 				? 4 : 0)),
-			  symbol_name);
+			  tmp.symbol_name);
 		  }
 	      }
 	      break;
@@ -366,8 +381,12 @@
 		bfd_vma ATTRIBUTE_UNUSED sec_vma
 		  = tls_sec->output_section->vma;
 
+		struct arc_static_sym_data tmp =
+		  get_static_sym_data (r_symndx, local_syms, local_sections,
+				       h, reloc_data);
+
 		bfd_put_32 (output_bfd,
-			    sym_value - sec_vma
+			    tmp.sym_value - sec_vma
 			    + (elf_hash_table (info)->dynamic_sections_created
 			       ? 0
 			       : (align_power (TCB_SIZE,
@@ -386,7 +405,7 @@
 			      + entry->offset
 			      + (entry->existing_entries == TLS_GOT_MOD_AND_OFF
 				 ? 4 : 0)),
-			   symbol_name);
+			   tmp.symbol_name);
 	      }
 	      break;
 
@@ -415,7 +434,8 @@
 			       "@ %#08lx for sym %s in got offset %#lx\n",
 			       (long) (reloc_data->sym_value + sec_vma),
 			       (long) (htab->sgot->output_section->vma
-				       + htab->sgot->output_offset + entry->offset),
+				       + htab->sgot->output_offset
+				       + entry->offset),
 			       symbol_name,
 			       (long) entry->offset);
 		  }
--- /dev/null
+++ b/ld/testsuite/ld-arc/got-weak.d
@@ -0,0 +1,12 @@
+#source: got-weak.s
+#as:
+#ld: -Bstatic
+#objdump: -d
+
+[^:]*:     file format elf32-.*arc
+
+
+Disassembly of section \.text:
+
+00000100 <.*>:
+ 100:	2730 7f80 0000 2014 	ld	r0,\[pcl,0x2014\].*
--- /dev/null
+++ b/ld/testsuite/ld-arc/got-weak.s
@@ -0,0 +1,7 @@
+	.cpu archs
+
+	.weak symb
+	.global __start
+	.text
+__start:
+	ld	r0,[pcl,@symb@gotpc]