1*a9fa9459Szrj /* Or1k-specific support for 32-bit ELF.
2*a9fa9459Szrj Copyright (C) 2001-2016 Free Software Foundation, Inc.
3*a9fa9459Szrj Contributed for OR32 by Johan Rydberg, jrydberg@opencores.org
4*a9fa9459Szrj
5*a9fa9459Szrj PIC parts added by Stefan Kristiansson, stefan.kristiansson@saunalahti.fi,
6*a9fa9459Szrj largely based on elf32-m32r.c and elf32-microblaze.c.
7*a9fa9459Szrj
8*a9fa9459Szrj This file is part of BFD, the Binary File Descriptor library.
9*a9fa9459Szrj
10*a9fa9459Szrj This program is free software; you can redistribute it and/or modify
11*a9fa9459Szrj it under the terms of the GNU General Public License as published by
12*a9fa9459Szrj the Free Software Foundation; either version 3 of the License, or
13*a9fa9459Szrj (at your option) any later version.
14*a9fa9459Szrj
15*a9fa9459Szrj This program is distributed in the hope that it will be useful,
16*a9fa9459Szrj but WITHOUT ANY WARRANTY; without even the implied warranty of
17*a9fa9459Szrj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18*a9fa9459Szrj GNU General Public License for more details.
19*a9fa9459Szrj
20*a9fa9459Szrj You should have received a copy of the GNU General Public License
21*a9fa9459Szrj along with this program; if not, see <http://www.gnu.org/licenses/>. */
22*a9fa9459Szrj
23*a9fa9459Szrj #include "sysdep.h"
24*a9fa9459Szrj #include "bfd.h"
25*a9fa9459Szrj #include "libbfd.h"
26*a9fa9459Szrj #include "elf-bfd.h"
27*a9fa9459Szrj #include "elf/or1k.h"
28*a9fa9459Szrj #include "libiberty.h"
29*a9fa9459Szrj
30*a9fa9459Szrj #define PLT_ENTRY_SIZE 20
31*a9fa9459Szrj
32*a9fa9459Szrj #define PLT0_ENTRY_WORD0 0x19800000 /* l.movhi r12, 0 <- hi(.got+4) */
33*a9fa9459Szrj #define PLT0_ENTRY_WORD1 0xa98c0000 /* l.ori r12, r12, 0 <- lo(.got+4) */
34*a9fa9459Szrj #define PLT0_ENTRY_WORD2 0x85ec0004 /* l.lwz r15, 4(r12) <- *(.got+8)*/
35*a9fa9459Szrj #define PLT0_ENTRY_WORD3 0x44007800 /* l.jr r15 */
36*a9fa9459Szrj #define PLT0_ENTRY_WORD4 0x858c0000 /* l.lwz r12, 0(r12) */
37*a9fa9459Szrj
38*a9fa9459Szrj #define PLT0_PIC_ENTRY_WORD0 0x85900004 /* l.lwz r12, 4(r16) */
39*a9fa9459Szrj #define PLT0_PIC_ENTRY_WORD1 0x85f00008 /* l.lwz r15, 8(r16) */
40*a9fa9459Szrj #define PLT0_PIC_ENTRY_WORD2 0x44007800 /* l.jr r15 */
41*a9fa9459Szrj #define PLT0_PIC_ENTRY_WORD3 0x15000000 /* l.nop */
42*a9fa9459Szrj #define PLT0_PIC_ENTRY_WORD4 0x15000000 /* l.nop */
43*a9fa9459Szrj
44*a9fa9459Szrj #define PLT_ENTRY_WORD0 0x19800000 /* l.movhi r12, 0 <- hi(got idx addr) */
45*a9fa9459Szrj #define PLT_ENTRY_WORD1 0xa98c0000 /* l.ori r12, r12, 0 <- lo(got idx addr) */
46*a9fa9459Szrj #define PLT_ENTRY_WORD2 0x858c0000 /* l.lwz r12, 0(r12) */
47*a9fa9459Szrj #define PLT_ENTRY_WORD3 0x44006000 /* l.jr r12 */
48*a9fa9459Szrj #define PLT_ENTRY_WORD4 0xa9600000 /* l.ori r11, r0, 0 <- reloc offset */
49*a9fa9459Szrj
50*a9fa9459Szrj #define PLT_PIC_ENTRY_WORD0 0x85900000 /* l.lwz r12, 0(r16) <- index in got */
51*a9fa9459Szrj #define PLT_PIC_ENTRY_WORD1 0xa9600000 /* l.ori r11, r0, 0 <- reloc offset */
52*a9fa9459Szrj #define PLT_PIC_ENTRY_WORD2 0x44006000 /* l.jr r12 */
53*a9fa9459Szrj #define PLT_PIC_ENTRY_WORD3 0x15000000 /* l.nop */
54*a9fa9459Szrj #define PLT_PIC_ENTRY_WORD4 0x15000000 /* l.nop */
55*a9fa9459Szrj
56*a9fa9459Szrj #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
57*a9fa9459Szrj
58*a9fa9459Szrj static reloc_howto_type or1k_elf_howto_table[] =
59*a9fa9459Szrj {
60*a9fa9459Szrj /* This reloc does nothing. */
61*a9fa9459Szrj HOWTO (R_OR1K_NONE, /* type */
62*a9fa9459Szrj 0, /* rightshift */
63*a9fa9459Szrj 3, /* size (0 = byte, 1 = short, 2 = long) */
64*a9fa9459Szrj 0, /* bitsize */
65*a9fa9459Szrj FALSE, /* pc_relative */
66*a9fa9459Szrj 0, /* bitpos */
67*a9fa9459Szrj complain_overflow_dont, /* complain_on_overflow */
68*a9fa9459Szrj bfd_elf_generic_reloc, /* special_function */
69*a9fa9459Szrj "R_OR1K_NONE", /* name */
70*a9fa9459Szrj FALSE, /* partial_inplace */
71*a9fa9459Szrj 0, /* src_mask */
72*a9fa9459Szrj 0, /* dst_mask */
73*a9fa9459Szrj FALSE), /* pcrel_offset */
74*a9fa9459Szrj
75*a9fa9459Szrj HOWTO (R_OR1K_32,
76*a9fa9459Szrj 0, /* rightshift */
77*a9fa9459Szrj 2, /* size (0 = byte, 1 = short, 2 = long) */
78*a9fa9459Szrj 32, /* bitsize */
79*a9fa9459Szrj FALSE, /* pc_relative */
80*a9fa9459Szrj 0, /* bitpos */
81*a9fa9459Szrj complain_overflow_unsigned, /* complain_on_overflow */
82*a9fa9459Szrj bfd_elf_generic_reloc, /* special_function */
83*a9fa9459Szrj "R_OR1K_32", /* name */
84*a9fa9459Szrj FALSE, /* partial_inplace */
85*a9fa9459Szrj 0, /* src_mask */
86*a9fa9459Szrj 0xffffffff, /* dst_mask */
87*a9fa9459Szrj FALSE), /* pcrel_offset */
88*a9fa9459Szrj
89*a9fa9459Szrj HOWTO (R_OR1K_16,
90*a9fa9459Szrj 0, /* rightshift */
91*a9fa9459Szrj 1, /* size (0 = byte, 1 = short, 2 = long) */
92*a9fa9459Szrj 16, /* bitsize */
93*a9fa9459Szrj FALSE, /* pc_relative */
94*a9fa9459Szrj 0, /* bitpos */
95*a9fa9459Szrj complain_overflow_unsigned, /* complain_on_overflow */
96*a9fa9459Szrj bfd_elf_generic_reloc, /* special_function */
97*a9fa9459Szrj "R_OR1K_16", /* name */
98*a9fa9459Szrj FALSE, /* partial_inplace */
99*a9fa9459Szrj 0, /* src_mask */
100*a9fa9459Szrj 0xffff, /* dst_mask */
101*a9fa9459Szrj FALSE), /* pcrel_offset */
102*a9fa9459Szrj
103*a9fa9459Szrj HOWTO (R_OR1K_8,
104*a9fa9459Szrj 0, /* rightshift */
105*a9fa9459Szrj 0, /* size (0 = byte, 1 = short, 2 = long) */
106*a9fa9459Szrj 8, /* bitsize */
107*a9fa9459Szrj FALSE, /* pc_relative */
108*a9fa9459Szrj 0, /* bitpos */
109*a9fa9459Szrj complain_overflow_unsigned, /* complain_on_overflow */
110*a9fa9459Szrj bfd_elf_generic_reloc, /* special_function */
111*a9fa9459Szrj "R_OR1K_8", /* name */
112*a9fa9459Szrj FALSE, /* partial_inplace */
113*a9fa9459Szrj 0, /* src_mask */
114*a9fa9459Szrj 0xff, /* dst_mask */
115*a9fa9459Szrj FALSE), /* pcrel_offset */
116*a9fa9459Szrj
117*a9fa9459Szrj HOWTO (R_OR1K_LO_16_IN_INSN, /* type */
118*a9fa9459Szrj 0, /* rightshift */
119*a9fa9459Szrj 2, /* size (0 = byte, 1 = short, 2 = long) */
120*a9fa9459Szrj 16, /* bitsize */
121*a9fa9459Szrj FALSE, /* pc_relative */
122*a9fa9459Szrj 0, /* bitpos */
123*a9fa9459Szrj complain_overflow_dont, /* complain_on_overflow */
124*a9fa9459Szrj bfd_elf_generic_reloc, /* special_function */
125*a9fa9459Szrj "R_OR1K_LO_16_IN_INSN", /* name */
126*a9fa9459Szrj FALSE, /* partial_inplace */
127*a9fa9459Szrj 0, /* src_mask */
128*a9fa9459Szrj 0x0000ffff, /* dst_mask */
129*a9fa9459Szrj FALSE), /* pcrel_offset */
130*a9fa9459Szrj
131*a9fa9459Szrj HOWTO (R_OR1K_HI_16_IN_INSN, /* type */
132*a9fa9459Szrj 16, /* rightshift */
133*a9fa9459Szrj 2, /* size (0 = byte, 1 = short, 2 = long) */
134*a9fa9459Szrj 16, /* bitsize */
135*a9fa9459Szrj FALSE, /* pc_relative */
136*a9fa9459Szrj 0, /* bitpos */
137*a9fa9459Szrj complain_overflow_dont, /* complain_on_overflow */
138*a9fa9459Szrj bfd_elf_generic_reloc, /* special_function */
139*a9fa9459Szrj "R_OR1K_HI_16_IN_INSN", /* name */
140*a9fa9459Szrj FALSE, /* partial_inplace */
141*a9fa9459Szrj 0, /* src_mask */
142*a9fa9459Szrj 0x0000ffff, /* dst_mask */
143*a9fa9459Szrj FALSE), /* pcrel_offset */
144*a9fa9459Szrj
145*a9fa9459Szrj /* A PC relative 26 bit relocation, right shifted by 2. */
146*a9fa9459Szrj HOWTO (R_OR1K_INSN_REL_26, /* type */
147*a9fa9459Szrj 2, /* rightshift */
148*a9fa9459Szrj 2, /* size (0 = byte, 1 = short, 2 = long) */
149*a9fa9459Szrj 26, /* bitsize */
150*a9fa9459Szrj TRUE, /* pc_relative */
151*a9fa9459Szrj 0, /* bitpos */
152*a9fa9459Szrj complain_overflow_signed, /* complain_on_overflow */
153*a9fa9459Szrj bfd_elf_generic_reloc, /* special_function */
154*a9fa9459Szrj "R_OR1K_INSN_REL_26", /* name */
155*a9fa9459Szrj FALSE, /* partial_inplace */
156*a9fa9459Szrj 0, /* src_mask */
157*a9fa9459Szrj 0x03ffffff, /* dst_mask */
158*a9fa9459Szrj TRUE), /* pcrel_offset */
159*a9fa9459Szrj
160*a9fa9459Szrj /* GNU extension to record C++ vtable hierarchy. */
161*a9fa9459Szrj HOWTO (R_OR1K_GNU_VTINHERIT, /* type */
162*a9fa9459Szrj 0, /* rightshift */
163*a9fa9459Szrj 2, /* size (0 = byte, 1 = short, 2 = long) */
164*a9fa9459Szrj 0, /* bitsize */
165*a9fa9459Szrj FALSE, /* pc_relative */
166*a9fa9459Szrj 0, /* bitpos */
167*a9fa9459Szrj complain_overflow_dont, /* complain_on_overflow */
168*a9fa9459Szrj NULL, /* special_function */
169*a9fa9459Szrj "R_OR1K_GNU_VTINHERIT", /* name */
170*a9fa9459Szrj FALSE, /* partial_inplace */
171*a9fa9459Szrj 0, /* src_mask */
172*a9fa9459Szrj 0, /* dst_mask */
173*a9fa9459Szrj FALSE), /* pcrel_offset */
174*a9fa9459Szrj
175*a9fa9459Szrj /* GNU extension to record C++ vtable member usage. */
176*a9fa9459Szrj HOWTO (R_OR1K_GNU_VTENTRY, /* type */
177*a9fa9459Szrj 0, /* rightshift */
178*a9fa9459Szrj 2, /* size (0 = byte, 1 = short, 2 = long) */
179*a9fa9459Szrj 0, /* bitsize */
180*a9fa9459Szrj FALSE, /* pc_relative */
181*a9fa9459Szrj 0, /* bitpos */
182*a9fa9459Szrj complain_overflow_dont, /* complain_on_overflow */
183*a9fa9459Szrj _bfd_elf_rel_vtable_reloc_fn, /* special_function */
184*a9fa9459Szrj "R_OR1K_GNU_VTENTRY", /* name */
185*a9fa9459Szrj FALSE, /* partial_inplace */
186*a9fa9459Szrj 0, /* src_mask */
187*a9fa9459Szrj 0, /* dst_mask */
188*a9fa9459Szrj FALSE), /* pcrel_offset */
189*a9fa9459Szrj
190*a9fa9459Szrj HOWTO (R_OR1K_32_PCREL,
191*a9fa9459Szrj 0, /* rightshift */
192*a9fa9459Szrj 2, /* size (0 = byte, 1 = short, 2 = long) */
193*a9fa9459Szrj 32, /* bitsize */
194*a9fa9459Szrj TRUE, /* pc_relative */
195*a9fa9459Szrj 0, /* bitpos */
196*a9fa9459Szrj complain_overflow_signed, /* complain_on_overflow */
197*a9fa9459Szrj bfd_elf_generic_reloc, /* special_function */
198*a9fa9459Szrj "R_OR1K_32_PCREL", /* name */
199*a9fa9459Szrj FALSE, /* partial_inplace */
200*a9fa9459Szrj 0, /* src_mask */
201*a9fa9459Szrj 0xffffffff, /* dst_mask */
202*a9fa9459Szrj TRUE), /* pcrel_offset */
203*a9fa9459Szrj
204*a9fa9459Szrj HOWTO (R_OR1K_16_PCREL,
205*a9fa9459Szrj 0, /* rightshift */
206*a9fa9459Szrj 1, /* size (0 = byte, 1 = short, 2 = long) */
207*a9fa9459Szrj 16, /* bitsize */
208*a9fa9459Szrj TRUE, /* pc_relative */
209*a9fa9459Szrj 0, /* bitpos */
210*a9fa9459Szrj complain_overflow_signed, /* complain_on_overflow */
211*a9fa9459Szrj bfd_elf_generic_reloc, /* special_function */
212*a9fa9459Szrj "R_OR1K_16_PCREL", /* name */
213*a9fa9459Szrj FALSE, /* partial_inplace */
214*a9fa9459Szrj 0, /* src_mask */
215*a9fa9459Szrj 0xffff, /* dst_mask */
216*a9fa9459Szrj TRUE), /* pcrel_offset */
217*a9fa9459Szrj
218*a9fa9459Szrj HOWTO (R_OR1K_8_PCREL,
219*a9fa9459Szrj 0, /* rightshift */
220*a9fa9459Szrj 0, /* size (0 = byte, 1 = short, 2 = long) */
221*a9fa9459Szrj 8, /* bitsize */
222*a9fa9459Szrj TRUE, /* pc_relative */
223*a9fa9459Szrj 0, /* bitpos */
224*a9fa9459Szrj complain_overflow_signed, /* complain_on_overflow */
225*a9fa9459Szrj bfd_elf_generic_reloc, /* special_function */
226*a9fa9459Szrj "R_OR1K_8_PCREL", /* name */
227*a9fa9459Szrj FALSE, /* partial_inplace */
228*a9fa9459Szrj 0, /* src_mask */
229*a9fa9459Szrj 0xff, /* dst_mask */
230*a9fa9459Szrj TRUE), /* pcrel_offset */
231*a9fa9459Szrj
232*a9fa9459Szrj HOWTO (R_OR1K_GOTPC_HI16, /* Type. */
233*a9fa9459Szrj 16, /* Rightshift. */
234*a9fa9459Szrj 2, /* Size (0 = byte, 1 = short, 2 = long). */
235*a9fa9459Szrj 16, /* Bitsize. */
236*a9fa9459Szrj TRUE, /* PC_relative. */
237*a9fa9459Szrj 0, /* Bitpos. */
238*a9fa9459Szrj complain_overflow_dont, /* Complain on overflow. */
239*a9fa9459Szrj bfd_elf_generic_reloc, /* Special Function. */
240*a9fa9459Szrj "R_OR1K_GOTPC_HI16", /* Name. */
241*a9fa9459Szrj FALSE, /* Partial Inplace. */
242*a9fa9459Szrj 0, /* Source Mask. */
243*a9fa9459Szrj 0xffff, /* Dest Mask. */
244*a9fa9459Szrj TRUE), /* PC relative offset? */
245*a9fa9459Szrj
246*a9fa9459Szrj HOWTO (R_OR1K_GOTPC_LO16, /* Type. */
247*a9fa9459Szrj 0, /* Rightshift. */
248*a9fa9459Szrj 2, /* Size (0 = byte, 1 = short, 2 = long). */
249*a9fa9459Szrj 16, /* Bitsize. */
250*a9fa9459Szrj TRUE, /* PC_relative. */
251*a9fa9459Szrj 0, /* Bitpos. */
252*a9fa9459Szrj complain_overflow_dont, /* Complain on overflow. */
253*a9fa9459Szrj bfd_elf_generic_reloc, /* Special Function. */
254*a9fa9459Szrj "R_OR1K_GOTPC_LO16", /* Name. */
255*a9fa9459Szrj FALSE, /* Partial Inplace. */
256*a9fa9459Szrj 0, /* Source Mask. */
257*a9fa9459Szrj 0xffff, /* Dest Mask. */
258*a9fa9459Szrj TRUE), /* PC relative offset? */
259*a9fa9459Szrj
260*a9fa9459Szrj HOWTO (R_OR1K_GOT16, /* type */
261*a9fa9459Szrj 0, /* rightshift */
262*a9fa9459Szrj 2, /* size (0 = byte, 1 = short, 2 = long) */
263*a9fa9459Szrj 16, /* bitsize */
264*a9fa9459Szrj FALSE, /* pc_relative */
265*a9fa9459Szrj 0, /* bitpos */
266*a9fa9459Szrj complain_overflow_signed, /* complain_on_overflow */
267*a9fa9459Szrj bfd_elf_generic_reloc, /* special_function */
268*a9fa9459Szrj "R_OR1K_GOT16", /* name */
269*a9fa9459Szrj FALSE, /* partial_inplace */
270*a9fa9459Szrj 0, /* src_mask */
271*a9fa9459Szrj 0xffff, /* dst_mask */
272*a9fa9459Szrj FALSE), /* pcrel_offset */
273*a9fa9459Szrj
274*a9fa9459Szrj /* A 26 bit PLT relocation. Shifted by 2. */
275*a9fa9459Szrj HOWTO (R_OR1K_PLT26, /* Type. */
276*a9fa9459Szrj 2, /* Rightshift. */
277*a9fa9459Szrj 2, /* Size (0 = byte, 1 = short, 2 = long). */
278*a9fa9459Szrj 26, /* Bitsize. */
279*a9fa9459Szrj TRUE, /* PC_relative. */
280*a9fa9459Szrj 0, /* Bitpos. */
281*a9fa9459Szrj complain_overflow_dont, /* Complain on overflow. */
282*a9fa9459Szrj bfd_elf_generic_reloc,/* Special Function. */
283*a9fa9459Szrj "R_OR1K_PLT26", /* Name. */
284*a9fa9459Szrj FALSE, /* Partial Inplace. */
285*a9fa9459Szrj 0, /* Source Mask. */
286*a9fa9459Szrj 0x03ffffff, /* Dest Mask. */
287*a9fa9459Szrj TRUE), /* PC relative offset? */
288*a9fa9459Szrj
289*a9fa9459Szrj HOWTO (R_OR1K_GOTOFF_HI16, /* type */
290*a9fa9459Szrj 16, /* rightshift */
291*a9fa9459Szrj 2, /* size (0 = byte, 1 = short, 2 = long) */
292*a9fa9459Szrj 16, /* bitsize */
293*a9fa9459Szrj FALSE, /* pc_relative */
294*a9fa9459Szrj 0, /* bitpos */
295*a9fa9459Szrj complain_overflow_dont, /* complain_on_overflow */
296*a9fa9459Szrj bfd_elf_generic_reloc, /* special_function */
297*a9fa9459Szrj "R_OR1K_GOTOFF_HI16", /* name */
298*a9fa9459Szrj FALSE, /* partial_inplace */
299*a9fa9459Szrj 0x0, /* src_mask */
300*a9fa9459Szrj 0xffff, /* dst_mask */
301*a9fa9459Szrj FALSE), /* pcrel_offset */
302*a9fa9459Szrj
303*a9fa9459Szrj HOWTO (R_OR1K_GOTOFF_LO16, /* type */
304*a9fa9459Szrj 0, /* rightshift */
305*a9fa9459Szrj 2, /* size (0 = byte, 1 = short, 2 = long) */
306*a9fa9459Szrj 16, /* bitsize */
307*a9fa9459Szrj FALSE, /* pc_relative */
308*a9fa9459Szrj 0, /* bitpos */
309*a9fa9459Szrj complain_overflow_dont, /* complain_on_overflow */
310*a9fa9459Szrj bfd_elf_generic_reloc, /* special_function */
311*a9fa9459Szrj "R_OR1K_GOTOFF_LO16", /* name */
312*a9fa9459Szrj FALSE, /* partial_inplace */
313*a9fa9459Szrj 0x0, /* src_mask */
314*a9fa9459Szrj 0xffff, /* dst_mask */
315*a9fa9459Szrj FALSE), /* pcrel_offset */
316*a9fa9459Szrj
317*a9fa9459Szrj HOWTO (R_OR1K_COPY, /* type */
318*a9fa9459Szrj 0, /* rightshift */
319*a9fa9459Szrj 2, /* size (0 = byte, 1 = short, 2 = long) */
320*a9fa9459Szrj 32, /* bitsize */
321*a9fa9459Szrj FALSE, /* pc_relative */
322*a9fa9459Szrj 0, /* bitpos */
323*a9fa9459Szrj complain_overflow_bitfield, /* complain_on_overflow */
324*a9fa9459Szrj bfd_elf_generic_reloc, /* special_function */
325*a9fa9459Szrj "R_OR1K_COPY", /* name */
326*a9fa9459Szrj FALSE, /* partial_inplace */
327*a9fa9459Szrj 0xffffffff, /* src_mask */
328*a9fa9459Szrj 0xffffffff, /* dst_mask */
329*a9fa9459Szrj FALSE), /* pcrel_offset */
330*a9fa9459Szrj
331*a9fa9459Szrj HOWTO (R_OR1K_GLOB_DAT, /* type */
332*a9fa9459Szrj 0, /* rightshift */
333*a9fa9459Szrj 2, /* size (0 = byte, 1 = short, 2 = long) */
334*a9fa9459Szrj 32, /* bitsize */
335*a9fa9459Szrj FALSE, /* pc_relative */
336*a9fa9459Szrj 0, /* bitpos */
337*a9fa9459Szrj complain_overflow_bitfield, /* complain_on_overflow */
338*a9fa9459Szrj bfd_elf_generic_reloc, /* special_function */
339*a9fa9459Szrj "R_OR1K_GLOB_DAT", /* name */
340*a9fa9459Szrj FALSE, /* partial_inplace */
341*a9fa9459Szrj 0xffffffff, /* src_mask */
342*a9fa9459Szrj 0xffffffff, /* dst_mask */
343*a9fa9459Szrj FALSE), /* pcrel_offset */
344*a9fa9459Szrj
345*a9fa9459Szrj HOWTO (R_OR1K_JMP_SLOT, /* type */
346*a9fa9459Szrj 0, /* rightshift */
347*a9fa9459Szrj 2, /* size (0 = byte, 1 = short, 2 = long) */
348*a9fa9459Szrj 32, /* bitsize */
349*a9fa9459Szrj FALSE, /* pc_relative */
350*a9fa9459Szrj 0, /* bitpos */
351*a9fa9459Szrj complain_overflow_bitfield, /* complain_on_overflow */
352*a9fa9459Szrj bfd_elf_generic_reloc, /* special_function */
353*a9fa9459Szrj "R_OR1K_JMP_SLOT", /* name */
354*a9fa9459Szrj FALSE, /* partial_inplace */
355*a9fa9459Szrj 0xffffffff, /* src_mask */
356*a9fa9459Szrj 0xffffffff, /* dst_mask */
357*a9fa9459Szrj FALSE), /* pcrel_offset */
358*a9fa9459Szrj
359*a9fa9459Szrj HOWTO (R_OR1K_RELATIVE, /* type */
360*a9fa9459Szrj 0, /* rightshift */
361*a9fa9459Szrj 2, /* size (0 = byte, 1 = short, 2 = long) */
362*a9fa9459Szrj 32, /* bitsize */
363*a9fa9459Szrj FALSE, /* pc_relative */
364*a9fa9459Szrj 0, /* bitpos */
365*a9fa9459Szrj complain_overflow_bitfield, /* complain_on_overflow */
366*a9fa9459Szrj bfd_elf_generic_reloc, /* special_function */
367*a9fa9459Szrj "R_OR1K_RELATIVE", /* name */
368*a9fa9459Szrj FALSE, /* partial_inplace */
369*a9fa9459Szrj 0xffffffff, /* src_mask */
370*a9fa9459Szrj 0xffffffff, /* dst_mask */
371*a9fa9459Szrj FALSE), /* pcrel_offset */
372*a9fa9459Szrj
373*a9fa9459Szrj HOWTO (R_OR1K_TLS_GD_HI16, /* type */
374*a9fa9459Szrj 16, /* rightshift */
375*a9fa9459Szrj 2, /* size (0 = byte, 1 = short, 2 = long) */
376*a9fa9459Szrj 16, /* bitsize */
377*a9fa9459Szrj FALSE, /* pc_relative */
378*a9fa9459Szrj 0, /* bitpos */
379*a9fa9459Szrj complain_overflow_dont, /* complain_on_overflow */
380*a9fa9459Szrj bfd_elf_generic_reloc, /* special_function */
381*a9fa9459Szrj "R_OR1K_TLS_GD_HI16", /* name */
382*a9fa9459Szrj FALSE, /* partial_inplace */
383*a9fa9459Szrj 0x0, /* src_mask */
384*a9fa9459Szrj 0xffff, /* dst_mask */
385*a9fa9459Szrj FALSE), /* pcrel_offset */
386*a9fa9459Szrj
387*a9fa9459Szrj HOWTO (R_OR1K_TLS_GD_LO16, /* type */
388*a9fa9459Szrj 0, /* rightshift */
389*a9fa9459Szrj 2, /* size (0 = byte, 1 = short, 2 = long) */
390*a9fa9459Szrj 16, /* bitsize */
391*a9fa9459Szrj FALSE, /* pc_relative */
392*a9fa9459Szrj 0, /* bitpos */
393*a9fa9459Szrj complain_overflow_dont, /* complain_on_overflow */
394*a9fa9459Szrj bfd_elf_generic_reloc, /* special_function */
395*a9fa9459Szrj "R_OR1K_TLS_GD_LO16", /* name */
396*a9fa9459Szrj FALSE, /* partial_inplace */
397*a9fa9459Szrj 0x0, /* src_mask */
398*a9fa9459Szrj 0xffff, /* dst_mask */
399*a9fa9459Szrj FALSE), /* pcrel_offset */
400*a9fa9459Szrj
401*a9fa9459Szrj HOWTO (R_OR1K_TLS_LDM_HI16, /* type */
402*a9fa9459Szrj 16, /* rightshift */
403*a9fa9459Szrj 2, /* size (0 = byte, 1 = short, 2 = long) */
404*a9fa9459Szrj 16, /* bitsize */
405*a9fa9459Szrj FALSE, /* pc_relative */
406*a9fa9459Szrj 0, /* bitpos */
407*a9fa9459Szrj complain_overflow_dont, /* complain_on_overflow */
408*a9fa9459Szrj bfd_elf_generic_reloc, /* special_function */
409*a9fa9459Szrj "R_OR1K_TLS_LDM_HI16", /* name */
410*a9fa9459Szrj FALSE, /* partial_inplace */
411*a9fa9459Szrj 0x0, /* src_mask */
412*a9fa9459Szrj 0xffff, /* dst_mask */
413*a9fa9459Szrj FALSE), /* pcrel_offset */
414*a9fa9459Szrj
415*a9fa9459Szrj HOWTO (R_OR1K_TLS_LDM_LO16, /* type */
416*a9fa9459Szrj 0, /* rightshift */
417*a9fa9459Szrj 2, /* size (0 = byte, 1 = short, 2 = long) */
418*a9fa9459Szrj 16, /* bitsize */
419*a9fa9459Szrj FALSE, /* pc_relative */
420*a9fa9459Szrj 0, /* bitpos */
421*a9fa9459Szrj complain_overflow_dont, /* complain_on_overflow */
422*a9fa9459Szrj bfd_elf_generic_reloc, /* special_function */
423*a9fa9459Szrj "R_OR1K_TLS_LDM_LO16", /* name */
424*a9fa9459Szrj FALSE, /* partial_inplace */
425*a9fa9459Szrj 0x0, /* src_mask */
426*a9fa9459Szrj 0xffff, /* dst_mask */
427*a9fa9459Szrj FALSE), /* pcrel_offset */
428*a9fa9459Szrj
429*a9fa9459Szrj HOWTO (R_OR1K_TLS_LDO_HI16, /* type */
430*a9fa9459Szrj 16, /* rightshift */
431*a9fa9459Szrj 2, /* size (0 = byte, 1 = short, 2 = long) */
432*a9fa9459Szrj 16, /* bitsize */
433*a9fa9459Szrj FALSE, /* pc_relative */
434*a9fa9459Szrj 0, /* bitpos */
435*a9fa9459Szrj complain_overflow_dont, /* complain_on_overflow */
436*a9fa9459Szrj bfd_elf_generic_reloc, /* special_function */
437*a9fa9459Szrj "R_OR1K_TLS_LDO_HI16", /* name */
438*a9fa9459Szrj FALSE, /* partial_inplace */
439*a9fa9459Szrj 0x0, /* src_mask */
440*a9fa9459Szrj 0xffff, /* dst_mask */
441*a9fa9459Szrj FALSE), /* pcrel_offset */
442*a9fa9459Szrj
443*a9fa9459Szrj HOWTO (R_OR1K_TLS_LDO_LO16, /* type */
444*a9fa9459Szrj 0, /* rightshift */
445*a9fa9459Szrj 2, /* size (0 = byte, 1 = short, 2 = long) */
446*a9fa9459Szrj 16, /* bitsize */
447*a9fa9459Szrj FALSE, /* pc_relative */
448*a9fa9459Szrj 0, /* bitpos */
449*a9fa9459Szrj complain_overflow_dont, /* complain_on_overflow */
450*a9fa9459Szrj bfd_elf_generic_reloc, /* special_function */
451*a9fa9459Szrj "R_OR1K_TLS_LDO_LO16", /* name */
452*a9fa9459Szrj FALSE, /* partial_inplace */
453*a9fa9459Szrj 0x0, /* src_mask */
454*a9fa9459Szrj 0xffff, /* dst_mask */
455*a9fa9459Szrj FALSE), /* pcrel_offset */
456*a9fa9459Szrj
457*a9fa9459Szrj HOWTO (R_OR1K_TLS_IE_HI16, /* type */
458*a9fa9459Szrj 16, /* rightshift */
459*a9fa9459Szrj 2, /* size (0 = byte, 1 = short, 2 = long) */
460*a9fa9459Szrj 16, /* bitsize */
461*a9fa9459Szrj FALSE, /* pc_relative */
462*a9fa9459Szrj 0, /* bitpos */
463*a9fa9459Szrj complain_overflow_dont, /* complain_on_overflow */
464*a9fa9459Szrj bfd_elf_generic_reloc, /* special_function */
465*a9fa9459Szrj "R_OR1K_TLS_IE_HI16", /* name */
466*a9fa9459Szrj FALSE, /* partial_inplace */
467*a9fa9459Szrj 0x0, /* src_mask */
468*a9fa9459Szrj 0xffff, /* dst_mask */
469*a9fa9459Szrj FALSE), /* pcrel_offset */
470*a9fa9459Szrj
471*a9fa9459Szrj HOWTO (R_OR1K_TLS_IE_LO16, /* type */
472*a9fa9459Szrj 0, /* rightshift */
473*a9fa9459Szrj 2, /* size (0 = byte, 1 = short, 2 = long) */
474*a9fa9459Szrj 16, /* bitsize */
475*a9fa9459Szrj FALSE, /* pc_relative */
476*a9fa9459Szrj 0, /* bitpos */
477*a9fa9459Szrj complain_overflow_dont, /* complain_on_overflow */
478*a9fa9459Szrj bfd_elf_generic_reloc, /* special_function */
479*a9fa9459Szrj "R_OR1K_TLS_IE_LO16", /* name */
480*a9fa9459Szrj FALSE, /* partial_inplace */
481*a9fa9459Szrj 0x0, /* src_mask */
482*a9fa9459Szrj 0xffff, /* dst_mask */
483*a9fa9459Szrj FALSE), /* pcrel_offset */
484*a9fa9459Szrj
485*a9fa9459Szrj HOWTO (R_OR1K_TLS_LE_HI16, /* type */
486*a9fa9459Szrj 16, /* rightshift */
487*a9fa9459Szrj 2, /* size (0 = byte, 1 = short, 2 = long) */
488*a9fa9459Szrj 16, /* bitsize */
489*a9fa9459Szrj FALSE, /* pc_relative */
490*a9fa9459Szrj 0, /* bitpos */
491*a9fa9459Szrj complain_overflow_dont, /* complain_on_overflow */
492*a9fa9459Szrj bfd_elf_generic_reloc, /* special_function */
493*a9fa9459Szrj "R_OR1K_TLS_LE_HI16", /* name */
494*a9fa9459Szrj FALSE, /* partial_inplace */
495*a9fa9459Szrj 0x0, /* src_mask */
496*a9fa9459Szrj 0xffff, /* dst_mask */
497*a9fa9459Szrj FALSE), /* pcrel_offset */
498*a9fa9459Szrj
499*a9fa9459Szrj HOWTO (R_OR1K_TLS_LE_LO16, /* type */
500*a9fa9459Szrj 0, /* rightshift */
501*a9fa9459Szrj 2, /* size (0 = byte, 1 = short, 2 = long) */
502*a9fa9459Szrj 16, /* bitsize */
503*a9fa9459Szrj FALSE, /* pc_relative */
504*a9fa9459Szrj 0, /* bitpos */
505*a9fa9459Szrj complain_overflow_dont, /* complain_on_overflow */
506*a9fa9459Szrj bfd_elf_generic_reloc, /* special_function */
507*a9fa9459Szrj "R_OR1K_TLS_LE_LO16", /* name */
508*a9fa9459Szrj FALSE, /* partial_inplace */
509*a9fa9459Szrj 0x0, /* src_mask */
510*a9fa9459Szrj 0xffff, /* dst_mask */
511*a9fa9459Szrj FALSE), /* pcrel_offset */
512*a9fa9459Szrj
513*a9fa9459Szrj };
514*a9fa9459Szrj
515*a9fa9459Szrj /* Map BFD reloc types to Or1k ELF reloc types. */
516*a9fa9459Szrj
517*a9fa9459Szrj struct or1k_reloc_map
518*a9fa9459Szrj {
519*a9fa9459Szrj bfd_reloc_code_real_type bfd_reloc_val;
520*a9fa9459Szrj unsigned int or1k_reloc_val;
521*a9fa9459Szrj };
522*a9fa9459Szrj
523*a9fa9459Szrj static const struct or1k_reloc_map or1k_reloc_map[] =
524*a9fa9459Szrj {
525*a9fa9459Szrj { BFD_RELOC_NONE, R_OR1K_NONE },
526*a9fa9459Szrj { BFD_RELOC_32, R_OR1K_32 },
527*a9fa9459Szrj { BFD_RELOC_16, R_OR1K_16 },
528*a9fa9459Szrj { BFD_RELOC_8, R_OR1K_8 },
529*a9fa9459Szrj { BFD_RELOC_LO16, R_OR1K_LO_16_IN_INSN },
530*a9fa9459Szrj { BFD_RELOC_HI16, R_OR1K_HI_16_IN_INSN },
531*a9fa9459Szrj { BFD_RELOC_OR1K_REL_26, R_OR1K_INSN_REL_26 },
532*a9fa9459Szrj { BFD_RELOC_VTABLE_ENTRY, R_OR1K_GNU_VTENTRY },
533*a9fa9459Szrj { BFD_RELOC_VTABLE_INHERIT, R_OR1K_GNU_VTINHERIT },
534*a9fa9459Szrj { BFD_RELOC_32_PCREL, R_OR1K_32_PCREL },
535*a9fa9459Szrj { BFD_RELOC_16_PCREL, R_OR1K_16_PCREL },
536*a9fa9459Szrj { BFD_RELOC_8_PCREL, R_OR1K_8_PCREL },
537*a9fa9459Szrj { BFD_RELOC_OR1K_GOTPC_HI16, R_OR1K_GOTPC_HI16 },
538*a9fa9459Szrj { BFD_RELOC_OR1K_GOTPC_LO16, R_OR1K_GOTPC_LO16 },
539*a9fa9459Szrj { BFD_RELOC_OR1K_GOT16, R_OR1K_GOT16 },
540*a9fa9459Szrj { BFD_RELOC_OR1K_PLT26, R_OR1K_PLT26 },
541*a9fa9459Szrj { BFD_RELOC_OR1K_GOTOFF_HI16, R_OR1K_GOTOFF_HI16 },
542*a9fa9459Szrj { BFD_RELOC_OR1K_GOTOFF_LO16, R_OR1K_GOTOFF_LO16 },
543*a9fa9459Szrj { BFD_RELOC_OR1K_GLOB_DAT, R_OR1K_GLOB_DAT },
544*a9fa9459Szrj { BFD_RELOC_OR1K_COPY, R_OR1K_COPY },
545*a9fa9459Szrj { BFD_RELOC_OR1K_JMP_SLOT, R_OR1K_JMP_SLOT },
546*a9fa9459Szrj { BFD_RELOC_OR1K_RELATIVE, R_OR1K_RELATIVE },
547*a9fa9459Szrj { BFD_RELOC_OR1K_TLS_GD_HI16, R_OR1K_TLS_GD_HI16 },
548*a9fa9459Szrj { BFD_RELOC_OR1K_TLS_GD_LO16, R_OR1K_TLS_GD_LO16 },
549*a9fa9459Szrj { BFD_RELOC_OR1K_TLS_LDM_HI16, R_OR1K_TLS_LDM_HI16 },
550*a9fa9459Szrj { BFD_RELOC_OR1K_TLS_LDM_LO16, R_OR1K_TLS_LDM_LO16 },
551*a9fa9459Szrj { BFD_RELOC_OR1K_TLS_LDO_HI16, R_OR1K_TLS_LDO_HI16 },
552*a9fa9459Szrj { BFD_RELOC_OR1K_TLS_LDO_LO16, R_OR1K_TLS_LDO_LO16 },
553*a9fa9459Szrj { BFD_RELOC_OR1K_TLS_IE_HI16, R_OR1K_TLS_IE_HI16 },
554*a9fa9459Szrj { BFD_RELOC_OR1K_TLS_IE_LO16, R_OR1K_TLS_IE_LO16 },
555*a9fa9459Szrj { BFD_RELOC_OR1K_TLS_LE_HI16, R_OR1K_TLS_LE_HI16 },
556*a9fa9459Szrj { BFD_RELOC_OR1K_TLS_LE_LO16, R_OR1K_TLS_LE_LO16 },
557*a9fa9459Szrj };
558*a9fa9459Szrj
559*a9fa9459Szrj /* The linker needs to keep track of the number of relocs that it
560*a9fa9459Szrj decides to copy as dynamic relocs in check_relocs for each symbol.
561*a9fa9459Szrj This is so that it can later discard them if they are found to be
562*a9fa9459Szrj unnecessary. We store the information in a field extending the
563*a9fa9459Szrj regular ELF linker hash table. */
564*a9fa9459Szrj
565*a9fa9459Szrj struct elf_or1k_dyn_relocs
566*a9fa9459Szrj {
567*a9fa9459Szrj struct elf_or1k_dyn_relocs *next;
568*a9fa9459Szrj
569*a9fa9459Szrj /* The input section of the reloc. */
570*a9fa9459Szrj asection *sec;
571*a9fa9459Szrj
572*a9fa9459Szrj /* Total number of relocs copied for the input section. */
573*a9fa9459Szrj bfd_size_type count;
574*a9fa9459Szrj
575*a9fa9459Szrj /* Number of pc-relative relocs copied for the input section. */
576*a9fa9459Szrj bfd_size_type pc_count;
577*a9fa9459Szrj };
578*a9fa9459Szrj
579*a9fa9459Szrj #define TLS_UNKNOWN 0
580*a9fa9459Szrj #define TLS_NONE 1
581*a9fa9459Szrj #define TLS_GD 2
582*a9fa9459Szrj #define TLS_LD 3
583*a9fa9459Szrj #define TLS_IE 4
584*a9fa9459Szrj #define TLS_LE 5
585*a9fa9459Szrj
586*a9fa9459Szrj /* ELF linker hash entry. */
587*a9fa9459Szrj struct elf_or1k_link_hash_entry
588*a9fa9459Szrj {
589*a9fa9459Szrj struct elf_link_hash_entry root;
590*a9fa9459Szrj
591*a9fa9459Szrj /* Track dynamic relocs copied for this symbol. */
592*a9fa9459Szrj struct elf_or1k_dyn_relocs *dyn_relocs;
593*a9fa9459Szrj
594*a9fa9459Szrj /* Track type of TLS access. */
595*a9fa9459Szrj unsigned char tls_type;
596*a9fa9459Szrj };
597*a9fa9459Szrj
598*a9fa9459Szrj /* ELF object data. */
599*a9fa9459Szrj struct elf_or1k_obj_tdata
600*a9fa9459Szrj {
601*a9fa9459Szrj struct elf_obj_tdata root;
602*a9fa9459Szrj
603*a9fa9459Szrj /* tls_type for each local got entry. */
604*a9fa9459Szrj unsigned char *local_tls_type;
605*a9fa9459Szrj };
606*a9fa9459Szrj
607*a9fa9459Szrj #define elf_or1k_tdata(abfd) \
608*a9fa9459Szrj ((struct elf_or1k_obj_tdata *) (abfd)->tdata.any)
609*a9fa9459Szrj
610*a9fa9459Szrj #define elf_or1k_local_tls_type(abfd) \
611*a9fa9459Szrj (elf_or1k_tdata (abfd)->local_tls_type)
612*a9fa9459Szrj
613*a9fa9459Szrj /* ELF linker hash table. */
614*a9fa9459Szrj struct elf_or1k_link_hash_table
615*a9fa9459Szrj {
616*a9fa9459Szrj struct elf_link_hash_table root;
617*a9fa9459Szrj
618*a9fa9459Szrj /* Short-cuts to get to dynamic linker sections. */
619*a9fa9459Szrj asection *sgot;
620*a9fa9459Szrj asection *sgotplt;
621*a9fa9459Szrj asection *srelgot;
622*a9fa9459Szrj asection *splt;
623*a9fa9459Szrj asection *srelplt;
624*a9fa9459Szrj asection *sdynbss;
625*a9fa9459Szrj asection *srelbss;
626*a9fa9459Szrj
627*a9fa9459Szrj /* Small local sym to section mapping cache. */
628*a9fa9459Szrj struct sym_cache sym_sec;
629*a9fa9459Szrj };
630*a9fa9459Szrj
631*a9fa9459Szrj /* Get the ELF linker hash table from a link_info structure. */
632*a9fa9459Szrj #define or1k_elf_hash_table(p) \
633*a9fa9459Szrj (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
634*a9fa9459Szrj == OR1K_ELF_DATA ? ((struct elf_or1k_link_hash_table *) ((p)->hash)) : NULL)
635*a9fa9459Szrj
636*a9fa9459Szrj static bfd_boolean
elf_or1k_mkobject(bfd * abfd)637*a9fa9459Szrj elf_or1k_mkobject (bfd *abfd)
638*a9fa9459Szrj {
639*a9fa9459Szrj return bfd_elf_allocate_object (abfd, sizeof (struct elf_or1k_obj_tdata),
640*a9fa9459Szrj OR1K_ELF_DATA);
641*a9fa9459Szrj }
642*a9fa9459Szrj
643*a9fa9459Szrj /* Create an entry in an or1k ELF linker hash table. */
644*a9fa9459Szrj
645*a9fa9459Szrj static struct bfd_hash_entry *
or1k_elf_link_hash_newfunc(struct bfd_hash_entry * entry,struct bfd_hash_table * table,const char * string)646*a9fa9459Szrj or1k_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
647*a9fa9459Szrj struct bfd_hash_table *table,
648*a9fa9459Szrj const char *string)
649*a9fa9459Szrj {
650*a9fa9459Szrj struct elf_or1k_link_hash_entry *ret =
651*a9fa9459Szrj (struct elf_or1k_link_hash_entry *) entry;
652*a9fa9459Szrj
653*a9fa9459Szrj /* Allocate the structure if it has not already been allocated by a
654*a9fa9459Szrj subclass. */
655*a9fa9459Szrj if (ret == NULL)
656*a9fa9459Szrj ret = bfd_hash_allocate (table,
657*a9fa9459Szrj sizeof (struct elf_or1k_link_hash_entry));
658*a9fa9459Szrj if (ret == NULL)
659*a9fa9459Szrj return NULL;
660*a9fa9459Szrj
661*a9fa9459Szrj /* Call the allocation method of the superclass. */
662*a9fa9459Szrj ret = ((struct elf_or1k_link_hash_entry *)
663*a9fa9459Szrj _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
664*a9fa9459Szrj table, string));
665*a9fa9459Szrj if (ret != NULL)
666*a9fa9459Szrj {
667*a9fa9459Szrj struct elf_or1k_link_hash_entry *eh;
668*a9fa9459Szrj
669*a9fa9459Szrj eh = (struct elf_or1k_link_hash_entry *) ret;
670*a9fa9459Szrj eh->dyn_relocs = NULL;
671*a9fa9459Szrj eh->tls_type = TLS_UNKNOWN;
672*a9fa9459Szrj }
673*a9fa9459Szrj
674*a9fa9459Szrj return (struct bfd_hash_entry *) ret;
675*a9fa9459Szrj }
676*a9fa9459Szrj
677*a9fa9459Szrj /* Create an or1k ELF linker hash table. */
678*a9fa9459Szrj
679*a9fa9459Szrj static struct bfd_link_hash_table *
or1k_elf_link_hash_table_create(bfd * abfd)680*a9fa9459Szrj or1k_elf_link_hash_table_create (bfd *abfd)
681*a9fa9459Szrj {
682*a9fa9459Szrj struct elf_or1k_link_hash_table *ret;
683*a9fa9459Szrj bfd_size_type amt = sizeof (struct elf_or1k_link_hash_table);
684*a9fa9459Szrj
685*a9fa9459Szrj ret = bfd_zmalloc (amt);
686*a9fa9459Szrj if (ret == NULL)
687*a9fa9459Szrj return NULL;
688*a9fa9459Szrj
689*a9fa9459Szrj if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
690*a9fa9459Szrj or1k_elf_link_hash_newfunc,
691*a9fa9459Szrj sizeof (struct elf_or1k_link_hash_entry),
692*a9fa9459Szrj OR1K_ELF_DATA))
693*a9fa9459Szrj {
694*a9fa9459Szrj free (ret);
695*a9fa9459Szrj return NULL;
696*a9fa9459Szrj }
697*a9fa9459Szrj
698*a9fa9459Szrj return &ret->root.root;
699*a9fa9459Szrj }
700*a9fa9459Szrj
701*a9fa9459Szrj static reloc_howto_type *
or1k_reloc_type_lookup(bfd * abfd ATTRIBUTE_UNUSED,bfd_reloc_code_real_type code)702*a9fa9459Szrj or1k_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
703*a9fa9459Szrj bfd_reloc_code_real_type code)
704*a9fa9459Szrj {
705*a9fa9459Szrj unsigned int i;
706*a9fa9459Szrj
707*a9fa9459Szrj for (i = ARRAY_SIZE (or1k_reloc_map); i--;)
708*a9fa9459Szrj if (or1k_reloc_map[i].bfd_reloc_val == code)
709*a9fa9459Szrj return & or1k_elf_howto_table[or1k_reloc_map[i].or1k_reloc_val];
710*a9fa9459Szrj
711*a9fa9459Szrj return NULL;
712*a9fa9459Szrj }
713*a9fa9459Szrj
714*a9fa9459Szrj static reloc_howto_type *
or1k_reloc_name_lookup(bfd * abfd ATTRIBUTE_UNUSED,const char * r_name)715*a9fa9459Szrj or1k_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
716*a9fa9459Szrj const char *r_name)
717*a9fa9459Szrj {
718*a9fa9459Szrj unsigned int i;
719*a9fa9459Szrj
720*a9fa9459Szrj for (i = 0;
721*a9fa9459Szrj i < (sizeof (or1k_elf_howto_table)
722*a9fa9459Szrj / sizeof (or1k_elf_howto_table[0]));
723*a9fa9459Szrj i++)
724*a9fa9459Szrj if (or1k_elf_howto_table[i].name != NULL
725*a9fa9459Szrj && strcasecmp (or1k_elf_howto_table[i].name, r_name) == 0)
726*a9fa9459Szrj return &or1k_elf_howto_table[i];
727*a9fa9459Szrj
728*a9fa9459Szrj return NULL;
729*a9fa9459Szrj }
730*a9fa9459Szrj
731*a9fa9459Szrj /* Set the howto pointer for an Or1k ELF reloc. */
732*a9fa9459Szrj
733*a9fa9459Szrj static void
or1k_info_to_howto_rela(bfd * abfd ATTRIBUTE_UNUSED,arelent * cache_ptr,Elf_Internal_Rela * dst)734*a9fa9459Szrj or1k_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
735*a9fa9459Szrj arelent * cache_ptr,
736*a9fa9459Szrj Elf_Internal_Rela * dst)
737*a9fa9459Szrj {
738*a9fa9459Szrj unsigned int r_type;
739*a9fa9459Szrj
740*a9fa9459Szrj r_type = ELF32_R_TYPE (dst->r_info);
741*a9fa9459Szrj if (r_type >= (unsigned int) R_OR1K_max)
742*a9fa9459Szrj {
743*a9fa9459Szrj _bfd_error_handler (_("%B: invalid OR1K reloc number: %d"), abfd, r_type);
744*a9fa9459Szrj r_type = 0;
745*a9fa9459Szrj }
746*a9fa9459Szrj cache_ptr->howto = & or1k_elf_howto_table[r_type];
747*a9fa9459Szrj }
748*a9fa9459Szrj
749*a9fa9459Szrj
750*a9fa9459Szrj /* Return the relocation value for @tpoff relocations.. */
751*a9fa9459Szrj static bfd_vma
tpoff(struct bfd_link_info * info,bfd_vma address)752*a9fa9459Szrj tpoff (struct bfd_link_info *info, bfd_vma address)
753*a9fa9459Szrj {
754*a9fa9459Szrj /* If tls_sec is NULL, we should have signalled an error already. */
755*a9fa9459Szrj if (elf_hash_table (info)->tls_sec == NULL)
756*a9fa9459Szrj return 0;
757*a9fa9459Szrj
758*a9fa9459Szrj /* The thread pointer on or1k stores the address after the TCB where
759*a9fa9459Szrj the data is, just compute the difference. No need to compensate
760*a9fa9459Szrj for the size of TCB. */
761*a9fa9459Szrj return (address - elf_hash_table (info)->tls_sec->vma);
762*a9fa9459Szrj }
763*a9fa9459Szrj
764*a9fa9459Szrj /* Relocate an Or1k ELF section.
765*a9fa9459Szrj
766*a9fa9459Szrj The RELOCATE_SECTION function is called by the new ELF backend linker
767*a9fa9459Szrj to handle the relocations for a section.
768*a9fa9459Szrj
769*a9fa9459Szrj The relocs are always passed as Rela structures; if the section
770*a9fa9459Szrj actually uses Rel structures, the r_addend field will always be
771*a9fa9459Szrj zero.
772*a9fa9459Szrj
773*a9fa9459Szrj This function is responsible for adjusting the section contents as
774*a9fa9459Szrj necessary, and (if using Rela relocs and generating a relocatable
775*a9fa9459Szrj output file) adjusting the reloc addend as necessary.
776*a9fa9459Szrj
777*a9fa9459Szrj This function does not have to worry about setting the reloc
778*a9fa9459Szrj address or the reloc symbol index.
779*a9fa9459Szrj
780*a9fa9459Szrj LOCAL_SYMS is a pointer to the swapped in local symbols.
781*a9fa9459Szrj
782*a9fa9459Szrj LOCAL_SECTIONS is an array giving the section in the input file
783*a9fa9459Szrj corresponding to the st_shndx field of each local symbol.
784*a9fa9459Szrj
785*a9fa9459Szrj The global hash table entry for the global symbols can be found
786*a9fa9459Szrj via elf_sym_hashes (input_bfd).
787*a9fa9459Szrj
788*a9fa9459Szrj When generating relocatable output, this function must handle
789*a9fa9459Szrj STB_LOCAL/STT_SECTION symbols specially. The output symbol is
790*a9fa9459Szrj going to be the section symbol corresponding to the output
791*a9fa9459Szrj section, which means that the addend must be adjusted
792*a9fa9459Szrj accordingly. */
793*a9fa9459Szrj
794*a9fa9459Szrj static bfd_boolean
or1k_elf_relocate_section(bfd * output_bfd,struct bfd_link_info * info,bfd * input_bfd,asection * input_section,bfd_byte * contents,Elf_Internal_Rela * relocs,Elf_Internal_Sym * local_syms,asection ** local_sections)795*a9fa9459Szrj or1k_elf_relocate_section (bfd *output_bfd,
796*a9fa9459Szrj struct bfd_link_info *info,
797*a9fa9459Szrj bfd *input_bfd,
798*a9fa9459Szrj asection *input_section,
799*a9fa9459Szrj bfd_byte *contents,
800*a9fa9459Szrj Elf_Internal_Rela *relocs,
801*a9fa9459Szrj Elf_Internal_Sym *local_syms,
802*a9fa9459Szrj asection **local_sections)
803*a9fa9459Szrj {
804*a9fa9459Szrj Elf_Internal_Shdr *symtab_hdr;
805*a9fa9459Szrj struct elf_link_hash_entry **sym_hashes;
806*a9fa9459Szrj Elf_Internal_Rela *rel;
807*a9fa9459Szrj Elf_Internal_Rela *relend;
808*a9fa9459Szrj struct elf_or1k_link_hash_table *htab = or1k_elf_hash_table (info);
809*a9fa9459Szrj bfd *dynobj;
810*a9fa9459Szrj asection *sreloc;
811*a9fa9459Szrj bfd_vma *local_got_offsets;
812*a9fa9459Szrj asection *sgot;
813*a9fa9459Szrj
814*a9fa9459Szrj if (htab == NULL)
815*a9fa9459Szrj return FALSE;
816*a9fa9459Szrj
817*a9fa9459Szrj dynobj = htab->root.dynobj;
818*a9fa9459Szrj local_got_offsets = elf_local_got_offsets (input_bfd);
819*a9fa9459Szrj
820*a9fa9459Szrj sreloc = elf_section_data (input_section)->sreloc;
821*a9fa9459Szrj
822*a9fa9459Szrj sgot = htab->sgot;
823*a9fa9459Szrj
824*a9fa9459Szrj symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
825*a9fa9459Szrj sym_hashes = elf_sym_hashes (input_bfd);
826*a9fa9459Szrj relend = relocs + input_section->reloc_count;
827*a9fa9459Szrj
828*a9fa9459Szrj for (rel = relocs; rel < relend; rel++)
829*a9fa9459Szrj {
830*a9fa9459Szrj reloc_howto_type *howto;
831*a9fa9459Szrj unsigned long r_symndx;
832*a9fa9459Szrj Elf_Internal_Sym *sym;
833*a9fa9459Szrj asection *sec;
834*a9fa9459Szrj struct elf_link_hash_entry *h;
835*a9fa9459Szrj bfd_vma relocation;
836*a9fa9459Szrj bfd_reloc_status_type r;
837*a9fa9459Szrj const char *name = NULL;
838*a9fa9459Szrj int r_type;
839*a9fa9459Szrj
840*a9fa9459Szrj r_type = ELF32_R_TYPE (rel->r_info);
841*a9fa9459Szrj r_symndx = ELF32_R_SYM (rel->r_info);
842*a9fa9459Szrj
843*a9fa9459Szrj if (r_type == R_OR1K_GNU_VTINHERIT
844*a9fa9459Szrj || r_type == R_OR1K_GNU_VTENTRY)
845*a9fa9459Szrj continue;
846*a9fa9459Szrj
847*a9fa9459Szrj if (r_type < 0 || r_type >= (int) R_OR1K_max)
848*a9fa9459Szrj {
849*a9fa9459Szrj bfd_set_error (bfd_error_bad_value);
850*a9fa9459Szrj return FALSE;
851*a9fa9459Szrj }
852*a9fa9459Szrj
853*a9fa9459Szrj howto = or1k_elf_howto_table + ELF32_R_TYPE (rel->r_info);
854*a9fa9459Szrj h = NULL;
855*a9fa9459Szrj sym = NULL;
856*a9fa9459Szrj sec = NULL;
857*a9fa9459Szrj
858*a9fa9459Szrj if (r_symndx < symtab_hdr->sh_info)
859*a9fa9459Szrj {
860*a9fa9459Szrj sym = local_syms + r_symndx;
861*a9fa9459Szrj sec = local_sections[r_symndx];
862*a9fa9459Szrj relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
863*a9fa9459Szrj
864*a9fa9459Szrj name = bfd_elf_string_from_elf_section
865*a9fa9459Szrj (input_bfd, symtab_hdr->sh_link, sym->st_name);
866*a9fa9459Szrj name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
867*a9fa9459Szrj }
868*a9fa9459Szrj else
869*a9fa9459Szrj {
870*a9fa9459Szrj bfd_boolean unresolved_reloc, warned, ignored;
871*a9fa9459Szrj
872*a9fa9459Szrj RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
873*a9fa9459Szrj r_symndx, symtab_hdr, sym_hashes,
874*a9fa9459Szrj h, sec, relocation,
875*a9fa9459Szrj unresolved_reloc, warned, ignored);
876*a9fa9459Szrj }
877*a9fa9459Szrj
878*a9fa9459Szrj if (sec != NULL && discarded_section (sec))
879*a9fa9459Szrj RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
880*a9fa9459Szrj rel, 1, relend, howto, 0, contents);
881*a9fa9459Szrj
882*a9fa9459Szrj if (bfd_link_relocatable (info))
883*a9fa9459Szrj continue;
884*a9fa9459Szrj
885*a9fa9459Szrj switch (howto->type)
886*a9fa9459Szrj {
887*a9fa9459Szrj case R_OR1K_PLT26:
888*a9fa9459Szrj {
889*a9fa9459Szrj if (htab->splt != NULL && h != NULL
890*a9fa9459Szrj && h->plt.offset != (bfd_vma) -1)
891*a9fa9459Szrj {
892*a9fa9459Szrj relocation = (htab->splt->output_section->vma
893*a9fa9459Szrj + htab->splt->output_offset
894*a9fa9459Szrj + h->plt.offset);
895*a9fa9459Szrj }
896*a9fa9459Szrj break;
897*a9fa9459Szrj }
898*a9fa9459Szrj
899*a9fa9459Szrj case R_OR1K_GOT16:
900*a9fa9459Szrj /* Relocation is to the entry for this symbol in the global
901*a9fa9459Szrj offset table. */
902*a9fa9459Szrj BFD_ASSERT (sgot != NULL);
903*a9fa9459Szrj if (h != NULL)
904*a9fa9459Szrj {
905*a9fa9459Szrj bfd_boolean dyn;
906*a9fa9459Szrj bfd_vma off;
907*a9fa9459Szrj
908*a9fa9459Szrj off = h->got.offset;
909*a9fa9459Szrj BFD_ASSERT (off != (bfd_vma) -1);
910*a9fa9459Szrj
911*a9fa9459Szrj dyn = htab->root.dynamic_sections_created;
912*a9fa9459Szrj if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
913*a9fa9459Szrj bfd_link_pic (info),
914*a9fa9459Szrj h)
915*a9fa9459Szrj || (bfd_link_pic (info)
916*a9fa9459Szrj && SYMBOL_REFERENCES_LOCAL (info, h)))
917*a9fa9459Szrj {
918*a9fa9459Szrj /* This is actually a static link, or it is a
919*a9fa9459Szrj -Bsymbolic link and the symbol is defined
920*a9fa9459Szrj locally, or the symbol was forced to be local
921*a9fa9459Szrj because of a version file. We must initialize
922*a9fa9459Szrj this entry in the global offset table. Since the
923*a9fa9459Szrj offset must always be a multiple of 4, we use the
924*a9fa9459Szrj least significant bit to record whether we have
925*a9fa9459Szrj initialized it already.
926*a9fa9459Szrj
927*a9fa9459Szrj When doing a dynamic link, we create a .rela.got
928*a9fa9459Szrj relocation entry to initialize the value. This
929*a9fa9459Szrj is done in the finish_dynamic_symbol routine. */
930*a9fa9459Szrj if ((off & 1) != 0)
931*a9fa9459Szrj off &= ~1;
932*a9fa9459Szrj else
933*a9fa9459Szrj {
934*a9fa9459Szrj /* Write entry in GOT. */
935*a9fa9459Szrj bfd_put_32 (output_bfd, relocation,
936*a9fa9459Szrj sgot->contents + off);
937*a9fa9459Szrj /* Mark GOT entry as having been written. */
938*a9fa9459Szrj h->got.offset |= 1;
939*a9fa9459Szrj }
940*a9fa9459Szrj }
941*a9fa9459Szrj
942*a9fa9459Szrj relocation = sgot->output_offset + off;
943*a9fa9459Szrj }
944*a9fa9459Szrj else
945*a9fa9459Szrj {
946*a9fa9459Szrj bfd_vma off;
947*a9fa9459Szrj bfd_byte *loc;
948*a9fa9459Szrj
949*a9fa9459Szrj BFD_ASSERT (local_got_offsets != NULL
950*a9fa9459Szrj && local_got_offsets[r_symndx] != (bfd_vma) -1);
951*a9fa9459Szrj
952*a9fa9459Szrj /* Get offset into GOT table. */
953*a9fa9459Szrj off = local_got_offsets[r_symndx];
954*a9fa9459Szrj
955*a9fa9459Szrj /* The offset must always be a multiple of 4. We use
956*a9fa9459Szrj the least significant bit to record whether we have
957*a9fa9459Szrj already processed this entry. */
958*a9fa9459Szrj if ((off & 1) != 0)
959*a9fa9459Szrj off &= ~1;
960*a9fa9459Szrj else
961*a9fa9459Szrj {
962*a9fa9459Szrj /* Write entry in GOT. */
963*a9fa9459Szrj bfd_put_32 (output_bfd, relocation, sgot->contents + off);
964*a9fa9459Szrj if (bfd_link_pic (info))
965*a9fa9459Szrj {
966*a9fa9459Szrj asection *srelgot;
967*a9fa9459Szrj Elf_Internal_Rela outrel;
968*a9fa9459Szrj
969*a9fa9459Szrj /* We need to generate a R_OR1K_RELATIVE reloc
970*a9fa9459Szrj for the dynamic linker. */
971*a9fa9459Szrj srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
972*a9fa9459Szrj BFD_ASSERT (srelgot != NULL);
973*a9fa9459Szrj
974*a9fa9459Szrj outrel.r_offset = (sgot->output_section->vma
975*a9fa9459Szrj + sgot->output_offset
976*a9fa9459Szrj + off);
977*a9fa9459Szrj outrel.r_info = ELF32_R_INFO (0, R_OR1K_RELATIVE);
978*a9fa9459Szrj outrel.r_addend = relocation;
979*a9fa9459Szrj loc = srelgot->contents;
980*a9fa9459Szrj loc += srelgot->reloc_count * sizeof (Elf32_External_Rela);
981*a9fa9459Szrj bfd_elf32_swap_reloca_out (output_bfd, &outrel,loc);
982*a9fa9459Szrj ++srelgot->reloc_count;
983*a9fa9459Szrj }
984*a9fa9459Szrj
985*a9fa9459Szrj local_got_offsets[r_symndx] |= 1;
986*a9fa9459Szrj }
987*a9fa9459Szrj relocation = sgot->output_offset + off;
988*a9fa9459Szrj }
989*a9fa9459Szrj
990*a9fa9459Szrj /* Addend should be zero. */
991*a9fa9459Szrj if (rel->r_addend != 0)
992*a9fa9459Szrj (*_bfd_error_handler)
993*a9fa9459Szrj (_("internal error: addend should be zero for R_OR1K_GOT16"));
994*a9fa9459Szrj
995*a9fa9459Szrj break;
996*a9fa9459Szrj
997*a9fa9459Szrj case R_OR1K_GOTOFF_LO16:
998*a9fa9459Szrj case R_OR1K_GOTOFF_HI16:
999*a9fa9459Szrj /* Relocation is offset from GOT. */
1000*a9fa9459Szrj BFD_ASSERT (sgot != NULL);
1001*a9fa9459Szrj relocation -= sgot->output_section->vma;
1002*a9fa9459Szrj break;
1003*a9fa9459Szrj
1004*a9fa9459Szrj case R_OR1K_INSN_REL_26:
1005*a9fa9459Szrj case R_OR1K_HI_16_IN_INSN:
1006*a9fa9459Szrj case R_OR1K_LO_16_IN_INSN:
1007*a9fa9459Szrj case R_OR1K_32:
1008*a9fa9459Szrj /* R_OR1K_16? */
1009*a9fa9459Szrj {
1010*a9fa9459Szrj /* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
1011*a9fa9459Szrj from removed linkonce sections, or sections discarded by
1012*a9fa9459Szrj a linker script. */
1013*a9fa9459Szrj if (r_symndx == STN_UNDEF
1014*a9fa9459Szrj || (input_section->flags & SEC_ALLOC) == 0)
1015*a9fa9459Szrj break;
1016*a9fa9459Szrj
1017*a9fa9459Szrj if ((bfd_link_pic (info)
1018*a9fa9459Szrj && (h == NULL
1019*a9fa9459Szrj || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1020*a9fa9459Szrj || h->root.type != bfd_link_hash_undefweak)
1021*a9fa9459Szrj && (howto->type != R_OR1K_INSN_REL_26
1022*a9fa9459Szrj || !SYMBOL_CALLS_LOCAL (info, h)))
1023*a9fa9459Szrj || (!bfd_link_pic (info)
1024*a9fa9459Szrj && h != NULL
1025*a9fa9459Szrj && h->dynindx != -1
1026*a9fa9459Szrj && !h->non_got_ref
1027*a9fa9459Szrj && ((h->def_dynamic
1028*a9fa9459Szrj && !h->def_regular)
1029*a9fa9459Szrj || h->root.type == bfd_link_hash_undefweak
1030*a9fa9459Szrj || h->root.type == bfd_link_hash_undefined)))
1031*a9fa9459Szrj {
1032*a9fa9459Szrj Elf_Internal_Rela outrel;
1033*a9fa9459Szrj bfd_byte *loc;
1034*a9fa9459Szrj bfd_boolean skip;
1035*a9fa9459Szrj
1036*a9fa9459Szrj /* When generating a shared object, these relocations
1037*a9fa9459Szrj are copied into the output file to be resolved at run
1038*a9fa9459Szrj time. */
1039*a9fa9459Szrj
1040*a9fa9459Szrj BFD_ASSERT (sreloc != NULL);
1041*a9fa9459Szrj
1042*a9fa9459Szrj skip = FALSE;
1043*a9fa9459Szrj
1044*a9fa9459Szrj outrel.r_offset =
1045*a9fa9459Szrj _bfd_elf_section_offset (output_bfd, info, input_section,
1046*a9fa9459Szrj rel->r_offset);
1047*a9fa9459Szrj if (outrel.r_offset == (bfd_vma) -1)
1048*a9fa9459Szrj skip = TRUE;
1049*a9fa9459Szrj else if (outrel.r_offset == (bfd_vma) -2)
1050*a9fa9459Szrj skip = TRUE;
1051*a9fa9459Szrj outrel.r_offset += (input_section->output_section->vma
1052*a9fa9459Szrj + input_section->output_offset);
1053*a9fa9459Szrj
1054*a9fa9459Szrj if (skip)
1055*a9fa9459Szrj memset (&outrel, 0, sizeof outrel);
1056*a9fa9459Szrj /* h->dynindx may be -1 if the symbol was marked to
1057*a9fa9459Szrj become local. */
1058*a9fa9459Szrj else if (h != NULL
1059*a9fa9459Szrj && ((! info->symbolic && h->dynindx != -1)
1060*a9fa9459Szrj || !h->def_regular))
1061*a9fa9459Szrj {
1062*a9fa9459Szrj BFD_ASSERT (h->dynindx != -1);
1063*a9fa9459Szrj outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
1064*a9fa9459Szrj outrel.r_addend = rel->r_addend;
1065*a9fa9459Szrj }
1066*a9fa9459Szrj else
1067*a9fa9459Szrj {
1068*a9fa9459Szrj if (r_type == R_OR1K_32)
1069*a9fa9459Szrj {
1070*a9fa9459Szrj outrel.r_info = ELF32_R_INFO (0, R_OR1K_RELATIVE);
1071*a9fa9459Szrj outrel.r_addend = relocation + rel->r_addend;
1072*a9fa9459Szrj }
1073*a9fa9459Szrj else
1074*a9fa9459Szrj {
1075*a9fa9459Szrj BFD_FAIL ();
1076*a9fa9459Szrj (*_bfd_error_handler)
1077*a9fa9459Szrj (_("%B: probably compiled without -fPIC?"),
1078*a9fa9459Szrj input_bfd);
1079*a9fa9459Szrj bfd_set_error (bfd_error_bad_value);
1080*a9fa9459Szrj return FALSE;
1081*a9fa9459Szrj }
1082*a9fa9459Szrj }
1083*a9fa9459Szrj
1084*a9fa9459Szrj loc = sreloc->contents;
1085*a9fa9459Szrj loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
1086*a9fa9459Szrj bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1087*a9fa9459Szrj break;
1088*a9fa9459Szrj }
1089*a9fa9459Szrj break;
1090*a9fa9459Szrj }
1091*a9fa9459Szrj
1092*a9fa9459Szrj case R_OR1K_TLS_LDM_HI16:
1093*a9fa9459Szrj case R_OR1K_TLS_LDM_LO16:
1094*a9fa9459Szrj case R_OR1K_TLS_LDO_HI16:
1095*a9fa9459Szrj case R_OR1K_TLS_LDO_LO16:
1096*a9fa9459Szrj /* TODO: implement support for local dynamic. */
1097*a9fa9459Szrj BFD_FAIL ();
1098*a9fa9459Szrj (*_bfd_error_handler)
1099*a9fa9459Szrj (_("%B: support for local dynamic not implemented"),
1100*a9fa9459Szrj input_bfd);
1101*a9fa9459Szrj bfd_set_error (bfd_error_bad_value);
1102*a9fa9459Szrj return FALSE;
1103*a9fa9459Szrj
1104*a9fa9459Szrj
1105*a9fa9459Szrj case R_OR1K_TLS_GD_HI16:
1106*a9fa9459Szrj case R_OR1K_TLS_GD_LO16:
1107*a9fa9459Szrj case R_OR1K_TLS_IE_HI16:
1108*a9fa9459Szrj case R_OR1K_TLS_IE_LO16:
1109*a9fa9459Szrj {
1110*a9fa9459Szrj bfd_vma gotoff;
1111*a9fa9459Szrj Elf_Internal_Rela rela;
1112*a9fa9459Szrj bfd_byte *loc;
1113*a9fa9459Szrj int dynamic;
1114*a9fa9459Szrj
1115*a9fa9459Szrj sreloc = bfd_get_section_by_name (dynobj, ".rela.got");
1116*a9fa9459Szrj
1117*a9fa9459Szrj /* Mark as TLS related GOT entry by setting
1118*a9fa9459Szrj bit 2 as well as bit 1. */
1119*a9fa9459Szrj if (h != NULL)
1120*a9fa9459Szrj {
1121*a9fa9459Szrj gotoff = h->got.offset;
1122*a9fa9459Szrj h->got.offset |= 3;
1123*a9fa9459Szrj }
1124*a9fa9459Szrj else
1125*a9fa9459Szrj {
1126*a9fa9459Szrj gotoff = local_got_offsets[r_symndx];
1127*a9fa9459Szrj local_got_offsets[r_symndx] |= 3;
1128*a9fa9459Szrj }
1129*a9fa9459Szrj
1130*a9fa9459Szrj /* Only process the relocation once. */
1131*a9fa9459Szrj if (gotoff & 1)
1132*a9fa9459Szrj {
1133*a9fa9459Szrj relocation = sgot->output_offset + (gotoff & ~3);
1134*a9fa9459Szrj break;
1135*a9fa9459Szrj }
1136*a9fa9459Szrj
1137*a9fa9459Szrj BFD_ASSERT (elf_hash_table (info)->hgot == NULL
1138*a9fa9459Szrj || elf_hash_table (info)->hgot->root.u.def.value == 0);
1139*a9fa9459Szrj
1140*a9fa9459Szrj /* Dynamic entries will require relocations. if we do not need
1141*a9fa9459Szrj them we will just use the default R_OR1K_NONE and
1142*a9fa9459Szrj not set anything. */
1143*a9fa9459Szrj dynamic = bfd_link_pic (info)
1144*a9fa9459Szrj || (sec && (sec->flags & SEC_ALLOC) != 0
1145*a9fa9459Szrj && h != NULL
1146*a9fa9459Szrj && (h->root.type == bfd_link_hash_defweak || !h->def_regular));
1147*a9fa9459Szrj
1148*a9fa9459Szrj /* Shared GD. */
1149*a9fa9459Szrj if (dynamic && (howto->type == R_OR1K_TLS_GD_HI16
1150*a9fa9459Szrj || howto->type == R_OR1K_TLS_GD_LO16))
1151*a9fa9459Szrj {
1152*a9fa9459Szrj int i;
1153*a9fa9459Szrj
1154*a9fa9459Szrj /* Add DTPMOD and DTPOFF GOT and rela entries. */
1155*a9fa9459Szrj for (i = 0; i < 2; ++i)
1156*a9fa9459Szrj {
1157*a9fa9459Szrj rela.r_offset = sgot->output_section->vma +
1158*a9fa9459Szrj sgot->output_offset + gotoff + i*4;
1159*a9fa9459Szrj if (h != NULL && h->dynindx != -1)
1160*a9fa9459Szrj {
1161*a9fa9459Szrj rela.r_info = ELF32_R_INFO (h->dynindx,
1162*a9fa9459Szrj (i == 0 ? R_OR1K_TLS_DTPMOD : R_OR1K_TLS_DTPOFF));
1163*a9fa9459Szrj rela.r_addend = 0;
1164*a9fa9459Szrj }
1165*a9fa9459Szrj else
1166*a9fa9459Szrj {
1167*a9fa9459Szrj rela.r_info = ELF32_R_INFO (0,
1168*a9fa9459Szrj (i == 0 ? R_OR1K_TLS_DTPMOD : R_OR1K_TLS_DTPOFF));
1169*a9fa9459Szrj rela.r_addend = tpoff (info, relocation);
1170*a9fa9459Szrj }
1171*a9fa9459Szrj
1172*a9fa9459Szrj loc = sreloc->contents;
1173*a9fa9459Szrj loc += sreloc->reloc_count++ *
1174*a9fa9459Szrj sizeof (Elf32_External_Rela);
1175*a9fa9459Szrj
1176*a9fa9459Szrj bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
1177*a9fa9459Szrj bfd_put_32 (output_bfd, 0, sgot->contents + gotoff + i*4);
1178*a9fa9459Szrj }
1179*a9fa9459Szrj }
1180*a9fa9459Szrj /* Static GD. */
1181*a9fa9459Szrj else if (howto->type == R_OR1K_TLS_GD_HI16
1182*a9fa9459Szrj || howto->type == R_OR1K_TLS_GD_LO16)
1183*a9fa9459Szrj {
1184*a9fa9459Szrj bfd_put_32 (output_bfd, 1, sgot->contents + gotoff);
1185*a9fa9459Szrj bfd_put_32 (output_bfd, tpoff (info, relocation),
1186*a9fa9459Szrj sgot->contents + gotoff + 4);
1187*a9fa9459Szrj }
1188*a9fa9459Szrj /* Shared IE. */
1189*a9fa9459Szrj else if (dynamic)
1190*a9fa9459Szrj {
1191*a9fa9459Szrj /* Add TPOFF GOT and rela entries. */
1192*a9fa9459Szrj rela.r_offset = sgot->output_section->vma +
1193*a9fa9459Szrj sgot->output_offset + gotoff;
1194*a9fa9459Szrj if (h != NULL && h->dynindx != -1)
1195*a9fa9459Szrj {
1196*a9fa9459Szrj rela.r_info = ELF32_R_INFO (h->dynindx, R_OR1K_TLS_TPOFF);
1197*a9fa9459Szrj rela.r_addend = 0;
1198*a9fa9459Szrj }
1199*a9fa9459Szrj else
1200*a9fa9459Szrj {
1201*a9fa9459Szrj rela.r_info = ELF32_R_INFO (0, R_OR1K_TLS_TPOFF);
1202*a9fa9459Szrj rela.r_addend = tpoff (info, relocation);
1203*a9fa9459Szrj }
1204*a9fa9459Szrj
1205*a9fa9459Szrj loc = sreloc->contents;
1206*a9fa9459Szrj loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
1207*a9fa9459Szrj
1208*a9fa9459Szrj bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
1209*a9fa9459Szrj bfd_put_32 (output_bfd, 0, sgot->contents + gotoff);
1210*a9fa9459Szrj }
1211*a9fa9459Szrj /* Static IE. */
1212*a9fa9459Szrj else
1213*a9fa9459Szrj {
1214*a9fa9459Szrj bfd_put_32 (output_bfd, tpoff (info, relocation),
1215*a9fa9459Szrj sgot->contents + gotoff);
1216*a9fa9459Szrj }
1217*a9fa9459Szrj relocation = sgot->output_offset + gotoff;
1218*a9fa9459Szrj break;
1219*a9fa9459Szrj }
1220*a9fa9459Szrj case R_OR1K_TLS_LE_HI16:
1221*a9fa9459Szrj case R_OR1K_TLS_LE_LO16:
1222*a9fa9459Szrj
1223*a9fa9459Szrj /* Relocation is offset from TP. */
1224*a9fa9459Szrj relocation = tpoff (info, relocation);
1225*a9fa9459Szrj break;
1226*a9fa9459Szrj
1227*a9fa9459Szrj case R_OR1K_TLS_DTPMOD:
1228*a9fa9459Szrj case R_OR1K_TLS_DTPOFF:
1229*a9fa9459Szrj case R_OR1K_TLS_TPOFF:
1230*a9fa9459Szrj /* These are resolved dynamically on load and shouldn't
1231*a9fa9459Szrj be used as linker input. */
1232*a9fa9459Szrj BFD_FAIL ();
1233*a9fa9459Szrj (*_bfd_error_handler)
1234*a9fa9459Szrj (_("%B: will not resolve runtime TLS relocation"),
1235*a9fa9459Szrj input_bfd);
1236*a9fa9459Szrj bfd_set_error (bfd_error_bad_value);
1237*a9fa9459Szrj return FALSE;
1238*a9fa9459Szrj
1239*a9fa9459Szrj default:
1240*a9fa9459Szrj break;
1241*a9fa9459Szrj }
1242*a9fa9459Szrj r = _bfd_final_link_relocate (howto, input_bfd, input_section, contents,
1243*a9fa9459Szrj rel->r_offset, relocation, rel->r_addend);
1244*a9fa9459Szrj
1245*a9fa9459Szrj if (r != bfd_reloc_ok)
1246*a9fa9459Szrj {
1247*a9fa9459Szrj const char *msg = NULL;
1248*a9fa9459Szrj
1249*a9fa9459Szrj switch (r)
1250*a9fa9459Szrj {
1251*a9fa9459Szrj case bfd_reloc_overflow:
1252*a9fa9459Szrj (*info->callbacks->reloc_overflow)
1253*a9fa9459Szrj (info, (h ? &h->root : NULL), name, howto->name,
1254*a9fa9459Szrj (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
1255*a9fa9459Szrj break;
1256*a9fa9459Szrj
1257*a9fa9459Szrj case bfd_reloc_undefined:
1258*a9fa9459Szrj (*info->callbacks->undefined_symbol)
1259*a9fa9459Szrj (info, name, input_bfd, input_section, rel->r_offset, TRUE);
1260*a9fa9459Szrj break;
1261*a9fa9459Szrj
1262*a9fa9459Szrj case bfd_reloc_outofrange:
1263*a9fa9459Szrj msg = _("internal error: out of range error");
1264*a9fa9459Szrj break;
1265*a9fa9459Szrj
1266*a9fa9459Szrj case bfd_reloc_notsupported:
1267*a9fa9459Szrj msg = _("internal error: unsupported relocation error");
1268*a9fa9459Szrj break;
1269*a9fa9459Szrj
1270*a9fa9459Szrj case bfd_reloc_dangerous:
1271*a9fa9459Szrj msg = _("internal error: dangerous relocation");
1272*a9fa9459Szrj break;
1273*a9fa9459Szrj
1274*a9fa9459Szrj default:
1275*a9fa9459Szrj msg = _("internal error: unknown error");
1276*a9fa9459Szrj break;
1277*a9fa9459Szrj }
1278*a9fa9459Szrj
1279*a9fa9459Szrj if (msg)
1280*a9fa9459Szrj (*info->callbacks->warning) (info, msg, name, input_bfd,
1281*a9fa9459Szrj input_section, rel->r_offset);
1282*a9fa9459Szrj }
1283*a9fa9459Szrj }
1284*a9fa9459Szrj
1285*a9fa9459Szrj return TRUE;
1286*a9fa9459Szrj }
1287*a9fa9459Szrj
1288*a9fa9459Szrj /* Return the section that should be marked against GC for a given
1289*a9fa9459Szrj relocation. */
1290*a9fa9459Szrj
1291*a9fa9459Szrj static asection *
or1k_elf_gc_mark_hook(asection * sec,struct bfd_link_info * info,Elf_Internal_Rela * rel,struct elf_link_hash_entry * h,Elf_Internal_Sym * sym)1292*a9fa9459Szrj or1k_elf_gc_mark_hook (asection *sec,
1293*a9fa9459Szrj struct bfd_link_info *info,
1294*a9fa9459Szrj Elf_Internal_Rela *rel,
1295*a9fa9459Szrj struct elf_link_hash_entry *h,
1296*a9fa9459Szrj Elf_Internal_Sym *sym)
1297*a9fa9459Szrj {
1298*a9fa9459Szrj if (h != NULL)
1299*a9fa9459Szrj switch (ELF32_R_TYPE (rel->r_info))
1300*a9fa9459Szrj {
1301*a9fa9459Szrj case R_OR1K_GNU_VTINHERIT:
1302*a9fa9459Szrj case R_OR1K_GNU_VTENTRY:
1303*a9fa9459Szrj return NULL;
1304*a9fa9459Szrj }
1305*a9fa9459Szrj
1306*a9fa9459Szrj return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
1307*a9fa9459Szrj }
1308*a9fa9459Szrj
1309*a9fa9459Szrj static bfd_boolean
or1k_elf_gc_sweep_hook(bfd * abfd,struct bfd_link_info * info ATTRIBUTE_UNUSED,asection * sec,const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)1310*a9fa9459Szrj or1k_elf_gc_sweep_hook (bfd *abfd,
1311*a9fa9459Szrj struct bfd_link_info *info ATTRIBUTE_UNUSED,
1312*a9fa9459Szrj asection *sec,
1313*a9fa9459Szrj const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED)
1314*a9fa9459Szrj {
1315*a9fa9459Szrj /* Update the got entry reference counts for the section being removed. */
1316*a9fa9459Szrj Elf_Internal_Shdr *symtab_hdr;
1317*a9fa9459Szrj struct elf_link_hash_entry **sym_hashes;
1318*a9fa9459Szrj bfd_signed_vma *local_got_refcounts;
1319*a9fa9459Szrj const Elf_Internal_Rela *rel, *relend;
1320*a9fa9459Szrj
1321*a9fa9459Szrj elf_section_data (sec)->local_dynrel = NULL;
1322*a9fa9459Szrj
1323*a9fa9459Szrj symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1324*a9fa9459Szrj sym_hashes = elf_sym_hashes (abfd);
1325*a9fa9459Szrj local_got_refcounts = elf_local_got_refcounts (abfd);
1326*a9fa9459Szrj
1327*a9fa9459Szrj relend = relocs + sec->reloc_count;
1328*a9fa9459Szrj for (rel = relocs; rel < relend; rel++)
1329*a9fa9459Szrj {
1330*a9fa9459Szrj unsigned long r_symndx;
1331*a9fa9459Szrj struct elf_link_hash_entry *h = NULL;
1332*a9fa9459Szrj
1333*a9fa9459Szrj r_symndx = ELF32_R_SYM (rel->r_info);
1334*a9fa9459Szrj if (r_symndx >= symtab_hdr->sh_info)
1335*a9fa9459Szrj {
1336*a9fa9459Szrj h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1337*a9fa9459Szrj while (h->root.type == bfd_link_hash_indirect
1338*a9fa9459Szrj || h->root.type == bfd_link_hash_warning)
1339*a9fa9459Szrj h = (struct elf_link_hash_entry *) h->root.u.i.link;
1340*a9fa9459Szrj }
1341*a9fa9459Szrj
1342*a9fa9459Szrj switch (ELF32_R_TYPE (rel->r_info))
1343*a9fa9459Szrj {
1344*a9fa9459Szrj case R_OR1K_GOT16:
1345*a9fa9459Szrj if (h != NULL)
1346*a9fa9459Szrj {
1347*a9fa9459Szrj if (h->got.refcount > 0)
1348*a9fa9459Szrj h->got.refcount--;
1349*a9fa9459Szrj }
1350*a9fa9459Szrj else
1351*a9fa9459Szrj {
1352*a9fa9459Szrj if (local_got_refcounts && local_got_refcounts[r_symndx] > 0)
1353*a9fa9459Szrj local_got_refcounts[r_symndx]--;
1354*a9fa9459Szrj }
1355*a9fa9459Szrj break;
1356*a9fa9459Szrj
1357*a9fa9459Szrj default:
1358*a9fa9459Szrj break;
1359*a9fa9459Szrj }
1360*a9fa9459Szrj }
1361*a9fa9459Szrj return TRUE;
1362*a9fa9459Szrj }
1363*a9fa9459Szrj
1364*a9fa9459Szrj /* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
1365*a9fa9459Szrj shortcuts to them in our hash table. */
1366*a9fa9459Szrj
1367*a9fa9459Szrj static bfd_boolean
create_got_section(bfd * dynobj,struct bfd_link_info * info)1368*a9fa9459Szrj create_got_section (bfd *dynobj, struct bfd_link_info *info)
1369*a9fa9459Szrj {
1370*a9fa9459Szrj struct elf_or1k_link_hash_table *htab;
1371*a9fa9459Szrj asection *s;
1372*a9fa9459Szrj
1373*a9fa9459Szrj /* This function may be called more than once. */
1374*a9fa9459Szrj s = bfd_get_section_by_name (dynobj, ".got");
1375*a9fa9459Szrj if (s != NULL && (s->flags & SEC_LINKER_CREATED) != 0)
1376*a9fa9459Szrj return TRUE;
1377*a9fa9459Szrj
1378*a9fa9459Szrj htab = or1k_elf_hash_table (info);
1379*a9fa9459Szrj if (htab == NULL)
1380*a9fa9459Szrj return FALSE;
1381*a9fa9459Szrj
1382*a9fa9459Szrj if (! _bfd_elf_create_got_section (dynobj, info))
1383*a9fa9459Szrj return FALSE;
1384*a9fa9459Szrj
1385*a9fa9459Szrj htab->sgot = bfd_get_section_by_name (dynobj, ".got");
1386*a9fa9459Szrj htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
1387*a9fa9459Szrj htab->srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
1388*a9fa9459Szrj
1389*a9fa9459Szrj if (! htab->sgot || ! htab->sgotplt || ! htab->srelgot)
1390*a9fa9459Szrj abort ();
1391*a9fa9459Szrj
1392*a9fa9459Szrj if (! bfd_set_section_flags (dynobj, htab->srelgot, SEC_ALLOC
1393*a9fa9459Szrj | SEC_LOAD
1394*a9fa9459Szrj | SEC_HAS_CONTENTS
1395*a9fa9459Szrj | SEC_IN_MEMORY
1396*a9fa9459Szrj | SEC_LINKER_CREATED
1397*a9fa9459Szrj | SEC_READONLY)
1398*a9fa9459Szrj || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2))
1399*a9fa9459Szrj return FALSE;
1400*a9fa9459Szrj
1401*a9fa9459Szrj return TRUE;
1402*a9fa9459Szrj }
1403*a9fa9459Szrj
1404*a9fa9459Szrj /* Look through the relocs for a section during the first phase. */
1405*a9fa9459Szrj
1406*a9fa9459Szrj static bfd_boolean
or1k_elf_check_relocs(bfd * abfd,struct bfd_link_info * info,asection * sec,const Elf_Internal_Rela * relocs)1407*a9fa9459Szrj or1k_elf_check_relocs (bfd *abfd,
1408*a9fa9459Szrj struct bfd_link_info *info,
1409*a9fa9459Szrj asection *sec,
1410*a9fa9459Szrj const Elf_Internal_Rela *relocs)
1411*a9fa9459Szrj {
1412*a9fa9459Szrj Elf_Internal_Shdr *symtab_hdr;
1413*a9fa9459Szrj struct elf_link_hash_entry **sym_hashes;
1414*a9fa9459Szrj const Elf_Internal_Rela *rel;
1415*a9fa9459Szrj
1416*a9fa9459Szrj const Elf_Internal_Rela *rel_end;
1417*a9fa9459Szrj struct elf_or1k_link_hash_table *htab;
1418*a9fa9459Szrj bfd *dynobj;
1419*a9fa9459Szrj asection *sreloc = NULL;
1420*a9fa9459Szrj
1421*a9fa9459Szrj if (bfd_link_relocatable (info))
1422*a9fa9459Szrj return TRUE;
1423*a9fa9459Szrj
1424*a9fa9459Szrj symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1425*a9fa9459Szrj sym_hashes = elf_sym_hashes (abfd);
1426*a9fa9459Szrj
1427*a9fa9459Szrj htab = or1k_elf_hash_table (info);
1428*a9fa9459Szrj if (htab == NULL)
1429*a9fa9459Szrj return FALSE;
1430*a9fa9459Szrj
1431*a9fa9459Szrj dynobj = htab->root.dynobj;
1432*a9fa9459Szrj
1433*a9fa9459Szrj rel_end = relocs + sec->reloc_count;
1434*a9fa9459Szrj for (rel = relocs; rel < rel_end; rel++)
1435*a9fa9459Szrj {
1436*a9fa9459Szrj struct elf_link_hash_entry *h;
1437*a9fa9459Szrj unsigned long r_symndx;
1438*a9fa9459Szrj unsigned char tls_type;
1439*a9fa9459Szrj
1440*a9fa9459Szrj r_symndx = ELF32_R_SYM (rel->r_info);
1441*a9fa9459Szrj if (r_symndx < symtab_hdr->sh_info)
1442*a9fa9459Szrj h = NULL;
1443*a9fa9459Szrj else
1444*a9fa9459Szrj {
1445*a9fa9459Szrj h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1446*a9fa9459Szrj while (h->root.type == bfd_link_hash_indirect
1447*a9fa9459Szrj || h->root.type == bfd_link_hash_warning)
1448*a9fa9459Szrj h = (struct elf_link_hash_entry *) h->root.u.i.link;
1449*a9fa9459Szrj
1450*a9fa9459Szrj /* PR15323, ref flags aren't set for references in the same
1451*a9fa9459Szrj object. */
1452*a9fa9459Szrj h->root.non_ir_ref = 1;
1453*a9fa9459Szrj }
1454*a9fa9459Szrj
1455*a9fa9459Szrj switch (ELF32_R_TYPE (rel->r_info))
1456*a9fa9459Szrj {
1457*a9fa9459Szrj case R_OR1K_TLS_GD_HI16:
1458*a9fa9459Szrj case R_OR1K_TLS_GD_LO16:
1459*a9fa9459Szrj tls_type = TLS_GD;
1460*a9fa9459Szrj break;
1461*a9fa9459Szrj case R_OR1K_TLS_LDM_HI16:
1462*a9fa9459Szrj case R_OR1K_TLS_LDM_LO16:
1463*a9fa9459Szrj case R_OR1K_TLS_LDO_HI16:
1464*a9fa9459Szrj case R_OR1K_TLS_LDO_LO16:
1465*a9fa9459Szrj tls_type = TLS_LD;
1466*a9fa9459Szrj break;
1467*a9fa9459Szrj case R_OR1K_TLS_IE_HI16:
1468*a9fa9459Szrj case R_OR1K_TLS_IE_LO16:
1469*a9fa9459Szrj tls_type = TLS_IE;
1470*a9fa9459Szrj break;
1471*a9fa9459Szrj case R_OR1K_TLS_LE_HI16:
1472*a9fa9459Szrj case R_OR1K_TLS_LE_LO16:
1473*a9fa9459Szrj tls_type = TLS_LE;
1474*a9fa9459Szrj break;
1475*a9fa9459Szrj default:
1476*a9fa9459Szrj tls_type = TLS_NONE;
1477*a9fa9459Szrj }
1478*a9fa9459Szrj
1479*a9fa9459Szrj /* Record TLS type. */
1480*a9fa9459Szrj if (h != NULL)
1481*a9fa9459Szrj ((struct elf_or1k_link_hash_entry *) h)->tls_type = tls_type;
1482*a9fa9459Szrj else
1483*a9fa9459Szrj {
1484*a9fa9459Szrj unsigned char *local_tls_type;
1485*a9fa9459Szrj
1486*a9fa9459Szrj /* This is a TLS type record for a local symbol. */
1487*a9fa9459Szrj local_tls_type = (unsigned char *) elf_or1k_local_tls_type (abfd);
1488*a9fa9459Szrj if (local_tls_type == NULL)
1489*a9fa9459Szrj {
1490*a9fa9459Szrj bfd_size_type size;
1491*a9fa9459Szrj
1492*a9fa9459Szrj size = symtab_hdr->sh_info;
1493*a9fa9459Szrj local_tls_type = bfd_zalloc (abfd, size);
1494*a9fa9459Szrj if (local_tls_type == NULL)
1495*a9fa9459Szrj return FALSE;
1496*a9fa9459Szrj elf_or1k_local_tls_type (abfd) = local_tls_type;
1497*a9fa9459Szrj }
1498*a9fa9459Szrj local_tls_type[r_symndx] = tls_type;
1499*a9fa9459Szrj }
1500*a9fa9459Szrj
1501*a9fa9459Szrj switch (ELF32_R_TYPE (rel->r_info))
1502*a9fa9459Szrj {
1503*a9fa9459Szrj /* This relocation describes the C++ object vtable hierarchy.
1504*a9fa9459Szrj Reconstruct it for later use during GC. */
1505*a9fa9459Szrj case R_OR1K_GNU_VTINHERIT:
1506*a9fa9459Szrj if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
1507*a9fa9459Szrj return FALSE;
1508*a9fa9459Szrj break;
1509*a9fa9459Szrj
1510*a9fa9459Szrj /* This relocation describes which C++ vtable entries are actually
1511*a9fa9459Szrj used. Record for later use during GC. */
1512*a9fa9459Szrj case R_OR1K_GNU_VTENTRY:
1513*a9fa9459Szrj BFD_ASSERT (h != NULL);
1514*a9fa9459Szrj if (h != NULL
1515*a9fa9459Szrj && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
1516*a9fa9459Szrj return FALSE;
1517*a9fa9459Szrj break;
1518*a9fa9459Szrj
1519*a9fa9459Szrj /* This relocation requires .plt entry. */
1520*a9fa9459Szrj case R_OR1K_PLT26:
1521*a9fa9459Szrj if (h != NULL)
1522*a9fa9459Szrj {
1523*a9fa9459Szrj h->needs_plt = 1;
1524*a9fa9459Szrj h->plt.refcount += 1;
1525*a9fa9459Szrj }
1526*a9fa9459Szrj break;
1527*a9fa9459Szrj
1528*a9fa9459Szrj case R_OR1K_GOT16:
1529*a9fa9459Szrj case R_OR1K_GOTOFF_HI16:
1530*a9fa9459Szrj case R_OR1K_GOTOFF_LO16:
1531*a9fa9459Szrj case R_OR1K_TLS_GD_HI16:
1532*a9fa9459Szrj case R_OR1K_TLS_GD_LO16:
1533*a9fa9459Szrj case R_OR1K_TLS_IE_HI16:
1534*a9fa9459Szrj case R_OR1K_TLS_IE_LO16:
1535*a9fa9459Szrj if (htab->sgot == NULL)
1536*a9fa9459Szrj {
1537*a9fa9459Szrj if (dynobj == NULL)
1538*a9fa9459Szrj htab->root.dynobj = dynobj = abfd;
1539*a9fa9459Szrj if (! create_got_section (dynobj, info))
1540*a9fa9459Szrj return FALSE;
1541*a9fa9459Szrj }
1542*a9fa9459Szrj
1543*a9fa9459Szrj if (ELF32_R_TYPE (rel->r_info) != R_OR1K_GOTOFF_HI16 &&
1544*a9fa9459Szrj ELF32_R_TYPE (rel->r_info) != R_OR1K_GOTOFF_LO16)
1545*a9fa9459Szrj {
1546*a9fa9459Szrj if (h != NULL)
1547*a9fa9459Szrj h->got.refcount += 1;
1548*a9fa9459Szrj else
1549*a9fa9459Szrj {
1550*a9fa9459Szrj bfd_signed_vma *local_got_refcounts;
1551*a9fa9459Szrj
1552*a9fa9459Szrj /* This is a global offset table entry for a local symbol. */
1553*a9fa9459Szrj local_got_refcounts = elf_local_got_refcounts (abfd);
1554*a9fa9459Szrj if (local_got_refcounts == NULL)
1555*a9fa9459Szrj {
1556*a9fa9459Szrj bfd_size_type size;
1557*a9fa9459Szrj
1558*a9fa9459Szrj size = symtab_hdr->sh_info;
1559*a9fa9459Szrj size *= sizeof (bfd_signed_vma);
1560*a9fa9459Szrj local_got_refcounts = bfd_zalloc (abfd, size);
1561*a9fa9459Szrj if (local_got_refcounts == NULL)
1562*a9fa9459Szrj return FALSE;
1563*a9fa9459Szrj elf_local_got_refcounts (abfd) = local_got_refcounts;
1564*a9fa9459Szrj }
1565*a9fa9459Szrj local_got_refcounts[r_symndx] += 1;
1566*a9fa9459Szrj }
1567*a9fa9459Szrj }
1568*a9fa9459Szrj break;
1569*a9fa9459Szrj
1570*a9fa9459Szrj case R_OR1K_INSN_REL_26:
1571*a9fa9459Szrj case R_OR1K_HI_16_IN_INSN:
1572*a9fa9459Szrj case R_OR1K_LO_16_IN_INSN:
1573*a9fa9459Szrj case R_OR1K_32:
1574*a9fa9459Szrj /* R_OR1K_16? */
1575*a9fa9459Szrj {
1576*a9fa9459Szrj if (h != NULL && !bfd_link_pic (info))
1577*a9fa9459Szrj {
1578*a9fa9459Szrj /* We may need a copy reloc. */
1579*a9fa9459Szrj h->non_got_ref = 1;
1580*a9fa9459Szrj
1581*a9fa9459Szrj /* We may also need a .plt entry. */
1582*a9fa9459Szrj h->plt.refcount += 1;
1583*a9fa9459Szrj if (ELF32_R_TYPE (rel->r_info) != R_OR1K_INSN_REL_26)
1584*a9fa9459Szrj h->pointer_equality_needed = 1;
1585*a9fa9459Szrj }
1586*a9fa9459Szrj
1587*a9fa9459Szrj /* If we are creating a shared library, and this is a reloc
1588*a9fa9459Szrj against a global symbol, or a non PC relative reloc
1589*a9fa9459Szrj against a local symbol, then we need to copy the reloc
1590*a9fa9459Szrj into the shared library. However, if we are linking with
1591*a9fa9459Szrj -Bsymbolic, we do not need to copy a reloc against a
1592*a9fa9459Szrj global symbol which is defined in an object we are
1593*a9fa9459Szrj including in the link (i.e., DEF_REGULAR is set). At
1594*a9fa9459Szrj this point we have not seen all the input files, so it is
1595*a9fa9459Szrj possible that DEF_REGULAR is not set now but will be set
1596*a9fa9459Szrj later (it is never cleared). In case of a weak definition,
1597*a9fa9459Szrj DEF_REGULAR may be cleared later by a strong definition in
1598*a9fa9459Szrj a shared library. We account for that possibility below by
1599*a9fa9459Szrj storing information in the relocs_copied field of the hash
1600*a9fa9459Szrj table entry. A similar situation occurs when creating
1601*a9fa9459Szrj shared libraries and symbol visibility changes render the
1602*a9fa9459Szrj symbol local.
1603*a9fa9459Szrj
1604*a9fa9459Szrj If on the other hand, we are creating an executable, we
1605*a9fa9459Szrj may need to keep relocations for symbols satisfied by a
1606*a9fa9459Szrj dynamic library if we manage to avoid copy relocs for the
1607*a9fa9459Szrj symbol. */
1608*a9fa9459Szrj
1609*a9fa9459Szrj if ((bfd_link_pic (info)
1610*a9fa9459Szrj && (sec->flags & SEC_ALLOC) != 0
1611*a9fa9459Szrj && (ELF32_R_TYPE (rel->r_info) != R_OR1K_INSN_REL_26
1612*a9fa9459Szrj || (h != NULL
1613*a9fa9459Szrj && (!SYMBOLIC_BIND (info, h)
1614*a9fa9459Szrj || h->root.type == bfd_link_hash_defweak
1615*a9fa9459Szrj || !h->def_regular))))
1616*a9fa9459Szrj || (!bfd_link_pic (info)
1617*a9fa9459Szrj && (sec->flags & SEC_ALLOC) != 0
1618*a9fa9459Szrj && h != NULL
1619*a9fa9459Szrj && (h->root.type == bfd_link_hash_defweak
1620*a9fa9459Szrj || !h->def_regular)))
1621*a9fa9459Szrj {
1622*a9fa9459Szrj struct elf_or1k_dyn_relocs *p;
1623*a9fa9459Szrj struct elf_or1k_dyn_relocs **head;
1624*a9fa9459Szrj
1625*a9fa9459Szrj /* When creating a shared object, we must copy these
1626*a9fa9459Szrj relocs into the output file. We create a reloc
1627*a9fa9459Szrj section in dynobj and make room for the reloc. */
1628*a9fa9459Szrj if (sreloc == NULL)
1629*a9fa9459Szrj {
1630*a9fa9459Szrj const char *name;
1631*a9fa9459Szrj unsigned int strndx = elf_elfheader (abfd)->e_shstrndx;
1632*a9fa9459Szrj unsigned int shnam = _bfd_elf_single_rel_hdr (sec)->sh_name;
1633*a9fa9459Szrj
1634*a9fa9459Szrj name = bfd_elf_string_from_elf_section (abfd, strndx, shnam);
1635*a9fa9459Szrj if (name == NULL)
1636*a9fa9459Szrj return FALSE;
1637*a9fa9459Szrj
1638*a9fa9459Szrj if (strncmp (name, ".rela", 5) != 0
1639*a9fa9459Szrj || strcmp (bfd_get_section_name (abfd, sec),
1640*a9fa9459Szrj name + 5) != 0)
1641*a9fa9459Szrj {
1642*a9fa9459Szrj (*_bfd_error_handler)
1643*a9fa9459Szrj (_("%B: bad relocation section name `%s\'"),
1644*a9fa9459Szrj abfd, name);
1645*a9fa9459Szrj }
1646*a9fa9459Szrj
1647*a9fa9459Szrj if (htab->root.dynobj == NULL)
1648*a9fa9459Szrj htab->root.dynobj = abfd;
1649*a9fa9459Szrj dynobj = htab->root.dynobj;
1650*a9fa9459Szrj
1651*a9fa9459Szrj sreloc = bfd_get_section_by_name (dynobj, name);
1652*a9fa9459Szrj if (sreloc == NULL)
1653*a9fa9459Szrj {
1654*a9fa9459Szrj sreloc = _bfd_elf_make_dynamic_reloc_section
1655*a9fa9459Szrj (sec, dynobj, 2, abfd, /*rela?*/ TRUE);
1656*a9fa9459Szrj
1657*a9fa9459Szrj if (sreloc == NULL)
1658*a9fa9459Szrj return FALSE;
1659*a9fa9459Szrj }
1660*a9fa9459Szrj elf_section_data (sec)->sreloc = sreloc;
1661*a9fa9459Szrj }
1662*a9fa9459Szrj
1663*a9fa9459Szrj /* If this is a global symbol, we count the number of
1664*a9fa9459Szrj relocations we need for this symbol. */
1665*a9fa9459Szrj if (h != NULL)
1666*a9fa9459Szrj head = &((struct elf_or1k_link_hash_entry *) h)->dyn_relocs;
1667*a9fa9459Szrj else
1668*a9fa9459Szrj {
1669*a9fa9459Szrj /* Track dynamic relocs needed for local syms too.
1670*a9fa9459Szrj We really need local syms available to do this
1671*a9fa9459Szrj easily. Oh well. */
1672*a9fa9459Szrj
1673*a9fa9459Szrj asection *s;
1674*a9fa9459Szrj Elf_Internal_Sym *isym;
1675*a9fa9459Szrj void *vpp;
1676*a9fa9459Szrj
1677*a9fa9459Szrj isym = bfd_sym_from_r_symndx (&htab->sym_sec,
1678*a9fa9459Szrj abfd, r_symndx);
1679*a9fa9459Szrj if (isym == NULL)
1680*a9fa9459Szrj return FALSE;
1681*a9fa9459Szrj
1682*a9fa9459Szrj s = bfd_section_from_elf_index (abfd, isym->st_shndx);
1683*a9fa9459Szrj if (s == NULL)
1684*a9fa9459Szrj return FALSE;
1685*a9fa9459Szrj
1686*a9fa9459Szrj vpp = &elf_section_data (s)->local_dynrel;
1687*a9fa9459Szrj head = (struct elf_or1k_dyn_relocs **) vpp;
1688*a9fa9459Szrj }
1689*a9fa9459Szrj
1690*a9fa9459Szrj p = *head;
1691*a9fa9459Szrj if (p == NULL || p->sec != sec)
1692*a9fa9459Szrj {
1693*a9fa9459Szrj bfd_size_type amt = sizeof *p;
1694*a9fa9459Szrj p = ((struct elf_or1k_dyn_relocs *)
1695*a9fa9459Szrj bfd_alloc (htab->root.dynobj, amt));
1696*a9fa9459Szrj if (p == NULL)
1697*a9fa9459Szrj return FALSE;
1698*a9fa9459Szrj p->next = *head;
1699*a9fa9459Szrj *head = p;
1700*a9fa9459Szrj p->sec = sec;
1701*a9fa9459Szrj p->count = 0;
1702*a9fa9459Szrj p->pc_count = 0;
1703*a9fa9459Szrj }
1704*a9fa9459Szrj
1705*a9fa9459Szrj p->count += 1;
1706*a9fa9459Szrj if (ELF32_R_TYPE (rel->r_info) == R_OR1K_INSN_REL_26)
1707*a9fa9459Szrj p->pc_count += 1;
1708*a9fa9459Szrj }
1709*a9fa9459Szrj }
1710*a9fa9459Szrj break;
1711*a9fa9459Szrj }
1712*a9fa9459Szrj }
1713*a9fa9459Szrj
1714*a9fa9459Szrj return TRUE;
1715*a9fa9459Szrj }
1716*a9fa9459Szrj
1717*a9fa9459Szrj /* Finish up the dynamic sections. */
1718*a9fa9459Szrj
1719*a9fa9459Szrj static bfd_boolean
or1k_elf_finish_dynamic_sections(bfd * output_bfd,struct bfd_link_info * info)1720*a9fa9459Szrj or1k_elf_finish_dynamic_sections (bfd *output_bfd,
1721*a9fa9459Szrj struct bfd_link_info *info)
1722*a9fa9459Szrj {
1723*a9fa9459Szrj bfd *dynobj;
1724*a9fa9459Szrj asection *sdyn, *sgot;
1725*a9fa9459Szrj struct elf_or1k_link_hash_table *htab;
1726*a9fa9459Szrj
1727*a9fa9459Szrj htab = or1k_elf_hash_table (info);
1728*a9fa9459Szrj if (htab == NULL)
1729*a9fa9459Szrj return FALSE;
1730*a9fa9459Szrj
1731*a9fa9459Szrj dynobj = htab->root.dynobj;
1732*a9fa9459Szrj
1733*a9fa9459Szrj sgot = htab->sgotplt;
1734*a9fa9459Szrj sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
1735*a9fa9459Szrj
1736*a9fa9459Szrj if (htab->root.dynamic_sections_created)
1737*a9fa9459Szrj {
1738*a9fa9459Szrj asection *splt;
1739*a9fa9459Szrj Elf32_External_Dyn *dyncon, *dynconend;
1740*a9fa9459Szrj
1741*a9fa9459Szrj BFD_ASSERT (sgot != NULL && sdyn != NULL);
1742*a9fa9459Szrj
1743*a9fa9459Szrj dyncon = (Elf32_External_Dyn *) sdyn->contents;
1744*a9fa9459Szrj dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
1745*a9fa9459Szrj
1746*a9fa9459Szrj for (; dyncon < dynconend; dyncon++)
1747*a9fa9459Szrj {
1748*a9fa9459Szrj Elf_Internal_Dyn dyn;
1749*a9fa9459Szrj asection *s;
1750*a9fa9459Szrj
1751*a9fa9459Szrj bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
1752*a9fa9459Szrj
1753*a9fa9459Szrj switch (dyn.d_tag)
1754*a9fa9459Szrj {
1755*a9fa9459Szrj default:
1756*a9fa9459Szrj continue;
1757*a9fa9459Szrj
1758*a9fa9459Szrj case DT_PLTGOT:
1759*a9fa9459Szrj s = htab->sgotplt;
1760*a9fa9459Szrj dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
1761*a9fa9459Szrj break;
1762*a9fa9459Szrj
1763*a9fa9459Szrj case DT_JMPREL:
1764*a9fa9459Szrj s = htab->srelplt;
1765*a9fa9459Szrj dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
1766*a9fa9459Szrj break;
1767*a9fa9459Szrj
1768*a9fa9459Szrj case DT_PLTRELSZ:
1769*a9fa9459Szrj s = htab->srelplt;
1770*a9fa9459Szrj dyn.d_un.d_val = s->size;
1771*a9fa9459Szrj break;
1772*a9fa9459Szrj
1773*a9fa9459Szrj case DT_RELASZ:
1774*a9fa9459Szrj /* My reading of the SVR4 ABI indicates that the
1775*a9fa9459Szrj procedure linkage table relocs (DT_JMPREL) should be
1776*a9fa9459Szrj included in the overall relocs (DT_RELA). This is
1777*a9fa9459Szrj what Solaris does. However, UnixWare can not handle
1778*a9fa9459Szrj that case. Therefore, we override the DT_RELASZ entry
1779*a9fa9459Szrj here to make it not include the JMPREL relocs. Since
1780*a9fa9459Szrj the linker script arranges for .rela.plt to follow all
1781*a9fa9459Szrj other relocation sections, we don't have to worry
1782*a9fa9459Szrj about changing the DT_RELA entry. */
1783*a9fa9459Szrj if (htab->srelplt != NULL)
1784*a9fa9459Szrj {
1785*a9fa9459Szrj s = htab->srelplt;
1786*a9fa9459Szrj dyn.d_un.d_val -= s->size;
1787*a9fa9459Szrj }
1788*a9fa9459Szrj break;
1789*a9fa9459Szrj }
1790*a9fa9459Szrj bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
1791*a9fa9459Szrj }
1792*a9fa9459Szrj
1793*a9fa9459Szrj
1794*a9fa9459Szrj /* Fill in the first entry in the procedure linkage table. */
1795*a9fa9459Szrj splt = htab->splt;
1796*a9fa9459Szrj if (splt && splt->size > 0)
1797*a9fa9459Szrj {
1798*a9fa9459Szrj if (bfd_link_pic (info))
1799*a9fa9459Szrj {
1800*a9fa9459Szrj bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD0,
1801*a9fa9459Szrj splt->contents);
1802*a9fa9459Szrj bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD1,
1803*a9fa9459Szrj splt->contents + 4);
1804*a9fa9459Szrj bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD2,
1805*a9fa9459Szrj splt->contents + 8);
1806*a9fa9459Szrj bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD3,
1807*a9fa9459Szrj splt->contents + 12);
1808*a9fa9459Szrj bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD4,
1809*a9fa9459Szrj splt->contents + 16);
1810*a9fa9459Szrj }
1811*a9fa9459Szrj else
1812*a9fa9459Szrj {
1813*a9fa9459Szrj unsigned long addr;
1814*a9fa9459Szrj /* addr = .got + 4 */
1815*a9fa9459Szrj addr = sgot->output_section->vma + sgot->output_offset + 4;
1816*a9fa9459Szrj bfd_put_32 (output_bfd,
1817*a9fa9459Szrj PLT0_ENTRY_WORD0 | ((addr >> 16) & 0xffff),
1818*a9fa9459Szrj splt->contents);
1819*a9fa9459Szrj bfd_put_32 (output_bfd,
1820*a9fa9459Szrj PLT0_ENTRY_WORD1 | (addr & 0xffff),
1821*a9fa9459Szrj splt->contents + 4);
1822*a9fa9459Szrj bfd_put_32 (output_bfd, PLT0_ENTRY_WORD2, splt->contents + 8);
1823*a9fa9459Szrj bfd_put_32 (output_bfd, PLT0_ENTRY_WORD3, splt->contents + 12);
1824*a9fa9459Szrj bfd_put_32 (output_bfd, PLT0_ENTRY_WORD4, splt->contents + 16);
1825*a9fa9459Szrj }
1826*a9fa9459Szrj
1827*a9fa9459Szrj elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
1828*a9fa9459Szrj }
1829*a9fa9459Szrj }
1830*a9fa9459Szrj
1831*a9fa9459Szrj /* Set the first entry in the global offset table to the address of
1832*a9fa9459Szrj the dynamic section. */
1833*a9fa9459Szrj if (sgot && sgot->size > 0)
1834*a9fa9459Szrj {
1835*a9fa9459Szrj if (sdyn == NULL)
1836*a9fa9459Szrj bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
1837*a9fa9459Szrj else
1838*a9fa9459Szrj bfd_put_32 (output_bfd,
1839*a9fa9459Szrj sdyn->output_section->vma + sdyn->output_offset,
1840*a9fa9459Szrj sgot->contents);
1841*a9fa9459Szrj elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
1842*a9fa9459Szrj }
1843*a9fa9459Szrj
1844*a9fa9459Szrj if (htab->sgot && htab->sgot->size > 0)
1845*a9fa9459Szrj elf_section_data (htab->sgot->output_section)->this_hdr.sh_entsize = 4;
1846*a9fa9459Szrj
1847*a9fa9459Szrj return TRUE;
1848*a9fa9459Szrj }
1849*a9fa9459Szrj
1850*a9fa9459Szrj /* Finish up dynamic symbol handling. We set the contents of various
1851*a9fa9459Szrj dynamic sections here. */
1852*a9fa9459Szrj
1853*a9fa9459Szrj static bfd_boolean
or1k_elf_finish_dynamic_symbol(bfd * output_bfd,struct bfd_link_info * info,struct elf_link_hash_entry * h,Elf_Internal_Sym * sym)1854*a9fa9459Szrj or1k_elf_finish_dynamic_symbol (bfd *output_bfd,
1855*a9fa9459Szrj struct bfd_link_info *info,
1856*a9fa9459Szrj struct elf_link_hash_entry *h,
1857*a9fa9459Szrj Elf_Internal_Sym *sym)
1858*a9fa9459Szrj {
1859*a9fa9459Szrj struct elf_or1k_link_hash_table *htab;
1860*a9fa9459Szrj bfd_byte *loc;
1861*a9fa9459Szrj
1862*a9fa9459Szrj htab = or1k_elf_hash_table (info);
1863*a9fa9459Szrj if (htab == NULL)
1864*a9fa9459Szrj return FALSE;
1865*a9fa9459Szrj
1866*a9fa9459Szrj if (h->plt.offset != (bfd_vma) -1)
1867*a9fa9459Szrj {
1868*a9fa9459Szrj asection *splt;
1869*a9fa9459Szrj asection *sgot;
1870*a9fa9459Szrj asection *srela;
1871*a9fa9459Szrj
1872*a9fa9459Szrj bfd_vma plt_index;
1873*a9fa9459Szrj bfd_vma got_offset;
1874*a9fa9459Szrj bfd_vma got_addr;
1875*a9fa9459Szrj Elf_Internal_Rela rela;
1876*a9fa9459Szrj
1877*a9fa9459Szrj /* This symbol has an entry in the procedure linkage table. Set
1878*a9fa9459Szrj it up. */
1879*a9fa9459Szrj BFD_ASSERT (h->dynindx != -1);
1880*a9fa9459Szrj
1881*a9fa9459Szrj splt = htab->splt;
1882*a9fa9459Szrj sgot = htab->sgotplt;
1883*a9fa9459Szrj srela = htab->srelplt;
1884*a9fa9459Szrj BFD_ASSERT (splt != NULL && sgot != NULL && srela != NULL);
1885*a9fa9459Szrj
1886*a9fa9459Szrj /* Get the index in the procedure linkage table which
1887*a9fa9459Szrj corresponds to this symbol. This is the index of this symbol
1888*a9fa9459Szrj in all the symbols for which we are making plt entries. The
1889*a9fa9459Szrj first entry in the procedure linkage table is reserved. */
1890*a9fa9459Szrj plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
1891*a9fa9459Szrj
1892*a9fa9459Szrj /* Get the offset into the .got table of the entry that
1893*a9fa9459Szrj corresponds to this function. Each .got entry is 4 bytes.
1894*a9fa9459Szrj The first three are reserved. */
1895*a9fa9459Szrj got_offset = (plt_index + 3) * 4;
1896*a9fa9459Szrj got_addr = got_offset;
1897*a9fa9459Szrj
1898*a9fa9459Szrj /* Fill in the entry in the procedure linkage table. */
1899*a9fa9459Szrj if (! bfd_link_pic (info))
1900*a9fa9459Szrj {
1901*a9fa9459Szrj got_addr += htab->sgotplt->output_section->vma
1902*a9fa9459Szrj + htab->sgotplt->output_offset;
1903*a9fa9459Szrj bfd_put_32 (output_bfd, PLT_ENTRY_WORD0 | ((got_addr >> 16) & 0xffff),
1904*a9fa9459Szrj splt->contents + h->plt.offset);
1905*a9fa9459Szrj bfd_put_32 (output_bfd, PLT_ENTRY_WORD1 | (got_addr & 0xffff),
1906*a9fa9459Szrj splt->contents + h->plt.offset + 4);
1907*a9fa9459Szrj bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD2,
1908*a9fa9459Szrj splt->contents + h->plt.offset + 8);
1909*a9fa9459Szrj bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD3,
1910*a9fa9459Szrj splt->contents + h->plt.offset + 12);
1911*a9fa9459Szrj bfd_put_32 (output_bfd, PLT_ENTRY_WORD4
1912*a9fa9459Szrj | plt_index * sizeof (Elf32_External_Rela),
1913*a9fa9459Szrj splt->contents + h->plt.offset + 16);
1914*a9fa9459Szrj }
1915*a9fa9459Szrj else
1916*a9fa9459Szrj {
1917*a9fa9459Szrj bfd_put_32 (output_bfd, PLT_PIC_ENTRY_WORD0 | (got_addr & 0xffff),
1918*a9fa9459Szrj splt->contents + h->plt.offset);
1919*a9fa9459Szrj bfd_put_32 (output_bfd, PLT_PIC_ENTRY_WORD1
1920*a9fa9459Szrj | plt_index * sizeof (Elf32_External_Rela),
1921*a9fa9459Szrj splt->contents + h->plt.offset + 4);
1922*a9fa9459Szrj bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_ENTRY_WORD2,
1923*a9fa9459Szrj splt->contents + h->plt.offset + 8);
1924*a9fa9459Szrj bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_ENTRY_WORD3,
1925*a9fa9459Szrj splt->contents + h->plt.offset + 12);
1926*a9fa9459Szrj bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_ENTRY_WORD4,
1927*a9fa9459Szrj splt->contents + h->plt.offset + 16);
1928*a9fa9459Szrj }
1929*a9fa9459Szrj
1930*a9fa9459Szrj /* Fill in the entry in the global offset table. */
1931*a9fa9459Szrj bfd_put_32 (output_bfd,
1932*a9fa9459Szrj (splt->output_section->vma
1933*a9fa9459Szrj + splt->output_offset), /* Same offset. */
1934*a9fa9459Szrj sgot->contents + got_offset);
1935*a9fa9459Szrj
1936*a9fa9459Szrj /* Fill in the entry in the .rela.plt section. */
1937*a9fa9459Szrj rela.r_offset = (sgot->output_section->vma
1938*a9fa9459Szrj + sgot->output_offset
1939*a9fa9459Szrj + got_offset);
1940*a9fa9459Szrj rela.r_info = ELF32_R_INFO (h->dynindx, R_OR1K_JMP_SLOT);
1941*a9fa9459Szrj rela.r_addend = 0;
1942*a9fa9459Szrj loc = srela->contents;
1943*a9fa9459Szrj loc += plt_index * sizeof (Elf32_External_Rela);
1944*a9fa9459Szrj bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
1945*a9fa9459Szrj
1946*a9fa9459Szrj if (!h->def_regular)
1947*a9fa9459Szrj {
1948*a9fa9459Szrj /* Mark the symbol as undefined, rather than as defined in
1949*a9fa9459Szrj the .plt section. Leave the value alone. */
1950*a9fa9459Szrj sym->st_shndx = SHN_UNDEF;
1951*a9fa9459Szrj }
1952*a9fa9459Szrj
1953*a9fa9459Szrj }
1954*a9fa9459Szrj
1955*a9fa9459Szrj if (h->got.offset != (bfd_vma) -1
1956*a9fa9459Szrj && (h->got.offset & 2) == 0) /* Homemade TLS check. */
1957*a9fa9459Szrj {
1958*a9fa9459Szrj asection *sgot;
1959*a9fa9459Szrj asection *srela;
1960*a9fa9459Szrj Elf_Internal_Rela rela;
1961*a9fa9459Szrj
1962*a9fa9459Szrj /* This symbol has an entry in the global offset table. Set it
1963*a9fa9459Szrj up. */
1964*a9fa9459Szrj sgot = htab->sgot;
1965*a9fa9459Szrj srela = htab->srelgot;
1966*a9fa9459Szrj BFD_ASSERT (sgot != NULL && srela != NULL);
1967*a9fa9459Szrj
1968*a9fa9459Szrj rela.r_offset = (sgot->output_section->vma
1969*a9fa9459Szrj + sgot->output_offset
1970*a9fa9459Szrj + (h->got.offset &~ 1));
1971*a9fa9459Szrj
1972*a9fa9459Szrj /* If this is a -Bsymbolic link, and the symbol is defined
1973*a9fa9459Szrj locally, we just want to emit a RELATIVE reloc. Likewise if
1974*a9fa9459Szrj the symbol was forced to be local because of a version file.
1975*a9fa9459Szrj The entry in the global offset table will already have been
1976*a9fa9459Szrj initialized in the relocate_section function. */
1977*a9fa9459Szrj if (bfd_link_pic (info) && SYMBOL_REFERENCES_LOCAL (info, h))
1978*a9fa9459Szrj {
1979*a9fa9459Szrj rela.r_info = ELF32_R_INFO (0, R_OR1K_RELATIVE);
1980*a9fa9459Szrj rela.r_addend = (h->root.u.def.value
1981*a9fa9459Szrj + h->root.u.def.section->output_section->vma
1982*a9fa9459Szrj + h->root.u.def.section->output_offset);
1983*a9fa9459Szrj }
1984*a9fa9459Szrj else
1985*a9fa9459Szrj {
1986*a9fa9459Szrj BFD_ASSERT ((h->got.offset & 1) == 0);
1987*a9fa9459Szrj bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
1988*a9fa9459Szrj rela.r_info = ELF32_R_INFO (h->dynindx, R_OR1K_GLOB_DAT);
1989*a9fa9459Szrj rela.r_addend = 0;
1990*a9fa9459Szrj }
1991*a9fa9459Szrj
1992*a9fa9459Szrj loc = srela->contents;
1993*a9fa9459Szrj loc += srela->reloc_count * sizeof (Elf32_External_Rela);
1994*a9fa9459Szrj bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
1995*a9fa9459Szrj ++srela->reloc_count;
1996*a9fa9459Szrj }
1997*a9fa9459Szrj
1998*a9fa9459Szrj if (h->needs_copy)
1999*a9fa9459Szrj {
2000*a9fa9459Szrj asection *s;
2001*a9fa9459Szrj Elf_Internal_Rela rela;
2002*a9fa9459Szrj
2003*a9fa9459Szrj /* This symbols needs a copy reloc. Set it up. */
2004*a9fa9459Szrj BFD_ASSERT (h->dynindx != -1
2005*a9fa9459Szrj && (h->root.type == bfd_link_hash_defined
2006*a9fa9459Szrj || h->root.type == bfd_link_hash_defweak));
2007*a9fa9459Szrj
2008*a9fa9459Szrj s = bfd_get_section_by_name (h->root.u.def.section->owner,
2009*a9fa9459Szrj ".rela.bss");
2010*a9fa9459Szrj BFD_ASSERT (s != NULL);
2011*a9fa9459Szrj
2012*a9fa9459Szrj rela.r_offset = (h->root.u.def.value
2013*a9fa9459Szrj + h->root.u.def.section->output_section->vma
2014*a9fa9459Szrj + h->root.u.def.section->output_offset);
2015*a9fa9459Szrj rela.r_info = ELF32_R_INFO (h->dynindx, R_OR1K_COPY);
2016*a9fa9459Szrj rela.r_addend = 0;
2017*a9fa9459Szrj loc = s->contents;
2018*a9fa9459Szrj loc += s->reloc_count * sizeof (Elf32_External_Rela);
2019*a9fa9459Szrj bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
2020*a9fa9459Szrj ++s->reloc_count;
2021*a9fa9459Szrj }
2022*a9fa9459Szrj
2023*a9fa9459Szrj /* Mark some specially defined symbols as absolute. */
2024*a9fa9459Szrj if (strcmp (h->root.root.string, "_DYNAMIC") == 0
2025*a9fa9459Szrj || h == htab->root.hgot)
2026*a9fa9459Szrj sym->st_shndx = SHN_ABS;
2027*a9fa9459Szrj
2028*a9fa9459Szrj return TRUE;
2029*a9fa9459Szrj }
2030*a9fa9459Szrj
2031*a9fa9459Szrj static enum elf_reloc_type_class
or1k_elf_reloc_type_class(const struct bfd_link_info * info ATTRIBUTE_UNUSED,const asection * rel_sec ATTRIBUTE_UNUSED,const Elf_Internal_Rela * rela)2032*a9fa9459Szrj or1k_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
2033*a9fa9459Szrj const asection *rel_sec ATTRIBUTE_UNUSED,
2034*a9fa9459Szrj const Elf_Internal_Rela *rela)
2035*a9fa9459Szrj {
2036*a9fa9459Szrj switch ((int) ELF32_R_TYPE (rela->r_info))
2037*a9fa9459Szrj {
2038*a9fa9459Szrj case R_OR1K_RELATIVE: return reloc_class_relative;
2039*a9fa9459Szrj case R_OR1K_JMP_SLOT: return reloc_class_plt;
2040*a9fa9459Szrj case R_OR1K_COPY: return reloc_class_copy;
2041*a9fa9459Szrj default: return reloc_class_normal;
2042*a9fa9459Szrj }
2043*a9fa9459Szrj }
2044*a9fa9459Szrj
2045*a9fa9459Szrj /* Adjust a symbol defined by a dynamic object and referenced by a
2046*a9fa9459Szrj regular object. The current definition is in some section of the
2047*a9fa9459Szrj dynamic object, but we're not including those sections. We have to
2048*a9fa9459Szrj change the definition to something the rest of the link can
2049*a9fa9459Szrj understand. */
2050*a9fa9459Szrj
2051*a9fa9459Szrj static bfd_boolean
or1k_elf_adjust_dynamic_symbol(struct bfd_link_info * info,struct elf_link_hash_entry * h)2052*a9fa9459Szrj or1k_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
2053*a9fa9459Szrj struct elf_link_hash_entry *h)
2054*a9fa9459Szrj {
2055*a9fa9459Szrj struct elf_or1k_link_hash_table *htab;
2056*a9fa9459Szrj struct elf_or1k_link_hash_entry *eh;
2057*a9fa9459Szrj struct elf_or1k_dyn_relocs *p;
2058*a9fa9459Szrj bfd *dynobj;
2059*a9fa9459Szrj asection *s;
2060*a9fa9459Szrj
2061*a9fa9459Szrj dynobj = elf_hash_table (info)->dynobj;
2062*a9fa9459Szrj
2063*a9fa9459Szrj /* Make sure we know what is going on here. */
2064*a9fa9459Szrj BFD_ASSERT (dynobj != NULL
2065*a9fa9459Szrj && (h->needs_plt
2066*a9fa9459Szrj || h->u.weakdef != NULL
2067*a9fa9459Szrj || (h->def_dynamic
2068*a9fa9459Szrj && h->ref_regular
2069*a9fa9459Szrj && !h->def_regular)));
2070*a9fa9459Szrj
2071*a9fa9459Szrj /* If this is a function, put it in the procedure linkage table. We
2072*a9fa9459Szrj will fill in the contents of the procedure linkage table later,
2073*a9fa9459Szrj when we know the address of the .got section. */
2074*a9fa9459Szrj if (h->type == STT_FUNC
2075*a9fa9459Szrj || h->needs_plt)
2076*a9fa9459Szrj {
2077*a9fa9459Szrj if (! bfd_link_pic (info)
2078*a9fa9459Szrj && !h->def_dynamic
2079*a9fa9459Szrj && !h->ref_dynamic
2080*a9fa9459Szrj && h->root.type != bfd_link_hash_undefweak
2081*a9fa9459Szrj && h->root.type != bfd_link_hash_undefined)
2082*a9fa9459Szrj {
2083*a9fa9459Szrj /* This case can occur if we saw a PLT reloc in an input
2084*a9fa9459Szrj file, but the symbol was never referred to by a dynamic
2085*a9fa9459Szrj object. In such a case, we don't actually need to build
2086*a9fa9459Szrj a procedure linkage table, and we can just do a PCREL
2087*a9fa9459Szrj reloc instead. */
2088*a9fa9459Szrj h->plt.offset = (bfd_vma) -1;
2089*a9fa9459Szrj h->needs_plt = 0;
2090*a9fa9459Szrj }
2091*a9fa9459Szrj
2092*a9fa9459Szrj return TRUE;
2093*a9fa9459Szrj }
2094*a9fa9459Szrj else
2095*a9fa9459Szrj h->plt.offset = (bfd_vma) -1;
2096*a9fa9459Szrj
2097*a9fa9459Szrj /* If this is a weak symbol, and there is a real definition, the
2098*a9fa9459Szrj processor independent code will have arranged for us to see the
2099*a9fa9459Szrj real definition first, and we can just use the same value. */
2100*a9fa9459Szrj if (h->u.weakdef != NULL)
2101*a9fa9459Szrj {
2102*a9fa9459Szrj BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2103*a9fa9459Szrj || h->u.weakdef->root.type == bfd_link_hash_defweak);
2104*a9fa9459Szrj h->root.u.def.section = h->u.weakdef->root.u.def.section;
2105*a9fa9459Szrj h->root.u.def.value = h->u.weakdef->root.u.def.value;
2106*a9fa9459Szrj return TRUE;
2107*a9fa9459Szrj }
2108*a9fa9459Szrj
2109*a9fa9459Szrj /* This is a reference to a symbol defined by a dynamic object which
2110*a9fa9459Szrj is not a function. */
2111*a9fa9459Szrj
2112*a9fa9459Szrj /* If we are creating a shared library, we must presume that the
2113*a9fa9459Szrj only references to the symbol are via the global offset table.
2114*a9fa9459Szrj For such cases we need not do anything here; the relocations will
2115*a9fa9459Szrj be handled correctly by relocate_section. */
2116*a9fa9459Szrj if (bfd_link_pic (info))
2117*a9fa9459Szrj return TRUE;
2118*a9fa9459Szrj
2119*a9fa9459Szrj /* If there are no references to this symbol that do not use the
2120*a9fa9459Szrj GOT, we don't need to generate a copy reloc. */
2121*a9fa9459Szrj if (!h->non_got_ref)
2122*a9fa9459Szrj return TRUE;
2123*a9fa9459Szrj
2124*a9fa9459Szrj /* If -z nocopyreloc was given, we won't generate them either. */
2125*a9fa9459Szrj if (info->nocopyreloc)
2126*a9fa9459Szrj {
2127*a9fa9459Szrj h->non_got_ref = 0;
2128*a9fa9459Szrj return TRUE;
2129*a9fa9459Szrj }
2130*a9fa9459Szrj
2131*a9fa9459Szrj eh = (struct elf_or1k_link_hash_entry *) h;
2132*a9fa9459Szrj for (p = eh->dyn_relocs; p != NULL; p = p->next)
2133*a9fa9459Szrj {
2134*a9fa9459Szrj s = p->sec->output_section;
2135*a9fa9459Szrj if (s != NULL && (s->flags & (SEC_READONLY | SEC_HAS_CONTENTS)) != 0)
2136*a9fa9459Szrj break;
2137*a9fa9459Szrj }
2138*a9fa9459Szrj
2139*a9fa9459Szrj /* If we didn't find any dynamic relocs in sections which needs the
2140*a9fa9459Szrj copy reloc, then we'll be keeping the dynamic relocs and avoiding
2141*a9fa9459Szrj the copy reloc. */
2142*a9fa9459Szrj if (p == NULL)
2143*a9fa9459Szrj {
2144*a9fa9459Szrj h->non_got_ref = 0;
2145*a9fa9459Szrj return TRUE;
2146*a9fa9459Szrj }
2147*a9fa9459Szrj
2148*a9fa9459Szrj /* We must allocate the symbol in our .dynbss section, which will
2149*a9fa9459Szrj become part of the .bss section of the executable. There will be
2150*a9fa9459Szrj an entry for this symbol in the .dynsym section. The dynamic
2151*a9fa9459Szrj object will contain position independent code, so all references
2152*a9fa9459Szrj from the dynamic object to this symbol will go through the global
2153*a9fa9459Szrj offset table. The dynamic linker will use the .dynsym entry to
2154*a9fa9459Szrj determine the address it must put in the global offset table, so
2155*a9fa9459Szrj both the dynamic object and the regular object will refer to the
2156*a9fa9459Szrj same memory location for the variable. */
2157*a9fa9459Szrj
2158*a9fa9459Szrj htab = or1k_elf_hash_table (info);
2159*a9fa9459Szrj if (htab == NULL)
2160*a9fa9459Szrj return FALSE;
2161*a9fa9459Szrj
2162*a9fa9459Szrj s = htab->sdynbss;
2163*a9fa9459Szrj BFD_ASSERT (s != NULL);
2164*a9fa9459Szrj
2165*a9fa9459Szrj /* We must generate a R_OR1K_COPY reloc to tell the dynamic linker
2166*a9fa9459Szrj to copy the initial value out of the dynamic object and into the
2167*a9fa9459Szrj runtime process image. We need to remember the offset into the
2168*a9fa9459Szrj .rela.bss section we are going to use. */
2169*a9fa9459Szrj if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
2170*a9fa9459Szrj {
2171*a9fa9459Szrj asection *srel;
2172*a9fa9459Szrj
2173*a9fa9459Szrj srel = htab->srelbss;
2174*a9fa9459Szrj BFD_ASSERT (srel != NULL);
2175*a9fa9459Szrj srel->size += sizeof (Elf32_External_Rela);
2176*a9fa9459Szrj h->needs_copy = 1;
2177*a9fa9459Szrj }
2178*a9fa9459Szrj
2179*a9fa9459Szrj return _bfd_elf_adjust_dynamic_copy (info, h, s);
2180*a9fa9459Szrj }
2181*a9fa9459Szrj
2182*a9fa9459Szrj /* Allocate space in .plt, .got and associated reloc sections for
2183*a9fa9459Szrj dynamic relocs. */
2184*a9fa9459Szrj
2185*a9fa9459Szrj static bfd_boolean
allocate_dynrelocs(struct elf_link_hash_entry * h,void * inf)2186*a9fa9459Szrj allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
2187*a9fa9459Szrj {
2188*a9fa9459Szrj struct bfd_link_info *info;
2189*a9fa9459Szrj struct elf_or1k_link_hash_table *htab;
2190*a9fa9459Szrj struct elf_or1k_link_hash_entry *eh;
2191*a9fa9459Szrj struct elf_or1k_dyn_relocs *p;
2192*a9fa9459Szrj
2193*a9fa9459Szrj if (h->root.type == bfd_link_hash_indirect)
2194*a9fa9459Szrj return TRUE;
2195*a9fa9459Szrj
2196*a9fa9459Szrj info = (struct bfd_link_info *) inf;
2197*a9fa9459Szrj htab = or1k_elf_hash_table (info);
2198*a9fa9459Szrj if (htab == NULL)
2199*a9fa9459Szrj return FALSE;
2200*a9fa9459Szrj
2201*a9fa9459Szrj eh = (struct elf_or1k_link_hash_entry *) h;
2202*a9fa9459Szrj
2203*a9fa9459Szrj if (htab->root.dynamic_sections_created
2204*a9fa9459Szrj && h->plt.refcount > 0)
2205*a9fa9459Szrj {
2206*a9fa9459Szrj /* Make sure this symbol is output as a dynamic symbol.
2207*a9fa9459Szrj Undefined weak syms won't yet be marked as dynamic. */
2208*a9fa9459Szrj if (h->dynindx == -1
2209*a9fa9459Szrj && !h->forced_local)
2210*a9fa9459Szrj {
2211*a9fa9459Szrj if (! bfd_elf_link_record_dynamic_symbol (info, h))
2212*a9fa9459Szrj return FALSE;
2213*a9fa9459Szrj }
2214*a9fa9459Szrj
2215*a9fa9459Szrj if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h))
2216*a9fa9459Szrj {
2217*a9fa9459Szrj asection *s = htab->splt;
2218*a9fa9459Szrj
2219*a9fa9459Szrj /* If this is the first .plt entry, make room for the special
2220*a9fa9459Szrj first entry. */
2221*a9fa9459Szrj if (s->size == 0)
2222*a9fa9459Szrj s->size = PLT_ENTRY_SIZE;
2223*a9fa9459Szrj
2224*a9fa9459Szrj h->plt.offset = s->size;
2225*a9fa9459Szrj
2226*a9fa9459Szrj /* If this symbol is not defined in a regular file, and we are
2227*a9fa9459Szrj not generating a shared library, then set the symbol to this
2228*a9fa9459Szrj location in the .plt. This is required to make function
2229*a9fa9459Szrj pointers compare as equal between the normal executable and
2230*a9fa9459Szrj the shared library. */
2231*a9fa9459Szrj if (! bfd_link_pic (info)
2232*a9fa9459Szrj && !h->def_regular)
2233*a9fa9459Szrj {
2234*a9fa9459Szrj h->root.u.def.section = s;
2235*a9fa9459Szrj h->root.u.def.value = h->plt.offset;
2236*a9fa9459Szrj }
2237*a9fa9459Szrj
2238*a9fa9459Szrj /* Make room for this entry. */
2239*a9fa9459Szrj s->size += PLT_ENTRY_SIZE;
2240*a9fa9459Szrj
2241*a9fa9459Szrj /* We also need to make an entry in the .got.plt section, which
2242*a9fa9459Szrj will be placed in the .got section by the linker script. */
2243*a9fa9459Szrj htab->sgotplt->size += 4;
2244*a9fa9459Szrj
2245*a9fa9459Szrj /* We also need to make an entry in the .rel.plt section. */
2246*a9fa9459Szrj htab->srelplt->size += sizeof (Elf32_External_Rela);
2247*a9fa9459Szrj }
2248*a9fa9459Szrj else
2249*a9fa9459Szrj {
2250*a9fa9459Szrj h->plt.offset = (bfd_vma) -1;
2251*a9fa9459Szrj h->needs_plt = 0;
2252*a9fa9459Szrj }
2253*a9fa9459Szrj }
2254*a9fa9459Szrj else
2255*a9fa9459Szrj {
2256*a9fa9459Szrj h->plt.offset = (bfd_vma) -1;
2257*a9fa9459Szrj h->needs_plt = 0;
2258*a9fa9459Szrj }
2259*a9fa9459Szrj
2260*a9fa9459Szrj if (h->got.refcount > 0)
2261*a9fa9459Szrj {
2262*a9fa9459Szrj asection *s;
2263*a9fa9459Szrj bfd_boolean dyn;
2264*a9fa9459Szrj unsigned char tls_type;
2265*a9fa9459Szrj
2266*a9fa9459Szrj /* Make sure this symbol is output as a dynamic symbol.
2267*a9fa9459Szrj Undefined weak syms won't yet be marked as dynamic. */
2268*a9fa9459Szrj if (h->dynindx == -1
2269*a9fa9459Szrj && !h->forced_local)
2270*a9fa9459Szrj {
2271*a9fa9459Szrj if (! bfd_elf_link_record_dynamic_symbol (info, h))
2272*a9fa9459Szrj return FALSE;
2273*a9fa9459Szrj }
2274*a9fa9459Szrj
2275*a9fa9459Szrj s = htab->sgot;
2276*a9fa9459Szrj
2277*a9fa9459Szrj h->got.offset = s->size;
2278*a9fa9459Szrj
2279*a9fa9459Szrj tls_type = ((struct elf_or1k_link_hash_entry *) h)->tls_type;
2280*a9fa9459Szrj
2281*a9fa9459Szrj /* TLS GD requires two GOT and two relocs. */
2282*a9fa9459Szrj if (tls_type == TLS_GD)
2283*a9fa9459Szrj s->size += 8;
2284*a9fa9459Szrj else
2285*a9fa9459Szrj s->size += 4;
2286*a9fa9459Szrj dyn = htab->root.dynamic_sections_created;
2287*a9fa9459Szrj if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h))
2288*a9fa9459Szrj {
2289*a9fa9459Szrj if (tls_type == TLS_GD)
2290*a9fa9459Szrj htab->srelgot->size += 2 * sizeof (Elf32_External_Rela);
2291*a9fa9459Szrj else
2292*a9fa9459Szrj htab->srelgot->size += sizeof (Elf32_External_Rela);
2293*a9fa9459Szrj }
2294*a9fa9459Szrj }
2295*a9fa9459Szrj else
2296*a9fa9459Szrj h->got.offset = (bfd_vma) -1;
2297*a9fa9459Szrj
2298*a9fa9459Szrj if (eh->dyn_relocs == NULL)
2299*a9fa9459Szrj return TRUE;
2300*a9fa9459Szrj
2301*a9fa9459Szrj /* In the shared -Bsymbolic case, discard space allocated for
2302*a9fa9459Szrj dynamic pc-relative relocs against symbols which turn out to be
2303*a9fa9459Szrj defined in regular objects. For the normal shared case, discard
2304*a9fa9459Szrj space for pc-relative relocs that have become local due to symbol
2305*a9fa9459Szrj visibility changes. */
2306*a9fa9459Szrj
2307*a9fa9459Szrj if (bfd_link_pic (info))
2308*a9fa9459Szrj {
2309*a9fa9459Szrj if (SYMBOL_CALLS_LOCAL (info, h))
2310*a9fa9459Szrj {
2311*a9fa9459Szrj struct elf_or1k_dyn_relocs **pp;
2312*a9fa9459Szrj
2313*a9fa9459Szrj for (pp = &eh->dyn_relocs; (p = *pp) != NULL;)
2314*a9fa9459Szrj {
2315*a9fa9459Szrj p->count -= p->pc_count;
2316*a9fa9459Szrj p->pc_count = 0;
2317*a9fa9459Szrj if (p->count == 0)
2318*a9fa9459Szrj *pp = p->next;
2319*a9fa9459Szrj else
2320*a9fa9459Szrj pp = &p->next;
2321*a9fa9459Szrj }
2322*a9fa9459Szrj }
2323*a9fa9459Szrj
2324*a9fa9459Szrj /* Also discard relocs on undefined weak syms with non-default
2325*a9fa9459Szrj visibility. */
2326*a9fa9459Szrj if (eh->dyn_relocs != NULL
2327*a9fa9459Szrj && h->root.type == bfd_link_hash_undefweak)
2328*a9fa9459Szrj {
2329*a9fa9459Szrj if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
2330*a9fa9459Szrj eh->dyn_relocs = NULL;
2331*a9fa9459Szrj
2332*a9fa9459Szrj /* Make sure undefined weak symbols are output as a dynamic
2333*a9fa9459Szrj symbol in PIEs. */
2334*a9fa9459Szrj else if (h->dynindx == -1
2335*a9fa9459Szrj && !h->forced_local)
2336*a9fa9459Szrj {
2337*a9fa9459Szrj if (! bfd_elf_link_record_dynamic_symbol (info, h))
2338*a9fa9459Szrj return FALSE;
2339*a9fa9459Szrj }
2340*a9fa9459Szrj }
2341*a9fa9459Szrj }
2342*a9fa9459Szrj else
2343*a9fa9459Szrj {
2344*a9fa9459Szrj /* For the non-shared case, discard space for relocs against
2345*a9fa9459Szrj symbols which turn out to need copy relocs or are not
2346*a9fa9459Szrj dynamic. */
2347*a9fa9459Szrj
2348*a9fa9459Szrj if (!h->non_got_ref
2349*a9fa9459Szrj && ((h->def_dynamic
2350*a9fa9459Szrj && !h->def_regular)
2351*a9fa9459Szrj || (htab->root.dynamic_sections_created
2352*a9fa9459Szrj && (h->root.type == bfd_link_hash_undefweak
2353*a9fa9459Szrj || h->root.type == bfd_link_hash_undefined))))
2354*a9fa9459Szrj {
2355*a9fa9459Szrj /* Make sure this symbol is output as a dynamic symbol.
2356*a9fa9459Szrj Undefined weak syms won't yet be marked as dynamic. */
2357*a9fa9459Szrj if (h->dynindx == -1
2358*a9fa9459Szrj && !h->forced_local)
2359*a9fa9459Szrj {
2360*a9fa9459Szrj if (! bfd_elf_link_record_dynamic_symbol (info, h))
2361*a9fa9459Szrj return FALSE;
2362*a9fa9459Szrj }
2363*a9fa9459Szrj
2364*a9fa9459Szrj /* If that succeeded, we know we'll be keeping all the
2365*a9fa9459Szrj relocs. */
2366*a9fa9459Szrj if (h->dynindx != -1)
2367*a9fa9459Szrj goto keep;
2368*a9fa9459Szrj }
2369*a9fa9459Szrj
2370*a9fa9459Szrj eh->dyn_relocs = NULL;
2371*a9fa9459Szrj
2372*a9fa9459Szrj keep: ;
2373*a9fa9459Szrj }
2374*a9fa9459Szrj
2375*a9fa9459Szrj /* Finally, allocate space. */
2376*a9fa9459Szrj for (p = eh->dyn_relocs; p != NULL; p = p->next)
2377*a9fa9459Szrj {
2378*a9fa9459Szrj asection *sreloc = elf_section_data (p->sec)->sreloc;
2379*a9fa9459Szrj sreloc->size += p->count * sizeof (Elf32_External_Rela);
2380*a9fa9459Szrj }
2381*a9fa9459Szrj
2382*a9fa9459Szrj return TRUE;
2383*a9fa9459Szrj }
2384*a9fa9459Szrj
2385*a9fa9459Szrj /* Find any dynamic relocs that apply to read-only sections. */
2386*a9fa9459Szrj
2387*a9fa9459Szrj static bfd_boolean
readonly_dynrelocs(struct elf_link_hash_entry * h,void * inf)2388*a9fa9459Szrj readonly_dynrelocs (struct elf_link_hash_entry *h, void * inf)
2389*a9fa9459Szrj {
2390*a9fa9459Szrj struct elf_or1k_link_hash_entry *eh;
2391*a9fa9459Szrj struct elf_or1k_dyn_relocs *p;
2392*a9fa9459Szrj
2393*a9fa9459Szrj eh = (struct elf_or1k_link_hash_entry *) h;
2394*a9fa9459Szrj for (p = eh->dyn_relocs; p != NULL; p = p->next)
2395*a9fa9459Szrj {
2396*a9fa9459Szrj asection *s = p->sec->output_section;
2397*a9fa9459Szrj
2398*a9fa9459Szrj if (s != NULL && (s->flags & SEC_READONLY) != 0)
2399*a9fa9459Szrj {
2400*a9fa9459Szrj struct bfd_link_info *info = (struct bfd_link_info *) inf;
2401*a9fa9459Szrj
2402*a9fa9459Szrj info->flags |= DF_TEXTREL;
2403*a9fa9459Szrj
2404*a9fa9459Szrj /* Not an error, just cut short the traversal. */
2405*a9fa9459Szrj return FALSE;
2406*a9fa9459Szrj }
2407*a9fa9459Szrj }
2408*a9fa9459Szrj return TRUE;
2409*a9fa9459Szrj }
2410*a9fa9459Szrj
2411*a9fa9459Szrj /* Set the sizes of the dynamic sections. */
2412*a9fa9459Szrj
2413*a9fa9459Szrj static bfd_boolean
or1k_elf_size_dynamic_sections(bfd * output_bfd ATTRIBUTE_UNUSED,struct bfd_link_info * info)2414*a9fa9459Szrj or1k_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
2415*a9fa9459Szrj struct bfd_link_info *info)
2416*a9fa9459Szrj {
2417*a9fa9459Szrj struct elf_or1k_link_hash_table *htab;
2418*a9fa9459Szrj bfd *dynobj;
2419*a9fa9459Szrj asection *s;
2420*a9fa9459Szrj bfd_boolean relocs;
2421*a9fa9459Szrj bfd *ibfd;
2422*a9fa9459Szrj
2423*a9fa9459Szrj htab = or1k_elf_hash_table (info);
2424*a9fa9459Szrj if (htab == NULL)
2425*a9fa9459Szrj return FALSE;
2426*a9fa9459Szrj
2427*a9fa9459Szrj dynobj = htab->root.dynobj;
2428*a9fa9459Szrj BFD_ASSERT (dynobj != NULL);
2429*a9fa9459Szrj
2430*a9fa9459Szrj if (htab->root.dynamic_sections_created)
2431*a9fa9459Szrj {
2432*a9fa9459Szrj /* Set the contents of the .interp section to the interpreter. */
2433*a9fa9459Szrj if (bfd_link_executable (info) && !info->nointerp)
2434*a9fa9459Szrj {
2435*a9fa9459Szrj s = bfd_get_section_by_name (dynobj, ".interp");
2436*a9fa9459Szrj BFD_ASSERT (s != NULL);
2437*a9fa9459Szrj s->size = sizeof ELF_DYNAMIC_INTERPRETER;
2438*a9fa9459Szrj s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
2439*a9fa9459Szrj }
2440*a9fa9459Szrj }
2441*a9fa9459Szrj
2442*a9fa9459Szrj /* Set up .got offsets for local syms, and space for local dynamic
2443*a9fa9459Szrj relocs. */
2444*a9fa9459Szrj for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
2445*a9fa9459Szrj {
2446*a9fa9459Szrj bfd_signed_vma *local_got;
2447*a9fa9459Szrj bfd_signed_vma *end_local_got;
2448*a9fa9459Szrj bfd_size_type locsymcount;
2449*a9fa9459Szrj Elf_Internal_Shdr *symtab_hdr;
2450*a9fa9459Szrj unsigned char *local_tls_type;
2451*a9fa9459Szrj asection *srel;
2452*a9fa9459Szrj
2453*a9fa9459Szrj if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
2454*a9fa9459Szrj continue;
2455*a9fa9459Szrj
2456*a9fa9459Szrj for (s = ibfd->sections; s != NULL; s = s->next)
2457*a9fa9459Szrj {
2458*a9fa9459Szrj struct elf_or1k_dyn_relocs *p;
2459*a9fa9459Szrj
2460*a9fa9459Szrj for (p = ((struct elf_or1k_dyn_relocs *)
2461*a9fa9459Szrj elf_section_data (s)->local_dynrel);
2462*a9fa9459Szrj p != NULL;
2463*a9fa9459Szrj p = p->next)
2464*a9fa9459Szrj {
2465*a9fa9459Szrj if (! bfd_is_abs_section (p->sec)
2466*a9fa9459Szrj && bfd_is_abs_section (p->sec->output_section))
2467*a9fa9459Szrj {
2468*a9fa9459Szrj /* Input section has been discarded, either because
2469*a9fa9459Szrj it is a copy of a linkonce section or due to
2470*a9fa9459Szrj linker script /DISCARD/, so we'll be discarding
2471*a9fa9459Szrj the relocs too. */
2472*a9fa9459Szrj }
2473*a9fa9459Szrj else if (p->count != 0)
2474*a9fa9459Szrj {
2475*a9fa9459Szrj srel = elf_section_data (p->sec)->sreloc;
2476*a9fa9459Szrj srel->size += p->count * sizeof (Elf32_External_Rela);
2477*a9fa9459Szrj if ((p->sec->output_section->flags & SEC_READONLY) != 0)
2478*a9fa9459Szrj info->flags |= DF_TEXTREL;
2479*a9fa9459Szrj }
2480*a9fa9459Szrj }
2481*a9fa9459Szrj }
2482*a9fa9459Szrj
2483*a9fa9459Szrj local_got = elf_local_got_refcounts (ibfd);
2484*a9fa9459Szrj if (!local_got)
2485*a9fa9459Szrj continue;
2486*a9fa9459Szrj
2487*a9fa9459Szrj symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
2488*a9fa9459Szrj locsymcount = symtab_hdr->sh_info;
2489*a9fa9459Szrj end_local_got = local_got + locsymcount;
2490*a9fa9459Szrj s = htab->sgot;
2491*a9fa9459Szrj srel = htab->srelgot;
2492*a9fa9459Szrj local_tls_type = (unsigned char *) elf_or1k_local_tls_type (ibfd);
2493*a9fa9459Szrj for (; local_got < end_local_got; ++local_got)
2494*a9fa9459Szrj {
2495*a9fa9459Szrj if (*local_got > 0)
2496*a9fa9459Szrj {
2497*a9fa9459Szrj *local_got = s->size;
2498*a9fa9459Szrj
2499*a9fa9459Szrj /* TLS GD requires two GOT and two relocs. */
2500*a9fa9459Szrj if (local_tls_type != NULL && *local_tls_type == TLS_GD)
2501*a9fa9459Szrj s->size += 8;
2502*a9fa9459Szrj else
2503*a9fa9459Szrj s->size += 4;
2504*a9fa9459Szrj if (bfd_link_pic (info))
2505*a9fa9459Szrj {
2506*a9fa9459Szrj if (local_tls_type != NULL && *local_tls_type == TLS_GD)
2507*a9fa9459Szrj srel->size += 2 * sizeof (Elf32_External_Rela);
2508*a9fa9459Szrj else
2509*a9fa9459Szrj srel->size += sizeof (Elf32_External_Rela);
2510*a9fa9459Szrj }
2511*a9fa9459Szrj }
2512*a9fa9459Szrj else
2513*a9fa9459Szrj
2514*a9fa9459Szrj *local_got = (bfd_vma) -1;
2515*a9fa9459Szrj
2516*a9fa9459Szrj if (local_tls_type)
2517*a9fa9459Szrj ++local_tls_type;
2518*a9fa9459Szrj }
2519*a9fa9459Szrj }
2520*a9fa9459Szrj
2521*a9fa9459Szrj /* Allocate global sym .plt and .got entries, and space for global
2522*a9fa9459Szrj sym dynamic relocs. */
2523*a9fa9459Szrj elf_link_hash_traverse (&htab->root, allocate_dynrelocs, info);
2524*a9fa9459Szrj
2525*a9fa9459Szrj /* We now have determined the sizes of the various dynamic sections.
2526*a9fa9459Szrj Allocate memory for them. */
2527*a9fa9459Szrj relocs = FALSE;
2528*a9fa9459Szrj for (s = dynobj->sections; s != NULL; s = s->next)
2529*a9fa9459Szrj {
2530*a9fa9459Szrj if ((s->flags & SEC_LINKER_CREATED) == 0)
2531*a9fa9459Szrj continue;
2532*a9fa9459Szrj
2533*a9fa9459Szrj if (s == htab->splt
2534*a9fa9459Szrj || s == htab->sgot
2535*a9fa9459Szrj || s == htab->sgotplt
2536*a9fa9459Szrj || s == htab->sdynbss)
2537*a9fa9459Szrj {
2538*a9fa9459Szrj /* Strip this section if we don't need it; see the
2539*a9fa9459Szrj comment below. */
2540*a9fa9459Szrj }
2541*a9fa9459Szrj else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela"))
2542*a9fa9459Szrj {
2543*a9fa9459Szrj if (s->size != 0 && s != htab->srelplt)
2544*a9fa9459Szrj relocs = TRUE;
2545*a9fa9459Szrj
2546*a9fa9459Szrj /* We use the reloc_count field as a counter if we need
2547*a9fa9459Szrj to copy relocs into the output file. */
2548*a9fa9459Szrj s->reloc_count = 0;
2549*a9fa9459Szrj }
2550*a9fa9459Szrj else
2551*a9fa9459Szrj /* It's not one of our sections, so don't allocate space. */
2552*a9fa9459Szrj continue;
2553*a9fa9459Szrj
2554*a9fa9459Szrj if (s->size == 0)
2555*a9fa9459Szrj {
2556*a9fa9459Szrj /* If we don't need this section, strip it from the
2557*a9fa9459Szrj output file. This is mostly to handle .rela.bss and
2558*a9fa9459Szrj .rela.plt. We must create both sections in
2559*a9fa9459Szrj create_dynamic_sections, because they must be created
2560*a9fa9459Szrj before the linker maps input sections to output
2561*a9fa9459Szrj sections. The linker does that before
2562*a9fa9459Szrj adjust_dynamic_symbol is called, and it is that
2563*a9fa9459Szrj function which decides whether anything needs to go
2564*a9fa9459Szrj into these sections. */
2565*a9fa9459Szrj s->flags |= SEC_EXCLUDE;
2566*a9fa9459Szrj continue;
2567*a9fa9459Szrj }
2568*a9fa9459Szrj
2569*a9fa9459Szrj if ((s->flags & SEC_HAS_CONTENTS) == 0)
2570*a9fa9459Szrj continue;
2571*a9fa9459Szrj
2572*a9fa9459Szrj /* Allocate memory for the section contents. We use bfd_zalloc
2573*a9fa9459Szrj here in case unused entries are not reclaimed before the
2574*a9fa9459Szrj section's contents are written out. This should not happen,
2575*a9fa9459Szrj but this way if it does, we get a R_OR1K_NONE reloc instead
2576*a9fa9459Szrj of garbage. */
2577*a9fa9459Szrj s->contents = bfd_zalloc (dynobj, s->size);
2578*a9fa9459Szrj
2579*a9fa9459Szrj if (s->contents == NULL)
2580*a9fa9459Szrj return FALSE;
2581*a9fa9459Szrj }
2582*a9fa9459Szrj
2583*a9fa9459Szrj if (htab->root.dynamic_sections_created)
2584*a9fa9459Szrj {
2585*a9fa9459Szrj /* Add some entries to the .dynamic section. We fill in the
2586*a9fa9459Szrj values later, in or1k_elf_finish_dynamic_sections, but we
2587*a9fa9459Szrj must add the entries now so that we get the correct size for
2588*a9fa9459Szrj the .dynamic section. The DT_DEBUG entry is filled in by the
2589*a9fa9459Szrj dynamic linker and used by the debugger. */
2590*a9fa9459Szrj #define add_dynamic_entry(TAG, VAL) \
2591*a9fa9459Szrj _bfd_elf_add_dynamic_entry (info, TAG, VAL)
2592*a9fa9459Szrj
2593*a9fa9459Szrj if (bfd_link_executable (info))
2594*a9fa9459Szrj {
2595*a9fa9459Szrj if (! add_dynamic_entry (DT_DEBUG, 0))
2596*a9fa9459Szrj return FALSE;
2597*a9fa9459Szrj }
2598*a9fa9459Szrj
2599*a9fa9459Szrj if (htab->splt->size != 0)
2600*a9fa9459Szrj {
2601*a9fa9459Szrj if (! add_dynamic_entry (DT_PLTGOT, 0)
2602*a9fa9459Szrj || ! add_dynamic_entry (DT_PLTRELSZ, 0)
2603*a9fa9459Szrj || ! add_dynamic_entry (DT_PLTREL, DT_RELA)
2604*a9fa9459Szrj || ! add_dynamic_entry (DT_JMPREL, 0))
2605*a9fa9459Szrj return FALSE;
2606*a9fa9459Szrj }
2607*a9fa9459Szrj
2608*a9fa9459Szrj if (relocs)
2609*a9fa9459Szrj {
2610*a9fa9459Szrj if (! add_dynamic_entry (DT_RELA, 0)
2611*a9fa9459Szrj || ! add_dynamic_entry (DT_RELASZ, 0)
2612*a9fa9459Szrj || ! add_dynamic_entry (DT_RELAENT,
2613*a9fa9459Szrj sizeof (Elf32_External_Rela)))
2614*a9fa9459Szrj return FALSE;
2615*a9fa9459Szrj
2616*a9fa9459Szrj /* If any dynamic relocs apply to a read-only section,
2617*a9fa9459Szrj then we need a DT_TEXTREL entry. */
2618*a9fa9459Szrj if ((info->flags & DF_TEXTREL) == 0)
2619*a9fa9459Szrj elf_link_hash_traverse (&htab->root, readonly_dynrelocs,
2620*a9fa9459Szrj info);
2621*a9fa9459Szrj
2622*a9fa9459Szrj if ((info->flags & DF_TEXTREL) != 0)
2623*a9fa9459Szrj {
2624*a9fa9459Szrj if (! add_dynamic_entry (DT_TEXTREL, 0))
2625*a9fa9459Szrj return FALSE;
2626*a9fa9459Szrj }
2627*a9fa9459Szrj }
2628*a9fa9459Szrj }
2629*a9fa9459Szrj
2630*a9fa9459Szrj #undef add_dynamic_entry
2631*a9fa9459Szrj return TRUE;
2632*a9fa9459Szrj }
2633*a9fa9459Szrj
2634*a9fa9459Szrj /* Create dynamic sections when linking against a dynamic object. */
2635*a9fa9459Szrj
2636*a9fa9459Szrj static bfd_boolean
or1k_elf_create_dynamic_sections(bfd * dynobj,struct bfd_link_info * info)2637*a9fa9459Szrj or1k_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
2638*a9fa9459Szrj {
2639*a9fa9459Szrj struct elf_or1k_link_hash_table *htab;
2640*a9fa9459Szrj
2641*a9fa9459Szrj htab = or1k_elf_hash_table (info);
2642*a9fa9459Szrj if (htab == NULL)
2643*a9fa9459Szrj return FALSE;
2644*a9fa9459Szrj
2645*a9fa9459Szrj if (!htab->sgot && !create_got_section (dynobj, info))
2646*a9fa9459Szrj return FALSE;
2647*a9fa9459Szrj
2648*a9fa9459Szrj if (!_bfd_elf_create_dynamic_sections (dynobj, info))
2649*a9fa9459Szrj return FALSE;
2650*a9fa9459Szrj
2651*a9fa9459Szrj htab->splt = bfd_get_section_by_name (dynobj, ".plt");
2652*a9fa9459Szrj htab->srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
2653*a9fa9459Szrj htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss");
2654*a9fa9459Szrj if (!bfd_link_pic (info))
2655*a9fa9459Szrj htab->srelbss = bfd_get_section_by_name (dynobj, ".rela.bss");
2656*a9fa9459Szrj
2657*a9fa9459Szrj if (!htab->splt || !htab->srelplt || !htab->sdynbss
2658*a9fa9459Szrj || (!bfd_link_pic (info) && !htab->srelbss))
2659*a9fa9459Szrj abort ();
2660*a9fa9459Szrj
2661*a9fa9459Szrj return TRUE;
2662*a9fa9459Szrj }
2663*a9fa9459Szrj
2664*a9fa9459Szrj /* Copy the extra info we tack onto an elf_link_hash_entry. */
2665*a9fa9459Szrj
2666*a9fa9459Szrj static void
or1k_elf_copy_indirect_symbol(struct bfd_link_info * info,struct elf_link_hash_entry * dir,struct elf_link_hash_entry * ind)2667*a9fa9459Szrj or1k_elf_copy_indirect_symbol (struct bfd_link_info *info,
2668*a9fa9459Szrj struct elf_link_hash_entry *dir,
2669*a9fa9459Szrj struct elf_link_hash_entry *ind)
2670*a9fa9459Szrj {
2671*a9fa9459Szrj struct elf_or1k_link_hash_entry * edir;
2672*a9fa9459Szrj struct elf_or1k_link_hash_entry * eind;
2673*a9fa9459Szrj
2674*a9fa9459Szrj edir = (struct elf_or1k_link_hash_entry *) dir;
2675*a9fa9459Szrj eind = (struct elf_or1k_link_hash_entry *) ind;
2676*a9fa9459Szrj
2677*a9fa9459Szrj if (eind->dyn_relocs != NULL)
2678*a9fa9459Szrj {
2679*a9fa9459Szrj if (edir->dyn_relocs != NULL)
2680*a9fa9459Szrj {
2681*a9fa9459Szrj struct elf_or1k_dyn_relocs **pp;
2682*a9fa9459Szrj struct elf_or1k_dyn_relocs *p;
2683*a9fa9459Szrj
2684*a9fa9459Szrj /* Add reloc counts against the indirect sym to the direct sym
2685*a9fa9459Szrj list. Merge any entries against the same section. */
2686*a9fa9459Szrj for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
2687*a9fa9459Szrj {
2688*a9fa9459Szrj struct elf_or1k_dyn_relocs *q;
2689*a9fa9459Szrj
2690*a9fa9459Szrj for (q = edir->dyn_relocs; q != NULL; q = q->next)
2691*a9fa9459Szrj if (q->sec == p->sec)
2692*a9fa9459Szrj {
2693*a9fa9459Szrj q->pc_count += p->pc_count;
2694*a9fa9459Szrj q->count += p->count;
2695*a9fa9459Szrj *pp = p->next;
2696*a9fa9459Szrj break;
2697*a9fa9459Szrj }
2698*a9fa9459Szrj if (q == NULL)
2699*a9fa9459Szrj pp = &p->next;
2700*a9fa9459Szrj }
2701*a9fa9459Szrj *pp = edir->dyn_relocs;
2702*a9fa9459Szrj }
2703*a9fa9459Szrj
2704*a9fa9459Szrj edir->dyn_relocs = eind->dyn_relocs;
2705*a9fa9459Szrj eind->dyn_relocs = NULL;
2706*a9fa9459Szrj }
2707*a9fa9459Szrj
2708*a9fa9459Szrj if (ind->root.type == bfd_link_hash_indirect)
2709*a9fa9459Szrj {
2710*a9fa9459Szrj if (dir->got.refcount <= 0)
2711*a9fa9459Szrj {
2712*a9fa9459Szrj edir->tls_type = eind->tls_type;
2713*a9fa9459Szrj eind->tls_type = TLS_UNKNOWN;
2714*a9fa9459Szrj }
2715*a9fa9459Szrj }
2716*a9fa9459Szrj
2717*a9fa9459Szrj _bfd_elf_link_hash_copy_indirect (info, dir, ind);
2718*a9fa9459Szrj }
2719*a9fa9459Szrj
2720*a9fa9459Szrj /* Set the right machine number. */
2721*a9fa9459Szrj
2722*a9fa9459Szrj static bfd_boolean
or1k_elf_object_p(bfd * abfd)2723*a9fa9459Szrj or1k_elf_object_p (bfd *abfd)
2724*a9fa9459Szrj {
2725*a9fa9459Szrj unsigned long mach = bfd_mach_or1k;
2726*a9fa9459Szrj
2727*a9fa9459Szrj if (elf_elfheader (abfd)->e_flags & EF_OR1K_NODELAY)
2728*a9fa9459Szrj mach = bfd_mach_or1knd;
2729*a9fa9459Szrj
2730*a9fa9459Szrj return bfd_default_set_arch_mach (abfd, bfd_arch_or1k, mach);
2731*a9fa9459Szrj }
2732*a9fa9459Szrj
2733*a9fa9459Szrj /* Store the machine number in the flags field. */
2734*a9fa9459Szrj
2735*a9fa9459Szrj static void
or1k_elf_final_write_processing(bfd * abfd,bfd_boolean linker ATTRIBUTE_UNUSED)2736*a9fa9459Szrj or1k_elf_final_write_processing (bfd *abfd,
2737*a9fa9459Szrj bfd_boolean linker ATTRIBUTE_UNUSED)
2738*a9fa9459Szrj {
2739*a9fa9459Szrj switch (bfd_get_mach (abfd))
2740*a9fa9459Szrj {
2741*a9fa9459Szrj default:
2742*a9fa9459Szrj case bfd_mach_or1k:
2743*a9fa9459Szrj break;
2744*a9fa9459Szrj case bfd_mach_or1knd:
2745*a9fa9459Szrj elf_elfheader (abfd)->e_flags |= EF_OR1K_NODELAY;
2746*a9fa9459Szrj break;
2747*a9fa9459Szrj }
2748*a9fa9459Szrj }
2749*a9fa9459Szrj
2750*a9fa9459Szrj static bfd_boolean
or1k_elf_set_private_flags(bfd * abfd,flagword flags)2751*a9fa9459Szrj or1k_elf_set_private_flags (bfd *abfd, flagword flags)
2752*a9fa9459Szrj {
2753*a9fa9459Szrj BFD_ASSERT (!elf_flags_init (abfd)
2754*a9fa9459Szrj || elf_elfheader (abfd)->e_flags == flags);
2755*a9fa9459Szrj
2756*a9fa9459Szrj elf_elfheader (abfd)->e_flags = flags;
2757*a9fa9459Szrj elf_flags_init (abfd) = TRUE;
2758*a9fa9459Szrj return TRUE;
2759*a9fa9459Szrj }
2760*a9fa9459Szrj
2761*a9fa9459Szrj /* Make sure all input files are consistent with respect to
2762*a9fa9459Szrj EF_OR1K_NODELAY flag setting. */
2763*a9fa9459Szrj
2764*a9fa9459Szrj static bfd_boolean
elf32_or1k_merge_private_bfd_data(bfd * ibfd,bfd * obfd)2765*a9fa9459Szrj elf32_or1k_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
2766*a9fa9459Szrj {
2767*a9fa9459Szrj flagword out_flags;
2768*a9fa9459Szrj flagword in_flags;
2769*a9fa9459Szrj
2770*a9fa9459Szrj in_flags = elf_elfheader (ibfd)->e_flags;
2771*a9fa9459Szrj out_flags = elf_elfheader (obfd)->e_flags;
2772*a9fa9459Szrj
2773*a9fa9459Szrj if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
2774*a9fa9459Szrj || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
2775*a9fa9459Szrj return TRUE;
2776*a9fa9459Szrj
2777*a9fa9459Szrj if (!elf_flags_init (obfd))
2778*a9fa9459Szrj {
2779*a9fa9459Szrj elf_flags_init (obfd) = TRUE;
2780*a9fa9459Szrj elf_elfheader (obfd)->e_flags = in_flags;
2781*a9fa9459Szrj
2782*a9fa9459Szrj return TRUE;
2783*a9fa9459Szrj }
2784*a9fa9459Szrj
2785*a9fa9459Szrj if (in_flags == out_flags)
2786*a9fa9459Szrj return TRUE;
2787*a9fa9459Szrj
2788*a9fa9459Szrj if ((in_flags & EF_OR1K_NODELAY) != (out_flags & EF_OR1K_NODELAY))
2789*a9fa9459Szrj {
2790*a9fa9459Szrj (*_bfd_error_handler)
2791*a9fa9459Szrj (_("%B: EF_OR1K_NODELAY flag mismatch with previous modules"), ibfd);
2792*a9fa9459Szrj
2793*a9fa9459Szrj bfd_set_error (bfd_error_bad_value);
2794*a9fa9459Szrj return FALSE;
2795*a9fa9459Szrj }
2796*a9fa9459Szrj
2797*a9fa9459Szrj return TRUE;
2798*a9fa9459Szrj
2799*a9fa9459Szrj }
2800*a9fa9459Szrj
2801*a9fa9459Szrj #define ELF_ARCH bfd_arch_or1k
2802*a9fa9459Szrj #define ELF_MACHINE_CODE EM_OR1K
2803*a9fa9459Szrj #define ELF_TARGET_ID OR1K_ELF_DATA
2804*a9fa9459Szrj #define ELF_MAXPAGESIZE 0x2000
2805*a9fa9459Szrj
2806*a9fa9459Szrj #define TARGET_BIG_SYM or1k_elf32_vec
2807*a9fa9459Szrj #define TARGET_BIG_NAME "elf32-or1k"
2808*a9fa9459Szrj
2809*a9fa9459Szrj #define elf_info_to_howto_rel NULL
2810*a9fa9459Szrj #define elf_info_to_howto or1k_info_to_howto_rela
2811*a9fa9459Szrj #define elf_backend_relocate_section or1k_elf_relocate_section
2812*a9fa9459Szrj #define elf_backend_gc_mark_hook or1k_elf_gc_mark_hook
2813*a9fa9459Szrj #define elf_backend_gc_sweep_hook or1k_elf_gc_sweep_hook
2814*a9fa9459Szrj #define elf_backend_check_relocs or1k_elf_check_relocs
2815*a9fa9459Szrj #define elf_backend_reloc_type_class or1k_elf_reloc_type_class
2816*a9fa9459Szrj #define elf_backend_can_gc_sections 1
2817*a9fa9459Szrj #define elf_backend_rela_normal 1
2818*a9fa9459Szrj
2819*a9fa9459Szrj #define bfd_elf32_mkobject elf_or1k_mkobject
2820*a9fa9459Szrj
2821*a9fa9459Szrj #define bfd_elf32_bfd_merge_private_bfd_data elf32_or1k_merge_private_bfd_data
2822*a9fa9459Szrj #define bfd_elf32_bfd_set_private_flags or1k_elf_set_private_flags
2823*a9fa9459Szrj #define bfd_elf32_bfd_reloc_type_lookup or1k_reloc_type_lookup
2824*a9fa9459Szrj #define bfd_elf32_bfd_reloc_name_lookup or1k_reloc_name_lookup
2825*a9fa9459Szrj
2826*a9fa9459Szrj #define elf_backend_object_p or1k_elf_object_p
2827*a9fa9459Szrj #define elf_backend_final_write_processing or1k_elf_final_write_processing
2828*a9fa9459Szrj #define elf_backend_can_refcount 1
2829*a9fa9459Szrj
2830*a9fa9459Szrj #define elf_backend_plt_readonly 1
2831*a9fa9459Szrj #define elf_backend_want_got_plt 1
2832*a9fa9459Szrj #define elf_backend_want_plt_sym 0
2833*a9fa9459Szrj #define elf_backend_got_header_size 12
2834*a9fa9459Szrj #define bfd_elf32_bfd_link_hash_table_create or1k_elf_link_hash_table_create
2835*a9fa9459Szrj #define elf_backend_copy_indirect_symbol or1k_elf_copy_indirect_symbol
2836*a9fa9459Szrj #define elf_backend_create_dynamic_sections or1k_elf_create_dynamic_sections
2837*a9fa9459Szrj #define elf_backend_finish_dynamic_sections or1k_elf_finish_dynamic_sections
2838*a9fa9459Szrj #define elf_backend_size_dynamic_sections or1k_elf_size_dynamic_sections
2839*a9fa9459Szrj #define elf_backend_adjust_dynamic_symbol or1k_elf_adjust_dynamic_symbol
2840*a9fa9459Szrj #define elf_backend_finish_dynamic_symbol or1k_elf_finish_dynamic_symbol
2841*a9fa9459Szrj
2842*a9fa9459Szrj #include "elf32-target.h"
2843