1377e23a2Schristos /* VAX series support for 32-bit ELF
2*1424dfb3Schristos Copyright (C) 1993-2020 Free Software Foundation, Inc.
3377e23a2Schristos Contributed by Matt Thomas <matt@3am-software.com>.
4377e23a2Schristos
5377e23a2Schristos This file is part of BFD, the Binary File Descriptor library.
6377e23a2Schristos
7377e23a2Schristos This program is free software; you can redistribute it and/or modify
8377e23a2Schristos it under the terms of the GNU General Public License as published by
9377e23a2Schristos the Free Software Foundation; either version 3 of the License, or
10377e23a2Schristos (at your option) any later version.
11377e23a2Schristos
12377e23a2Schristos This program is distributed in the hope that it will be useful,
13377e23a2Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
14377e23a2Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15377e23a2Schristos GNU General Public License for more details.
16377e23a2Schristos
17377e23a2Schristos You should have received a copy of the GNU General Public License
18377e23a2Schristos along with this program; if not, write to the Free Software
19377e23a2Schristos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20377e23a2Schristos MA 02110-1301, USA. */
21377e23a2Schristos
22377e23a2Schristos #include "sysdep.h"
23377e23a2Schristos #include "bfd.h"
24377e23a2Schristos #include "bfdlink.h"
25377e23a2Schristos #include "libbfd.h"
26377e23a2Schristos #include "elf-bfd.h"
27377e23a2Schristos #include "elf/vax.h"
28377e23a2Schristos
29377e23a2Schristos static reloc_howto_type *reloc_type_lookup (bfd *, bfd_reloc_code_real_type);
3007163879Schristos static bfd_boolean rtype_to_howto (bfd *, arelent *, Elf_Internal_Rela *);
31377e23a2Schristos static struct bfd_hash_entry *elf_vax_link_hash_newfunc (struct bfd_hash_entry *,
32377e23a2Schristos struct bfd_hash_table *,
33377e23a2Schristos const char *);
34377e23a2Schristos static struct bfd_link_hash_table *elf_vax_link_hash_table_create (bfd *);
35377e23a2Schristos static bfd_boolean elf_vax_check_relocs (bfd *, struct bfd_link_info *,
36377e23a2Schristos asection *, const Elf_Internal_Rela *);
37377e23a2Schristos static bfd_boolean elf_vax_adjust_dynamic_symbol (struct bfd_link_info *,
38377e23a2Schristos struct elf_link_hash_entry *);
39377e23a2Schristos static bfd_boolean elf_vax_size_dynamic_sections (bfd *, struct bfd_link_info *);
40377e23a2Schristos static bfd_boolean elf_vax_relocate_section (bfd *, struct bfd_link_info *,
41377e23a2Schristos bfd *, asection *, bfd_byte *,
42377e23a2Schristos Elf_Internal_Rela *,
43377e23a2Schristos Elf_Internal_Sym *, asection **);
44377e23a2Schristos static bfd_boolean elf_vax_finish_dynamic_symbol (bfd *, struct bfd_link_info *,
45377e23a2Schristos struct elf_link_hash_entry *,
46377e23a2Schristos Elf_Internal_Sym *);
47377e23a2Schristos static bfd_boolean elf_vax_finish_dynamic_sections (bfd *,
48377e23a2Schristos struct bfd_link_info *);
49377e23a2Schristos static bfd_vma elf_vax_plt_sym_val (bfd_vma, const asection *,
50377e23a2Schristos const arelent *);
51377e23a2Schristos
52377e23a2Schristos static bfd_boolean elf32_vax_set_private_flags (bfd *, flagword);
5348596154Schristos static bfd_boolean elf32_vax_print_private_bfd_data (bfd *, void *);
54377e23a2Schristos
55377e23a2Schristos static reloc_howto_type howto_table[] = {
56377e23a2Schristos HOWTO (R_VAX_NONE, /* type */
57377e23a2Schristos 0, /* rightshift */
58ed6a76a9Schristos 3, /* size (0 = byte, 1 = short, 2 = long) */
59377e23a2Schristos 0, /* bitsize */
60377e23a2Schristos FALSE, /* pc_relative */
61377e23a2Schristos 0, /* bitpos */
62377e23a2Schristos complain_overflow_dont, /* complain_on_overflow */
63377e23a2Schristos bfd_elf_generic_reloc, /* special_function */
64377e23a2Schristos "R_VAX_NONE", /* name */
65377e23a2Schristos FALSE, /* partial_inplace */
66377e23a2Schristos 0, /* src_mask */
67377e23a2Schristos 0x00000000, /* dst_mask */
68377e23a2Schristos FALSE), /* pcrel_offset */
69377e23a2Schristos
70377e23a2Schristos HOWTO (R_VAX_32, /* type */
71377e23a2Schristos 0, /* rightshift */
72377e23a2Schristos 2, /* size (0 = byte, 1 = short, 2 = long) */
73377e23a2Schristos 32, /* bitsize */
74377e23a2Schristos FALSE, /* pc_relative */
75377e23a2Schristos 0, /* bitpos */
76377e23a2Schristos complain_overflow_bitfield, /* complain_on_overflow */
77377e23a2Schristos bfd_elf_generic_reloc, /* special_function */
78377e23a2Schristos "R_VAX_32", /* name */
79377e23a2Schristos FALSE, /* partial_inplace */
80377e23a2Schristos 0, /* src_mask */
81377e23a2Schristos 0xffffffff, /* dst_mask */
82377e23a2Schristos FALSE), /* pcrel_offset */
83377e23a2Schristos
84377e23a2Schristos HOWTO (R_VAX_16, /* type */
85377e23a2Schristos 0, /* rightshift */
86377e23a2Schristos 1, /* size (0 = byte, 1 = short, 2 = long) */
87377e23a2Schristos 16, /* bitsize */
88377e23a2Schristos FALSE, /* pc_relative */
89377e23a2Schristos 0, /* bitpos */
90377e23a2Schristos complain_overflow_bitfield, /* complain_on_overflow */
91377e23a2Schristos bfd_elf_generic_reloc, /* special_function */
92377e23a2Schristos "R_VAX_16", /* name */
93377e23a2Schristos FALSE, /* partial_inplace */
94377e23a2Schristos 0, /* src_mask */
95377e23a2Schristos 0x0000ffff, /* dst_mask */
96377e23a2Schristos FALSE), /* pcrel_offset */
97377e23a2Schristos
98377e23a2Schristos HOWTO (R_VAX_8, /* type */
99377e23a2Schristos 0, /* rightshift */
100377e23a2Schristos 0, /* size (0 = byte, 1 = short, 2 = long) */
101377e23a2Schristos 8, /* bitsize */
102377e23a2Schristos FALSE, /* pc_relative */
103377e23a2Schristos 0, /* bitpos */
104377e23a2Schristos complain_overflow_bitfield, /* complain_on_overflow */
105377e23a2Schristos bfd_elf_generic_reloc, /* special_function */
106377e23a2Schristos "R_VAX_8", /* name */
107377e23a2Schristos FALSE, /* partial_inplace */
108377e23a2Schristos 0, /* src_mask */
109377e23a2Schristos 0x000000ff, /* dst_mask */
110377e23a2Schristos FALSE), /* pcrel_offset */
111377e23a2Schristos
112377e23a2Schristos HOWTO (R_VAX_PC32, /* type */
113377e23a2Schristos 0, /* rightshift */
114377e23a2Schristos 2, /* size (0 = byte, 1 = short, 2 = long) */
115377e23a2Schristos 32, /* bitsize */
116377e23a2Schristos TRUE, /* pc_relative */
117377e23a2Schristos 0, /* bitpos */
118377e23a2Schristos complain_overflow_bitfield, /* complain_on_overflow */
119377e23a2Schristos bfd_elf_generic_reloc, /* special_function */
120377e23a2Schristos "R_VAX_PC32", /* name */
121377e23a2Schristos FALSE, /* partial_inplace */
122377e23a2Schristos 0, /* src_mask */
123377e23a2Schristos 0xffffffff, /* dst_mask */
124377e23a2Schristos TRUE), /* pcrel_offset */
125377e23a2Schristos
126377e23a2Schristos HOWTO (R_VAX_PC16, /* type */
127377e23a2Schristos 0, /* rightshift */
128377e23a2Schristos 1, /* size (0 = byte, 1 = short, 2 = long) */
129377e23a2Schristos 16, /* bitsize */
130377e23a2Schristos TRUE, /* pc_relative */
131377e23a2Schristos 0, /* bitpos */
132377e23a2Schristos complain_overflow_signed, /* complain_on_overflow */
133377e23a2Schristos bfd_elf_generic_reloc, /* special_function */
134377e23a2Schristos "R_VAX_PC16", /* name */
135377e23a2Schristos FALSE, /* partial_inplace */
136377e23a2Schristos 0, /* src_mask */
137377e23a2Schristos 0x0000ffff, /* dst_mask */
138377e23a2Schristos TRUE), /* pcrel_offset */
139377e23a2Schristos
140377e23a2Schristos HOWTO (R_VAX_PC8, /* type */
141377e23a2Schristos 0, /* rightshift */
142377e23a2Schristos 0, /* size (0 = byte, 1 = short, 2 = long) */
143377e23a2Schristos 8, /* bitsize */
144377e23a2Schristos TRUE, /* pc_relative */
145377e23a2Schristos 0, /* bitpos */
146377e23a2Schristos complain_overflow_signed, /* complain_on_overflow */
147377e23a2Schristos bfd_elf_generic_reloc, /* special_function */
148377e23a2Schristos "R_VAX_PC8", /* name */
149377e23a2Schristos FALSE, /* partial_inplace */
150377e23a2Schristos 0, /* src_mask */
151377e23a2Schristos 0x000000ff, /* dst_mask */
152377e23a2Schristos TRUE), /* pcrel_offset */
153377e23a2Schristos
154377e23a2Schristos HOWTO (R_VAX_GOT32, /* type */
155377e23a2Schristos 0, /* rightshift */
156377e23a2Schristos 2, /* size (0 = byte, 1 = short, 2 = long) */
157377e23a2Schristos 32, /* bitsize */
158377e23a2Schristos TRUE, /* pc_relative */
159377e23a2Schristos 0, /* bitpos */
160377e23a2Schristos complain_overflow_bitfield, /* complain_on_overflow */
161377e23a2Schristos bfd_elf_generic_reloc, /* special_function */
162377e23a2Schristos "R_VAX_GOT32", /* name */
163377e23a2Schristos FALSE, /* partial_inplace */
164377e23a2Schristos 0, /* src_mask */
165377e23a2Schristos 0xffffffff, /* dst_mask */
166377e23a2Schristos TRUE), /* pcrel_offset */
167377e23a2Schristos
168377e23a2Schristos EMPTY_HOWTO (-1),
169377e23a2Schristos EMPTY_HOWTO (-1),
170377e23a2Schristos EMPTY_HOWTO (-1),
171377e23a2Schristos EMPTY_HOWTO (-1),
172377e23a2Schristos EMPTY_HOWTO (-1),
173377e23a2Schristos
174377e23a2Schristos HOWTO (R_VAX_PLT32, /* type */
175377e23a2Schristos 0, /* rightshift */
176377e23a2Schristos 2, /* size (0 = byte, 1 = short, 2 = long) */
177377e23a2Schristos 32, /* bitsize */
178377e23a2Schristos TRUE, /* pc_relative */
179377e23a2Schristos 0, /* bitpos */
180377e23a2Schristos complain_overflow_bitfield, /* complain_on_overflow */
181377e23a2Schristos bfd_elf_generic_reloc, /* special_function */
182377e23a2Schristos "R_VAX_PLT32", /* name */
183377e23a2Schristos FALSE, /* partial_inplace */
184377e23a2Schristos 0, /* src_mask */
185377e23a2Schristos 0xffffffff, /* dst_mask */
186377e23a2Schristos TRUE), /* pcrel_offset */
187377e23a2Schristos
188377e23a2Schristos EMPTY_HOWTO (-1),
189377e23a2Schristos EMPTY_HOWTO (-1),
190377e23a2Schristos EMPTY_HOWTO (-1),
191377e23a2Schristos EMPTY_HOWTO (-1),
192377e23a2Schristos EMPTY_HOWTO (-1),
193377e23a2Schristos
194377e23a2Schristos HOWTO (R_VAX_COPY, /* type */
195377e23a2Schristos 0, /* rightshift */
196377e23a2Schristos 0, /* size (0 = byte, 1 = short, 2 = long) */
197377e23a2Schristos 0, /* bitsize */
198377e23a2Schristos FALSE, /* pc_relative */
199377e23a2Schristos 0, /* bitpos */
200377e23a2Schristos complain_overflow_dont, /* complain_on_overflow */
201377e23a2Schristos bfd_elf_generic_reloc, /* special_function */
202377e23a2Schristos "R_VAX_COPY", /* name */
203377e23a2Schristos FALSE, /* partial_inplace */
204377e23a2Schristos 0, /* src_mask */
205377e23a2Schristos 0xffffffff, /* dst_mask */
206377e23a2Schristos FALSE), /* pcrel_offset */
207377e23a2Schristos
208377e23a2Schristos HOWTO (R_VAX_GLOB_DAT, /* type */
209377e23a2Schristos 0, /* rightshift */
210377e23a2Schristos 2, /* size (0 = byte, 1 = short, 2 = long) */
211377e23a2Schristos 32, /* bitsize */
212377e23a2Schristos FALSE, /* pc_relative */
213377e23a2Schristos 0, /* bitpos */
214377e23a2Schristos complain_overflow_dont, /* complain_on_overflow */
215377e23a2Schristos bfd_elf_generic_reloc, /* special_function */
216377e23a2Schristos "R_VAX_GLOB_DAT", /* name */
217377e23a2Schristos FALSE, /* partial_inplace */
218377e23a2Schristos 0, /* src_mask */
219377e23a2Schristos 0xffffffff, /* dst_mask */
220377e23a2Schristos FALSE), /* pcrel_offset */
221377e23a2Schristos
222377e23a2Schristos HOWTO (R_VAX_JMP_SLOT, /* type */
223377e23a2Schristos 0, /* rightshift */
224377e23a2Schristos 2, /* size (0 = byte, 1 = short, 2 = long) */
225377e23a2Schristos 32, /* bitsize */
226377e23a2Schristos FALSE, /* pc_relative */
227377e23a2Schristos 0, /* bitpos */
228377e23a2Schristos complain_overflow_dont, /* complain_on_overflow */
229377e23a2Schristos bfd_elf_generic_reloc, /* special_function */
230377e23a2Schristos "R_VAX_JMP_SLOT", /* name */
231377e23a2Schristos FALSE, /* partial_inplace */
232377e23a2Schristos 0, /* src_mask */
233377e23a2Schristos 0xffffffff, /* dst_mask */
234377e23a2Schristos FALSE), /* pcrel_offset */
235377e23a2Schristos
236377e23a2Schristos HOWTO (R_VAX_RELATIVE, /* type */
237377e23a2Schristos 0, /* rightshift */
238377e23a2Schristos 2, /* size (0 = byte, 1 = short, 2 = long) */
239377e23a2Schristos 32, /* bitsize */
240377e23a2Schristos FALSE, /* pc_relative */
241377e23a2Schristos 0, /* bitpos */
242377e23a2Schristos complain_overflow_dont, /* complain_on_overflow */
243377e23a2Schristos bfd_elf_generic_reloc, /* special_function */
244377e23a2Schristos "R_VAX_RELATIVE", /* name */
245377e23a2Schristos FALSE, /* partial_inplace */
246377e23a2Schristos 0, /* src_mask */
247377e23a2Schristos 0xffffffff, /* dst_mask */
248377e23a2Schristos FALSE), /* pcrel_offset */
249377e23a2Schristos
250377e23a2Schristos /* GNU extension to record C++ vtable hierarchy */
251377e23a2Schristos HOWTO (R_VAX_GNU_VTINHERIT, /* type */
252377e23a2Schristos 0, /* rightshift */
253377e23a2Schristos 2, /* size (0 = byte, 1 = short, 2 = long) */
254377e23a2Schristos 0, /* bitsize */
255377e23a2Schristos FALSE, /* pc_relative */
256377e23a2Schristos 0, /* bitpos */
257377e23a2Schristos complain_overflow_dont, /* complain_on_overflow */
258377e23a2Schristos NULL, /* special_function */
259377e23a2Schristos "R_VAX_GNU_VTINHERIT", /* name */
260377e23a2Schristos FALSE, /* partial_inplace */
261377e23a2Schristos 0, /* src_mask */
262377e23a2Schristos 0, /* dst_mask */
263377e23a2Schristos FALSE), /* pcrel_offset */
264377e23a2Schristos
265377e23a2Schristos /* GNU extension to record C++ vtable member usage */
266377e23a2Schristos HOWTO (R_VAX_GNU_VTENTRY, /* type */
267377e23a2Schristos 0, /* rightshift */
268377e23a2Schristos 2, /* size (0 = byte, 1 = short, 2 = long) */
269377e23a2Schristos 0, /* bitsize */
270377e23a2Schristos FALSE, /* pc_relative */
271377e23a2Schristos 0, /* bitpos */
272377e23a2Schristos complain_overflow_dont, /* complain_on_overflow */
273377e23a2Schristos _bfd_elf_rel_vtable_reloc_fn, /* special_function */
274377e23a2Schristos "R_VAX_GNU_VTENTRY", /* name */
275377e23a2Schristos FALSE, /* partial_inplace */
276377e23a2Schristos 0, /* src_mask */
277377e23a2Schristos 0, /* dst_mask */
278377e23a2Schristos FALSE), /* pcrel_offset */
279377e23a2Schristos };
280377e23a2Schristos
28107163879Schristos static bfd_boolean
rtype_to_howto(bfd * abfd,arelent * cache_ptr,Elf_Internal_Rela * dst)282ed6a76a9Schristos rtype_to_howto (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
283377e23a2Schristos {
284ed6a76a9Schristos unsigned int r_type;
285ed6a76a9Schristos
286ed6a76a9Schristos r_type = ELF32_R_TYPE (dst->r_info);
287ed6a76a9Schristos if (r_type >= R_VAX_max)
288ed6a76a9Schristos {
2891c468f90Schristos /* xgettext:c-format */
29007163879Schristos _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
291ed6a76a9Schristos abfd, r_type);
292ed6a76a9Schristos bfd_set_error (bfd_error_bad_value);
29307163879Schristos return FALSE;
294ed6a76a9Schristos }
295ed6a76a9Schristos cache_ptr->howto = &howto_table[r_type];
29607163879Schristos return TRUE;
297377e23a2Schristos }
298377e23a2Schristos
299377e23a2Schristos #define elf_info_to_howto rtype_to_howto
300377e23a2Schristos
301377e23a2Schristos static const struct
302377e23a2Schristos {
303377e23a2Schristos bfd_reloc_code_real_type bfd_val;
304377e23a2Schristos int elf_val;
305377e23a2Schristos } reloc_map[] = {
306377e23a2Schristos { BFD_RELOC_NONE, R_VAX_NONE },
307377e23a2Schristos { BFD_RELOC_32, R_VAX_32 },
308377e23a2Schristos { BFD_RELOC_16, R_VAX_16 },
309377e23a2Schristos { BFD_RELOC_8, R_VAX_8 },
310377e23a2Schristos { BFD_RELOC_32_PCREL, R_VAX_PC32 },
311377e23a2Schristos { BFD_RELOC_16_PCREL, R_VAX_PC16 },
312377e23a2Schristos { BFD_RELOC_8_PCREL, R_VAX_PC8 },
313377e23a2Schristos { BFD_RELOC_32_GOT_PCREL, R_VAX_GOT32 },
314377e23a2Schristos { BFD_RELOC_32_PLT_PCREL, R_VAX_PLT32 },
315377e23a2Schristos { BFD_RELOC_NONE, R_VAX_COPY },
316377e23a2Schristos { BFD_RELOC_VAX_GLOB_DAT, R_VAX_GLOB_DAT },
317377e23a2Schristos { BFD_RELOC_VAX_JMP_SLOT, R_VAX_JMP_SLOT },
318377e23a2Schristos { BFD_RELOC_VAX_RELATIVE, R_VAX_RELATIVE },
319377e23a2Schristos { BFD_RELOC_CTOR, R_VAX_32 },
320377e23a2Schristos { BFD_RELOC_VTABLE_INHERIT, R_VAX_GNU_VTINHERIT },
321377e23a2Schristos { BFD_RELOC_VTABLE_ENTRY, R_VAX_GNU_VTENTRY },
322377e23a2Schristos };
323377e23a2Schristos
324377e23a2Schristos static reloc_howto_type *
reloc_type_lookup(bfd * abfd ATTRIBUTE_UNUSED,bfd_reloc_code_real_type code)325377e23a2Schristos reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
326377e23a2Schristos {
327377e23a2Schristos unsigned int i;
328377e23a2Schristos for (i = 0; i < sizeof (reloc_map) / sizeof (reloc_map[0]); i++)
329377e23a2Schristos {
330377e23a2Schristos if (reloc_map[i].bfd_val == code)
331377e23a2Schristos return &howto_table[reloc_map[i].elf_val];
332377e23a2Schristos }
333377e23a2Schristos return 0;
334377e23a2Schristos }
335377e23a2Schristos
336377e23a2Schristos static reloc_howto_type *
reloc_name_lookup(bfd * abfd ATTRIBUTE_UNUSED,const char * r_name)337377e23a2Schristos reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
338377e23a2Schristos const char *r_name)
339377e23a2Schristos {
340377e23a2Schristos unsigned int i;
341377e23a2Schristos
342377e23a2Schristos for (i = 0; i < sizeof (howto_table) / sizeof (howto_table[0]); i++)
343377e23a2Schristos if (howto_table[i].name != NULL
344377e23a2Schristos && strcasecmp (howto_table[i].name, r_name) == 0)
345377e23a2Schristos return &howto_table[i];
346377e23a2Schristos
347377e23a2Schristos return NULL;
348377e23a2Schristos }
349377e23a2Schristos
350377e23a2Schristos #define bfd_elf32_bfd_reloc_type_lookup reloc_type_lookup
351377e23a2Schristos #define bfd_elf32_bfd_reloc_name_lookup reloc_name_lookup
352377e23a2Schristos #define ELF_ARCH bfd_arch_vax
353377e23a2Schristos /* end code generated by elf.el */
354377e23a2Schristos
355377e23a2Schristos /* Functions for the VAX ELF linker. */
356377e23a2Schristos
357377e23a2Schristos /* The name of the dynamic interpreter. This is put in the .interp
358377e23a2Schristos section. */
359377e23a2Schristos
360377e23a2Schristos #define ELF_DYNAMIC_INTERPRETER "/usr/libexec/ld.elf_so"
361377e23a2Schristos
362377e23a2Schristos /* The size in bytes of an entry in the procedure linkage table. */
363377e23a2Schristos
364377e23a2Schristos #define PLT_ENTRY_SIZE 12
365377e23a2Schristos
366377e23a2Schristos /* The first entry in a procedure linkage table looks like this. See
367377e23a2Schristos the SVR4 ABI VAX supplement to see how this works. */
368377e23a2Schristos
369377e23a2Schristos static const bfd_byte elf_vax_plt0_entry[PLT_ENTRY_SIZE] =
370377e23a2Schristos {
371377e23a2Schristos 0xdd, 0xef, /* pushl l^ */
372377e23a2Schristos 0, 0, 0, 0, /* offset to .plt.got + 4 */
373377e23a2Schristos 0x17, 0xff, /* jmp @L^(pc) */
374377e23a2Schristos 0, 0, 0, 0, /* offset to .plt.got + 8 */
375377e23a2Schristos };
376377e23a2Schristos
377377e23a2Schristos /* Subsequent entries in a procedure linkage table look like this. */
378377e23a2Schristos
379377e23a2Schristos static const bfd_byte elf_vax_plt_entry[PLT_ENTRY_SIZE] =
380377e23a2Schristos {
381377e23a2Schristos 0xfc, 0x0f, /* .word ^M<r11:r2> */
382377e23a2Schristos 0x16, 0xef, /* jsb L^(pc) */
383377e23a2Schristos 0, 0, 0, 0, /* replaced with offset to start of .plt */
384377e23a2Schristos 0, 0, 0, 0, /* index into .rela.plt */
385377e23a2Schristos };
386377e23a2Schristos
387377e23a2Schristos /* The VAX linker needs to keep track of the number of relocs that it
388377e23a2Schristos decides to copy in check_relocs for each symbol. This is so that it
389377e23a2Schristos can discard PC relative relocs if it doesn't need them when linking
390377e23a2Schristos with -Bsymbolic. We store the information in a field extending the
391377e23a2Schristos regular ELF linker hash table. */
392377e23a2Schristos
393377e23a2Schristos /* This structure keeps track of the number of PC relative relocs we have
394377e23a2Schristos copied for a given symbol. */
395377e23a2Schristos
396377e23a2Schristos struct elf_vax_pcrel_relocs_copied
397377e23a2Schristos {
398377e23a2Schristos /* Next section. */
399377e23a2Schristos struct elf_vax_pcrel_relocs_copied *next;
400377e23a2Schristos /* A section in dynobj. */
401377e23a2Schristos asection *section;
402377e23a2Schristos /* Number of relocs copied in this section. */
403377e23a2Schristos bfd_size_type count;
404377e23a2Schristos };
405377e23a2Schristos
406377e23a2Schristos /* VAX ELF linker hash entry. */
407377e23a2Schristos
408377e23a2Schristos struct elf_vax_link_hash_entry
409377e23a2Schristos {
410377e23a2Schristos struct elf_link_hash_entry root;
411377e23a2Schristos
412377e23a2Schristos /* Number of PC relative relocs copied for this symbol. */
413377e23a2Schristos struct elf_vax_pcrel_relocs_copied *pcrel_relocs_copied;
414377e23a2Schristos
415377e23a2Schristos bfd_vma got_addend;
416377e23a2Schristos };
417377e23a2Schristos
418377e23a2Schristos /* Declare this now that the above structures are defined. */
419377e23a2Schristos
420377e23a2Schristos static bfd_boolean elf_vax_discard_copies (struct elf_vax_link_hash_entry *,
421377e23a2Schristos void *);
422377e23a2Schristos
423377e23a2Schristos /* Declare this now that the above structures are defined. */
424377e23a2Schristos
425377e23a2Schristos static bfd_boolean elf_vax_instantiate_got_entries (struct elf_link_hash_entry *,
426377e23a2Schristos void *);
427377e23a2Schristos
428377e23a2Schristos /* Traverse an VAX ELF linker hash table. */
429377e23a2Schristos
430377e23a2Schristos #define elf_vax_link_hash_traverse(table, func, info) \
431377e23a2Schristos (elf_link_hash_traverse \
432377e23a2Schristos ((table), \
43348596154Schristos (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \
434377e23a2Schristos (info)))
435377e23a2Schristos
436377e23a2Schristos /* Create an entry in an VAX ELF linker hash table. */
437377e23a2Schristos
438377e23a2Schristos static struct bfd_hash_entry *
elf_vax_link_hash_newfunc(struct bfd_hash_entry * entry,struct bfd_hash_table * table,const char * string)439377e23a2Schristos elf_vax_link_hash_newfunc (struct bfd_hash_entry *entry,
440377e23a2Schristos struct bfd_hash_table *table,
441377e23a2Schristos const char *string)
442377e23a2Schristos {
443377e23a2Schristos struct elf_vax_link_hash_entry *ret =
444377e23a2Schristos (struct elf_vax_link_hash_entry *) entry;
445377e23a2Schristos
446377e23a2Schristos /* Allocate the structure if it has not already been allocated by a
447377e23a2Schristos subclass. */
448377e23a2Schristos if (ret == NULL)
449377e23a2Schristos ret = ((struct elf_vax_link_hash_entry *)
450377e23a2Schristos bfd_hash_allocate (table,
451377e23a2Schristos sizeof (struct elf_vax_link_hash_entry)));
452377e23a2Schristos if (ret == NULL)
453377e23a2Schristos return (struct bfd_hash_entry *) ret;
454377e23a2Schristos
455377e23a2Schristos /* Call the allocation method of the superclass. */
456377e23a2Schristos ret = ((struct elf_vax_link_hash_entry *)
457377e23a2Schristos _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
458377e23a2Schristos table, string));
459377e23a2Schristos if (ret != NULL)
460377e23a2Schristos {
461377e23a2Schristos ret->pcrel_relocs_copied = NULL;
462377e23a2Schristos }
463377e23a2Schristos
464377e23a2Schristos return (struct bfd_hash_entry *) ret;
465377e23a2Schristos }
466377e23a2Schristos
467377e23a2Schristos /* Create an VAX ELF linker hash table. */
468377e23a2Schristos
469377e23a2Schristos static struct bfd_link_hash_table *
elf_vax_link_hash_table_create(bfd * abfd)470377e23a2Schristos elf_vax_link_hash_table_create (bfd *abfd)
471377e23a2Schristos {
472377e23a2Schristos struct elf_link_hash_table *ret;
473*1424dfb3Schristos size_t amt = sizeof (struct elf_link_hash_table);
474377e23a2Schristos
47548596154Schristos ret = bfd_zmalloc (amt);
476377e23a2Schristos if (ret == NULL)
477377e23a2Schristos return NULL;
478377e23a2Schristos
479377e23a2Schristos if (!_bfd_elf_link_hash_table_init (ret, abfd,
480377e23a2Schristos elf_vax_link_hash_newfunc,
481377e23a2Schristos sizeof (struct elf_vax_link_hash_entry),
482377e23a2Schristos GENERIC_ELF_DATA))
483377e23a2Schristos {
484377e23a2Schristos free (ret);
485377e23a2Schristos return NULL;
486377e23a2Schristos }
487377e23a2Schristos
488377e23a2Schristos return &ret->root;
489377e23a2Schristos }
490377e23a2Schristos
491377e23a2Schristos /* Keep vax-specific flags in the ELF header */
492377e23a2Schristos static bfd_boolean
elf32_vax_set_private_flags(bfd * abfd,flagword flags)493377e23a2Schristos elf32_vax_set_private_flags (bfd *abfd, flagword flags)
494377e23a2Schristos {
495377e23a2Schristos elf_elfheader (abfd)->e_flags = flags;
496377e23a2Schristos elf_flags_init (abfd) = TRUE;
497377e23a2Schristos return TRUE;
498377e23a2Schristos }
499377e23a2Schristos
500377e23a2Schristos /* Merge backend specific data from an object file to the output
501377e23a2Schristos object file when linking. */
502377e23a2Schristos static bfd_boolean
elf32_vax_merge_private_bfd_data(bfd * ibfd,struct bfd_link_info * info)5031c468f90Schristos elf32_vax_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
504377e23a2Schristos {
5051c468f90Schristos bfd *obfd = info->output_bfd;
506377e23a2Schristos flagword in_flags;
507377e23a2Schristos
508377e23a2Schristos if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
509377e23a2Schristos || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
510377e23a2Schristos return TRUE;
511377e23a2Schristos
512377e23a2Schristos in_flags = elf_elfheader (ibfd)->e_flags;
513377e23a2Schristos
514377e23a2Schristos if (!elf_flags_init (obfd))
515377e23a2Schristos {
516377e23a2Schristos elf_flags_init (obfd) = TRUE;
517377e23a2Schristos elf_elfheader (obfd)->e_flags = in_flags;
518377e23a2Schristos }
519377e23a2Schristos
520377e23a2Schristos return TRUE;
521377e23a2Schristos }
522377e23a2Schristos
523377e23a2Schristos /* Display the flags field */
524377e23a2Schristos static bfd_boolean
elf32_vax_print_private_bfd_data(bfd * abfd,void * ptr)52548596154Schristos elf32_vax_print_private_bfd_data (bfd *abfd, void * ptr)
526377e23a2Schristos {
527377e23a2Schristos FILE *file = (FILE *) ptr;
528377e23a2Schristos
529377e23a2Schristos BFD_ASSERT (abfd != NULL && ptr != NULL);
530377e23a2Schristos
531377e23a2Schristos /* Print normal ELF private data. */
532377e23a2Schristos _bfd_elf_print_private_bfd_data (abfd, ptr);
533377e23a2Schristos
534377e23a2Schristos /* Ignore init flag - it may not be set, despite the flags field containing valid data. */
535377e23a2Schristos
536377e23a2Schristos /* xgettext:c-format */
537377e23a2Schristos fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
538377e23a2Schristos
539377e23a2Schristos if (elf_elfheader (abfd)->e_flags & EF_VAX_NONPIC)
540377e23a2Schristos fprintf (file, _(" [nonpic]"));
541377e23a2Schristos
542377e23a2Schristos if (elf_elfheader (abfd)->e_flags & EF_VAX_DFLOAT)
543377e23a2Schristos fprintf (file, _(" [d-float]"));
544377e23a2Schristos
545377e23a2Schristos if (elf_elfheader (abfd)->e_flags & EF_VAX_GFLOAT)
546377e23a2Schristos fprintf (file, _(" [g-float]"));
547377e23a2Schristos
548377e23a2Schristos fputc ('\n', file);
549377e23a2Schristos
550377e23a2Schristos return TRUE;
551377e23a2Schristos }
552377e23a2Schristos /* Look through the relocs for a section during the first phase, and
553377e23a2Schristos allocate space in the global offset table or procedure linkage
554377e23a2Schristos table. */
555377e23a2Schristos
556377e23a2Schristos static bfd_boolean
elf_vax_check_relocs(bfd * abfd,struct bfd_link_info * info,asection * sec,const Elf_Internal_Rela * relocs)557377e23a2Schristos elf_vax_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec,
558377e23a2Schristos const Elf_Internal_Rela *relocs)
559377e23a2Schristos {
560377e23a2Schristos bfd *dynobj;
561377e23a2Schristos Elf_Internal_Shdr *symtab_hdr;
562377e23a2Schristos struct elf_link_hash_entry **sym_hashes;
563377e23a2Schristos const Elf_Internal_Rela *rel;
564377e23a2Schristos const Elf_Internal_Rela *rel_end;
565377e23a2Schristos asection *sreloc;
566377e23a2Schristos
567c03b94e9Schristos if (bfd_link_relocatable (info))
568377e23a2Schristos return TRUE;
569377e23a2Schristos
570377e23a2Schristos dynobj = elf_hash_table (info)->dynobj;
571377e23a2Schristos symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
572377e23a2Schristos sym_hashes = elf_sym_hashes (abfd);
573377e23a2Schristos
574377e23a2Schristos sreloc = NULL;
575377e23a2Schristos
576377e23a2Schristos rel_end = relocs + sec->reloc_count;
577377e23a2Schristos for (rel = relocs; rel < rel_end; rel++)
578377e23a2Schristos {
579377e23a2Schristos unsigned long r_symndx;
580377e23a2Schristos struct elf_link_hash_entry *h;
581377e23a2Schristos
582377e23a2Schristos r_symndx = ELF32_R_SYM (rel->r_info);
583377e23a2Schristos
584377e23a2Schristos if (r_symndx < symtab_hdr->sh_info)
585377e23a2Schristos h = NULL;
586377e23a2Schristos else
587377e23a2Schristos {
588377e23a2Schristos h = sym_hashes[r_symndx - symtab_hdr->sh_info];
589377e23a2Schristos while (h->root.type == bfd_link_hash_indirect
590377e23a2Schristos || h->root.type == bfd_link_hash_warning)
591377e23a2Schristos h = (struct elf_link_hash_entry *) h->root.u.i.link;
592377e23a2Schristos }
593377e23a2Schristos
594377e23a2Schristos switch (ELF32_R_TYPE (rel->r_info))
595377e23a2Schristos {
596377e23a2Schristos case R_VAX_GOT32:
597377e23a2Schristos BFD_ASSERT (h != NULL);
598377e23a2Schristos
599377e23a2Schristos /* If this is a local symbol, we resolve it directly without
600377e23a2Schristos creating a global offset table entry. */
6017af5a897Schristos if (h->forced_local
6027af5a897Schristos || h == elf_hash_table (info)->hgot
6037af5a897Schristos || h == elf_hash_table (info)->hplt)
604377e23a2Schristos break;
605377e23a2Schristos
606377e23a2Schristos /* This symbol requires a global offset table entry. */
607377e23a2Schristos
608377e23a2Schristos if (dynobj == NULL)
609377e23a2Schristos {
610377e23a2Schristos /* Create the .got section. */
611377e23a2Schristos elf_hash_table (info)->dynobj = dynobj = abfd;
612377e23a2Schristos if (!_bfd_elf_create_got_section (dynobj, info))
613377e23a2Schristos return FALSE;
614377e23a2Schristos }
615377e23a2Schristos
616377e23a2Schristos if (h != NULL)
617377e23a2Schristos {
618377e23a2Schristos struct elf_vax_link_hash_entry *eh;
619377e23a2Schristos
620377e23a2Schristos eh = (struct elf_vax_link_hash_entry *) h;
621377e23a2Schristos if (h->got.refcount == -1)
622377e23a2Schristos {
623377e23a2Schristos h->got.refcount = 1;
624377e23a2Schristos eh->got_addend = rel->r_addend;
625377e23a2Schristos }
626377e23a2Schristos else
627377e23a2Schristos {
628377e23a2Schristos h->got.refcount++;
629377e23a2Schristos if (eh->got_addend != (bfd_vma) rel->r_addend)
6301c468f90Schristos _bfd_error_handler
6311c468f90Schristos /* xgettext:c-format */
63207163879Schristos (_("%pB: warning: GOT addend of %" PRId64 " to `%s' does"
63307163879Schristos " not match previous GOT addend of %" PRId64),
63407163879Schristos abfd, (int64_t) rel->r_addend, h->root.root.string,
63507163879Schristos (int64_t) eh->got_addend);
636377e23a2Schristos
637377e23a2Schristos }
638377e23a2Schristos }
639377e23a2Schristos break;
640377e23a2Schristos
641377e23a2Schristos case R_VAX_PLT32:
642377e23a2Schristos /* This symbol requires a procedure linkage table entry. We
643377e23a2Schristos actually build the entry in adjust_dynamic_symbol,
644377e23a2Schristos because this might be a case of linking PIC code which is
645377e23a2Schristos never referenced by a dynamic object, in which case we
646377e23a2Schristos don't need to generate a procedure linkage table entry
647377e23a2Schristos after all. */
6487af5a897Schristos BFD_ASSERT (h != NULL);
649377e23a2Schristos
650377e23a2Schristos /* If this is a local symbol, we resolve it directly without
651377e23a2Schristos creating a procedure linkage table entry. */
6527af5a897Schristos if (h->forced_local)
653377e23a2Schristos break;
654377e23a2Schristos
655377e23a2Schristos h->needs_plt = 1;
656377e23a2Schristos if (h->plt.refcount == -1)
657377e23a2Schristos h->plt.refcount = 1;
658377e23a2Schristos else
659377e23a2Schristos h->plt.refcount++;
660377e23a2Schristos break;
661377e23a2Schristos
662377e23a2Schristos case R_VAX_PC8:
663377e23a2Schristos case R_VAX_PC16:
664377e23a2Schristos case R_VAX_PC32:
665377e23a2Schristos /* If we are creating a shared library and this is not a local
666377e23a2Schristos symbol, we need to copy the reloc into the shared library.
667377e23a2Schristos However when linking with -Bsymbolic and this is a global
668377e23a2Schristos symbol which is defined in an object we are including in the
669377e23a2Schristos link (i.e., DEF_REGULAR is set), then we can resolve the
670377e23a2Schristos reloc directly. At this point we have not seen all the input
671377e23a2Schristos files, so it is possible that DEF_REGULAR is not set now but
672377e23a2Schristos will be set later (it is never cleared). We account for that
673377e23a2Schristos possibility below by storing information in the
674377e23a2Schristos pcrel_relocs_copied field of the hash table entry. */
675c03b94e9Schristos if (!(bfd_link_pic (info)
676377e23a2Schristos && (sec->flags & SEC_ALLOC) != 0
677377e23a2Schristos && h != NULL
678377e23a2Schristos && (!info->symbolic
679377e23a2Schristos || !h->def_regular)))
680377e23a2Schristos {
681377e23a2Schristos if (h != NULL
682377e23a2Schristos && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
683377e23a2Schristos && !h->forced_local)
684377e23a2Schristos {
685377e23a2Schristos /* Make sure a plt entry is created for this symbol if
686377e23a2Schristos it turns out to be a function defined by a dynamic
687377e23a2Schristos object. */
688377e23a2Schristos if (h->plt.refcount == -1)
689377e23a2Schristos h->plt.refcount = 1;
690377e23a2Schristos else
691377e23a2Schristos h->plt.refcount++;
692377e23a2Schristos }
693377e23a2Schristos break;
694377e23a2Schristos }
695377e23a2Schristos /* If this is a local symbol, we can resolve it directly. */
696377e23a2Schristos if (h != NULL
697377e23a2Schristos && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
698377e23a2Schristos || h->forced_local))
699377e23a2Schristos break;
700377e23a2Schristos
701377e23a2Schristos /* Fall through. */
702377e23a2Schristos case R_VAX_8:
703377e23a2Schristos case R_VAX_16:
704377e23a2Schristos case R_VAX_32:
705377e23a2Schristos if (h != NULL && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
706377e23a2Schristos {
707377e23a2Schristos /* Make sure a plt entry is created for this symbol if it
708377e23a2Schristos turns out to be a function defined by a dynamic object. */
709377e23a2Schristos if (h->plt.refcount == -1)
710377e23a2Schristos h->plt.refcount = 1;
711377e23a2Schristos else
712377e23a2Schristos h->plt.refcount++;
713377e23a2Schristos }
714377e23a2Schristos
715*1424dfb3Schristos /* Non-GOT reference may need a copy reloc in executable or
716*1424dfb3Schristos a dynamic reloc in shared library. */
717*1424dfb3Schristos if (h != NULL)
718*1424dfb3Schristos h->non_got_ref = 1;
719*1424dfb3Schristos
720377e23a2Schristos /* If we are creating a shared library, we need to copy the
721377e23a2Schristos reloc into the shared library. */
722c03b94e9Schristos if (bfd_link_pic (info)
723377e23a2Schristos && (sec->flags & SEC_ALLOC) != 0)
724377e23a2Schristos {
725377e23a2Schristos /* When creating a shared object, we must copy these
726377e23a2Schristos reloc types into the output file. We create a reloc
727377e23a2Schristos section in dynobj and make room for this reloc. */
728377e23a2Schristos if (sreloc == NULL)
729377e23a2Schristos {
730377e23a2Schristos sreloc = _bfd_elf_make_dynamic_reloc_section
731377e23a2Schristos (sec, dynobj, 2, abfd, /*rela?*/ TRUE);
732377e23a2Schristos
733377e23a2Schristos if (sreloc == NULL)
734377e23a2Schristos return FALSE;
735377e23a2Schristos
736377e23a2Schristos if (sec->flags & SEC_READONLY)
737377e23a2Schristos info->flags |= DF_TEXTREL;
738377e23a2Schristos }
739377e23a2Schristos
740377e23a2Schristos sreloc->size += sizeof (Elf32_External_Rela);
741377e23a2Schristos
742377e23a2Schristos /* If we are linking with -Bsymbolic, we count the number of
743377e23a2Schristos PC relative relocations we have entered for this symbol,
744377e23a2Schristos so that we can discard them again if the symbol is later
745377e23a2Schristos defined by a regular object. Note that this function is
746377e23a2Schristos only called if we are using a vaxelf linker hash table,
747377e23a2Schristos which means that h is really a pointer to an
748377e23a2Schristos elf_vax_link_hash_entry. */
749377e23a2Schristos if ((ELF32_R_TYPE (rel->r_info) == R_VAX_PC8
750377e23a2Schristos || ELF32_R_TYPE (rel->r_info) == R_VAX_PC16
751377e23a2Schristos || ELF32_R_TYPE (rel->r_info) == R_VAX_PC32)
752377e23a2Schristos && info->symbolic)
753377e23a2Schristos {
754377e23a2Schristos struct elf_vax_link_hash_entry *eh;
755377e23a2Schristos struct elf_vax_pcrel_relocs_copied *p;
756377e23a2Schristos
757377e23a2Schristos eh = (struct elf_vax_link_hash_entry *) h;
758377e23a2Schristos
759377e23a2Schristos for (p = eh->pcrel_relocs_copied; p != NULL; p = p->next)
760377e23a2Schristos if (p->section == sreloc)
761377e23a2Schristos break;
762377e23a2Schristos
763377e23a2Schristos if (p == NULL)
764377e23a2Schristos {
765377e23a2Schristos p = ((struct elf_vax_pcrel_relocs_copied *)
766377e23a2Schristos bfd_alloc (dynobj, (bfd_size_type) sizeof *p));
767377e23a2Schristos if (p == NULL)
768377e23a2Schristos return FALSE;
769377e23a2Schristos p->next = eh->pcrel_relocs_copied;
770377e23a2Schristos eh->pcrel_relocs_copied = p;
771377e23a2Schristos p->section = sreloc;
772377e23a2Schristos p->count = 0;
773377e23a2Schristos }
774377e23a2Schristos
775377e23a2Schristos ++p->count;
776377e23a2Schristos }
777377e23a2Schristos }
778377e23a2Schristos
779377e23a2Schristos break;
780377e23a2Schristos
781377e23a2Schristos /* This relocation describes the C++ object vtable hierarchy.
782377e23a2Schristos Reconstruct it for later use during GC. */
783377e23a2Schristos case R_VAX_GNU_VTINHERIT:
784377e23a2Schristos if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
785377e23a2Schristos return FALSE;
786377e23a2Schristos break;
787377e23a2Schristos
788377e23a2Schristos /* This relocation describes which C++ vtable entries are actually
789377e23a2Schristos used. Record for later use during GC. */
790377e23a2Schristos case R_VAX_GNU_VTENTRY:
791*1424dfb3Schristos if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
792377e23a2Schristos return FALSE;
793377e23a2Schristos break;
794377e23a2Schristos
795377e23a2Schristos default:
796377e23a2Schristos break;
797377e23a2Schristos }
798377e23a2Schristos }
799377e23a2Schristos
800377e23a2Schristos return TRUE;
801377e23a2Schristos }
802377e23a2Schristos
803377e23a2Schristos /* Return the section that should be marked against GC for a given
804377e23a2Schristos relocation. */
805377e23a2Schristos
806377e23a2Schristos static asection *
elf_vax_gc_mark_hook(asection * sec,struct bfd_link_info * info,Elf_Internal_Rela * rel,struct elf_link_hash_entry * h,Elf_Internal_Sym * sym)807377e23a2Schristos elf_vax_gc_mark_hook (asection *sec,
808377e23a2Schristos struct bfd_link_info *info,
809377e23a2Schristos Elf_Internal_Rela *rel,
810377e23a2Schristos struct elf_link_hash_entry *h,
811377e23a2Schristos Elf_Internal_Sym *sym)
812377e23a2Schristos {
813377e23a2Schristos if (h != NULL)
814377e23a2Schristos switch (ELF32_R_TYPE (rel->r_info))
815377e23a2Schristos {
816377e23a2Schristos case R_VAX_GNU_VTINHERIT:
817377e23a2Schristos case R_VAX_GNU_VTENTRY:
818377e23a2Schristos return NULL;
819377e23a2Schristos }
820377e23a2Schristos
821377e23a2Schristos return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
822377e23a2Schristos }
823377e23a2Schristos
824377e23a2Schristos /* Adjust a symbol defined by a dynamic object and referenced by a
825377e23a2Schristos regular object. The current definition is in some section of the
826377e23a2Schristos dynamic object, but we're not including those sections. We have to
827377e23a2Schristos change the definition to something the rest of the link can
828377e23a2Schristos understand. */
829377e23a2Schristos
830377e23a2Schristos static bfd_boolean
elf_vax_adjust_dynamic_symbol(struct bfd_link_info * info,struct elf_link_hash_entry * h)8317af5a897Schristos elf_vax_adjust_dynamic_symbol (struct bfd_link_info *info,
8327af5a897Schristos struct elf_link_hash_entry *h)
833377e23a2Schristos {
834377e23a2Schristos bfd *dynobj;
835377e23a2Schristos asection *s;
836377e23a2Schristos
837377e23a2Schristos dynobj = elf_hash_table (info)->dynobj;
838377e23a2Schristos
839377e23a2Schristos /* Make sure we know what is going on here. */
840377e23a2Schristos BFD_ASSERT (dynobj != NULL
841377e23a2Schristos && (h->needs_plt
84207163879Schristos || h->is_weakalias
843377e23a2Schristos || (h->def_dynamic
844377e23a2Schristos && h->ref_regular
845377e23a2Schristos && !h->def_regular)));
846377e23a2Schristos
847377e23a2Schristos /* If this is a function, put it in the procedure linkage table. We
848377e23a2Schristos will fill in the contents of the procedure linkage table later,
849377e23a2Schristos when we know the address of the .got section. */
850377e23a2Schristos if (h->type == STT_FUNC
851377e23a2Schristos || h->needs_plt)
852377e23a2Schristos {
85348596154Schristos if (h->plt.refcount <= 0
85448596154Schristos || SYMBOL_CALLS_LOCAL (info, h)
85548596154Schristos || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
85648596154Schristos && h->root.type == bfd_link_hash_undefweak))
857377e23a2Schristos {
858377e23a2Schristos /* This case can occur if we saw a PLTxx reloc in an input
859377e23a2Schristos file, but the symbol was never referred to by a dynamic
86048596154Schristos object, or if all references were garbage collected. In
86148596154Schristos such a case, we don't actually need to build a procedure
86248596154Schristos linkage table, and we can just do a PCxx reloc instead. */
863377e23a2Schristos h->plt.offset = (bfd_vma) -1;
864377e23a2Schristos h->needs_plt = 0;
865377e23a2Schristos return TRUE;
866377e23a2Schristos }
867377e23a2Schristos
8681c468f90Schristos s = elf_hash_table (info)->splt;
869377e23a2Schristos BFD_ASSERT (s != NULL);
870377e23a2Schristos
871377e23a2Schristos /* If this is the first .plt entry, make room for the special
872377e23a2Schristos first entry. */
873377e23a2Schristos if (s->size == 0)
874377e23a2Schristos {
875377e23a2Schristos s->size += PLT_ENTRY_SIZE;
876377e23a2Schristos }
877377e23a2Schristos
878377e23a2Schristos /* If this symbol is not defined in a regular file, and we are
879377e23a2Schristos not generating a shared library, then set the symbol to this
880377e23a2Schristos location in the .plt. This is required to make function
881377e23a2Schristos pointers compare as equal between the normal executable and
882377e23a2Schristos the shared library. */
883c03b94e9Schristos if (!bfd_link_pic (info)
884377e23a2Schristos && !h->def_regular)
885377e23a2Schristos {
886377e23a2Schristos h->root.u.def.section = s;
887377e23a2Schristos h->root.u.def.value = s->size;
888377e23a2Schristos }
889377e23a2Schristos
890377e23a2Schristos h->plt.offset = s->size;
891377e23a2Schristos
892377e23a2Schristos /* Make room for this entry. */
893377e23a2Schristos s->size += PLT_ENTRY_SIZE;
894377e23a2Schristos
895377e23a2Schristos /* We also need to make an entry in the .got.plt section, which
896377e23a2Schristos will be placed in the .got section by the linker script. */
897377e23a2Schristos
8981c468f90Schristos s = elf_hash_table (info)->sgotplt;
899377e23a2Schristos BFD_ASSERT (s != NULL);
900377e23a2Schristos s->size += 4;
901377e23a2Schristos
902377e23a2Schristos /* We also need to make an entry in the .rela.plt section. */
903377e23a2Schristos
9041c468f90Schristos s = elf_hash_table (info)->srelplt;
905377e23a2Schristos BFD_ASSERT (s != NULL);
906377e23a2Schristos s->size += sizeof (Elf32_External_Rela);
907377e23a2Schristos
908377e23a2Schristos return TRUE;
909377e23a2Schristos }
910377e23a2Schristos
911377e23a2Schristos /* Reinitialize the plt offset now that it is not used as a reference
912377e23a2Schristos count any more. */
913377e23a2Schristos h->plt.offset = (bfd_vma) -1;
914377e23a2Schristos
915377e23a2Schristos /* If this is a weak symbol, and there is a real definition, the
916377e23a2Schristos processor independent code will have arranged for us to see the
917377e23a2Schristos real definition first, and we can just use the same value. */
91807163879Schristos if (h->is_weakalias)
919377e23a2Schristos {
92007163879Schristos struct elf_link_hash_entry *def = weakdef (h);
92107163879Schristos BFD_ASSERT (def->root.type == bfd_link_hash_defined);
92207163879Schristos h->root.u.def.section = def->root.u.def.section;
92307163879Schristos h->root.u.def.value = def->root.u.def.value;
924377e23a2Schristos return TRUE;
925377e23a2Schristos }
926377e23a2Schristos
927377e23a2Schristos /* This is a reference to a symbol defined by a dynamic object which
928377e23a2Schristos is not a function. */
929377e23a2Schristos
930377e23a2Schristos /* If we are creating a shared library, we must presume that the
931377e23a2Schristos only references to the symbol are via the global offset table.
932377e23a2Schristos For such cases we need not do anything here; the relocations will
933377e23a2Schristos be handled correctly by relocate_section. */
934c03b94e9Schristos if (bfd_link_pic (info))
935377e23a2Schristos return TRUE;
936377e23a2Schristos
937*1424dfb3Schristos /* If there are no references to this symbol that do not use the
938*1424dfb3Schristos GOT relocation, we don't need to generate a copy reloc. */
939*1424dfb3Schristos if (!h->non_got_ref)
940*1424dfb3Schristos return TRUE;
941*1424dfb3Schristos
942377e23a2Schristos /* We must allocate the symbol in our .dynbss section, which will
943377e23a2Schristos become part of the .bss section of the executable. There will be
944377e23a2Schristos an entry for this symbol in the .dynsym section. The dynamic
945377e23a2Schristos object will contain position independent code, so all references
946377e23a2Schristos from the dynamic object to this symbol will go through the global
947377e23a2Schristos offset table. The dynamic linker will use the .dynsym entry to
948377e23a2Schristos determine the address it must put in the global offset table, so
949377e23a2Schristos both the dynamic object and the regular object will refer to the
950377e23a2Schristos same memory location for the variable. */
951377e23a2Schristos
95248596154Schristos s = bfd_get_linker_section (dynobj, ".dynbss");
953377e23a2Schristos BFD_ASSERT (s != NULL);
954377e23a2Schristos
955377e23a2Schristos /* We must generate a R_VAX_COPY reloc to tell the dynamic linker to
956377e23a2Schristos copy the initial value out of the dynamic object and into the
957377e23a2Schristos runtime process image. We need to remember the offset into the
958377e23a2Schristos .rela.bss section we are going to use. */
95948596154Schristos if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
960377e23a2Schristos {
961377e23a2Schristos asection *srel;
962377e23a2Schristos
96348596154Schristos srel = bfd_get_linker_section (dynobj, ".rela.bss");
964377e23a2Schristos BFD_ASSERT (srel != NULL);
965377e23a2Schristos srel->size += sizeof (Elf32_External_Rela);
966377e23a2Schristos h->needs_copy = 1;
967377e23a2Schristos }
968377e23a2Schristos
9695e098073Schristos return _bfd_elf_adjust_dynamic_copy (info, h, s);
970377e23a2Schristos }
971377e23a2Schristos
9727af5a897Schristos /* This function is called via elf_link_hash_traverse. It resets GOT
9737af5a897Schristos and PLT (.GOT) reference counts back to -1 so normal PC32 relocation
9747af5a897Schristos will be done. */
9757af5a897Schristos
9767af5a897Schristos static bfd_boolean
elf_vax_discard_got_entries(struct elf_link_hash_entry * h,void * infoptr ATTRIBUTE_UNUSED)9777af5a897Schristos elf_vax_discard_got_entries (struct elf_link_hash_entry *h,
9787af5a897Schristos void *infoptr ATTRIBUTE_UNUSED)
9797af5a897Schristos {
9807af5a897Schristos h->got.refcount = -1;
9817af5a897Schristos h->plt.refcount = -1;
9827af5a897Schristos
9837af5a897Schristos return TRUE;
9847af5a897Schristos }
9857af5a897Schristos
9867af5a897Schristos /* Discard unused dynamic data if this is a static link. */
9877af5a897Schristos
9887af5a897Schristos static bfd_boolean
elf_vax_always_size_sections(bfd * output_bfd ATTRIBUTE_UNUSED,struct bfd_link_info * info)9897af5a897Schristos elf_vax_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
9907af5a897Schristos struct bfd_link_info *info)
9917af5a897Schristos {
9927af5a897Schristos bfd *dynobj;
9937af5a897Schristos asection *s;
9947af5a897Schristos
9957af5a897Schristos dynobj = elf_hash_table (info)->dynobj;
9967af5a897Schristos
9977af5a897Schristos if (dynobj && !elf_hash_table (info)->dynamic_sections_created)
9987af5a897Schristos {
9997af5a897Schristos /* We may have created entries in the .rela.got and .got sections.
10007af5a897Schristos However, if we are not creating the dynamic sections, we will
10017af5a897Schristos not actually use these entries. Reset the size of .rela.got
10027af5a897Schristos and .got, which will cause them to get stripped from the output
10037af5a897Schristos file below. */
10041c468f90Schristos s = elf_hash_table (info)->srelgot;
10057af5a897Schristos if (s != NULL)
10067af5a897Schristos s->size = 0;
10071c468f90Schristos s = elf_hash_table (info)->sgotplt;
10087af5a897Schristos if (s != NULL)
10097af5a897Schristos s->size = 0;
10101c468f90Schristos s = elf_hash_table (info)->sgot;
10117af5a897Schristos if (s != NULL)
10127af5a897Schristos s->size = 0;
10137af5a897Schristos }
10147af5a897Schristos
10157af5a897Schristos /* If this is a static link, we need to discard all the got entries we've
10167af5a897Schristos recorded. */
10177af5a897Schristos if (!dynobj || !elf_hash_table (info)->dynamic_sections_created)
10187af5a897Schristos elf_link_hash_traverse (elf_hash_table (info),
10197af5a897Schristos elf_vax_discard_got_entries,
10207af5a897Schristos info);
10217af5a897Schristos
10227af5a897Schristos return TRUE;
10237af5a897Schristos }
10247af5a897Schristos
1025377e23a2Schristos /* Set the sizes of the dynamic sections. */
1026377e23a2Schristos
1027377e23a2Schristos static bfd_boolean
elf_vax_size_dynamic_sections(bfd * output_bfd,struct bfd_link_info * info)1028377e23a2Schristos elf_vax_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
1029377e23a2Schristos {
1030377e23a2Schristos bfd *dynobj;
1031377e23a2Schristos asection *s;
1032377e23a2Schristos bfd_boolean relocs;
1033377e23a2Schristos
1034377e23a2Schristos dynobj = elf_hash_table (info)->dynobj;
1035377e23a2Schristos BFD_ASSERT (dynobj != NULL);
1036377e23a2Schristos
1037377e23a2Schristos if (elf_hash_table (info)->dynamic_sections_created)
1038377e23a2Schristos {
1039377e23a2Schristos /* Set the contents of the .interp section to the interpreter. */
1040c03b94e9Schristos if (bfd_link_executable (info) && !info->nointerp)
1041377e23a2Schristos {
104248596154Schristos s = bfd_get_linker_section (dynobj, ".interp");
1043377e23a2Schristos BFD_ASSERT (s != NULL);
1044377e23a2Schristos s->size = sizeof ELF_DYNAMIC_INTERPRETER;
1045377e23a2Schristos s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
1046377e23a2Schristos }
1047377e23a2Schristos }
1048377e23a2Schristos
1049377e23a2Schristos /* If this is a -Bsymbolic shared link, then we need to discard all PC
1050377e23a2Schristos relative relocs against symbols defined in a regular object. We
1051377e23a2Schristos allocated space for them in the check_relocs routine, but we will not
1052377e23a2Schristos fill them in in the relocate_section routine. */
1053c03b94e9Schristos if (bfd_link_pic (info) && info->symbolic)
1054377e23a2Schristos elf_vax_link_hash_traverse (elf_hash_table (info),
1055377e23a2Schristos elf_vax_discard_copies,
1056377e23a2Schristos NULL);
1057377e23a2Schristos
10587af5a897Schristos /* If this is a -Bsymbolic shared link, we need to discard all the got
10597af5a897Schristos entries we've recorded. Otherwise, we need to instantiate (allocate
10607af5a897Schristos space for them). */
1061377e23a2Schristos elf_link_hash_traverse (elf_hash_table (info),
1062377e23a2Schristos elf_vax_instantiate_got_entries,
106348596154Schristos info);
1064377e23a2Schristos
1065377e23a2Schristos /* The check_relocs and adjust_dynamic_symbol entry points have
1066377e23a2Schristos determined the sizes of the various dynamic sections. Allocate
1067377e23a2Schristos memory for them. */
1068377e23a2Schristos relocs = FALSE;
1069377e23a2Schristos for (s = dynobj->sections; s != NULL; s = s->next)
1070377e23a2Schristos {
1071377e23a2Schristos const char *name;
1072377e23a2Schristos
1073377e23a2Schristos if ((s->flags & SEC_LINKER_CREATED) == 0)
1074377e23a2Schristos continue;
1075377e23a2Schristos
1076377e23a2Schristos /* It's OK to base decisions on the section name, because none
1077377e23a2Schristos of the dynobj section names depend upon the input files. */
1078*1424dfb3Schristos name = bfd_section_name (s);
1079377e23a2Schristos
1080377e23a2Schristos if (strcmp (name, ".plt") == 0)
1081377e23a2Schristos {
1082377e23a2Schristos /* Remember whether there is a PLT. */
1083*1424dfb3Schristos ;
1084377e23a2Schristos }
1085377e23a2Schristos else if (CONST_STRNEQ (name, ".rela"))
1086377e23a2Schristos {
1087377e23a2Schristos if (s->size != 0)
1088377e23a2Schristos {
1089377e23a2Schristos if (strcmp (name, ".rela.plt") != 0)
1090377e23a2Schristos relocs = TRUE;
1091377e23a2Schristos
1092377e23a2Schristos /* We use the reloc_count field as a counter if we need
1093377e23a2Schristos to copy relocs into the output file. */
1094377e23a2Schristos s->reloc_count = 0;
1095377e23a2Schristos }
1096377e23a2Schristos }
1097377e23a2Schristos else if (! CONST_STRNEQ (name, ".got")
1098377e23a2Schristos && strcmp (name, ".dynbss") != 0)
1099377e23a2Schristos {
1100377e23a2Schristos /* It's not one of our sections, so don't allocate space. */
1101377e23a2Schristos continue;
1102377e23a2Schristos }
1103377e23a2Schristos
1104377e23a2Schristos if (s->size == 0)
1105377e23a2Schristos {
1106377e23a2Schristos /* If we don't need this section, strip it from the
1107377e23a2Schristos output file. This is mostly to handle .rela.bss and
1108377e23a2Schristos .rela.plt. We must create both sections in
1109377e23a2Schristos create_dynamic_sections, because they must be created
1110377e23a2Schristos before the linker maps input sections to output
1111377e23a2Schristos sections. The linker does that before
1112377e23a2Schristos adjust_dynamic_symbol is called, and it is that
1113377e23a2Schristos function which decides whether anything needs to go
1114377e23a2Schristos into these sections. */
1115377e23a2Schristos s->flags |= SEC_EXCLUDE;
1116377e23a2Schristos continue;
1117377e23a2Schristos }
1118377e23a2Schristos
1119377e23a2Schristos if ((s->flags & SEC_HAS_CONTENTS) == 0)
1120377e23a2Schristos continue;
1121377e23a2Schristos
1122377e23a2Schristos /* Allocate memory for the section contents. */
11235e098073Schristos s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
1124377e23a2Schristos if (s->contents == NULL)
1125377e23a2Schristos return FALSE;
1126377e23a2Schristos }
1127377e23a2Schristos
1128*1424dfb3Schristos return _bfd_elf_add_dynamic_tags (output_bfd, info, relocs);
1129377e23a2Schristos }
1130377e23a2Schristos
1131377e23a2Schristos /* This function is called via elf_vax_link_hash_traverse if we are
1132377e23a2Schristos creating a shared object with -Bsymbolic. It discards the space
1133377e23a2Schristos allocated to copy PC relative relocs against symbols which are defined
1134377e23a2Schristos in regular objects. We allocated space for them in the check_relocs
1135377e23a2Schristos routine, but we won't fill them in in the relocate_section routine. */
1136377e23a2Schristos
1137377e23a2Schristos static bfd_boolean
elf_vax_discard_copies(struct elf_vax_link_hash_entry * h,void * ignore ATTRIBUTE_UNUSED)1138377e23a2Schristos elf_vax_discard_copies (struct elf_vax_link_hash_entry *h,
113948596154Schristos void * ignore ATTRIBUTE_UNUSED)
1140377e23a2Schristos {
1141377e23a2Schristos struct elf_vax_pcrel_relocs_copied *s;
1142377e23a2Schristos
1143377e23a2Schristos /* We only discard relocs for symbols defined in a regular object. */
1144377e23a2Schristos if (!h->root.def_regular)
1145377e23a2Schristos return TRUE;
1146377e23a2Schristos
1147377e23a2Schristos for (s = h->pcrel_relocs_copied; s != NULL; s = s->next)
1148377e23a2Schristos s->section->size -= s->count * sizeof (Elf32_External_Rela);
1149377e23a2Schristos
1150377e23a2Schristos return TRUE;
1151377e23a2Schristos }
1152377e23a2Schristos
11537af5a897Schristos /* This function is called via elf_link_hash_traverse. It looks for
11547af5a897Schristos entries that have GOT or PLT (.GOT) references. If creating a shared
11557af5a897Schristos object with -Bsymbolic, or the symbol has been forced local, then it
11567af5a897Schristos resets the reference count back to -1 so normal PC32 relocation will
11577af5a897Schristos be done. Otherwise space in the .got and .rela.got will be reserved
11587af5a897Schristos for the symbol. */
1159377e23a2Schristos
1160377e23a2Schristos static bfd_boolean
elf_vax_instantiate_got_entries(struct elf_link_hash_entry * h,void * infoptr)116148596154Schristos elf_vax_instantiate_got_entries (struct elf_link_hash_entry *h, void * infoptr)
1162377e23a2Schristos {
1163377e23a2Schristos struct bfd_link_info *info = (struct bfd_link_info *) infoptr;
1164377e23a2Schristos bfd *dynobj;
1165377e23a2Schristos asection *sgot;
1166377e23a2Schristos asection *srelgot;
1167377e23a2Schristos
1168377e23a2Schristos /* We don't care about non-GOT (and non-PLT) entries. */
1169377e23a2Schristos if (h->got.refcount <= 0 && h->plt.refcount <= 0)
1170377e23a2Schristos return TRUE;
1171377e23a2Schristos
1172377e23a2Schristos dynobj = elf_hash_table (info)->dynobj;
11737af5a897Schristos BFD_ASSERT (dynobj != NULL);
1174377e23a2Schristos
11751c468f90Schristos sgot = elf_hash_table (info)->sgot;
11761c468f90Schristos srelgot = elf_hash_table (info)->srelgot;
1177377e23a2Schristos
11787af5a897Schristos if (SYMBOL_REFERENCES_LOCAL (info, h))
1179377e23a2Schristos {
11807af5a897Schristos h->got.refcount = -1;
11817af5a897Schristos h->plt.refcount = -1;
1182377e23a2Schristos }
1183377e23a2Schristos else if (h->got.refcount > 0)
1184377e23a2Schristos {
1185377e23a2Schristos /* Make sure this symbol is output as a dynamic symbol. */
1186377e23a2Schristos if (h->dynindx == -1)
1187377e23a2Schristos {
1188377e23a2Schristos if (!bfd_elf_link_record_dynamic_symbol (info, h))
1189377e23a2Schristos return FALSE;
1190377e23a2Schristos }
1191377e23a2Schristos
1192377e23a2Schristos /* Allocate space in the .got and .rela.got sections. */
1193377e23a2Schristos sgot->size += 4;
1194377e23a2Schristos srelgot->size += sizeof (Elf32_External_Rela);
1195377e23a2Schristos }
1196377e23a2Schristos
1197377e23a2Schristos return TRUE;
1198377e23a2Schristos }
1199377e23a2Schristos
1200377e23a2Schristos /* Relocate an VAX ELF section. */
1201377e23a2Schristos
1202377e23a2Schristos static bfd_boolean
elf_vax_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)1203377e23a2Schristos elf_vax_relocate_section (bfd *output_bfd,
1204377e23a2Schristos struct bfd_link_info *info,
1205377e23a2Schristos bfd *input_bfd,
1206377e23a2Schristos asection *input_section,
1207377e23a2Schristos bfd_byte *contents,
1208377e23a2Schristos Elf_Internal_Rela *relocs,
1209377e23a2Schristos Elf_Internal_Sym *local_syms,
1210377e23a2Schristos asection **local_sections)
1211377e23a2Schristos {
1212377e23a2Schristos Elf_Internal_Shdr *symtab_hdr;
1213377e23a2Schristos struct elf_link_hash_entry **sym_hashes;
1214377e23a2Schristos bfd_vma plt_index;
1215377e23a2Schristos bfd_vma got_offset;
1216377e23a2Schristos asection *sgot;
1217377e23a2Schristos asection *splt;
1218377e23a2Schristos asection *sgotplt;
1219377e23a2Schristos asection *sreloc;
1220377e23a2Schristos Elf_Internal_Rela *rel;
1221377e23a2Schristos Elf_Internal_Rela *relend;
1222377e23a2Schristos
1223377e23a2Schristos symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1224377e23a2Schristos sym_hashes = elf_sym_hashes (input_bfd);
1225377e23a2Schristos
1226377e23a2Schristos sgot = NULL;
1227377e23a2Schristos splt = NULL;
1228377e23a2Schristos sgotplt = NULL;
1229377e23a2Schristos sreloc = NULL;
1230377e23a2Schristos
1231377e23a2Schristos rel = relocs;
1232377e23a2Schristos relend = relocs + input_section->reloc_count;
1233377e23a2Schristos for (; rel < relend; rel++)
1234377e23a2Schristos {
1235377e23a2Schristos int r_type;
1236377e23a2Schristos reloc_howto_type *howto;
1237377e23a2Schristos unsigned long r_symndx;
1238377e23a2Schristos struct elf_link_hash_entry *h;
1239377e23a2Schristos Elf_Internal_Sym *sym;
1240377e23a2Schristos asection *sec;
1241377e23a2Schristos bfd_vma relocation;
1242377e23a2Schristos bfd_reloc_status_type r;
1243377e23a2Schristos
1244377e23a2Schristos r_type = ELF32_R_TYPE (rel->r_info);
1245377e23a2Schristos if (r_type < 0 || r_type >= (int) R_VAX_max)
1246377e23a2Schristos {
1247377e23a2Schristos bfd_set_error (bfd_error_bad_value);
1248377e23a2Schristos return FALSE;
1249377e23a2Schristos }
1250377e23a2Schristos howto = howto_table + r_type;
1251377e23a2Schristos
1252377e23a2Schristos r_symndx = ELF32_R_SYM (rel->r_info);
1253377e23a2Schristos h = NULL;
1254377e23a2Schristos sym = NULL;
1255377e23a2Schristos sec = NULL;
1256377e23a2Schristos if (r_symndx < symtab_hdr->sh_info)
1257377e23a2Schristos {
1258377e23a2Schristos sym = local_syms + r_symndx;
1259377e23a2Schristos sec = local_sections[r_symndx];
1260377e23a2Schristos relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
1261377e23a2Schristos }
1262377e23a2Schristos else
1263377e23a2Schristos {
1264377e23a2Schristos bfd_boolean unresolved_reloc;
12657af5a897Schristos bfd_boolean warned, ignored;
1266377e23a2Schristos
1267377e23a2Schristos RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1268377e23a2Schristos r_symndx, symtab_hdr, sym_hashes,
1269377e23a2Schristos h, sec, relocation,
12707af5a897Schristos unresolved_reloc, warned, ignored);
1271377e23a2Schristos
1272377e23a2Schristos if ((h->root.type == bfd_link_hash_defined
1273377e23a2Schristos || h->root.type == bfd_link_hash_defweak)
1274377e23a2Schristos && ((r_type == R_VAX_PLT32
1275377e23a2Schristos && h->plt.offset != (bfd_vma) -1
1276377e23a2Schristos && !h->forced_local
1277377e23a2Schristos && elf_hash_table (info)->dynamic_sections_created)
1278377e23a2Schristos || (r_type == R_VAX_GOT32
1279377e23a2Schristos && h->got.offset != (bfd_vma) -1
1280377e23a2Schristos && !h->forced_local
1281377e23a2Schristos && elf_hash_table (info)->dynamic_sections_created
1282c03b94e9Schristos && (! bfd_link_pic (info)
1283377e23a2Schristos || (! info->symbolic && h->dynindx != -1)
1284377e23a2Schristos || !h->def_regular))
1285c03b94e9Schristos || (bfd_link_pic (info)
1286377e23a2Schristos && ((! info->symbolic && h->dynindx != -1)
1287377e23a2Schristos || !h->def_regular)
1288377e23a2Schristos && ((input_section->flags & SEC_ALLOC) != 0
1289377e23a2Schristos /* DWARF will emit R_VAX_32 relocations in its
1290377e23a2Schristos sections against symbols defined externally
1291377e23a2Schristos in shared libraries. We can't do anything
1292377e23a2Schristos with them here. */
1293377e23a2Schristos
1294377e23a2Schristos || ((input_section->flags & SEC_DEBUGGING) != 0
1295377e23a2Schristos && h->def_dynamic))
1296377e23a2Schristos && (r_type == R_VAX_8
1297377e23a2Schristos || r_type == R_VAX_16
1298377e23a2Schristos || r_type == R_VAX_32))))
1299377e23a2Schristos /* In these cases, we don't need the relocation
1300377e23a2Schristos value. We check specially because in some
1301377e23a2Schristos obscure cases sec->output_section will be NULL. */
1302377e23a2Schristos relocation = 0;
1303377e23a2Schristos }
1304377e23a2Schristos
130548596154Schristos if (sec != NULL && discarded_section (sec))
1306377e23a2Schristos RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
130748596154Schristos rel, 1, relend, howto, 0, contents);
1308377e23a2Schristos
1309c03b94e9Schristos if (bfd_link_relocatable (info))
1310377e23a2Schristos continue;
1311377e23a2Schristos
1312377e23a2Schristos switch (r_type)
1313377e23a2Schristos {
1314377e23a2Schristos case R_VAX_GOT32:
1315377e23a2Schristos /* Relocation is to the address of the entry for this symbol
1316377e23a2Schristos in the global offset table. */
13177af5a897Schristos
13187af5a897Schristos /* Resolve a GOTxx reloc against a local symbol directly,
13197af5a897Schristos without using the global offset table. */
1320377e23a2Schristos if (h == NULL
13217af5a897Schristos || h->got.offset == (bfd_vma) -1)
1322377e23a2Schristos break;
1323377e23a2Schristos
1324377e23a2Schristos {
1325377e23a2Schristos bfd_vma off;
1326377e23a2Schristos
13271c468f90Schristos sgot = elf_hash_table (info)->sgot;
1328377e23a2Schristos BFD_ASSERT (sgot != NULL);
1329377e23a2Schristos
1330377e23a2Schristos off = h->got.offset;
1331377e23a2Schristos BFD_ASSERT (off < sgot->size);
1332377e23a2Schristos
1333377e23a2Schristos bfd_put_32 (output_bfd, rel->r_addend, sgot->contents + off);
1334377e23a2Schristos
1335377e23a2Schristos relocation = sgot->output_offset + off;
1336377e23a2Schristos /* The GOT relocation uses the addend. */
1337377e23a2Schristos rel->r_addend = 0;
1338377e23a2Schristos
1339377e23a2Schristos /* Change the reference to be indirect. */
1340377e23a2Schristos contents[rel->r_offset - 1] |= 0x10;
1341377e23a2Schristos relocation += sgot->output_section->vma;
1342377e23a2Schristos }
1343377e23a2Schristos break;
1344377e23a2Schristos
1345377e23a2Schristos case R_VAX_PC32:
1346377e23a2Schristos /* If we are creating an executable and the function this
1347377e23a2Schristos reloc refers to is in a shared lib, then we made a PLT
1348377e23a2Schristos entry for this symbol and need to handle the reloc like
1349377e23a2Schristos a PLT reloc. */
1350c03b94e9Schristos if (bfd_link_pic (info))
1351377e23a2Schristos goto r_vax_pc32_shared;
1352377e23a2Schristos /* Fall through. */
1353377e23a2Schristos case R_VAX_PLT32:
1354377e23a2Schristos /* Relocation is to the entry for this symbol in the
1355377e23a2Schristos procedure linkage table. */
1356377e23a2Schristos
1357377e23a2Schristos /* Resolve a PLTxx reloc against a local symbol directly,
1358377e23a2Schristos without using the procedure linkage table. */
1359377e23a2Schristos if (h == NULL
13607af5a897Schristos || h->plt.offset == (bfd_vma) -1)
1361377e23a2Schristos break;
1362377e23a2Schristos
13631c468f90Schristos splt = elf_hash_table (info)->splt;
1364377e23a2Schristos BFD_ASSERT (splt != NULL);
1365377e23a2Schristos
13661c468f90Schristos sgotplt = elf_hash_table (info)->sgotplt;
1367377e23a2Schristos BFD_ASSERT (sgotplt != NULL);
1368377e23a2Schristos
1369377e23a2Schristos plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
1370377e23a2Schristos
1371377e23a2Schristos /* Get the offset into the .got table of the entry that
1372377e23a2Schristos corresponds to this function. Each .got entry is 4 bytes.
1373377e23a2Schristos The first two are reserved. */
1374377e23a2Schristos got_offset = (plt_index + 3) * 4;
1375377e23a2Schristos
1376377e23a2Schristos /* We want the relocation to point into the .got.plt instead
1377377e23a2Schristos of the plt itself. */
1378377e23a2Schristos relocation = (sgotplt->output_section->vma
1379377e23a2Schristos + sgotplt->output_offset
1380377e23a2Schristos + got_offset);
1381377e23a2Schristos contents[rel->r_offset-1] |= 0x10; /* make indirect */
1382377e23a2Schristos if (rel->r_addend == 2)
1383377e23a2Schristos {
1384377e23a2Schristos h->plt.offset |= 1;
1385377e23a2Schristos }
1386377e23a2Schristos else if (rel->r_addend != 0)
13871c468f90Schristos _bfd_error_handler
13881c468f90Schristos /* xgettext:c-format */
138907163879Schristos (_("%pB: warning: PLT addend of %" PRId64 " to `%s'"
139007163879Schristos " from %pA section ignored"),
139107163879Schristos input_bfd, (int64_t) rel->r_addend, h->root.root.string,
139207163879Schristos input_section);
1393377e23a2Schristos rel->r_addend = 0;
1394377e23a2Schristos
1395377e23a2Schristos break;
1396377e23a2Schristos
1397377e23a2Schristos case R_VAX_PC8:
1398377e23a2Schristos case R_VAX_PC16:
1399377e23a2Schristos r_vax_pc32_shared:
1400377e23a2Schristos if (h == NULL
1401377e23a2Schristos || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
1402377e23a2Schristos || h->forced_local)
1403377e23a2Schristos break;
1404377e23a2Schristos /* Fall through. */
1405377e23a2Schristos case R_VAX_8:
1406377e23a2Schristos case R_VAX_16:
1407377e23a2Schristos case R_VAX_32:
1408c03b94e9Schristos if (bfd_link_pic (info)
1409377e23a2Schristos && r_symndx != STN_UNDEF
1410377e23a2Schristos && (input_section->flags & SEC_ALLOC) != 0
1411377e23a2Schristos && ((r_type != R_VAX_PC8
1412377e23a2Schristos && r_type != R_VAX_PC16
1413377e23a2Schristos && r_type != R_VAX_PC32)
1414377e23a2Schristos || ((input_section->flags & SEC_CODE)
1415377e23a2Schristos && (!info->symbolic
1416377e23a2Schristos || (!h->def_regular && h->type != STT_SECTION)))))
1417377e23a2Schristos {
1418377e23a2Schristos Elf_Internal_Rela outrel;
1419377e23a2Schristos bfd_byte *loc;
1420377e23a2Schristos bfd_boolean skip, relocate;
1421377e23a2Schristos
1422377e23a2Schristos /* When generating a shared object, these relocations
1423377e23a2Schristos are copied into the output file to be resolved at run
1424377e23a2Schristos time. */
1425377e23a2Schristos if (sreloc == NULL)
1426377e23a2Schristos {
1427377e23a2Schristos sreloc = _bfd_elf_get_dynamic_reloc_section
1428377e23a2Schristos (input_bfd, input_section, /*rela?*/ TRUE);
1429377e23a2Schristos if (sreloc == NULL)
1430377e23a2Schristos return FALSE;
1431377e23a2Schristos }
1432377e23a2Schristos
1433377e23a2Schristos skip = FALSE;
1434377e23a2Schristos relocate = FALSE;
1435377e23a2Schristos
1436377e23a2Schristos outrel.r_offset =
1437377e23a2Schristos _bfd_elf_section_offset (output_bfd, info, input_section,
1438377e23a2Schristos rel->r_offset);
1439377e23a2Schristos if (outrel.r_offset == (bfd_vma) -1)
1440377e23a2Schristos skip = TRUE;
1441377e23a2Schristos if (outrel.r_offset == (bfd_vma) -2)
1442377e23a2Schristos skip = TRUE, relocate = TRUE;
1443377e23a2Schristos outrel.r_offset += (input_section->output_section->vma
1444377e23a2Schristos + input_section->output_offset);
1445377e23a2Schristos
1446377e23a2Schristos if (skip)
1447377e23a2Schristos memset (&outrel, 0, sizeof outrel);
1448377e23a2Schristos /* h->dynindx may be -1 if the symbol was marked to
1449377e23a2Schristos become local. */
1450377e23a2Schristos else if (h != NULL
1451377e23a2Schristos && ((! info->symbolic && h->dynindx != -1)
1452377e23a2Schristos || !h->def_regular))
1453377e23a2Schristos {
1454377e23a2Schristos BFD_ASSERT (h->dynindx != -1);
1455377e23a2Schristos outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
1456377e23a2Schristos outrel.r_addend = relocation + rel->r_addend;
1457377e23a2Schristos }
1458377e23a2Schristos else
1459377e23a2Schristos {
1460377e23a2Schristos if (r_type == R_VAX_32)
1461377e23a2Schristos {
1462377e23a2Schristos relocate = TRUE;
1463377e23a2Schristos outrel.r_info = ELF32_R_INFO (0, R_VAX_RELATIVE);
1464377e23a2Schristos BFD_ASSERT (bfd_get_signed_32 (input_bfd,
1465377e23a2Schristos &contents[rel->r_offset]) == 0);
1466377e23a2Schristos outrel.r_addend = relocation + rel->r_addend;
1467377e23a2Schristos }
1468377e23a2Schristos else
1469377e23a2Schristos {
1470377e23a2Schristos long indx;
1471377e23a2Schristos
1472377e23a2Schristos if (bfd_is_abs_section (sec))
1473377e23a2Schristos indx = 0;
1474377e23a2Schristos else if (sec == NULL || sec->owner == NULL)
1475377e23a2Schristos {
1476377e23a2Schristos bfd_set_error (bfd_error_bad_value);
1477377e23a2Schristos return FALSE;
1478377e23a2Schristos }
1479377e23a2Schristos else
1480377e23a2Schristos {
1481377e23a2Schristos asection *osec;
1482377e23a2Schristos
1483377e23a2Schristos /* We are turning this relocation into one
1484377e23a2Schristos against a section symbol. It would be
1485377e23a2Schristos proper to subtract the symbol's value,
1486377e23a2Schristos osec->vma, from the emitted reloc addend,
1487377e23a2Schristos but ld.so expects buggy relocs. */
1488377e23a2Schristos osec = sec->output_section;
1489377e23a2Schristos indx = elf_section_data (osec)->dynindx;
1490377e23a2Schristos if (indx == 0)
1491377e23a2Schristos {
1492377e23a2Schristos struct elf_link_hash_table *htab;
1493377e23a2Schristos htab = elf_hash_table (info);
1494377e23a2Schristos osec = htab->text_index_section;
1495377e23a2Schristos indx = elf_section_data (osec)->dynindx;
1496377e23a2Schristos }
1497377e23a2Schristos BFD_ASSERT (indx != 0);
1498377e23a2Schristos }
1499377e23a2Schristos
1500377e23a2Schristos outrel.r_info = ELF32_R_INFO (indx, r_type);
1501377e23a2Schristos outrel.r_addend = relocation + rel->r_addend;
1502377e23a2Schristos }
1503377e23a2Schristos }
1504377e23a2Schristos
150548596154Schristos if ((input_section->flags & SEC_CODE) != 0
150648596154Schristos || (ELF32_R_TYPE (outrel.r_info) != R_VAX_32
1507377e23a2Schristos && ELF32_R_TYPE (outrel.r_info) != R_VAX_RELATIVE
1508377e23a2Schristos && ELF32_R_TYPE (outrel.r_info) != R_VAX_COPY
1509377e23a2Schristos && ELF32_R_TYPE (outrel.r_info) != R_VAX_JMP_SLOT
1510377e23a2Schristos && ELF32_R_TYPE (outrel.r_info) != R_VAX_GLOB_DAT))
1511377e23a2Schristos {
1512377e23a2Schristos if (h != NULL)
15131c468f90Schristos _bfd_error_handler
15141c468f90Schristos /* xgettext:c-format */
151507163879Schristos (_("%pB: warning: %s relocation against symbol `%s'"
151607163879Schristos " from %pA section"),
15171c468f90Schristos input_bfd, howto->name, h->root.root.string,
15181c468f90Schristos input_section);
1519377e23a2Schristos else
15201c468f90Schristos _bfd_error_handler
15211c468f90Schristos /* xgettext:c-format */
152207163879Schristos (_("%pB: warning: %s relocation to %#" PRIx64
152307163879Schristos " from %pA section"),
152407163879Schristos input_bfd, howto->name, (uint64_t) outrel.r_addend,
15251c468f90Schristos input_section);
1526377e23a2Schristos }
1527377e23a2Schristos loc = sreloc->contents;
1528377e23a2Schristos loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
1529377e23a2Schristos bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1530377e23a2Schristos
1531377e23a2Schristos /* This reloc will be computed at runtime, so there's no
1532377e23a2Schristos need to do anything now, except for R_VAX_32
1533377e23a2Schristos relocations that have been turned into
1534377e23a2Schristos R_VAX_RELATIVE. */
1535377e23a2Schristos if (!relocate)
1536377e23a2Schristos continue;
1537377e23a2Schristos }
1538377e23a2Schristos
1539377e23a2Schristos break;
1540377e23a2Schristos
1541377e23a2Schristos case R_VAX_GNU_VTINHERIT:
1542377e23a2Schristos case R_VAX_GNU_VTENTRY:
1543377e23a2Schristos /* These are no-ops in the end. */
1544377e23a2Schristos continue;
1545377e23a2Schristos
1546377e23a2Schristos default:
1547377e23a2Schristos break;
1548377e23a2Schristos }
1549377e23a2Schristos
1550377e23a2Schristos /* VAX PCREL relocations are from the end of relocation, not the start.
1551377e23a2Schristos So subtract the difference from the relocation amount since we can't
1552377e23a2Schristos add it to the offset. */
1553377e23a2Schristos if (howto->pc_relative && howto->pcrel_offset)
1554377e23a2Schristos relocation -= bfd_get_reloc_size(howto);
1555377e23a2Schristos
1556377e23a2Schristos r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1557377e23a2Schristos contents, rel->r_offset,
1558377e23a2Schristos relocation, rel->r_addend);
1559377e23a2Schristos
1560377e23a2Schristos if (r != bfd_reloc_ok)
1561377e23a2Schristos {
1562377e23a2Schristos switch (r)
1563377e23a2Schristos {
1564377e23a2Schristos default:
1565377e23a2Schristos case bfd_reloc_outofrange:
1566377e23a2Schristos abort ();
1567377e23a2Schristos case bfd_reloc_overflow:
1568377e23a2Schristos {
1569377e23a2Schristos const char *name;
1570377e23a2Schristos
1571377e23a2Schristos if (h != NULL)
1572377e23a2Schristos name = NULL;
1573377e23a2Schristos else
1574377e23a2Schristos {
1575377e23a2Schristos name = bfd_elf_string_from_elf_section (input_bfd,
1576377e23a2Schristos symtab_hdr->sh_link,
1577377e23a2Schristos sym->st_name);
1578377e23a2Schristos if (name == NULL)
1579377e23a2Schristos return FALSE;
1580377e23a2Schristos if (*name == '\0')
1581*1424dfb3Schristos name = bfd_section_name (sec);
1582377e23a2Schristos }
1583c03b94e9Schristos info->callbacks->reloc_overflow
1584377e23a2Schristos (info, (h ? &h->root : NULL), name, howto->name,
1585c03b94e9Schristos (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
1586377e23a2Schristos }
1587377e23a2Schristos break;
1588377e23a2Schristos }
1589377e23a2Schristos }
1590377e23a2Schristos }
1591377e23a2Schristos
1592377e23a2Schristos return TRUE;
1593377e23a2Schristos }
1594377e23a2Schristos
1595377e23a2Schristos /* Finish up dynamic symbol handling. We set the contents of various
1596377e23a2Schristos dynamic sections here. */
1597377e23a2Schristos
1598377e23a2Schristos static bfd_boolean
elf_vax_finish_dynamic_symbol(bfd * output_bfd,struct bfd_link_info * info,struct elf_link_hash_entry * h,Elf_Internal_Sym * sym)1599377e23a2Schristos elf_vax_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
1600377e23a2Schristos struct elf_link_hash_entry *h,
1601377e23a2Schristos Elf_Internal_Sym *sym)
1602377e23a2Schristos {
1603377e23a2Schristos bfd *dynobj;
1604377e23a2Schristos
1605377e23a2Schristos dynobj = elf_hash_table (info)->dynobj;
1606377e23a2Schristos
1607377e23a2Schristos if (h->plt.offset != (bfd_vma) -1)
1608377e23a2Schristos {
1609377e23a2Schristos asection *splt;
1610377e23a2Schristos asection *sgot;
1611377e23a2Schristos asection *srela;
1612377e23a2Schristos bfd_vma plt_index;
1613377e23a2Schristos bfd_vma got_offset;
1614377e23a2Schristos bfd_vma addend;
1615377e23a2Schristos Elf_Internal_Rela rela;
1616377e23a2Schristos bfd_byte *loc;
1617377e23a2Schristos
1618377e23a2Schristos /* This symbol has an entry in the procedure linkage table. Set
1619377e23a2Schristos it up. */
1620377e23a2Schristos BFD_ASSERT (h->dynindx != -1);
1621377e23a2Schristos
16221c468f90Schristos splt = elf_hash_table (info)->splt;
16231c468f90Schristos sgot = elf_hash_table (info)->sgotplt;
16241c468f90Schristos srela = elf_hash_table (info)->srelplt;
1625377e23a2Schristos BFD_ASSERT (splt != NULL && sgot != NULL && srela != NULL);
1626377e23a2Schristos
1627377e23a2Schristos addend = 2 * (h->plt.offset & 1);
1628377e23a2Schristos h->plt.offset &= ~1;
1629377e23a2Schristos
1630377e23a2Schristos /* Get the index in the procedure linkage table which
1631377e23a2Schristos corresponds to this symbol. This is the index of this symbol
1632377e23a2Schristos in all the symbols for which we are making plt entries. The
1633377e23a2Schristos first entry in the procedure linkage table is reserved. */
1634377e23a2Schristos plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
1635377e23a2Schristos
1636377e23a2Schristos /* Get the offset into the .got table of the entry that
1637377e23a2Schristos corresponds to this function. Each .got entry is 4 bytes.
1638377e23a2Schristos The first two are reserved. */
1639377e23a2Schristos got_offset = (plt_index + 3) * 4;
1640377e23a2Schristos
1641377e23a2Schristos /* Fill in the entry in the procedure linkage table. */
1642377e23a2Schristos memcpy (splt->contents + h->plt.offset, elf_vax_plt_entry,
1643377e23a2Schristos PLT_ENTRY_SIZE);
1644377e23a2Schristos
1645377e23a2Schristos /* The offset is relative to the first extension word. */
1646377e23a2Schristos bfd_put_32 (output_bfd,
1647377e23a2Schristos -(h->plt.offset + 8),
1648377e23a2Schristos splt->contents + h->plt.offset + 4);
1649377e23a2Schristos
1650377e23a2Schristos bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rela),
1651377e23a2Schristos splt->contents + h->plt.offset + 8);
1652377e23a2Schristos
1653377e23a2Schristos /* Fill in the entry in the global offset table. */
1654377e23a2Schristos bfd_put_32 (output_bfd,
1655377e23a2Schristos (splt->output_section->vma
1656377e23a2Schristos + splt->output_offset
1657377e23a2Schristos + h->plt.offset) + addend,
1658377e23a2Schristos sgot->contents + got_offset);
1659377e23a2Schristos
1660377e23a2Schristos /* Fill in the entry in the .rela.plt section. */
1661377e23a2Schristos rela.r_offset = (sgot->output_section->vma
1662377e23a2Schristos + sgot->output_offset
1663377e23a2Schristos + got_offset);
1664377e23a2Schristos rela.r_info = ELF32_R_INFO (h->dynindx, R_VAX_JMP_SLOT);
1665377e23a2Schristos rela.r_addend = addend;
1666377e23a2Schristos loc = srela->contents + plt_index * sizeof (Elf32_External_Rela);
1667377e23a2Schristos bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
1668377e23a2Schristos
1669377e23a2Schristos if (!h->def_regular)
1670377e23a2Schristos {
1671377e23a2Schristos /* Mark the symbol as undefined, rather than as defined in
1672377e23a2Schristos the .plt section. Leave the value alone. */
1673377e23a2Schristos sym->st_shndx = SHN_UNDEF;
1674377e23a2Schristos }
1675377e23a2Schristos }
1676377e23a2Schristos
1677377e23a2Schristos if (h->got.offset != (bfd_vma) -1)
1678377e23a2Schristos {
1679377e23a2Schristos asection *sgot;
1680377e23a2Schristos asection *srela;
1681377e23a2Schristos Elf_Internal_Rela rela;
1682377e23a2Schristos bfd_byte *loc;
1683377e23a2Schristos
1684377e23a2Schristos /* This symbol has an entry in the global offset table. Set it
1685377e23a2Schristos up. */
16861c468f90Schristos sgot = elf_hash_table (info)->sgot;
16871c468f90Schristos srela = elf_hash_table (info)->srelgot;
1688377e23a2Schristos BFD_ASSERT (sgot != NULL && srela != NULL);
1689377e23a2Schristos
1690377e23a2Schristos rela.r_offset = (sgot->output_section->vma
1691377e23a2Schristos + sgot->output_offset
16927af5a897Schristos + h->got.offset);
1693377e23a2Schristos rela.r_info = ELF32_R_INFO (h->dynindx, R_VAX_GLOB_DAT);
1694377e23a2Schristos rela.r_addend = bfd_get_signed_32 (output_bfd,
16957af5a897Schristos sgot->contents + h->got.offset);
1696377e23a2Schristos
1697377e23a2Schristos loc = srela->contents;
1698377e23a2Schristos loc += srela->reloc_count++ * sizeof (Elf32_External_Rela);
1699377e23a2Schristos bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
1700377e23a2Schristos }
1701377e23a2Schristos
1702377e23a2Schristos if (h->needs_copy)
1703377e23a2Schristos {
1704377e23a2Schristos asection *s;
1705377e23a2Schristos Elf_Internal_Rela rela;
1706377e23a2Schristos bfd_byte *loc;
1707377e23a2Schristos
1708377e23a2Schristos /* This symbol needs a copy reloc. Set it up. */
1709377e23a2Schristos BFD_ASSERT (h->dynindx != -1
1710377e23a2Schristos && (h->root.type == bfd_link_hash_defined
1711377e23a2Schristos || h->root.type == bfd_link_hash_defweak));
1712377e23a2Schristos
171348596154Schristos s = bfd_get_linker_section (dynobj, ".rela.bss");
1714377e23a2Schristos BFD_ASSERT (s != NULL);
1715377e23a2Schristos
1716377e23a2Schristos rela.r_offset = (h->root.u.def.value
1717377e23a2Schristos + h->root.u.def.section->output_section->vma
1718377e23a2Schristos + h->root.u.def.section->output_offset);
1719377e23a2Schristos rela.r_info = ELF32_R_INFO (h->dynindx, R_VAX_COPY);
1720377e23a2Schristos rela.r_addend = 0;
1721377e23a2Schristos loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
1722377e23a2Schristos bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
1723377e23a2Schristos }
1724377e23a2Schristos
1725377e23a2Schristos /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
172648596154Schristos if (h == elf_hash_table (info)->hdynamic
1727377e23a2Schristos || h == elf_hash_table (info)->hgot)
1728377e23a2Schristos sym->st_shndx = SHN_ABS;
1729377e23a2Schristos
1730377e23a2Schristos return TRUE;
1731377e23a2Schristos }
1732377e23a2Schristos
1733377e23a2Schristos /* Finish up the dynamic sections. */
1734377e23a2Schristos
1735377e23a2Schristos static bfd_boolean
elf_vax_finish_dynamic_sections(bfd * output_bfd,struct bfd_link_info * info)1736377e23a2Schristos elf_vax_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
1737377e23a2Schristos {
1738377e23a2Schristos bfd *dynobj;
1739377e23a2Schristos asection *sgot;
1740377e23a2Schristos asection *sdyn;
1741377e23a2Schristos
1742377e23a2Schristos dynobj = elf_hash_table (info)->dynobj;
1743377e23a2Schristos
17441c468f90Schristos sgot = elf_hash_table (info)->sgotplt;
1745377e23a2Schristos BFD_ASSERT (sgot != NULL);
174648596154Schristos sdyn = bfd_get_linker_section (dynobj, ".dynamic");
1747377e23a2Schristos
1748377e23a2Schristos if (elf_hash_table (info)->dynamic_sections_created)
1749377e23a2Schristos {
1750377e23a2Schristos asection *splt;
1751377e23a2Schristos Elf32_External_Dyn *dyncon, *dynconend;
1752377e23a2Schristos
17531c468f90Schristos splt = elf_hash_table (info)->splt;
1754377e23a2Schristos BFD_ASSERT (splt != NULL && sdyn != NULL);
1755377e23a2Schristos
1756377e23a2Schristos dyncon = (Elf32_External_Dyn *) sdyn->contents;
1757377e23a2Schristos dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
1758377e23a2Schristos for (; dyncon < dynconend; dyncon++)
1759377e23a2Schristos {
1760377e23a2Schristos Elf_Internal_Dyn dyn;
1761377e23a2Schristos asection *s;
1762377e23a2Schristos
1763377e23a2Schristos bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
1764377e23a2Schristos
1765377e23a2Schristos switch (dyn.d_tag)
1766377e23a2Schristos {
1767377e23a2Schristos default:
1768377e23a2Schristos break;
1769377e23a2Schristos
1770377e23a2Schristos case DT_PLTGOT:
17711c468f90Schristos s = elf_hash_table (info)->sgotplt;
1772377e23a2Schristos goto get_vma;
1773377e23a2Schristos case DT_JMPREL:
17741c468f90Schristos s = elf_hash_table (info)->srelplt;
1775377e23a2Schristos get_vma:
1776c03b94e9Schristos dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
1777377e23a2Schristos bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
1778377e23a2Schristos break;
1779377e23a2Schristos
1780377e23a2Schristos case DT_PLTRELSZ:
17811c468f90Schristos s = elf_hash_table (info)->srelplt;
1782377e23a2Schristos dyn.d_un.d_val = s->size;
1783377e23a2Schristos bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
1784377e23a2Schristos break;
1785377e23a2Schristos }
1786377e23a2Schristos }
1787377e23a2Schristos
1788377e23a2Schristos /* Fill in the first entry in the procedure linkage table. */
1789377e23a2Schristos if (splt->size > 0)
1790377e23a2Schristos {
1791377e23a2Schristos memcpy (splt->contents, elf_vax_plt0_entry, PLT_ENTRY_SIZE);
1792377e23a2Schristos bfd_put_32 (output_bfd,
1793377e23a2Schristos (sgot->output_section->vma
1794377e23a2Schristos + sgot->output_offset + 4
1795377e23a2Schristos - (splt->output_section->vma + 6)),
1796377e23a2Schristos splt->contents + 2);
1797377e23a2Schristos bfd_put_32 (output_bfd,
1798377e23a2Schristos (sgot->output_section->vma
1799377e23a2Schristos + sgot->output_offset + 8
1800377e23a2Schristos - (splt->output_section->vma + 12)),
1801377e23a2Schristos splt->contents + 8);
1802377e23a2Schristos elf_section_data (splt->output_section)->this_hdr.sh_entsize
1803377e23a2Schristos = PLT_ENTRY_SIZE;
1804377e23a2Schristos }
1805377e23a2Schristos }
1806377e23a2Schristos
1807377e23a2Schristos /* Fill in the first three entries in the global offset table. */
1808377e23a2Schristos if (sgot->size > 0)
1809377e23a2Schristos {
1810377e23a2Schristos if (sdyn == NULL)
1811377e23a2Schristos bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
1812377e23a2Schristos else
1813377e23a2Schristos bfd_put_32 (output_bfd,
1814377e23a2Schristos sdyn->output_section->vma + sdyn->output_offset,
1815377e23a2Schristos sgot->contents);
1816377e23a2Schristos bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 4);
1817377e23a2Schristos bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 8);
1818377e23a2Schristos }
1819377e23a2Schristos
18207af5a897Schristos if (elf_section_data (sgot->output_section) != NULL)
1821377e23a2Schristos elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
1822377e23a2Schristos
1823377e23a2Schristos return TRUE;
1824377e23a2Schristos }
1825377e23a2Schristos
1826377e23a2Schristos static enum elf_reloc_type_class
elf_vax_reloc_type_class(const struct bfd_link_info * info ATTRIBUTE_UNUSED,const asection * rel_sec ATTRIBUTE_UNUSED,const Elf_Internal_Rela * rela)18277af5a897Schristos elf_vax_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
18287af5a897Schristos const asection *rel_sec ATTRIBUTE_UNUSED,
18297af5a897Schristos const Elf_Internal_Rela *rela)
1830377e23a2Schristos {
1831377e23a2Schristos switch ((int) ELF32_R_TYPE (rela->r_info))
1832377e23a2Schristos {
1833377e23a2Schristos case R_VAX_RELATIVE:
1834377e23a2Schristos return reloc_class_relative;
1835377e23a2Schristos case R_VAX_JMP_SLOT:
1836377e23a2Schristos return reloc_class_plt;
1837377e23a2Schristos case R_VAX_COPY:
1838377e23a2Schristos return reloc_class_copy;
1839377e23a2Schristos default:
1840377e23a2Schristos return reloc_class_normal;
1841377e23a2Schristos }
1842377e23a2Schristos }
1843377e23a2Schristos
1844377e23a2Schristos static bfd_vma
elf_vax_plt_sym_val(bfd_vma i,const asection * plt,const arelent * rel ATTRIBUTE_UNUSED)1845377e23a2Schristos elf_vax_plt_sym_val (bfd_vma i, const asection *plt,
1846377e23a2Schristos const arelent *rel ATTRIBUTE_UNUSED)
1847377e23a2Schristos {
1848377e23a2Schristos return plt->vma + (i + 1) * PLT_ENTRY_SIZE;
1849377e23a2Schristos }
1850377e23a2Schristos
18515e098073Schristos #define TARGET_LITTLE_SYM vax_elf32_vec
1852377e23a2Schristos #define TARGET_LITTLE_NAME "elf32-vax"
1853377e23a2Schristos #define ELF_MACHINE_CODE EM_VAX
1854377e23a2Schristos #define ELF_MAXPAGESIZE 0x1000
1855377e23a2Schristos
1856377e23a2Schristos #define elf_backend_create_dynamic_sections \
1857377e23a2Schristos _bfd_elf_create_dynamic_sections
1858377e23a2Schristos #define bfd_elf32_bfd_link_hash_table_create \
1859377e23a2Schristos elf_vax_link_hash_table_create
1860377e23a2Schristos #define bfd_elf32_bfd_final_link bfd_elf_gc_common_final_link
1861377e23a2Schristos
1862377e23a2Schristos #define elf_backend_check_relocs elf_vax_check_relocs
1863377e23a2Schristos #define elf_backend_adjust_dynamic_symbol \
1864377e23a2Schristos elf_vax_adjust_dynamic_symbol
18657af5a897Schristos #define elf_backend_always_size_sections \
18667af5a897Schristos elf_vax_always_size_sections
1867377e23a2Schristos #define elf_backend_size_dynamic_sections \
1868377e23a2Schristos elf_vax_size_dynamic_sections
1869377e23a2Schristos #define elf_backend_init_index_section _bfd_elf_init_1_index_section
1870377e23a2Schristos #define elf_backend_relocate_section elf_vax_relocate_section
1871377e23a2Schristos #define elf_backend_finish_dynamic_symbol \
1872377e23a2Schristos elf_vax_finish_dynamic_symbol
1873377e23a2Schristos #define elf_backend_finish_dynamic_sections \
1874377e23a2Schristos elf_vax_finish_dynamic_sections
1875377e23a2Schristos #define elf_backend_reloc_type_class elf_vax_reloc_type_class
1876377e23a2Schristos #define elf_backend_gc_mark_hook elf_vax_gc_mark_hook
1877377e23a2Schristos #define elf_backend_plt_sym_val elf_vax_plt_sym_val
1878377e23a2Schristos #define bfd_elf32_bfd_merge_private_bfd_data \
1879377e23a2Schristos elf32_vax_merge_private_bfd_data
1880377e23a2Schristos #define bfd_elf32_bfd_set_private_flags \
1881377e23a2Schristos elf32_vax_set_private_flags
1882377e23a2Schristos #define bfd_elf32_bfd_print_private_bfd_data \
1883377e23a2Schristos elf32_vax_print_private_bfd_data
1884377e23a2Schristos
1885377e23a2Schristos #define elf_backend_can_gc_sections 1
1886377e23a2Schristos #define elf_backend_want_got_plt 1
1887377e23a2Schristos #define elf_backend_plt_readonly 1
1888377e23a2Schristos #define elf_backend_want_plt_sym 0
1889377e23a2Schristos #define elf_backend_got_header_size 16
1890377e23a2Schristos #define elf_backend_rela_normal 1
18911c468f90Schristos #define elf_backend_dtrel_excludes_plt 1
1892377e23a2Schristos
1893377e23a2Schristos #include "elf32-target.h"
1894