summaryrefslogtreecommitdiffstats
path: root/meta-microblaze/recipes-devtools
diff options
context:
space:
mode:
authorMark Hatle <mark.hatle@xilinx.com>2022-02-02 09:46:31 -0800
committerMark Hatle <mark.hatle@xilinx.com>2022-02-04 13:24:54 -0800
commit03f7b76106fc05999421d54cbf5d1d51bc83b25a (patch)
tree55a7ab1a3b438f7372d6fc10cad96277373ef8fe /meta-microblaze/recipes-devtools
parent53bf6148e9360bbfc9909ff7867dace9fc21bf88 (diff)
downloadmeta-xilinx-03f7b76106fc05999421d54cbf5d1d51bc83b25a.tar.gz
microblaze binutils: Integrate community binutils contributions
Three bug fixes suggested by community member dednev@rambler.ru: *elf*-microblaze-relaxation.patch short description: The roots of invalid data offsets (pointer) after relaxation are in internal symbol table cache handling. If symbol table was cached while section processing for garbage collection, the elf_tdata (abfd)->symtab_hdr pointer is not NULL, but (Elf_Internal_Sym *) symtab_hdr->contents array contains data for local symbols only. But in the repeated relocation processing there is no check whenever the symbol index is local (ELF32_R_SYM (irelscan->r_info) < symtab_hdr->sh_info) or global. This leads to the buffer overflow (global symbol index is out of bounds) and following invalid relocation processing, especially in extra relocation data modifications (f.e. irelscan->r_addend could be decreased by arbitrary values). *elf*-microblaze-no-keep-memory.patch short description: There is incorrect newly allocated buffers handling if internal memory caching is disabled (without --no-keep-memory ld switch). This leads to possible double free(...) calls for such data and results in unexpected ld termination with abort(). I've fixed this issue by implementing similar to the elf32-avr.c data buffer handling. *elf*-imm-check-for-relaxation.patch short description: I've reverted Xilinx path to the original GNU binutils bfd code for microblaze, because this patch incorrectly leaves some "imm -1" instructions in resulting binary file after relaxation and increases executable size. If you look at the IMM instruction argument processing in binutils/gas/config/tc-microblaze.c you will see, that gas checks are similar to the original bfd microblaze_elf_relax_section(...) Signed-off-by: Mark Hatle <mark.hatle@xilinx.com>
Diffstat (limited to 'meta-microblaze/recipes-devtools')
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils-microblaze.inc3
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0039-Patch-MicroBlaze-Double-free-with-ld-no-keep-memory.patch196
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0040-Patch-MicroBlaze-Fixing-the-imm-imml-generation-for-.patch47
-rw-r--r--meta-microblaze/recipes-devtools/binutils/binutils/0041-Patch-MicroBlaze-Invalid-data-offsets-pointer-after-.patch142
4 files changed, 388 insertions, 0 deletions
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils-microblaze.inc b/meta-microblaze/recipes-devtools/binutils/binutils-microblaze.inc
index 462bbefd..4a84be9e 100644
--- a/meta-microblaze/recipes-devtools/binutils/binutils-microblaze.inc
+++ b/meta-microblaze/recipes-devtools/binutils/binutils-microblaze.inc
@@ -39,4 +39,7 @@ SRC_URI:append = " \
39 file://0036-microblaze-Add-build_gdbserver-yes-to-top-level-conf.patch \ 39 file://0036-microblaze-Add-build_gdbserver-yes-to-top-level-conf.patch \
40 file://0037-Fixing-the-issues-related-to-GDB-7.12.patch \ 40 file://0037-Fixing-the-issues-related-to-GDB-7.12.patch \
41 file://0038-Patch-MB-MB-binutils-Upstream-port-issues.patch \ 41 file://0038-Patch-MB-MB-binutils-Upstream-port-issues.patch \
42 file://0039-Patch-MicroBlaze-Double-free-with-ld-no-keep-memory.patch \
43 file://0040-Patch-MicroBlaze-Fixing-the-imm-imml-generation-for-.patch \
44 file://0041-Patch-MicroBlaze-Invalid-data-offsets-pointer-after-.patch \
42 " 45 "
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0039-Patch-MicroBlaze-Double-free-with-ld-no-keep-memory.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0039-Patch-MicroBlaze-Double-free-with-ld-no-keep-memory.patch
new file mode 100644
index 00000000..b79640b0
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0039-Patch-MicroBlaze-Double-free-with-ld-no-keep-memory.patch
@@ -0,0 +1,196 @@
1From 64b96c071b051cb4eb7471ee016e12c50a00c9d0 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Mon, 24 Jan 2022 16:59:19 +0530
4Subject: [PATCH] [Patch,MicroBlaze] : Double free with ld --no-keep-memory.
5 Proposed patches from the community member (dednev@rambler.ru) for 2021.1.
6 [CR-1115233]
7
8---
9 bfd/elf32-microblaze.c | 39 ++++++++++++++++++++------------------
10 bfd/elf64-microblaze.c | 43 ++++++++++++++++++++----------------------
11 2 files changed, 41 insertions(+), 41 deletions(-)
12
13diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
14index 290e70e0f4..cbbedddd1a 100644
15--- a/bfd/elf32-microblaze.c
16+++ b/bfd/elf32-microblaze.c
17@@ -1839,10 +1839,8 @@ microblaze_elf_relax_section (bfd *abfd,
18 {
19 Elf_Internal_Shdr *symtab_hdr;
20 Elf_Internal_Rela *internal_relocs;
21- Elf_Internal_Rela *free_relocs = NULL;
22 Elf_Internal_Rela *irel, *irelend;
23 bfd_byte *contents = NULL;
24- bfd_byte *free_contents = NULL;
25 int rel_count;
26 unsigned int shndx;
27 int i, sym_index;
28@@ -1884,8 +1882,6 @@ microblaze_elf_relax_section (bfd *abfd,
29 internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory);
30 if (internal_relocs == NULL)
31 goto error_return;
32- if (! link_info->keep_memory)
33- free_relocs = internal_relocs;
34
35 sec->relax = (struct relax_table *) bfd_malloc ((sec->reloc_count + 1)
36 * sizeof (struct relax_table));
37@@ -1913,7 +1909,6 @@ microblaze_elf_relax_section (bfd *abfd,
38 contents = (bfd_byte *) bfd_malloc (sec->size);
39 if (contents == NULL)
40 goto error_return;
41- free_contents = contents;
42
43 if (!bfd_get_section_contents (abfd, sec, contents,
44 (file_ptr) 0, sec->size))
45@@ -2445,25 +2440,26 @@ microblaze_elf_relax_section (bfd *abfd,
46 }
47
48 elf_section_data (sec)->relocs = internal_relocs;
49- free_relocs = NULL;
50
51 elf_section_data (sec)->this_hdr.contents = contents;
52- free_contents = NULL;
53
54 symtab_hdr->contents = (bfd_byte *) isymbuf;
55 }
56
57- free (free_relocs);
58- free_relocs = NULL;
59+ if (internal_relocs != NULL
60+ && elf_section_data (sec)->relocs != internal_relocs)
61+ free (internal_relocs);
62
63- if (free_contents != NULL)
64- {
65- if (!link_info->keep_memory)
66- free (free_contents);
67+ if (contents != NULL
68+ && elf_section_data (sec)->this_hdr.contents != contents)
69+ {
70+ if (! link_info->keep_memory)
71+ free (contents);
72 else
73- /* Cache the section contents for elf_link_input_bfd. */
74- elf_section_data (sec)->this_hdr.contents = contents;
75- free_contents = NULL;
76+ {
77+ /* Cache the section contents for elf_link_input_bfd. */
78+ elf_section_data (sec)->this_hdr.contents = contents;
79+ }
80 }
81
82 if (sec->relax_count == 0)
83@@ -2477,8 +2473,15 @@ microblaze_elf_relax_section (bfd *abfd,
84 return true;
85
86 error_return:
87- free (free_relocs);
88- free (free_contents);
89+ if (isymbuf != NULL
90+ && symtab_hdr->contents != (unsigned char *) isymbuf)
91+ free (isymbuf);
92+ if (internal_relocs != NULL
93+ && elf_section_data (sec)->relocs != internal_relocs)
94+ free (internal_relocs);
95+ if (contents != NULL
96+ && elf_section_data (sec)->this_hdr.contents != contents)
97+ free (contents);
98 free (sec->relax);
99 sec->relax = NULL;
100 sec->relax_count = 0;
101diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
102index 7bad93e706..677499e672 100644
103--- a/bfd/elf64-microblaze.c
104+++ b/bfd/elf64-microblaze.c
105@@ -1849,10 +1849,8 @@ microblaze_elf_relax_section (bfd *abfd,
106 {
107 Elf_Internal_Shdr *symtab_hdr;
108 Elf_Internal_Rela *internal_relocs;
109- Elf_Internal_Rela *free_relocs = NULL;
110 Elf_Internal_Rela *irel, *irelend;
111 bfd_byte *contents = NULL;
112- bfd_byte *free_contents = NULL;
113 int rel_count;
114 unsigned int shndx;
115 int i, sym_index;
116@@ -1894,8 +1892,6 @@ microblaze_elf_relax_section (bfd *abfd,
117 internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory);
118 if (internal_relocs == NULL)
119 goto error_return;
120- if (! link_info->keep_memory)
121- free_relocs = internal_relocs;
122
123 sec->relax = (struct relax_table *) bfd_malloc ((sec->reloc_count + 1)
124 * sizeof (struct relax_table));
125@@ -1923,8 +1919,6 @@ microblaze_elf_relax_section (bfd *abfd,
126 contents = (bfd_byte *) bfd_malloc (sec->size);
127 if (contents == NULL)
128 goto error_return;
129- free_contents = contents;
130-
131 if (!bfd_get_section_contents (abfd, sec, contents,
132 (file_ptr) 0, sec->size))
133 goto error_return;
134@@ -2454,28 +2448,26 @@ microblaze_elf_relax_section (bfd *abfd,
135 }
136
137 elf_section_data (sec)->relocs = internal_relocs;
138- free_relocs = NULL;
139
140 elf_section_data (sec)->this_hdr.contents = contents;
141- free_contents = NULL;
142
143 symtab_hdr->contents = (bfd_byte *) isymbuf;
144 }
145
146- if (free_relocs != NULL)
147- {
148- free (free_relocs);
149- free_relocs = NULL;
150- }
151+ if (internal_relocs != NULL
152+ && elf_section_data (sec)->relocs != internal_relocs)
153+ free (internal_relocs);
154
155- if (free_contents != NULL)
156+ if (contents != NULL
157+ && elf_section_data (sec)->this_hdr.contents != contents)
158 {
159- if (!link_info->keep_memory)
160- free (free_contents);
161+ if (! link_info->keep_memory)
162+ free (contents);
163 else
164- /* Cache the section contents for elf_link_input_bfd. */
165- elf_section_data (sec)->this_hdr.contents = contents;
166- free_contents = NULL;
167+ {
168+ /* Cache the section contents for elf_link_input_bfd. */
169+ elf_section_data (sec)->this_hdr.contents = contents;
170+ }
171 }
172
173 if (sec->relax_count == 0)
174@@ -2489,10 +2481,15 @@ microblaze_elf_relax_section (bfd *abfd,
175 return true;
176
177 error_return:
178- if (free_relocs != NULL)
179- free (free_relocs);
180- if (free_contents != NULL)
181- free (free_contents);
182+ if (isymbuf != NULL
183+ && symtab_hdr->contents != (unsigned char *) isymbuf)
184+ free (isymbuf);
185+ if (internal_relocs != NULL
186+ && elf_section_data (sec)->relocs != internal_relocs)
187+ free (internal_relocs);
188+ if (contents != NULL
189+ && elf_section_data (sec)->this_hdr.contents != contents)
190+ free (contents);
191 if (sec->relax != NULL)
192 {
193 free (sec->relax);
194--
1952.17.1
196
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0040-Patch-MicroBlaze-Fixing-the-imm-imml-generation-for-.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0040-Patch-MicroBlaze-Fixing-the-imm-imml-generation-for-.patch
new file mode 100644
index 00000000..f93b87ee
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0040-Patch-MicroBlaze-Fixing-the-imm-imml-generation-for-.patch
@@ -0,0 +1,47 @@
1From 0435ac5ae5d2fa9da8561fd47802ca742061e462 Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Mon, 24 Jan 2022 16:21:33 +0530
4Subject: [PATCH] [Patch,MicroBlaze] : Fixing the imm/imml generation for 16
5 bit argument [CR-1115234].
6
7---
8 bfd/elf32-microblaze.c | 6 +++++-
9 bfd/elf64-microblaze.c | 5 ++++-
10 2 files changed, 9 insertions(+), 2 deletions(-)
11
12diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
13index 37a1873570..290e70e0f4 100644
14--- a/bfd/elf32-microblaze.c
15+++ b/bfd/elf32-microblaze.c
16@@ -1977,7 +1977,11 @@ microblaze_elf_relax_section (bfd *abfd,
17 else
18 symval += irel->r_addend;
19
20- if ((symval & 0xffff8000) == 0)
21+ /* Check for imm command argument value to decide if
22+ * we need full 32-bit value for next command */
23+ if ((symval & 0xffff8000) == 0
24+ || (symval & 0xffff8000) == 0xffff8000)
25+
26 {
27 /* We can delete this instruction. */
28 sec->relax[sec->relax_count].addr = irel->r_offset;
29diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
30index bd1c7d3b1f..7bad93e706 100644
31--- a/bfd/elf64-microblaze.c
32+++ b/bfd/elf64-microblaze.c
33@@ -1987,7 +1987,10 @@ microblaze_elf_relax_section (bfd *abfd,
34 else
35 symval += irel->r_addend;
36
37- if ((symval & 0xffff8000) == 0)
38+ /* Check for imm command argument value to decide if
39+ * we need full 32-bit value for next command */
40+ if ((symval & 0xffff8000) == 0
41+ || (symval & 0xffff8000) == 0xffff8000)
42 {
43 /* We can delete this instruction. */
44 sec->relax[sec->relax_count].addr = irel->r_offset;
45--
462.17.1
47
diff --git a/meta-microblaze/recipes-devtools/binutils/binutils/0041-Patch-MicroBlaze-Invalid-data-offsets-pointer-after-.patch b/meta-microblaze/recipes-devtools/binutils/binutils/0041-Patch-MicroBlaze-Invalid-data-offsets-pointer-after-.patch
new file mode 100644
index 00000000..f98f6e99
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/binutils/binutils/0041-Patch-MicroBlaze-Invalid-data-offsets-pointer-after-.patch
@@ -0,0 +1,142 @@
1From 9fb3bc7ade713f55182aae4c57f8504cc07c366b Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Mon, 24 Jan 2022 16:04:07 +0530
4Subject: [PATCH] [Patch,MicroBlaze] : Invalid data offsets (pointer) after
5 relaxation. Proposed patch from community member (dednev@rambler.ru) against
6 2021.1 [CR-1115232]
7
8---
9 bfd/elf32-microblaze.c | 18 ++++++++++++++++++
10 bfd/elf64-microblaze.c | 17 +++++++++++++++++
11 2 files changed, 35 insertions(+)
12
13diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
14index 713f5e8e50..37a1873570 100644
15--- a/bfd/elf32-microblaze.c
16+++ b/bfd/elf32-microblaze.c
17@@ -2131,6 +2131,9 @@ microblaze_elf_relax_section (bfd *abfd,
18 {
19 unsigned int val;
20
21+ if (ELF32_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
22+ continue;
23+
24 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
25
26 /* hax: We only do the following fixup for debug location lists. */
27@@ -2172,6 +2175,9 @@ microblaze_elf_relax_section (bfd *abfd,
28 }
29 if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
30 {
31+ if (ELF32_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
32+ continue;
33+
34 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
35
36 /* Look at the reloc only if the value has been resolved. */
37@@ -2204,6 +2210,9 @@ microblaze_elf_relax_section (bfd *abfd,
38 }
39 else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_SYM_OP_SYM)
40 {
41+ if (ELF32_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
42+ continue;
43+
44 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
45
46 /* Look at the reloc only if the value has been resolved. */
47@@ -2241,6 +2250,9 @@ microblaze_elf_relax_section (bfd *abfd,
48 || (ELF32_R_TYPE (irelscan->r_info)
49 == (int) R_MICROBLAZE_TEXTREL_32_LO))
50 {
51+ if (ELF32_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
52+ continue;
53+
54 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
55
56 /* Look at the reloc only if the value has been resolved. */
57@@ -2287,6 +2299,9 @@ microblaze_elf_relax_section (bfd *abfd,
58 || (ELF32_R_TYPE (irelscan->r_info)
59 == (int) R_MICROBLAZE_TEXTREL_64))
60 {
61+ if (ELF32_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
62+ continue;
63+
64 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
65
66 /* Look at the reloc only if the value has been resolved. */
67@@ -2331,6 +2346,9 @@ microblaze_elf_relax_section (bfd *abfd,
68 }
69 else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64_PCREL)
70 {
71+ if (ELF32_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
72+ continue;
73+
74 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
75
76 /* Look at the reloc only if the value has been resolved. */
77diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
78index 210b84b2a5..bd1c7d3b1f 100644
79--- a/bfd/elf64-microblaze.c
80+++ b/bfd/elf64-microblaze.c
81@@ -2138,6 +2138,8 @@ microblaze_elf_relax_section (bfd *abfd,
82 if (1 && ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_NONE)
83 {
84 unsigned int val;
85+ if (ELF64_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
86+ continue;
87
88 isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
89
90@@ -2180,6 +2182,9 @@ microblaze_elf_relax_section (bfd *abfd,
91 if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32
92 || ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_IMML_64)
93 {
94+ if (ELF64_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
95+ continue;
96+
97 isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
98
99 /* Look at the reloc only if the value has been resolved. */
100@@ -2212,6 +2217,9 @@ microblaze_elf_relax_section (bfd *abfd,
101 }
102 else if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_SYM_OP_SYM)
103 {
104+ if (ELF64_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
105+ continue;
106+
107 isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
108
109 /* Look at the reloc only if the value has been resolved. */
110@@ -2247,6 +2255,9 @@ microblaze_elf_relax_section (bfd *abfd,
111 || (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_LO)
112 || (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_TEXTREL_32_LO))
113 {
114+ if (ELF64_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
115+ continue;
116+
117 isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
118
119 /* Look at the reloc only if the value has been resolved. */
120@@ -2292,6 +2303,9 @@ microblaze_elf_relax_section (bfd *abfd,
121 if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64
122 || (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_TEXTREL_64))
123 {
124+ if (ELF64_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
125+ continue;
126+
127 isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
128
129 /* Look at the reloc only if the value has been resolved. */
130@@ -2339,6 +2353,9 @@ microblaze_elf_relax_section (bfd *abfd,
131 }
132 else if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64_PCREL)
133 {
134+ if (ELF64_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
135+ continue;
136+
137 isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
138
139 /* Look at the reloc only if the value has been resolved. */
140--
1412.17.1
142