summaryrefslogtreecommitdiffstats
path: root/meta-microblaze/recipes-devtools/binutils/binutils/0004-LOCAL-Fix-relaxation-of-assembler-resolved-reference.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-microblaze/recipes-devtools/binutils/binutils/0004-LOCAL-Fix-relaxation-of-assembler-resolved-reference.patch')
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0004-LOCAL-Fix-relaxation-of-assembler-resolved-reference.patch310
1 files changed, 310 insertions, 0 deletions
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0004-LOCAL-Fix-relaxation-of-assembler-resolved-reference.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0004-LOCAL-Fix-relaxation-of-assembler-resolved-reference.patch
new file mode 100644
index 00000000..e0bd25b9
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0004-LOCAL-Fix-relaxation-of-assembler-resolved-reference.patch
@@ -0,0 +1,310 @@
1From f7c540994e73e430e73d220109e911dff5961f16 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Tue, 8 Nov 2016 11:54:08 +0530
4Subject: [PATCH 04/34] [LOCAL]: Fix relaxation of assembler resolved
5 references,Fixup debug_loc sections after linker relaxation Adds a new
6 reloctype R_MICROBLAZE_32_NONE, used for passing reloc info from the
7 assembler to the linker when the linker manages to fully resolve a local
8 symbol reference.
9
10This is a workaround for design flaws in the assembler to
11linker interface with regards to linker relaxation.
12
13Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
14Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
15
16Conflicts:
17 bfd/elf32-microblaze.c
18 binutils/readelf.c
19 include/elf/microblaze.h
20
21Conflicts:
22 binutils/readelf.c
23
24Conflicts:
25 bfd/elf32-microblaze.c
26---
27 bfd/bfd-in2.h | 5 ++
28 bfd/elf32-microblaze.c | 126 ++++++++++++++++++++++++++++---------
29 bfd/libbfd.h | 1 +
30 bfd/reloc.c | 6 ++
31 binutils/readelf.c | 4 ++
32 gas/config/tc-microblaze.c | 4 ++
33 include/elf/microblaze.h | 2 +
34 7 files changed, 119 insertions(+), 29 deletions(-)
35
36diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
37index 1f0f18a7e75..26e3bb2b34b 100644
38--- a/bfd/bfd-in2.h
39+++ b/bfd/bfd-in2.h
40@@ -5379,6 +5379,11 @@ value relative to the read-write small data area anchor */
41 expressions of the form "Symbol Op Symbol" */
42 BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM,
43
44+/* This is a 32 bit reloc that stores the 32 bit pc relative
45+value in two words (with an imm instruction).No relocation is
46+done here - only used for relaxing */
47+ BFD_RELOC_MICROBLAZE_32_NONE,
48+
49 /* This is a 64 bit reloc that stores the 32 bit pc relative
50 value in two words (with an imm instruction). No relocation is
51 done here - only used for relaxing */
52diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
53index 013c32a1e51..7cf1b6eab5b 100644
54--- a/bfd/elf32-microblaze.c
55+++ b/bfd/elf32-microblaze.c
56@@ -175,6 +175,20 @@ static reloc_howto_type microblaze_elf_howto_raw[] =
57 false), /* PC relative offset? */
58
59 /* This reloc does nothing. Used for relaxation. */
60+ HOWTO (R_MICROBLAZE_32_NONE, /* Type. */
61+ 0, /* Rightshift. */
62+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
63+ 32, /* Bitsize. */
64+ true, /* PC_relative. */
65+ 0, /* Bitpos. */
66+ complain_overflow_bitfield, /* Complain on overflow. */
67+ NULL, /* Special Function. */
68+ "R_MICROBLAZE_32_NONE",/* Name. */
69+ false, /* Partial Inplace. */
70+ 0, /* Source Mask. */
71+ 0, /* Dest Mask. */
72+ false), /* PC relative offset? */
73+
74 HOWTO (R_MICROBLAZE_64_NONE, /* Type. */
75 0, /* Rightshift. */
76 0, /* Size. */
77@@ -560,7 +574,10 @@ microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
78 case BFD_RELOC_NONE:
79 microblaze_reloc = R_MICROBLAZE_NONE;
80 break;
81- case BFD_RELOC_MICROBLAZE_64_NONE:
82+ case BFD_RELOC_MICROBLAZE_32_NONE:
83+ microblaze_reloc = R_MICROBLAZE_32_NONE;
84+ break;
85+ case BFD_RELOC_MICROBLAZE_64_NONE:
86 microblaze_reloc = R_MICROBLAZE_64_NONE;
87 break;
88 case BFD_RELOC_32:
89@@ -1954,18 +1971,26 @@ microblaze_elf_relax_section (bfd *abfd,
90 }
91 break;
92 case R_MICROBLAZE_NONE:
93+ case R_MICROBLAZE_32_NONE:
94 {
95 /* This was a PC-relative instruction that was
96 completely resolved. */
97 size_t sfix, efix;
98+ unsigned int val;
99 bfd_vma target_address;
100 target_address = irel->r_addend + irel->r_offset;
101 sfix = calc_fixup (irel->r_offset, 0, sec);
102 efix = calc_fixup (target_address, 0, sec);
103- irel->r_addend -= (efix - sfix);
104- /* Should use HOWTO. */
105- microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset,
106- irel->r_addend);
107+
108+ /* Validate the in-band val. */
109+ val = bfd_get_32 (abfd, contents + irel->r_offset);
110+ if (val != irel->r_addend && ELF32_R_TYPE (irel->r_info) == R_MICROBLAZE_32_NONE) {
111+ fprintf(stderr, "%d: CORRUPT relax reloc %x %lx\n", __LINE__, val, irel->r_addend);
112+ }
113+ irel->r_addend -= (efix - sfix);
114+ /* Should use HOWTO. */
115+ microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset,
116+ irel->r_addend);
117 }
118 break;
119 case R_MICROBLAZE_64_NONE:
120@@ -2009,30 +2034,73 @@ microblaze_elf_relax_section (bfd *abfd,
121 irelscanend = irelocs + o->reloc_count;
122 for (irelscan = irelocs; irelscan < irelscanend; irelscan++)
123 {
124- if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
125- {
126- isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
127+ if (1 && ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_NONE)
128+ {
129+ unsigned int val;
130+
131+ isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
132+
133+ /* hax: We only do the following fixup for debug location lists. */
134+ if (strcmp(".debug_loc", o->name))
135+ continue;
136+
137+ /* This was a PC-relative instruction that was completely resolved. */
138+ if (ocontents == NULL)
139+ {
140+ if (elf_section_data (o)->this_hdr.contents != NULL)
141+ ocontents = elf_section_data (o)->this_hdr.contents;
142+ else
143+ {
144+ /* We always cache the section contents.
145+ Perhaps, if info->keep_memory is FALSE, we
146+ should free them, if we are permitted to. */
147+
148+ if (o->rawsize == 0)
149+ o->rawsize = o->size;
150+ ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
151+ if (ocontents == NULL)
152+ goto error_return;
153+ if (!bfd_get_section_contents (abfd, o, ocontents,
154+ (file_ptr) 0,
155+ o->rawsize))
156+ goto error_return;
157+ elf_section_data (o)->this_hdr.contents = ocontents;
158+ }
159+ }
160
161- /* Look at the reloc only if the value has been resolved. */
162- if (isym->st_shndx == shndx
163- && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
164- {
165- if (ocontents == NULL)
166- {
167- if (elf_section_data (o)->this_hdr.contents != NULL)
168- ocontents = elf_section_data (o)->this_hdr.contents;
169- else
170- {
171- /* We always cache the section contents.
172- Perhaps, if info->keep_memory is FALSE, we
173- should free them, if we are permitted to. */
174- if (o->rawsize == 0)
175- o->rawsize = o->size;
176- ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
177- if (ocontents == NULL)
178- goto error_return;
179- if (!bfd_get_section_contents (abfd, o, ocontents,
180- (file_ptr) 0,
181+ val = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
182+ if (val != irelscan->r_addend) {
183+ fprintf(stderr, "%d: CORRUPT relax reloc! %x %lx\n", __LINE__, val, irelscan->r_addend);
184+ }
185+
186+ irelscan->r_addend -= calc_fixup (irelscan->r_addend, 0, sec);
187+ microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
188+ irelscan->r_addend);
189+ }
190+ if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
191+ {
192+ isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
193+
194+ /* Look at the reloc only if the value has been resolved. */
195+ if (isym->st_shndx == shndx
196+ && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
197+ {
198+ if (ocontents == NULL)
199+ {
200+ if (elf_section_data (o)->this_hdr.contents != NULL)
201+ ocontents = elf_section_data (o)->this_hdr.contents;
202+ else
203+ {
204+ /* We always cache the section contents.
205+ Perhaps, if info->keep_memory is FALSE, we
206+ should free them, if we are permitted to. */
207+ if (o->rawsize == 0)
208+ o->rawsize = o->size;
209+ ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
210+ if (ocontents == NULL)
211+ goto error_return;
212+ if (!bfd_get_section_contents (abfd, o, ocontents,
213+ (file_ptr) 0,
214 o->rawsize))
215 goto error_return;
216 elf_section_data (o)->this_hdr.contents = ocontents;
217@@ -2068,7 +2136,7 @@ microblaze_elf_relax_section (bfd *abfd,
218 elf_section_data (o)->this_hdr.contents = ocontents;
219 }
220 }
221- irelscan->r_addend -= calc_fixup (irel->r_addend
222+ irelscan->r_addend -= calc_fixup (irelscan->r_addend
223 + isym->st_value,
224 0,
225 sec);
226diff --git a/bfd/libbfd.h b/bfd/libbfd.h
227index 29e8187f95f..ea2507d1879 100644
228--- a/bfd/libbfd.h
229+++ b/bfd/libbfd.h
230@@ -2989,6 +2989,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
231 "BFD_RELOC_MICROBLAZE_32_ROSDA",
232 "BFD_RELOC_MICROBLAZE_32_RWSDA",
233 "BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM",
234+ "BFD_RELOC_MICROBLAZE_32_NONE",
235 "BFD_RELOC_MICROBLAZE_64_NONE",
236 "BFD_RELOC_MICROBLAZE_64_GOTPC",
237 "BFD_RELOC_MICROBLAZE_64_GOT",
238diff --git a/bfd/reloc.c b/bfd/reloc.c
239index 36999fe9a40..5ac8a8536a7 100644
240--- a/bfd/reloc.c
241+++ b/bfd/reloc.c
242@@ -6867,6 +6867,12 @@ ENUM
243 ENUMDOC
244 This is a 32 bit reloc for the microblaze to handle
245 expressions of the form "Symbol Op Symbol"
246+ENUM
247+ BFD_RELOC_MICROBLAZE_32_NONE
248+ENUMDOC
249+ This is a 32 bit reloc that stores the 32 bit pc relative
250+ value in two words (with an imm instruction). No relocation is
251+ done here - only used for relaxing
252 ENUM
253 BFD_RELOC_MICROBLAZE_64_NONE
254 ENUMDOC
255diff --git a/binutils/readelf.c b/binutils/readelf.c
256index 0f5977bc072..acd12713361 100644
257--- a/binutils/readelf.c
258+++ b/binutils/readelf.c
259@@ -14621,6 +14621,10 @@ is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
260 return reloc_type == 1; /* R_Z80_8. */
261 default:
262 return false;
263+ case EM_MICROBLAZE:
264+ return reloc_type == 33 /* R_MICROBLAZE_32_NONE. */
265+ || reloc_type == 0 /* R_MICROBLAZE_NONE. */
266+ || reloc_type == 9; /* R_MICROBLAZE_64_NONE. */
267 }
268 }
269
270diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
271index c927331ea0a..8018d1f5686 100644
272--- a/gas/config/tc-microblaze.c
273+++ b/gas/config/tc-microblaze.c
274@@ -2211,9 +2211,12 @@ md_apply_fix (fixS * fixP,
275 moves code around due to relaxing. */
276 if (fixP->fx_r_type == BFD_RELOC_64_PCREL)
277 fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
278+ else if (fixP->fx_r_type == BFD_RELOC_32)
279+ fixP->fx_r_type = BFD_RELOC_MICROBLAZE_32_NONE;
280 else
281 fixP->fx_r_type = BFD_RELOC_NONE;
282 fixP->fx_addsy = section_symbol (absolute_section);
283+ fixP->fx_done = 0;
284 }
285 return;
286 }
287@@ -2434,6 +2437,7 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
288 switch (fixp->fx_r_type)
289 {
290 case BFD_RELOC_NONE:
291+ case BFD_RELOC_MICROBLAZE_32_NONE:
292 case BFD_RELOC_MICROBLAZE_64_NONE:
293 case BFD_RELOC_32:
294 case BFD_RELOC_MICROBLAZE_32_LO:
295diff --git a/include/elf/microblaze.h b/include/elf/microblaze.h
296index 43ad3ad3904..a2e1ce4580f 100644
297--- a/include/elf/microblaze.h
298+++ b/include/elf/microblaze.h
299@@ -61,6 +61,8 @@ START_RELOC_NUMBERS (elf_microblaze_reloc_type)
300 RELOC_NUMBER (R_MICROBLAZE_TEXTPCREL_64, 30) /* PC-relative TEXT offset. */
301 RELOC_NUMBER (R_MICROBLAZE_TEXTREL_64, 31) /* TEXT Entry offset 64-bit. */
302 RELOC_NUMBER (R_MICROBLAZE_TEXTREL_32_LO, 32) /* TEXT Entry offset 32-bit. */
303+ RELOC_NUMBER (R_MICROBLAZE_32_NONE, 33)
304+
305 END_RELOC_NUMBERS (R_MICROBLAZE_max)
306
307 /* Global base address names. */
308--
3092.37.1 (Apple Git-137.1)
310