diff options
Diffstat (limited to 'meta/recipes-devtools/binutils/binutils/0036-2011-12-19-Chung-Lin-Tang-cltang-codesourcery.com.patch')
-rw-r--r-- | meta/recipes-devtools/binutils/binutils/0036-2011-12-19-Chung-Lin-Tang-cltang-codesourcery.com.patch | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/meta/recipes-devtools/binutils/binutils/0036-2011-12-19-Chung-Lin-Tang-cltang-codesourcery.com.patch b/meta/recipes-devtools/binutils/binutils/0036-2011-12-19-Chung-Lin-Tang-cltang-codesourcery.com.patch new file mode 100644 index 0000000000..9017c250de --- /dev/null +++ b/meta/recipes-devtools/binutils/binutils/0036-2011-12-19-Chung-Lin-Tang-cltang-codesourcery.com.patch | |||
@@ -0,0 +1,214 @@ | |||
1 | Upstream-Status: Backport | ||
2 | |||
3 | From 26e802720ccd055d70addadbc39f4119716f8573 Mon Sep 17 00:00:00 2001 | ||
4 | From: cltang <cltang> | ||
5 | Date: Mon, 19 Dec 2011 10:39:27 +0000 | ||
6 | Subject: [PATCH 036/262] 2011-12-19 Chung-Lin Tang | ||
7 | <cltang@codesourcery.com> | ||
8 | |||
9 | Backport from mainline: | ||
10 | |||
11 | 2011-12-19 Chung-Lin Tang <cltang@codesourcery.com> | ||
12 | Catherine Moore <clm@codesourcery.com> | ||
13 | Sandra Loosemore <sandra@codesourcery.com> | ||
14 | Richard Sandiford <rdsandiford@googlemail.com> | ||
15 | |||
16 | * elfxx-mips.c (mips_elf_local_pic_function_p): Return true when | ||
17 | H is a MIPS16 function with a kept 32-bit stub. Update comments. | ||
18 | (mips_elf_get_la25_target): New function. | ||
19 | (mips_elf_add_la25_intro): Change to use mips_elf_get_la25_target(). | ||
20 | (mips_elf_add_la25_stub): Move compute of use_trampoline_p down, | ||
21 | change to use mips_elf_get_la25_target(). | ||
22 | (mips_elf_relocation_needs_la25_stub): Add target_is_16_bit_code_p | ||
23 | parameter, add switch case for R_MIPS16_26. | ||
24 | (mips_elf_calculate_relocation): Redirect relocation to point to the | ||
25 | LA25 stub if it exists, instead of the MIPS16 stub. Update arguments | ||
26 | of call to mips_elf_relocation_needs_la25_stub(), don't use la25 stub | ||
27 | for mips16->mips16 calls. | ||
28 | (_bfd_mips_elf_check_relocs): Update arguments of call to | ||
29 | mips_elf_relocation_needs_la25_stub(). | ||
30 | (mips_elf_create_la25_stub): Change to use mips_elf_get_la25_target(). | ||
31 | |||
32 | diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c | ||
33 | index 3939183..9f3833b 100644 | ||
34 | --- a/bfd/elfxx-mips.c | ||
35 | +++ b/bfd/elfxx-mips.c | ||
36 | @@ -1575,9 +1575,10 @@ _bfd_mips_elf_init_stubs (struct bfd_link_info *info, | ||
37 | } | ||
38 | |||
39 | /* Return true if H is a locally-defined PIC function, in the sense | ||
40 | - that it might need $25 to be valid on entry. Note that MIPS16 | ||
41 | - functions never need $25 to be valid on entry; they set up $gp | ||
42 | - using PC-relative instructions instead. */ | ||
43 | + that it or its fn_stub might need $25 to be valid on entry. | ||
44 | + Note that MIPS16 functions set up $gp using PC-relative instructions, | ||
45 | + so they themselves never need $25 to be valid. Only non-MIPS16 | ||
46 | + entry points are of interest here. */ | ||
47 | |||
48 | static bfd_boolean | ||
49 | mips_elf_local_pic_function_p (struct mips_elf_link_hash_entry *h) | ||
50 | @@ -1586,11 +1587,32 @@ mips_elf_local_pic_function_p (struct mips_elf_link_hash_entry *h) | ||
51 | || h->root.root.type == bfd_link_hash_defweak) | ||
52 | && h->root.def_regular | ||
53 | && !bfd_is_abs_section (h->root.root.u.def.section) | ||
54 | - && !ELF_ST_IS_MIPS16 (h->root.other) | ||
55 | + && (!ELF_ST_IS_MIPS16 (h->root.other) | ||
56 | + || (h->fn_stub && h->need_fn_stub)) | ||
57 | && (PIC_OBJECT_P (h->root.root.u.def.section->owner) | ||
58 | || ELF_ST_IS_MIPS_PIC (h->root.other))); | ||
59 | } | ||
60 | |||
61 | +/* Set *SEC to the input section that contains the target of STUB. | ||
62 | + Return the offset of the target from the start of that section. */ | ||
63 | + | ||
64 | +static bfd_vma | ||
65 | +mips_elf_get_la25_target (struct mips_elf_la25_stub *stub, | ||
66 | + asection **sec) | ||
67 | +{ | ||
68 | + if (ELF_ST_IS_MIPS16 (stub->h->root.other)) | ||
69 | + { | ||
70 | + BFD_ASSERT (stub->h->need_fn_stub); | ||
71 | + *sec = stub->h->fn_stub; | ||
72 | + return 0; | ||
73 | + } | ||
74 | + else | ||
75 | + { | ||
76 | + *sec = stub->h->root.root.u.def.section; | ||
77 | + return stub->h->root.root.u.def.value; | ||
78 | + } | ||
79 | +} | ||
80 | + | ||
81 | /* STUB describes an la25 stub that we have decided to implement | ||
82 | by inserting an LUI/ADDIU pair before the target function. | ||
83 | Create the section and redirect the function symbol to it. */ | ||
84 | @@ -1615,7 +1637,7 @@ mips_elf_add_la25_intro (struct mips_elf_la25_stub *stub, | ||
85 | sprintf (name, ".text.stub.%d", (int) htab_elements (htab->la25_stubs)); | ||
86 | |||
87 | /* Create the section. */ | ||
88 | - input_section = stub->h->root.root.u.def.section; | ||
89 | + mips_elf_get_la25_target (stub, &input_section); | ||
90 | s = htab->add_stub_section (name, input_section, | ||
91 | input_section->output_section); | ||
92 | if (s == NULL) | ||
93 | @@ -1689,12 +1711,6 @@ mips_elf_add_la25_stub (struct bfd_link_info *info, | ||
94 | bfd_vma value; | ||
95 | void **slot; | ||
96 | |||
97 | - /* Prefer to use LUI/ADDIU stubs if the function is at the beginning | ||
98 | - of the section and if we would need no more than 2 nops. */ | ||
99 | - s = h->root.root.u.def.section; | ||
100 | - value = h->root.root.u.def.value; | ||
101 | - use_trampoline_p = (value != 0 || s->alignment_power > 4); | ||
102 | - | ||
103 | /* Describe the stub we want. */ | ||
104 | search.stub_section = NULL; | ||
105 | search.offset = 0; | ||
106 | @@ -1724,6 +1740,11 @@ mips_elf_add_la25_stub (struct bfd_link_info *info, | ||
107 | *stub = search; | ||
108 | *slot = stub; | ||
109 | |||
110 | + /* Prefer to use LUI/ADDIU stubs if the function is at the beginning | ||
111 | + of the section and if we would need no more than 2 nops. */ | ||
112 | + value = mips_elf_get_la25_target (stub, &s); | ||
113 | + use_trampoline_p = (value != 0 || s->alignment_power > 4); | ||
114 | + | ||
115 | h->la25_stub = stub; | ||
116 | return (use_trampoline_p | ||
117 | ? mips_elf_add_la25_trampoline (stub, info) | ||
118 | @@ -4911,7 +4932,8 @@ is_gott_symbol (struct bfd_link_info *info, struct elf_link_hash_entry *h) | ||
119 | stub. */ | ||
120 | |||
121 | static bfd_boolean | ||
122 | -mips_elf_relocation_needs_la25_stub (bfd *input_bfd, int r_type) | ||
123 | +mips_elf_relocation_needs_la25_stub (bfd *input_bfd, int r_type, | ||
124 | + bfd_boolean target_is_16_bit_code_p) | ||
125 | { | ||
126 | /* We specifically ignore branches and jumps from EF_PIC objects, | ||
127 | where the onus is on the compiler or programmer to perform any | ||
128 | @@ -4925,7 +4947,6 @@ mips_elf_relocation_needs_la25_stub (bfd *input_bfd, int r_type) | ||
129 | { | ||
130 | case R_MIPS_26: | ||
131 | case R_MIPS_PC16: | ||
132 | - case R_MIPS16_26: | ||
133 | case R_MICROMIPS_26_S1: | ||
134 | case R_MICROMIPS_PC7_S1: | ||
135 | case R_MICROMIPS_PC10_S1: | ||
136 | @@ -4933,6 +4954,9 @@ mips_elf_relocation_needs_la25_stub (bfd *input_bfd, int r_type) | ||
137 | case R_MICROMIPS_PC23_S2: | ||
138 | return TRUE; | ||
139 | |||
140 | + case R_MIPS16_26: | ||
141 | + return !target_is_16_bit_code_p; | ||
142 | + | ||
143 | default: | ||
144 | return FALSE; | ||
145 | } | ||
146 | @@ -5193,14 +5217,28 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, | ||
147 | have already noticed that we were going to need the | ||
148 | stub. */ | ||
149 | if (local_p) | ||
150 | - sec = elf_tdata (input_bfd)->local_stubs[r_symndx]; | ||
151 | + { | ||
152 | + sec = elf_tdata (input_bfd)->local_stubs[r_symndx]; | ||
153 | + value = 0; | ||
154 | + } | ||
155 | else | ||
156 | { | ||
157 | BFD_ASSERT (h->need_fn_stub); | ||
158 | - sec = h->fn_stub; | ||
159 | + if (h->la25_stub) | ||
160 | + { | ||
161 | + /* If a LA25 header for the stub itself exists, point to the | ||
162 | + prepended LUI/ADDIU sequence. */ | ||
163 | + sec = h->la25_stub->stub_section; | ||
164 | + value = h->la25_stub->offset; | ||
165 | + } | ||
166 | + else | ||
167 | + { | ||
168 | + sec = h->fn_stub; | ||
169 | + value = 0; | ||
170 | + } | ||
171 | } | ||
172 | |||
173 | - symbol = sec->output_section->vma + sec->output_offset; | ||
174 | + symbol = sec->output_section->vma + sec->output_offset + value; | ||
175 | /* The target is 16-bit, but the stub isn't. */ | ||
176 | target_is_16_bit_code_p = FALSE; | ||
177 | } | ||
178 | @@ -5250,7 +5288,8 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, | ||
179 | /* If this is a direct call to a PIC function, redirect to the | ||
180 | non-PIC stub. */ | ||
181 | else if (h != NULL && h->la25_stub | ||
182 | - && mips_elf_relocation_needs_la25_stub (input_bfd, r_type)) | ||
183 | + && mips_elf_relocation_needs_la25_stub (input_bfd, r_type, | ||
184 | + target_is_16_bit_code_p)) | ||
185 | symbol = (h->la25_stub->stub_section->output_section->vma | ||
186 | + h->la25_stub->stub_section->output_offset | ||
187 | + h->la25_stub->offset); | ||
188 | @@ -7925,7 +7964,9 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, | ||
189 | return FALSE; | ||
190 | } | ||
191 | |||
192 | - if (h != NULL && mips_elf_relocation_needs_la25_stub (abfd, r_type)) | ||
193 | + if (h != NULL | ||
194 | + && mips_elf_relocation_needs_la25_stub (abfd, r_type, | ||
195 | + ELF_ST_IS_MIPS16 (h->other))) | ||
196 | ((struct mips_elf_link_hash_entry *) h)->has_nonpic_branches = TRUE; | ||
197 | |||
198 | switch (r_type) | ||
199 | @@ -9622,9 +9663,9 @@ mips_elf_create_la25_stub (void **slot, void *data) | ||
200 | offset = stub->offset; | ||
201 | |||
202 | /* Work out the target address. */ | ||
203 | - target = (stub->h->root.root.u.def.section->output_section->vma | ||
204 | - + stub->h->root.root.u.def.section->output_offset | ||
205 | - + stub->h->root.root.u.def.value); | ||
206 | + target = mips_elf_get_la25_target (stub, &s); | ||
207 | + target += s->output_section->vma + s->output_offset; | ||
208 | + | ||
209 | target_high = ((target + 0x8000) >> 16) & 0xffff; | ||
210 | target_low = (target & 0xffff); | ||
211 | |||
212 | -- | ||
213 | 1.7.9.5 | ||
214 | |||