xref: /netbsd/external/gpl3/gdb/dist/bfd/elf32-vax.c (revision 1424dfb3)
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