blob: 18646195c45c186acb9b7e26a2f347d8c4602b7b [file] [log] [blame]
Andrew Geissler84ad7c52020-06-27 00:00:16 -05001From 62859c17077c559ad5e5db1cfbb496d5e8c3da68 Mon Sep 17 00:00:00 2001
Brad Bishop26bdd442019-08-16 17:08:17 -04002From: Nagaraju Mekala <nmekala@xilix.com>
3Date: Mon, 6 Feb 2017 15:53:08 +0530
Andrew Geissler84ad7c52020-06-27 00:00:16 -05004Subject: [PATCH 05/43] [LOCAL]: Fixup debug_loc sections after linker
5 relaxation Adds a new reloctype R_MICROBLAZE_32_NONE, used for passing reloc
6 info from the assembler to the linker when the linker manages to fully
7 resolve a local symbol reference.
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08008
9This is a workaround for design flaws in the assembler to
10linker interface with regards to linker relaxation.
11
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080012Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
Andrew Geissler84ad7c52020-06-27 00:00:16 -050013Signed-off-by: Nagaraju Mekala <nmekala@xilinx.com>
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080014---
Andrew Geissler84ad7c52020-06-27 00:00:16 -050015 bfd/bfd-in2.h | 9 +++++--
16 bfd/elf32-microblaze.c | 53 ++++++++++++++++++++++++++++----------
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080017 bfd/libbfd.h | 1 +
Andrew Geissler84ad7c52020-06-27 00:00:16 -050018 bfd/reloc.c | 6 +++++
Brad Bishop26bdd442019-08-16 17:08:17 -040019 include/elf/microblaze.h | 2 ++
20 7 files changed, 64 insertions(+), 16 deletions(-)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080021
Brad Bishop26bdd442019-08-16 17:08:17 -040022diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
Andrew Geissler84ad7c52020-06-27 00:00:16 -050023index e25da50aaf..721531886a 100644
Brad Bishop26bdd442019-08-16 17:08:17 -040024--- a/bfd/bfd-in2.h
25+++ b/bfd/bfd-in2.h
Andrew Geissler84ad7c52020-06-27 00:00:16 -050026@@ -5866,10 +5866,15 @@ value relative to the read-write small data area anchor */
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080027 expressions of the form "Symbol Op Symbol" */
28 BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM,
29
30-/* This is a 64 bit reloc that stores the 32 bit pc relative
31+/* This is a 32 bit reloc that stores the 32 bit pc relative
32 value in two words (with an imm instruction). No relocation is
33 done here - only used for relaxing */
34- BFD_RELOC_MICROBLAZE_64_NONE,
35+ BFD_RELOC_MICROBLAZE_32_NONE,
36+
37+/* This is a 64 bit reloc that stores the 32 bit pc relative
38+ * +value in two words (with an imm instruction). No relocation is
39+ * +done here - only used for relaxing */
40+ BFD_RELOC_MICROBLAZE_64_NONE,
41
42 /* This is a 64 bit reloc that stores the 32 bit pc relative
43 value in two words (with an imm instruction). The relocation is
Brad Bishop26bdd442019-08-16 17:08:17 -040044diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
Andrew Geissler84ad7c52020-06-27 00:00:16 -050045index 359484dd5e..1c69c269c7 100644
Brad Bishop26bdd442019-08-16 17:08:17 -040046--- a/bfd/elf32-microblaze.c
47+++ b/bfd/elf32-microblaze.c
48@@ -176,7 +176,21 @@ static reloc_howto_type microblaze_elf_howto_raw[] =
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080049 0x0000ffff, /* Dest Mask. */
50 FALSE), /* PC relative offset? */
51
Brad Bishop26bdd442019-08-16 17:08:17 -040052- /* This reloc does nothing. Used for relaxation. */
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080053+ HOWTO (R_MICROBLAZE_32_NONE, /* Type. */
54+ 0, /* Rightshift. */
55+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
56+ 32, /* Bitsize. */
57+ TRUE, /* PC_relative. */
58+ 0, /* Bitpos. */
59+ complain_overflow_bitfield, /* Complain on overflow. */
60+ NULL, /* Special Function. */
61+ "R_MICROBLAZE_32_NONE",/* Name. */
62+ FALSE, /* Partial Inplace. */
63+ 0, /* Source Mask. */
64+ 0, /* Dest Mask. */
65+ FALSE), /* PC relative offset? */
66+
Brad Bishop26bdd442019-08-16 17:08:17 -040067+ /* This reloc does nothing. Used for relaxation. */
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080068 HOWTO (R_MICROBLAZE_64_NONE, /* Type. */
69 0, /* Rightshift. */
Brad Bishop26bdd442019-08-16 17:08:17 -040070 3, /* Size (0 = byte, 1 = short, 2 = long). */
71@@ -562,6 +576,9 @@ microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080072 case BFD_RELOC_NONE:
73 microblaze_reloc = R_MICROBLAZE_NONE;
74 break;
75+ case BFD_RELOC_MICROBLAZE_32_NONE:
76+ microblaze_reloc = R_MICROBLAZE_32_NONE;
77+ break;
78 case BFD_RELOC_MICROBLAZE_64_NONE:
79 microblaze_reloc = R_MICROBLAZE_64_NONE;
80 break;
Brad Bishop26bdd442019-08-16 17:08:17 -040081@@ -1918,6 +1935,7 @@ microblaze_elf_relax_section (bfd *abfd,
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080082 }
83 break;
84 case R_MICROBLAZE_NONE:
Brad Bishop26bdd442019-08-16 17:08:17 -040085+ case R_MICROBLAZE_32_NONE:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080086 {
87 /* This was a PC-relative instruction that was
88 completely resolved. */
Brad Bishop26bdd442019-08-16 17:08:17 -040089@@ -1926,12 +1944,18 @@ microblaze_elf_relax_section (bfd *abfd,
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080090 target_address = irel->r_addend + irel->r_offset;
91 sfix = calc_fixup (irel->r_offset, 0, sec);
92 efix = calc_fixup (target_address, 0, sec);
93+
Brad Bishop26bdd442019-08-16 17:08:17 -040094+ /* Validate the in-band val. */
95+ val = bfd_get_32 (abfd, contents + irel->r_offset);
96+ if (val != irel->r_addend && ELF32_R_TYPE (irel->r_info) == R_MICROBLAZE_32_NONE) {
97+ fprintf(stderr, "%d: CORRUPT relax reloc %x %lx\n", __LINE__, val, irel->r_addend);
98+ }
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080099 irel->r_addend -= (efix - sfix);
100 /* Should use HOWTO. */
101 microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset,
Brad Bishop26bdd442019-08-16 17:08:17 -0400102 irel->r_addend);
103- }
104- break;
105+ }
106+ break;
107 case R_MICROBLAZE_64_NONE:
108 {
109 /* This was a PC-relative 64-bit instruction that was
110@@ -1973,12 +1997,16 @@ microblaze_elf_relax_section (bfd *abfd,
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800111 irelscanend = irelocs + o->reloc_count;
112 for (irelscan = irelocs; irelscan < irelscanend; irelscan++)
113 {
114- if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_NONE)
Brad Bishop26bdd442019-08-16 17:08:17 -0400115+ if (1 && ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_NONE)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800116 {
117 unsigned int val;
118
119 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
120
121+ /* hax: We only do the following fixup for debug location lists. */
122+ if (strcmp(".debug_loc", o->name))
123+ continue;
124+
125 /* This was a PC-relative instruction that was completely resolved. */
126 if (ocontents == NULL)
127 {
Brad Bishop26bdd442019-08-16 17:08:17 -0400128@@ -1999,18 +2027,17 @@ microblaze_elf_relax_section (bfd *abfd,
129 (file_ptr) 0,
130 o->rawsize))
131 goto error_return;
132- elf_section_data (o)->this_hdr.contents = ocontents;
133- }
134- }
135- irelscan->r_addend -= calc_fixup (irelscan->r_addend
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800136- + isym->st_value, sec);
Brad Bishop26bdd442019-08-16 17:08:17 -0400137+ elf_section_data (o)->this_hdr.contents = ocontents;
138+ }
139+ }
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800140 val = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800141+ if (val != irelscan->r_addend) {
142+ fprintf(stderr, "%d: CORRUPT relax reloc! %x %lx\n", __LINE__, val, irelscan->r_addend);
143+ }
144+ irelscan->r_addend -= calc_fixup (irelscan->r_addend, 0, sec);
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800145 microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
146 irelscan->r_addend);
147 }
148- if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64_NONE) {
149- fprintf(stderr, "Unhandled NONE 64\n");
150- }
151 if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
152 {
153 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
Brad Bishop26bdd442019-08-16 17:08:17 -0400154@@ -2070,7 +2097,7 @@ microblaze_elf_relax_section (bfd *abfd,
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800155 elf_section_data (o)->this_hdr.contents = ocontents;
156 }
157 }
158- irelscan->r_addend -= calc_fixup (irel->r_addend
159+ irelscan->r_addend -= calc_fixup (irelscan->r_addend
160 + isym->st_value,
161 0,
162 sec);
Brad Bishop26bdd442019-08-16 17:08:17 -0400163diff --git a/bfd/libbfd.h b/bfd/libbfd.h
Andrew Geissler84ad7c52020-06-27 00:00:16 -0500164index 36284d71a9..feb9fada1e 100644
Brad Bishop26bdd442019-08-16 17:08:17 -0400165--- a/bfd/libbfd.h
166+++ b/bfd/libbfd.h
167@@ -2901,6 +2901,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800168 "BFD_RELOC_MICROBLAZE_32_ROSDA",
169 "BFD_RELOC_MICROBLAZE_32_RWSDA",
170 "BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM",
171+ "BFD_RELOC_MICROBLAZE_32_NONE",
172 "BFD_RELOC_MICROBLAZE_64_NONE",
173 "BFD_RELOC_MICROBLAZE_64_GOTPC",
174 "BFD_RELOC_MICROBLAZE_64_GOT",
Brad Bishop26bdd442019-08-16 17:08:17 -0400175diff --git a/bfd/reloc.c b/bfd/reloc.c
Andrew Geissler84ad7c52020-06-27 00:00:16 -0500176index e6446a7809..87753ae4f0 100644
Brad Bishop26bdd442019-08-16 17:08:17 -0400177--- a/bfd/reloc.c
178+++ b/bfd/reloc.c
Andrew Geissler84ad7c52020-06-27 00:00:16 -0500179@@ -6795,6 +6795,12 @@ ENUM
180 ENUMDOC
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800181 This is a 32 bit reloc for the microblaze to handle
182 expressions of the form "Symbol Op Symbol"
Andrew Geissler84ad7c52020-06-27 00:00:16 -0500183+ENUM
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800184+ BFD_RELOC_MICROBLAZE_32_NONE
185+ENUMDOC
186+ This is a 32 bit reloc that stores the 32 bit pc relative
187+ value in two words (with an imm instruction). No relocation is
188+ done here - only used for relaxing
Andrew Geissler84ad7c52020-06-27 00:00:16 -0500189 ENUM
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800190 BFD_RELOC_MICROBLAZE_64_NONE
191 ENUMDOC
Brad Bishop26bdd442019-08-16 17:08:17 -0400192diff --git a/include/elf/microblaze.h b/include/elf/microblaze.h
Andrew Geissler84ad7c52020-06-27 00:00:16 -0500193index 830b5ad446..6ee0966444 100644
Brad Bishop26bdd442019-08-16 17:08:17 -0400194--- a/include/elf/microblaze.h
195+++ b/include/elf/microblaze.h
196@@ -61,6 +61,8 @@ START_RELOC_NUMBERS (elf_microblaze_reloc_type)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800197 RELOC_NUMBER (R_MICROBLAZE_TEXTPCREL_64, 30) /* PC-relative TEXT offset. */
198 RELOC_NUMBER (R_MICROBLAZE_TEXTREL_64, 31) /* TEXT Entry offset 64-bit. */
199 RELOC_NUMBER (R_MICROBLAZE_TEXTREL_32_LO, 32) /* TEXT Entry offset 32-bit. */
200+ RELOC_NUMBER (R_MICROBLAZE_32_NONE, 33)
Brad Bishop26bdd442019-08-16 17:08:17 -0400201+
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800202 END_RELOC_NUMBERS (R_MICROBLAZE_max)
203
204 /* Global base address names. */
Andrew Geissler84ad7c52020-06-27 00:00:16 -0500205--
2062.17.1
207