OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [bfd/] [elf32-m68k.c] - Blame information for rev 853

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 24 jeremybenn
/* Motorola 68k series support for 32-bit ELF
2
   Copyright 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3 225 jeremybenn
   2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
4 24 jeremybenn
 
5
   This file is part of BFD, the Binary File Descriptor library.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20
   MA 02110-1301, USA.  */
21
 
22
#include "sysdep.h"
23
#include "bfd.h"
24
#include "bfdlink.h"
25
#include "libbfd.h"
26
#include "elf-bfd.h"
27
#include "elf/m68k.h"
28
#include "opcode/m68k.h"
29
 
30
static reloc_howto_type *reloc_type_lookup
31
  PARAMS ((bfd *, bfd_reloc_code_real_type));
32
static void rtype_to_howto
33
  PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
34
static struct bfd_hash_entry *elf_m68k_link_hash_newfunc
35
  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
36
static struct bfd_link_hash_table *elf_m68k_link_hash_table_create
37
  PARAMS ((bfd *));
38
static bfd_boolean elf_m68k_check_relocs
39
  PARAMS ((bfd *, struct bfd_link_info *, asection *,
40
           const Elf_Internal_Rela *));
41
static bfd_boolean elf_m68k_adjust_dynamic_symbol
42
  PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
43
static bfd_boolean elf_m68k_size_dynamic_sections
44
  PARAMS ((bfd *, struct bfd_link_info *));
45
static bfd_boolean elf_m68k_discard_copies
46
  PARAMS ((struct elf_link_hash_entry *, PTR));
47
static bfd_boolean elf_m68k_relocate_section
48
  PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
49
           Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
50
static bfd_boolean elf_m68k_finish_dynamic_symbol
51
  PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
52
           Elf_Internal_Sym *));
53
static bfd_boolean elf_m68k_finish_dynamic_sections
54
  PARAMS ((bfd *, struct bfd_link_info *));
55
 
56
static bfd_boolean elf32_m68k_set_private_flags
57
  PARAMS ((bfd *, flagword));
58
static bfd_boolean elf32_m68k_merge_private_bfd_data
59
  PARAMS ((bfd *, bfd *));
60
static bfd_boolean elf32_m68k_print_private_bfd_data
61
  PARAMS ((bfd *, PTR));
62
static enum elf_reloc_type_class elf32_m68k_reloc_type_class
63
  PARAMS ((const Elf_Internal_Rela *));
64
 
65
static reloc_howto_type howto_table[] = {
66
  HOWTO(R_68K_NONE,       0, 0, 0, FALSE,0, complain_overflow_dont,     bfd_elf_generic_reloc, "R_68K_NONE",      FALSE, 0, 0x00000000,FALSE),
67
  HOWTO(R_68K_32,         0, 2,32, FALSE,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_32",        FALSE, 0, 0xffffffff,FALSE),
68
  HOWTO(R_68K_16,         0, 1,16, FALSE,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_16",        FALSE, 0, 0x0000ffff,FALSE),
69
  HOWTO(R_68K_8,          0, 0, 8, FALSE,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_8",         FALSE, 0, 0x000000ff,FALSE),
70
  HOWTO(R_68K_PC32,       0, 2,32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_PC32",      FALSE, 0, 0xffffffff,TRUE),
71
  HOWTO(R_68K_PC16,       0, 1,16, TRUE, 0, complain_overflow_signed,   bfd_elf_generic_reloc, "R_68K_PC16",      FALSE, 0, 0x0000ffff,TRUE),
72
  HOWTO(R_68K_PC8,        0, 0, 8, TRUE, 0, complain_overflow_signed,   bfd_elf_generic_reloc, "R_68K_PC8",       FALSE, 0, 0x000000ff,TRUE),
73
  HOWTO(R_68K_GOT32,      0, 2,32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_GOT32",     FALSE, 0, 0xffffffff,TRUE),
74
  HOWTO(R_68K_GOT16,      0, 1,16, TRUE, 0, complain_overflow_signed,   bfd_elf_generic_reloc, "R_68K_GOT16",     FALSE, 0, 0x0000ffff,TRUE),
75
  HOWTO(R_68K_GOT8,       0, 0, 8, TRUE, 0, complain_overflow_signed,   bfd_elf_generic_reloc, "R_68K_GOT8",      FALSE, 0, 0x000000ff,TRUE),
76
  HOWTO(R_68K_GOT32O,     0, 2,32, FALSE,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_GOT32O",    FALSE, 0, 0xffffffff,FALSE),
77
  HOWTO(R_68K_GOT16O,     0, 1,16, FALSE,0, complain_overflow_signed,   bfd_elf_generic_reloc, "R_68K_GOT16O",    FALSE, 0, 0x0000ffff,FALSE),
78
  HOWTO(R_68K_GOT8O,      0, 0, 8, FALSE,0, complain_overflow_signed,   bfd_elf_generic_reloc, "R_68K_GOT8O",     FALSE, 0, 0x000000ff,FALSE),
79
  HOWTO(R_68K_PLT32,      0, 2,32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_PLT32",     FALSE, 0, 0xffffffff,TRUE),
80
  HOWTO(R_68K_PLT16,      0, 1,16, TRUE, 0, complain_overflow_signed,   bfd_elf_generic_reloc, "R_68K_PLT16",     FALSE, 0, 0x0000ffff,TRUE),
81
  HOWTO(R_68K_PLT8,       0, 0, 8, TRUE, 0, complain_overflow_signed,   bfd_elf_generic_reloc, "R_68K_PLT8",      FALSE, 0, 0x000000ff,TRUE),
82
  HOWTO(R_68K_PLT32O,     0, 2,32, FALSE,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_PLT32O",    FALSE, 0, 0xffffffff,FALSE),
83
  HOWTO(R_68K_PLT16O,     0, 1,16, FALSE,0, complain_overflow_signed,   bfd_elf_generic_reloc, "R_68K_PLT16O",    FALSE, 0, 0x0000ffff,FALSE),
84
  HOWTO(R_68K_PLT8O,      0, 0, 8, FALSE,0, complain_overflow_signed,   bfd_elf_generic_reloc, "R_68K_PLT8O",     FALSE, 0, 0x000000ff,FALSE),
85
  HOWTO(R_68K_COPY,       0, 0, 0, FALSE,0, complain_overflow_dont,     bfd_elf_generic_reloc, "R_68K_COPY",      FALSE, 0, 0xffffffff,FALSE),
86
  HOWTO(R_68K_GLOB_DAT,   0, 2,32, FALSE,0, complain_overflow_dont,     bfd_elf_generic_reloc, "R_68K_GLOB_DAT",  FALSE, 0, 0xffffffff,FALSE),
87
  HOWTO(R_68K_JMP_SLOT,   0, 2,32, FALSE,0, complain_overflow_dont,     bfd_elf_generic_reloc, "R_68K_JMP_SLOT",  FALSE, 0, 0xffffffff,FALSE),
88
  HOWTO(R_68K_RELATIVE,   0, 2,32, FALSE,0, complain_overflow_dont,     bfd_elf_generic_reloc, "R_68K_RELATIVE",  FALSE, 0, 0xffffffff,FALSE),
89
  /* GNU extension to record C++ vtable hierarchy.  */
90
  HOWTO (R_68K_GNU_VTINHERIT,   /* type */
91
         0,                      /* rightshift */
92
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
93
         0,                      /* bitsize */
94
         FALSE,                 /* pc_relative */
95
         0,                      /* bitpos */
96
         complain_overflow_dont, /* complain_on_overflow */
97
         NULL,                  /* special_function */
98
         "R_68K_GNU_VTINHERIT", /* name */
99
         FALSE,                 /* partial_inplace */
100
         0,                      /* src_mask */
101
         0,                      /* dst_mask */
102
         FALSE),
103
  /* GNU extension to record C++ vtable member usage.  */
104
  HOWTO (R_68K_GNU_VTENTRY,     /* type */
105
         0,                      /* rightshift */
106
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
107
         0,                      /* bitsize */
108
         FALSE,                 /* pc_relative */
109
         0,                      /* bitpos */
110
         complain_overflow_dont, /* complain_on_overflow */
111
         _bfd_elf_rel_vtable_reloc_fn, /* special_function */
112
         "R_68K_GNU_VTENTRY",   /* name */
113
         FALSE,                 /* partial_inplace */
114
         0,                      /* src_mask */
115
         0,                      /* dst_mask */
116
         FALSE),
117 225 jeremybenn
 
118
  /* TLS general dynamic variable reference.  */
119
  HOWTO (R_68K_TLS_GD32,        /* type */
120
         0,                      /* rightshift */
121
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
122
         32,                    /* bitsize */
123
         FALSE,                 /* pc_relative */
124
         0,                      /* bitpos */
125
         complain_overflow_bitfield, /* complain_on_overflow */
126
         bfd_elf_generic_reloc, /* special_function */
127
         "R_68K_TLS_GD32",      /* name */
128
         FALSE,                 /* partial_inplace */
129
         0,                      /* src_mask */
130
         0xffffffff,            /* dst_mask */
131
         FALSE),                /* pcrel_offset */
132
 
133
  HOWTO (R_68K_TLS_GD16,        /* type */
134
         0,                      /* rightshift */
135
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
136
         16,                    /* bitsize */
137
         FALSE,                 /* pc_relative */
138
         0,                      /* bitpos */
139
         complain_overflow_signed, /* complain_on_overflow */
140
         bfd_elf_generic_reloc, /* special_function */
141
         "R_68K_TLS_GD16",      /* name */
142
         FALSE,                 /* partial_inplace */
143
         0,                      /* src_mask */
144
         0x0000ffff,            /* dst_mask */
145
         FALSE),                /* pcrel_offset */
146
 
147
  HOWTO (R_68K_TLS_GD8,         /* type */
148
         0,                      /* rightshift */
149
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
150
         8,                     /* bitsize */
151
         FALSE,                 /* pc_relative */
152
         0,                      /* bitpos */
153
         complain_overflow_signed, /* complain_on_overflow */
154
         bfd_elf_generic_reloc, /* special_function */
155
         "R_68K_TLS_GD8",       /* name */
156
         FALSE,                 /* partial_inplace */
157
         0,                      /* src_mask */
158
         0x000000ff,            /* dst_mask */
159
         FALSE),                /* pcrel_offset */
160
 
161
  /* TLS local dynamic variable reference.  */
162
  HOWTO (R_68K_TLS_LDM32,       /* type */
163
         0,                      /* rightshift */
164
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
165
         32,                    /* bitsize */
166
         FALSE,                 /* pc_relative */
167
         0,                      /* bitpos */
168
         complain_overflow_bitfield, /* complain_on_overflow */
169
         bfd_elf_generic_reloc, /* special_function */
170
         "R_68K_TLS_LDM32",     /* name */
171
         FALSE,                 /* partial_inplace */
172
         0,                      /* src_mask */
173
         0xffffffff,            /* dst_mask */
174
         FALSE),                /* pcrel_offset */
175
 
176
  HOWTO (R_68K_TLS_LDM16,       /* type */
177
         0,                      /* rightshift */
178
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
179
         16,                    /* bitsize */
180
         FALSE,                 /* pc_relative */
181
         0,                      /* bitpos */
182
         complain_overflow_signed, /* complain_on_overflow */
183
         bfd_elf_generic_reloc, /* special_function */
184
         "R_68K_TLS_LDM16",     /* name */
185
         FALSE,                 /* partial_inplace */
186
         0,                      /* src_mask */
187
         0x0000ffff,            /* dst_mask */
188
         FALSE),                /* pcrel_offset */
189
 
190
  HOWTO (R_68K_TLS_LDM8,                /* type */
191
         0,                      /* rightshift */
192
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
193
         8,                     /* bitsize */
194
         FALSE,                 /* pc_relative */
195
         0,                      /* bitpos */
196
         complain_overflow_signed, /* complain_on_overflow */
197
         bfd_elf_generic_reloc, /* special_function */
198
         "R_68K_TLS_LDM8",      /* name */
199
         FALSE,                 /* partial_inplace */
200
         0,                      /* src_mask */
201
         0x000000ff,            /* dst_mask */
202
         FALSE),                /* pcrel_offset */
203
 
204
  HOWTO (R_68K_TLS_LDO32,       /* type */
205
         0,                      /* rightshift */
206
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
207
         32,                    /* bitsize */
208
         FALSE,                 /* pc_relative */
209
         0,                      /* bitpos */
210
         complain_overflow_bitfield, /* complain_on_overflow */
211
         bfd_elf_generic_reloc, /* special_function */
212
         "R_68K_TLS_LDO32",     /* name */
213
         FALSE,                 /* partial_inplace */
214
         0,                      /* src_mask */
215
         0xffffffff,            /* dst_mask */
216
         FALSE),                /* pcrel_offset */
217
 
218
  HOWTO (R_68K_TLS_LDO16,       /* type */
219
         0,                      /* rightshift */
220
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
221
         16,                    /* bitsize */
222
         FALSE,                 /* pc_relative */
223
         0,                      /* bitpos */
224
         complain_overflow_signed, /* complain_on_overflow */
225
         bfd_elf_generic_reloc, /* special_function */
226
         "R_68K_TLS_LDO16",     /* name */
227
         FALSE,                 /* partial_inplace */
228
         0,                      /* src_mask */
229
         0x0000ffff,            /* dst_mask */
230
         FALSE),                /* pcrel_offset */
231
 
232
  HOWTO (R_68K_TLS_LDO8,                /* type */
233
         0,                      /* rightshift */
234
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
235
         8,                     /* bitsize */
236
         FALSE,                 /* pc_relative */
237
         0,                      /* bitpos */
238
         complain_overflow_signed, /* complain_on_overflow */
239
         bfd_elf_generic_reloc, /* special_function */
240
         "R_68K_TLS_LDO8",      /* name */
241
         FALSE,                 /* partial_inplace */
242
         0,                      /* src_mask */
243
         0x000000ff,            /* dst_mask */
244
         FALSE),                /* pcrel_offset */
245
 
246
  /* TLS initial execution variable reference.  */
247
  HOWTO (R_68K_TLS_IE32,        /* type */
248
         0,                      /* rightshift */
249
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
250
         32,                    /* bitsize */
251
         FALSE,                 /* pc_relative */
252
         0,                      /* bitpos */
253
         complain_overflow_bitfield, /* complain_on_overflow */
254
         bfd_elf_generic_reloc, /* special_function */
255
         "R_68K_TLS_IE32",      /* name */
256
         FALSE,                 /* partial_inplace */
257
         0,                      /* src_mask */
258
         0xffffffff,            /* dst_mask */
259
         FALSE),                /* pcrel_offset */
260
 
261
  HOWTO (R_68K_TLS_IE16,        /* type */
262
         0,                      /* rightshift */
263
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
264
         16,                    /* bitsize */
265
         FALSE,                 /* pc_relative */
266
         0,                      /* bitpos */
267
         complain_overflow_signed, /* complain_on_overflow */
268
         bfd_elf_generic_reloc, /* special_function */
269
         "R_68K_TLS_IE16",      /* name */
270
         FALSE,                 /* partial_inplace */
271
         0,                      /* src_mask */
272
         0x0000ffff,            /* dst_mask */
273
         FALSE),                /* pcrel_offset */
274
 
275
  HOWTO (R_68K_TLS_IE8,         /* type */
276
         0,                      /* rightshift */
277
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
278
         8,                     /* bitsize */
279
         FALSE,                 /* pc_relative */
280
         0,                      /* bitpos */
281
         complain_overflow_signed, /* complain_on_overflow */
282
         bfd_elf_generic_reloc, /* special_function */
283
         "R_68K_TLS_IE8",       /* name */
284
         FALSE,                 /* partial_inplace */
285
         0,                      /* src_mask */
286
         0x000000ff,            /* dst_mask */
287
         FALSE),                /* pcrel_offset */
288
 
289
  /* TLS local execution variable reference.  */
290
  HOWTO (R_68K_TLS_LE32,        /* type */
291
         0,                      /* rightshift */
292
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
293
         32,                    /* bitsize */
294
         FALSE,                 /* pc_relative */
295
         0,                      /* bitpos */
296
         complain_overflow_bitfield, /* complain_on_overflow */
297
         bfd_elf_generic_reloc, /* special_function */
298
         "R_68K_TLS_LE32",      /* name */
299
         FALSE,                 /* partial_inplace */
300
         0,                      /* src_mask */
301
         0xffffffff,            /* dst_mask */
302
         FALSE),                /* pcrel_offset */
303
 
304
  HOWTO (R_68K_TLS_LE16,        /* type */
305
         0,                      /* rightshift */
306
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
307
         16,                    /* bitsize */
308
         FALSE,                 /* pc_relative */
309
         0,                      /* bitpos */
310
         complain_overflow_signed, /* complain_on_overflow */
311
         bfd_elf_generic_reloc, /* special_function */
312
         "R_68K_TLS_LE16",      /* name */
313
         FALSE,                 /* partial_inplace */
314
         0,                      /* src_mask */
315
         0x0000ffff,            /* dst_mask */
316
         FALSE),                /* pcrel_offset */
317
 
318
  HOWTO (R_68K_TLS_LE8,         /* type */
319
         0,                      /* rightshift */
320
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
321
         8,                     /* bitsize */
322
         FALSE,                 /* pc_relative */
323
         0,                      /* bitpos */
324
         complain_overflow_signed, /* complain_on_overflow */
325
         bfd_elf_generic_reloc, /* special_function */
326
         "R_68K_TLS_LE8",       /* name */
327
         FALSE,                 /* partial_inplace */
328
         0,                      /* src_mask */
329
         0x000000ff,            /* dst_mask */
330
         FALSE),                /* pcrel_offset */
331
 
332
  /* TLS GD/LD dynamic relocations.  */
333
  HOWTO (R_68K_TLS_DTPMOD32,    /* type */
334
         0,                      /* rightshift */
335
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
336
         32,                    /* bitsize */
337
         FALSE,                 /* pc_relative */
338
         0,                      /* bitpos */
339
         complain_overflow_dont, /* complain_on_overflow */
340
         bfd_elf_generic_reloc, /* special_function */
341
         "R_68K_TLS_DTPMOD32",  /* name */
342
         FALSE,                 /* partial_inplace */
343
         0,                      /* src_mask */
344
         0xffffffff,            /* dst_mask */
345
         FALSE),                /* pcrel_offset */
346
 
347
  HOWTO (R_68K_TLS_DTPREL32,    /* type */
348
         0,                      /* rightshift */
349
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
350
         32,                    /* bitsize */
351
         FALSE,                 /* pc_relative */
352
         0,                      /* bitpos */
353
         complain_overflow_dont, /* complain_on_overflow */
354
         bfd_elf_generic_reloc, /* special_function */
355
         "R_68K_TLS_DTPREL32",  /* name */
356
         FALSE,                 /* partial_inplace */
357
         0,                      /* src_mask */
358
         0xffffffff,            /* dst_mask */
359
         FALSE),                /* pcrel_offset */
360
 
361
  HOWTO (R_68K_TLS_TPREL32,     /* type */
362
         0,                      /* rightshift */
363
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
364
         32,                    /* bitsize */
365
         FALSE,                 /* pc_relative */
366
         0,                      /* bitpos */
367
         complain_overflow_dont, /* complain_on_overflow */
368
         bfd_elf_generic_reloc, /* special_function */
369
         "R_68K_TLS_TPREL32",   /* name */
370
         FALSE,                 /* partial_inplace */
371
         0,                      /* src_mask */
372
         0xffffffff,            /* dst_mask */
373
         FALSE),                /* pcrel_offset */
374 24 jeremybenn
};
375
 
376
static void
377
rtype_to_howto (abfd, cache_ptr, dst)
378
     bfd *abfd ATTRIBUTE_UNUSED;
379
     arelent *cache_ptr;
380
     Elf_Internal_Rela *dst;
381
{
382
  BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_68K_max);
383
  cache_ptr->howto = &howto_table[ELF32_R_TYPE(dst->r_info)];
384
}
385
 
386
#define elf_info_to_howto rtype_to_howto
387
 
388
static const struct
389
{
390
  bfd_reloc_code_real_type bfd_val;
391
  int elf_val;
392 225 jeremybenn
}
393
  reloc_map[] =
394
{
395 24 jeremybenn
  { BFD_RELOC_NONE, R_68K_NONE },
396
  { BFD_RELOC_32, R_68K_32 },
397
  { BFD_RELOC_16, R_68K_16 },
398
  { BFD_RELOC_8, R_68K_8 },
399
  { BFD_RELOC_32_PCREL, R_68K_PC32 },
400
  { BFD_RELOC_16_PCREL, R_68K_PC16 },
401
  { BFD_RELOC_8_PCREL, R_68K_PC8 },
402
  { BFD_RELOC_32_GOT_PCREL, R_68K_GOT32 },
403
  { BFD_RELOC_16_GOT_PCREL, R_68K_GOT16 },
404
  { BFD_RELOC_8_GOT_PCREL, R_68K_GOT8 },
405
  { BFD_RELOC_32_GOTOFF, R_68K_GOT32O },
406
  { BFD_RELOC_16_GOTOFF, R_68K_GOT16O },
407
  { BFD_RELOC_8_GOTOFF, R_68K_GOT8O },
408
  { BFD_RELOC_32_PLT_PCREL, R_68K_PLT32 },
409
  { BFD_RELOC_16_PLT_PCREL, R_68K_PLT16 },
410
  { BFD_RELOC_8_PLT_PCREL, R_68K_PLT8 },
411
  { BFD_RELOC_32_PLTOFF, R_68K_PLT32O },
412
  { BFD_RELOC_16_PLTOFF, R_68K_PLT16O },
413
  { BFD_RELOC_8_PLTOFF, R_68K_PLT8O },
414
  { BFD_RELOC_NONE, R_68K_COPY },
415
  { BFD_RELOC_68K_GLOB_DAT, R_68K_GLOB_DAT },
416
  { BFD_RELOC_68K_JMP_SLOT, R_68K_JMP_SLOT },
417
  { BFD_RELOC_68K_RELATIVE, R_68K_RELATIVE },
418
  { BFD_RELOC_CTOR, R_68K_32 },
419
  { BFD_RELOC_VTABLE_INHERIT, R_68K_GNU_VTINHERIT },
420
  { BFD_RELOC_VTABLE_ENTRY, R_68K_GNU_VTENTRY },
421 225 jeremybenn
  { BFD_RELOC_68K_TLS_GD32, R_68K_TLS_GD32 },
422
  { BFD_RELOC_68K_TLS_GD16, R_68K_TLS_GD16 },
423
  { BFD_RELOC_68K_TLS_GD8, R_68K_TLS_GD8 },
424
  { BFD_RELOC_68K_TLS_LDM32, R_68K_TLS_LDM32 },
425
  { BFD_RELOC_68K_TLS_LDM16, R_68K_TLS_LDM16 },
426
  { BFD_RELOC_68K_TLS_LDM8, R_68K_TLS_LDM8 },
427
  { BFD_RELOC_68K_TLS_LDO32, R_68K_TLS_LDO32 },
428
  { BFD_RELOC_68K_TLS_LDO16, R_68K_TLS_LDO16 },
429
  { BFD_RELOC_68K_TLS_LDO8, R_68K_TLS_LDO8 },
430
  { BFD_RELOC_68K_TLS_IE32, R_68K_TLS_IE32 },
431
  { BFD_RELOC_68K_TLS_IE16, R_68K_TLS_IE16 },
432
  { BFD_RELOC_68K_TLS_IE8, R_68K_TLS_IE8 },
433
  { BFD_RELOC_68K_TLS_LE32, R_68K_TLS_LE32 },
434
  { BFD_RELOC_68K_TLS_LE16, R_68K_TLS_LE16 },
435
  { BFD_RELOC_68K_TLS_LE8, R_68K_TLS_LE8 },
436 24 jeremybenn
};
437
 
438
static reloc_howto_type *
439
reloc_type_lookup (abfd, code)
440
     bfd *abfd ATTRIBUTE_UNUSED;
441
     bfd_reloc_code_real_type code;
442
{
443
  unsigned int i;
444
  for (i = 0; i < sizeof (reloc_map) / sizeof (reloc_map[0]); i++)
445
    {
446
      if (reloc_map[i].bfd_val == code)
447
        return &howto_table[reloc_map[i].elf_val];
448
    }
449
  return 0;
450
}
451
 
452
static reloc_howto_type *
453
reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
454
{
455
  unsigned int i;
456
 
457
  for (i = 0; i < sizeof (howto_table) / sizeof (howto_table[0]); i++)
458
    if (howto_table[i].name != NULL
459
        && strcasecmp (howto_table[i].name, r_name) == 0)
460
      return &howto_table[i];
461
 
462
  return NULL;
463
}
464
 
465
#define bfd_elf32_bfd_reloc_type_lookup reloc_type_lookup
466
#define bfd_elf32_bfd_reloc_name_lookup reloc_name_lookup
467
#define ELF_ARCH bfd_arch_m68k
468
 
469
/* Functions for the m68k ELF linker.  */
470
 
471
/* The name of the dynamic interpreter.  This is put in the .interp
472
   section.  */
473
 
474
#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
475
 
476
/* Describes one of the various PLT styles.  */
477
 
478
struct elf_m68k_plt_info
479
{
480
  /* The size of each PLT entry.  */
481
  bfd_vma size;
482
 
483
  /* The template for the first PLT entry.  */
484
  const bfd_byte *plt0_entry;
485
 
486
  /* Offsets of fields in PLT0_ENTRY that require R_68K_PC32 relocations.
487
     The comments by each member indicate the value that the relocation
488
     is against.  */
489
  struct {
490
    unsigned int got4; /* .got + 4 */
491
    unsigned int got8; /* .got + 8 */
492
  } plt0_relocs;
493
 
494
  /* The template for a symbol's PLT entry.  */
495
  const bfd_byte *symbol_entry;
496
 
497
  /* Offsets of fields in SYMBOL_ENTRY that require R_68K_PC32 relocations.
498
     The comments by each member indicate the value that the relocation
499
     is against.  */
500
  struct {
501
    unsigned int got; /* the symbol's .got.plt entry */
502
    unsigned int plt; /* .plt */
503
  } symbol_relocs;
504
 
505
  /* The offset of the resolver stub from the start of SYMBOL_ENTRY.
506
     The stub starts with "move.l #relocoffset,%d0".  */
507
  bfd_vma symbol_resolve_entry;
508
};
509
 
510
/* The size in bytes of an entry in the procedure linkage table.  */
511
 
512
#define PLT_ENTRY_SIZE 20
513
 
514
/* The first entry in a procedure linkage table looks like this.  See
515
   the SVR4 ABI m68k supplement to see how this works.  */
516
 
517
static const bfd_byte elf_m68k_plt0_entry[PLT_ENTRY_SIZE] =
518
{
519
  0x2f, 0x3b, 0x01, 0x70, /* move.l (%pc,addr),-(%sp) */
520
  0, 0, 0, 2,                /* + (.got + 4) - . */
521
  0x4e, 0xfb, 0x01, 0x71, /* jmp ([%pc,addr]) */
522
  0, 0, 0, 2,                /* + (.got + 8) - . */
523
  0, 0, 0, 0                  /* pad out to 20 bytes.  */
524
};
525
 
526
/* Subsequent entries in a procedure linkage table look like this.  */
527
 
528
static const bfd_byte elf_m68k_plt_entry[PLT_ENTRY_SIZE] =
529
{
530
  0x4e, 0xfb, 0x01, 0x71, /* jmp ([%pc,symbol@GOTPC]) */
531
  0, 0, 0, 2,                /* + (.got.plt entry) - . */
532
  0x2f, 0x3c,             /* move.l #offset,-(%sp) */
533
  0, 0, 0, 0,                 /* + reloc index */
534
  0x60, 0xff,             /* bra.l .plt */
535
  0, 0, 0, 0                  /* + .plt - . */
536
};
537
 
538
static const struct elf_m68k_plt_info elf_m68k_plt_info = {
539
  PLT_ENTRY_SIZE,
540
  elf_m68k_plt0_entry, { 4, 12 },
541
  elf_m68k_plt_entry, { 4, 16 }, 8
542
};
543
 
544 225 jeremybenn
#define ISAB_PLT_ENTRY_SIZE 24
545 24 jeremybenn
 
546
static const bfd_byte elf_isab_plt0_entry[ISAB_PLT_ENTRY_SIZE] =
547
{
548
  0x20, 0x3c,             /* move.l #offset,%d0 */
549
  0, 0, 0, 0,             /* + (.got + 4) - . */
550
  0x2f, 0x3b, 0x08, 0xfa, /* move.l (-6,%pc,%d0:l),-(%sp) */
551
  0x20, 0x3c,             /* move.l #offset,%d0 */
552
  0, 0, 0, 0,             /* + (.got + 8) - . */
553
  0x20, 0x7b, 0x08, 0xfa, /* move.l (-6,%pc,%d0:l), %a0 */
554
  0x4e, 0xd0,             /* jmp (%a0) */
555
  0x4e, 0x71              /* nop */
556
};
557
 
558
/* Subsequent entries in a procedure linkage table look like this.  */
559
 
560
static const bfd_byte elf_isab_plt_entry[ISAB_PLT_ENTRY_SIZE] =
561
{
562
  0x20, 0x3c,             /* move.l #offset,%d0 */
563
  0, 0, 0, 0,             /* + (.got.plt entry) - . */
564
  0x20, 0x7b, 0x08, 0xfa, /* move.l (-6,%pc,%d0:l), %a0 */
565
  0x4e, 0xd0,             /* jmp (%a0) */
566
  0x2f, 0x3c,             /* move.l #offset,-(%sp) */
567
  0, 0, 0, 0,             /* + reloc index */
568
  0x60, 0xff,             /* bra.l .plt */
569
  0, 0, 0, 0              /* + .plt - . */
570
};
571
 
572
static const struct elf_m68k_plt_info elf_isab_plt_info = {
573
  ISAB_PLT_ENTRY_SIZE,
574
  elf_isab_plt0_entry, { 2, 12 },
575
  elf_isab_plt_entry, { 2, 20 }, 12
576
};
577
 
578 225 jeremybenn
#define ISAC_PLT_ENTRY_SIZE 24
579 24 jeremybenn
 
580
static const bfd_byte elf_isac_plt0_entry[ISAC_PLT_ENTRY_SIZE] =
581
{
582
  0x20, 0x3c,             /* move.l #offset,%d0 */
583
  0, 0, 0, 0,                 /* replaced with .got + 4 - . */
584
  0x2e, 0xbb, 0x08, 0xfa, /* move.l (-6,%pc,%d0:l),(%sp) */
585
  0x20, 0x3c,             /* move.l #offset,%d0 */
586
  0, 0, 0, 0,                 /* replaced with .got + 8 - . */
587
  0x20, 0x7b, 0x08, 0xfa, /* move.l (-6,%pc,%d0:l), %a0 */
588
  0x4e, 0xd0,             /* jmp (%a0) */
589
  0x4e, 0x71              /* nop */
590
};
591
 
592
/* Subsequent entries in a procedure linkage table look like this.  */
593
 
594
static const bfd_byte elf_isac_plt_entry[ISAC_PLT_ENTRY_SIZE] =
595
{
596
  0x20, 0x3c,             /* move.l #offset,%d0 */
597
  0, 0, 0, 0,                 /* replaced with (.got entry) - . */
598
  0x20, 0x7b, 0x08, 0xfa, /* move.l (-6,%pc,%d0:l), %a0 */
599
  0x4e, 0xd0,             /* jmp (%a0) */
600
  0x2f, 0x3c,             /* move.l #offset,-(%sp) */
601
  0, 0, 0, 0,                 /* replaced with offset into relocation table */
602
  0x61, 0xff,             /* bsr.l .plt */
603
  0, 0, 0, 0                  /* replaced with .plt - . */
604
};
605
 
606
static const struct elf_m68k_plt_info elf_isac_plt_info = {
607
  ISAC_PLT_ENTRY_SIZE,
608
  elf_isac_plt0_entry, { 2, 12},
609
  elf_isac_plt_entry, { 2, 20 }, 12
610
};
611
 
612
#define CPU32_PLT_ENTRY_SIZE 24
613
/* Procedure linkage table entries for the cpu32 */
614
static const bfd_byte elf_cpu32_plt0_entry[CPU32_PLT_ENTRY_SIZE] =
615
{
616
  0x2f, 0x3b, 0x01, 0x70, /* move.l (%pc,addr),-(%sp) */
617
  0, 0, 0, 2,             /* + (.got + 4) - . */
618
  0x22, 0x7b, 0x01, 0x70, /* moveal %pc@(0xc), %a1 */
619
  0, 0, 0, 2,             /* + (.got + 8) - . */
620
  0x4e, 0xd1,             /* jmp %a1@ */
621
  0, 0, 0, 0,             /* pad out to 24 bytes.  */
622
  0, 0
623
};
624
 
625
static const bfd_byte elf_cpu32_plt_entry[CPU32_PLT_ENTRY_SIZE] =
626
{
627
  0x22, 0x7b, 0x01, 0x70,  /* moveal %pc@(0xc), %a1 */
628
  0, 0, 0, 2,              /* + (.got.plt entry) - . */
629
  0x4e, 0xd1,              /* jmp %a1@ */
630
  0x2f, 0x3c,              /* move.l #offset,-(%sp) */
631
  0, 0, 0, 0,              /* + reloc index */
632
  0x60, 0xff,              /* bra.l .plt */
633
  0, 0, 0, 0,              /* + .plt - . */
634
  0, 0
635
};
636
 
637
static const struct elf_m68k_plt_info elf_cpu32_plt_info = {
638
  CPU32_PLT_ENTRY_SIZE,
639
  elf_cpu32_plt0_entry, { 4, 12 },
640
  elf_cpu32_plt_entry, { 4, 18 }, 10
641
};
642
 
643
/* The m68k linker needs to keep track of the number of relocs that it
644
   decides to copy in check_relocs for each symbol.  This is so that it
645
   can discard PC relative relocs if it doesn't need them when linking
646
   with -Bsymbolic.  We store the information in a field extending the
647
   regular ELF linker hash table.  */
648
 
649
/* This structure keeps track of the number of PC relative relocs we have
650
   copied for a given symbol.  */
651
 
652
struct elf_m68k_pcrel_relocs_copied
653
{
654
  /* Next section.  */
655
  struct elf_m68k_pcrel_relocs_copied *next;
656
  /* A section in dynobj.  */
657
  asection *section;
658
  /* Number of relocs copied in this section.  */
659
  bfd_size_type count;
660
};
661
 
662 225 jeremybenn
/* Forward declaration.  */
663
struct elf_m68k_got_entry;
664
 
665 24 jeremybenn
/* m68k ELF linker hash entry.  */
666
 
667
struct elf_m68k_link_hash_entry
668
{
669
  struct elf_link_hash_entry root;
670
 
671
  /* Number of PC relative relocs copied for this symbol.  */
672
  struct elf_m68k_pcrel_relocs_copied *pcrel_relocs_copied;
673 225 jeremybenn
 
674
  /* Key to got_entries.  */
675
  unsigned long got_entry_key;
676
 
677
  /* List of GOT entries for this symbol.  This list is build during
678
     offset finalization and is used within elf_m68k_finish_dynamic_symbol
679
     to traverse all GOT entries for a particular symbol.
680
 
681
     ??? We could've used root.got.glist field instead, but having
682
     a separate field is cleaner.  */
683
  struct elf_m68k_got_entry *glist;
684 24 jeremybenn
};
685
 
686
#define elf_m68k_hash_entry(ent) ((struct elf_m68k_link_hash_entry *) (ent))
687
 
688 225 jeremybenn
/* Key part of GOT entry in hashtable.  */
689
struct elf_m68k_got_entry_key
690
{
691
  /* BFD in which this symbol was defined.  NULL for global symbols.  */
692
  const bfd *bfd;
693
 
694
  /* Symbol index.  Either local symbol index or h->got_entry_key.  */
695
  unsigned long symndx;
696
 
697
  /* Type is one of R_68K_GOT{8, 16, 32}O, R_68K_TLS_GD{8, 16, 32},
698
     R_68K_TLS_LDM{8, 16, 32} or R_68K_TLS_IE{8, 16, 32}.
699
 
700
     From perspective of hashtable key, only elf_m68k_got_reloc_type (type)
701
     matters.  That is, we distinguish between, say, R_68K_GOT16O
702
     and R_68K_GOT32O when allocating offsets, but they are considered to be
703
     the same when searching got->entries.  */
704
  enum elf_m68k_reloc_type type;
705
};
706
 
707
/* Size of the GOT offset suitable for relocation.  */
708
enum elf_m68k_got_offset_size { R_8, R_16, R_32, R_LAST };
709
 
710
/* Entry of the GOT.  */
711
struct elf_m68k_got_entry
712
{
713
  /* GOT entries are put into a got->entries hashtable.  This is the key.  */
714
  struct elf_m68k_got_entry_key key_;
715
 
716
  /* GOT entry data.  We need s1 before offset finalization and s2 after.  */
717
  union
718
  {
719
    struct
720
    {
721
      /* Number of times this entry is referenced.  It is used to
722
         filter out unnecessary GOT slots in elf_m68k_gc_sweep_hook.  */
723
      bfd_vma refcount;
724
    } s1;
725
 
726
    struct
727
    {
728
      /* Offset from the start of .got section.  To calculate offset relative
729
         to GOT pointer one should substract got->offset from this value.  */
730
      bfd_vma offset;
731
 
732
      /* Pointer to the next GOT entry for this global symbol.
733
         Symbols have at most one entry in one GOT, but might
734
         have entries in more than one GOT.
735
         Root of this list is h->glist.
736
         NULL for local symbols.  */
737
      struct elf_m68k_got_entry *next;
738
    } s2;
739
  } u;
740
};
741
 
742
/* Return representative type for relocation R_TYPE.
743
   This is used to avoid enumerating many relocations in comparisons,
744
   switches etc.  */
745
 
746
static enum elf_m68k_reloc_type
747
elf_m68k_reloc_got_type (enum elf_m68k_reloc_type r_type)
748
{
749
  switch (r_type)
750
    {
751
      /* In most cases R_68K_GOTx relocations require the very same
752
         handling as R_68K_GOT32O relocation.  In cases when we need
753
         to distinguish between the two, we use explicitly compare against
754
         r_type.  */
755
    case R_68K_GOT32:
756
    case R_68K_GOT16:
757
    case R_68K_GOT8:
758
    case R_68K_GOT32O:
759
    case R_68K_GOT16O:
760
    case R_68K_GOT8O:
761
      return R_68K_GOT32O;
762
 
763
    case R_68K_TLS_GD32:
764
    case R_68K_TLS_GD16:
765
    case R_68K_TLS_GD8:
766
      return R_68K_TLS_GD32;
767
 
768
    case R_68K_TLS_LDM32:
769
    case R_68K_TLS_LDM16:
770
    case R_68K_TLS_LDM8:
771
      return R_68K_TLS_LDM32;
772
 
773
    case R_68K_TLS_IE32:
774
    case R_68K_TLS_IE16:
775
    case R_68K_TLS_IE8:
776
      return R_68K_TLS_IE32;
777
 
778
    default:
779
      BFD_ASSERT (FALSE);
780
      return 0;
781
    }
782
}
783
 
784
/* Return size of the GOT entry offset for relocation R_TYPE.  */
785
 
786
static enum elf_m68k_got_offset_size
787
elf_m68k_reloc_got_offset_size (enum elf_m68k_reloc_type r_type)
788
{
789
  switch (r_type)
790
    {
791
    case R_68K_GOT32: case R_68K_GOT16: case R_68K_GOT8:
792
    case R_68K_GOT32O: case R_68K_TLS_GD32: case R_68K_TLS_LDM32:
793
    case R_68K_TLS_IE32:
794
      return R_32;
795
 
796
    case R_68K_GOT16O: case R_68K_TLS_GD16: case R_68K_TLS_LDM16:
797
    case R_68K_TLS_IE16:
798
      return R_16;
799
 
800
    case R_68K_GOT8O: case R_68K_TLS_GD8: case R_68K_TLS_LDM8:
801
    case R_68K_TLS_IE8:
802
      return R_8;
803
 
804
    default:
805
      BFD_ASSERT (FALSE);
806
      return 0;
807
    }
808
}
809
 
810
/* Return number of GOT entries we need to allocate in GOT for
811
   relocation R_TYPE.  */
812
 
813
static bfd_vma
814
elf_m68k_reloc_got_n_slots (enum elf_m68k_reloc_type r_type)
815
{
816
  switch (elf_m68k_reloc_got_type (r_type))
817
    {
818
    case R_68K_GOT32O:
819
    case R_68K_TLS_IE32:
820
      return 1;
821
 
822
    case R_68K_TLS_GD32:
823
    case R_68K_TLS_LDM32:
824
      return 2;
825
 
826
    default:
827
      BFD_ASSERT (FALSE);
828
      return 0;
829
    }
830
}
831
 
832
/* Return TRUE if relocation R_TYPE is a TLS one.  */
833
 
834
static bfd_boolean
835
elf_m68k_reloc_tls_p (enum elf_m68k_reloc_type r_type)
836
{
837
  switch (r_type)
838
    {
839
    case R_68K_TLS_GD32: case R_68K_TLS_GD16: case R_68K_TLS_GD8:
840
    case R_68K_TLS_LDM32: case R_68K_TLS_LDM16: case R_68K_TLS_LDM8:
841
    case R_68K_TLS_LDO32: case R_68K_TLS_LDO16: case R_68K_TLS_LDO8:
842
    case R_68K_TLS_IE32: case R_68K_TLS_IE16: case R_68K_TLS_IE8:
843
    case R_68K_TLS_LE32: case R_68K_TLS_LE16: case R_68K_TLS_LE8:
844
    case R_68K_TLS_DTPMOD32: case R_68K_TLS_DTPREL32: case R_68K_TLS_TPREL32:
845
      return TRUE;
846
 
847
    default:
848
      return FALSE;
849
    }
850
}
851
 
852
/* Data structure representing a single GOT.  */
853
struct elf_m68k_got
854
{
855
  /* Hashtable of 'struct elf_m68k_got_entry's.
856
     Starting size of this table is the maximum number of
857
     R_68K_GOT8O entries.  */
858
  htab_t entries;
859
 
860
  /* Number of R_x slots in this GOT.  Some (e.g., TLS) entries require
861
     several GOT slots.
862
 
863
     n_slots[R_8] is the count of R_8 slots in this GOT.
864
     n_slots[R_16] is the cumulative count of R_8 and R_16 slots
865
     in this GOT.
866
     n_slots[R_32] is the cumulative count of R_8, R_16 and R_32 slots
867
     in this GOT.  This is the total number of slots.  */
868
  bfd_vma n_slots[R_LAST];
869
 
870
  /* Number of local (entry->key_.h == NULL) slots in this GOT.
871
     This is only used to properly calculate size of .rela.got section;
872
     see elf_m68k_partition_multi_got.  */
873
  bfd_vma local_n_slots;
874
 
875
  /* Offset of this GOT relative to beginning of .got section.  */
876
  bfd_vma offset;
877
};
878
 
879
/* BFD and its GOT.  This is an entry in multi_got->bfd2got hashtable.  */
880
struct elf_m68k_bfd2got_entry
881
{
882
  /* BFD.  */
883
  const bfd *bfd;
884
 
885
  /* Assigned GOT.  Before partitioning multi-GOT each BFD has its own
886
     GOT structure.  After partitioning several BFD's might [and often do]
887
     share a single GOT.  */
888
  struct elf_m68k_got *got;
889
};
890
 
891
/* The main data structure holding all the pieces.  */
892
struct elf_m68k_multi_got
893
{
894
  /* Hashtable mapping each BFD to its GOT.  If a BFD doesn't have an entry
895
     here, then it doesn't need a GOT (this includes the case of a BFD
896
     having an empty GOT).
897
 
898
     ??? This hashtable can be replaced by an array indexed by bfd->id.  */
899
  htab_t bfd2got;
900
 
901
  /* Next symndx to assign a global symbol.
902
     h->got_entry_key is initialized from this counter.  */
903
  unsigned long global_symndx;
904
};
905
 
906 24 jeremybenn
/* m68k ELF linker hash table.  */
907
 
908
struct elf_m68k_link_hash_table
909
{
910
  struct elf_link_hash_table root;
911
 
912 225 jeremybenn
  /* Small local sym cache.  */
913
  struct sym_cache sym_cache;
914 24 jeremybenn
 
915
  /* The PLT format used by this link, or NULL if the format has not
916
     yet been chosen.  */
917
  const struct elf_m68k_plt_info *plt_info;
918 225 jeremybenn
 
919
  /* True, if GP is loaded within each function which uses it.
920
     Set to TRUE when GOT negative offsets or multi-GOT is enabled.  */
921
  bfd_boolean local_gp_p;
922
 
923
  /* Switch controlling use of negative offsets to double the size of GOTs.  */
924
  bfd_boolean use_neg_got_offsets_p;
925
 
926
  /* Switch controlling generation of multiple GOTs.  */
927
  bfd_boolean allow_multigot_p;
928
 
929
  /* Multi-GOT data structure.  */
930
  struct elf_m68k_multi_got multi_got_;
931 24 jeremybenn
};
932
 
933
/* Get the m68k ELF linker hash table from a link_info structure.  */
934
 
935
#define elf_m68k_hash_table(p) \
936
  ((struct elf_m68k_link_hash_table *) (p)->hash)
937
 
938 225 jeremybenn
/* Shortcut to multi-GOT data.  */
939
#define elf_m68k_multi_got(INFO) (&elf_m68k_hash_table (INFO)->multi_got_)
940
 
941 24 jeremybenn
/* Create an entry in an m68k ELF linker hash table.  */
942
 
943
static struct bfd_hash_entry *
944
elf_m68k_link_hash_newfunc (entry, table, string)
945
     struct bfd_hash_entry *entry;
946
     struct bfd_hash_table *table;
947
     const char *string;
948
{
949
  struct bfd_hash_entry *ret = entry;
950
 
951
  /* Allocate the structure if it has not already been allocated by a
952
     subclass.  */
953
  if (ret == NULL)
954
    ret = bfd_hash_allocate (table,
955
                             sizeof (struct elf_m68k_link_hash_entry));
956
  if (ret == NULL)
957
    return ret;
958
 
959
  /* Call the allocation method of the superclass.  */
960
  ret = _bfd_elf_link_hash_newfunc (ret, table, string);
961
  if (ret != NULL)
962 225 jeremybenn
    {
963
      elf_m68k_hash_entry (ret)->pcrel_relocs_copied = NULL;
964
      elf_m68k_hash_entry (ret)->got_entry_key = 0;
965
      elf_m68k_hash_entry (ret)->glist = NULL;
966
    }
967 24 jeremybenn
 
968
  return ret;
969
}
970
 
971
/* Create an m68k ELF linker hash table.  */
972
 
973
static struct bfd_link_hash_table *
974
elf_m68k_link_hash_table_create (abfd)
975
     bfd *abfd;
976
{
977
  struct elf_m68k_link_hash_table *ret;
978
  bfd_size_type amt = sizeof (struct elf_m68k_link_hash_table);
979
 
980
  ret = (struct elf_m68k_link_hash_table *) bfd_malloc (amt);
981
  if (ret == (struct elf_m68k_link_hash_table *) NULL)
982
    return NULL;
983
 
984
  if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
985
                                      elf_m68k_link_hash_newfunc,
986
                                      sizeof (struct elf_m68k_link_hash_entry)))
987
    {
988
      free (ret);
989
      return NULL;
990
    }
991
 
992 225 jeremybenn
  ret->sym_cache.abfd = NULL;
993 24 jeremybenn
  ret->plt_info = NULL;
994 225 jeremybenn
  ret->local_gp_p = FALSE;
995
  ret->use_neg_got_offsets_p = FALSE;
996
  ret->allow_multigot_p = FALSE;
997
  ret->multi_got_.bfd2got = NULL;
998
  ret->multi_got_.global_symndx = 1;
999 24 jeremybenn
 
1000
  return &ret->root.root;
1001
}
1002
 
1003 225 jeremybenn
/* Destruct local data.  */
1004
 
1005
static void
1006
elf_m68k_link_hash_table_free (struct bfd_link_hash_table *_htab)
1007
{
1008
  struct elf_m68k_link_hash_table *htab;
1009
 
1010
  htab = (struct elf_m68k_link_hash_table *) _htab;
1011
 
1012
  if (htab->multi_got_.bfd2got != NULL)
1013
    {
1014
      htab_delete (htab->multi_got_.bfd2got);
1015
      htab->multi_got_.bfd2got = NULL;
1016
    }
1017
}
1018
 
1019 24 jeremybenn
/* Set the right machine number.  */
1020
 
1021
static bfd_boolean
1022
elf32_m68k_object_p (bfd *abfd)
1023
{
1024
  unsigned int mach = 0;
1025
  unsigned features = 0;
1026
  flagword eflags = elf_elfheader (abfd)->e_flags;
1027
 
1028
  if ((eflags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
1029
    features |= m68000;
1030
  else if ((eflags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
1031
    features |= cpu32;
1032
  else if ((eflags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
1033
    features |= fido_a;
1034
  else
1035
    {
1036
      switch (eflags & EF_M68K_CF_ISA_MASK)
1037
        {
1038
        case EF_M68K_CF_ISA_A_NODIV:
1039
          features |= mcfisa_a;
1040
          break;
1041
        case EF_M68K_CF_ISA_A:
1042
          features |= mcfisa_a|mcfhwdiv;
1043
          break;
1044
        case EF_M68K_CF_ISA_A_PLUS:
1045
          features |= mcfisa_a|mcfisa_aa|mcfhwdiv|mcfusp;
1046
          break;
1047
        case EF_M68K_CF_ISA_B_NOUSP:
1048
          features |= mcfisa_a|mcfisa_b|mcfhwdiv;
1049
          break;
1050
        case EF_M68K_CF_ISA_B:
1051
          features |= mcfisa_a|mcfisa_b|mcfhwdiv|mcfusp;
1052
          break;
1053
        case EF_M68K_CF_ISA_C:
1054
          features |= mcfisa_a|mcfisa_c|mcfhwdiv|mcfusp;
1055
          break;
1056
        case EF_M68K_CF_ISA_C_NODIV:
1057
          features |= mcfisa_a|mcfisa_c|mcfusp;
1058
          break;
1059
        }
1060
      switch (eflags & EF_M68K_CF_MAC_MASK)
1061
        {
1062
        case EF_M68K_CF_MAC:
1063
          features |= mcfmac;
1064
          break;
1065
        case EF_M68K_CF_EMAC:
1066
          features |= mcfemac;
1067
          break;
1068
        }
1069
      if (eflags & EF_M68K_CF_FLOAT)
1070
        features |= cfloat;
1071
    }
1072
 
1073
  mach = bfd_m68k_features_to_mach (features);
1074
  bfd_default_set_arch_mach (abfd, bfd_arch_m68k, mach);
1075
 
1076
  return TRUE;
1077
}
1078
 
1079
/* Keep m68k-specific flags in the ELF header.  */
1080
static bfd_boolean
1081
elf32_m68k_set_private_flags (abfd, flags)
1082
     bfd *abfd;
1083
     flagword flags;
1084
{
1085
  elf_elfheader (abfd)->e_flags = flags;
1086
  elf_flags_init (abfd) = TRUE;
1087
  return TRUE;
1088
}
1089
 
1090
/* Merge backend specific data from an object file to the output
1091
   object file when linking.  */
1092
static bfd_boolean
1093
elf32_m68k_merge_private_bfd_data (ibfd, obfd)
1094
     bfd *ibfd;
1095
     bfd *obfd;
1096
{
1097
  flagword out_flags;
1098
  flagword in_flags;
1099
  flagword out_isa;
1100
  flagword in_isa;
1101
  const bfd_arch_info_type *arch_info;
1102 225 jeremybenn
 
1103 24 jeremybenn
  if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1104
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1105
    return FALSE;
1106
 
1107
  /* Get the merged machine.  This checks for incompatibility between
1108
     Coldfire & non-Coldfire flags, incompability between different
1109
     Coldfire ISAs, and incompability between different MAC types.  */
1110
  arch_info = bfd_arch_get_compatible (ibfd, obfd, FALSE);
1111
  if (!arch_info)
1112
    return FALSE;
1113
 
1114
  bfd_set_arch_mach (obfd, bfd_arch_m68k, arch_info->mach);
1115 225 jeremybenn
 
1116 24 jeremybenn
  in_flags = elf_elfheader (ibfd)->e_flags;
1117
  if (!elf_flags_init (obfd))
1118
    {
1119
      elf_flags_init (obfd) = TRUE;
1120
      out_flags = in_flags;
1121
    }
1122
  else
1123
    {
1124
      out_flags = elf_elfheader (obfd)->e_flags;
1125
      unsigned int variant_mask;
1126
 
1127
      if ((in_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
1128
        variant_mask = 0;
1129
      else if ((in_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
1130
        variant_mask = 0;
1131
      else if ((in_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
1132
        variant_mask = 0;
1133
      else
1134
        variant_mask = EF_M68K_CF_ISA_MASK;
1135
 
1136
      in_isa = (in_flags & variant_mask);
1137
      out_isa = (out_flags & variant_mask);
1138
      if (in_isa > out_isa)
1139
        out_flags ^= in_isa ^ out_isa;
1140
      if (((in_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32
1141
           && (out_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
1142
          || ((in_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO
1143
              && (out_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32))
1144
        out_flags = EF_M68K_FIDO;
1145
      else
1146
      out_flags |= in_flags ^ in_isa;
1147
    }
1148
  elf_elfheader (obfd)->e_flags = out_flags;
1149
 
1150
  return TRUE;
1151
}
1152
 
1153
/* Display the flags field.  */
1154 225 jeremybenn
 
1155 24 jeremybenn
static bfd_boolean
1156 225 jeremybenn
elf32_m68k_print_private_bfd_data (bfd *abfd, void * ptr)
1157 24 jeremybenn
{
1158
  FILE *file = (FILE *) ptr;
1159
  flagword eflags = elf_elfheader (abfd)->e_flags;
1160
 
1161
  BFD_ASSERT (abfd != NULL && ptr != NULL);
1162
 
1163
  /* Print normal ELF private data.  */
1164
  _bfd_elf_print_private_bfd_data (abfd, ptr);
1165
 
1166
  /* Ignore init flag - it may not be set, despite the flags field containing valid data.  */
1167
 
1168
  /* xgettext:c-format */
1169
  fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
1170
 
1171
  if ((eflags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
1172
    fprintf (file, " [m68000]");
1173
  else if ((eflags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
1174
    fprintf (file, " [cpu32]");
1175
  else if ((eflags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
1176
    fprintf (file, " [fido]");
1177
  else
1178
    {
1179
      if ((eflags & EF_M68K_ARCH_MASK) == EF_M68K_CFV4E)
1180
        fprintf (file, " [cfv4e]");
1181
 
1182
      if (eflags & EF_M68K_CF_ISA_MASK)
1183
        {
1184
          char const *isa = _("unknown");
1185
          char const *mac = _("unknown");
1186
          char const *additional = "";
1187 225 jeremybenn
 
1188 24 jeremybenn
          switch (eflags & EF_M68K_CF_ISA_MASK)
1189
            {
1190
            case EF_M68K_CF_ISA_A_NODIV:
1191
              isa = "A";
1192
              additional = " [nodiv]";
1193
              break;
1194
            case EF_M68K_CF_ISA_A:
1195
              isa = "A";
1196
              break;
1197
            case EF_M68K_CF_ISA_A_PLUS:
1198
              isa = "A+";
1199
              break;
1200
            case EF_M68K_CF_ISA_B_NOUSP:
1201
              isa = "B";
1202
              additional = " [nousp]";
1203
              break;
1204
            case EF_M68K_CF_ISA_B:
1205
              isa = "B";
1206
              break;
1207
            case EF_M68K_CF_ISA_C:
1208
              isa = "C";
1209
              break;
1210
            case EF_M68K_CF_ISA_C_NODIV:
1211
              isa = "C";
1212
              additional = " [nodiv]";
1213
              break;
1214
            }
1215
          fprintf (file, " [isa %s]%s", isa, additional);
1216 225 jeremybenn
 
1217 24 jeremybenn
          if (eflags & EF_M68K_CF_FLOAT)
1218
            fprintf (file, " [float]");
1219 225 jeremybenn
 
1220 24 jeremybenn
          switch (eflags & EF_M68K_CF_MAC_MASK)
1221
            {
1222
            case 0:
1223
              mac = NULL;
1224
              break;
1225
            case EF_M68K_CF_MAC:
1226
              mac = "mac";
1227
              break;
1228
            case EF_M68K_CF_EMAC:
1229
              mac = "emac";
1230
              break;
1231
            }
1232
          if (mac)
1233
            fprintf (file, " [%s]", mac);
1234
        }
1235
    }
1236 225 jeremybenn
 
1237 24 jeremybenn
  fputc ('\n', file);
1238
 
1239
  return TRUE;
1240
}
1241 225 jeremybenn
 
1242
/* Multi-GOT support implementation design:
1243
 
1244
   Multi-GOT starts in check_relocs hook.  There we scan all
1245
   relocations of a BFD and build a local GOT (struct elf_m68k_got)
1246
   for it.  If a single BFD appears to require too many GOT slots with
1247
   R_68K_GOT8O or R_68K_GOT16O relocations, we fail with notification
1248
   to user.
1249
   After check_relocs has been invoked for each input BFD, we have
1250
   constructed a GOT for each input BFD.
1251
 
1252
   To minimize total number of GOTs required for a particular output BFD
1253
   (as some environments support only 1 GOT per output object) we try
1254
   to merge some of the GOTs to share an offset space.  Ideally [and in most
1255
   cases] we end up with a single GOT.  In cases when there are too many
1256
   restricted relocations (e.g., R_68K_GOT16O relocations) we end up with
1257
   several GOTs, assuming the environment can handle them.
1258
 
1259
   Partitioning is done in elf_m68k_partition_multi_got.  We start with
1260
   an empty GOT and traverse bfd2got hashtable putting got_entries from
1261
   local GOTs to the new 'big' one.  We do that by constructing an
1262
   intermediate GOT holding all the entries the local GOT has and the big
1263
   GOT lacks.  Then we check if there is room in the big GOT to accomodate
1264
   all the entries from diff.  On success we add those entries to the big
1265
   GOT; on failure we start the new 'big' GOT and retry the adding of
1266
   entries from the local GOT.  Note that this retry will always succeed as
1267
   each local GOT doesn't overflow the limits.  After partitioning we
1268
   end up with each bfd assigned one of the big GOTs.  GOT entries in the
1269
   big GOTs are initialized with GOT offsets.  Note that big GOTs are
1270
   positioned consequently in program space and represent a single huge GOT
1271
   to the outside world.
1272
 
1273
   After that we get to elf_m68k_relocate_section.  There we
1274
   adjust relocations of GOT pointer (_GLOBAL_OFFSET_TABLE_) and symbol
1275
   relocations to refer to appropriate [assigned to current input_bfd]
1276
   big GOT.
1277
 
1278
   Notes:
1279
 
1280
   GOT entry type: We have several types of GOT entries.
1281
   * R_8 type is used in entries for symbols that have at least one
1282
   R_68K_GOT8O or R_68K_TLS_*8 relocation.  We can have at most 0x40
1283
   such entries in one GOT.
1284
   * R_16 type is used in entries for symbols that have at least one
1285
   R_68K_GOT16O or R_68K_TLS_*16 relocation and no R_8 relocations.
1286
   We can have at most 0x4000 such entries in one GOT.
1287
   * R_32 type is used in all other cases.  We can have as many
1288
   such entries in one GOT as we'd like.
1289
   When counting relocations we have to include the count of the smaller
1290
   ranged relocations in the counts of the larger ranged ones in order
1291
   to correctly detect overflow.
1292
 
1293
   Sorting the GOT: In each GOT starting offsets are assigned to
1294
   R_8 entries, which are followed by R_16 entries, and
1295
   R_32 entries go at the end.  See finalize_got_offsets for details.
1296
 
1297
   Negative GOT offsets: To double usable offset range of GOTs we use
1298
   negative offsets.  As we assign entries with GOT offsets relative to
1299
   start of .got section, the offset values are positive.  They become
1300
   negative only in relocate_section where got->offset value is
1301
   subtracted from them.
1302
 
1303
   3 special GOT entries: There are 3 special GOT entries used internally
1304
   by loader.  These entries happen to be placed to .got.plt section,
1305
   so we don't do anything about them in multi-GOT support.
1306
 
1307
   Memory management: All data except for hashtables
1308
   multi_got->bfd2got and got->entries are allocated on
1309
   elf_hash_table (info)->dynobj bfd (for this reason we pass 'info'
1310
   to most functions), so we don't need to care to free them.  At the
1311
   moment of allocation hashtables are being linked into main data
1312
   structure (multi_got), all pieces of which are reachable from
1313
   elf_m68k_multi_got (info).  We deallocate them in
1314
   elf_m68k_link_hash_table_free.  */
1315
 
1316
/* Initialize GOT.  */
1317
 
1318
static void
1319
elf_m68k_init_got (struct elf_m68k_got *got)
1320
{
1321
  got->entries = NULL;
1322
  got->n_slots[R_8] = 0;
1323
  got->n_slots[R_16] = 0;
1324
  got->n_slots[R_32] = 0;
1325
  got->local_n_slots = 0;
1326
  got->offset = (bfd_vma) -1;
1327
}
1328
 
1329
/* Destruct GOT.  */
1330
 
1331
static void
1332
elf_m68k_clear_got (struct elf_m68k_got *got)
1333
{
1334
  if (got->entries != NULL)
1335
    {
1336
      htab_delete (got->entries);
1337
      got->entries = NULL;
1338
    }
1339
}
1340
 
1341
/* Create and empty GOT structure.  INFO is the context where memory
1342
   should be allocated.  */
1343
 
1344
static struct elf_m68k_got *
1345
elf_m68k_create_empty_got (struct bfd_link_info *info)
1346
{
1347
  struct elf_m68k_got *got;
1348
 
1349
  got = bfd_alloc (elf_hash_table (info)->dynobj, sizeof (*got));
1350
  if (got == NULL)
1351
    return NULL;
1352
 
1353
  elf_m68k_init_got (got);
1354
 
1355
  return got;
1356
}
1357
 
1358
/* Initialize KEY.  */
1359
 
1360
static void
1361
elf_m68k_init_got_entry_key (struct elf_m68k_got_entry_key *key,
1362
                             struct elf_link_hash_entry *h,
1363
                             const bfd *abfd, unsigned long symndx,
1364
                             enum elf_m68k_reloc_type reloc_type)
1365
{
1366
  if (elf_m68k_reloc_got_type (reloc_type) == R_68K_TLS_LDM32)
1367
    /* All TLS_LDM relocations share a single GOT entry.  */
1368
    {
1369
      key->bfd = NULL;
1370
      key->symndx = 0;
1371
    }
1372
  else if (h != NULL)
1373
    /* Global symbols are identified with their got_entry_key.  */
1374
    {
1375
      key->bfd = NULL;
1376
      key->symndx = elf_m68k_hash_entry (h)->got_entry_key;
1377
      BFD_ASSERT (key->symndx != 0);
1378
    }
1379
  else
1380
    /* Local symbols are identified by BFD they appear in and symndx.  */
1381
    {
1382
      key->bfd = abfd;
1383
      key->symndx = symndx;
1384
    }
1385
 
1386
  key->type = reloc_type;
1387
}
1388
 
1389
/* Calculate hash of got_entry.
1390
   ??? Is it good?  */
1391
 
1392
static hashval_t
1393
elf_m68k_got_entry_hash (const void *_entry)
1394
{
1395
  const struct elf_m68k_got_entry_key *key;
1396
 
1397
  key = &((const struct elf_m68k_got_entry *) _entry)->key_;
1398
 
1399
  return (key->symndx
1400
          + (key->bfd != NULL ? (int) key->bfd->id : -1)
1401
          + elf_m68k_reloc_got_type (key->type));
1402
}
1403
 
1404
/* Check if two got entries are equal.  */
1405
 
1406
static int
1407
elf_m68k_got_entry_eq (const void *_entry1, const void *_entry2)
1408
{
1409
  const struct elf_m68k_got_entry_key *key1;
1410
  const struct elf_m68k_got_entry_key *key2;
1411
 
1412
  key1 = &((const struct elf_m68k_got_entry *) _entry1)->key_;
1413
  key2 = &((const struct elf_m68k_got_entry *) _entry2)->key_;
1414
 
1415
  return (key1->bfd == key2->bfd
1416
          && key1->symndx == key2->symndx
1417
          && (elf_m68k_reloc_got_type (key1->type)
1418
              == elf_m68k_reloc_got_type (key2->type)));
1419
}
1420
 
1421
/* When using negative offsets, we allocate one extra R_8, one extra R_16
1422
   and one extra R_32 slots to simplify handling of 2-slot entries during
1423
   offset allocation -- hence -1 for R_8 slots and -2 for R_16 slots.  */
1424
 
1425
/* Maximal number of R_8 slots in a single GOT.  */
1426
#define ELF_M68K_R_8_MAX_N_SLOTS_IN_GOT(INFO)           \
1427
  (elf_m68k_hash_table (INFO)->use_neg_got_offsets_p            \
1428
   ? (0x40 - 1)                                                 \
1429
   : 0x20)
1430
 
1431
/* Maximal number of R_8 and R_16 slots in a single GOT.  */
1432
#define ELF_M68K_R_8_16_MAX_N_SLOTS_IN_GOT(INFO)                \
1433
  (elf_m68k_hash_table (INFO)->use_neg_got_offsets_p            \
1434
   ? (0x4000 - 2)                                               \
1435
   : 0x2000)
1436
 
1437
/* SEARCH - simply search the hashtable, don't insert new entries or fail when
1438
   the entry cannot be found.
1439
   FIND_OR_CREATE - search for an existing entry, but create new if there's
1440
   no such.
1441
   MUST_FIND - search for an existing entry and assert that it exist.
1442
   MUST_CREATE - assert that there's no such entry and create new one.  */
1443
enum elf_m68k_get_entry_howto
1444
  {
1445
    SEARCH,
1446
    FIND_OR_CREATE,
1447
    MUST_FIND,
1448
    MUST_CREATE
1449
  };
1450
 
1451
/* Get or create (depending on HOWTO) entry with KEY in GOT.
1452
   INFO is context in which memory should be allocated (can be NULL if
1453
   HOWTO is SEARCH or MUST_FIND).  */
1454
 
1455
static struct elf_m68k_got_entry *
1456
elf_m68k_get_got_entry (struct elf_m68k_got *got,
1457
                        const struct elf_m68k_got_entry_key *key,
1458
                        enum elf_m68k_get_entry_howto howto,
1459
                        struct bfd_link_info *info)
1460
{
1461
  struct elf_m68k_got_entry entry_;
1462
  struct elf_m68k_got_entry *entry;
1463
  void **ptr;
1464
 
1465
  BFD_ASSERT ((info == NULL) == (howto == SEARCH || howto == MUST_FIND));
1466
 
1467
  if (got->entries == NULL)
1468
    /* This is the first entry in ABFD.  Initialize hashtable.  */
1469
    {
1470
      if (howto == SEARCH)
1471
        return NULL;
1472
 
1473
      got->entries = htab_try_create (ELF_M68K_R_8_MAX_N_SLOTS_IN_GOT
1474
                                      (info),
1475
                                      elf_m68k_got_entry_hash,
1476
                                      elf_m68k_got_entry_eq, NULL);
1477
      if (got->entries == NULL)
1478
        {
1479
          bfd_set_error (bfd_error_no_memory);
1480
          return NULL;
1481
        }
1482
    }
1483
 
1484
  entry_.key_ = *key;
1485
  ptr = htab_find_slot (got->entries, &entry_, (howto != SEARCH
1486
                                                ? INSERT : NO_INSERT));
1487
  if (ptr == NULL)
1488
    {
1489
      if (howto == SEARCH)
1490
        /* Entry not found.  */
1491
        return NULL;
1492
 
1493
      /* We're out of memory.  */
1494
      bfd_set_error (bfd_error_no_memory);
1495
      return NULL;
1496
    }
1497
 
1498
  if (*ptr == NULL)
1499
    /* We didn't find the entry and we're asked to create a new one.  */
1500
    {
1501
      BFD_ASSERT (howto != MUST_FIND && howto != SEARCH);
1502
 
1503
      entry = bfd_alloc (elf_hash_table (info)->dynobj, sizeof (*entry));
1504
      if (entry == NULL)
1505
        return NULL;
1506
 
1507
      /* Initialize new entry.  */
1508
      entry->key_ = *key;
1509
 
1510
      entry->u.s1.refcount = 0;
1511
 
1512
      /* Mark the entry as not initialized.  */
1513
      entry->key_.type = R_68K_max;
1514
 
1515
      *ptr = entry;
1516
    }
1517
  else
1518
    /* We found the entry.  */
1519
    {
1520
      BFD_ASSERT (howto != MUST_CREATE);
1521
 
1522
      entry = *ptr;
1523
    }
1524
 
1525
  return entry;
1526
}
1527
 
1528
/* Update GOT counters when merging entry of WAS type with entry of NEW type.
1529
   Return the value to which ENTRY's type should be set.  */
1530
 
1531
static enum elf_m68k_reloc_type
1532
elf_m68k_update_got_entry_type (struct elf_m68k_got *got,
1533
                                enum elf_m68k_reloc_type was,
1534
                                enum elf_m68k_reloc_type new_reloc)
1535
{
1536
  enum elf_m68k_got_offset_size was_size;
1537
  enum elf_m68k_got_offset_size new_size;
1538
  bfd_vma n_slots;
1539
 
1540
  if (was == R_68K_max)
1541
    /* The type of the entry is not initialized yet.  */
1542
    {
1543
      /* Update all got->n_slots counters, including n_slots[R_32].  */
1544
      was_size = R_LAST;
1545
 
1546
      was = new_reloc;
1547
    }
1548
  else
1549
    {
1550
      /* !!! We, probably, should emit an error rather then fail on assert
1551
         in such a case.  */
1552
      BFD_ASSERT (elf_m68k_reloc_got_type (was)
1553
                  == elf_m68k_reloc_got_type (new_reloc));
1554
 
1555
      was_size = elf_m68k_reloc_got_offset_size (was);
1556
    }
1557
 
1558
  new_size = elf_m68k_reloc_got_offset_size (new_reloc);
1559
  n_slots = elf_m68k_reloc_got_n_slots (new_reloc);
1560
 
1561
  while (was_size > new_size)
1562
    {
1563
      --was_size;
1564
      got->n_slots[was_size] += n_slots;
1565
    }
1566
 
1567
  if (new_reloc > was)
1568
    /* Relocations are ordered from bigger got offset size to lesser,
1569
       so choose the relocation type with lesser offset size.  */
1570
    was = new_reloc;
1571
 
1572
  return was;
1573
}
1574
 
1575
/* Update GOT counters when removing an entry of type TYPE.  */
1576
 
1577
static void
1578
elf_m68k_remove_got_entry_type (struct elf_m68k_got *got,
1579
                                enum elf_m68k_reloc_type type)
1580
{
1581
  enum elf_m68k_got_offset_size os;
1582
  bfd_vma n_slots;
1583
 
1584
  n_slots = elf_m68k_reloc_got_n_slots (type);
1585
 
1586
  /* Decrese counter of slots with offset size corresponding to TYPE
1587
     and all greater offset sizes.  */
1588
  for (os = elf_m68k_reloc_got_offset_size (type); os <= R_32; ++os)
1589
    {
1590
      BFD_ASSERT (got->n_slots[os] >= n_slots);
1591
 
1592
      got->n_slots[os] -= n_slots;
1593
    }
1594
}
1595
 
1596
/* Add new or update existing entry to GOT.
1597
   H, ABFD, TYPE and SYMNDX is data for the entry.
1598
   INFO is a context where memory should be allocated.  */
1599
 
1600
static struct elf_m68k_got_entry *
1601
elf_m68k_add_entry_to_got (struct elf_m68k_got *got,
1602
                           struct elf_link_hash_entry *h,
1603
                           const bfd *abfd,
1604
                           enum elf_m68k_reloc_type reloc_type,
1605
                           unsigned long symndx,
1606
                           struct bfd_link_info *info)
1607
{
1608
  struct elf_m68k_got_entry_key key_;
1609
  struct elf_m68k_got_entry *entry;
1610
 
1611
  if (h != NULL && elf_m68k_hash_entry (h)->got_entry_key == 0)
1612
    elf_m68k_hash_entry (h)->got_entry_key
1613
      = elf_m68k_multi_got (info)->global_symndx++;
1614
 
1615
  elf_m68k_init_got_entry_key (&key_, h, abfd, symndx, reloc_type);
1616
 
1617
  entry = elf_m68k_get_got_entry (got, &key_, FIND_OR_CREATE, info);
1618
  if (entry == NULL)
1619
    return NULL;
1620
 
1621
  /* Determine entry's type and update got->n_slots counters.  */
1622
  entry->key_.type = elf_m68k_update_got_entry_type (got,
1623
                                                     entry->key_.type,
1624
                                                     reloc_type);
1625
 
1626
  /* Update refcount.  */
1627
  ++entry->u.s1.refcount;
1628
 
1629
  if (entry->u.s1.refcount == 1)
1630
    /* We see this entry for the first time.  */
1631
    {
1632
      if (entry->key_.bfd != NULL)
1633
        got->local_n_slots += elf_m68k_reloc_got_n_slots (entry->key_.type);
1634
    }
1635
 
1636
  BFD_ASSERT (got->n_slots[R_32] >= got->local_n_slots);
1637
 
1638
  if ((got->n_slots[R_8]
1639
       > ELF_M68K_R_8_MAX_N_SLOTS_IN_GOT (info))
1640
      || (got->n_slots[R_16]
1641
          > ELF_M68K_R_8_16_MAX_N_SLOTS_IN_GOT (info)))
1642
    /* This BFD has too many relocation.  */
1643
    {
1644
      if (got->n_slots[R_8] > ELF_M68K_R_8_MAX_N_SLOTS_IN_GOT (info))
1645
        (*_bfd_error_handler) (_("%B: GOT overflow: "
1646
                                 "Number of relocations with 8-bit "
1647
                                 "offset > %d"),
1648
                               abfd,
1649
                               ELF_M68K_R_8_MAX_N_SLOTS_IN_GOT (info));
1650
      else
1651
        (*_bfd_error_handler) (_("%B: GOT overflow: "
1652
                                 "Number of relocations with 8- or 16-bit "
1653
                                 "offset > %d"),
1654
                               abfd,
1655
                               ELF_M68K_R_8_16_MAX_N_SLOTS_IN_GOT (info));
1656
 
1657
      return NULL;
1658
    }
1659
 
1660
  return entry;
1661
}
1662
 
1663
/* Compute the hash value of the bfd in a bfd2got hash entry.  */
1664
 
1665
static hashval_t
1666
elf_m68k_bfd2got_entry_hash (const void *entry)
1667
{
1668
  const struct elf_m68k_bfd2got_entry *e;
1669
 
1670
  e = (const struct elf_m68k_bfd2got_entry *) entry;
1671
 
1672
  return e->bfd->id;
1673
}
1674
 
1675
/* Check whether two hash entries have the same bfd.  */
1676
 
1677
static int
1678
elf_m68k_bfd2got_entry_eq (const void *entry1, const void *entry2)
1679
{
1680
  const struct elf_m68k_bfd2got_entry *e1;
1681
  const struct elf_m68k_bfd2got_entry *e2;
1682
 
1683
  e1 = (const struct elf_m68k_bfd2got_entry *) entry1;
1684
  e2 = (const struct elf_m68k_bfd2got_entry *) entry2;
1685
 
1686
  return e1->bfd == e2->bfd;
1687
}
1688
 
1689
/* Destruct a bfd2got entry.  */
1690
 
1691
static void
1692
elf_m68k_bfd2got_entry_del (void *_entry)
1693
{
1694
  struct elf_m68k_bfd2got_entry *entry;
1695
 
1696
  entry = (struct elf_m68k_bfd2got_entry *) _entry;
1697
 
1698
  BFD_ASSERT (entry->got != NULL);
1699
  elf_m68k_clear_got (entry->got);
1700
}
1701
 
1702
/* Find existing or create new (depending on HOWTO) bfd2got entry in
1703
   MULTI_GOT.  ABFD is the bfd we need a GOT for.  INFO is a context where
1704
   memory should be allocated.  */
1705
 
1706
static struct elf_m68k_bfd2got_entry *
1707
elf_m68k_get_bfd2got_entry (struct elf_m68k_multi_got *multi_got,
1708
                            const bfd *abfd,
1709
                            enum elf_m68k_get_entry_howto howto,
1710
                            struct bfd_link_info *info)
1711
{
1712
  struct elf_m68k_bfd2got_entry entry_;
1713
  void **ptr;
1714
  struct elf_m68k_bfd2got_entry *entry;
1715
 
1716
  BFD_ASSERT ((info == NULL) == (howto == SEARCH || howto == MUST_FIND));
1717
 
1718
  if (multi_got->bfd2got == NULL)
1719
    /* This is the first GOT.  Initialize bfd2got.  */
1720
    {
1721
      if (howto == SEARCH)
1722
        return NULL;
1723
 
1724
      multi_got->bfd2got = htab_try_create (1, elf_m68k_bfd2got_entry_hash,
1725
                                            elf_m68k_bfd2got_entry_eq,
1726
                                            elf_m68k_bfd2got_entry_del);
1727
      if (multi_got->bfd2got == NULL)
1728
        {
1729
          bfd_set_error (bfd_error_no_memory);
1730
          return NULL;
1731
        }
1732
    }
1733
 
1734
  entry_.bfd = abfd;
1735
  ptr = htab_find_slot (multi_got->bfd2got, &entry_, (howto != SEARCH
1736
                                                      ? INSERT : NO_INSERT));
1737
  if (ptr == NULL)
1738
    {
1739
      if (howto == SEARCH)
1740
        /* Entry not found.  */
1741
        return NULL;
1742
 
1743
      /* We're out of memory.  */
1744
      bfd_set_error (bfd_error_no_memory);
1745
      return NULL;
1746
    }
1747
 
1748
  if (*ptr == NULL)
1749
    /* Entry was not found.  Create new one.  */
1750
    {
1751
      BFD_ASSERT (howto != MUST_FIND && howto != SEARCH);
1752
 
1753
      entry = ((struct elf_m68k_bfd2got_entry *)
1754
               bfd_alloc (elf_hash_table (info)->dynobj, sizeof (*entry)));
1755
      if (entry == NULL)
1756
        return NULL;
1757
 
1758
      entry->bfd = abfd;
1759
 
1760
      entry->got = elf_m68k_create_empty_got (info);
1761
      if (entry->got == NULL)
1762
        return NULL;
1763
 
1764
      *ptr = entry;
1765
    }
1766
  else
1767
    {
1768
      BFD_ASSERT (howto != MUST_CREATE);
1769
 
1770
      /* Return existing entry.  */
1771
      entry = *ptr;
1772
    }
1773
 
1774
  return entry;
1775
}
1776
 
1777
struct elf_m68k_can_merge_gots_arg
1778
{
1779
  /* A current_got that we constructing a DIFF against.  */
1780
  struct elf_m68k_got *big;
1781
 
1782
  /* GOT holding entries not present or that should be changed in
1783
     BIG.  */
1784
  struct elf_m68k_got *diff;
1785
 
1786
  /* Context where to allocate memory.  */
1787
  struct bfd_link_info *info;
1788
 
1789
  /* Error flag.  */
1790
  bfd_boolean error_p;
1791
};
1792
 
1793
/* Process a single entry from the small GOT to see if it should be added
1794
   or updated in the big GOT.  */
1795
 
1796
static int
1797
elf_m68k_can_merge_gots_1 (void **_entry_ptr, void *_arg)
1798
{
1799
  const struct elf_m68k_got_entry *entry1;
1800
  struct elf_m68k_can_merge_gots_arg *arg;
1801
  const struct elf_m68k_got_entry *entry2;
1802
  enum elf_m68k_reloc_type type;
1803
 
1804
  entry1 = (const struct elf_m68k_got_entry *) *_entry_ptr;
1805
  arg = (struct elf_m68k_can_merge_gots_arg *) _arg;
1806
 
1807
  entry2 = elf_m68k_get_got_entry (arg->big, &entry1->key_, SEARCH, NULL);
1808
 
1809
  if (entry2 != NULL)
1810
    /* We found an existing entry.  Check if we should update it.  */
1811
    {
1812
      type = elf_m68k_update_got_entry_type (arg->diff,
1813
                                             entry2->key_.type,
1814
                                             entry1->key_.type);
1815
 
1816
      if (type == entry2->key_.type)
1817
        /* ENTRY1 doesn't update data in ENTRY2.  Skip it.
1818
           To skip creation of difference entry we use the type,
1819
           which we won't see in GOT entries for sure.  */
1820
        type = R_68K_max;
1821
    }
1822
  else
1823
    /* We didn't find the entry.  Add entry1 to DIFF.  */
1824
    {
1825
      BFD_ASSERT (entry1->key_.type != R_68K_max);
1826
 
1827
      type = elf_m68k_update_got_entry_type (arg->diff,
1828
                                             R_68K_max, entry1->key_.type);
1829
 
1830
      if (entry1->key_.bfd != NULL)
1831
        arg->diff->local_n_slots += elf_m68k_reloc_got_n_slots (type);
1832
    }
1833
 
1834
  if (type != R_68K_max)
1835
    /* Create an entry in DIFF.  */
1836
    {
1837
      struct elf_m68k_got_entry *entry;
1838
 
1839
      entry = elf_m68k_get_got_entry (arg->diff, &entry1->key_, MUST_CREATE,
1840
                                      arg->info);
1841
      if (entry == NULL)
1842
        {
1843
          arg->error_p = TRUE;
1844
          return 0;
1845
        }
1846
 
1847
      entry->key_.type = type;
1848
    }
1849
 
1850
  return 1;
1851
}
1852
 
1853
/* Return TRUE if SMALL GOT can be added to BIG GOT without overflowing it.
1854
   Construct DIFF GOT holding the entries which should be added or updated
1855
   in BIG GOT to accumulate information from SMALL.
1856
   INFO is the context where memory should be allocated.  */
1857
 
1858
static bfd_boolean
1859
elf_m68k_can_merge_gots (struct elf_m68k_got *big,
1860
                         const struct elf_m68k_got *small,
1861
                         struct bfd_link_info *info,
1862
                         struct elf_m68k_got *diff)
1863
{
1864
  struct elf_m68k_can_merge_gots_arg arg_;
1865
 
1866
  BFD_ASSERT (small->offset == (bfd_vma) -1);
1867
 
1868
  arg_.big = big;
1869
  arg_.diff = diff;
1870
  arg_.info = info;
1871
  arg_.error_p = FALSE;
1872
  htab_traverse_noresize (small->entries, elf_m68k_can_merge_gots_1, &arg_);
1873
  if (arg_.error_p)
1874
    {
1875
      diff->offset = 0;
1876
      return FALSE;
1877
    }
1878
 
1879
  /* Check for overflow.  */
1880
  if ((big->n_slots[R_8] + arg_.diff->n_slots[R_8]
1881
       > ELF_M68K_R_8_MAX_N_SLOTS_IN_GOT (info))
1882
      || (big->n_slots[R_16] + arg_.diff->n_slots[R_16]
1883
          > ELF_M68K_R_8_16_MAX_N_SLOTS_IN_GOT (info)))
1884
    return FALSE;
1885
 
1886
  return TRUE;
1887
}
1888
 
1889
struct elf_m68k_merge_gots_arg
1890
{
1891
  /* The BIG got.  */
1892
  struct elf_m68k_got *big;
1893
 
1894
  /* Context where memory should be allocated.  */
1895
  struct bfd_link_info *info;
1896
 
1897
  /* Error flag.  */
1898
  bfd_boolean error_p;
1899
};
1900
 
1901
/* Process a single entry from DIFF got.  Add or update corresponding
1902
   entry in the BIG got.  */
1903
 
1904
static int
1905
elf_m68k_merge_gots_1 (void **entry_ptr, void *_arg)
1906
{
1907
  const struct elf_m68k_got_entry *from;
1908
  struct elf_m68k_merge_gots_arg *arg;
1909
  struct elf_m68k_got_entry *to;
1910
 
1911
  from = (const struct elf_m68k_got_entry *) *entry_ptr;
1912
  arg = (struct elf_m68k_merge_gots_arg *) _arg;
1913
 
1914
  to = elf_m68k_get_got_entry (arg->big, &from->key_, FIND_OR_CREATE,
1915
                               arg->info);
1916
  if (to == NULL)
1917
    {
1918
      arg->error_p = TRUE;
1919
      return 0;
1920
    }
1921
 
1922
  BFD_ASSERT (to->u.s1.refcount == 0);
1923
  /* All we need to merge is TYPE.  */
1924
  to->key_.type = from->key_.type;
1925
 
1926
  return 1;
1927
}
1928
 
1929
/* Merge data from DIFF to BIG.  INFO is context where memory should be
1930
   allocated.  */
1931
 
1932
static bfd_boolean
1933
elf_m68k_merge_gots (struct elf_m68k_got *big,
1934
                     struct elf_m68k_got *diff,
1935
                     struct bfd_link_info *info)
1936
{
1937
  if (diff->entries != NULL)
1938
    /* DIFF is not empty.  Merge it into BIG GOT.  */
1939
    {
1940
      struct elf_m68k_merge_gots_arg arg_;
1941
 
1942
      /* Merge entries.  */
1943
      arg_.big = big;
1944
      arg_.info = info;
1945
      arg_.error_p = FALSE;
1946
      htab_traverse_noresize (diff->entries, elf_m68k_merge_gots_1, &arg_);
1947
      if (arg_.error_p)
1948
        return FALSE;
1949
 
1950
      /* Merge counters.  */
1951
      big->n_slots[R_8] += diff->n_slots[R_8];
1952
      big->n_slots[R_16] += diff->n_slots[R_16];
1953
      big->n_slots[R_32] += diff->n_slots[R_32];
1954
      big->local_n_slots += diff->local_n_slots;
1955
    }
1956
  else
1957
    /* DIFF is empty.  */
1958
    {
1959
      BFD_ASSERT (diff->n_slots[R_8] == 0);
1960
      BFD_ASSERT (diff->n_slots[R_16] == 0);
1961
      BFD_ASSERT (diff->n_slots[R_32] == 0);
1962
      BFD_ASSERT (diff->local_n_slots == 0);
1963
    }
1964
 
1965
  BFD_ASSERT (!elf_m68k_hash_table (info)->allow_multigot_p
1966
              || ((big->n_slots[R_8]
1967
                   <= ELF_M68K_R_8_MAX_N_SLOTS_IN_GOT (info))
1968
                  && (big->n_slots[R_16]
1969
                      <= ELF_M68K_R_8_16_MAX_N_SLOTS_IN_GOT (info))));
1970
 
1971
  return TRUE;
1972
}
1973
 
1974
struct elf_m68k_finalize_got_offsets_arg
1975
{
1976
  /* Ranges of the offsets for GOT entries.
1977
     R_x entries receive offsets between offset1[R_x] and offset2[R_x].
1978
     R_x is R_8, R_16 and R_32.  */
1979
  bfd_vma *offset1;
1980
  bfd_vma *offset2;
1981
 
1982
  /* Mapping from global symndx to global symbols.
1983
     This is used to build lists of got entries for global symbols.  */
1984
  struct elf_m68k_link_hash_entry **symndx2h;
1985
 
1986
  bfd_vma n_ldm_entries;
1987
};
1988
 
1989
/* Assign ENTRY an offset.  Build list of GOT entries for global symbols
1990
   along the way.  */
1991
 
1992
static int
1993
elf_m68k_finalize_got_offsets_1 (void **entry_ptr, void *_arg)
1994
{
1995
  struct elf_m68k_got_entry *entry;
1996
  struct elf_m68k_finalize_got_offsets_arg *arg;
1997
 
1998
  enum elf_m68k_got_offset_size got_offset_size;
1999
  bfd_vma entry_size;
2000
 
2001
  entry = (struct elf_m68k_got_entry *) *entry_ptr;
2002
  arg = (struct elf_m68k_finalize_got_offsets_arg *) _arg;
2003
 
2004
  /* This should be a fresh entry created in elf_m68k_can_merge_gots.  */
2005
  BFD_ASSERT (entry->u.s1.refcount == 0);
2006
 
2007
  /* Get GOT offset size for the entry .  */
2008
  got_offset_size = elf_m68k_reloc_got_offset_size (entry->key_.type);
2009
 
2010
  /* Calculate entry size in bytes.  */
2011
  entry_size = 4 * elf_m68k_reloc_got_n_slots (entry->key_.type);
2012
 
2013
  /* Check if we should switch to negative range of the offsets. */
2014
  if (arg->offset1[got_offset_size] + entry_size
2015
      > arg->offset2[got_offset_size])
2016
    {
2017
      /* Verify that this is the only switch to negative range for
2018
         got_offset_size.  If this assertion fails, then we've miscalculated
2019
         range for got_offset_size entries in
2020
         elf_m68k_finalize_got_offsets.  */
2021
      BFD_ASSERT (arg->offset2[got_offset_size]
2022
                  != arg->offset2[-(int) got_offset_size - 1]);
2023
 
2024
      /* Switch.  */
2025
      arg->offset1[got_offset_size] = arg->offset1[-(int) got_offset_size - 1];
2026
      arg->offset2[got_offset_size] = arg->offset2[-(int) got_offset_size - 1];
2027
 
2028
      /* Verify that now we have enough room for the entry.  */
2029
      BFD_ASSERT (arg->offset1[got_offset_size] + entry_size
2030
                  <= arg->offset2[got_offset_size]);
2031
    }
2032
 
2033
  /* Assign offset to entry.  */
2034
  entry->u.s2.offset = arg->offset1[got_offset_size];
2035
  arg->offset1[got_offset_size] += entry_size;
2036
 
2037
  if (entry->key_.bfd == NULL)
2038
    /* Hook up this entry into the list of got_entries of H.  */
2039
    {
2040
      struct elf_m68k_link_hash_entry *h;
2041
 
2042
      h = arg->symndx2h[entry->key_.symndx];
2043
      if (h != NULL)
2044
        {
2045
          entry->u.s2.next = h->glist;
2046
          h->glist = entry;
2047
        }
2048
      else
2049
        /* This should be the entry for TLS_LDM relocation then.  */
2050
        {
2051
          BFD_ASSERT ((elf_m68k_reloc_got_type (entry->key_.type)
2052
                       == R_68K_TLS_LDM32)
2053
                      && entry->key_.symndx == 0);
2054
 
2055
          ++arg->n_ldm_entries;
2056
        }
2057
    }
2058
  else
2059
    /* This entry is for local symbol.  */
2060
    entry->u.s2.next = NULL;
2061
 
2062
  return 1;
2063
}
2064
 
2065
/* Assign offsets within GOT.  USE_NEG_GOT_OFFSETS_P indicates if we
2066
   should use negative offsets.
2067
   Build list of GOT entries for global symbols along the way.
2068
   SYMNDX2H is mapping from global symbol indices to actual
2069
   global symbols.
2070
   Return offset at which next GOT should start.  */
2071
 
2072
static void
2073
elf_m68k_finalize_got_offsets (struct elf_m68k_got *got,
2074
                               bfd_boolean use_neg_got_offsets_p,
2075
                               struct elf_m68k_link_hash_entry **symndx2h,
2076
                               bfd_vma *final_offset, bfd_vma *n_ldm_entries)
2077
{
2078
  struct elf_m68k_finalize_got_offsets_arg arg_;
2079
  bfd_vma offset1_[2 * R_LAST];
2080
  bfd_vma offset2_[2 * R_LAST];
2081
  int i;
2082
  bfd_vma start_offset;
2083
 
2084
  BFD_ASSERT (got->offset != (bfd_vma) -1);
2085
 
2086
  /* We set entry offsets relative to the .got section (and not the
2087
     start of a particular GOT), so that we can use them in
2088
     finish_dynamic_symbol without needing to know the GOT which they come
2089
     from.  */
2090
 
2091
  /* Put offset1 in the middle of offset1_, same for offset2.  */
2092
  arg_.offset1 = offset1_ + R_LAST;
2093
  arg_.offset2 = offset2_ + R_LAST;
2094
 
2095
  start_offset = got->offset;
2096
 
2097
  if (use_neg_got_offsets_p)
2098
    /* Setup both negative and positive ranges for R_8, R_16 and R_32.  */
2099
    i = -(int) R_32 - 1;
2100
  else
2101
    /* Setup positives ranges for R_8, R_16 and R_32.  */
2102
    i = (int) R_8;
2103
 
2104
  for (; i <= (int) R_32; ++i)
2105
    {
2106
      int j;
2107
      size_t n;
2108
 
2109
      /* Set beginning of the range of offsets I.  */
2110
      arg_.offset1[i] = start_offset;
2111
 
2112
      /* Calculate number of slots that require I offsets.  */
2113
      j = (i >= 0) ? i : -i - 1;
2114
      n = (j >= 1) ? got->n_slots[j - 1] : 0;
2115
      n = got->n_slots[j] - n;
2116
 
2117
      if (use_neg_got_offsets_p && n != 0)
2118
        {
2119
          if (i < 0)
2120
            /* We first fill the positive side of the range, so we might
2121
               end up with one empty slot at that side when we can't fit
2122
               whole 2-slot entry.  Account for that at negative side of
2123
               the interval with one additional entry.  */
2124
            n = n / 2 + 1;
2125
          else
2126
            /* When the number of slots is odd, make positive side of the
2127
               range one entry bigger.  */
2128
            n = (n + 1) / 2;
2129
        }
2130
 
2131
      /* N is the number of slots that require I offsets.
2132
         Calculate length of the range for I offsets.  */
2133
      n = 4 * n;
2134
 
2135
      /* Set end of the range.  */
2136
      arg_.offset2[i] = start_offset + n;
2137
 
2138
      start_offset = arg_.offset2[i];
2139
    }
2140
 
2141
  if (!use_neg_got_offsets_p)
2142
    /* Make sure that if we try to switch to negative offsets in
2143
       elf_m68k_finalize_got_offsets_1, the assert therein will catch
2144
       the bug.  */
2145
    for (i = R_8; i <= R_32; ++i)
2146
      arg_.offset2[-i - 1] = arg_.offset2[i];
2147
 
2148
  /* Setup got->offset.  offset1[R_8] is either in the middle or at the
2149
     beginning of GOT depending on use_neg_got_offsets_p.  */
2150
  got->offset = arg_.offset1[R_8];
2151
 
2152
  arg_.symndx2h = symndx2h;
2153
  arg_.n_ldm_entries = 0;
2154
 
2155
  /* Assign offsets.  */
2156
  htab_traverse (got->entries, elf_m68k_finalize_got_offsets_1, &arg_);
2157
 
2158
  /* Check offset ranges we have actually assigned.  */
2159
  for (i = (int) R_8; i <= (int) R_32; ++i)
2160
    BFD_ASSERT (arg_.offset2[i] - arg_.offset1[i] <= 4);
2161
 
2162
  *final_offset = start_offset;
2163
  *n_ldm_entries = arg_.n_ldm_entries;
2164
}
2165
 
2166
struct elf_m68k_partition_multi_got_arg
2167
{
2168
  /* The GOT we are adding entries to.  Aka big got.  */
2169
  struct elf_m68k_got *current_got;
2170
 
2171
  /* Offset to assign the next CURRENT_GOT.  */
2172
  bfd_vma offset;
2173
 
2174
  /* Context where memory should be allocated.  */
2175
  struct bfd_link_info *info;
2176
 
2177
  /* Total number of slots in the .got section.
2178
     This is used to calculate size of the .got and .rela.got sections.  */
2179
  bfd_vma n_slots;
2180
 
2181
  /* Difference in numbers of allocated slots in the .got section
2182
     and necessary relocations in the .rela.got section.
2183
     This is used to calculate size of the .rela.got section.  */
2184
  bfd_vma slots_relas_diff;
2185
 
2186
  /* Error flag.  */
2187
  bfd_boolean error_p;
2188
 
2189
  /* Mapping from global symndx to global symbols.
2190
     This is used to build lists of got entries for global symbols.  */
2191
  struct elf_m68k_link_hash_entry **symndx2h;
2192
};
2193
 
2194
static void
2195
elf_m68k_partition_multi_got_2 (struct elf_m68k_partition_multi_got_arg *arg)
2196
{
2197
  bfd_vma n_ldm_entries;
2198
 
2199
  elf_m68k_finalize_got_offsets (arg->current_got,
2200
                                 (elf_m68k_hash_table (arg->info)
2201
                                  ->use_neg_got_offsets_p),
2202
                                 arg->symndx2h,
2203
                                 &arg->offset, &n_ldm_entries);
2204
 
2205
  arg->n_slots += arg->current_got->n_slots[R_32];
2206
 
2207
  if (!arg->info->shared)
2208
    /* If we are generating a shared object, we need to
2209
       output a R_68K_RELATIVE reloc so that the dynamic
2210
       linker can adjust this GOT entry.  Overwise we
2211
       don't need space in .rela.got for local symbols.  */
2212
    arg->slots_relas_diff += arg->current_got->local_n_slots;
2213
 
2214
  /* @LDM relocations require a 2-slot GOT entry, but only
2215
     one relocation.  Account for that.  */
2216
  arg->slots_relas_diff += n_ldm_entries;
2217
 
2218
  BFD_ASSERT (arg->slots_relas_diff <= arg->n_slots);
2219
}
2220
 
2221
 
2222
/* Process a single BFD2GOT entry and either merge GOT to CURRENT_GOT
2223
   or start a new CURRENT_GOT.  */
2224
 
2225
static int
2226
elf_m68k_partition_multi_got_1 (void **_entry, void *_arg)
2227
{
2228
  struct elf_m68k_bfd2got_entry *entry;
2229
  struct elf_m68k_partition_multi_got_arg *arg;
2230
  struct elf_m68k_got *got;
2231
  struct elf_m68k_got diff_;
2232
  struct elf_m68k_got *diff;
2233
 
2234
  entry = (struct elf_m68k_bfd2got_entry *) *_entry;
2235
  arg = (struct elf_m68k_partition_multi_got_arg *) _arg;
2236
 
2237
  got = entry->got;
2238
  BFD_ASSERT (got != NULL);
2239
  BFD_ASSERT (got->offset == (bfd_vma) -1);
2240
 
2241
  diff = NULL;
2242
 
2243
  if (arg->current_got != NULL)
2244
    /* Construct diff.  */
2245
    {
2246
      diff = &diff_;
2247
      elf_m68k_init_got (diff);
2248
 
2249
      if (!elf_m68k_can_merge_gots (arg->current_got, got, arg->info, diff))
2250
        {
2251
          if (diff->offset == 0)
2252
            /* Offset set to 0 in the diff_ indicates an error.  */
2253
            {
2254
              arg->error_p = TRUE;
2255
              goto final_return;
2256
            }
2257
 
2258
          if (elf_m68k_hash_table (arg->info)->allow_multigot_p)
2259
            {
2260
              elf_m68k_clear_got (diff);
2261
              /* Schedule to finish up current_got and start new one.  */
2262
              diff = NULL;
2263
            }
2264
          /* else
2265
             Merge GOTs no matter what.  If big GOT overflows,
2266
             we'll fail in relocate_section due to truncated relocations.
2267
 
2268
             ??? May be fail earlier?  E.g., in can_merge_gots.  */
2269
        }
2270
    }
2271
  else
2272
    /* Diff of got against empty current_got is got itself.  */
2273
    {
2274
      /* Create empty current_got to put subsequent GOTs to.  */
2275
      arg->current_got = elf_m68k_create_empty_got (arg->info);
2276
      if (arg->current_got == NULL)
2277
        {
2278
          arg->error_p = TRUE;
2279
          goto final_return;
2280
        }
2281
 
2282
      arg->current_got->offset = arg->offset;
2283
 
2284
      diff = got;
2285
    }
2286
 
2287
  if (diff != NULL)
2288
    {
2289
      if (!elf_m68k_merge_gots (arg->current_got, diff, arg->info))
2290
        {
2291
          arg->error_p = TRUE;
2292
          goto final_return;
2293
        }
2294
 
2295
      /* Now we can free GOT.  */
2296
      elf_m68k_clear_got (got);
2297
 
2298
      entry->got = arg->current_got;
2299
    }
2300
  else
2301
    {
2302
      /* Finish up current_got.  */
2303
      elf_m68k_partition_multi_got_2 (arg);
2304
 
2305
      /* Schedule to start a new current_got.  */
2306
      arg->current_got = NULL;
2307
 
2308
      /* Retry.  */
2309
      if (!elf_m68k_partition_multi_got_1 (_entry, _arg))
2310
        {
2311
          BFD_ASSERT (arg->error_p);
2312
          goto final_return;
2313
        }
2314
    }
2315
 
2316
 final_return:
2317
  if (diff != NULL)
2318
    elf_m68k_clear_got (diff);
2319
 
2320
  return arg->error_p == FALSE ? 1 : 0;
2321
}
2322
 
2323
/* Helper function to build symndx2h mapping.  */
2324
 
2325
static bfd_boolean
2326
elf_m68k_init_symndx2h_1 (struct elf_link_hash_entry *_h,
2327
                          void *_arg)
2328
{
2329
  struct elf_m68k_link_hash_entry *h;
2330
 
2331
  h = elf_m68k_hash_entry (_h);
2332
 
2333
  if (h->got_entry_key != 0)
2334
    /* H has at least one entry in the GOT.  */
2335
    {
2336
      struct elf_m68k_partition_multi_got_arg *arg;
2337
 
2338
      arg = (struct elf_m68k_partition_multi_got_arg *) _arg;
2339
 
2340
      BFD_ASSERT (arg->symndx2h[h->got_entry_key] == NULL);
2341
      arg->symndx2h[h->got_entry_key] = h;
2342
    }
2343
 
2344
  return TRUE;
2345
}
2346
 
2347
/* Merge GOTs of some BFDs, assign offsets to GOT entries and build
2348
   lists of GOT entries for global symbols.
2349
   Calculate sizes of .got and .rela.got sections.  */
2350
 
2351
static bfd_boolean
2352
elf_m68k_partition_multi_got (struct bfd_link_info *info)
2353
{
2354
  struct elf_m68k_multi_got *multi_got;
2355
  struct elf_m68k_partition_multi_got_arg arg_;
2356
 
2357
  multi_got = elf_m68k_multi_got (info);
2358
 
2359
  arg_.current_got = NULL;
2360
  arg_.offset = 0;
2361
  arg_.info = info;
2362
  arg_.n_slots = 0;
2363
  arg_.slots_relas_diff = 0;
2364
  arg_.error_p = FALSE;
2365
 
2366
  if (multi_got->bfd2got != NULL)
2367
    {
2368
      /* Initialize symndx2h mapping.  */
2369
      {
2370
        arg_.symndx2h = bfd_zmalloc (multi_got->global_symndx
2371
                                     * sizeof (*arg_.symndx2h));
2372
        if (arg_.symndx2h == NULL)
2373
          return FALSE;
2374
 
2375
        elf_link_hash_traverse (elf_hash_table (info),
2376
                                elf_m68k_init_symndx2h_1, &arg_);
2377
      }
2378
 
2379
      /* Partition.  */
2380
      htab_traverse (multi_got->bfd2got, elf_m68k_partition_multi_got_1,
2381
                     &arg_);
2382
      if (arg_.error_p)
2383
        {
2384
          free (arg_.symndx2h);
2385
          arg_.symndx2h = NULL;
2386
 
2387
          return FALSE;
2388
        }
2389
 
2390
      /* Finish up last current_got.  */
2391
      elf_m68k_partition_multi_got_2 (&arg_);
2392
 
2393
      free (arg_.symndx2h);
2394
    }
2395
 
2396
  if (elf_hash_table (info)->dynobj != NULL)
2397
    /* Set sizes of .got and .rela.got sections.  */
2398
    {
2399
      asection *s;
2400
 
2401
      s = bfd_get_section_by_name (elf_hash_table (info)->dynobj, ".got");
2402
      if (s != NULL)
2403
        s->size = arg_.offset;
2404
      else
2405
        BFD_ASSERT (arg_.offset == 0);
2406
 
2407
      BFD_ASSERT (arg_.slots_relas_diff <= arg_.n_slots);
2408
      arg_.n_slots -= arg_.slots_relas_diff;
2409
 
2410
      s = bfd_get_section_by_name (elf_hash_table (info)->dynobj, ".rela.got");
2411
      if (s != NULL)
2412
        s->size = arg_.n_slots * sizeof (Elf32_External_Rela);
2413
      else
2414
        BFD_ASSERT (arg_.n_slots == 0);
2415
    }
2416
  else
2417
    BFD_ASSERT (multi_got->bfd2got == NULL);
2418
 
2419
  return TRUE;
2420
}
2421
 
2422
/* Specialized version of elf_m68k_get_got_entry that returns pointer
2423
   to hashtable slot, thus allowing removal of entry via
2424
   elf_m68k_remove_got_entry.  */
2425
 
2426
static struct elf_m68k_got_entry **
2427
elf_m68k_find_got_entry_ptr (struct elf_m68k_got *got,
2428
                             struct elf_m68k_got_entry_key *key)
2429
{
2430
  void **ptr;
2431
  struct elf_m68k_got_entry entry_;
2432
  struct elf_m68k_got_entry **entry_ptr;
2433
 
2434
  entry_.key_ = *key;
2435
  ptr = htab_find_slot (got->entries, &entry_, NO_INSERT);
2436
  BFD_ASSERT (ptr != NULL);
2437
 
2438
  entry_ptr = (struct elf_m68k_got_entry **) ptr;
2439
 
2440
  return entry_ptr;
2441
}
2442
 
2443
/* Remove entry pointed to by ENTRY_PTR from GOT.  */
2444
 
2445
static void
2446
elf_m68k_remove_got_entry (struct elf_m68k_got *got,
2447
                           struct elf_m68k_got_entry **entry_ptr)
2448
{
2449
  struct elf_m68k_got_entry *entry;
2450
 
2451
  entry = *entry_ptr;
2452
 
2453
  /* Check that offsets have not been finalized yet.  */
2454
  BFD_ASSERT (got->offset == (bfd_vma) -1);
2455
  /* Check that this entry is indeed unused.  */
2456
  BFD_ASSERT (entry->u.s1.refcount == 0);
2457
 
2458
  elf_m68k_remove_got_entry_type (got, entry->key_.type);
2459
 
2460
  if (entry->key_.bfd != NULL)
2461
    got->local_n_slots -= elf_m68k_reloc_got_n_slots (entry->key_.type);
2462
 
2463
  BFD_ASSERT (got->n_slots[R_32] >= got->local_n_slots);
2464
 
2465
  htab_clear_slot (got->entries, (void **) entry_ptr);
2466
}
2467
 
2468
/* Copy any information related to dynamic linking from a pre-existing
2469
   symbol to a newly created symbol.  Also called to copy flags and
2470
   other back-end info to a weakdef, in which case the symbol is not
2471
   newly created and plt/got refcounts and dynamic indices should not
2472
   be copied.  */
2473
 
2474
static void
2475
elf_m68k_copy_indirect_symbol (struct bfd_link_info *info,
2476
                               struct elf_link_hash_entry *_dir,
2477
                               struct elf_link_hash_entry *_ind)
2478
{
2479
  struct elf_m68k_link_hash_entry *dir;
2480
  struct elf_m68k_link_hash_entry *ind;
2481
 
2482
  _bfd_elf_link_hash_copy_indirect (info, _dir, _ind);
2483
 
2484
  if (_ind->root.type != bfd_link_hash_indirect)
2485
    return;
2486
 
2487
  dir = elf_m68k_hash_entry (_dir);
2488
  ind = elf_m68k_hash_entry (_ind);
2489
 
2490
  /* Any absolute non-dynamic relocations against an indirect or weak
2491
     definition will be against the target symbol.  */
2492
  _dir->non_got_ref |= _ind->non_got_ref;
2493
 
2494
  /* We might have a direct symbol already having entries in the GOTs.
2495
     Update its key only in case indirect symbol has GOT entries and
2496
     assert that both indirect and direct symbols don't have GOT entries
2497
     at the same time.  */
2498
  if (ind->got_entry_key != 0)
2499
    {
2500
      BFD_ASSERT (dir->got_entry_key == 0);
2501
      /* Assert that GOTs aren't partioned yet.  */
2502
      BFD_ASSERT (ind->glist == NULL);
2503
 
2504
      dir->got_entry_key = ind->got_entry_key;
2505
      ind->got_entry_key = 0;
2506
    }
2507
}
2508
 
2509 24 jeremybenn
/* Look through the relocs for a section during the first phase, and
2510
   allocate space in the global offset table or procedure linkage
2511
   table.  */
2512
 
2513
static bfd_boolean
2514
elf_m68k_check_relocs (abfd, info, sec, relocs)
2515
     bfd *abfd;
2516
     struct bfd_link_info *info;
2517
     asection *sec;
2518
     const Elf_Internal_Rela *relocs;
2519
{
2520
  bfd *dynobj;
2521
  Elf_Internal_Shdr *symtab_hdr;
2522
  struct elf_link_hash_entry **sym_hashes;
2523
  const Elf_Internal_Rela *rel;
2524
  const Elf_Internal_Rela *rel_end;
2525
  asection *sgot;
2526
  asection *srelgot;
2527
  asection *sreloc;
2528 225 jeremybenn
  struct elf_m68k_got *got;
2529 24 jeremybenn
 
2530
  if (info->relocatable)
2531
    return TRUE;
2532
 
2533
  dynobj = elf_hash_table (info)->dynobj;
2534
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2535
  sym_hashes = elf_sym_hashes (abfd);
2536
 
2537
  sgot = NULL;
2538
  srelgot = NULL;
2539
  sreloc = NULL;
2540
 
2541 225 jeremybenn
  got = NULL;
2542
 
2543 24 jeremybenn
  rel_end = relocs + sec->reloc_count;
2544
  for (rel = relocs; rel < rel_end; rel++)
2545
    {
2546
      unsigned long r_symndx;
2547
      struct elf_link_hash_entry *h;
2548
 
2549
      r_symndx = ELF32_R_SYM (rel->r_info);
2550
 
2551
      if (r_symndx < symtab_hdr->sh_info)
2552
        h = NULL;
2553
      else
2554
        {
2555
          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
2556
          while (h->root.type == bfd_link_hash_indirect
2557
                 || h->root.type == bfd_link_hash_warning)
2558
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
2559
        }
2560
 
2561
      switch (ELF32_R_TYPE (rel->r_info))
2562
        {
2563
        case R_68K_GOT8:
2564
        case R_68K_GOT16:
2565
        case R_68K_GOT32:
2566
          if (h != NULL
2567
              && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
2568
            break;
2569
          /* Fall through.  */
2570 225 jeremybenn
 
2571
          /* Relative GOT relocations.  */
2572 24 jeremybenn
        case R_68K_GOT8O:
2573
        case R_68K_GOT16O:
2574
        case R_68K_GOT32O:
2575 225 jeremybenn
          /* Fall through.  */
2576
 
2577
          /* TLS relocations.  */
2578
        case R_68K_TLS_GD8:
2579
        case R_68K_TLS_GD16:
2580
        case R_68K_TLS_GD32:
2581
        case R_68K_TLS_LDM8:
2582
        case R_68K_TLS_LDM16:
2583
        case R_68K_TLS_LDM32:
2584
        case R_68K_TLS_IE8:
2585
        case R_68K_TLS_IE16:
2586
        case R_68K_TLS_IE32:
2587
 
2588
        case R_68K_TLS_TPREL32:
2589
        case R_68K_TLS_DTPREL32:
2590
 
2591
          if (ELF32_R_TYPE (rel->r_info) == R_68K_TLS_TPREL32
2592
              && info->shared)
2593
            /* Do the special chorus for libraries with static TLS.  */
2594
            info->flags |= DF_STATIC_TLS;
2595
 
2596 24 jeremybenn
          /* This symbol requires a global offset table entry.  */
2597
 
2598
          if (dynobj == NULL)
2599
            {
2600
              /* Create the .got section.  */
2601
              elf_hash_table (info)->dynobj = dynobj = abfd;
2602
              if (!_bfd_elf_create_got_section (dynobj, info))
2603
                return FALSE;
2604
            }
2605
 
2606
          if (sgot == NULL)
2607
            {
2608
              sgot = bfd_get_section_by_name (dynobj, ".got");
2609
              BFD_ASSERT (sgot != NULL);
2610
            }
2611
 
2612
          if (srelgot == NULL
2613
              && (h != NULL || info->shared))
2614
            {
2615
              srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
2616
              if (srelgot == NULL)
2617
                {
2618
                  srelgot = bfd_make_section_with_flags (dynobj,
2619
                                                         ".rela.got",
2620
                                                         (SEC_ALLOC
2621
                                                          | SEC_LOAD
2622
                                                          | SEC_HAS_CONTENTS
2623
                                                          | SEC_IN_MEMORY
2624
                                                          | SEC_LINKER_CREATED
2625
                                                          | SEC_READONLY));
2626
                  if (srelgot == NULL
2627
                      || !bfd_set_section_alignment (dynobj, srelgot, 2))
2628
                    return FALSE;
2629
                }
2630
            }
2631
 
2632 225 jeremybenn
          if (got == NULL)
2633 24 jeremybenn
            {
2634 225 jeremybenn
              struct elf_m68k_bfd2got_entry *bfd2got_entry;
2635 24 jeremybenn
 
2636 225 jeremybenn
              bfd2got_entry
2637
                = elf_m68k_get_bfd2got_entry (elf_m68k_multi_got (info),
2638
                                              abfd, FIND_OR_CREATE, info);
2639
              if (bfd2got_entry == NULL)
2640
                return FALSE;
2641
 
2642
              got = bfd2got_entry->got;
2643
              BFD_ASSERT (got != NULL);
2644 24 jeremybenn
            }
2645
 
2646 225 jeremybenn
          {
2647
            struct elf_m68k_got_entry *got_entry;
2648
 
2649
            /* Add entry to got.  */
2650
            got_entry = elf_m68k_add_entry_to_got (got, h, abfd,
2651
                                                   ELF32_R_TYPE (rel->r_info),
2652
                                                   r_symndx, info);
2653
            if (got_entry == NULL)
2654
              return FALSE;
2655
 
2656
            if (got_entry->u.s1.refcount == 1)
2657
              {
2658
                /* Make sure this symbol is output as a dynamic symbol.  */
2659
                if (h != NULL
2660
                    && h->dynindx == -1
2661
                    && !h->forced_local)
2662
                  {
2663
                    if (!bfd_elf_link_record_dynamic_symbol (info, h))
2664
                      return FALSE;
2665
                  }
2666
              }
2667
          }
2668
 
2669 24 jeremybenn
          break;
2670
 
2671
        case R_68K_PLT8:
2672
        case R_68K_PLT16:
2673
        case R_68K_PLT32:
2674
          /* This symbol requires a procedure linkage table entry.  We
2675
             actually build the entry in adjust_dynamic_symbol,
2676
             because this might be a case of linking PIC code which is
2677
             never referenced by a dynamic object, in which case we
2678
             don't need to generate a procedure linkage table entry
2679
             after all.  */
2680
 
2681
          /* If this is a local symbol, we resolve it directly without
2682
             creating a procedure linkage table entry.  */
2683
          if (h == NULL)
2684
            continue;
2685
 
2686
          h->needs_plt = 1;
2687
          h->plt.refcount++;
2688
          break;
2689
 
2690
        case R_68K_PLT8O:
2691
        case R_68K_PLT16O:
2692
        case R_68K_PLT32O:
2693
          /* This symbol requires a procedure linkage table entry.  */
2694
 
2695
          if (h == NULL)
2696
            {
2697
              /* It does not make sense to have this relocation for a
2698
                 local symbol.  FIXME: does it?  How to handle it if
2699
                 it does make sense?  */
2700
              bfd_set_error (bfd_error_bad_value);
2701
              return FALSE;
2702
            }
2703
 
2704
          /* Make sure this symbol is output as a dynamic symbol.  */
2705
          if (h->dynindx == -1
2706
              && !h->forced_local)
2707
            {
2708
              if (!bfd_elf_link_record_dynamic_symbol (info, h))
2709
                return FALSE;
2710
            }
2711
 
2712
          h->needs_plt = 1;
2713
          h->plt.refcount++;
2714
          break;
2715
 
2716
        case R_68K_PC8:
2717
        case R_68K_PC16:
2718
        case R_68K_PC32:
2719
          /* If we are creating a shared library and this is not a local
2720
             symbol, we need to copy the reloc into the shared library.
2721
             However when linking with -Bsymbolic and this is a global
2722
             symbol which is defined in an object we are including in the
2723
             link (i.e., DEF_REGULAR is set), then we can resolve the
2724
             reloc directly.  At this point we have not seen all the input
2725
             files, so it is possible that DEF_REGULAR is not set now but
2726
             will be set later (it is never cleared).  We account for that
2727
             possibility below by storing information in the
2728
             pcrel_relocs_copied field of the hash table entry.  */
2729
          if (!(info->shared
2730
                && (sec->flags & SEC_ALLOC) != 0
2731
                && h != NULL
2732
                && (!info->symbolic
2733
                    || h->root.type == bfd_link_hash_defweak
2734
                    || !h->def_regular)))
2735
            {
2736
              if (h != NULL)
2737
                {
2738
                  /* Make sure a plt entry is created for this symbol if
2739
                     it turns out to be a function defined by a dynamic
2740
                     object.  */
2741
                  h->plt.refcount++;
2742
                }
2743
              break;
2744
            }
2745
          /* Fall through.  */
2746
        case R_68K_8:
2747
        case R_68K_16:
2748
        case R_68K_32:
2749
          if (h != NULL)
2750
            {
2751
              /* Make sure a plt entry is created for this symbol if it
2752
                 turns out to be a function defined by a dynamic object.  */
2753
              h->plt.refcount++;
2754 225 jeremybenn
 
2755
              if (!info->shared)
2756
                /* This symbol needs a non-GOT reference.  */
2757
                h->non_got_ref = 1;
2758 24 jeremybenn
            }
2759
 
2760
          /* If we are creating a shared library, we need to copy the
2761
             reloc into the shared library.  */
2762
          if (info->shared
2763
              && (sec->flags & SEC_ALLOC) != 0)
2764
            {
2765
              /* When creating a shared object, we must copy these
2766
                 reloc types into the output file.  We create a reloc
2767
                 section in dynobj and make room for this reloc.  */
2768
              if (sreloc == NULL)
2769
                {
2770 225 jeremybenn
                  sreloc = _bfd_elf_make_dynamic_reloc_section
2771
                    (sec, dynobj, 2, abfd, /*rela?*/ TRUE);
2772 24 jeremybenn
 
2773 225 jeremybenn
                  if (sreloc == NULL)
2774 24 jeremybenn
                    return FALSE;
2775
                }
2776
 
2777
              if (sec->flags & SEC_READONLY
2778
                  /* Don't set DF_TEXTREL yet for PC relative
2779
                     relocations, they might be discarded later.  */
2780
                  && !(ELF32_R_TYPE (rel->r_info) == R_68K_PC8
2781
                       || ELF32_R_TYPE (rel->r_info) == R_68K_PC16
2782
                       || ELF32_R_TYPE (rel->r_info) == R_68K_PC32))
2783
                    info->flags |= DF_TEXTREL;
2784
 
2785
              sreloc->size += sizeof (Elf32_External_Rela);
2786
 
2787
              /* We count the number of PC relative relocations we have
2788
                 entered for this symbol, so that we can discard them
2789
                 again if, in the -Bsymbolic case, the symbol is later
2790
                 defined by a regular object, or, in the normal shared
2791
                 case, the symbol is forced to be local.  Note that this
2792
                 function is only called if we are using an m68kelf linker
2793
                 hash table, which means that h is really a pointer to an
2794
                 elf_m68k_link_hash_entry.  */
2795
              if (ELF32_R_TYPE (rel->r_info) == R_68K_PC8
2796
                  || ELF32_R_TYPE (rel->r_info) == R_68K_PC16
2797
                  || ELF32_R_TYPE (rel->r_info) == R_68K_PC32)
2798
                {
2799
                  struct elf_m68k_pcrel_relocs_copied *p;
2800
                  struct elf_m68k_pcrel_relocs_copied **head;
2801
 
2802
                  if (h != NULL)
2803
                    {
2804
                      struct elf_m68k_link_hash_entry *eh
2805
                        = elf_m68k_hash_entry (h);
2806
                      head = &eh->pcrel_relocs_copied;
2807
                    }
2808
                  else
2809
                    {
2810
                      asection *s;
2811
                      void *vpp;
2812 225 jeremybenn
                      Elf_Internal_Sym *isym;
2813 24 jeremybenn
 
2814 225 jeremybenn
                      isym = bfd_sym_from_r_symndx (&elf_m68k_hash_table (info)->sym_cache,
2815
                                                    abfd, r_symndx);
2816
                      if (isym == NULL)
2817 24 jeremybenn
                        return FALSE;
2818
 
2819 225 jeremybenn
                      s = bfd_section_from_elf_index (abfd, isym->st_shndx);
2820
                      if (s == NULL)
2821
                        s = sec;
2822
 
2823 24 jeremybenn
                      vpp = &elf_section_data (s)->local_dynrel;
2824
                      head = (struct elf_m68k_pcrel_relocs_copied **) vpp;
2825
                    }
2826
 
2827
                  for (p = *head; p != NULL; p = p->next)
2828
                    if (p->section == sreloc)
2829
                      break;
2830
 
2831
                  if (p == NULL)
2832
                    {
2833
                      p = ((struct elf_m68k_pcrel_relocs_copied *)
2834
                           bfd_alloc (dynobj, (bfd_size_type) sizeof *p));
2835
                      if (p == NULL)
2836
                        return FALSE;
2837
                      p->next = *head;
2838
                      *head = p;
2839
                      p->section = sreloc;
2840
                      p->count = 0;
2841
                    }
2842
 
2843
                  ++p->count;
2844
                }
2845
            }
2846
 
2847
          break;
2848
 
2849
          /* This relocation describes the C++ object vtable hierarchy.
2850
             Reconstruct it for later use during GC.  */
2851
        case R_68K_GNU_VTINHERIT:
2852
          if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
2853
            return FALSE;
2854
          break;
2855
 
2856
          /* This relocation describes which C++ vtable entries are actually
2857
             used.  Record for later use during GC.  */
2858
        case R_68K_GNU_VTENTRY:
2859
          BFD_ASSERT (h != NULL);
2860
          if (h != NULL
2861
              && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
2862
            return FALSE;
2863
          break;
2864
 
2865
        default:
2866
          break;
2867
        }
2868
    }
2869
 
2870
  return TRUE;
2871
}
2872
 
2873
/* Return the section that should be marked against GC for a given
2874
   relocation.  */
2875
 
2876
static asection *
2877
elf_m68k_gc_mark_hook (asection *sec,
2878
                       struct bfd_link_info *info,
2879
                       Elf_Internal_Rela *rel,
2880
                       struct elf_link_hash_entry *h,
2881
                       Elf_Internal_Sym *sym)
2882
{
2883
  if (h != NULL)
2884
    switch (ELF32_R_TYPE (rel->r_info))
2885
      {
2886
      case R_68K_GNU_VTINHERIT:
2887
      case R_68K_GNU_VTENTRY:
2888
        return NULL;
2889
      }
2890
 
2891
  return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
2892
}
2893
 
2894
/* Update the got entry reference counts for the section being removed.  */
2895
 
2896
static bfd_boolean
2897
elf_m68k_gc_sweep_hook (bfd *abfd,
2898
                        struct bfd_link_info *info,
2899
                        asection *sec,
2900
                        const Elf_Internal_Rela *relocs)
2901
{
2902
  Elf_Internal_Shdr *symtab_hdr;
2903
  struct elf_link_hash_entry **sym_hashes;
2904
  const Elf_Internal_Rela *rel, *relend;
2905
  bfd *dynobj;
2906
  asection *sgot;
2907
  asection *srelgot;
2908 225 jeremybenn
  struct elf_m68k_got *got;
2909 24 jeremybenn
 
2910
  if (info->relocatable)
2911
    return TRUE;
2912
 
2913
  dynobj = elf_hash_table (info)->dynobj;
2914
  if (dynobj == NULL)
2915
    return TRUE;
2916
 
2917
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2918
  sym_hashes = elf_sym_hashes (abfd);
2919
 
2920
  sgot = bfd_get_section_by_name (dynobj, ".got");
2921
  srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
2922 225 jeremybenn
  got = NULL;
2923 24 jeremybenn
 
2924
  relend = relocs + sec->reloc_count;
2925
  for (rel = relocs; rel < relend; rel++)
2926
    {
2927
      unsigned long r_symndx;
2928
      struct elf_link_hash_entry *h = NULL;
2929
 
2930
      r_symndx = ELF32_R_SYM (rel->r_info);
2931
      if (r_symndx >= symtab_hdr->sh_info)
2932
        {
2933
          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
2934
          while (h->root.type == bfd_link_hash_indirect
2935
                 || h->root.type == bfd_link_hash_warning)
2936
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
2937
        }
2938
 
2939
      switch (ELF32_R_TYPE (rel->r_info))
2940
        {
2941
        case R_68K_GOT8:
2942
        case R_68K_GOT16:
2943
        case R_68K_GOT32:
2944 225 jeremybenn
          if (h != NULL
2945
              && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
2946
            break;
2947
 
2948
          /* FALLTHRU */
2949 24 jeremybenn
        case R_68K_GOT8O:
2950
        case R_68K_GOT16O:
2951
        case R_68K_GOT32O:
2952 225 jeremybenn
          /* Fall through.  */
2953
 
2954
          /* TLS relocations.  */
2955
        case R_68K_TLS_GD8:
2956
        case R_68K_TLS_GD16:
2957
        case R_68K_TLS_GD32:
2958
        case R_68K_TLS_LDM8:
2959
        case R_68K_TLS_LDM16:
2960
        case R_68K_TLS_LDM32:
2961
        case R_68K_TLS_IE8:
2962
        case R_68K_TLS_IE16:
2963
        case R_68K_TLS_IE32:
2964
 
2965
        case R_68K_TLS_TPREL32:
2966
        case R_68K_TLS_DTPREL32:
2967
 
2968
          if (got == NULL)
2969 24 jeremybenn
            {
2970 225 jeremybenn
              got = elf_m68k_get_bfd2got_entry (elf_m68k_multi_got (info),
2971
                                                abfd, MUST_FIND, NULL)->got;
2972
              BFD_ASSERT (got != NULL);
2973 24 jeremybenn
            }
2974 225 jeremybenn
 
2975
          {
2976
            struct elf_m68k_got_entry_key key_;
2977
            struct elf_m68k_got_entry **got_entry_ptr;
2978
            struct elf_m68k_got_entry *got_entry;
2979
 
2980
            elf_m68k_init_got_entry_key (&key_, h, abfd, r_symndx,
2981
                                         ELF32_R_TYPE (rel->r_info));
2982
            got_entry_ptr = elf_m68k_find_got_entry_ptr (got, &key_);
2983
 
2984
            got_entry = *got_entry_ptr;
2985
 
2986
            if (got_entry->u.s1.refcount > 0)
2987
              {
2988
                --got_entry->u.s1.refcount;
2989
 
2990
                if (got_entry->u.s1.refcount == 0)
2991
                  /* We don't need the .got entry any more.  */
2992
                  elf_m68k_remove_got_entry (got, got_entry_ptr);
2993
              }
2994
          }
2995 24 jeremybenn
          break;
2996
 
2997
        case R_68K_PLT8:
2998
        case R_68K_PLT16:
2999
        case R_68K_PLT32:
3000
        case R_68K_PLT8O:
3001
        case R_68K_PLT16O:
3002
        case R_68K_PLT32O:
3003
        case R_68K_PC8:
3004
        case R_68K_PC16:
3005
        case R_68K_PC32:
3006
        case R_68K_8:
3007
        case R_68K_16:
3008
        case R_68K_32:
3009
          if (h != NULL)
3010
            {
3011
              if (h->plt.refcount > 0)
3012
                --h->plt.refcount;
3013
            }
3014
          break;
3015
 
3016
        default:
3017
          break;
3018
        }
3019
    }
3020
 
3021
  return TRUE;
3022
}
3023
 
3024
/* Return the type of PLT associated with OUTPUT_BFD.  */
3025
 
3026
static const struct elf_m68k_plt_info *
3027
elf_m68k_get_plt_info (bfd *output_bfd)
3028
{
3029
  unsigned int features;
3030
 
3031
  features = bfd_m68k_mach_to_features (bfd_get_mach (output_bfd));
3032
  if (features & cpu32)
3033
    return &elf_cpu32_plt_info;
3034
  if (features & mcfisa_b)
3035
    return &elf_isab_plt_info;
3036
  if (features & mcfisa_c)
3037
    return &elf_isac_plt_info;
3038
  return &elf_m68k_plt_info;
3039
}
3040
 
3041
/* This function is called after all the input files have been read,
3042
   and the input sections have been assigned to output sections.
3043
   It's a convenient place to determine the PLT style.  */
3044
 
3045
static bfd_boolean
3046
elf_m68k_always_size_sections (bfd *output_bfd, struct bfd_link_info *info)
3047
{
3048 225 jeremybenn
  /* Bind input BFDs to GOTs and calculate sizes of .got and .rela.got
3049
     sections.  */
3050
  if (!elf_m68k_partition_multi_got (info))
3051
    return FALSE;
3052
 
3053 24 jeremybenn
  elf_m68k_hash_table (info)->plt_info = elf_m68k_get_plt_info (output_bfd);
3054
  return TRUE;
3055
}
3056
 
3057
/* Adjust a symbol defined by a dynamic object and referenced by a
3058
   regular object.  The current definition is in some section of the
3059
   dynamic object, but we're not including those sections.  We have to
3060
   change the definition to something the rest of the link can
3061
   understand.  */
3062
 
3063
static bfd_boolean
3064
elf_m68k_adjust_dynamic_symbol (info, h)
3065
     struct bfd_link_info *info;
3066
     struct elf_link_hash_entry *h;
3067
{
3068
  struct elf_m68k_link_hash_table *htab;
3069
  bfd *dynobj;
3070
  asection *s;
3071
 
3072
  htab = elf_m68k_hash_table (info);
3073
  dynobj = elf_hash_table (info)->dynobj;
3074
 
3075
  /* Make sure we know what is going on here.  */
3076
  BFD_ASSERT (dynobj != NULL
3077
              && (h->needs_plt
3078
                  || h->u.weakdef != NULL
3079
                  || (h->def_dynamic
3080
                      && h->ref_regular
3081
                      && !h->def_regular)));
3082
 
3083
  /* If this is a function, put it in the procedure linkage table.  We
3084
     will fill in the contents of the procedure linkage table later,
3085
     when we know the address of the .got section.  */
3086
  if (h->type == STT_FUNC
3087
      || h->needs_plt)
3088
    {
3089
      if ((h->plt.refcount <= 0
3090
           || SYMBOL_CALLS_LOCAL (info, h)
3091
           || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
3092
               && h->root.type == bfd_link_hash_undefweak))
3093
          /* We must always create the plt entry if it was referenced
3094
             by a PLTxxO relocation.  In this case we already recorded
3095
             it as a dynamic symbol.  */
3096
          && h->dynindx == -1)
3097
        {
3098
          /* This case can occur if we saw a PLTxx reloc in an input
3099
             file, but the symbol was never referred to by a dynamic
3100
             object, or if all references were garbage collected.  In
3101
             such a case, we don't actually need to build a procedure
3102
             linkage table, and we can just do a PCxx reloc instead.  */
3103
          h->plt.offset = (bfd_vma) -1;
3104
          h->needs_plt = 0;
3105
          return TRUE;
3106
        }
3107
 
3108
      /* Make sure this symbol is output as a dynamic symbol.  */
3109
      if (h->dynindx == -1
3110
          && !h->forced_local)
3111
        {
3112
          if (! bfd_elf_link_record_dynamic_symbol (info, h))
3113
            return FALSE;
3114
        }
3115
 
3116
      s = bfd_get_section_by_name (dynobj, ".plt");
3117
      BFD_ASSERT (s != NULL);
3118
 
3119
      /* If this is the first .plt entry, make room for the special
3120
         first entry.  */
3121
      if (s->size == 0)
3122
        s->size = htab->plt_info->size;
3123
 
3124
      /* If this symbol is not defined in a regular file, and we are
3125
         not generating a shared library, then set the symbol to this
3126
         location in the .plt.  This is required to make function
3127
         pointers compare as equal between the normal executable and
3128
         the shared library.  */
3129
      if (!info->shared
3130
          && !h->def_regular)
3131
        {
3132
          h->root.u.def.section = s;
3133
          h->root.u.def.value = s->size;
3134
        }
3135
 
3136
      h->plt.offset = s->size;
3137
 
3138
      /* Make room for this entry.  */
3139
      s->size += htab->plt_info->size;
3140
 
3141
      /* We also need to make an entry in the .got.plt section, which
3142
         will be placed in the .got section by the linker script.  */
3143
      s = bfd_get_section_by_name (dynobj, ".got.plt");
3144
      BFD_ASSERT (s != NULL);
3145
      s->size += 4;
3146
 
3147
      /* We also need to make an entry in the .rela.plt section.  */
3148
      s = bfd_get_section_by_name (dynobj, ".rela.plt");
3149
      BFD_ASSERT (s != NULL);
3150
      s->size += sizeof (Elf32_External_Rela);
3151
 
3152
      return TRUE;
3153
    }
3154
 
3155
  /* Reinitialize the plt offset now that it is not used as a reference
3156
     count any more.  */
3157
  h->plt.offset = (bfd_vma) -1;
3158
 
3159
  /* If this is a weak symbol, and there is a real definition, the
3160
     processor independent code will have arranged for us to see the
3161
     real definition first, and we can just use the same value.  */
3162
  if (h->u.weakdef != NULL)
3163
    {
3164
      BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
3165
                  || h->u.weakdef->root.type == bfd_link_hash_defweak);
3166
      h->root.u.def.section = h->u.weakdef->root.u.def.section;
3167
      h->root.u.def.value = h->u.weakdef->root.u.def.value;
3168
      return TRUE;
3169
    }
3170
 
3171
  /* This is a reference to a symbol defined by a dynamic object which
3172
     is not a function.  */
3173
 
3174
  /* If we are creating a shared library, we must presume that the
3175
     only references to the symbol are via the global offset table.
3176
     For such cases we need not do anything here; the relocations will
3177
     be handled correctly by relocate_section.  */
3178
  if (info->shared)
3179
    return TRUE;
3180
 
3181 225 jeremybenn
  /* If there are no references to this symbol that do not use the
3182
     GOT, we don't need to generate a copy reloc.  */
3183
  if (!h->non_got_ref)
3184
    return TRUE;
3185
 
3186 24 jeremybenn
  if (h->size == 0)
3187
    {
3188
      (*_bfd_error_handler) (_("dynamic variable `%s' is zero size"),
3189
                             h->root.root.string);
3190
      return TRUE;
3191
    }
3192
 
3193
  /* We must allocate the symbol in our .dynbss section, which will
3194
     become part of the .bss section of the executable.  There will be
3195
     an entry for this symbol in the .dynsym section.  The dynamic
3196
     object will contain position independent code, so all references
3197
     from the dynamic object to this symbol will go through the global
3198
     offset table.  The dynamic linker will use the .dynsym entry to
3199
     determine the address it must put in the global offset table, so
3200
     both the dynamic object and the regular object will refer to the
3201
     same memory location for the variable.  */
3202
 
3203
  s = bfd_get_section_by_name (dynobj, ".dynbss");
3204
  BFD_ASSERT (s != NULL);
3205
 
3206
  /* We must generate a R_68K_COPY reloc to tell the dynamic linker to
3207
     copy the initial value out of the dynamic object and into the
3208
     runtime process image.  We need to remember the offset into the
3209
     .rela.bss section we are going to use.  */
3210
  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
3211
    {
3212
      asection *srel;
3213
 
3214
      srel = bfd_get_section_by_name (dynobj, ".rela.bss");
3215
      BFD_ASSERT (srel != NULL);
3216
      srel->size += sizeof (Elf32_External_Rela);
3217
      h->needs_copy = 1;
3218
    }
3219
 
3220
  return _bfd_elf_adjust_dynamic_copy (h, s);
3221
}
3222
 
3223
/* Set the sizes of the dynamic sections.  */
3224
 
3225
static bfd_boolean
3226
elf_m68k_size_dynamic_sections (output_bfd, info)
3227
     bfd *output_bfd ATTRIBUTE_UNUSED;
3228
     struct bfd_link_info *info;
3229
{
3230
  bfd *dynobj;
3231
  asection *s;
3232
  bfd_boolean plt;
3233
  bfd_boolean relocs;
3234
 
3235
  dynobj = elf_hash_table (info)->dynobj;
3236
  BFD_ASSERT (dynobj != NULL);
3237
 
3238
  if (elf_hash_table (info)->dynamic_sections_created)
3239
    {
3240
      /* Set the contents of the .interp section to the interpreter.  */
3241
      if (info->executable)
3242
        {
3243
          s = bfd_get_section_by_name (dynobj, ".interp");
3244
          BFD_ASSERT (s != NULL);
3245
          s->size = sizeof ELF_DYNAMIC_INTERPRETER;
3246
          s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
3247
        }
3248
    }
3249
  else
3250
    {
3251
      /* We may have created entries in the .rela.got section.
3252
         However, if we are not creating the dynamic sections, we will
3253
         not actually use these entries.  Reset the size of .rela.got,
3254
         which will cause it to get stripped from the output file
3255
         below.  */
3256
      s = bfd_get_section_by_name (dynobj, ".rela.got");
3257
      if (s != NULL)
3258
        s->size = 0;
3259
    }
3260
 
3261
  /* If this is a -Bsymbolic shared link, then we need to discard all
3262
     PC relative relocs against symbols defined in a regular object.
3263
     For the normal shared case we discard the PC relative relocs
3264
     against symbols that have become local due to visibility changes.
3265
     We allocated space for them in the check_relocs routine, but we
3266
     will not fill them in in the relocate_section routine.  */
3267
  if (info->shared)
3268
    elf_link_hash_traverse (elf_hash_table (info),
3269
                            elf_m68k_discard_copies,
3270
                            (PTR) info);
3271
 
3272
  /* The check_relocs and adjust_dynamic_symbol entry points have
3273
     determined the sizes of the various dynamic sections.  Allocate
3274
     memory for them.  */
3275
  plt = FALSE;
3276
  relocs = FALSE;
3277
  for (s = dynobj->sections; s != NULL; s = s->next)
3278
    {
3279
      const char *name;
3280
 
3281
      if ((s->flags & SEC_LINKER_CREATED) == 0)
3282
        continue;
3283
 
3284
      /* It's OK to base decisions on the section name, because none
3285
         of the dynobj section names depend upon the input files.  */
3286
      name = bfd_get_section_name (dynobj, s);
3287
 
3288
      if (strcmp (name, ".plt") == 0)
3289
        {
3290
          /* Remember whether there is a PLT.  */
3291
          plt = s->size != 0;
3292
        }
3293
      else if (CONST_STRNEQ (name, ".rela"))
3294
        {
3295
          if (s->size != 0)
3296
            {
3297
              relocs = TRUE;
3298
 
3299
              /* We use the reloc_count field as a counter if we need
3300
                 to copy relocs into the output file.  */
3301
              s->reloc_count = 0;
3302
            }
3303
        }
3304
      else if (! CONST_STRNEQ (name, ".got")
3305
               && strcmp (name, ".dynbss") != 0)
3306
        {
3307
          /* It's not one of our sections, so don't allocate space.  */
3308
          continue;
3309
        }
3310
 
3311
      if (s->size == 0)
3312
        {
3313
          /* If we don't need this section, strip it from the
3314
             output file.  This is mostly to handle .rela.bss and
3315
             .rela.plt.  We must create both sections in
3316
             create_dynamic_sections, because they must be created
3317
             before the linker maps input sections to output
3318
             sections.  The linker does that before
3319
             adjust_dynamic_symbol is called, and it is that
3320
             function which decides whether anything needs to go
3321
             into these sections.  */
3322
          s->flags |= SEC_EXCLUDE;
3323
          continue;
3324
        }
3325
 
3326
      if ((s->flags & SEC_HAS_CONTENTS) == 0)
3327
        continue;
3328
 
3329
      /* Allocate memory for the section contents.  */
3330
      /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
3331
         Unused entries should be reclaimed before the section's contents
3332
         are written out, but at the moment this does not happen.  Thus in
3333
         order to prevent writing out garbage, we initialise the section's
3334
         contents to zero.  */
3335
      s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
3336
      if (s->contents == NULL)
3337
        return FALSE;
3338
    }
3339
 
3340
  if (elf_hash_table (info)->dynamic_sections_created)
3341
    {
3342
      /* Add some entries to the .dynamic section.  We fill in the
3343
         values later, in elf_m68k_finish_dynamic_sections, but we
3344
         must add the entries now so that we get the correct size for
3345
         the .dynamic section.  The DT_DEBUG entry is filled in by the
3346
         dynamic linker and used by the debugger.  */
3347
#define add_dynamic_entry(TAG, VAL) \
3348
  _bfd_elf_add_dynamic_entry (info, TAG, VAL)
3349
 
3350
      if (!info->shared)
3351
        {
3352
          if (!add_dynamic_entry (DT_DEBUG, 0))
3353
            return FALSE;
3354
        }
3355
 
3356
      if (plt)
3357
        {
3358
          if (!add_dynamic_entry (DT_PLTGOT, 0)
3359
              || !add_dynamic_entry (DT_PLTRELSZ, 0)
3360
              || !add_dynamic_entry (DT_PLTREL, DT_RELA)
3361
              || !add_dynamic_entry (DT_JMPREL, 0))
3362
            return FALSE;
3363
        }
3364
 
3365
      if (relocs)
3366
        {
3367
          if (!add_dynamic_entry (DT_RELA, 0)
3368
              || !add_dynamic_entry (DT_RELASZ, 0)
3369
              || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
3370
            return FALSE;
3371
        }
3372
 
3373
      if ((info->flags & DF_TEXTREL) != 0)
3374
        {
3375
          if (!add_dynamic_entry (DT_TEXTREL, 0))
3376
            return FALSE;
3377
        }
3378
    }
3379
#undef add_dynamic_entry
3380
 
3381
  return TRUE;
3382
}
3383
 
3384
/* This function is called via elf_link_hash_traverse if we are
3385
   creating a shared object.  In the -Bsymbolic case it discards the
3386
   space allocated to copy PC relative relocs against symbols which
3387
   are defined in regular objects.  For the normal shared case, it
3388
   discards space for pc-relative relocs that have become local due to
3389
   symbol visibility changes.  We allocated space for them in the
3390
   check_relocs routine, but we won't fill them in in the
3391
   relocate_section routine.
3392
 
3393
   We also check whether any of the remaining relocations apply
3394
   against a readonly section, and set the DF_TEXTREL flag in this
3395
   case.  */
3396
 
3397
static bfd_boolean
3398
elf_m68k_discard_copies (h, inf)
3399
     struct elf_link_hash_entry *h;
3400
     PTR inf;
3401
{
3402
  struct bfd_link_info *info = (struct bfd_link_info *) inf;
3403
  struct elf_m68k_pcrel_relocs_copied *s;
3404
 
3405
  if (h->root.type == bfd_link_hash_warning)
3406
    h = (struct elf_link_hash_entry *) h->root.u.i.link;
3407
 
3408 225 jeremybenn
  if (!SYMBOL_CALLS_LOCAL (info, h))
3409 24 jeremybenn
    {
3410
      if ((info->flags & DF_TEXTREL) == 0)
3411
        {
3412
          /* Look for relocations against read-only sections.  */
3413
          for (s = elf_m68k_hash_entry (h)->pcrel_relocs_copied;
3414
               s != NULL;
3415
               s = s->next)
3416
            if ((s->section->flags & SEC_READONLY) != 0)
3417
              {
3418
                info->flags |= DF_TEXTREL;
3419
                break;
3420
              }
3421
        }
3422
 
3423
      return TRUE;
3424
    }
3425
 
3426
  for (s = elf_m68k_hash_entry (h)->pcrel_relocs_copied;
3427
       s != NULL;
3428
       s = s->next)
3429
    s->section->size -= s->count * sizeof (Elf32_External_Rela);
3430
 
3431
  return TRUE;
3432
}
3433
 
3434 225 jeremybenn
 
3435
/* Install relocation RELA.  */
3436
 
3437
static void
3438
elf_m68k_install_rela (bfd *output_bfd,
3439
                       asection *srela,
3440
                       Elf_Internal_Rela *rela)
3441
{
3442
  bfd_byte *loc;
3443
 
3444
  loc = srela->contents;
3445
  loc += srela->reloc_count++ * sizeof (Elf32_External_Rela);
3446
  bfd_elf32_swap_reloca_out (output_bfd, rela, loc);
3447
}
3448
 
3449
/* Find the base offsets for thread-local storage in this object,
3450
   for GD/LD and IE/LE respectively.  */
3451
 
3452
#define DTP_OFFSET 0x8000
3453
#define TP_OFFSET  0x7000
3454
 
3455
static bfd_vma
3456
dtpoff_base (struct bfd_link_info *info)
3457
{
3458
  /* If tls_sec is NULL, we should have signalled an error already.  */
3459
  if (elf_hash_table (info)->tls_sec == NULL)
3460
    return 0;
3461
  return elf_hash_table (info)->tls_sec->vma + DTP_OFFSET;
3462
}
3463
 
3464
static bfd_vma
3465
tpoff_base (struct bfd_link_info *info)
3466
{
3467
  /* If tls_sec is NULL, we should have signalled an error already.  */
3468
  if (elf_hash_table (info)->tls_sec == NULL)
3469
    return 0;
3470
  return elf_hash_table (info)->tls_sec->vma + TP_OFFSET;
3471
}
3472
 
3473
/* Output necessary relocation to handle a symbol during static link.
3474
   This function is called from elf_m68k_relocate_section.  */
3475
 
3476
static void
3477
elf_m68k_init_got_entry_static (struct bfd_link_info *info,
3478
                                bfd *output_bfd,
3479
                                enum elf_m68k_reloc_type r_type,
3480
                                asection *sgot,
3481
                                bfd_vma got_entry_offset,
3482
                                bfd_vma relocation)
3483
{
3484
  switch (elf_m68k_reloc_got_type (r_type))
3485
    {
3486
    case R_68K_GOT32O:
3487
      bfd_put_32 (output_bfd, relocation, sgot->contents + got_entry_offset);
3488
      break;
3489
 
3490
    case R_68K_TLS_GD32:
3491
      /* We know the offset within the module,
3492
         put it into the second GOT slot.  */
3493
      bfd_put_32 (output_bfd, relocation - dtpoff_base (info),
3494
                  sgot->contents + got_entry_offset + 4);
3495
      /* FALLTHRU */
3496
 
3497
    case R_68K_TLS_LDM32:
3498
      /* Mark it as belonging to module 1, the executable.  */
3499
      bfd_put_32 (output_bfd, 1, sgot->contents + got_entry_offset);
3500
      break;
3501
 
3502
    case R_68K_TLS_IE32:
3503
      bfd_put_32 (output_bfd, relocation - tpoff_base (info),
3504
                  sgot->contents + got_entry_offset);
3505
      break;
3506
 
3507
    default:
3508
      BFD_ASSERT (FALSE);
3509
    }
3510
}
3511
 
3512
/* Output necessary relocation to handle a local symbol
3513
   during dynamic link.
3514
   This function is called either from elf_m68k_relocate_section
3515
   or from elf_m68k_finish_dynamic_symbol.  */
3516
 
3517
static void
3518
elf_m68k_init_got_entry_local_shared (struct bfd_link_info *info,
3519
                                      bfd *output_bfd,
3520
                                      enum elf_m68k_reloc_type r_type,
3521
                                      asection *sgot,
3522
                                      bfd_vma got_entry_offset,
3523
                                      bfd_vma relocation,
3524
                                      asection *srela)
3525
{
3526
  Elf_Internal_Rela outrel;
3527
 
3528
  switch (elf_m68k_reloc_got_type (r_type))
3529
    {
3530
    case R_68K_GOT32O:
3531
      /* Emit RELATIVE relocation to initialize GOT slot
3532
         at run-time.  */
3533
      outrel.r_info = ELF32_R_INFO (0, R_68K_RELATIVE);
3534
      outrel.r_addend = relocation;
3535
      break;
3536
 
3537
    case R_68K_TLS_GD32:
3538
      /* We know the offset within the module,
3539
         put it into the second GOT slot.  */
3540
      bfd_put_32 (output_bfd, relocation - dtpoff_base (info),
3541
                  sgot->contents + got_entry_offset + 4);
3542
      /* FALLTHRU */
3543
 
3544
    case R_68K_TLS_LDM32:
3545
      /* We don't know the module number,
3546
         create a relocation for it.  */
3547
      outrel.r_info = ELF32_R_INFO (0, R_68K_TLS_DTPMOD32);
3548
      outrel.r_addend = 0;
3549
      break;
3550
 
3551
    case R_68K_TLS_IE32:
3552
      /* Emit TPREL relocation to initialize GOT slot
3553
         at run-time.  */
3554
      outrel.r_info = ELF32_R_INFO (0, R_68K_TLS_TPREL32);
3555
      outrel.r_addend = relocation - elf_hash_table (info)->tls_sec->vma;
3556
      break;
3557
 
3558
    default:
3559
      BFD_ASSERT (FALSE);
3560
    }
3561
 
3562
  /* Offset of the GOT entry.  */
3563
  outrel.r_offset = (sgot->output_section->vma
3564
                     + sgot->output_offset
3565
                     + got_entry_offset);
3566
 
3567
  /* Install one of the above relocations.  */
3568
  elf_m68k_install_rela (output_bfd, srela, &outrel);
3569
 
3570
  bfd_put_32 (output_bfd, outrel.r_addend, sgot->contents + got_entry_offset);
3571
}
3572
 
3573 24 jeremybenn
/* Relocate an M68K ELF section.  */
3574
 
3575
static bfd_boolean
3576
elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
3577
                           contents, relocs, local_syms, local_sections)
3578
     bfd *output_bfd;
3579
     struct bfd_link_info *info;
3580
     bfd *input_bfd;
3581
     asection *input_section;
3582
     bfd_byte *contents;
3583
     Elf_Internal_Rela *relocs;
3584
     Elf_Internal_Sym *local_syms;
3585
     asection **local_sections;
3586
{
3587
  bfd *dynobj;
3588
  Elf_Internal_Shdr *symtab_hdr;
3589
  struct elf_link_hash_entry **sym_hashes;
3590
  asection *sgot;
3591
  asection *splt;
3592
  asection *sreloc;
3593 225 jeremybenn
  asection *srela;
3594
  struct elf_m68k_got *got;
3595 24 jeremybenn
  Elf_Internal_Rela *rel;
3596
  Elf_Internal_Rela *relend;
3597
 
3598
  dynobj = elf_hash_table (info)->dynobj;
3599
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
3600
  sym_hashes = elf_sym_hashes (input_bfd);
3601
 
3602
  sgot = NULL;
3603
  splt = NULL;
3604
  sreloc = NULL;
3605 225 jeremybenn
  srela = NULL;
3606 24 jeremybenn
 
3607 225 jeremybenn
  got = NULL;
3608
 
3609 24 jeremybenn
  rel = relocs;
3610
  relend = relocs + input_section->reloc_count;
3611
  for (; rel < relend; rel++)
3612
    {
3613
      int r_type;
3614
      reloc_howto_type *howto;
3615
      unsigned long r_symndx;
3616
      struct elf_link_hash_entry *h;
3617
      Elf_Internal_Sym *sym;
3618
      asection *sec;
3619
      bfd_vma relocation;
3620
      bfd_boolean unresolved_reloc;
3621
      bfd_reloc_status_type r;
3622
 
3623
      r_type = ELF32_R_TYPE (rel->r_info);
3624
      if (r_type < 0 || r_type >= (int) R_68K_max)
3625
        {
3626
          bfd_set_error (bfd_error_bad_value);
3627
          return FALSE;
3628
        }
3629
      howto = howto_table + r_type;
3630
 
3631
      r_symndx = ELF32_R_SYM (rel->r_info);
3632
 
3633
      h = NULL;
3634
      sym = NULL;
3635
      sec = NULL;
3636
      unresolved_reloc = FALSE;
3637
 
3638
      if (r_symndx < symtab_hdr->sh_info)
3639
        {
3640
          sym = local_syms + r_symndx;
3641
          sec = local_sections[r_symndx];
3642
          relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
3643
        }
3644
      else
3645
        {
3646
          bfd_boolean warned;
3647
 
3648
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
3649
                                   r_symndx, symtab_hdr, sym_hashes,
3650
                                   h, sec, relocation,
3651
                                   unresolved_reloc, warned);
3652
        }
3653
 
3654
      if (sec != NULL && elf_discarded_section (sec))
3655
        {
3656
          /* For relocs against symbols from removed linkonce sections,
3657
             or sections discarded by a linker script, we just want the
3658
             section contents zeroed.  Avoid any special processing.  */
3659
          _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
3660
          rel->r_info = 0;
3661
          rel->r_addend = 0;
3662
          continue;
3663
        }
3664
 
3665
      if (info->relocatable)
3666
        continue;
3667
 
3668
      switch (r_type)
3669
        {
3670
        case R_68K_GOT8:
3671
        case R_68K_GOT16:
3672
        case R_68K_GOT32:
3673
          /* Relocation is to the address of the entry for this symbol
3674
             in the global offset table.  */
3675
          if (h != NULL
3676
              && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
3677 225 jeremybenn
            {
3678
              if (elf_m68k_hash_table (info)->local_gp_p)
3679
                {
3680
                  bfd_vma sgot_output_offset;
3681
                  bfd_vma got_offset;
3682
 
3683
                  if (sgot == NULL)
3684
                    {
3685
                      sgot = bfd_get_section_by_name (dynobj, ".got");
3686
 
3687
                      if (sgot != NULL)
3688
                        sgot_output_offset = sgot->output_offset;
3689
                      else
3690
                        /* In this case we have a reference to
3691
                           _GLOBAL_OFFSET_TABLE_, but the GOT itself is
3692
                           empty.
3693
                           ??? Issue a warning?  */
3694
                        sgot_output_offset = 0;
3695
                    }
3696
                  else
3697
                    sgot_output_offset = sgot->output_offset;
3698
 
3699
                  if (got == NULL)
3700
                    {
3701
                      struct elf_m68k_bfd2got_entry *bfd2got_entry;
3702
 
3703
                      bfd2got_entry
3704
                        = elf_m68k_get_bfd2got_entry (elf_m68k_multi_got (info),
3705
                                                      input_bfd, SEARCH, NULL);
3706
 
3707
                      if (bfd2got_entry != NULL)
3708
                        {
3709
                          got = bfd2got_entry->got;
3710
                          BFD_ASSERT (got != NULL);
3711
 
3712
                          got_offset = got->offset;
3713
                        }
3714
                      else
3715
                        /* In this case we have a reference to
3716
                           _GLOBAL_OFFSET_TABLE_, but no other references
3717
                           accessing any GOT entries.
3718
                           ??? Issue a warning?  */
3719
                        got_offset = 0;
3720
                    }
3721
                  else
3722
                    got_offset = got->offset;
3723
 
3724
                  /* Adjust GOT pointer to point to the GOT
3725
                     assigned to input_bfd.  */
3726
                  rel->r_addend += sgot_output_offset + got_offset;
3727
                }
3728
              else
3729
                BFD_ASSERT (got == NULL || got->offset == 0);
3730
 
3731
              break;
3732
            }
3733 24 jeremybenn
          /* Fall through.  */
3734
        case R_68K_GOT8O:
3735
        case R_68K_GOT16O:
3736
        case R_68K_GOT32O:
3737 225 jeremybenn
 
3738
        case R_68K_TLS_LDM32:
3739
        case R_68K_TLS_LDM16:
3740
        case R_68K_TLS_LDM8:
3741
 
3742
        case R_68K_TLS_GD8:
3743
        case R_68K_TLS_GD16:
3744
        case R_68K_TLS_GD32:
3745
 
3746
        case R_68K_TLS_IE8:
3747
        case R_68K_TLS_IE16:
3748
        case R_68K_TLS_IE32:
3749
 
3750 24 jeremybenn
          /* Relocation is the offset of the entry for this symbol in
3751
             the global offset table.  */
3752
 
3753
          {
3754 225 jeremybenn
            struct elf_m68k_got_entry_key key_;
3755
            bfd_vma *off_ptr;
3756 24 jeremybenn
            bfd_vma off;
3757
 
3758
            if (sgot == NULL)
3759
              {
3760
                sgot = bfd_get_section_by_name (dynobj, ".got");
3761
                BFD_ASSERT (sgot != NULL);
3762
              }
3763
 
3764 225 jeremybenn
            if (got == NULL)
3765 24 jeremybenn
              {
3766 225 jeremybenn
                got = elf_m68k_get_bfd2got_entry (elf_m68k_multi_got (info),
3767
                                                  input_bfd, MUST_FIND,
3768
                                                  NULL)->got;
3769
                BFD_ASSERT (got != NULL);
3770
              }
3771 24 jeremybenn
 
3772 225 jeremybenn
            /* Get GOT offset for this symbol.  */
3773
            elf_m68k_init_got_entry_key (&key_, h, input_bfd, r_symndx,
3774
                                         r_type);
3775
            off_ptr = &elf_m68k_get_got_entry (got, &key_, MUST_FIND,
3776
                                               NULL)->u.s2.offset;
3777
            off = *off_ptr;
3778 24 jeremybenn
 
3779 225 jeremybenn
            /* The offset must always be a multiple of 4.  We use
3780
               the least significant bit to record whether we have
3781
               already generated the necessary reloc.  */
3782
            if ((off & 1) != 0)
3783
              off &= ~1;
3784
            else
3785
              {
3786
                if (h != NULL
3787
                    /* @TLSLDM relocations are bounded to the module, in
3788
                       which the symbol is defined -- not to the symbol
3789
                       itself.  */
3790
                    && elf_m68k_reloc_got_type (r_type) != R_68K_TLS_LDM32)
3791 24 jeremybenn
                  {
3792 225 jeremybenn
                    bfd_boolean dyn;
3793 24 jeremybenn
 
3794 225 jeremybenn
                    dyn = elf_hash_table (info)->dynamic_sections_created;
3795
                    if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
3796
                        || (info->shared
3797
                            && SYMBOL_REFERENCES_LOCAL (info, h))
3798
                        || (ELF_ST_VISIBILITY (h->other)
3799
                            && h->root.type == bfd_link_hash_undefweak))
3800 24 jeremybenn
                      {
3801 225 jeremybenn
                        /* This is actually a static link, or it is a
3802
                           -Bsymbolic link and the symbol is defined
3803
                           locally, or the symbol was forced to be local
3804
                           because of a version file.  We must initialize
3805
                           this entry in the global offset table.  Since
3806
                           the offset must always be a multiple of 4, we
3807
                           use the least significant bit to record whether
3808
                           we have initialized it already.
3809
 
3810
                           When doing a dynamic link, we create a .rela.got
3811
                           relocation entry to initialize the value.  This
3812
                           is done in the finish_dynamic_symbol routine.  */
3813
 
3814
                        elf_m68k_init_got_entry_static (info,
3815
                                                        output_bfd,
3816
                                                        r_type,
3817
                                                        sgot,
3818
                                                        off,
3819
                                                        relocation);
3820
 
3821
                        *off_ptr |= 1;
3822 24 jeremybenn
                      }
3823 225 jeremybenn
                    else
3824
                      unresolved_reloc = FALSE;
3825 24 jeremybenn
                  }
3826 225 jeremybenn
                else if (info->shared) /* && h == NULL */
3827
                  /* Process local symbol during dynamic link.  */
3828 24 jeremybenn
                  {
3829 225 jeremybenn
                    if (srela == NULL)
3830 24 jeremybenn
                      {
3831 225 jeremybenn
                        srela = bfd_get_section_by_name (dynobj, ".rela.got");
3832
                        BFD_ASSERT (srela != NULL);
3833
                      }
3834 24 jeremybenn
 
3835 225 jeremybenn
                    elf_m68k_init_got_entry_local_shared (info,
3836
                                                          output_bfd,
3837
                                                          r_type,
3838
                                                          sgot,
3839
                                                          off,
3840
                                                          relocation,
3841
                                                          srela);
3842 24 jeremybenn
 
3843 225 jeremybenn
                    *off_ptr |= 1;
3844
                  }
3845
                else /* h == NULL && !info->shared */
3846
                  {
3847
                    elf_m68k_init_got_entry_static (info,
3848
                                                    output_bfd,
3849
                                                    r_type,
3850
                                                    sgot,
3851
                                                    off,
3852
                                                    relocation);
3853 24 jeremybenn
 
3854 225 jeremybenn
                    *off_ptr |= 1;
3855 24 jeremybenn
                  }
3856
              }
3857
 
3858 225 jeremybenn
            /* We don't use elf_m68k_reloc_got_type in the condition below
3859
               because this is the only place where difference between
3860
               R_68K_GOTx and R_68K_GOTxO relocations matters.  */
3861
            if (r_type == R_68K_GOT32O
3862 24 jeremybenn
                || r_type == R_68K_GOT16O
3863 225 jeremybenn
                || r_type == R_68K_GOT8O
3864
                || elf_m68k_reloc_got_type (r_type) == R_68K_TLS_GD32
3865
                || elf_m68k_reloc_got_type (r_type) == R_68K_TLS_LDM32
3866
                || elf_m68k_reloc_got_type (r_type) == R_68K_TLS_IE32)
3867 24 jeremybenn
              {
3868 225 jeremybenn
                /* GOT pointer is adjusted to point to the start/middle
3869
                   of local GOT.  Adjust the offset accordingly.  */
3870
                BFD_ASSERT (elf_m68k_hash_table (info)->use_neg_got_offsets_p
3871
                            || off >= got->offset);
3872
 
3873
                if (elf_m68k_hash_table (info)->local_gp_p)
3874
                  relocation = off - got->offset;
3875
                else
3876
                  {
3877
                    BFD_ASSERT (got->offset == 0);
3878
                    relocation = sgot->output_offset + off;
3879
                  }
3880
 
3881 24 jeremybenn
                /* This relocation does not use the addend.  */
3882
                rel->r_addend = 0;
3883
              }
3884
            else
3885 225 jeremybenn
              relocation = (sgot->output_section->vma + sgot->output_offset
3886
                            + off);
3887 24 jeremybenn
          }
3888
          break;
3889
 
3890 225 jeremybenn
        case R_68K_TLS_LDO32:
3891
        case R_68K_TLS_LDO16:
3892
        case R_68K_TLS_LDO8:
3893
          relocation -= dtpoff_base (info);
3894
          break;
3895
 
3896
        case R_68K_TLS_LE32:
3897
        case R_68K_TLS_LE16:
3898
        case R_68K_TLS_LE8:
3899
          if (info->shared)
3900
            {
3901
              (*_bfd_error_handler)
3902
                (_("%B(%A+0x%lx): R_68K_TLS_LE32 relocation not permitted "
3903
                   "in shared object"),
3904
                 input_bfd, input_section, (long) rel->r_offset, howto->name);
3905
 
3906
              return FALSE;
3907
            }
3908
          else
3909
            relocation -= tpoff_base (info);
3910
 
3911
          break;
3912
 
3913 24 jeremybenn
        case R_68K_PLT8:
3914
        case R_68K_PLT16:
3915
        case R_68K_PLT32:
3916
          /* Relocation is to the entry for this symbol in the
3917
             procedure linkage table.  */
3918
 
3919
          /* Resolve a PLTxx reloc against a local symbol directly,
3920
             without using the procedure linkage table.  */
3921
          if (h == NULL)
3922
            break;
3923
 
3924
          if (h->plt.offset == (bfd_vma) -1
3925
              || !elf_hash_table (info)->dynamic_sections_created)
3926
            {
3927
              /* We didn't make a PLT entry for this symbol.  This
3928
                 happens when statically linking PIC code, or when
3929
                 using -Bsymbolic.  */
3930
              break;
3931
            }
3932
 
3933
          if (splt == NULL)
3934
            {
3935
              splt = bfd_get_section_by_name (dynobj, ".plt");
3936
              BFD_ASSERT (splt != NULL);
3937
            }
3938
 
3939
          relocation = (splt->output_section->vma
3940
                        + splt->output_offset
3941
                        + h->plt.offset);
3942
          unresolved_reloc = FALSE;
3943
          break;
3944
 
3945
        case R_68K_PLT8O:
3946
        case R_68K_PLT16O:
3947
        case R_68K_PLT32O:
3948
          /* Relocation is the offset of the entry for this symbol in
3949
             the procedure linkage table.  */
3950
          BFD_ASSERT (h != NULL && h->plt.offset != (bfd_vma) -1);
3951
 
3952
          if (splt == NULL)
3953
            {
3954
              splt = bfd_get_section_by_name (dynobj, ".plt");
3955
              BFD_ASSERT (splt != NULL);
3956
            }
3957
 
3958
          relocation = h->plt.offset;
3959
          unresolved_reloc = FALSE;
3960
 
3961
          /* This relocation does not use the addend.  */
3962
          rel->r_addend = 0;
3963
 
3964
          break;
3965
 
3966 225 jeremybenn
        case R_68K_8:
3967
        case R_68K_16:
3968
        case R_68K_32:
3969 24 jeremybenn
        case R_68K_PC8:
3970
        case R_68K_PC16:
3971
        case R_68K_PC32:
3972
          if (info->shared
3973
              && r_symndx != 0
3974
              && (input_section->flags & SEC_ALLOC) != 0
3975
              && (h == NULL
3976
                  || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
3977
                  || h->root.type != bfd_link_hash_undefweak)
3978
              && ((r_type != R_68K_PC8
3979
                   && r_type != R_68K_PC16
3980
                   && r_type != R_68K_PC32)
3981 225 jeremybenn
                  || !SYMBOL_CALLS_LOCAL (info, h)))
3982 24 jeremybenn
            {
3983
              Elf_Internal_Rela outrel;
3984
              bfd_byte *loc;
3985
              bfd_boolean skip, relocate;
3986
 
3987
              /* When generating a shared object, these relocations
3988
                 are copied into the output file to be resolved at run
3989
                 time.  */
3990
 
3991
              skip = FALSE;
3992
              relocate = FALSE;
3993
 
3994
              outrel.r_offset =
3995
                _bfd_elf_section_offset (output_bfd, info, input_section,
3996
                                         rel->r_offset);
3997
              if (outrel.r_offset == (bfd_vma) -1)
3998
                skip = TRUE;
3999
              else if (outrel.r_offset == (bfd_vma) -2)
4000
                skip = TRUE, relocate = TRUE;
4001
              outrel.r_offset += (input_section->output_section->vma
4002
                                  + input_section->output_offset);
4003
 
4004
              if (skip)
4005
                memset (&outrel, 0, sizeof outrel);
4006
              else if (h != NULL
4007
                       && h->dynindx != -1
4008
                       && (r_type == R_68K_PC8
4009
                           || r_type == R_68K_PC16
4010
                           || r_type == R_68K_PC32
4011
                           || !info->shared
4012
                           || !info->symbolic
4013
                           || !h->def_regular))
4014
                {
4015
                  outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
4016
                  outrel.r_addend = rel->r_addend;
4017
                }
4018
              else
4019
                {
4020
                  /* This symbol is local, or marked to become local.  */
4021
                  outrel.r_addend = relocation + rel->r_addend;
4022
 
4023
                  if (r_type == R_68K_32)
4024
                    {
4025
                      relocate = TRUE;
4026
                      outrel.r_info = ELF32_R_INFO (0, R_68K_RELATIVE);
4027
                    }
4028
                  else
4029
                    {
4030
                      long indx;
4031
 
4032
                      if (bfd_is_abs_section (sec))
4033
                        indx = 0;
4034
                      else if (sec == NULL || sec->owner == NULL)
4035
                        {
4036
                          bfd_set_error (bfd_error_bad_value);
4037
                          return FALSE;
4038
                        }
4039
                      else
4040
                        {
4041
                          asection *osec;
4042
 
4043
                          /* We are turning this relocation into one
4044
                             against a section symbol.  It would be
4045
                             proper to subtract the symbol's value,
4046
                             osec->vma, from the emitted reloc addend,
4047
                             but ld.so expects buggy relocs.  */
4048
                          osec = sec->output_section;
4049
                          indx = elf_section_data (osec)->dynindx;
4050
                          if (indx == 0)
4051
                            {
4052
                              struct elf_link_hash_table *htab;
4053
                              htab = elf_hash_table (info);
4054
                              osec = htab->text_index_section;
4055
                              indx = elf_section_data (osec)->dynindx;
4056
                            }
4057
                          BFD_ASSERT (indx != 0);
4058
                        }
4059
 
4060
                      outrel.r_info = ELF32_R_INFO (indx, r_type);
4061
                    }
4062
                }
4063
 
4064
              sreloc = elf_section_data (input_section)->sreloc;
4065
              if (sreloc == NULL)
4066
                abort ();
4067
 
4068
              loc = sreloc->contents;
4069
              loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
4070
              bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
4071
 
4072
              /* This reloc will be computed at runtime, so there's no
4073
                 need to do anything now, except for R_68K_32
4074
                 relocations that have been turned into
4075
                 R_68K_RELATIVE.  */
4076
              if (!relocate)
4077
                continue;
4078
            }
4079
 
4080
          break;
4081
 
4082
        case R_68K_GNU_VTINHERIT:
4083
        case R_68K_GNU_VTENTRY:
4084
          /* These are no-ops in the end.  */
4085
          continue;
4086
 
4087
        default:
4088
          break;
4089
        }
4090
 
4091
      /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
4092
         because such sections are not SEC_ALLOC and thus ld.so will
4093
         not process them.  */
4094
      if (unresolved_reloc
4095
          && !((input_section->flags & SEC_DEBUGGING) != 0
4096
               && h->def_dynamic))
4097
        {
4098
          (*_bfd_error_handler)
4099
            (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
4100
             input_bfd,
4101
             input_section,
4102
             (long) rel->r_offset,
4103
             howto->name,
4104
             h->root.root.string);
4105
          return FALSE;
4106
        }
4107
 
4108 225 jeremybenn
      if (r_symndx != 0
4109
          && r_type != R_68K_NONE
4110
          && (h == NULL
4111
              || h->root.type == bfd_link_hash_defined
4112
              || h->root.type == bfd_link_hash_defweak))
4113
        {
4114
          char sym_type;
4115
 
4116
          sym_type = (sym != NULL) ? ELF32_ST_TYPE (sym->st_info) : h->type;
4117
 
4118
          if (elf_m68k_reloc_tls_p (r_type) != (sym_type == STT_TLS))
4119
            {
4120
              const char *name;
4121
 
4122
              if (h != NULL)
4123
                name = h->root.root.string;
4124
              else
4125
                {
4126
                  name = (bfd_elf_string_from_elf_section
4127
                          (input_bfd, symtab_hdr->sh_link, sym->st_name));
4128
                  if (name == NULL || *name == '\0')
4129
                    name = bfd_section_name (input_bfd, sec);
4130
                }
4131
 
4132
              (*_bfd_error_handler)
4133
                ((sym_type == STT_TLS
4134
                  ? _("%B(%A+0x%lx): %s used with TLS symbol %s")
4135
                  : _("%B(%A+0x%lx): %s used with non-TLS symbol %s")),
4136
                 input_bfd,
4137
                 input_section,
4138
                 (long) rel->r_offset,
4139
                 howto->name,
4140
                 name);
4141
            }
4142
        }
4143
 
4144 24 jeremybenn
      r = _bfd_final_link_relocate (howto, input_bfd, input_section,
4145
                                    contents, rel->r_offset,
4146
                                    relocation, rel->r_addend);
4147
 
4148
      if (r != bfd_reloc_ok)
4149
        {
4150
          const char *name;
4151
 
4152
          if (h != NULL)
4153
            name = h->root.root.string;
4154
          else
4155
            {
4156
              name = bfd_elf_string_from_elf_section (input_bfd,
4157
                                                      symtab_hdr->sh_link,
4158
                                                      sym->st_name);
4159
              if (name == NULL)
4160
                return FALSE;
4161
              if (*name == '\0')
4162
                name = bfd_section_name (input_bfd, sec);
4163
            }
4164
 
4165
          if (r == bfd_reloc_overflow)
4166
            {
4167
              if (!(info->callbacks->reloc_overflow
4168
                    (info, (h ? &h->root : NULL), name, howto->name,
4169
                     (bfd_vma) 0, input_bfd, input_section,
4170
                     rel->r_offset)))
4171
                return FALSE;
4172
            }
4173
          else
4174
            {
4175
              (*_bfd_error_handler)
4176
                (_("%B(%A+0x%lx): reloc against `%s': error %d"),
4177
                 input_bfd, input_section,
4178
                 (long) rel->r_offset, name, (int) r);
4179
              return FALSE;
4180
            }
4181
        }
4182
    }
4183
 
4184
  return TRUE;
4185
}
4186
 
4187
/* Install an M_68K_PC32 relocation against VALUE at offset OFFSET
4188
   into section SEC.  */
4189
 
4190
static void
4191
elf_m68k_install_pc32 (asection *sec, bfd_vma offset, bfd_vma value)
4192
{
4193
  /* Make VALUE PC-relative.  */
4194
  value -= sec->output_section->vma + offset;
4195
 
4196
  /* Apply any in-place addend.  */
4197
  value += bfd_get_32 (sec->owner, sec->contents + offset);
4198
 
4199
  bfd_put_32 (sec->owner, value, sec->contents + offset);
4200
}
4201
 
4202
/* Finish up dynamic symbol handling.  We set the contents of various
4203
   dynamic sections here.  */
4204
 
4205
static bfd_boolean
4206
elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym)
4207
     bfd *output_bfd;
4208
     struct bfd_link_info *info;
4209
     struct elf_link_hash_entry *h;
4210
     Elf_Internal_Sym *sym;
4211
{
4212
  bfd *dynobj;
4213
 
4214
  dynobj = elf_hash_table (info)->dynobj;
4215
 
4216
  if (h->plt.offset != (bfd_vma) -1)
4217
    {
4218
      const struct elf_m68k_plt_info *plt_info;
4219
      asection *splt;
4220
      asection *sgot;
4221
      asection *srela;
4222
      bfd_vma plt_index;
4223
      bfd_vma got_offset;
4224
      Elf_Internal_Rela rela;
4225
      bfd_byte *loc;
4226
 
4227
      /* This symbol has an entry in the procedure linkage table.  Set
4228
         it up.  */
4229
 
4230
      BFD_ASSERT (h->dynindx != -1);
4231
 
4232
      plt_info = elf_m68k_hash_table (info)->plt_info;
4233
      splt = bfd_get_section_by_name (dynobj, ".plt");
4234
      sgot = bfd_get_section_by_name (dynobj, ".got.plt");
4235
      srela = bfd_get_section_by_name (dynobj, ".rela.plt");
4236
      BFD_ASSERT (splt != NULL && sgot != NULL && srela != NULL);
4237
 
4238
      /* Get the index in the procedure linkage table which
4239
         corresponds to this symbol.  This is the index of this symbol
4240
         in all the symbols for which we are making plt entries.  The
4241
         first entry in the procedure linkage table is reserved.  */
4242
      plt_index = (h->plt.offset / plt_info->size) - 1;
4243
 
4244
      /* Get the offset into the .got table of the entry that
4245
         corresponds to this function.  Each .got entry is 4 bytes.
4246
         The first three are reserved.  */
4247
      got_offset = (plt_index + 3) * 4;
4248
 
4249
      memcpy (splt->contents + h->plt.offset,
4250
              plt_info->symbol_entry,
4251
              plt_info->size);
4252
 
4253
      elf_m68k_install_pc32 (splt, h->plt.offset + plt_info->symbol_relocs.got,
4254
                             (sgot->output_section->vma
4255
                              + sgot->output_offset
4256
                              + got_offset));
4257
 
4258
      bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rela),
4259
                  splt->contents
4260
                  + h->plt.offset
4261
                  + plt_info->symbol_resolve_entry + 2);
4262
 
4263
      elf_m68k_install_pc32 (splt, h->plt.offset + plt_info->symbol_relocs.plt,
4264
                             splt->output_section->vma);
4265
 
4266
      /* Fill in the entry in the global offset table.  */
4267
      bfd_put_32 (output_bfd,
4268
                  (splt->output_section->vma
4269
                   + splt->output_offset
4270
                   + h->plt.offset
4271
                   + plt_info->symbol_resolve_entry),
4272
                  sgot->contents + got_offset);
4273
 
4274
      /* Fill in the entry in the .rela.plt section.  */
4275
      rela.r_offset = (sgot->output_section->vma
4276
                       + sgot->output_offset
4277
                       + got_offset);
4278
      rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_JMP_SLOT);
4279
      rela.r_addend = 0;
4280
      loc = srela->contents + plt_index * sizeof (Elf32_External_Rela);
4281
      bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
4282
 
4283
      if (!h->def_regular)
4284
        {
4285
          /* Mark the symbol as undefined, rather than as defined in
4286
             the .plt section.  Leave the value alone.  */
4287
          sym->st_shndx = SHN_UNDEF;
4288
        }
4289
    }
4290
 
4291 225 jeremybenn
  if (elf_m68k_hash_entry (h)->glist != NULL)
4292 24 jeremybenn
    {
4293
      asection *sgot;
4294
      asection *srela;
4295 225 jeremybenn
      struct elf_m68k_got_entry *got_entry;
4296 24 jeremybenn
 
4297
      /* This symbol has an entry in the global offset table.  Set it
4298
         up.  */
4299
 
4300
      sgot = bfd_get_section_by_name (dynobj, ".got");
4301
      srela = bfd_get_section_by_name (dynobj, ".rela.got");
4302
      BFD_ASSERT (sgot != NULL && srela != NULL);
4303
 
4304 225 jeremybenn
      got_entry = elf_m68k_hash_entry (h)->glist;
4305 24 jeremybenn
 
4306 225 jeremybenn
      while (got_entry != NULL)
4307 24 jeremybenn
        {
4308 225 jeremybenn
          enum elf_m68k_reloc_type r_type;
4309
          bfd_vma got_entry_offset;
4310
 
4311
          r_type = got_entry->key_.type;
4312
          got_entry_offset = got_entry->u.s2.offset &~ (bfd_vma) 1;
4313
 
4314
          /* If this is a -Bsymbolic link, and the symbol is defined
4315
             locally, we just want to emit a RELATIVE reloc.  Likewise if
4316
             the symbol was forced to be local because of a version file.
4317
             The entry in the global offset table already have been
4318
             initialized in the relocate_section function.  */
4319
          if (info->shared
4320
              && SYMBOL_REFERENCES_LOCAL (info, h))
4321
            {
4322
              bfd_vma relocation;
4323
 
4324
              relocation = bfd_get_signed_32 (output_bfd,
4325
                                              (sgot->contents
4326
                                               + got_entry_offset));
4327
 
4328
              /* Undo TP bias.  */
4329
              switch (elf_m68k_reloc_got_type (r_type))
4330
                {
4331
                case R_68K_GOT32O:
4332
                case R_68K_TLS_LDM32:
4333
                  break;
4334
 
4335
                case R_68K_TLS_GD32:
4336
                  relocation += dtpoff_base (info);
4337
                  break;
4338
 
4339
                case R_68K_TLS_IE32:
4340
                  relocation += tpoff_base (info);
4341
                  break;
4342
 
4343
                default:
4344
                  BFD_ASSERT (FALSE);
4345
                }
4346
 
4347
              elf_m68k_init_got_entry_local_shared (info,
4348
                                                    output_bfd,
4349
                                                    r_type,
4350
                                                    sgot,
4351
                                                    got_entry_offset,
4352
                                                    relocation,
4353
                                                    srela);
4354
            }
4355
          else
4356
            {
4357
              Elf_Internal_Rela rela;
4358
 
4359
              /* Put zeros to GOT slots that will be initialized
4360
                 at run-time.  */
4361
              {
4362
                bfd_vma n_slots;
4363
 
4364
                n_slots = elf_m68k_reloc_got_n_slots (got_entry->key_.type);
4365
                while (n_slots--)
4366
                  bfd_put_32 (output_bfd, (bfd_vma) 0,
4367
                              (sgot->contents + got_entry_offset
4368
                               + 4 * n_slots));
4369
              }
4370
 
4371
              rela.r_addend = 0;
4372
              rela.r_offset = (sgot->output_section->vma
4373
                               + sgot->output_offset
4374
                               + got_entry_offset);
4375
 
4376
              switch (elf_m68k_reloc_got_type (r_type))
4377
                {
4378
                case R_68K_GOT32O:
4379
                  rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_GLOB_DAT);
4380
                  elf_m68k_install_rela (output_bfd, srela, &rela);
4381
                  break;
4382
 
4383
                case R_68K_TLS_GD32:
4384
                  rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_TLS_DTPMOD32);
4385
                  elf_m68k_install_rela (output_bfd, srela, &rela);
4386
 
4387
                  rela.r_offset += 4;
4388
                  rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_TLS_DTPREL32);
4389
                  elf_m68k_install_rela (output_bfd, srela, &rela);
4390
                  break;
4391
 
4392
                case R_68K_TLS_IE32:
4393
                  rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_TLS_TPREL32);
4394
                  elf_m68k_install_rela (output_bfd, srela, &rela);
4395
                  break;
4396
 
4397
                default:
4398
                  BFD_ASSERT (FALSE);
4399
                  break;
4400
                }
4401
            }
4402
 
4403
          got_entry = got_entry->u.s2.next;
4404 24 jeremybenn
        }
4405
    }
4406
 
4407
  if (h->needs_copy)
4408
    {
4409
      asection *s;
4410
      Elf_Internal_Rela rela;
4411
      bfd_byte *loc;
4412
 
4413
      /* This symbol needs a copy reloc.  Set it up.  */
4414
 
4415
      BFD_ASSERT (h->dynindx != -1
4416
                  && (h->root.type == bfd_link_hash_defined
4417
                      || h->root.type == bfd_link_hash_defweak));
4418
 
4419
      s = bfd_get_section_by_name (h->root.u.def.section->owner,
4420
                                   ".rela.bss");
4421
      BFD_ASSERT (s != NULL);
4422
 
4423
      rela.r_offset = (h->root.u.def.value
4424
                       + h->root.u.def.section->output_section->vma
4425
                       + h->root.u.def.section->output_offset);
4426
      rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_COPY);
4427
      rela.r_addend = 0;
4428
      loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
4429
      bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
4430
    }
4431
 
4432
  /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
4433
  if (strcmp (h->root.root.string, "_DYNAMIC") == 0
4434
      || h == elf_hash_table (info)->hgot)
4435
    sym->st_shndx = SHN_ABS;
4436
 
4437
  return TRUE;
4438
}
4439
 
4440
/* Finish up the dynamic sections.  */
4441
 
4442
static bfd_boolean
4443
elf_m68k_finish_dynamic_sections (output_bfd, info)
4444
     bfd *output_bfd;
4445
     struct bfd_link_info *info;
4446
{
4447
  bfd *dynobj;
4448
  asection *sgot;
4449
  asection *sdyn;
4450
 
4451
  dynobj = elf_hash_table (info)->dynobj;
4452
 
4453
  sgot = bfd_get_section_by_name (dynobj, ".got.plt");
4454
  BFD_ASSERT (sgot != NULL);
4455
  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
4456
 
4457
  if (elf_hash_table (info)->dynamic_sections_created)
4458
    {
4459
      asection *splt;
4460
      Elf32_External_Dyn *dyncon, *dynconend;
4461
 
4462
      splt = bfd_get_section_by_name (dynobj, ".plt");
4463
      BFD_ASSERT (splt != NULL && sdyn != NULL);
4464
 
4465
      dyncon = (Elf32_External_Dyn *) sdyn->contents;
4466
      dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
4467
      for (; dyncon < dynconend; dyncon++)
4468
        {
4469
          Elf_Internal_Dyn dyn;
4470
          const char *name;
4471
          asection *s;
4472
 
4473
          bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
4474
 
4475
          switch (dyn.d_tag)
4476
            {
4477
            default:
4478
              break;
4479
 
4480
            case DT_PLTGOT:
4481
              name = ".got";
4482
              goto get_vma;
4483
            case DT_JMPREL:
4484
              name = ".rela.plt";
4485
            get_vma:
4486
              s = bfd_get_section_by_name (output_bfd, name);
4487
              BFD_ASSERT (s != NULL);
4488
              dyn.d_un.d_ptr = s->vma;
4489
              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
4490
              break;
4491
 
4492
            case DT_PLTRELSZ:
4493
              s = bfd_get_section_by_name (output_bfd, ".rela.plt");
4494
              BFD_ASSERT (s != NULL);
4495
              dyn.d_un.d_val = s->size;
4496
              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
4497
              break;
4498
 
4499
            case DT_RELASZ:
4500
              /* The procedure linkage table relocs (DT_JMPREL) should
4501
                 not be included in the overall relocs (DT_RELA).
4502
                 Therefore, we override the DT_RELASZ entry here to
4503
                 make it not include the JMPREL relocs.  Since the
4504
                 linker script arranges for .rela.plt to follow all
4505
                 other relocation sections, we don't have to worry
4506
                 about changing the DT_RELA entry.  */
4507
              s = bfd_get_section_by_name (output_bfd, ".rela.plt");
4508
              if (s != NULL)
4509
                dyn.d_un.d_val -= s->size;
4510
              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
4511
              break;
4512
            }
4513
        }
4514
 
4515
      /* Fill in the first entry in the procedure linkage table.  */
4516
      if (splt->size > 0)
4517
        {
4518
          const struct elf_m68k_plt_info *plt_info;
4519
 
4520
          plt_info = elf_m68k_hash_table (info)->plt_info;
4521
          memcpy (splt->contents, plt_info->plt0_entry, plt_info->size);
4522
 
4523
          elf_m68k_install_pc32 (splt, plt_info->plt0_relocs.got4,
4524
                                 (sgot->output_section->vma
4525
                                  + sgot->output_offset
4526
                                  + 4));
4527
 
4528
          elf_m68k_install_pc32 (splt, plt_info->plt0_relocs.got8,
4529
                                 (sgot->output_section->vma
4530
                                  + sgot->output_offset
4531
                                  + 8));
4532
 
4533
          elf_section_data (splt->output_section)->this_hdr.sh_entsize
4534
            = plt_info->size;
4535
        }
4536
    }
4537
 
4538
  /* Fill in the first three entries in the global offset table.  */
4539
  if (sgot->size > 0)
4540
    {
4541
      if (sdyn == NULL)
4542
        bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
4543
      else
4544
        bfd_put_32 (output_bfd,
4545
                    sdyn->output_section->vma + sdyn->output_offset,
4546
                    sgot->contents);
4547
      bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 4);
4548
      bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 8);
4549
    }
4550
 
4551
  elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
4552
 
4553
  return TRUE;
4554
}
4555
 
4556
/* Given a .data section and a .emreloc in-memory section, store
4557
   relocation information into the .emreloc section which can be
4558
   used at runtime to relocate the section.  This is called by the
4559
   linker when the --embedded-relocs switch is used.  This is called
4560
   after the add_symbols entry point has been called for all the
4561
   objects, and before the final_link entry point is called.  */
4562
 
4563
bfd_boolean
4564
bfd_m68k_elf32_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
4565
     bfd *abfd;
4566
     struct bfd_link_info *info;
4567
     asection *datasec;
4568
     asection *relsec;
4569
     char **errmsg;
4570
{
4571
  Elf_Internal_Shdr *symtab_hdr;
4572
  Elf_Internal_Sym *isymbuf = NULL;
4573
  Elf_Internal_Rela *internal_relocs = NULL;
4574
  Elf_Internal_Rela *irel, *irelend;
4575
  bfd_byte *p;
4576
  bfd_size_type amt;
4577
 
4578
  BFD_ASSERT (! info->relocatable);
4579
 
4580
  *errmsg = NULL;
4581
 
4582
  if (datasec->reloc_count == 0)
4583
    return TRUE;
4584
 
4585
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
4586
 
4587
  /* Get a copy of the native relocations.  */
4588
  internal_relocs = (_bfd_elf_link_read_relocs
4589
                     (abfd, datasec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
4590
                      info->keep_memory));
4591
  if (internal_relocs == NULL)
4592
    goto error_return;
4593
 
4594
  amt = (bfd_size_type) datasec->reloc_count * 12;
4595
  relsec->contents = (bfd_byte *) bfd_alloc (abfd, amt);
4596
  if (relsec->contents == NULL)
4597
    goto error_return;
4598
 
4599
  p = relsec->contents;
4600
 
4601
  irelend = internal_relocs + datasec->reloc_count;
4602
  for (irel = internal_relocs; irel < irelend; irel++, p += 12)
4603
    {
4604
      asection *targetsec;
4605
 
4606
      /* We are going to write a four byte longword into the runtime
4607
       reloc section.  The longword will be the address in the data
4608
       section which must be relocated.  It is followed by the name
4609
       of the target section NUL-padded or truncated to 8
4610
       characters.  */
4611
 
4612
      /* We can only relocate absolute longword relocs at run time.  */
4613
      if (ELF32_R_TYPE (irel->r_info) != (int) R_68K_32)
4614
        {
4615
          *errmsg = _("unsupported reloc type");
4616
          bfd_set_error (bfd_error_bad_value);
4617
          goto error_return;
4618
        }
4619
 
4620
      /* Get the target section referred to by the reloc.  */
4621
      if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
4622
        {
4623
          /* A local symbol.  */
4624
          Elf_Internal_Sym *isym;
4625
 
4626
          /* Read this BFD's local symbols if we haven't done so already.  */
4627
          if (isymbuf == NULL)
4628
            {
4629
              isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
4630
              if (isymbuf == NULL)
4631
                isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
4632
                                                symtab_hdr->sh_info, 0,
4633
                                                NULL, NULL, NULL);
4634
              if (isymbuf == NULL)
4635
                goto error_return;
4636
            }
4637
 
4638
          isym = isymbuf + ELF32_R_SYM (irel->r_info);
4639
          targetsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
4640
        }
4641
      else
4642
        {
4643
          unsigned long indx;
4644
          struct elf_link_hash_entry *h;
4645
 
4646
          /* An external symbol.  */
4647
          indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
4648
          h = elf_sym_hashes (abfd)[indx];
4649
          BFD_ASSERT (h != NULL);
4650
          if (h->root.type == bfd_link_hash_defined
4651
              || h->root.type == bfd_link_hash_defweak)
4652
            targetsec = h->root.u.def.section;
4653
          else
4654
            targetsec = NULL;
4655
        }
4656
 
4657
      bfd_put_32 (abfd, irel->r_offset + datasec->output_offset, p);
4658
      memset (p + 4, 0, 8);
4659
      if (targetsec != NULL)
4660
        strncpy ((char *) p + 4, targetsec->output_section->name, 8);
4661
    }
4662
 
4663
  if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
4664
    free (isymbuf);
4665
  if (internal_relocs != NULL
4666
      && elf_section_data (datasec)->relocs != internal_relocs)
4667
    free (internal_relocs);
4668
  return TRUE;
4669
 
4670
error_return:
4671
  if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
4672
    free (isymbuf);
4673
  if (internal_relocs != NULL
4674
      && elf_section_data (datasec)->relocs != internal_relocs)
4675
    free (internal_relocs);
4676
  return FALSE;
4677
}
4678
 
4679 225 jeremybenn
/* Set target options.  */
4680
 
4681
void
4682
bfd_elf_m68k_set_target_options (struct bfd_link_info *info, int got_handling)
4683
{
4684
  struct elf_m68k_link_hash_table *htab;
4685
 
4686
  htab = elf_m68k_hash_table (info);
4687
 
4688
  switch (got_handling)
4689
    {
4690
    case 0:
4691
      /* --got=single.  */
4692
      htab->local_gp_p = FALSE;
4693
      htab->use_neg_got_offsets_p = FALSE;
4694
      htab->allow_multigot_p = FALSE;
4695
      break;
4696
 
4697
    case 1:
4698
      /* --got=negative.  */
4699
      htab->local_gp_p = TRUE;
4700
      htab->use_neg_got_offsets_p = TRUE;
4701
      htab->allow_multigot_p = FALSE;
4702
      break;
4703
 
4704
    case 2:
4705
      /* --got=multigot.  */
4706
      htab->local_gp_p = TRUE;
4707
      htab->use_neg_got_offsets_p = TRUE;
4708
      htab->allow_multigot_p = TRUE;
4709
      break;
4710
 
4711
    default:
4712
      BFD_ASSERT (FALSE);
4713
    }
4714
}
4715
 
4716 24 jeremybenn
static enum elf_reloc_type_class
4717
elf32_m68k_reloc_type_class (rela)
4718
     const Elf_Internal_Rela *rela;
4719
{
4720
  switch ((int) ELF32_R_TYPE (rela->r_info))
4721
    {
4722
    case R_68K_RELATIVE:
4723
      return reloc_class_relative;
4724
    case R_68K_JMP_SLOT:
4725
      return reloc_class_plt;
4726
    case R_68K_COPY:
4727
      return reloc_class_copy;
4728
    default:
4729
      return reloc_class_normal;
4730
    }
4731
}
4732
 
4733
/* Return address for Ith PLT stub in section PLT, for relocation REL
4734
   or (bfd_vma) -1 if it should not be included.  */
4735
 
4736
static bfd_vma
4737
elf_m68k_plt_sym_val (bfd_vma i, const asection *plt,
4738
                      const arelent *rel ATTRIBUTE_UNUSED)
4739
{
4740
  return plt->vma + (i + 1) * elf_m68k_get_plt_info (plt->owner)->size;
4741
}
4742
 
4743
#define TARGET_BIG_SYM                  bfd_elf32_m68k_vec
4744
#define TARGET_BIG_NAME                 "elf32-m68k"
4745
#define ELF_MACHINE_CODE                EM_68K
4746
#define ELF_MAXPAGESIZE                 0x2000
4747
#define elf_backend_create_dynamic_sections \
4748
                                        _bfd_elf_create_dynamic_sections
4749
#define bfd_elf32_bfd_link_hash_table_create \
4750
                                        elf_m68k_link_hash_table_create
4751 225 jeremybenn
/* ??? Should it be this macro or bfd_elfNN_bfd_link_hash_table_create?  */
4752
#define bfd_elf32_bfd_link_hash_table_free \
4753
                                        elf_m68k_link_hash_table_free
4754
#define bfd_elf32_bfd_final_link        bfd_elf_final_link
4755 24 jeremybenn
 
4756
#define elf_backend_check_relocs        elf_m68k_check_relocs
4757
#define elf_backend_always_size_sections \
4758
                                        elf_m68k_always_size_sections
4759
#define elf_backend_adjust_dynamic_symbol \
4760
                                        elf_m68k_adjust_dynamic_symbol
4761
#define elf_backend_size_dynamic_sections \
4762
                                        elf_m68k_size_dynamic_sections
4763
#define elf_backend_init_index_section  _bfd_elf_init_1_index_section
4764
#define elf_backend_relocate_section    elf_m68k_relocate_section
4765
#define elf_backend_finish_dynamic_symbol \
4766
                                        elf_m68k_finish_dynamic_symbol
4767
#define elf_backend_finish_dynamic_sections \
4768
                                        elf_m68k_finish_dynamic_sections
4769
#define elf_backend_gc_mark_hook        elf_m68k_gc_mark_hook
4770
#define elf_backend_gc_sweep_hook       elf_m68k_gc_sweep_hook
4771 225 jeremybenn
#define elf_backend_copy_indirect_symbol elf_m68k_copy_indirect_symbol
4772 24 jeremybenn
#define bfd_elf32_bfd_merge_private_bfd_data \
4773
                                        elf32_m68k_merge_private_bfd_data
4774
#define bfd_elf32_bfd_set_private_flags \
4775
                                        elf32_m68k_set_private_flags
4776
#define bfd_elf32_bfd_print_private_bfd_data \
4777
                                        elf32_m68k_print_private_bfd_data
4778
#define elf_backend_reloc_type_class    elf32_m68k_reloc_type_class
4779
#define elf_backend_plt_sym_val         elf_m68k_plt_sym_val
4780
#define elf_backend_object_p            elf32_m68k_object_p
4781
 
4782
#define elf_backend_can_gc_sections 1
4783
#define elf_backend_can_refcount 1
4784
#define elf_backend_want_got_plt 1
4785
#define elf_backend_plt_readonly 1
4786
#define elf_backend_want_plt_sym 0
4787
#define elf_backend_got_header_size     12
4788
#define elf_backend_rela_normal         1
4789
 
4790
#include "elf32-target.h"

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.