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

Subversion Repositories openrisc

[/] [openrisc/] [tags/] [gnu-src/] [gdb-7.2/] [gdb-7.2-or32-1.0rc1/] [bfd/] [elf32-cr16.c] - Blame information for rev 341

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 jeremybenn
/* BFD back-end for National Semiconductor's CR16 ELF
2
   Copyright 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
3
   Written by M R Swami Reddy.
4
 
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 Foundation,
19
   Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
20
 
21
#include "sysdep.h"
22
#include "bfd.h"
23
#include "bfdlink.h"
24
#include "libbfd.h"
25
#include "libiberty.h"
26
#include "elf-bfd.h"
27
#include "elf/cr16.h"
28
 
29
/* The cr16 linker needs to keep track of the number of relocs that
30
   it decides to copy in check_relocs for each symbol.  This is so
31
   that it can discard PC relative relocs if it doesn't need them when
32
   linking with -Bsymbolic.  We store the information in a field
33
   extending the regular ELF linker hash table.  */
34
 
35
struct elf32_cr16_link_hash_entry
36
{
37
  /* The basic elf link hash table entry.  */
38
  struct elf_link_hash_entry root;
39
 
40
  /* For function symbols, the number of times this function is
41
     called directly (ie by name).  */
42
  unsigned int direct_calls;
43
 
44
  /* For function symbols, the size of this function's stack
45
     (if <= 255 bytes).  We stuff this into "call" instructions
46
     to this target when it's valid and profitable to do so.
47
 
48
     This does not include stack allocated by movm!  */
49
  unsigned char stack_size;
50
 
51
  /* For function symbols, arguments (if any) for movm instruction
52
     in the prologue.  We stuff this value into "call" instructions
53
     to the target when it's valid and profitable to do so.  */
54
  unsigned char movm_args;
55
 
56
  /* For function symbols, the amount of stack space that would be allocated
57
     by the movm instruction.  This is redundant with movm_args, but we
58
     add it to the hash table to avoid computing it over and over.  */
59
  unsigned char movm_stack_size;
60
 
61
/* Used to mark functions which have had redundant parts of their
62
   prologue deleted.  */
63
#define CR16_DELETED_PROLOGUE_BYTES 0x1
64
  unsigned char flags;
65
 
66
  /* Calculated value.  */
67
  bfd_vma value;
68
};
69
 
70
/* cr16_reloc_map array maps BFD relocation enum into a CRGAS relocation type.  */
71
 
72
struct cr16_reloc_map
73
{
74
  bfd_reloc_code_real_type bfd_reloc_enum; /* BFD relocation enum.  */
75
  unsigned short cr16_reloc_type;          /* CR16 relocation type.  */
76
};
77
 
78
static const struct cr16_reloc_map cr16_reloc_map[R_CR16_MAX] =
79
{
80
  {BFD_RELOC_NONE,           R_CR16_NONE},
81
  {BFD_RELOC_CR16_NUM8,      R_CR16_NUM8},
82
  {BFD_RELOC_CR16_NUM16,     R_CR16_NUM16},
83
  {BFD_RELOC_CR16_NUM32,     R_CR16_NUM32},
84
  {BFD_RELOC_CR16_NUM32a,    R_CR16_NUM32a},
85
  {BFD_RELOC_CR16_REGREL4,   R_CR16_REGREL4},
86
  {BFD_RELOC_CR16_REGREL4a,  R_CR16_REGREL4a},
87
  {BFD_RELOC_CR16_REGREL14,  R_CR16_REGREL14},
88
  {BFD_RELOC_CR16_REGREL14a, R_CR16_REGREL14a},
89
  {BFD_RELOC_CR16_REGREL16,  R_CR16_REGREL16},
90
  {BFD_RELOC_CR16_REGREL20,  R_CR16_REGREL20},
91
  {BFD_RELOC_CR16_REGREL20a, R_CR16_REGREL20a},
92
  {BFD_RELOC_CR16_ABS20,     R_CR16_ABS20},
93
  {BFD_RELOC_CR16_ABS24,     R_CR16_ABS24},
94
  {BFD_RELOC_CR16_IMM4,      R_CR16_IMM4},
95
  {BFD_RELOC_CR16_IMM8,      R_CR16_IMM8},
96
  {BFD_RELOC_CR16_IMM16,     R_CR16_IMM16},
97
  {BFD_RELOC_CR16_IMM20,     R_CR16_IMM20},
98
  {BFD_RELOC_CR16_IMM24,     R_CR16_IMM24},
99
  {BFD_RELOC_CR16_IMM32,     R_CR16_IMM32},
100
  {BFD_RELOC_CR16_IMM32a,    R_CR16_IMM32a},
101
  {BFD_RELOC_CR16_DISP4,     R_CR16_DISP4},
102
  {BFD_RELOC_CR16_DISP8,     R_CR16_DISP8},
103
  {BFD_RELOC_CR16_DISP16,    R_CR16_DISP16},
104
  {BFD_RELOC_CR16_DISP24,    R_CR16_DISP24},
105
  {BFD_RELOC_CR16_DISP24a,   R_CR16_DISP24a},
106
  {BFD_RELOC_CR16_SWITCH8,   R_CR16_SWITCH8},
107
  {BFD_RELOC_CR16_SWITCH16,  R_CR16_SWITCH16},
108
  {BFD_RELOC_CR16_SWITCH32,  R_CR16_SWITCH32},
109
  {BFD_RELOC_CR16_GOT_REGREL20, R_CR16_GOT_REGREL20},
110
  {BFD_RELOC_CR16_GOTC_REGREL20, R_CR16_GOTC_REGREL20},
111
  {BFD_RELOC_CR16_GLOB_DAT,  R_CR16_GLOB_DAT}
112
};
113
 
114
static reloc_howto_type cr16_elf_howto_table[] =
115
{
116
  HOWTO (R_CR16_NONE,              /* type */
117
         0,                        /* rightshift */
118
         2,                        /* size */
119
         32,                       /* bitsize */
120
         FALSE,                    /* pc_relative */
121
         0,                        /* bitpos */
122
         complain_overflow_dont,   /* complain_on_overflow */
123
         bfd_elf_generic_reloc,    /* special_function */
124
         "R_CR16_NONE",            /* name */
125
         FALSE,                    /* partial_inplace */
126
         0,                        /* src_mask */
127
         0,                        /* dst_mask */
128
         FALSE),                   /* pcrel_offset */
129
 
130
  HOWTO (R_CR16_NUM8,              /* type */
131
         0,                        /* rightshift */
132
         0,                        /* size */
133
         8,                        /* bitsize */
134
         FALSE,                    /* pc_relative */
135
         0,                        /* bitpos */
136
         complain_overflow_bitfield,/* complain_on_overflow */
137
         bfd_elf_generic_reloc,    /* special_function */
138
         "R_CR16_NUM8",            /* name */
139
         FALSE,                    /* partial_inplace */
140
         0x0,                      /* src_mask */
141
         0xff,                     /* dst_mask */
142
         FALSE),                   /* pcrel_offset */
143
 
144
  HOWTO (R_CR16_NUM16,             /* type */
145
         0,                        /* rightshift */
146
         1,                        /* size */
147
         16,                       /* bitsize */
148
         FALSE,                    /* pc_relative */
149
         0,                        /* bitpos */
150
         complain_overflow_bitfield,/* complain_on_overflow */
151
         bfd_elf_generic_reloc,    /* special_function */
152
         "R_CR16_NUM16",           /* name */
153
         FALSE,                    /* partial_inplace */
154
         0x0,                      /* src_mask */
155
         0xffff,                   /* dst_mask */
156
         FALSE),                   /* pcrel_offset */
157
 
158
  HOWTO (R_CR16_NUM32,             /* type */
159
         0,                        /* rightshift */
160
         2,                        /* size */
161
         32,                       /* bitsize */
162
         FALSE,                    /* pc_relative */
163
         0,                        /* bitpos */
164
         complain_overflow_bitfield,/* complain_on_overflow */
165
         bfd_elf_generic_reloc,    /* special_function */
166
         "R_CR16_NUM32",           /* name */
167
         FALSE,                    /* partial_inplace */
168
         0x0,                      /* src_mask */
169
         0xffffffff,               /* dst_mask */
170
         FALSE),                   /* pcrel_offset */
171
 
172
  HOWTO (R_CR16_NUM32a,            /* type */
173
         1,                        /* rightshift */
174
         2,                        /* size */
175
         32,                       /* bitsize */
176
         FALSE,                    /* pc_relative */
177
         0,                        /* bitpos */
178
         complain_overflow_bitfield,/* complain_on_overflow */
179
         bfd_elf_generic_reloc,    /* special_function */
180
         "R_CR16_NUM32a",          /* name */
181
         FALSE,                    /* partial_inplace */
182
         0x0,                      /* src_mask */
183
         0xffffffff,               /* dst_mask */
184
         FALSE),                   /* pcrel_offset */
185
 
186
  HOWTO (R_CR16_REGREL4,           /* type */
187
         0,                        /* rightshift */
188
         0,                        /* size */
189
         4,                        /* bitsize */
190
         FALSE,                    /* pc_relative */
191
         0,                        /* bitpos */
192
         complain_overflow_bitfield,/* complain_on_overflow */
193
         bfd_elf_generic_reloc,    /* special_function */
194
         "R_CR16_REGREL4",         /* name */
195
         FALSE,                    /* partial_inplace */
196
         0x0,                      /* src_mask */
197
         0xf,                      /* dst_mask */
198
         FALSE),                   /* pcrel_offset */
199
 
200
  HOWTO (R_CR16_REGREL4a,          /* type */
201
         0,                        /* rightshift */
202
         0,                        /* size */
203
         4,                        /* bitsize */
204
         FALSE,                    /* pc_relative */
205
         0,                        /* bitpos */
206
         complain_overflow_bitfield,/* complain_on_overflow */
207
         bfd_elf_generic_reloc,    /* special_function */
208
         "R_CR16_REGREL4a",        /* name */
209
         FALSE,                    /* partial_inplace */
210
         0x0,                      /* src_mask */
211
         0xf,                      /* dst_mask */
212
         FALSE),                   /* pcrel_offset */
213
 
214
  HOWTO (R_CR16_REGREL14,          /* type */
215
         0,                        /* rightshift */
216
         1,                        /* size */
217
         14,                       /* bitsize */
218
         FALSE,                    /* pc_relative */
219
         0,                        /* bitpos */
220
         complain_overflow_bitfield,/* complain_on_overflow */
221
         bfd_elf_generic_reloc,    /* special_function */
222
         "R_CR16_REGREL14",        /* name */
223
         FALSE,                    /* partial_inplace */
224
         0x0,                      /* src_mask */
225
         0x3fff,                   /* dst_mask */
226
         FALSE),                   /* pcrel_offset */
227
 
228
  HOWTO (R_CR16_REGREL14a,         /* type */
229
         0,                        /* rightshift */
230
         1,                        /* size */
231
         14,                       /* bitsize */
232
         FALSE,                    /* pc_relative */
233
         0,                        /* bitpos */
234
         complain_overflow_bitfield,/* complain_on_overflow */
235
         bfd_elf_generic_reloc,    /* special_function */
236
         "R_CR16_REGREL14a",       /* name */
237
         FALSE,                    /* partial_inplace */
238
         0x0,                      /* src_mask */
239
         0x3fff,                   /* dst_mask */
240
         FALSE),                   /* pcrel_offset */
241
 
242
  HOWTO (R_CR16_REGREL16,          /* type */
243
         0,                        /* rightshift */
244
         1,                        /* size */
245
         16,                       /* bitsize */
246
         FALSE,                    /* pc_relative */
247
         0,                        /* bitpos */
248
         complain_overflow_bitfield,/* complain_on_overflow */
249
         bfd_elf_generic_reloc,    /* special_function */
250
         "R_CR16_REGREL16",        /* name */
251
         FALSE,                    /* partial_inplace */
252
         0x0,                      /* src_mask */
253
         0xffff,                   /* dst_mask */
254
         FALSE),                   /* pcrel_offset */
255
 
256
  HOWTO (R_CR16_REGREL20,          /* type */
257
         0,                        /* rightshift */
258
         2,                        /* size */
259
         20,                       /* bitsize */
260
         FALSE,                    /* pc_relative */
261
         0,                        /* bitpos */
262
         complain_overflow_bitfield,/* complain_on_overflow */
263
         bfd_elf_generic_reloc,    /* special_function */
264
         "R_CR16_REGREL20",        /* name */
265
         FALSE,                    /* partial_inplace */
266
         0x0,                      /* src_mask */
267
         0xfffff,                  /* dst_mask */
268
         FALSE),                   /* pcrel_offset */
269
 
270
  HOWTO (R_CR16_REGREL20a,         /* type */
271
         0,                        /* rightshift */
272
         2,                        /* size */
273
         20,                       /* bitsize */
274
         FALSE,                    /* pc_relative */
275
         0,                        /* bitpos */
276
         complain_overflow_bitfield,/* complain_on_overflow */
277
         bfd_elf_generic_reloc,    /* special_function */
278
         "R_CR16_REGREL20a",       /* name */
279
         FALSE,                    /* partial_inplace */
280
         0x0,                      /* src_mask */
281
         0xfffff,                  /* dst_mask */
282
         FALSE),                   /* pcrel_offset */
283
 
284
  HOWTO (R_CR16_ABS20,             /* type */
285
         0,                        /* rightshift */
286
         2,                        /* size */
287
         20,                       /* bitsize */
288
         FALSE,                    /* pc_relative */
289
         0,                        /* bitpos */
290
         complain_overflow_bitfield,/* complain_on_overflow */
291
         bfd_elf_generic_reloc,    /* special_function */
292
         "R_CR16_ABS20",           /* name */
293
         FALSE,                    /* partial_inplace */
294
         0x0,                      /* src_mask */
295
         0xfffff,                  /* dst_mask */
296
         FALSE),                   /* pcrel_offset */
297
 
298
  HOWTO (R_CR16_ABS24,             /* type */
299
         0,                        /* rightshift */
300
         2,                        /* size */
301
         24,                       /* bitsize */
302
         FALSE,                    /* pc_relative */
303
         0,                        /* bitpos */
304
         complain_overflow_bitfield,/* complain_on_overflow */
305
         bfd_elf_generic_reloc,    /* special_function */
306
         "R_CR16_ABS24",           /* name */
307
         FALSE,                    /* partial_inplace */
308
         0x0,                      /* src_mask */
309
         0xffffff,                 /* dst_mask */
310
         FALSE),                   /* pcrel_offset */
311
 
312
  HOWTO (R_CR16_IMM4,              /* type */
313
         0,                        /* rightshift */
314
         0,                        /* size */
315
         4,                        /* bitsize */
316
         FALSE,                    /* pc_relative */
317
         0,                        /* bitpos */
318
         complain_overflow_bitfield,/* complain_on_overflow */
319
         bfd_elf_generic_reloc,    /* special_function */
320
         "R_CR16_IMM4",            /* name */
321
         FALSE,                    /* partial_inplace */
322
         0x0,                      /* src_mask */
323
         0xf,                      /* dst_mask */
324
         FALSE),                   /* pcrel_offset */
325
 
326
  HOWTO (R_CR16_IMM8,              /* type */
327
         0,                        /* rightshift */
328
         0,                        /* size */
329
         8,                        /* bitsize */
330
         FALSE,                    /* pc_relative */
331
         0,                        /* bitpos */
332
         complain_overflow_bitfield,/* complain_on_overflow */
333
         bfd_elf_generic_reloc,    /* special_function */
334
         "R_CR16_IMM8",            /* name */
335
         FALSE,                    /* partial_inplace */
336
         0x0,                      /* src_mask */
337
         0xff,                     /* dst_mask */
338
         FALSE),                   /* pcrel_offset */
339
 
340
  HOWTO (R_CR16_IMM16,             /* type */
341
         0,                        /* rightshift */
342
         1,                        /* size */
343
         16,                       /* bitsize */
344
         FALSE,                    /* pc_relative */
345
         0,                        /* bitpos */
346
         complain_overflow_bitfield,/* complain_on_overflow */
347
         bfd_elf_generic_reloc,    /* special_function */
348
         "R_CR16_IMM16",           /* name */
349
         FALSE,                    /* partial_inplace */
350
         0x0,                      /* src_mask */
351
         0xffff,                   /* dst_mask */
352
         FALSE),                   /* pcrel_offset */
353
 
354
  HOWTO (R_CR16_IMM20,             /* type */
355
         0,                        /* rightshift */
356
         2,                        /* size */
357
         20,                       /* bitsize */
358
         FALSE,                    /* pc_relative */
359
         0,                        /* bitpos */
360
         complain_overflow_bitfield,/* complain_on_overflow */
361
         bfd_elf_generic_reloc,    /* special_function */
362
         "R_CR16_IMM20",           /* name */
363
         FALSE,                    /* partial_inplace */
364
         0x0,                      /* src_mask */
365
         0xfffff,                  /* dst_mask */
366
         FALSE),                   /* pcrel_offset */
367
 
368
  HOWTO (R_CR16_IMM24,             /* type */
369
         0,                        /* rightshift */
370
         2,                        /* size */
371
         24,                       /* bitsize */
372
         FALSE,                    /* pc_relative */
373
         0,                        /* bitpos */
374
         complain_overflow_bitfield,/* complain_on_overflow */
375
         bfd_elf_generic_reloc,    /* special_function */
376
         "R_CR16_IMM24",           /* name */
377
         FALSE,                    /* partial_inplace */
378
         0x0,                      /* src_mask */
379
         0xffffff,                 /* dst_mask */
380
         FALSE),                   /* pcrel_offset */
381
 
382
  HOWTO (R_CR16_IMM32,             /* type */
383
         0,                        /* rightshift */
384
         2,                        /* size */
385
         32,                       /* bitsize */
386
         FALSE,                    /* pc_relative */
387
         0,                        /* bitpos */
388
         complain_overflow_bitfield,/* complain_on_overflow */
389
         bfd_elf_generic_reloc,    /* special_function */
390
         "R_CR16_IMM32",           /* name */
391
         FALSE,                    /* partial_inplace */
392
         0x0,                      /* src_mask */
393
         0xffffffff,               /* dst_mask */
394
         FALSE),                   /* pcrel_offset */
395
 
396
  HOWTO (R_CR16_IMM32a,            /* type */
397
         1,                        /* rightshift */
398
         2,                        /* size */
399
         32,                       /* bitsize */
400
         FALSE,                    /* pc_relative */
401
         0,                        /* bitpos */
402
         complain_overflow_bitfield,/* complain_on_overflow */
403
         bfd_elf_generic_reloc,    /* special_function */
404
         "R_CR16_IMM32a",          /* name */
405
         FALSE,                    /* partial_inplace */
406
         0x0,                      /* src_mask */
407
         0xffffffff,               /* dst_mask */
408
         FALSE),                   /* pcrel_offset */
409
 
410
  HOWTO (R_CR16_DISP4,             /* type */
411
         1,                        /* rightshift */
412
         0,                        /* size (0 = byte, 1 = short, 2 = long) */
413
         4,                        /* bitsize */
414
         TRUE,                     /* pc_relative */
415
         0,                        /* bitpos */
416
         complain_overflow_unsigned, /* complain_on_overflow */
417
         bfd_elf_generic_reloc,    /* special_function */
418
         "R_CR16_DISP4",           /* name */
419
         FALSE,                    /* partial_inplace */
420
         0x0,                      /* src_mask */
421
         0xf,                      /* dst_mask */
422
         FALSE),                   /* pcrel_offset */
423
 
424
  HOWTO (R_CR16_DISP8,             /* type */
425
         1,                        /* rightshift */
426
         0,                        /* size (0 = byte, 1 = short, 2 = long) */
427
         8,                        /* bitsize */
428
         TRUE,                     /* pc_relative */
429
         0,                        /* bitpos */
430
         complain_overflow_unsigned, /* complain_on_overflow */
431
         bfd_elf_generic_reloc,    /* special_function */
432
         "R_CR16_DISP8",           /* name */
433
         FALSE,                    /* partial_inplace */
434
         0x0,                      /* src_mask */
435
         0x1ff,                    /* dst_mask */
436
         FALSE),                   /* pcrel_offset */
437
 
438
  HOWTO (R_CR16_DISP16,            /* type */
439
         0,                        /* rightshift REVIITS: To sync with WinIDEA*/
440
         1,                        /* size (0 = byte, 1 = short, 2 = long) */
441
         16,                       /* bitsize */
442
         TRUE,                     /* pc_relative */
443
         0,                        /* bitpos */
444
         complain_overflow_unsigned, /* complain_on_overflow */
445
         bfd_elf_generic_reloc,    /* special_function */
446
         "R_CR16_DISP16",          /* name */
447
         FALSE,                    /* partial_inplace */
448
         0x0,                      /* src_mask */
449
         0x1ffff,                  /* dst_mask */
450
         FALSE),                   /* pcrel_offset */
451
  /* REVISIT: DISP24 should be left-shift by 2 as per ISA doc
452
     but its not done, to sync with WinIDEA and CR16 4.1 tools */
453
  HOWTO (R_CR16_DISP24,            /* type */
454
         0,                        /* rightshift */
455
         2,                        /* size (0 = byte, 1 = short, 2 = long) */
456
         24,                       /* bitsize */
457
         TRUE,                     /* pc_relative */
458
         0,                        /* bitpos */
459
         complain_overflow_unsigned, /* complain_on_overflow */
460
         bfd_elf_generic_reloc,    /* special_function */
461
         "R_CR16_DISP24",          /* name */
462
         FALSE,                    /* partial_inplace */
463
         0x0,                      /* src_mask */
464
         0x1ffffff,                /* dst_mask */
465
         FALSE),                   /* pcrel_offset */
466
 
467
  HOWTO (R_CR16_DISP24a,           /* type */
468
         0,                        /* rightshift */
469
         2,                        /* size (0 = byte, 1 = short, 2 = long) */
470
         24,                       /* bitsize */
471
         TRUE,                     /* pc_relative */
472
         0,                        /* bitpos */
473
         complain_overflow_unsigned, /* complain_on_overflow */
474
         bfd_elf_generic_reloc,    /* special_function */
475
         "R_CR16_DISP24a",         /* name */
476
         FALSE,                    /* partial_inplace */
477
         0x0,                      /* src_mask */
478
         0xffffff,                 /* dst_mask */
479
         FALSE),                   /* pcrel_offset */
480
 
481
  /* An 8 bit switch table entry.  This is generated for an expression
482
     such as ``.byte L1 - L2''.  The offset holds the difference
483
     between the reloc address and L2.  */
484
  HOWTO (R_CR16_SWITCH8,           /* type */
485
         0,                        /* rightshift */
486
         0,                        /* size (0 = byte, 1 = short, 2 = long) */
487
         8,                        /* bitsize */
488
         FALSE,                    /* pc_relative */
489
         0,                        /* bitpos */
490
         complain_overflow_unsigned, /* complain_on_overflow */
491
         bfd_elf_generic_reloc,    /* special_function */
492
         "R_CR16_SWITCH8",         /* name */
493
         FALSE,                    /* partial_inplace */
494
         0x0,                      /* src_mask */
495
         0xff,                     /* dst_mask */
496
         TRUE),                    /* pcrel_offset */
497
 
498
  /* A 16 bit switch table entry.  This is generated for an expression
499
     such as ``.word L1 - L2''.  The offset holds the difference
500
     between the reloc address and L2.  */
501
  HOWTO (R_CR16_SWITCH16,          /* type */
502
         0,                        /* rightshift */
503
         1,                        /* size (0 = byte, 1 = short, 2 = long) */
504
         16,                       /* bitsize */
505
         FALSE,                    /* pc_relative */
506
         0,                        /* bitpos */
507
         complain_overflow_unsigned, /* complain_on_overflow */
508
         bfd_elf_generic_reloc,    /* special_function */
509
         "R_CR16_SWITCH16",        /* name */
510
         FALSE,                    /* partial_inplace */
511
         0x0,                      /* src_mask */
512
         0xffff,                   /* dst_mask */
513
         TRUE),                    /* pcrel_offset */
514
 
515
  /* A 32 bit switch table entry.  This is generated for an expression
516
     such as ``.long L1 - L2''.  The offset holds the difference
517
     between the reloc address and L2.  */
518
  HOWTO (R_CR16_SWITCH32,          /* type */
519
         0,                        /* rightshift */
520
         2,                        /* size (0 = byte, 1 = short, 2 = long) */
521
         32,                       /* bitsize */
522
         FALSE,                    /* pc_relative */
523
         0,                        /* bitpos */
524
         complain_overflow_unsigned, /* complain_on_overflow */
525
         bfd_elf_generic_reloc,    /* special_function */
526
         "R_CR16_SWITCH32",        /* name */
527
         FALSE,                    /* partial_inplace */
528
         0x0,                      /* src_mask */
529
         0xffffffff,               /* dst_mask */
530
         TRUE),                    /* pcrel_offset */
531
 
532
  HOWTO (R_CR16_GOT_REGREL20,      /* type */
533
         0,                        /* rightshift */
534
         2,                        /* size */
535
         20,                       /* bitsize */
536
         FALSE,                    /* pc_relative */
537
         0,                        /* bitpos */
538
         complain_overflow_bitfield,/* complain_on_overflow */
539
         bfd_elf_generic_reloc,    /* special_function */
540
         "R_CR16_GOT_REGREL20",    /* name */
541
         TRUE,                     /* partial_inplace */
542
         0x0,                      /* src_mask */
543
         0xfffff,                  /* dst_mask */
544
         FALSE),                   /* pcrel_offset */
545
 
546
  HOWTO (R_CR16_GOTC_REGREL20,     /* type */
547
         0,                        /* rightshift */
548
         2,                        /* size */
549
         20,                       /* bitsize */
550
         FALSE,                    /* pc_relative */
551
         0,                        /* bitpos */
552
         complain_overflow_bitfield,/* complain_on_overflow */
553
         bfd_elf_generic_reloc,    /* special_function */
554
         "R_CR16_GOTC_REGREL20",   /* name */
555
         TRUE,                     /* partial_inplace */
556
         0x0,                      /* src_mask */
557
         0xfffff,                  /* dst_mask */
558
         FALSE),                   /* pcrel_offset */
559
 
560
  HOWTO (R_CR16_GLOB_DAT,          /* type */
561
         0,                        /* rightshift */
562
         2,                        /* size (0 = byte, 1 = short, 2 = long) */
563
         32,                       /* bitsize */
564
         FALSE,                    /* pc_relative */
565
         0,                        /* bitpos */
566
         complain_overflow_unsigned, /* complain_on_overflow */
567
         bfd_elf_generic_reloc,    /* special_function */
568
         "R_CR16_GLOB_DAT",        /* name */
569
         FALSE,                    /* partial_inplace */
570
         0x0,                      /* src_mask */
571
         0xffffffff,               /* dst_mask */
572
         TRUE)                     /* pcrel_offset */
573
};
574
 
575
 
576
/* Create the GOT section.  */
577
 
578
static bfd_boolean
579
_bfd_cr16_elf_create_got_section (bfd * abfd, struct bfd_link_info * info)
580
{
581
  flagword   flags;
582
  asection * s;
583
  struct elf_link_hash_entry * h;
584
  const struct elf_backend_data * bed = get_elf_backend_data (abfd);
585
  int ptralign;
586
 
587
  /* This function may be called more than once.  */
588
  if (bfd_get_section_by_name (abfd, ".got") != NULL)
589
    return TRUE;
590
 
591
  switch (bed->s->arch_size)
592
    {
593
    case 16:
594
      ptralign = 1;
595
      break;
596
 
597
    case 32:
598
      ptralign = 2;
599
      break;
600
 
601
    default:
602
      bfd_set_error (bfd_error_bad_value);
603
      return FALSE;
604
    }
605
 
606
  flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
607
           | SEC_LINKER_CREATED);
608
 
609
  s = bfd_make_section_with_flags (abfd, ".got", flags);
610
  if (s == NULL
611
      || ! bfd_set_section_alignment (abfd, s, ptralign))
612
    return FALSE;
613
 
614
  if (bed->want_got_plt)
615
    {
616
      s = bfd_make_section_with_flags (abfd, ".got.plt", flags);
617
      if (s == NULL
618
          || ! bfd_set_section_alignment (abfd, s, ptralign))
619
        return FALSE;
620
    }
621
 
622
  /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
623
     (or .got.plt) section.  We don't do this in the linker script
624
     because we don't want to define the symbol if we are not creating
625
     a global offset table.  */
626
  h = _bfd_elf_define_linkage_sym (abfd, info, s, "_GLOBAL_OFFSET_TABLE_");
627
  elf_hash_table (info)->hgot = h;
628
  if (h == NULL)
629
    return FALSE;
630
 
631
  /* The first bit of the global offset table is the header.  */
632
  s->size += bed->got_header_size;
633
 
634
  return TRUE;
635
}
636
 
637
 
638
/* Retrieve a howto ptr using a BFD reloc_code.  */
639
 
640
static reloc_howto_type *
641
elf_cr16_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
642
                            bfd_reloc_code_real_type code)
643
{
644
  unsigned int i;
645
 
646
  for (i = 0; i < R_CR16_MAX; i++)
647
    if (code == cr16_reloc_map[i].bfd_reloc_enum)
648
      return &cr16_elf_howto_table[cr16_reloc_map[i].cr16_reloc_type];
649
 
650
  _bfd_error_handler ("Unsupported CR16 relocation type: 0x%x\n", code);
651
  return NULL;
652
}
653
 
654
static reloc_howto_type *
655
elf_cr16_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
656
                            const char *r_name)
657
{
658
  unsigned int i;
659
 
660
  for (i = 0; ARRAY_SIZE (cr16_elf_howto_table); i++)
661
    if (cr16_elf_howto_table[i].name != NULL
662
        && strcasecmp (cr16_elf_howto_table[i].name, r_name) == 0)
663
      return cr16_elf_howto_table + i;
664
 
665
  return NULL;
666
}
667
 
668
/* Retrieve a howto ptr using an internal relocation entry.  */
669
 
670
static void
671
elf_cr16_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
672
                        Elf_Internal_Rela *dst)
673
{
674
  unsigned int r_type = ELF32_R_TYPE (dst->r_info);
675
 
676
  BFD_ASSERT (r_type < (unsigned int) R_CR16_MAX);
677
  cache_ptr->howto = cr16_elf_howto_table + r_type;
678
}
679
 
680
/* Look through the relocs for a section during the first phase.
681
   Since we don't do .gots or .plts, we just need to consider the
682
   virtual table relocs for gc.  */
683
 
684
static bfd_boolean
685
cr16_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec,
686
                       const Elf_Internal_Rela *relocs)
687
{
688
  Elf_Internal_Shdr *symtab_hdr;
689
  Elf_Internal_Sym * isymbuf = NULL;
690
  struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
691
  const Elf_Internal_Rela *rel;
692
  const Elf_Internal_Rela *rel_end;
693
  bfd *      dynobj;
694
  bfd_vma *  local_got_offsets;
695
  asection * sgot;
696
  asection * srelgot;
697
 
698
  sgot    = NULL;
699
  srelgot = NULL;
700
  bfd_boolean result = FALSE;
701
 
702
  if (info->relocatable)
703
    return TRUE;
704
 
705
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
706
  sym_hashes = elf_sym_hashes (abfd);
707
  sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof (Elf32_External_Sym);
708
  if (!elf_bad_symtab (abfd))
709
    sym_hashes_end -= symtab_hdr->sh_info;
710
 
711
  dynobj = elf_hash_table (info)->dynobj;
712
  local_got_offsets = elf_local_got_offsets (abfd);
713
  rel_end = relocs + sec->reloc_count;
714
  for (rel = relocs; rel < rel_end; rel++)
715
    {
716
      struct elf_link_hash_entry *h;
717
      unsigned long r_symndx;
718
 
719
      r_symndx = ELF32_R_SYM (rel->r_info);
720
      if (r_symndx < symtab_hdr->sh_info)
721
        h = NULL;
722
      else
723
        {
724
          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
725
          while (h->root.type == bfd_link_hash_indirect
726
                 || h->root.type == bfd_link_hash_warning)
727
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
728
        }
729
 
730
      /* Some relocs require a global offset table.  */
731
      if (dynobj == NULL)
732
        {
733
          switch (ELF32_R_TYPE (rel->r_info))
734
            {
735
            case R_CR16_GOT_REGREL20:
736
            case R_CR16_GOTC_REGREL20:
737
              elf_hash_table (info)->dynobj = dynobj = abfd;
738
              if (! _bfd_cr16_elf_create_got_section (dynobj, info))
739
                goto fail;
740
              break;
741
 
742
            default:
743
              break;
744
            }
745
        }
746
 
747
      switch (ELF32_R_TYPE (rel->r_info))
748
        {
749
        case R_CR16_GOT_REGREL20:
750
        case R_CR16_GOTC_REGREL20:
751
          /* This symbol requires a global offset table entry.  */
752
 
753
          if (sgot == NULL)
754
            {
755
              sgot = bfd_get_section_by_name (dynobj, ".got");
756
              BFD_ASSERT (sgot != NULL);
757
            }
758
 
759
          if (srelgot == NULL
760
              && (h != NULL || info->executable))
761
            {
762
              srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
763
              if (srelgot == NULL)
764
                {
765
                  srelgot = bfd_make_section_with_flags (dynobj,
766
                                                         ".rela.got",
767
                                                         (SEC_ALLOC
768
                                                          | SEC_LOAD
769
                                                          | SEC_HAS_CONTENTS
770
                                                          | SEC_IN_MEMORY
771
                                                          | SEC_LINKER_CREATED
772
                                                          | SEC_READONLY));
773
                  if (srelgot == NULL
774
                      || ! bfd_set_section_alignment (dynobj, srelgot, 2))
775
                    goto fail;
776
                }
777
            }
778
 
779
          if (h != NULL)
780
            {
781
              if (h->got.offset != (bfd_vma) -1)
782
                /* We have already allocated space in the .got.  */
783
                break;
784
 
785
              h->got.offset = sgot->size;
786
 
787
              /* Make sure this symbol is output as a dynamic symbol.  */
788
              if (h->dynindx == -1)
789
                {
790
                  if (! bfd_elf_link_record_dynamic_symbol (info, h))
791
                    goto fail;
792
                }
793
 
794
              srelgot->size += sizeof (Elf32_External_Rela);
795
            }
796
          else
797
            {
798
              /* This is a global offset table entry for a local
799
                 symbol.  */
800
              if (local_got_offsets == NULL)
801
                {
802
                  size_t       size;
803
                  unsigned int i;
804
 
805
                  size = symtab_hdr->sh_info * sizeof (bfd_vma);
806
                  local_got_offsets = (bfd_vma *) bfd_alloc (abfd, size);
807
 
808
                  if (local_got_offsets == NULL)
809
                    goto fail;
810
 
811
                  elf_local_got_offsets (abfd) = local_got_offsets;
812
 
813
                  for (i = 0; i < symtab_hdr->sh_info; i++)
814
                    local_got_offsets[i] = (bfd_vma) -1;
815
                }
816
 
817
              if (local_got_offsets[r_symndx] != (bfd_vma) -1)
818
                /* We have already allocated space in the .got.  */
819
                break;
820
 
821
              local_got_offsets[r_symndx] = sgot->size;
822
 
823
              if (info->executable)
824
                /* If we are generating a shared object, we need to
825
                   output a R_CR16_RELATIVE reloc so that the dynamic
826
                   linker can adjust this GOT entry.  */
827
                srelgot->size += sizeof (Elf32_External_Rela);
828
            }
829
 
830
          sgot->size += 4;
831
          break;
832
 
833
        }
834
    }
835
 
836
   result = TRUE;
837
  fail:
838
    if (isymbuf != NULL)
839
      free (isymbuf);
840
 
841
  return result;
842
}
843
 
844
/* Perform a relocation as part of a final link.  */
845
 
846
static bfd_reloc_status_type
847
cr16_elf_final_link_relocate (reloc_howto_type *howto,
848
                              bfd *input_bfd,
849
                              bfd *output_bfd ATTRIBUTE_UNUSED,
850
                              asection *input_section,
851
                              bfd_byte *contents,
852
                              bfd_vma offset,
853
                              bfd_vma Rvalue,
854
                              bfd_vma addend,
855
                              struct elf_link_hash_entry * h,
856
                              unsigned long symndx  ATTRIBUTE_UNUSED,
857
                              struct bfd_link_info *info ATTRIBUTE_UNUSED,
858
                              asection *sec ATTRIBUTE_UNUSED,
859
                              int is_local ATTRIBUTE_UNUSED)
860
{
861
  unsigned short r_type = howto->type;
862
  bfd_byte *hit_data = contents + offset;
863
  bfd_vma reloc_bits, check, Rvalue1;
864
  bfd *      dynobj;
865
 
866
  dynobj = elf_hash_table (info)->dynobj;
867
 
868
  switch (r_type)
869
    {
870
     case R_CR16_IMM4:
871
     case R_CR16_IMM20:
872
     case R_CR16_ABS20:
873
       break;
874
 
875
     case R_CR16_IMM8:
876
     case R_CR16_IMM16:
877
     case R_CR16_IMM32:
878
     case R_CR16_IMM32a:
879
     case R_CR16_REGREL4:
880
     case R_CR16_REGREL4a:
881
     case R_CR16_REGREL14:
882
     case R_CR16_REGREL14a:
883
     case R_CR16_REGREL16:
884
     case R_CR16_REGREL20:
885
     case R_CR16_REGREL20a:
886
     case R_CR16_GOT_REGREL20:
887
     case R_CR16_GOTC_REGREL20:
888
     case R_CR16_ABS24:
889
     case R_CR16_DISP16:
890
     case R_CR16_DISP24:
891
       /* 'hit_data' is relative to the start of the instruction, not the
892
           relocation offset. Advance it to account for the exact offset.  */
893
       hit_data += 2;
894
       break;
895
 
896
     case R_CR16_NONE:
897
       return bfd_reloc_ok;
898
       break;
899
 
900
     case R_CR16_DISP4:
901
       if (is_local)
902
        Rvalue += -1;
903
       break;
904
 
905
     case R_CR16_DISP8:
906
     case R_CR16_DISP24a:
907
       if (is_local)
908
        Rvalue -= -1;
909
       break;
910
 
911
     case R_CR16_SWITCH8:
912
     case R_CR16_SWITCH16:
913
     case R_CR16_SWITCH32:
914
       /* We only care about the addend, where the difference between
915
          expressions is kept.  */
916
       Rvalue = 0;
917
 
918
     default:
919
       break;
920
    }
921
 
922
  if (howto->pc_relative)
923
    {
924
      /* Subtract the address of the section containing the location.  */
925
      Rvalue -= (input_section->output_section->vma
926
                 + input_section->output_offset);
927
      /* Subtract the position of the location within the section.  */
928
      Rvalue -= offset;
929
    }
930
 
931
  /* Add in supplied addend.  */
932
  Rvalue += addend;
933
 
934
  /* Complain if the bitfield overflows, whether it is considered
935
     as signed or unsigned.  */
936
  check = Rvalue >> howto->rightshift;
937
 
938
  /* Assumes two's complement.  This expression avoids
939
     overflow if howto->bitsize is the number of bits in
940
     bfd_vma.  */
941
  reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
942
 
943
  /* For GOT and GOTC relocs no boundary checks applied.  */
944
  if (!((r_type == R_CR16_GOT_REGREL20)
945
      || (r_type == R_CR16_GOTC_REGREL20)))
946
    {
947
      if (((bfd_vma) check & ~reloc_bits) != 0
948
          && (((bfd_vma) check & ~reloc_bits)
949
          != (-(bfd_vma) 1 & ~reloc_bits)))
950
        {
951
          /* The above right shift is incorrect for a signed
952
             value.  See if turning on the upper bits fixes the
953
             overflow.  */
954
          if (howto->rightshift && (bfd_signed_vma) Rvalue < 0)
955
            {
956
              check |= ((bfd_vma) - 1
957
                        & ~((bfd_vma) - 1
958
                         >> howto->rightshift));
959
 
960
              if (((bfd_vma) check & ~reloc_bits)
961
                  != (-(bfd_vma) 1 & ~reloc_bits))
962
                 return bfd_reloc_overflow;
963
            }
964
          else
965
            return bfd_reloc_overflow;
966
        }
967
 
968
      /* Drop unwanted bits from the value we are relocating to.  */
969
      Rvalue >>= (bfd_vma) howto->rightshift;
970
 
971
      /* Apply dst_mask to select only relocatable part of the insn.  */
972
      Rvalue &= howto->dst_mask;
973
    }
974
 
975
  switch (howto->size)
976
    {
977
      case 0:
978
        if (r_type == R_CR16_DISP8)
979
          {
980
             Rvalue1 = bfd_get_16 (input_bfd, hit_data);
981
             Rvalue = ((Rvalue1 & 0xf000) | ((Rvalue << 4) & 0xf00)
982
                       | (Rvalue1 & 0x00f0) | (Rvalue & 0xf));
983
             bfd_put_16 (input_bfd, Rvalue, hit_data);
984
          }
985
        else if (r_type == R_CR16_IMM4)
986
          {
987
             Rvalue1 = bfd_get_16 (input_bfd, hit_data);
988
             Rvalue = (((Rvalue1 & 0xff) << 8) | ((Rvalue << 4) & 0xf0)
989
                       | ((Rvalue1 & 0x0f00) >> 8));
990
             bfd_put_16 (input_bfd, Rvalue, hit_data);
991
          }
992
        else if (r_type == R_CR16_DISP4)
993
          {
994
             Rvalue1 = bfd_get_16 (input_bfd, hit_data);
995
             Rvalue = (Rvalue1 | ((Rvalue & 0xf) << 4));
996
             bfd_put_16 (input_bfd, Rvalue, hit_data);
997
          }
998
        else
999
          {
1000
             bfd_put_8 (input_bfd, (unsigned char) Rvalue, hit_data);
1001
          }
1002
        break;
1003
 
1004
      case 1:
1005
        if (r_type == R_CR16_DISP16)
1006
          {
1007
            Rvalue |= (bfd_get_16 (input_bfd, hit_data));
1008
            Rvalue = ((Rvalue & 0xfffe) | ((Rvalue >> 16) & 0x1));
1009
          }
1010
        if (r_type == R_CR16_IMM16)
1011
          {
1012
            Rvalue1 = bfd_get_16 (input_bfd, hit_data);
1013
 
1014
            /* Add or subtract the offset value.  */
1015
            if (Rvalue1 & 0x8000)
1016
              Rvalue -= (~Rvalue1 + 1) & 0xffff;
1017
            else
1018
              Rvalue += Rvalue1;
1019
 
1020
             /* Check for range.  */
1021
             if ((long) Rvalue > 0xffff || (long) Rvalue < 0x0)
1022
              return bfd_reloc_overflow;
1023
          }
1024
 
1025
        bfd_put_16 (input_bfd, Rvalue, hit_data);
1026
        break;
1027
 
1028
      case 2:
1029
        if ((r_type == R_CR16_ABS20) || (r_type == R_CR16_IMM20))
1030
          {
1031
             Rvalue1 = (bfd_get_16 (input_bfd, hit_data + 2)
1032
                        | (((bfd_get_16 (input_bfd, hit_data) & 0xf) <<16)));
1033
 
1034
             /* Add or subtract the offset value.  */
1035
             if (Rvalue1 & 0x80000)
1036
                Rvalue -= (~Rvalue1 + 1) & 0xfffff;
1037
              else
1038
                Rvalue += Rvalue1;
1039
 
1040
              /* Check for range.  */
1041
              if ((long) Rvalue > 0xfffff || (long) Rvalue < 0x0)
1042
               return bfd_reloc_overflow;
1043
 
1044
            bfd_put_16 (input_bfd, ((bfd_get_16 (input_bfd, hit_data) & 0xfff0)
1045
                        | ((Rvalue >> 16) & 0xf)), hit_data);
1046
            bfd_put_16 (input_bfd, (Rvalue) & 0xffff, hit_data + 2);
1047
          }
1048
        else if (r_type == R_CR16_GOT_REGREL20)
1049
          {
1050
            asection * sgot = bfd_get_section_by_name (dynobj, ".got");
1051
 
1052
            if (h != NULL)
1053
              {
1054
                bfd_vma off;
1055
 
1056
                off = h->got.offset;
1057
                BFD_ASSERT (off != (bfd_vma) -1);
1058
 
1059
                if (! elf_hash_table (info)->dynamic_sections_created
1060
                     || SYMBOL_REFERENCES_LOCAL (info, h))
1061
                    /* This is actually a static link, or it is a
1062
                       -Bsymbolic link and the symbol is defined
1063
                       locally, or the symbol was forced to be local
1064
                       because of a version file.  We must initialize
1065
                       this entry in the global offset table.
1066
                       When doing a dynamic link, we create a .rela.got
1067
                       relocation entry to initialize the value.  This
1068
                       is done in the finish_dynamic_symbol routine.  */
1069
                  bfd_put_32 (output_bfd, Rvalue, sgot->contents + off);
1070
 
1071
                  Rvalue = sgot->output_offset + off;
1072
                }
1073
              else
1074
                {
1075
                   bfd_vma off;
1076
 
1077
                   off = elf_local_got_offsets (input_bfd)[symndx];
1078
                   bfd_put_32 (output_bfd,Rvalue, sgot->contents + off);
1079
 
1080
                   Rvalue = sgot->output_offset + off;
1081
                }
1082
 
1083
             Rvalue += addend;
1084
 
1085
             /* REVISIT: if ((long) Rvalue > 0xffffff ||
1086
                                    (long) Rvalue < -0x800000).  */
1087
             if ((long) Rvalue > 0xffffff || (long) Rvalue < 0)
1088
               return bfd_reloc_overflow;
1089
 
1090
 
1091
             bfd_put_16 (input_bfd, (bfd_get_16 (input_bfd, hit_data))
1092
                         | (((Rvalue >> 16) & 0xf) << 8), hit_data);
1093
             bfd_put_16 (input_bfd, (Rvalue) & 0xffff, hit_data + 2);
1094
 
1095
          }
1096
        else if (r_type == R_CR16_GOTC_REGREL20)
1097
          {
1098
             asection * sgot;
1099
             sgot = bfd_get_section_by_name (dynobj, ".got");
1100
 
1101
             if (h != NULL)
1102
               {
1103
                 bfd_vma off;
1104
 
1105
                 off = h->got.offset;
1106
                 BFD_ASSERT (off != (bfd_vma) -1);
1107
 
1108
                  Rvalue >>=1; /* For code symbols.  */
1109
 
1110
                 if (! elf_hash_table (info)->dynamic_sections_created
1111
                      || SYMBOL_REFERENCES_LOCAL (info, h))
1112
                 /* This is actually a static link, or it is a
1113
                    -Bsymbolic link and the symbol is defined
1114
                     locally, or the symbol was forced to be local
1115
                     because of a version file.  We must initialize
1116
                     this entry in the global offset table.
1117
                     When doing a dynamic link, we create a .rela.got
1118
                     relocation entry to initialize the value.  This
1119
                     is done in the finish_dynamic_symbol routine.  */
1120
                  bfd_put_32 (output_bfd, Rvalue, sgot->contents + off);
1121
 
1122
                  Rvalue = sgot->output_offset + off;
1123
               }
1124
             else
1125
               {
1126
                  bfd_vma off;
1127
 
1128
                  off = elf_local_got_offsets (input_bfd)[symndx];
1129
                  Rvalue >>= 1;
1130
                  bfd_put_32 (output_bfd,Rvalue, sgot->contents + off);
1131
                  Rvalue = sgot->output_offset + off;
1132
               }
1133
 
1134
             Rvalue += addend;
1135
 
1136
             /* Check if any value in DISP.  */
1137
             Rvalue1 =((bfd_get_32 (input_bfd, hit_data) >>16)
1138
                       | (((bfd_get_32 (input_bfd, hit_data) & 0xfff) >> 8) <<16));
1139
 
1140
             /* Add or subtract the offset value.  */
1141
             if (Rvalue1 & 0x80000)
1142
               Rvalue -= (~Rvalue1 + 1) & 0xfffff;
1143
             else
1144
               Rvalue += Rvalue1;
1145
 
1146
              /* Check for range.  */
1147
             /* REVISIT: if ((long) Rvalue > 0xffffff
1148
                             || (long) Rvalue < -0x800000).  */
1149
             if ((long) Rvalue > 0xffffff || (long) Rvalue < 0)
1150
               return bfd_reloc_overflow;
1151
 
1152
             bfd_put_16 (input_bfd, (bfd_get_16 (input_bfd, hit_data))
1153
                         | (((Rvalue >> 16) & 0xf) << 8), hit_data);
1154
             bfd_put_16 (input_bfd, (Rvalue) & 0xffff, hit_data + 2);
1155
          }
1156
        else
1157
          {
1158
             if (r_type == R_CR16_ABS24)
1159
               {
1160
                  Rvalue1 = ((bfd_get_32 (input_bfd, hit_data) >> 16)
1161
                             | (((bfd_get_32 (input_bfd, hit_data) & 0xfff) >> 8) <<16)
1162
                             | (((bfd_get_32 (input_bfd, hit_data) & 0xf) <<20)));
1163
 
1164
                  /* Add or subtract the offset value.  */
1165
                  if (Rvalue1 & 0x800000)
1166
                    Rvalue -= (~Rvalue1 + 1) & 0xffffff;
1167
                  else
1168
                    Rvalue += Rvalue1;
1169
 
1170
                 /* Check for Range.  */
1171
                 if ((long) Rvalue > 0xffffff || (long) Rvalue < 0x0)
1172
                   return bfd_reloc_overflow;
1173
 
1174
                 Rvalue = ((((Rvalue >> 20) & 0xf) | (((Rvalue >> 16) & 0xf)<<8)
1175
                           | (bfd_get_32 (input_bfd, hit_data) & 0xf0f0))
1176
                           | ((Rvalue & 0xffff) << 16));
1177
               }
1178
             else if (r_type == R_CR16_DISP24)
1179
               {
1180
                  Rvalue = ((((Rvalue >> 20)& 0xf) | (((Rvalue >>16) & 0xf)<<8)
1181
                            | (bfd_get_16 (input_bfd, hit_data)))
1182
                            | (((Rvalue & 0xfffe) | ((Rvalue >> 24) & 0x1)) << 16));
1183
               }
1184
             else if ((r_type == R_CR16_IMM32) || (r_type == R_CR16_IMM32a))
1185
               {
1186
                  Rvalue1 =((((bfd_get_32 (input_bfd, hit_data)) >> 16) &0xffff)
1187
                            | (((bfd_get_32 (input_bfd, hit_data)) &0xffff)) << 16);
1188
 
1189
                 /* Add or subtract the offset value.  */
1190
                 if (Rvalue1 & 0x80000000)
1191
                   Rvalue -= (~Rvalue1 + 1) & 0xffffffff;
1192
                 else
1193
                   Rvalue += Rvalue1;
1194
 
1195
                 /* Check for range.  */
1196
                 if (Rvalue > 0xffffffff || (long) Rvalue < 0x0)
1197
                   return bfd_reloc_overflow;
1198
 
1199
                 Rvalue = (((Rvalue >> 16)& 0xffff) | (Rvalue & 0xffff) << 16);
1200
               }
1201
             else if (r_type == R_CR16_DISP24a)
1202
               {
1203
                  Rvalue = (((Rvalue & 0xfffffe) | (Rvalue >> 23)));
1204
                  Rvalue = ((Rvalue >> 16) & 0xff) | ((Rvalue & 0xffff) << 16)
1205
                            | (bfd_get_32 (input_bfd, hit_data));
1206
               }
1207
             else if ((r_type == R_CR16_REGREL20)
1208
                      || (r_type == R_CR16_REGREL20a))
1209
               {
1210
                  Rvalue1 = ((bfd_get_32 (input_bfd, hit_data) >> 16)
1211
                             | (((bfd_get_32 (input_bfd, hit_data) & 0xfff) >> 8) <<16));
1212
                  /* Add or subtract the offset value.  */
1213
                  if (Rvalue1 & 0x80000)
1214
                     Rvalue -= (~Rvalue1 + 1) & 0xfffff;
1215
                  else
1216
                     Rvalue += Rvalue1;
1217
 
1218
                  /* Check for range.  */
1219
                  if ((long) Rvalue > 0xfffff || (long) Rvalue < 0x0)
1220
                    return bfd_reloc_overflow;
1221
 
1222
                  Rvalue = (((((Rvalue >> 20)& 0xf) | (((Rvalue >>16) & 0xf)<<8)
1223
                            | ((Rvalue & 0xffff) << 16)))
1224
                            | (bfd_get_32 (input_bfd, hit_data) & 0xf0ff));
1225
 
1226
              }
1227
            else if (r_type == R_CR16_NUM32)
1228
              {
1229
                 Rvalue1 = (bfd_get_32 (input_bfd, hit_data));
1230
 
1231
                 /* Add or subtract the offset value */
1232
                 if (Rvalue1 & 0x80000000)
1233
                   Rvalue -= (~Rvalue1 + 1) & 0xffffffff;
1234
                 else
1235
                   Rvalue += Rvalue1;
1236
 
1237
                /* Check for Ranga */
1238
                if (Rvalue > 0xffffffff)
1239
                  return bfd_reloc_overflow;
1240
              }
1241
 
1242
            bfd_put_32 (input_bfd, Rvalue, hit_data);
1243
          }
1244
        break;
1245
 
1246
      default:
1247
        return bfd_reloc_notsupported;
1248
    }
1249
 
1250
  return bfd_reloc_ok;
1251
}
1252
 
1253
/* Delete some bytes from a section while relaxing.  */
1254
 
1255
static bfd_boolean
1256
elf32_cr16_relax_delete_bytes (struct bfd_link_info *link_info, bfd *abfd,
1257
                               asection *sec, bfd_vma addr, int count)
1258
{
1259
  Elf_Internal_Shdr *symtab_hdr;
1260
  unsigned int sec_shndx;
1261
  bfd_byte *contents;
1262
  Elf_Internal_Rela *irel, *irelend;
1263
  bfd_vma toaddr;
1264
  Elf_Internal_Sym *isym;
1265
  Elf_Internal_Sym *isymend;
1266
  struct elf_link_hash_entry **sym_hashes;
1267
  struct elf_link_hash_entry **end_hashes;
1268
  struct elf_link_hash_entry **start_hashes;
1269
  unsigned int symcount;
1270
 
1271
  sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1272
 
1273
  contents = elf_section_data (sec)->this_hdr.contents;
1274
 
1275
  toaddr = sec->size;
1276
 
1277
  irel = elf_section_data (sec)->relocs;
1278
  irelend = irel + sec->reloc_count;
1279
 
1280
  /* Actually delete the bytes.  */
1281
  memmove (contents + addr, contents + addr + count,
1282
           (size_t) (toaddr - addr - count));
1283
  sec->size -= count;
1284
 
1285
  /* Adjust all the relocs.  */
1286
  for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
1287
    /* Get the new reloc address.  */
1288
    if ((irel->r_offset > addr && irel->r_offset < toaddr))
1289
        irel->r_offset -= count;
1290
 
1291
  /* Adjust the local symbols defined in this section.  */
1292
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1293
  isym = (Elf_Internal_Sym *) symtab_hdr->contents;
1294
  for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
1295
    {
1296
      if (isym->st_shndx == sec_shndx
1297
          && isym->st_value > addr
1298
          && isym->st_value < toaddr)
1299
        {
1300
          /* Adjust the addend of SWITCH relocations in this section,
1301
             which reference this local symbol.  */
1302
#if 0
1303
          for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
1304
            {
1305
              unsigned long r_symndx;
1306
              Elf_Internal_Sym *rsym;
1307
              bfd_vma addsym, subsym;
1308
 
1309
              /* Skip if not a SWITCH relocation.  */
1310
              if (ELF32_R_TYPE (irel->r_info) != (int) R_CR16_SWITCH8
1311
                  && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_SWITCH16
1312
                  && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_SWITCH32)
1313
                 continue;
1314
 
1315
              r_symndx = ELF32_R_SYM (irel->r_info);
1316
              rsym = (Elf_Internal_Sym *) symtab_hdr->contents + r_symndx;
1317
 
1318
              /* Skip if not the local adjusted symbol.  */
1319
              if (rsym != isym)
1320
                continue;
1321
 
1322
              addsym = isym->st_value;
1323
              subsym = addsym - irel->r_addend;
1324
 
1325
              /* Fix the addend only when -->> (addsym > addr >= subsym).  */
1326
              if (subsym <= addr)
1327
                irel->r_addend -= count;
1328
              else
1329
                continue;
1330
            }
1331
#endif
1332
 
1333
          isym->st_value -= count;
1334
        }
1335
    }
1336
 
1337
  /* Now adjust the global symbols defined in this section.  */
1338
  symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1339
               - symtab_hdr->sh_info);
1340
  sym_hashes = start_hashes = elf_sym_hashes (abfd);
1341
  end_hashes = sym_hashes + symcount;
1342
 
1343
  for (; sym_hashes < end_hashes; sym_hashes++)
1344
    {
1345
      struct elf_link_hash_entry *sym_hash = *sym_hashes;
1346
 
1347
      /* The '--wrap SYMBOL' option is causing a pain when the object file,
1348
         containing the definition of __wrap_SYMBOL, includes a direct
1349
         call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
1350
         the same symbol (which is __wrap_SYMBOL), but still exist as two
1351
         different symbols in 'sym_hashes', we don't want to adjust
1352
         the global symbol __wrap_SYMBOL twice.
1353
         This check is only relevant when symbols are being wrapped.  */
1354
      if (link_info->wrap_hash != NULL)
1355
        {
1356
          struct elf_link_hash_entry **cur_sym_hashes;
1357
 
1358
          /* Loop only over the symbols whom been already checked.  */
1359
          for (cur_sym_hashes = start_hashes; cur_sym_hashes < sym_hashes;
1360
               cur_sym_hashes++)
1361
            /* If the current symbol is identical to 'sym_hash', that means
1362
               the symbol was already adjusted (or at least checked).  */
1363
            if (*cur_sym_hashes == sym_hash)
1364
              break;
1365
 
1366
          /* Don't adjust the symbol again.  */
1367
          if (cur_sym_hashes < sym_hashes)
1368
            continue;
1369
        }
1370
 
1371
      if ((sym_hash->root.type == bfd_link_hash_defined
1372
          || sym_hash->root.type == bfd_link_hash_defweak)
1373
          && sym_hash->root.u.def.section == sec
1374
          && sym_hash->root.u.def.value > addr
1375
          && sym_hash->root.u.def.value < toaddr)
1376
        sym_hash->root.u.def.value -= count;
1377
    }
1378
 
1379
  return TRUE;
1380
}
1381
 
1382
/* Relocate a CR16 ELF section.  */
1383
 
1384
static bfd_boolean
1385
elf32_cr16_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
1386
                             bfd *input_bfd, asection *input_section,
1387
                             bfd_byte *contents, Elf_Internal_Rela *relocs,
1388
                             Elf_Internal_Sym *local_syms,
1389
                             asection **local_sections)
1390
{
1391
  Elf_Internal_Shdr *symtab_hdr;
1392
  struct elf_link_hash_entry **sym_hashes;
1393
  Elf_Internal_Rela *rel, *relend;
1394
 
1395
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1396
  sym_hashes = elf_sym_hashes (input_bfd);
1397
 
1398
  rel = relocs;
1399
  relend = relocs + input_section->reloc_count;
1400
  for (; rel < relend; rel++)
1401
    {
1402
      int r_type;
1403
      reloc_howto_type *howto;
1404
      unsigned long r_symndx;
1405
      Elf_Internal_Sym *sym;
1406
      asection *sec;
1407
      struct elf_link_hash_entry *h;
1408
      bfd_vma relocation;
1409
      bfd_reloc_status_type r;
1410
 
1411
      r_symndx = ELF32_R_SYM (rel->r_info);
1412
      r_type = ELF32_R_TYPE (rel->r_info);
1413
      howto = cr16_elf_howto_table + (r_type);
1414
 
1415
      h = NULL;
1416
      sym = NULL;
1417
      sec = NULL;
1418
      if (r_symndx < symtab_hdr->sh_info)
1419
        {
1420
          sym = local_syms + r_symndx;
1421
          sec = local_sections[r_symndx];
1422
          relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
1423
        }
1424
      else
1425
        {
1426
          bfd_boolean unresolved_reloc, warned;
1427
 
1428
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1429
                                   r_symndx, symtab_hdr, sym_hashes,
1430
                                   h, sec, relocation,
1431
                                   unresolved_reloc, warned);
1432
        }
1433
 
1434
      if (sec != NULL && elf_discarded_section (sec))
1435
       {
1436
         /* For relocs against symbols from removed linkonce sections,
1437
            or sections discarded by a linker script, we just want the
1438
            section contents zeroed.  Avoid any special processing.  */
1439
         _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
1440
         rel->r_info = 0;
1441
         rel->r_addend = 0;
1442
         continue;
1443
       }
1444
 
1445
      if (info->relocatable)
1446
        continue;
1447
 
1448
      r = cr16_elf_final_link_relocate (howto, input_bfd, output_bfd,
1449
                                        input_section,
1450
                                        contents, rel->r_offset,
1451
                                        relocation, rel->r_addend,
1452
                                        (struct elf_link_hash_entry *) h,
1453
                                        r_symndx,
1454
                                        info, sec, h == NULL);
1455
 
1456
      if (r != bfd_reloc_ok)
1457
        {
1458
          const char *name;
1459
          const char *msg = NULL;
1460
 
1461
          if (h != NULL)
1462
            name = h->root.root.string;
1463
          else
1464
            {
1465
              name = (bfd_elf_string_from_elf_section
1466
                      (input_bfd, symtab_hdr->sh_link, sym->st_name));
1467
              if (name == NULL || *name == '\0')
1468
                name = bfd_section_name (input_bfd, sec);
1469
            }
1470
 
1471
          switch (r)
1472
            {
1473
             case bfd_reloc_overflow:
1474
               if (!((*info->callbacks->reloc_overflow)
1475
                     (info, (h ? &h->root : NULL), name, howto->name,
1476
                      (bfd_vma) 0, input_bfd, input_section,
1477
                      rel->r_offset)))
1478
                 return FALSE;
1479
               break;
1480
 
1481
             case bfd_reloc_undefined:
1482
               if (!((*info->callbacks->undefined_symbol)
1483
                     (info, name, input_bfd, input_section,
1484
                      rel->r_offset, TRUE)))
1485
                 return FALSE;
1486
               break;
1487
 
1488
             case bfd_reloc_outofrange:
1489
               msg = _("internal error: out of range error");
1490
               goto common_error;
1491
 
1492
             case bfd_reloc_notsupported:
1493
               msg = _("internal error: unsupported relocation error");
1494
               goto common_error;
1495
 
1496
             case bfd_reloc_dangerous:
1497
               msg = _("internal error: dangerous error");
1498
               goto common_error;
1499
 
1500
             default:
1501
               msg = _("internal error: unknown error");
1502
               /* Fall through.  */
1503
 
1504
             common_error:
1505
               if (!((*info->callbacks->warning)
1506
                     (info, msg, name, input_bfd, input_section,
1507
                      rel->r_offset)))
1508
                 return FALSE;
1509
               break;
1510
            }
1511
        }
1512
    }
1513
 
1514
  return TRUE;
1515
}
1516
 
1517
/* This is a version of bfd_generic_get_relocated_section_contents
1518
   which uses elf32_cr16_relocate_section.  */
1519
 
1520
static bfd_byte *
1521
elf32_cr16_get_relocated_section_contents (bfd *output_bfd,
1522
                                           struct bfd_link_info *link_info,
1523
                                           struct bfd_link_order *link_order,
1524
                                           bfd_byte *data,
1525
                                           bfd_boolean relocatable,
1526
                                           asymbol **symbols)
1527
{
1528
  Elf_Internal_Shdr *symtab_hdr;
1529
  asection *input_section = link_order->u.indirect.section;
1530
  bfd *input_bfd = input_section->owner;
1531
  asection **sections = NULL;
1532
  Elf_Internal_Rela *internal_relocs = NULL;
1533
  Elf_Internal_Sym *isymbuf = NULL;
1534
 
1535
  /* We only need to handle the case of relaxing, or of having a
1536
     particular set of section contents, specially.  */
1537
  if (relocatable
1538
      || elf_section_data (input_section)->this_hdr.contents == NULL)
1539
    return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
1540
                                                       link_order, data,
1541
                                                       relocatable,
1542
                                                       symbols);
1543
 
1544
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1545
 
1546
  memcpy (data, elf_section_data (input_section)->this_hdr.contents,
1547
          (size_t) input_section->size);
1548
 
1549
  if ((input_section->flags & SEC_RELOC) != 0
1550
      && input_section->reloc_count > 0)
1551
    {
1552
      Elf_Internal_Sym *isym;
1553
      Elf_Internal_Sym *isymend;
1554
      asection **secpp;
1555
      bfd_size_type amt;
1556
 
1557
      internal_relocs = _bfd_elf_link_read_relocs (input_bfd, input_section,
1558
                                                   NULL, NULL, FALSE);
1559
      if (internal_relocs == NULL)
1560
        goto error_return;
1561
 
1562
      if (symtab_hdr->sh_info != 0)
1563
        {
1564
          isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1565
          if (isymbuf == NULL)
1566
            isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
1567
                                            symtab_hdr->sh_info, 0,
1568
                                            NULL, NULL, NULL);
1569
          if (isymbuf == NULL)
1570
            goto error_return;
1571
        }
1572
 
1573
      amt = symtab_hdr->sh_info;
1574
      amt *= sizeof (asection *);
1575
      sections = bfd_malloc (amt);
1576
      if (sections == NULL && amt != 0)
1577
        goto error_return;
1578
 
1579
      isymend = isymbuf + symtab_hdr->sh_info;
1580
      for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
1581
        {
1582
          asection *isec;
1583
 
1584
          if (isym->st_shndx == SHN_UNDEF)
1585
            isec = bfd_und_section_ptr;
1586
          else if (isym->st_shndx == SHN_ABS)
1587
            isec = bfd_abs_section_ptr;
1588
          else if (isym->st_shndx == SHN_COMMON)
1589
            isec = bfd_com_section_ptr;
1590
          else
1591
            isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
1592
 
1593
          *secpp = isec;
1594
        }
1595
 
1596
      if (! elf32_cr16_relocate_section (output_bfd, link_info, input_bfd,
1597
                                     input_section, data, internal_relocs,
1598
                                     isymbuf, sections))
1599
        goto error_return;
1600
 
1601
      if (sections != NULL)
1602
        free (sections);
1603
      if (isymbuf != NULL
1604
          && symtab_hdr->contents != (unsigned char *) isymbuf)
1605
        free (isymbuf);
1606
      if (elf_section_data (input_section)->relocs != internal_relocs)
1607
        free (internal_relocs);
1608
    }
1609
 
1610
  return data;
1611
 
1612
 error_return:
1613
  if (sections != NULL)
1614
    free (sections);
1615
  if (isymbuf != NULL
1616
      && symtab_hdr->contents != (unsigned char *) isymbuf)
1617
    free (isymbuf);
1618
  if (internal_relocs != NULL
1619
      && elf_section_data (input_section)->relocs != internal_relocs)
1620
    free (internal_relocs);
1621
  return NULL;
1622
}
1623
 
1624
/* Assorted hash table functions.  */
1625
 
1626
/* Initialize an entry in the link hash table.  */
1627
 
1628
/* Create an entry in an CR16 ELF linker hash table.  */
1629
 
1630
static struct bfd_hash_entry *
1631
elf32_cr16_link_hash_newfunc (struct bfd_hash_entry *entry,
1632
                              struct bfd_hash_table *table,
1633
                              const char *string)
1634
{
1635
  struct elf32_cr16_link_hash_entry *ret =
1636
    (struct elf32_cr16_link_hash_entry *) entry;
1637
 
1638
  /* Allocate the structure if it has not already been allocated by a
1639
     subclass.  */
1640
  if (ret == (struct elf32_cr16_link_hash_entry *) NULL)
1641
    ret = ((struct elf32_cr16_link_hash_entry *)
1642
           bfd_hash_allocate (table,
1643
                              sizeof (struct elf32_cr16_link_hash_entry)));
1644
  if (ret == (struct elf32_cr16_link_hash_entry *) NULL)
1645
    return (struct bfd_hash_entry *) ret;
1646
 
1647
  /* Call the allocation method of the superclass.  */
1648
  ret = ((struct elf32_cr16_link_hash_entry *)
1649
         _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1650
                                     table, string));
1651
  if (ret != (struct elf32_cr16_link_hash_entry *) NULL)
1652
    {
1653
      ret->direct_calls = 0;
1654
      ret->stack_size = 0;
1655
      ret->movm_args = 0;
1656
      ret->movm_stack_size = 0;
1657
      ret->flags = 0;
1658
      ret->value = 0;
1659
    }
1660
 
1661
  return (struct bfd_hash_entry *) ret;
1662
}
1663
 
1664
/* Create an cr16 ELF linker hash table.  */
1665
 
1666
static struct bfd_link_hash_table *
1667
elf32_cr16_link_hash_table_create (bfd *abfd)
1668
{
1669
  struct elf_link_hash_table *ret;
1670
  bfd_size_type amt = sizeof (struct elf_link_hash_table);
1671
 
1672
  ret = (struct elf_link_hash_table *) bfd_malloc (amt);
1673
  if (ret == (struct elf_link_hash_table *) NULL)
1674
    return NULL;
1675
 
1676
  if (!_bfd_elf_link_hash_table_init (ret, abfd,
1677
                                      elf32_cr16_link_hash_newfunc,
1678
                                      sizeof (struct elf32_cr16_link_hash_entry),
1679
                                      GENERIC_ELF_DATA))
1680
    {
1681
      free (ret);
1682
      return NULL;
1683
    }
1684
 
1685
  return &ret->root;
1686
}
1687
 
1688
/* Free an cr16 ELF linker hash table.  */
1689
 
1690
static void
1691
elf32_cr16_link_hash_table_free (struct bfd_link_hash_table *hash)
1692
{
1693
  struct elf_link_hash_table *ret
1694
    = (struct elf_link_hash_table *) hash;
1695
 
1696
  _bfd_generic_link_hash_table_free
1697
    ((struct bfd_link_hash_table *) ret);
1698
}
1699
 
1700
static unsigned long
1701
elf_cr16_mach (flagword flags)
1702
{
1703
  switch (flags)
1704
    {
1705
      case EM_CR16:
1706
      default:
1707
      return bfd_mach_cr16;
1708
    }
1709
}
1710
 
1711
/* The final processing done just before writing out a CR16 ELF object
1712
   file.  This gets the CR16 architecture right based on the machine
1713
   number.  */
1714
 
1715
static void
1716
_bfd_cr16_elf_final_write_processing (bfd *abfd,
1717
                                      bfd_boolean linker ATTRIBUTE_UNUSED)
1718
{
1719
  unsigned long val;
1720
  switch (bfd_get_mach (abfd))
1721
    {
1722
     default:
1723
     case bfd_mach_cr16:
1724
        val = EM_CR16;
1725
        break;
1726
    }
1727
 
1728
 
1729
 elf_elfheader (abfd)->e_flags |= val;
1730
}
1731
 
1732
 
1733
static bfd_boolean
1734
_bfd_cr16_elf_object_p (bfd *abfd)
1735
{
1736
  bfd_default_set_arch_mach (abfd, bfd_arch_cr16,
1737
                             elf_cr16_mach (elf_elfheader (abfd)->e_flags));
1738
  return TRUE;
1739
}
1740
 
1741
/* Merge backend specific data from an object file to the output
1742
   object file when linking.  */
1743
 
1744
static bfd_boolean
1745
_bfd_cr16_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
1746
{
1747
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1748
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1749
    return TRUE;
1750
 
1751
  if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1752
      && bfd_get_mach (obfd) < bfd_get_mach (ibfd))
1753
    {
1754
      if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
1755
                               bfd_get_mach (ibfd)))
1756
         return FALSE;
1757
     }
1758
 
1759
  return TRUE;
1760
}
1761
 
1762
 
1763
/* This function handles relaxing for the CR16.
1764
 
1765
   There's quite a few relaxing opportunites available on the CR16:
1766
 
1767
        * bcond:24 -> bcond:16                                1 byte
1768
        * bcond:16 -> bcond:8                                 1 byte
1769
        * arithmetic imm32 -> arithmetic imm20                12 bits
1770
        * arithmetic imm20/imm16 -> arithmetic imm4           12/16 bits
1771
 
1772
   Symbol- and reloc-reading infrastructure copied from elf-m10200.c.  */
1773
 
1774
static bfd_boolean
1775
elf32_cr16_relax_section (bfd *abfd, asection *sec,
1776
                          struct bfd_link_info *link_info, bfd_boolean *again)
1777
{
1778
  Elf_Internal_Shdr *symtab_hdr;
1779
  Elf_Internal_Rela *internal_relocs;
1780
  Elf_Internal_Rela *irel, *irelend;
1781
  bfd_byte *contents = NULL;
1782
  Elf_Internal_Sym *isymbuf = NULL;
1783
 
1784
  /* Assume nothing changes.  */
1785
  *again = FALSE;
1786
 
1787
  /* We don't have to do anything for a relocatable link, if
1788
     this section does not have relocs, or if this is not a
1789
     code section.  */
1790
  if (link_info->relocatable
1791
      || (sec->flags & SEC_RELOC) == 0
1792
      || sec->reloc_count == 0
1793
      || (sec->flags & SEC_CODE) == 0)
1794
    return TRUE;
1795
 
1796
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1797
 
1798
  /* Get a copy of the native relocations.  */
1799
  internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
1800
                                               link_info->keep_memory);
1801
  if (internal_relocs == NULL)
1802
    goto error_return;
1803
 
1804
  /* Walk through them looking for relaxing opportunities.  */
1805
  irelend = internal_relocs + sec->reloc_count;
1806
  for (irel = internal_relocs; irel < irelend; irel++)
1807
    {
1808
      bfd_vma symval;
1809
 
1810
      /* If this isn't something that can be relaxed, then ignore
1811
         this reloc.  */
1812
      if (ELF32_R_TYPE (irel->r_info) != (int) R_CR16_DISP16
1813
          && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_DISP24
1814
          && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_IMM32
1815
          && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_IMM20
1816
          && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_IMM16)
1817
        continue;
1818
 
1819
      /* Get the section contents if we haven't done so already.  */
1820
      if (contents == NULL)
1821
        {
1822
          /* Get cached copy if it exists.  */
1823
          if (elf_section_data (sec)->this_hdr.contents != NULL)
1824
            contents = elf_section_data (sec)->this_hdr.contents;
1825
          /* Go get them off disk.  */
1826
          else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
1827
            goto error_return;
1828
        }
1829
 
1830
      /* Read this BFD's local symbols if we haven't done so already.  */
1831
      if (isymbuf == NULL && symtab_hdr->sh_info != 0)
1832
        {
1833
          isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1834
          if (isymbuf == NULL)
1835
            isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
1836
                                            symtab_hdr->sh_info, 0,
1837
                                            NULL, NULL, NULL);
1838
          if (isymbuf == NULL)
1839
            goto error_return;
1840
        }
1841
 
1842
      /* Get the value of the symbol referred to by the reloc.  */
1843
      if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1844
        {
1845
          /* A local symbol.  */
1846
          Elf_Internal_Sym *isym;
1847
          asection *sym_sec;
1848
 
1849
          isym = isymbuf + ELF32_R_SYM (irel->r_info);
1850
          if (isym->st_shndx == SHN_UNDEF)
1851
            sym_sec = bfd_und_section_ptr;
1852
          else if (isym->st_shndx == SHN_ABS)
1853
            sym_sec = bfd_abs_section_ptr;
1854
          else if (isym->st_shndx == SHN_COMMON)
1855
            sym_sec = bfd_com_section_ptr;
1856
          else
1857
            sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1858
          symval = (isym->st_value
1859
                    + sym_sec->output_section->vma
1860
                    + sym_sec->output_offset);
1861
        }
1862
      else
1863
        {
1864
          unsigned long indx;
1865
          struct elf_link_hash_entry *h;
1866
 
1867
          /* An external symbol.  */
1868
          indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1869
          h = elf_sym_hashes (abfd)[indx];
1870
          BFD_ASSERT (h != NULL);
1871
 
1872
          if (h->root.type != bfd_link_hash_defined
1873
              && h->root.type != bfd_link_hash_defweak)
1874
            /* This appears to be a reference to an undefined
1875
               symbol.  Just ignore it--it will be caught by the
1876
               regular reloc processing.  */
1877
            continue;
1878
 
1879
          symval = (h->root.u.def.value
1880
                    + h->root.u.def.section->output_section->vma
1881
                    + h->root.u.def.section->output_offset);
1882
        }
1883
 
1884
      /* For simplicity of coding, we are going to modify the section
1885
         contents, the section relocs, and the BFD symbol table.  We
1886
         must tell the rest of the code not to free up this
1887
         information.  It would be possible to instead create a table
1888
         of changes which have to be made, as is done in coff-mips.c;
1889
         that would be more work, but would require less memory when
1890
         the linker is run.  */
1891
 
1892
      /* Try to turn a 24  branch/call into a 16bit relative
1893
         branch/call.  */
1894
      if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_DISP24)
1895
        {
1896
          bfd_vma value = symval;
1897
 
1898
          /* Deal with pc-relative gunk.  */
1899
          value -= (sec->output_section->vma + sec->output_offset);
1900
          value -= irel->r_offset;
1901
          value += irel->r_addend;
1902
 
1903
          /* See if the value will fit in 16 bits, note the high value is
1904
             0xfffe + 2 as the target will be two bytes closer if we are
1905
             able to relax.  */
1906
          if ((long) value < 0x10000 && (long) value > -0x10002)
1907
            {
1908
              unsigned int code;
1909
 
1910
              /* Get the opcode.  */
1911
              code = (unsigned int) bfd_get_32 (abfd, contents + irel->r_offset);
1912
 
1913
              /* Verify it's a 'bcond' and fix the opcode.  */
1914
              if ((code  & 0xffff) == 0x0010)
1915
                bfd_put_16 (abfd, 0x1800 | ((0xf & (code >> 20)) << 4), contents + irel->r_offset);
1916
              else
1917
                continue;
1918
 
1919
              /* Note that we've changed the relocs, section contents, etc.  */
1920
              elf_section_data (sec)->relocs = internal_relocs;
1921
              elf_section_data (sec)->this_hdr.contents = contents;
1922
              symtab_hdr->contents = (unsigned char *) isymbuf;
1923
 
1924
              /* Fix the relocation's type.  */
1925
              irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1926
                                           R_CR16_DISP16);
1927
 
1928
              /* Delete two bytes of data.  */
1929
              if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec,
1930
                                                   irel->r_offset + 2, 2))
1931
                goto error_return;
1932
 
1933
              /* That will change things, so, we should relax again.
1934
                 Note that this is not required, and it may be slow.  */
1935
              *again = TRUE;
1936
            }
1937
        }
1938
 
1939
      /* Try to turn a 16bit pc-relative branch into an
1940
         8bit pc-relative branch.  */
1941
      if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_DISP16)
1942
        {
1943
          bfd_vma value = symval;
1944
 
1945
          /* Deal with pc-relative gunk.  */
1946
          value -= (sec->output_section->vma + sec->output_offset);
1947
          value -= irel->r_offset;
1948
          value += irel->r_addend;
1949
 
1950
          /* See if the value will fit in 8 bits, note the high value is
1951
             0xfc + 2 as the target will be two bytes closer if we are
1952
             able to relax.  */
1953
          /*if ((long) value < 0x1fa && (long) value > -0x100) REVISIT:range */
1954
          if ((long) value < 0xfa && (long) value > -0x100)
1955
            {
1956
              unsigned short code;
1957
 
1958
              /* Get the opcode.  */
1959
              code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
1960
 
1961
              /* Verify it's a 'bcond' and fix the opcode.  */
1962
              if ((code & 0xff0f) == 0x1800)
1963
                bfd_put_16 (abfd, (code & 0xf0f0), contents + irel->r_offset);
1964
              else
1965
                continue;
1966
 
1967
              /* Note that we've changed the relocs, section contents, etc.  */
1968
              elf_section_data (sec)->relocs = internal_relocs;
1969
              elf_section_data (sec)->this_hdr.contents = contents;
1970
              symtab_hdr->contents = (unsigned char *) isymbuf;
1971
 
1972
              /* Fix the relocation's type.  */
1973
              irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1974
                                           R_CR16_DISP8);
1975
 
1976
              /* Delete two bytes of data.  */
1977
              if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec,
1978
                                                   irel->r_offset + 2, 2))
1979
                goto error_return;
1980
 
1981
              /* That will change things, so, we should relax again.
1982
                 Note that this is not required, and it may be slow.  */
1983
              *again = TRUE;
1984
            }
1985
        }
1986
 
1987
      /* Try to turn a 32-bit IMM address into a 20/16-bit IMM address */
1988
      if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM32)
1989
        {
1990
          bfd_vma value = symval;
1991
          unsigned short is_add_mov = 0;
1992
          bfd_vma value1 = 0;
1993
 
1994
          /* Get the existing value from the mcode */
1995
          value1 = ((bfd_get_32 (abfd, contents + irel->r_offset + 2) >> 16)
1996
                   |(((bfd_get_32 (abfd, contents + irel->r_offset + 2) & 0xffff) << 16)));
1997
 
1998
          /* See if the value will fit in 20 bits.  */
1999
          if ((long) (value + value1) < 0xfffff && (long) (value + value1) > 0)
2000
            {
2001
              unsigned short code;
2002
 
2003
              /* Get the opcode.  */
2004
              code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
2005
 
2006
              /* Verify it's a 'arithmetic ADDD or MOVD instruction'.
2007
                 For ADDD and MOVD only, convert to IMM32 -> IMM20.  */
2008
 
2009
              if (((code & 0xfff0) == 0x0070) || ((code & 0xfff0) == 0x0020))
2010
                 is_add_mov = 1;
2011
 
2012
              if (is_add_mov)
2013
                {
2014
                  /* Note that we've changed the relocs, section contents,
2015
                     etc.  */
2016
                  elf_section_data (sec)->relocs = internal_relocs;
2017
                  elf_section_data (sec)->this_hdr.contents = contents;
2018
                  symtab_hdr->contents = (unsigned char *) isymbuf;
2019
 
2020
                  /* Fix the opcode.  */
2021
                  if ((code & 0xfff0) == 0x0070) /* For movd.  */
2022
                    bfd_put_8 (abfd, 0x05, contents + irel->r_offset + 1);
2023
                  else                           /* code == 0x0020 for addd.  */
2024
                    bfd_put_8 (abfd, 0x04, contents + irel->r_offset + 1);
2025
 
2026
                  bfd_put_8 (abfd, (code & 0xf) << 4, contents + irel->r_offset);
2027
 
2028
                  /* If existing value is nagavive adjust approriately
2029
                     place the 16-20bits (ie 4 bit) in new opcode,
2030
                     as the 0xffffxxxx, the higher 2 byte values removed. */
2031
                  if (value1 & 0x80000000)
2032
                    bfd_put_8 (abfd, (0x0f | (bfd_get_8(abfd, contents + irel->r_offset))), contents + irel->r_offset);
2033
                  else
2034
                    bfd_put_8 (abfd, (((value1 >> 16)&0xf) | (bfd_get_8(abfd, contents + irel->r_offset))), contents + irel->r_offset);
2035
 
2036
                  /* Fix the relocation's type.  */
2037
                  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2038
                                               R_CR16_IMM20);
2039
 
2040
                  /* Delete two bytes of data.  */
2041
                  if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec,
2042
                                                      irel->r_offset + 2, 2))
2043
                    goto error_return;
2044
 
2045
                  /* That will change things, so, we should relax again.
2046
                     Note that this is not required, and it may be slow.  */
2047
                  *again = TRUE;
2048
                }
2049
            }
2050
 
2051
          /* See if the value will fit in 16 bits.  */
2052
          if ((!is_add_mov)
2053
              && ((long)(value + value1) < 0x7fff && (long)(value + value1) > 0))
2054
            {
2055
              unsigned short code;
2056
 
2057
              /* Get the opcode.  */
2058
              code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
2059
 
2060
              /* Note that we've changed the relocs, section contents, etc.  */
2061
              elf_section_data (sec)->relocs = internal_relocs;
2062
              elf_section_data (sec)->this_hdr.contents = contents;
2063
              symtab_hdr->contents = (unsigned char *) isymbuf;
2064
 
2065
              /* Fix the opcode.  */
2066
              if ((code & 0xf0) == 0x70)          /* For movd.  */
2067
                bfd_put_8 (abfd, 0x54, contents + irel->r_offset + 1);
2068
              else if ((code & 0xf0) == 0x20)     /* For addd.  */
2069
                bfd_put_8 (abfd, 0x60, contents + irel->r_offset + 1);
2070
              else if ((code & 0xf0) == 0x90)     /* For cmpd.  */
2071
                bfd_put_8 (abfd, 0x56, contents + irel->r_offset + 1);
2072
              else
2073
                continue;
2074
 
2075
              bfd_put_8 (abfd, 0xb0 | (code & 0xf), contents + irel->r_offset);
2076
 
2077
              /* If existing value is nagavive adjust approriately
2078
                 place the 12-16bits (ie 4 bit) in new opcode,
2079
                 as the 0xfffffxxx, the higher 2 byte values removed. */
2080
              if (value1 & 0x80000000)
2081
                bfd_put_8 (abfd, (0x0f | (bfd_get_8(abfd, contents + irel->r_offset))), contents + irel->r_offset);
2082
              else
2083
                bfd_put_16 (abfd, value1, contents + irel->r_offset + 2);
2084
 
2085
 
2086
              /* Fix the relocation's type.  */
2087
              irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2088
                                           R_CR16_IMM16);
2089
 
2090
              /* Delete two bytes of data.  */
2091
              if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec,
2092
                                                  irel->r_offset + 2, 2))
2093
                goto error_return;
2094
 
2095
              /* That will change things, so, we should relax again.
2096
                 Note that this is not required, and it may be slow.  */
2097
              *again = TRUE;
2098
            }
2099
        }
2100
 
2101
#if 0
2102
      /* Try to turn a 16bit immediate address into a 4bit
2103
         immediate address.  */
2104
      if ((ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM20)
2105
          || (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM16))
2106
        {
2107
          bfd_vma value = symval;
2108
          bfd_vma value1 = 0;
2109
 
2110
          /* Get the existing value from the mcode */
2111
          value1 = ((bfd_get_16 (abfd, contents + irel->r_offset + 2) & 0xffff));
2112
 
2113
          if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM20)
2114
            {
2115
              value1 |= ((bfd_get_16 (abfd, contents + irel->r_offset + 1) & 0xf000) << 0x4);
2116
            }
2117
 
2118
          /* See if the value will fit in 4 bits.  */
2119
          if ((((long) (value + value1)) < 0xf)
2120
              && (((long) (value + value1)) > 0))
2121
            {
2122
              unsigned short code;
2123
 
2124
              /* Get the opcode.  */
2125
              code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
2126
 
2127
              /* Note that we've changed the relocs, section contents, etc.  */
2128
              elf_section_data (sec)->relocs = internal_relocs;
2129
              elf_section_data (sec)->this_hdr.contents = contents;
2130
              symtab_hdr->contents = (unsigned char *) isymbuf;
2131
 
2132
              /* Fix the opcode.  */
2133
              if (((code & 0x0f00) == 0x0400) || ((code & 0x0f00) == 0x0500))
2134
                {
2135
                  if ((code & 0x0f00) == 0x0400)      /* For movd imm20.  */
2136
                    bfd_put_8 (abfd, 0x60, contents + irel->r_offset);
2137
                  else                                /* For addd imm20.  */
2138
                    bfd_put_8 (abfd, 0x54, contents + irel->r_offset);
2139
                  bfd_put_8 (abfd, (code & 0xf0) >> 4, contents + irel->r_offset + 1);
2140
                }
2141
              else
2142
                {
2143
                  if ((code & 0xfff0) == 0x56b0)       /*  For cmpd imm16.  */
2144
                    bfd_put_8 (abfd, 0x56, contents + irel->r_offset);
2145
                  else if ((code & 0xfff0) == 0x54b0)  /*  For movd imm16.  */
2146
                    bfd_put_8 (abfd, 0x54, contents + irel->r_offset);
2147
                  else if ((code & 0xfff0) == 0x58b0)  /*  For movb imm16.  */
2148
                    bfd_put_8 (abfd, 0x58, contents + irel->r_offset);
2149
                  else if ((code & 0xfff0) == 0x5Ab0)  /*  For movw imm16.  */
2150
                    bfd_put_8 (abfd, 0x5A, contents + irel->r_offset);
2151
                  else if ((code & 0xfff0) == 0x60b0)  /*  For addd imm16.  */
2152
                    bfd_put_8 (abfd, 0x60, contents + irel->r_offset);
2153
                  else if ((code & 0xfff0) == 0x30b0)  /*  For addb imm16.  */
2154
                    bfd_put_8 (abfd, 0x30, contents + irel->r_offset);
2155
                  else if ((code & 0xfff0) == 0x2Cb0)  /*  For addub imm16.  */
2156
                    bfd_put_8 (abfd, 0x2C, contents + irel->r_offset);
2157
                  else if ((code & 0xfff0) == 0x32b0)  /*  For adduw imm16.  */
2158
                    bfd_put_8 (abfd, 0x32, contents + irel->r_offset);
2159
                  else if ((code & 0xfff0) == 0x38b0)  /*  For subb imm16.  */
2160
                    bfd_put_8 (abfd, 0x38, contents + irel->r_offset);
2161
                  else if ((code & 0xfff0) == 0x3Cb0)  /*  For subcb imm16.  */
2162
                    bfd_put_8 (abfd, 0x3C, contents + irel->r_offset);
2163
                  else if ((code & 0xfff0) == 0x3Fb0)  /*  For subcw imm16.  */
2164
                    bfd_put_8 (abfd, 0x3F, contents + irel->r_offset);
2165
                  else if ((code & 0xfff0) == 0x3Ab0)  /*  For subw imm16.  */
2166
                    bfd_put_8 (abfd, 0x3A, contents + irel->r_offset);
2167
                  else if ((code & 0xfff0) == 0x50b0)  /*  For cmpb imm16.  */
2168
                    bfd_put_8 (abfd, 0x50, contents + irel->r_offset);
2169
                  else if ((code & 0xfff0) == 0x52b0)  /*  For cmpw imm16.  */
2170
                    bfd_put_8 (abfd, 0x52, contents + irel->r_offset);
2171
                  else
2172
                    continue;
2173
 
2174
                  bfd_put_8 (abfd, (code & 0xf), contents + irel->r_offset + 1);
2175
                }
2176
 
2177
              /* Fix the relocation's type.  */
2178
              irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2179
                                           R_CR16_IMM4);
2180
 
2181
              /* Delete two bytes of data.  */
2182
              if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec,
2183
                                                  irel->r_offset + 2, 2))
2184
                goto error_return;
2185
 
2186
              /* That will change things, so, we should relax again.
2187
                 Note that this is not required, and it may be slow.  */
2188
              *again = TRUE;
2189
            }
2190
        }
2191
#endif
2192
    }
2193
 
2194
  if (isymbuf != NULL
2195
      && symtab_hdr->contents != (unsigned char *) isymbuf)
2196
    {
2197
      if (! link_info->keep_memory)
2198
        free (isymbuf);
2199
      else
2200
       /* Cache the symbols for elf_link_input_bfd.  */
2201
       symtab_hdr->contents = (unsigned char *) isymbuf;
2202
    }
2203
 
2204
  if (contents != NULL
2205
      && elf_section_data (sec)->this_hdr.contents != contents)
2206
    {
2207
      if (! link_info->keep_memory)
2208
        free (contents);
2209
      else
2210
       /* Cache the section contents for elf_link_input_bfd.  */
2211
       elf_section_data (sec)->this_hdr.contents = contents;
2212
 
2213
    }
2214
 
2215
  if (internal_relocs != NULL
2216
      && elf_section_data (sec)->relocs != internal_relocs)
2217
    free (internal_relocs);
2218
 
2219
  return TRUE;
2220
 
2221
 error_return:
2222
  if (isymbuf != NULL
2223
      && symtab_hdr->contents != (unsigned char *) isymbuf)
2224
    free (isymbuf);
2225
  if (contents != NULL
2226
      && elf_section_data (sec)->this_hdr.contents != contents)
2227
    free (contents);
2228
  if (internal_relocs != NULL
2229
      && elf_section_data (sec)->relocs != internal_relocs)
2230
    free (internal_relocs);
2231
 
2232
  return FALSE;
2233
}
2234
 
2235
static asection *
2236
elf32_cr16_gc_mark_hook (asection *sec,
2237
                         struct bfd_link_info *info,
2238
                         Elf_Internal_Rela *rel,
2239
                         struct elf_link_hash_entry *h,
2240
                         Elf_Internal_Sym *sym)
2241
{
2242
  return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
2243
}
2244
 
2245
/* Update the got entry reference counts for the section being removed.  */
2246
 
2247
static bfd_boolean
2248
elf32_cr16_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED,
2249
                          struct bfd_link_info *info ATTRIBUTE_UNUSED,
2250
                          asection *sec ATTRIBUTE_UNUSED,
2251
                          const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED)
2252
{
2253
  /* We don't support garbage collection of GOT and PLT relocs yet.  */
2254
  return TRUE;
2255
}
2256
 
2257
/* Create dynamic sections when linking against a dynamic object.  */
2258
 
2259
static bfd_boolean
2260
_bfd_cr16_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
2261
{
2262
  flagword   flags;
2263
  asection * s;
2264
  const struct elf_backend_data * bed = get_elf_backend_data (abfd);
2265
  int ptralign = 0;
2266
 
2267
  switch (bed->s->arch_size)
2268
    {
2269
    case 16:
2270
      ptralign = 1;
2271
      break;
2272
 
2273
    case 32:
2274
      ptralign = 2;
2275
      break;
2276
 
2277
    default:
2278
      bfd_set_error (bfd_error_bad_value);
2279
      return FALSE;
2280
    }
2281
 
2282
  /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and
2283
     .rel[a].bss sections.  */
2284
 
2285
  flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
2286
           | SEC_LINKER_CREATED);
2287
 
2288
  s = bfd_make_section_with_flags (abfd,
2289
                                   (bed->default_use_rela_p
2290
                                    ? ".rela.plt" : ".rel.plt"),
2291
                                   flags | SEC_READONLY);
2292
  if (s == NULL
2293
      || ! bfd_set_section_alignment (abfd, s, ptralign))
2294
    return FALSE;
2295
 
2296
  if (! _bfd_cr16_elf_create_got_section (abfd, info))
2297
    return FALSE;
2298
 
2299
  {
2300
    const char * secname;
2301
    char *       relname;
2302
    flagword     secflags;
2303
    asection *   sec;
2304
 
2305
    for (sec = abfd->sections; sec; sec = sec->next)
2306
      {
2307
        secflags = bfd_get_section_flags (abfd, sec);
2308
        if ((secflags & (SEC_DATA | SEC_LINKER_CREATED))
2309
            || ((secflags & SEC_HAS_CONTENTS) != SEC_HAS_CONTENTS))
2310
          continue;
2311
 
2312
        secname = bfd_get_section_name (abfd, sec);
2313
        relname = (char *) bfd_malloc (strlen (secname) + 6);
2314
        strcpy (relname, ".rela");
2315
        strcat (relname, secname);
2316
 
2317
        s = bfd_make_section_with_flags (abfd, relname,
2318
                                         flags | SEC_READONLY);
2319
        if (s == NULL
2320
            || ! bfd_set_section_alignment (abfd, s, ptralign))
2321
          return FALSE;
2322
      }
2323
  }
2324
 
2325
  if (bed->want_dynbss)
2326
    {
2327
      /* The .dynbss section is a place to put symbols which are defined
2328
         by dynamic objects, are referenced by regular objects, and are
2329
         not functions.  We must allocate space for them in the process
2330
         image and use a R_*_COPY reloc to tell the dynamic linker to
2331
         initialize them at run time.  The linker script puts the .dynbss
2332
         section into the .bss section of the final image.  */
2333
      s = bfd_make_section_with_flags (abfd, ".dynbss",
2334
                                       SEC_ALLOC | SEC_LINKER_CREATED);
2335
      if (s == NULL)
2336
        return FALSE;
2337
 
2338
      /* The .rel[a].bss section holds copy relocs.  This section is not
2339
         normally needed.  We need to create it here, though, so that the
2340
         linker will map it to an output section.  We can't just create it
2341
         only if we need it, because we will not know whether we need it
2342
         until we have seen all the input files, and the first time the
2343
         main linker code calls BFD after examining all the input files
2344
         (size_dynamic_sections) the input sections have already been
2345
         mapped to the output sections.  If the section turns out not to
2346
         be needed, we can discard it later.  We will never need this
2347
         section when generating a shared object, since they do not use
2348
         copy relocs.  */
2349
      if (! info->executable)
2350
        {
2351
          s = bfd_make_section_with_flags (abfd,
2352
                                           (bed->default_use_rela_p
2353
                                            ? ".rela.bss" : ".rel.bss"),
2354
                                           flags | SEC_READONLY);
2355
          if (s == NULL
2356
              || ! bfd_set_section_alignment (abfd, s, ptralign))
2357
            return FALSE;
2358
        }
2359
    }
2360
 
2361
  return TRUE;
2362
}
2363
 
2364
/* Adjust a symbol defined by a dynamic object and referenced by a
2365
   regular object.  The current definition is in some section of the
2366
   dynamic object, but we're not including those sections.  We have to
2367
   change the definition to something the rest of the link can
2368
   understand.  */
2369
 
2370
static bfd_boolean
2371
_bfd_cr16_elf_adjust_dynamic_symbol (struct bfd_link_info * info,
2372
                                     struct elf_link_hash_entry * h)
2373
{
2374
  bfd * dynobj;
2375
  asection * s;
2376
 
2377
  dynobj = elf_hash_table (info)->dynobj;
2378
 
2379
  /* Make sure we know what is going on here.  */
2380
  BFD_ASSERT (dynobj != NULL
2381
              && (h->needs_plt
2382
                  || h->u.weakdef != NULL
2383
                  || (h->def_dynamic
2384
                      && h->ref_regular
2385
                      && !h->def_regular)));
2386
 
2387
  /* If this is a function, put it in the procedure linkage table.  We
2388
     will fill in the contents of the procedure linkage table later,
2389
     when we know the address of the .got section.  */
2390
  if (h->type == STT_FUNC
2391
      || h->needs_plt)
2392
    {
2393
      if (! info->executable
2394
          && !h->def_dynamic
2395
          && !h->ref_dynamic)
2396
        {
2397
          /* This case can occur if we saw a PLT reloc in an input
2398
             file, but the symbol was never referred to by a dynamic
2399
             object.  In such a case, we don't actually need to build
2400
             a procedure linkage table, and we can just do a REL32
2401
             reloc instead.  */
2402
          BFD_ASSERT (h->needs_plt);
2403
          return TRUE;
2404
        }
2405
 
2406
      /* Make sure this symbol is output as a dynamic symbol.  */
2407
      if (h->dynindx == -1)
2408
        {
2409
          if (! bfd_elf_link_record_dynamic_symbol (info, h))
2410
            return FALSE;
2411
        }
2412
 
2413
      /* We also need to make an entry in the .got.plt section, which
2414
         will be placed in the .got section by the linker script.  */
2415
 
2416
      s = bfd_get_section_by_name (dynobj, ".got.plt");
2417
      BFD_ASSERT (s != NULL);
2418
      s->size += 4;
2419
 
2420
      /* We also need to make an entry in the .rela.plt section.  */
2421
 
2422
      s = bfd_get_section_by_name (dynobj, ".rela.plt");
2423
      BFD_ASSERT (s != NULL);
2424
      s->size += sizeof (Elf32_External_Rela);
2425
 
2426
      return TRUE;
2427
    }
2428
 
2429
  /* If this is a weak symbol, and there is a real definition, the
2430
     processor independent code will have arranged for us to see the
2431
     real definition first, and we can just use the same value.  */
2432
  if (h->u.weakdef != NULL)
2433
    {
2434
      BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2435
                  || h->u.weakdef->root.type == bfd_link_hash_defweak);
2436
      h->root.u.def.section = h->u.weakdef->root.u.def.section;
2437
      h->root.u.def.value = h->u.weakdef->root.u.def.value;
2438
      return TRUE;
2439
    }
2440
 
2441
  /* This is a reference to a symbol defined by a dynamic object which
2442
     is not a function.  */
2443
 
2444
  /* If we are creating a shared library, we must presume that the
2445
     only references to the symbol are via the global offset table.
2446
     For such cases we need not do anything here; the relocations will
2447
     be handled correctly by relocate_section.  */
2448
  if (info->executable)
2449
    return TRUE;
2450
 
2451
  /* If there are no references to this symbol that do not use the
2452
     GOT, we don't need to generate a copy reloc.  */
2453
  if (!h->non_got_ref)
2454
    return TRUE;
2455
 
2456
  if (h->size == 0)
2457
    {
2458
      (*_bfd_error_handler) (_("dynamic variable `%s' is zero size"),
2459
                             h->root.root.string);
2460
      return TRUE;
2461
    }
2462
 
2463
  /* We must allocate the symbol in our .dynbss section, which will
2464
     become part of the .bss section of the executable.  There will be
2465
     an entry for this symbol in the .dynsym section.  The dynamic
2466
     object will contain position independent code, so all references
2467
     from the dynamic object to this symbol will go through the global
2468
     offset table.  The dynamic linker will use the .dynsym entry to
2469
     determine the address it must put in the global offset table, so
2470
     both the dynamic object and the regular object will refer to the
2471
     same memory location for the variable.  */
2472
 
2473
  s = bfd_get_section_by_name (dynobj, ".dynbss");
2474
  BFD_ASSERT (s != NULL);
2475
 
2476
  /* We must generate a R_CR16_COPY reloc to tell the dynamic linker to
2477
     copy the initial value out of the dynamic object and into the
2478
     runtime process image.  We need to remember the offset into the
2479
     .rela.bss section we are going to use.  */
2480
  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
2481
    {
2482
      asection * srel;
2483
 
2484
      srel = bfd_get_section_by_name (dynobj, ".rela.bss");
2485
      BFD_ASSERT (srel != NULL);
2486
      srel->size += sizeof (Elf32_External_Rela);
2487
      h->needs_copy = 1;
2488
    }
2489
 
2490
  return _bfd_elf_adjust_dynamic_copy (h, s);
2491
}
2492
 
2493
/* Set the sizes of the dynamic sections.  */
2494
 
2495
static bfd_boolean
2496
_bfd_cr16_elf_size_dynamic_sections (bfd * output_bfd,
2497
                                     struct bfd_link_info * info)
2498
{
2499
  bfd * dynobj;
2500
  asection * s;
2501
  bfd_boolean plt;
2502
  bfd_boolean relocs;
2503
  bfd_boolean reltext;
2504
 
2505
  dynobj = elf_hash_table (info)->dynobj;
2506
  BFD_ASSERT (dynobj != NULL);
2507
 
2508
  if (elf_hash_table (info)->dynamic_sections_created)
2509
    {
2510
      /* Set the contents of the .interp section to the interpreter.  */
2511
      if (info->executable)
2512
        {
2513
#if 0
2514
          s = bfd_get_section_by_name (dynobj, ".interp");
2515
          BFD_ASSERT (s != NULL);
2516
          s->size = sizeof ELF_DYNAMIC_INTERPRETER;
2517
          s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
2518
#endif
2519
        }
2520
    }
2521
  else
2522
    {
2523
      /* We may have created entries in the .rela.got section.
2524
         However, if we are not creating the dynamic sections, we will
2525
         not actually use these entries.  Reset the size of .rela.got,
2526
         which will cause it to get stripped from the output file
2527
         below.  */
2528
      s = bfd_get_section_by_name (dynobj, ".rela.got");
2529
      if (s != NULL)
2530
        s->size = 0;
2531
    }
2532
 
2533
  /* The check_relocs and adjust_dynamic_symbol entry points have
2534
     determined the sizes of the various dynamic sections.  Allocate
2535
     memory for them.  */
2536
  plt = FALSE;
2537
  relocs = FALSE;
2538
  reltext = FALSE;
2539
  for (s = dynobj->sections; s != NULL; s = s->next)
2540
    {
2541
      const char * name;
2542
 
2543
      if ((s->flags & SEC_LINKER_CREATED) == 0)
2544
        continue;
2545
 
2546
      /* It's OK to base decisions on the section name, because none
2547
         of the dynobj section names depend upon the input files.  */
2548
      name = bfd_get_section_name (dynobj, s);
2549
 
2550
      if (strcmp (name, ".plt") == 0)
2551
        {
2552
          /* Remember whether there is a PLT.  */
2553
          plt = s->size != 0;
2554
        }
2555
      else if (CONST_STRNEQ (name, ".rela"))
2556
        {
2557
          if (s->size != 0)
2558
            {
2559
              asection * target;
2560
 
2561
              /* Remember whether there are any reloc sections other
2562
                 than .rela.plt.  */
2563
              if (strcmp (name, ".rela.plt") != 0)
2564
                {
2565
                  const char * outname;
2566
 
2567
                  relocs = TRUE;
2568
 
2569
                  /* If this relocation section applies to a read only
2570
                     section, then we probably need a DT_TEXTREL
2571
                     entry.  The entries in the .rela.plt section
2572
                     really apply to the .got section, which we
2573
                     created ourselves and so know is not readonly.  */
2574
                  outname = bfd_get_section_name (output_bfd,
2575
                                                  s->output_section);
2576
                  target = bfd_get_section_by_name (output_bfd, outname + 5);
2577
                  if (target != NULL
2578
                      && (target->flags & SEC_READONLY) != 0
2579
                      && (target->flags & SEC_ALLOC) != 0)
2580
                    reltext = TRUE;
2581
                }
2582
 
2583
              /* We use the reloc_count field as a counter if we need
2584
                 to copy relocs into the output file.  */
2585
              s->reloc_count = 0;
2586
            }
2587
        }
2588
      else if (! CONST_STRNEQ (name, ".got")
2589
               && strcmp (name, ".dynbss") != 0)
2590
        /* It's not one of our sections, so don't allocate space.  */
2591
        continue;
2592
 
2593
      if (s->size == 0)
2594
        {
2595
          /* If we don't need this section, strip it from the
2596
             output file.  This is mostly to handle .rela.bss and
2597
             .rela.plt.  We must create both sections in
2598
             create_dynamic_sections, because they must be created
2599
             before the linker maps input sections to output
2600
             sections.  The linker does that before
2601
             adjust_dynamic_symbol is called, and it is that
2602
             function which decides whether anything needs to go
2603
             into these sections.  */
2604
          s->flags |= SEC_EXCLUDE;
2605
          continue;
2606
        }
2607
 
2608
        if ((s->flags & SEC_HAS_CONTENTS) == 0)
2609
          continue;
2610
 
2611
      /* Allocate memory for the section contents.  We use bfd_zalloc
2612
         here in case unused entries are not reclaimed before the
2613
         section's contents are written out.  This should not happen,
2614
         but this way if it does, we get a R_CR16_NONE reloc
2615
         instead of garbage.  */
2616
      s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
2617
      if (s->contents == NULL)
2618
        return FALSE;
2619
    }
2620
 
2621
  if (elf_hash_table (info)->dynamic_sections_created)
2622
    {
2623
      /* Add some entries to the .dynamic section.  We fill in the
2624
         values later, in _bfd_cr16_elf_finish_dynamic_sections,
2625
         but we must add the entries now so that we get the correct
2626
         size for the .dynamic section.  The DT_DEBUG entry is filled
2627
         in by the dynamic linker and used by the debugger.  */
2628
      if (! info->executable)
2629
        {
2630
          if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
2631
            return FALSE;
2632
        }
2633
 
2634
      if (plt)
2635
        {
2636
          if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)
2637
              || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
2638
              || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
2639
              || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0))
2640
            return FALSE;
2641
        }
2642
 
2643
      if (relocs)
2644
        {
2645
          if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0)
2646
              || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0)
2647
              || !_bfd_elf_add_dynamic_entry (info, DT_RELAENT,
2648
                                              sizeof (Elf32_External_Rela)))
2649
            return FALSE;
2650
        }
2651
 
2652
      if (reltext)
2653
        {
2654
          if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
2655
            return FALSE;
2656
        }
2657
    }
2658
 
2659
  return TRUE;
2660
}
2661
 
2662
/* Finish up dynamic symbol handling.  We set the contents of various
2663
   dynamic sections here.  */
2664
 
2665
static bfd_boolean
2666
_bfd_cr16_elf_finish_dynamic_symbol (bfd * output_bfd,
2667
                                     struct bfd_link_info * info,
2668
                                     struct elf_link_hash_entry * h,
2669
                                     Elf_Internal_Sym * sym)
2670
{
2671
  bfd * dynobj;
2672
 
2673
  dynobj = elf_hash_table (info)->dynobj;
2674
 
2675
  if (h->got.offset != (bfd_vma) -1)
2676
    {
2677
      asection *        sgot;
2678
      asection *        srel;
2679
      Elf_Internal_Rela rel;
2680
 
2681
      /* This symbol has an entry in the global offset table.  Set it up.  */
2682
 
2683
      sgot = bfd_get_section_by_name (dynobj, ".got");
2684
      srel = bfd_get_section_by_name (dynobj, ".rela.got");
2685
      BFD_ASSERT (sgot != NULL && srel != NULL);
2686
 
2687
      rel.r_offset = (sgot->output_section->vma
2688
                      + sgot->output_offset
2689
                      + (h->got.offset & ~1));
2690
 
2691
      /* If this is a -Bsymbolic link, and the symbol is defined
2692
         locally, we just want to emit a RELATIVE reloc.  Likewise if
2693
         the symbol was forced to be local because of a version file.
2694
         The entry in the global offset table will already have been
2695
         initialized in the relocate_section function.  */
2696
      if (info->executable
2697
          && (info->symbolic || h->dynindx == -1)
2698
          && h->def_regular)
2699
        {
2700
          rel.r_info = ELF32_R_INFO (0, R_CR16_GOT_REGREL20);
2701
          rel.r_addend = (h->root.u.def.value
2702
                          + h->root.u.def.section->output_section->vma
2703
                          + h->root.u.def.section->output_offset);
2704
        }
2705
      else
2706
        {
2707
          bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
2708
          rel.r_info = ELF32_R_INFO (h->dynindx, R_CR16_GOT_REGREL20);
2709
          rel.r_addend = 0;
2710
        }
2711
 
2712
      bfd_elf32_swap_reloca_out (output_bfd, &rel,
2713
                                 (bfd_byte *) ((Elf32_External_Rela *) srel->contents
2714
                                               + srel->reloc_count));
2715
      ++ srel->reloc_count;
2716
    }
2717
 
2718
  if (h->needs_copy)
2719
    {
2720
      asection *        s;
2721
      Elf_Internal_Rela rel;
2722
 
2723
      /* This symbol needs a copy reloc.  Set it up.  */
2724
      BFD_ASSERT (h->dynindx != -1
2725
                  && (h->root.type == bfd_link_hash_defined
2726
                      || h->root.type == bfd_link_hash_defweak));
2727
 
2728
      s = bfd_get_section_by_name (h->root.u.def.section->owner,
2729
                                   ".rela.bss");
2730
      BFD_ASSERT (s != NULL);
2731
 
2732
      rel.r_offset = (h->root.u.def.value
2733
                      + h->root.u.def.section->output_section->vma
2734
                      + h->root.u.def.section->output_offset);
2735
      rel.r_info = ELF32_R_INFO (h->dynindx, R_CR16_GOT_REGREL20);
2736
      rel.r_addend = 0;
2737
      bfd_elf32_swap_reloca_out (output_bfd, &rel,
2738
                                 (bfd_byte *) ((Elf32_External_Rela *) s->contents
2739
                                               + s->reloc_count));
2740
     ++ s->reloc_count;
2741
    }
2742
 
2743
  /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
2744
  if (strcmp (h->root.root.string, "_DYNAMIC") == 0
2745
      || h == elf_hash_table (info)->hgot)
2746
    sym->st_shndx = SHN_ABS;
2747
 
2748
  return TRUE;
2749
}
2750
 
2751
/* Finish up the dynamic sections.  */
2752
 
2753
static bfd_boolean
2754
_bfd_cr16_elf_finish_dynamic_sections (bfd * output_bfd,
2755
                                       struct bfd_link_info * info)
2756
{
2757
  bfd *      dynobj;
2758
  asection * sgot;
2759
  asection * sdyn;
2760
 
2761
  dynobj = elf_hash_table (info)->dynobj;
2762
 
2763
  sgot = bfd_get_section_by_name (dynobj, ".got.plt");
2764
  BFD_ASSERT (sgot != NULL);
2765
  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
2766
 
2767
  if (elf_hash_table (info)->dynamic_sections_created)
2768
    {
2769
      Elf32_External_Dyn * dyncon;
2770
      Elf32_External_Dyn * dynconend;
2771
 
2772
      BFD_ASSERT (sdyn != NULL);
2773
 
2774
      dyncon = (Elf32_External_Dyn *) sdyn->contents;
2775
      dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
2776
 
2777
      for (; dyncon < dynconend; dyncon++)
2778
        {
2779
          Elf_Internal_Dyn dyn;
2780
          const char * name;
2781
          asection * s;
2782
 
2783
          bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
2784
 
2785
          switch (dyn.d_tag)
2786
            {
2787
            default:
2788
              break;
2789
 
2790
            case DT_PLTGOT:
2791
              name = ".got";
2792
              goto get_vma;
2793
 
2794
            case DT_JMPREL:
2795
              name = ".rela.plt";
2796
            get_vma:
2797
              s = bfd_get_section_by_name (output_bfd, name);
2798
              BFD_ASSERT (s != NULL);
2799
              dyn.d_un.d_ptr = s->vma;
2800
              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
2801
              break;
2802
 
2803
            case DT_PLTRELSZ:
2804
              s = bfd_get_section_by_name (output_bfd, ".rela.plt");
2805
              BFD_ASSERT (s != NULL);
2806
              dyn.d_un.d_val = s->size;
2807
              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
2808
              break;
2809
 
2810
            case DT_RELASZ:
2811
              /* My reading of the SVR4 ABI indicates that the
2812
                 procedure linkage table relocs (DT_JMPREL) should be
2813
                 included in the overall relocs (DT_RELA).  This is
2814
                 what Solaris does.  However, UnixWare can not handle
2815
                 that case.  Therefore, we override the DT_RELASZ entry
2816
                 here to make it not include the JMPREL relocs.  Since
2817
                 the linker script arranges for .rela.plt to follow all
2818
                 other relocation sections, we don't have to worry
2819
                 about changing the DT_RELA entry.  */
2820
              s = bfd_get_section_by_name (output_bfd, ".rela.plt");
2821
              if (s != NULL)
2822
                dyn.d_un.d_val -= s->size;
2823
              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
2824
              break;
2825
            }
2826
        }
2827
 
2828
    }
2829
 
2830
  /* Fill in the first three entries in the global offset table.  */
2831
  if (sgot->size > 0)
2832
    {
2833
      if (sdyn == NULL)
2834
        bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
2835
      else
2836
        bfd_put_32 (output_bfd,
2837
                    sdyn->output_section->vma + sdyn->output_offset,
2838
                    sgot->contents);
2839
    }
2840
 
2841
  elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
2842
 
2843
  return TRUE;
2844
}
2845
 
2846
/* Given a .data.rel section and a .emreloc in-memory section, store
2847
   relocation information into the .emreloc section which can be
2848
   used at runtime to relocate the section.  This is called by the
2849
   linker when the --embedded-relocs switch is used.  This is called
2850
   after the add_symbols entry point has been called for all the
2851
   objects, and before the final_link entry point is called.  */
2852
 
2853
bfd_boolean
2854
bfd_cr16_elf32_create_embedded_relocs (bfd *abfd,
2855
                                       struct bfd_link_info *info,
2856
                                       asection *datasec,
2857
                                       asection *relsec,
2858
                                       char **errmsg)
2859
{
2860
  Elf_Internal_Shdr *symtab_hdr;
2861
  Elf_Internal_Sym *isymbuf = NULL;
2862
  Elf_Internal_Rela *internal_relocs = NULL;
2863
  Elf_Internal_Rela *irel, *irelend;
2864
  bfd_byte *p;
2865
  bfd_size_type amt;
2866
 
2867
  BFD_ASSERT (! info->relocatable);
2868
 
2869
  *errmsg = NULL;
2870
 
2871
  if (datasec->reloc_count == 0)
2872
    return TRUE;
2873
 
2874
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2875
 
2876
  /* Get a copy of the native relocations.  */
2877
  internal_relocs = (_bfd_elf_link_read_relocs
2878
                     (abfd, datasec, NULL, NULL, info->keep_memory));
2879
  if (internal_relocs == NULL)
2880
    goto error_return;
2881
 
2882
  amt = (bfd_size_type) datasec->reloc_count * 8;
2883
  relsec->contents = (bfd_byte *) bfd_alloc (abfd, amt);
2884
  if (relsec->contents == NULL)
2885
    goto error_return;
2886
 
2887
  p = relsec->contents;
2888
 
2889
  irelend = internal_relocs + datasec->reloc_count;
2890
  for (irel = internal_relocs; irel < irelend; irel++, p += 8)
2891
    {
2892
      asection *targetsec;
2893
 
2894
      /* We are going to write a four byte longword into the runtime
2895
       reloc section.  The longword will be the address in the data
2896
       section which must be relocated.  It is followed by the name
2897
       of the target section NUL-padded or truncated to 8
2898
       characters.  */
2899
 
2900
      /* We can only relocate absolute longword relocs at run time.  */
2901
      if (!((ELF32_R_TYPE (irel->r_info) == (int) R_CR16_NUM32a)
2902
          || (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_NUM32)))
2903
        {
2904
          *errmsg = _("unsupported reloc type");
2905
          bfd_set_error (bfd_error_bad_value);
2906
          goto error_return;
2907
        }
2908
 
2909
      /* Get the target section referred to by the reloc.  */
2910
      if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
2911
        {
2912
          /* A local symbol.  */
2913
          Elf_Internal_Sym *isym;
2914
 
2915
          /* Read this BFD's local symbols if we haven't done so already.  */
2916
          if (isymbuf == NULL)
2917
            {
2918
              isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
2919
              if (isymbuf == NULL)
2920
                isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
2921
                                                symtab_hdr->sh_info, 0,
2922
                                                NULL, NULL, NULL);
2923
              if (isymbuf == NULL)
2924
                goto error_return;
2925
            }
2926
 
2927
          isym = isymbuf + ELF32_R_SYM (irel->r_info);
2928
          targetsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
2929
        }
2930
      else
2931
        {
2932
          unsigned long indx;
2933
          struct elf_link_hash_entry *h;
2934
 
2935
          /* An external symbol.  */
2936
          indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
2937
          h = elf_sym_hashes (abfd)[indx];
2938
          BFD_ASSERT (h != NULL);
2939
          if (h->root.type == bfd_link_hash_defined
2940
              || h->root.type == bfd_link_hash_defweak)
2941
            targetsec = h->root.u.def.section;
2942
          else
2943
            targetsec = NULL;
2944
        }
2945
 
2946
      bfd_put_32 (abfd, irel->r_offset + datasec->output_offset, p);
2947
      memset (p + 4, 0, 4);
2948
      if ((ELF32_R_TYPE (irel->r_info) == (int) R_CR16_NUM32a)
2949
          && (targetsec != NULL) )
2950
         strncpy ((char *) p + 4, targetsec->output_section->name, 4);
2951
    }
2952
 
2953
  if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
2954
    free (isymbuf);
2955
  if (internal_relocs != NULL
2956
      && elf_section_data (datasec)->relocs != internal_relocs)
2957
    free (internal_relocs);
2958
  return TRUE;
2959
 
2960
error_return:
2961
  if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
2962
    free (isymbuf);
2963
  if (internal_relocs != NULL
2964
      && elf_section_data (datasec)->relocs != internal_relocs)
2965
    free (internal_relocs);
2966
  return FALSE;
2967
}
2968
 
2969
 
2970
/* Classify relocation types, such that combreloc can sort them
2971
   properly.  */
2972
 
2973
static enum elf_reloc_type_class
2974
_bfd_cr16_elf_reloc_type_class (const Elf_Internal_Rela *rela)
2975
{
2976
  switch ((int) ELF32_R_TYPE (rela->r_info))
2977
    {
2978
    case R_CR16_GOT_REGREL20:
2979
    case R_CR16_GOTC_REGREL20:
2980
      return reloc_class_relative;
2981
    default:
2982
      return reloc_class_normal;
2983
    }
2984
}
2985
 
2986
/* Definitions for setting CR16 target vector.  */
2987
#define TARGET_LITTLE_SYM                 bfd_elf32_cr16_vec
2988
#define TARGET_LITTLE_NAME                "elf32-cr16"
2989
#define ELF_ARCH                          bfd_arch_cr16
2990
#define ELF_MACHINE_CODE                  EM_CR16
2991
#define ELF_MACHINE_ALT1                  EM_CR16_OLD
2992
#define ELF_MAXPAGESIZE                   0x1
2993
#define elf_symbol_leading_char           '_'
2994
 
2995
#define bfd_elf32_bfd_reloc_type_lookup   elf_cr16_reloc_type_lookup
2996
#define bfd_elf32_bfd_reloc_name_lookup   elf_cr16_reloc_name_lookup
2997
#define elf_info_to_howto                 elf_cr16_info_to_howto
2998
#define elf_info_to_howto_rel             0
2999
#define elf_backend_relocate_section      elf32_cr16_relocate_section
3000
#define bfd_elf32_bfd_relax_section       elf32_cr16_relax_section
3001
#define bfd_elf32_bfd_get_relocated_section_contents \
3002
                                elf32_cr16_get_relocated_section_contents
3003
#define elf_backend_gc_mark_hook          elf32_cr16_gc_mark_hook
3004
#define elf_backend_gc_sweep_hook         elf32_cr16_gc_sweep_hook
3005
#define elf_backend_can_gc_sections       1
3006
#define elf_backend_rela_normal           1
3007
#define elf_backend_check_relocs          cr16_elf_check_relocs
3008
/* So we can set bits in e_flags.  */
3009
#define elf_backend_final_write_processing \
3010
                                 _bfd_cr16_elf_final_write_processing
3011
#define elf_backend_object_p     _bfd_cr16_elf_object_p
3012
 
3013
#define bfd_elf32_bfd_merge_private_bfd_data \
3014
                                 _bfd_cr16_elf_merge_private_bfd_data
3015
 
3016
 
3017
#define bfd_elf32_bfd_link_hash_table_create \
3018
                                  elf32_cr16_link_hash_table_create
3019
#define bfd_elf32_bfd_link_hash_table_free \
3020
                                  elf32_cr16_link_hash_table_free
3021
 
3022
#define elf_backend_create_dynamic_sections \
3023
                                  _bfd_cr16_elf_create_dynamic_sections
3024
#define elf_backend_adjust_dynamic_symbol \
3025
                                  _bfd_cr16_elf_adjust_dynamic_symbol
3026
#define elf_backend_size_dynamic_sections \
3027
                                  _bfd_cr16_elf_size_dynamic_sections
3028
#define elf_backend_omit_section_dynsym \
3029
      ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
3030
#define elf_backend_finish_dynamic_symbol \
3031
                                   _bfd_cr16_elf_finish_dynamic_symbol
3032
#define elf_backend_finish_dynamic_sections \
3033
                                   _bfd_cr16_elf_finish_dynamic_sections
3034
 
3035
#define elf_backend_reloc_type_class   _bfd_cr16_elf_reloc_type_class
3036
 
3037
 
3038
#define elf_backend_want_got_plt        1
3039
#define elf_backend_plt_readonly        1
3040
#define elf_backend_want_plt_sym        0
3041
#define elf_backend_got_header_size     12
3042
 
3043
#include "elf32-target.h"

powered by: WebSVN 2.1.0

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