diff options
Diffstat (limited to 'recipes-devtools/gdb/files/0008-Fixup-debug_loc-sections-after-linker-relaxation.patch')
-rw-r--r-- | recipes-devtools/gdb/files/0008-Fixup-debug_loc-sections-after-linker-relaxation.patch | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/recipes-devtools/gdb/files/0008-Fixup-debug_loc-sections-after-linker-relaxation.patch b/recipes-devtools/gdb/files/0008-Fixup-debug_loc-sections-after-linker-relaxation.patch new file mode 100644 index 00000000..95fc629b --- /dev/null +++ b/recipes-devtools/gdb/files/0008-Fixup-debug_loc-sections-after-linker-relaxation.patch | |||
@@ -0,0 +1,195 @@ | |||
1 | From: "Edgar E. Iglesias" <edgar.iglesias@gmail.com> | ||
2 | Date: Wed, 15 Feb 2012 13:53:02 +0100 | ||
3 | Subject: Fixup debug_loc sections after linker relaxation | ||
4 | |||
5 | Adds a new reloctype R_MICROBLAZE_32_NONE, used for passing | ||
6 | reloc info from the assembler to the linker when the linker | ||
7 | manages to fully resolve a local symbol reference. | ||
8 | |||
9 | This is a workaround for design flaws in the assembler to | ||
10 | linker interface with regards to linker relaxation. | ||
11 | |||
12 | Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com> | ||
13 | Upstream-Status: Pending | ||
14 | --- | ||
15 | bfd/bfd-in2.h | 5 +++++ | ||
16 | bfd/elf32-microblaze.c | 45 +++++++++++++++++++++++++++++++++++++-------- | ||
17 | bfd/libbfd.h | 1 + | ||
18 | bfd/reloc.c | 6 ++++++ | ||
19 | include/elf/microblaze.h | 1 + | ||
20 | 5 files changed, 50 insertions(+), 8 deletions(-) | ||
21 | mode change 100644 => 100755 bfd/elf32-microblaze.c | ||
22 | mode change 100644 => 100755 include/elf/microblaze.h | ||
23 | |||
24 | diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h | ||
25 | index 524e97e..17a5769 100644 | ||
26 | --- a/bfd/bfd-in2.h | ||
27 | +++ b/bfd/bfd-in2.h | ||
28 | @@ -5125,6 +5125,11 @@ value relative to the read-write small data area anchor */ | ||
29 | expressions of the form "Symbol Op Symbol" */ | ||
30 | BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM, | ||
31 | |||
32 | +/* This is a 32 bit reloc that stores the 32 bit pc relative | ||
33 | +value in two words (with an imm instruction). No relocation is | ||
34 | +done here - only used for relaxing */ | ||
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 | diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c | ||
41 | old mode 100644 | ||
42 | new mode 100755 | ||
43 | index 61926a4..c44c76f | ||
44 | --- a/bfd/elf32-microblaze.c | ||
45 | +++ b/bfd/elf32-microblaze.c | ||
46 | @@ -177,6 +177,20 @@ static reloc_howto_type microblaze_elf_howto_raw[] = | ||
47 | FALSE), /* PC relative offset? */ | ||
48 | |||
49 | /* This reloc does nothing. Used for relaxation. */ | ||
50 | + HOWTO (R_MICROBLAZE_32_NONE, /* Type. */ | ||
51 | + 0, /* Rightshift. */ | ||
52 | + 2, /* Size (0 = byte, 1 = short, 2 = long). */ | ||
53 | + 32, /* Bitsize. */ | ||
54 | + TRUE, /* PC_relative. */ | ||
55 | + 0, /* Bitpos. */ | ||
56 | + complain_overflow_bitfield, /* Complain on overflow. */ | ||
57 | + NULL, /* Special Function. */ | ||
58 | + "R_MICROBLAZE_32_NONE",/* Name. */ | ||
59 | + FALSE, /* Partial Inplace. */ | ||
60 | + 0, /* Source Mask. */ | ||
61 | + 0, /* Dest Mask. */ | ||
62 | + FALSE), /* PC relative offset? */ | ||
63 | + | ||
64 | HOWTO (R_MICROBLAZE_64_NONE, /* Type. */ | ||
65 | 0, /* Rightshift. */ | ||
66 | 2, /* Size (0 = byte, 1 = short, 2 = long). */ | ||
67 | @@ -532,7 +546,10 @@ microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, | ||
68 | case BFD_RELOC_NONE: | ||
69 | microblaze_reloc = R_MICROBLAZE_NONE; | ||
70 | break; | ||
71 | - case BFD_RELOC_MICROBLAZE_64_NONE: | ||
72 | + case BFD_RELOC_MICROBLAZE_32_NONE: | ||
73 | + microblaze_reloc = R_MICROBLAZE_32_NONE; | ||
74 | + break; | ||
75 | + case BFD_RELOC_MICROBLAZE_64_NONE: | ||
76 | microblaze_reloc = R_MICROBLAZE_64_NONE; | ||
77 | break; | ||
78 | case BFD_RELOC_32: | ||
79 | @@ -1912,14 +1929,22 @@ microblaze_elf_relax_section (bfd *abfd, | ||
80 | } | ||
81 | break; | ||
82 | case R_MICROBLAZE_NONE: | ||
83 | + case R_MICROBLAZE_32_NONE: | ||
84 | { | ||
85 | /* This was a PC-relative instruction that was | ||
86 | completely resolved. */ | ||
87 | int sfix, efix; | ||
88 | + unsigned int val; | ||
89 | bfd_vma target_address; | ||
90 | 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 | + | ||
94 | + /* 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 | + } | ||
99 | irel->r_addend -= (efix - sfix); | ||
100 | /* Should use HOWTO. */ | ||
101 | microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset, | ||
102 | @@ -1967,12 +1992,16 @@ microblaze_elf_relax_section (bfd *abfd, | ||
103 | irelscanend = irelocs + o->reloc_count; | ||
104 | for (irelscan = irelocs; irelscan < irelscanend; irelscan++) | ||
105 | { | ||
106 | - if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_NONE) | ||
107 | + if (1 && ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_NONE) | ||
108 | { | ||
109 | unsigned int val; | ||
110 | |||
111 | isym = isymbuf + ELF32_R_SYM (irelscan->r_info); | ||
112 | |||
113 | + /* hax: We only do the following fixup for debug location lists. */ | ||
114 | + if (strcmp(".debug_loc", o->name)) | ||
115 | + continue; | ||
116 | + | ||
117 | /* This was a PC-relative instruction that was completely resolved. */ | ||
118 | if (ocontents == NULL) | ||
119 | { | ||
120 | @@ -1997,15 +2026,15 @@ microblaze_elf_relax_section (bfd *abfd, | ||
121 | } | ||
122 | } | ||
123 | |||
124 | - irelscan->r_addend -= calc_fixup (irelscan->r_addend | ||
125 | - + isym->st_value, sec); | ||
126 | val = bfd_get_32 (abfd, ocontents + irelscan->r_offset); | ||
127 | + if (val != irelscan->r_addend) { | ||
128 | + fprintf(stderr, "%d: CORRUPT relax reloc! %x %lx\n", __LINE__, val, irelscan->r_addend); | ||
129 | + } | ||
130 | + | ||
131 | + irelscan->r_addend -= calc_fixup (irelscan->r_addend, 0, sec); | ||
132 | microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset, | ||
133 | irelscan->r_addend); | ||
134 | } | ||
135 | - if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64_NONE) { | ||
136 | - fprintf(stderr, "Unhandled NONE 64\n"); | ||
137 | - } | ||
138 | if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32) | ||
139 | { | ||
140 | isym = isymbuf + ELF32_R_SYM (irelscan->r_info); | ||
141 | @@ -2065,7 +2094,7 @@ microblaze_elf_relax_section (bfd *abfd, | ||
142 | elf_section_data (o)->this_hdr.contents = ocontents; | ||
143 | } | ||
144 | } | ||
145 | - irelscan->r_addend -= calc_fixup (irel->r_addend | ||
146 | + irelscan->r_addend -= calc_fixup (irelscan->r_addend | ||
147 | + isym->st_value, | ||
148 | 0, | ||
149 | sec); | ||
150 | diff --git a/bfd/libbfd.h b/bfd/libbfd.h | ||
151 | index 857d1ea..5c627fe 100644 | ||
152 | --- a/bfd/libbfd.h | ||
153 | +++ b/bfd/libbfd.h | ||
154 | @@ -2492,6 +2492,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", | ||
155 | "BFD_RELOC_MICROBLAZE_32_ROSDA", | ||
156 | "BFD_RELOC_MICROBLAZE_32_RWSDA", | ||
157 | "BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM", | ||
158 | + "BFD_RELOC_MICROBLAZE_32_NONE", | ||
159 | "BFD_RELOC_MICROBLAZE_64_NONE", | ||
160 | "BFD_RELOC_MICROBLAZE_64_GOTPC", | ||
161 | "BFD_RELOC_MICROBLAZE_64_GOT", | ||
162 | diff --git a/bfd/reloc.c b/bfd/reloc.c | ||
163 | index b59ca00..c9c547e 100644 | ||
164 | --- a/bfd/reloc.c | ||
165 | +++ b/bfd/reloc.c | ||
166 | @@ -6001,6 +6001,12 @@ ENUMDOC | ||
167 | This is a 32 bit reloc for the microblaze to handle | ||
168 | expressions of the form "Symbol Op Symbol" | ||
169 | ENUM | ||
170 | + BFD_RELOC_MICROBLAZE_32_NONE | ||
171 | +ENUMDOC | ||
172 | + This is a 32 bit reloc that stores the 32 bit pc relative | ||
173 | + value in two words (with an imm instruction). No relocation is | ||
174 | + done here - only used for relaxing | ||
175 | +ENUM | ||
176 | BFD_RELOC_MICROBLAZE_64_NONE | ||
177 | ENUMDOC | ||
178 | This is a 64 bit reloc that stores the 32 bit pc relative | ||
179 | diff --git a/include/elf/microblaze.h b/include/elf/microblaze.h | ||
180 | old mode 100644 | ||
181 | new mode 100755 | ||
182 | index c4d9821..72771e8 | ||
183 | --- a/include/elf/microblaze.h | ||
184 | +++ b/include/elf/microblaze.h | ||
185 | @@ -58,6 +58,7 @@ START_RELOC_NUMBERS (elf_microblaze_reloc_type) | ||
186 | RELOC_NUMBER (R_MICROBLAZE_TLSDTPREL64, 27) /* TLS Offset Within TLS Block */ | ||
187 | RELOC_NUMBER (R_MICROBLAZE_TLSGOTTPREL32, 28) /* TLS Offset From Thread Pointer */ | ||
188 | RELOC_NUMBER (R_MICROBLAZE_TLSTPREL32, 29) /* TLS Offset From Thread Pointer */ | ||
189 | + RELOC_NUMBER (R_MICROBLAZE_32_NONE, 30) | ||
190 | |||
191 | END_RELOC_NUMBERS (R_MICROBLAZE_max) | ||
192 | |||
193 | -- | ||
194 | 1.7.9.5 | ||
195 | |||