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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [elf32-cr16.c] - Blame information for rev 249

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

Line No. Rev Author Line
1 14 khays
/* 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
        RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
1436
                                         rel, relend, howto, contents);
1437
 
1438
      if (info->relocatable)
1439
        continue;
1440
 
1441
      r = cr16_elf_final_link_relocate (howto, input_bfd, output_bfd,
1442
                                        input_section,
1443
                                        contents, rel->r_offset,
1444
                                        relocation, rel->r_addend,
1445
                                        (struct elf_link_hash_entry *) h,
1446
                                        r_symndx,
1447
                                        info, sec, h == NULL);
1448
 
1449
      if (r != bfd_reloc_ok)
1450
        {
1451
          const char *name;
1452
          const char *msg = NULL;
1453
 
1454
          if (h != NULL)
1455
            name = h->root.root.string;
1456
          else
1457
            {
1458
              name = (bfd_elf_string_from_elf_section
1459
                      (input_bfd, symtab_hdr->sh_link, sym->st_name));
1460
              if (name == NULL || *name == '\0')
1461
                name = bfd_section_name (input_bfd, sec);
1462
            }
1463
 
1464
          switch (r)
1465
            {
1466
             case bfd_reloc_overflow:
1467
               if (!((*info->callbacks->reloc_overflow)
1468
                     (info, (h ? &h->root : NULL), name, howto->name,
1469
                      (bfd_vma) 0, input_bfd, input_section,
1470
                      rel->r_offset)))
1471
                 return FALSE;
1472
               break;
1473
 
1474
             case bfd_reloc_undefined:
1475
               if (!((*info->callbacks->undefined_symbol)
1476
                     (info, name, input_bfd, input_section,
1477
                      rel->r_offset, TRUE)))
1478
                 return FALSE;
1479
               break;
1480
 
1481
             case bfd_reloc_outofrange:
1482
               msg = _("internal error: out of range error");
1483
               goto common_error;
1484
 
1485
             case bfd_reloc_notsupported:
1486
               msg = _("internal error: unsupported relocation error");
1487
               goto common_error;
1488
 
1489
             case bfd_reloc_dangerous:
1490
               msg = _("internal error: dangerous error");
1491
               goto common_error;
1492
 
1493
             default:
1494
               msg = _("internal error: unknown error");
1495
               /* Fall through.  */
1496
 
1497
             common_error:
1498
               if (!((*info->callbacks->warning)
1499
                     (info, msg, name, input_bfd, input_section,
1500
                      rel->r_offset)))
1501
                 return FALSE;
1502
               break;
1503
            }
1504
        }
1505
    }
1506
 
1507
  return TRUE;
1508
}
1509
 
1510
/* This is a version of bfd_generic_get_relocated_section_contents
1511
   which uses elf32_cr16_relocate_section.  */
1512
 
1513
static bfd_byte *
1514
elf32_cr16_get_relocated_section_contents (bfd *output_bfd,
1515
                                           struct bfd_link_info *link_info,
1516
                                           struct bfd_link_order *link_order,
1517
                                           bfd_byte *data,
1518
                                           bfd_boolean relocatable,
1519
                                           asymbol **symbols)
1520
{
1521
  Elf_Internal_Shdr *symtab_hdr;
1522
  asection *input_section = link_order->u.indirect.section;
1523
  bfd *input_bfd = input_section->owner;
1524
  asection **sections = NULL;
1525
  Elf_Internal_Rela *internal_relocs = NULL;
1526
  Elf_Internal_Sym *isymbuf = NULL;
1527
 
1528
  /* We only need to handle the case of relaxing, or of having a
1529
     particular set of section contents, specially.  */
1530
  if (relocatable
1531
      || elf_section_data (input_section)->this_hdr.contents == NULL)
1532
    return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
1533
                                                       link_order, data,
1534
                                                       relocatable,
1535
                                                       symbols);
1536
 
1537
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1538
 
1539
  memcpy (data, elf_section_data (input_section)->this_hdr.contents,
1540
          (size_t) input_section->size);
1541
 
1542
  if ((input_section->flags & SEC_RELOC) != 0
1543
      && input_section->reloc_count > 0)
1544
    {
1545
      Elf_Internal_Sym *isym;
1546
      Elf_Internal_Sym *isymend;
1547
      asection **secpp;
1548
      bfd_size_type amt;
1549
 
1550
      internal_relocs = _bfd_elf_link_read_relocs (input_bfd, input_section,
1551
                                                   NULL, NULL, FALSE);
1552
      if (internal_relocs == NULL)
1553
        goto error_return;
1554
 
1555
      if (symtab_hdr->sh_info != 0)
1556
        {
1557
          isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1558
          if (isymbuf == NULL)
1559
            isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
1560
                                            symtab_hdr->sh_info, 0,
1561
                                            NULL, NULL, NULL);
1562
          if (isymbuf == NULL)
1563
            goto error_return;
1564
        }
1565
 
1566
      amt = symtab_hdr->sh_info;
1567
      amt *= sizeof (asection *);
1568
      sections = bfd_malloc (amt);
1569
      if (sections == NULL && amt != 0)
1570
        goto error_return;
1571
 
1572
      isymend = isymbuf + symtab_hdr->sh_info;
1573
      for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
1574
        {
1575
          asection *isec;
1576
 
1577
          if (isym->st_shndx == SHN_UNDEF)
1578
            isec = bfd_und_section_ptr;
1579
          else if (isym->st_shndx == SHN_ABS)
1580
            isec = bfd_abs_section_ptr;
1581
          else if (isym->st_shndx == SHN_COMMON)
1582
            isec = bfd_com_section_ptr;
1583
          else
1584
            isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
1585
 
1586
          *secpp = isec;
1587
        }
1588
 
1589
      if (! elf32_cr16_relocate_section (output_bfd, link_info, input_bfd,
1590
                                     input_section, data, internal_relocs,
1591
                                     isymbuf, sections))
1592
        goto error_return;
1593
 
1594
      if (sections != NULL)
1595
        free (sections);
1596
      if (isymbuf != NULL
1597
          && symtab_hdr->contents != (unsigned char *) isymbuf)
1598
        free (isymbuf);
1599
      if (elf_section_data (input_section)->relocs != internal_relocs)
1600
        free (internal_relocs);
1601
    }
1602
 
1603
  return data;
1604
 
1605
 error_return:
1606
  if (sections != NULL)
1607
    free (sections);
1608
  if (isymbuf != NULL
1609
      && symtab_hdr->contents != (unsigned char *) isymbuf)
1610
    free (isymbuf);
1611
  if (internal_relocs != NULL
1612
      && elf_section_data (input_section)->relocs != internal_relocs)
1613
    free (internal_relocs);
1614
  return NULL;
1615
}
1616
 
1617
/* Assorted hash table functions.  */
1618
 
1619
/* Initialize an entry in the link hash table.  */
1620
 
1621
/* Create an entry in an CR16 ELF linker hash table.  */
1622
 
1623
static struct bfd_hash_entry *
1624
elf32_cr16_link_hash_newfunc (struct bfd_hash_entry *entry,
1625
                              struct bfd_hash_table *table,
1626
                              const char *string)
1627
{
1628
  struct elf32_cr16_link_hash_entry *ret =
1629
    (struct elf32_cr16_link_hash_entry *) entry;
1630
 
1631
  /* Allocate the structure if it has not already been allocated by a
1632
     subclass.  */
1633
  if (ret == (struct elf32_cr16_link_hash_entry *) NULL)
1634
    ret = ((struct elf32_cr16_link_hash_entry *)
1635
           bfd_hash_allocate (table,
1636
                              sizeof (struct elf32_cr16_link_hash_entry)));
1637
  if (ret == (struct elf32_cr16_link_hash_entry *) NULL)
1638
    return (struct bfd_hash_entry *) ret;
1639
 
1640
  /* Call the allocation method of the superclass.  */
1641
  ret = ((struct elf32_cr16_link_hash_entry *)
1642
         _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1643
                                     table, string));
1644
  if (ret != (struct elf32_cr16_link_hash_entry *) NULL)
1645
    {
1646
      ret->direct_calls = 0;
1647
      ret->stack_size = 0;
1648
      ret->movm_args = 0;
1649
      ret->movm_stack_size = 0;
1650
      ret->flags = 0;
1651
      ret->value = 0;
1652
    }
1653
 
1654
  return (struct bfd_hash_entry *) ret;
1655
}
1656
 
1657
/* Create an cr16 ELF linker hash table.  */
1658
 
1659
static struct bfd_link_hash_table *
1660
elf32_cr16_link_hash_table_create (bfd *abfd)
1661
{
1662
  struct elf_link_hash_table *ret;
1663
  bfd_size_type amt = sizeof (struct elf_link_hash_table);
1664
 
1665
  ret = (struct elf_link_hash_table *) bfd_malloc (amt);
1666
  if (ret == (struct elf_link_hash_table *) NULL)
1667
    return NULL;
1668
 
1669
  if (!_bfd_elf_link_hash_table_init (ret, abfd,
1670
                                      elf32_cr16_link_hash_newfunc,
1671
                                      sizeof (struct elf32_cr16_link_hash_entry),
1672
                                      GENERIC_ELF_DATA))
1673
    {
1674
      free (ret);
1675
      return NULL;
1676
    }
1677
 
1678
  return &ret->root;
1679
}
1680
 
1681
/* Free an cr16 ELF linker hash table.  */
1682
 
1683
static void
1684
elf32_cr16_link_hash_table_free (struct bfd_link_hash_table *hash)
1685
{
1686
  struct elf_link_hash_table *ret
1687
    = (struct elf_link_hash_table *) hash;
1688
 
1689
  _bfd_generic_link_hash_table_free
1690
    ((struct bfd_link_hash_table *) ret);
1691
}
1692
 
1693
static unsigned long
1694
elf_cr16_mach (flagword flags)
1695
{
1696
  switch (flags)
1697
    {
1698
      case EM_CR16:
1699
      default:
1700
      return bfd_mach_cr16;
1701
    }
1702
}
1703
 
1704
/* The final processing done just before writing out a CR16 ELF object
1705
   file.  This gets the CR16 architecture right based on the machine
1706
   number.  */
1707
 
1708
static void
1709
_bfd_cr16_elf_final_write_processing (bfd *abfd,
1710
                                      bfd_boolean linker ATTRIBUTE_UNUSED)
1711
{
1712
  unsigned long val;
1713
  switch (bfd_get_mach (abfd))
1714
    {
1715
     default:
1716
     case bfd_mach_cr16:
1717
        val = EM_CR16;
1718
        break;
1719
    }
1720
 
1721
 
1722
 elf_elfheader (abfd)->e_flags |= val;
1723
}
1724
 
1725
 
1726
static bfd_boolean
1727
_bfd_cr16_elf_object_p (bfd *abfd)
1728
{
1729
  bfd_default_set_arch_mach (abfd, bfd_arch_cr16,
1730
                             elf_cr16_mach (elf_elfheader (abfd)->e_flags));
1731
  return TRUE;
1732
}
1733
 
1734
/* Merge backend specific data from an object file to the output
1735
   object file when linking.  */
1736
 
1737
static bfd_boolean
1738
_bfd_cr16_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
1739
{
1740
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1741
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1742
    return TRUE;
1743
 
1744
  if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1745
      && bfd_get_mach (obfd) < bfd_get_mach (ibfd))
1746
    {
1747
      if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
1748
                               bfd_get_mach (ibfd)))
1749
         return FALSE;
1750
     }
1751
 
1752
  return TRUE;
1753
}
1754
 
1755
 
1756
/* This function handles relaxing for the CR16.
1757
 
1758
   There's quite a few relaxing opportunites available on the CR16:
1759
 
1760
        * bcond:24 -> bcond:16                                1 byte
1761
        * bcond:16 -> bcond:8                                 1 byte
1762
        * arithmetic imm32 -> arithmetic imm20                12 bits
1763
        * arithmetic imm20/imm16 -> arithmetic imm4           12/16 bits
1764
 
1765
   Symbol- and reloc-reading infrastructure copied from elf-m10200.c.  */
1766
 
1767
static bfd_boolean
1768
elf32_cr16_relax_section (bfd *abfd, asection *sec,
1769
                          struct bfd_link_info *link_info, bfd_boolean *again)
1770
{
1771
  Elf_Internal_Shdr *symtab_hdr;
1772
  Elf_Internal_Rela *internal_relocs;
1773
  Elf_Internal_Rela *irel, *irelend;
1774
  bfd_byte *contents = NULL;
1775
  Elf_Internal_Sym *isymbuf = NULL;
1776
 
1777
  /* Assume nothing changes.  */
1778
  *again = FALSE;
1779
 
1780
  /* We don't have to do anything for a relocatable link, if
1781
     this section does not have relocs, or if this is not a
1782
     code section.  */
1783
  if (link_info->relocatable
1784
      || (sec->flags & SEC_RELOC) == 0
1785
      || sec->reloc_count == 0
1786
      || (sec->flags & SEC_CODE) == 0)
1787
    return TRUE;
1788
 
1789
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1790
 
1791
  /* Get a copy of the native relocations.  */
1792
  internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
1793
                                               link_info->keep_memory);
1794
  if (internal_relocs == NULL)
1795
    goto error_return;
1796
 
1797
  /* Walk through them looking for relaxing opportunities.  */
1798
  irelend = internal_relocs + sec->reloc_count;
1799
  for (irel = internal_relocs; irel < irelend; irel++)
1800
    {
1801
      bfd_vma symval;
1802
 
1803
      /* If this isn't something that can be relaxed, then ignore
1804
         this reloc.  */
1805
      if (ELF32_R_TYPE (irel->r_info) != (int) R_CR16_DISP16
1806
          && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_DISP24
1807
          && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_IMM32
1808
          && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_IMM20
1809
          && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_IMM16)
1810
        continue;
1811
 
1812
      /* Get the section contents if we haven't done so already.  */
1813
      if (contents == NULL)
1814
        {
1815
          /* Get cached copy if it exists.  */
1816
          if (elf_section_data (sec)->this_hdr.contents != NULL)
1817
            contents = elf_section_data (sec)->this_hdr.contents;
1818
          /* Go get them off disk.  */
1819
          else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
1820
            goto error_return;
1821
        }
1822
 
1823
      /* Read this BFD's local symbols if we haven't done so already.  */
1824
      if (isymbuf == NULL && symtab_hdr->sh_info != 0)
1825
        {
1826
          isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1827
          if (isymbuf == NULL)
1828
            isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
1829
                                            symtab_hdr->sh_info, 0,
1830
                                            NULL, NULL, NULL);
1831
          if (isymbuf == NULL)
1832
            goto error_return;
1833
        }
1834
 
1835
      /* Get the value of the symbol referred to by the reloc.  */
1836
      if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1837
        {
1838
          /* A local symbol.  */
1839
          Elf_Internal_Sym *isym;
1840
          asection *sym_sec;
1841
 
1842
          isym = isymbuf + ELF32_R_SYM (irel->r_info);
1843
          if (isym->st_shndx == SHN_UNDEF)
1844
            sym_sec = bfd_und_section_ptr;
1845
          else if (isym->st_shndx == SHN_ABS)
1846
            sym_sec = bfd_abs_section_ptr;
1847
          else if (isym->st_shndx == SHN_COMMON)
1848
            sym_sec = bfd_com_section_ptr;
1849
          else
1850
            sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1851
          symval = (isym->st_value
1852
                    + sym_sec->output_section->vma
1853
                    + sym_sec->output_offset);
1854
        }
1855
      else
1856
        {
1857
          unsigned long indx;
1858
          struct elf_link_hash_entry *h;
1859
 
1860
          /* An external symbol.  */
1861
          indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1862
          h = elf_sym_hashes (abfd)[indx];
1863
          BFD_ASSERT (h != NULL);
1864
 
1865
          if (h->root.type != bfd_link_hash_defined
1866
              && h->root.type != bfd_link_hash_defweak)
1867
            /* This appears to be a reference to an undefined
1868
               symbol.  Just ignore it--it will be caught by the
1869
               regular reloc processing.  */
1870
            continue;
1871
 
1872
          symval = (h->root.u.def.value
1873
                    + h->root.u.def.section->output_section->vma
1874
                    + h->root.u.def.section->output_offset);
1875
        }
1876
 
1877
      /* For simplicity of coding, we are going to modify the section
1878
         contents, the section relocs, and the BFD symbol table.  We
1879
         must tell the rest of the code not to free up this
1880
         information.  It would be possible to instead create a table
1881
         of changes which have to be made, as is done in coff-mips.c;
1882
         that would be more work, but would require less memory when
1883
         the linker is run.  */
1884
 
1885
      /* Try to turn a 24  branch/call into a 16bit relative
1886
         branch/call.  */
1887
      if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_DISP24)
1888
        {
1889
          bfd_vma value = symval;
1890
 
1891
          /* Deal with pc-relative gunk.  */
1892
          value -= (sec->output_section->vma + sec->output_offset);
1893
          value -= irel->r_offset;
1894
          value += irel->r_addend;
1895
 
1896
          /* See if the value will fit in 16 bits, note the high value is
1897
             0xfffe + 2 as the target will be two bytes closer if we are
1898
             able to relax.  */
1899
          if ((long) value < 0x10000 && (long) value > -0x10002)
1900
            {
1901
              unsigned int code;
1902
 
1903
              /* Get the opcode.  */
1904
              code = (unsigned int) bfd_get_32 (abfd, contents + irel->r_offset);
1905
 
1906
              /* Verify it's a 'bcond' and fix the opcode.  */
1907
              if ((code  & 0xffff) == 0x0010)
1908
                bfd_put_16 (abfd, 0x1800 | ((0xf & (code >> 20)) << 4), contents + irel->r_offset);
1909
              else
1910
                continue;
1911
 
1912
              /* Note that we've changed the relocs, section contents, etc.  */
1913
              elf_section_data (sec)->relocs = internal_relocs;
1914
              elf_section_data (sec)->this_hdr.contents = contents;
1915
              symtab_hdr->contents = (unsigned char *) isymbuf;
1916
 
1917
              /* Fix the relocation's type.  */
1918
              irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1919
                                           R_CR16_DISP16);
1920
 
1921
              /* Delete two bytes of data.  */
1922
              if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec,
1923
                                                   irel->r_offset + 2, 2))
1924
                goto error_return;
1925
 
1926
              /* That will change things, so, we should relax again.
1927
                 Note that this is not required, and it may be slow.  */
1928
              *again = TRUE;
1929
            }
1930
        }
1931
 
1932
      /* Try to turn a 16bit pc-relative branch into an
1933
         8bit pc-relative branch.  */
1934
      if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_DISP16)
1935
        {
1936
          bfd_vma value = symval;
1937
 
1938
          /* Deal with pc-relative gunk.  */
1939
          value -= (sec->output_section->vma + sec->output_offset);
1940
          value -= irel->r_offset;
1941
          value += irel->r_addend;
1942
 
1943
          /* See if the value will fit in 8 bits, note the high value is
1944
             0xfc + 2 as the target will be two bytes closer if we are
1945
             able to relax.  */
1946
          /*if ((long) value < 0x1fa && (long) value > -0x100) REVISIT:range */
1947
          if ((long) value < 0xfa && (long) value > -0x100)
1948
            {
1949
              unsigned short code;
1950
 
1951
              /* Get the opcode.  */
1952
              code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
1953
 
1954
              /* Verify it's a 'bcond' and fix the opcode.  */
1955
              if ((code & 0xff0f) == 0x1800)
1956
                bfd_put_16 (abfd, (code & 0xf0f0), contents + irel->r_offset);
1957
              else
1958
                continue;
1959
 
1960
              /* Note that we've changed the relocs, section contents, etc.  */
1961
              elf_section_data (sec)->relocs = internal_relocs;
1962
              elf_section_data (sec)->this_hdr.contents = contents;
1963
              symtab_hdr->contents = (unsigned char *) isymbuf;
1964
 
1965
              /* Fix the relocation's type.  */
1966
              irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1967
                                           R_CR16_DISP8);
1968
 
1969
              /* Delete two bytes of data.  */
1970
              if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec,
1971
                                                   irel->r_offset + 2, 2))
1972
                goto error_return;
1973
 
1974
              /* That will change things, so, we should relax again.
1975
                 Note that this is not required, and it may be slow.  */
1976
              *again = TRUE;
1977
            }
1978
        }
1979
 
1980
      /* Try to turn a 32-bit IMM address into a 20/16-bit IMM address */
1981
      if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM32)
1982
        {
1983
          bfd_vma value = symval;
1984
          unsigned short is_add_mov = 0;
1985
          bfd_vma value1 = 0;
1986
 
1987
          /* Get the existing value from the mcode */
1988
          value1 = ((bfd_get_32 (abfd, contents + irel->r_offset + 2) >> 16)
1989
                   |(((bfd_get_32 (abfd, contents + irel->r_offset + 2) & 0xffff) << 16)));
1990
 
1991
          /* See if the value will fit in 20 bits.  */
1992
          if ((long) (value + value1) < 0xfffff && (long) (value + value1) > 0)
1993
            {
1994
              unsigned short code;
1995
 
1996
              /* Get the opcode.  */
1997
              code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
1998
 
1999
              /* Verify it's a 'arithmetic ADDD or MOVD instruction'.
2000
                 For ADDD and MOVD only, convert to IMM32 -> IMM20.  */
2001
 
2002
              if (((code & 0xfff0) == 0x0070) || ((code & 0xfff0) == 0x0020))
2003
                 is_add_mov = 1;
2004
 
2005
              if (is_add_mov)
2006
                {
2007
                  /* Note that we've changed the relocs, section contents,
2008
                     etc.  */
2009
                  elf_section_data (sec)->relocs = internal_relocs;
2010
                  elf_section_data (sec)->this_hdr.contents = contents;
2011
                  symtab_hdr->contents = (unsigned char *) isymbuf;
2012
 
2013
                  /* Fix the opcode.  */
2014
                  if ((code & 0xfff0) == 0x0070) /* For movd.  */
2015
                    bfd_put_8 (abfd, 0x05, contents + irel->r_offset + 1);
2016
                  else                           /* code == 0x0020 for addd.  */
2017
                    bfd_put_8 (abfd, 0x04, contents + irel->r_offset + 1);
2018
 
2019
                  bfd_put_8 (abfd, (code & 0xf) << 4, contents + irel->r_offset);
2020
 
2021
                  /* If existing value is nagavive adjust approriately
2022
                     place the 16-20bits (ie 4 bit) in new opcode,
2023
                     as the 0xffffxxxx, the higher 2 byte values removed. */
2024
                  if (value1 & 0x80000000)
2025
                    bfd_put_8 (abfd, (0x0f | (bfd_get_8(abfd, contents + irel->r_offset))), contents + irel->r_offset);
2026
                  else
2027
                    bfd_put_8 (abfd, (((value1 >> 16)&0xf) | (bfd_get_8(abfd, contents + irel->r_offset))), contents + irel->r_offset);
2028
 
2029
                  /* Fix the relocation's type.  */
2030
                  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2031
                                               R_CR16_IMM20);
2032
 
2033
                  /* Delete two bytes of data.  */
2034
                  if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec,
2035
                                                      irel->r_offset + 2, 2))
2036
                    goto error_return;
2037
 
2038
                  /* That will change things, so, we should relax again.
2039
                     Note that this is not required, and it may be slow.  */
2040
                  *again = TRUE;
2041
                }
2042
            }
2043
 
2044
          /* See if the value will fit in 16 bits.  */
2045
          if ((!is_add_mov)
2046
              && ((long)(value + value1) < 0x7fff && (long)(value + value1) > 0))
2047
            {
2048
              unsigned short code;
2049
 
2050
              /* Get the opcode.  */
2051
              code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
2052
 
2053
              /* Note that we've changed the relocs, section contents, etc.  */
2054
              elf_section_data (sec)->relocs = internal_relocs;
2055
              elf_section_data (sec)->this_hdr.contents = contents;
2056
              symtab_hdr->contents = (unsigned char *) isymbuf;
2057
 
2058
              /* Fix the opcode.  */
2059
              if ((code & 0xf0) == 0x70)          /* For movd.  */
2060
                bfd_put_8 (abfd, 0x54, contents + irel->r_offset + 1);
2061
              else if ((code & 0xf0) == 0x20)     /* For addd.  */
2062
                bfd_put_8 (abfd, 0x60, contents + irel->r_offset + 1);
2063
              else if ((code & 0xf0) == 0x90)     /* For cmpd.  */
2064
                bfd_put_8 (abfd, 0x56, contents + irel->r_offset + 1);
2065
              else
2066
                continue;
2067
 
2068
              bfd_put_8 (abfd, 0xb0 | (code & 0xf), contents + irel->r_offset);
2069
 
2070
              /* If existing value is nagavive adjust approriately
2071
                 place the 12-16bits (ie 4 bit) in new opcode,
2072
                 as the 0xfffffxxx, the higher 2 byte values removed. */
2073
              if (value1 & 0x80000000)
2074
                bfd_put_8 (abfd, (0x0f | (bfd_get_8(abfd, contents + irel->r_offset))), contents + irel->r_offset);
2075
              else
2076
                bfd_put_16 (abfd, value1, contents + irel->r_offset + 2);
2077
 
2078
 
2079
              /* Fix the relocation's type.  */
2080
              irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2081
                                           R_CR16_IMM16);
2082
 
2083
              /* Delete two bytes of data.  */
2084
              if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec,
2085
                                                  irel->r_offset + 2, 2))
2086
                goto error_return;
2087
 
2088
              /* That will change things, so, we should relax again.
2089
                 Note that this is not required, and it may be slow.  */
2090
              *again = TRUE;
2091
            }
2092
        }
2093
 
2094
#if 0
2095
      /* Try to turn a 16bit immediate address into a 4bit
2096
         immediate address.  */
2097
      if ((ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM20)
2098
          || (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM16))
2099
        {
2100
          bfd_vma value = symval;
2101
          bfd_vma value1 = 0;
2102
 
2103
          /* Get the existing value from the mcode */
2104
          value1 = ((bfd_get_16 (abfd, contents + irel->r_offset + 2) & 0xffff));
2105
 
2106
          if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM20)
2107
            {
2108
              value1 |= ((bfd_get_16 (abfd, contents + irel->r_offset + 1) & 0xf000) << 0x4);
2109
            }
2110
 
2111
          /* See if the value will fit in 4 bits.  */
2112
          if ((((long) (value + value1)) < 0xf)
2113
              && (((long) (value + value1)) > 0))
2114
            {
2115
              unsigned short code;
2116
 
2117
              /* Get the opcode.  */
2118
              code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
2119
 
2120
              /* Note that we've changed the relocs, section contents, etc.  */
2121
              elf_section_data (sec)->relocs = internal_relocs;
2122
              elf_section_data (sec)->this_hdr.contents = contents;
2123
              symtab_hdr->contents = (unsigned char *) isymbuf;
2124
 
2125
              /* Fix the opcode.  */
2126
              if (((code & 0x0f00) == 0x0400) || ((code & 0x0f00) == 0x0500))
2127
                {
2128
                  if ((code & 0x0f00) == 0x0400)      /* For movd imm20.  */
2129
                    bfd_put_8 (abfd, 0x60, contents + irel->r_offset);
2130
                  else                                /* For addd imm20.  */
2131
                    bfd_put_8 (abfd, 0x54, contents + irel->r_offset);
2132
                  bfd_put_8 (abfd, (code & 0xf0) >> 4, contents + irel->r_offset + 1);
2133
                }
2134
              else
2135
                {
2136
                  if ((code & 0xfff0) == 0x56b0)       /*  For cmpd imm16.  */
2137
                    bfd_put_8 (abfd, 0x56, contents + irel->r_offset);
2138
                  else if ((code & 0xfff0) == 0x54b0)  /*  For movd imm16.  */
2139
                    bfd_put_8 (abfd, 0x54, contents + irel->r_offset);
2140
                  else if ((code & 0xfff0) == 0x58b0)  /*  For movb imm16.  */
2141
                    bfd_put_8 (abfd, 0x58, contents + irel->r_offset);
2142
                  else if ((code & 0xfff0) == 0x5Ab0)  /*  For movw imm16.  */
2143
                    bfd_put_8 (abfd, 0x5A, contents + irel->r_offset);
2144
                  else if ((code & 0xfff0) == 0x60b0)  /*  For addd imm16.  */
2145
                    bfd_put_8 (abfd, 0x60, contents + irel->r_offset);
2146
                  else if ((code & 0xfff0) == 0x30b0)  /*  For addb imm16.  */
2147
                    bfd_put_8 (abfd, 0x30, contents + irel->r_offset);
2148
                  else if ((code & 0xfff0) == 0x2Cb0)  /*  For addub imm16.  */
2149
                    bfd_put_8 (abfd, 0x2C, contents + irel->r_offset);
2150
                  else if ((code & 0xfff0) == 0x32b0)  /*  For adduw imm16.  */
2151
                    bfd_put_8 (abfd, 0x32, contents + irel->r_offset);
2152
                  else if ((code & 0xfff0) == 0x38b0)  /*  For subb imm16.  */
2153
                    bfd_put_8 (abfd, 0x38, contents + irel->r_offset);
2154
                  else if ((code & 0xfff0) == 0x3Cb0)  /*  For subcb imm16.  */
2155
                    bfd_put_8 (abfd, 0x3C, contents + irel->r_offset);
2156
                  else if ((code & 0xfff0) == 0x3Fb0)  /*  For subcw imm16.  */
2157
                    bfd_put_8 (abfd, 0x3F, contents + irel->r_offset);
2158
                  else if ((code & 0xfff0) == 0x3Ab0)  /*  For subw imm16.  */
2159
                    bfd_put_8 (abfd, 0x3A, contents + irel->r_offset);
2160
                  else if ((code & 0xfff0) == 0x50b0)  /*  For cmpb imm16.  */
2161
                    bfd_put_8 (abfd, 0x50, contents + irel->r_offset);
2162
                  else if ((code & 0xfff0) == 0x52b0)  /*  For cmpw imm16.  */
2163
                    bfd_put_8 (abfd, 0x52, contents + irel->r_offset);
2164
                  else
2165
                    continue;
2166
 
2167
                  bfd_put_8 (abfd, (code & 0xf), contents + irel->r_offset + 1);
2168
                }
2169
 
2170
              /* Fix the relocation's type.  */
2171
              irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2172
                                           R_CR16_IMM4);
2173
 
2174
              /* Delete two bytes of data.  */
2175
              if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec,
2176
                                                  irel->r_offset + 2, 2))
2177
                goto error_return;
2178
 
2179
              /* That will change things, so, we should relax again.
2180
                 Note that this is not required, and it may be slow.  */
2181
              *again = TRUE;
2182
            }
2183
        }
2184
#endif
2185
    }
2186
 
2187
  if (isymbuf != NULL
2188
      && symtab_hdr->contents != (unsigned char *) isymbuf)
2189
    {
2190
      if (! link_info->keep_memory)
2191
        free (isymbuf);
2192
      else
2193
       /* Cache the symbols for elf_link_input_bfd.  */
2194
       symtab_hdr->contents = (unsigned char *) isymbuf;
2195
    }
2196
 
2197
  if (contents != NULL
2198
      && elf_section_data (sec)->this_hdr.contents != contents)
2199
    {
2200
      if (! link_info->keep_memory)
2201
        free (contents);
2202
      else
2203
       /* Cache the section contents for elf_link_input_bfd.  */
2204
       elf_section_data (sec)->this_hdr.contents = contents;
2205
 
2206
    }
2207
 
2208
  if (internal_relocs != NULL
2209
      && elf_section_data (sec)->relocs != internal_relocs)
2210
    free (internal_relocs);
2211
 
2212
  return TRUE;
2213
 
2214
 error_return:
2215
  if (isymbuf != NULL
2216
      && symtab_hdr->contents != (unsigned char *) isymbuf)
2217
    free (isymbuf);
2218
  if (contents != NULL
2219
      && elf_section_data (sec)->this_hdr.contents != contents)
2220
    free (contents);
2221
  if (internal_relocs != NULL
2222
      && elf_section_data (sec)->relocs != internal_relocs)
2223
    free (internal_relocs);
2224
 
2225
  return FALSE;
2226
}
2227
 
2228
static asection *
2229
elf32_cr16_gc_mark_hook (asection *sec,
2230
                         struct bfd_link_info *info,
2231
                         Elf_Internal_Rela *rel,
2232
                         struct elf_link_hash_entry *h,
2233
                         Elf_Internal_Sym *sym)
2234
{
2235
  return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
2236
}
2237
 
2238
/* Update the got entry reference counts for the section being removed.  */
2239
 
2240
static bfd_boolean
2241
elf32_cr16_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED,
2242
                          struct bfd_link_info *info ATTRIBUTE_UNUSED,
2243
                          asection *sec ATTRIBUTE_UNUSED,
2244
                          const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED)
2245
{
2246
  /* We don't support garbage collection of GOT and PLT relocs yet.  */
2247
  return TRUE;
2248
}
2249
 
2250
/* Create dynamic sections when linking against a dynamic object.  */
2251
 
2252
static bfd_boolean
2253
_bfd_cr16_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
2254
{
2255
  flagword   flags;
2256
  asection * s;
2257
  const struct elf_backend_data * bed = get_elf_backend_data (abfd);
2258
  int ptralign = 0;
2259
 
2260
  switch (bed->s->arch_size)
2261
    {
2262
    case 16:
2263
      ptralign = 1;
2264
      break;
2265
 
2266
    case 32:
2267
      ptralign = 2;
2268
      break;
2269
 
2270
    default:
2271
      bfd_set_error (bfd_error_bad_value);
2272
      return FALSE;
2273
    }
2274
 
2275
  /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and
2276
     .rel[a].bss sections.  */
2277
 
2278
  flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
2279
           | SEC_LINKER_CREATED);
2280
 
2281
  s = bfd_make_section_with_flags (abfd,
2282
                                   (bed->default_use_rela_p
2283
                                    ? ".rela.plt" : ".rel.plt"),
2284
                                   flags | SEC_READONLY);
2285
  if (s == NULL
2286
      || ! bfd_set_section_alignment (abfd, s, ptralign))
2287
    return FALSE;
2288
 
2289
  if (! _bfd_cr16_elf_create_got_section (abfd, info))
2290
    return FALSE;
2291
 
2292
  {
2293
    const char * secname;
2294
    char *       relname;
2295
    flagword     secflags;
2296
    asection *   sec;
2297
 
2298
    for (sec = abfd->sections; sec; sec = sec->next)
2299
      {
2300
        secflags = bfd_get_section_flags (abfd, sec);
2301
        if ((secflags & (SEC_DATA | SEC_LINKER_CREATED))
2302
            || ((secflags & SEC_HAS_CONTENTS) != SEC_HAS_CONTENTS))
2303
          continue;
2304
 
2305
        secname = bfd_get_section_name (abfd, sec);
2306
        relname = (char *) bfd_malloc (strlen (secname) + 6);
2307
        strcpy (relname, ".rela");
2308
        strcat (relname, secname);
2309
 
2310
        s = bfd_make_section_with_flags (abfd, relname,
2311
                                         flags | SEC_READONLY);
2312
        if (s == NULL
2313
            || ! bfd_set_section_alignment (abfd, s, ptralign))
2314
          return FALSE;
2315
      }
2316
  }
2317
 
2318
  if (bed->want_dynbss)
2319
    {
2320
      /* The .dynbss section is a place to put symbols which are defined
2321
         by dynamic objects, are referenced by regular objects, and are
2322
         not functions.  We must allocate space for them in the process
2323
         image and use a R_*_COPY reloc to tell the dynamic linker to
2324
         initialize them at run time.  The linker script puts the .dynbss
2325
         section into the .bss section of the final image.  */
2326
      s = bfd_make_section_with_flags (abfd, ".dynbss",
2327
                                       SEC_ALLOC | SEC_LINKER_CREATED);
2328
      if (s == NULL)
2329
        return FALSE;
2330
 
2331
      /* The .rel[a].bss section holds copy relocs.  This section is not
2332
         normally needed.  We need to create it here, though, so that the
2333
         linker will map it to an output section.  We can't just create it
2334
         only if we need it, because we will not know whether we need it
2335
         until we have seen all the input files, and the first time the
2336
         main linker code calls BFD after examining all the input files
2337
         (size_dynamic_sections) the input sections have already been
2338
         mapped to the output sections.  If the section turns out not to
2339
         be needed, we can discard it later.  We will never need this
2340
         section when generating a shared object, since they do not use
2341
         copy relocs.  */
2342
      if (! info->executable)
2343
        {
2344
          s = bfd_make_section_with_flags (abfd,
2345
                                           (bed->default_use_rela_p
2346
                                            ? ".rela.bss" : ".rel.bss"),
2347
                                           flags | SEC_READONLY);
2348
          if (s == NULL
2349
              || ! bfd_set_section_alignment (abfd, s, ptralign))
2350
            return FALSE;
2351
        }
2352
    }
2353
 
2354
  return TRUE;
2355
}
2356
 
2357
/* Adjust a symbol defined by a dynamic object and referenced by a
2358
   regular object.  The current definition is in some section of the
2359
   dynamic object, but we're not including those sections.  We have to
2360
   change the definition to something the rest of the link can
2361
   understand.  */
2362
 
2363
static bfd_boolean
2364
_bfd_cr16_elf_adjust_dynamic_symbol (struct bfd_link_info * info,
2365
                                     struct elf_link_hash_entry * h)
2366
{
2367
  bfd * dynobj;
2368
  asection * s;
2369
 
2370
  dynobj = elf_hash_table (info)->dynobj;
2371
 
2372
  /* Make sure we know what is going on here.  */
2373
  BFD_ASSERT (dynobj != NULL
2374
              && (h->needs_plt
2375
                  || h->u.weakdef != NULL
2376
                  || (h->def_dynamic
2377
                      && h->ref_regular
2378
                      && !h->def_regular)));
2379
 
2380
  /* If this is a function, put it in the procedure linkage table.  We
2381
     will fill in the contents of the procedure linkage table later,
2382
     when we know the address of the .got section.  */
2383
  if (h->type == STT_FUNC
2384
      || h->needs_plt)
2385
    {
2386
      if (! info->executable
2387
          && !h->def_dynamic
2388
          && !h->ref_dynamic)
2389
        {
2390
          /* This case can occur if we saw a PLT reloc in an input
2391
             file, but the symbol was never referred to by a dynamic
2392
             object.  In such a case, we don't actually need to build
2393
             a procedure linkage table, and we can just do a REL32
2394
             reloc instead.  */
2395
          BFD_ASSERT (h->needs_plt);
2396
          return TRUE;
2397
        }
2398
 
2399
      /* Make sure this symbol is output as a dynamic symbol.  */
2400
      if (h->dynindx == -1)
2401
        {
2402
          if (! bfd_elf_link_record_dynamic_symbol (info, h))
2403
            return FALSE;
2404
        }
2405
 
2406
      /* We also need to make an entry in the .got.plt section, which
2407
         will be placed in the .got section by the linker script.  */
2408
 
2409
      s = bfd_get_section_by_name (dynobj, ".got.plt");
2410
      BFD_ASSERT (s != NULL);
2411
      s->size += 4;
2412
 
2413
      /* We also need to make an entry in the .rela.plt section.  */
2414
 
2415
      s = bfd_get_section_by_name (dynobj, ".rela.plt");
2416
      BFD_ASSERT (s != NULL);
2417
      s->size += sizeof (Elf32_External_Rela);
2418
 
2419
      return TRUE;
2420
    }
2421
 
2422
  /* If this is a weak symbol, and there is a real definition, the
2423
     processor independent code will have arranged for us to see the
2424
     real definition first, and we can just use the same value.  */
2425
  if (h->u.weakdef != NULL)
2426
    {
2427
      BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2428
                  || h->u.weakdef->root.type == bfd_link_hash_defweak);
2429
      h->root.u.def.section = h->u.weakdef->root.u.def.section;
2430
      h->root.u.def.value = h->u.weakdef->root.u.def.value;
2431
      return TRUE;
2432
    }
2433
 
2434
  /* This is a reference to a symbol defined by a dynamic object which
2435
     is not a function.  */
2436
 
2437
  /* If we are creating a shared library, we must presume that the
2438
     only references to the symbol are via the global offset table.
2439
     For such cases we need not do anything here; the relocations will
2440
     be handled correctly by relocate_section.  */
2441
  if (info->executable)
2442
    return TRUE;
2443
 
2444
  /* If there are no references to this symbol that do not use the
2445
     GOT, we don't need to generate a copy reloc.  */
2446
  if (!h->non_got_ref)
2447
    return TRUE;
2448
 
2449
  if (h->size == 0)
2450
    {
2451
      (*_bfd_error_handler) (_("dynamic variable `%s' is zero size"),
2452
                             h->root.root.string);
2453
      return TRUE;
2454
    }
2455
 
2456
  /* We must allocate the symbol in our .dynbss section, which will
2457
     become part of the .bss section of the executable.  There will be
2458
     an entry for this symbol in the .dynsym section.  The dynamic
2459
     object will contain position independent code, so all references
2460
     from the dynamic object to this symbol will go through the global
2461
     offset table.  The dynamic linker will use the .dynsym entry to
2462
     determine the address it must put in the global offset table, so
2463
     both the dynamic object and the regular object will refer to the
2464
     same memory location for the variable.  */
2465
 
2466
  s = bfd_get_section_by_name (dynobj, ".dynbss");
2467
  BFD_ASSERT (s != NULL);
2468
 
2469
  /* We must generate a R_CR16_COPY reloc to tell the dynamic linker to
2470
     copy the initial value out of the dynamic object and into the
2471
     runtime process image.  We need to remember the offset into the
2472
     .rela.bss section we are going to use.  */
2473
  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
2474
    {
2475
      asection * srel;
2476
 
2477
      srel = bfd_get_section_by_name (dynobj, ".rela.bss");
2478
      BFD_ASSERT (srel != NULL);
2479
      srel->size += sizeof (Elf32_External_Rela);
2480
      h->needs_copy = 1;
2481
    }
2482
 
2483
  return _bfd_elf_adjust_dynamic_copy (h, s);
2484
}
2485
 
2486
/* Set the sizes of the dynamic sections.  */
2487
 
2488
static bfd_boolean
2489
_bfd_cr16_elf_size_dynamic_sections (bfd * output_bfd,
2490
                                     struct bfd_link_info * info)
2491
{
2492
  bfd * dynobj;
2493
  asection * s;
2494
  bfd_boolean plt;
2495
  bfd_boolean relocs;
2496
  bfd_boolean reltext;
2497
 
2498
  dynobj = elf_hash_table (info)->dynobj;
2499
  BFD_ASSERT (dynobj != NULL);
2500
 
2501
  if (elf_hash_table (info)->dynamic_sections_created)
2502
    {
2503
      /* Set the contents of the .interp section to the interpreter.  */
2504
      if (info->executable)
2505
        {
2506
#if 0
2507
          s = bfd_get_section_by_name (dynobj, ".interp");
2508
          BFD_ASSERT (s != NULL);
2509
          s->size = sizeof ELF_DYNAMIC_INTERPRETER;
2510
          s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
2511
#endif
2512
        }
2513
    }
2514
  else
2515
    {
2516
      /* We may have created entries in the .rela.got section.
2517
         However, if we are not creating the dynamic sections, we will
2518
         not actually use these entries.  Reset the size of .rela.got,
2519
         which will cause it to get stripped from the output file
2520
         below.  */
2521
      s = bfd_get_section_by_name (dynobj, ".rela.got");
2522
      if (s != NULL)
2523
        s->size = 0;
2524
    }
2525
 
2526
  /* The check_relocs and adjust_dynamic_symbol entry points have
2527
     determined the sizes of the various dynamic sections.  Allocate
2528
     memory for them.  */
2529
  plt = FALSE;
2530
  relocs = FALSE;
2531
  reltext = FALSE;
2532
  for (s = dynobj->sections; s != NULL; s = s->next)
2533
    {
2534
      const char * name;
2535
 
2536
      if ((s->flags & SEC_LINKER_CREATED) == 0)
2537
        continue;
2538
 
2539
      /* It's OK to base decisions on the section name, because none
2540
         of the dynobj section names depend upon the input files.  */
2541
      name = bfd_get_section_name (dynobj, s);
2542
 
2543
      if (strcmp (name, ".plt") == 0)
2544
        {
2545
          /* Remember whether there is a PLT.  */
2546
          plt = s->size != 0;
2547
        }
2548
      else if (CONST_STRNEQ (name, ".rela"))
2549
        {
2550
          if (s->size != 0)
2551
            {
2552
              asection * target;
2553
 
2554
              /* Remember whether there are any reloc sections other
2555
                 than .rela.plt.  */
2556
              if (strcmp (name, ".rela.plt") != 0)
2557
                {
2558
                  const char * outname;
2559
 
2560
                  relocs = TRUE;
2561
 
2562
                  /* If this relocation section applies to a read only
2563
                     section, then we probably need a DT_TEXTREL
2564
                     entry.  The entries in the .rela.plt section
2565
                     really apply to the .got section, which we
2566
                     created ourselves and so know is not readonly.  */
2567
                  outname = bfd_get_section_name (output_bfd,
2568
                                                  s->output_section);
2569
                  target = bfd_get_section_by_name (output_bfd, outname + 5);
2570
                  if (target != NULL
2571
                      && (target->flags & SEC_READONLY) != 0
2572
                      && (target->flags & SEC_ALLOC) != 0)
2573
                    reltext = TRUE;
2574
                }
2575
 
2576
              /* We use the reloc_count field as a counter if we need
2577
                 to copy relocs into the output file.  */
2578
              s->reloc_count = 0;
2579
            }
2580
        }
2581
      else if (! CONST_STRNEQ (name, ".got")
2582
               && strcmp (name, ".dynbss") != 0)
2583
        /* It's not one of our sections, so don't allocate space.  */
2584
        continue;
2585
 
2586
      if (s->size == 0)
2587
        {
2588
          /* If we don't need this section, strip it from the
2589
             output file.  This is mostly to handle .rela.bss and
2590
             .rela.plt.  We must create both sections in
2591
             create_dynamic_sections, because they must be created
2592
             before the linker maps input sections to output
2593
             sections.  The linker does that before
2594
             adjust_dynamic_symbol is called, and it is that
2595
             function which decides whether anything needs to go
2596
             into these sections.  */
2597
          s->flags |= SEC_EXCLUDE;
2598
          continue;
2599
        }
2600
 
2601
        if ((s->flags & SEC_HAS_CONTENTS) == 0)
2602
          continue;
2603
 
2604
      /* Allocate memory for the section contents.  We use bfd_zalloc
2605
         here in case unused entries are not reclaimed before the
2606
         section's contents are written out.  This should not happen,
2607
         but this way if it does, we get a R_CR16_NONE reloc
2608
         instead of garbage.  */
2609
      s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
2610
      if (s->contents == NULL)
2611
        return FALSE;
2612
    }
2613
 
2614
  if (elf_hash_table (info)->dynamic_sections_created)
2615
    {
2616
      /* Add some entries to the .dynamic section.  We fill in the
2617
         values later, in _bfd_cr16_elf_finish_dynamic_sections,
2618
         but we must add the entries now so that we get the correct
2619
         size for the .dynamic section.  The DT_DEBUG entry is filled
2620
         in by the dynamic linker and used by the debugger.  */
2621
      if (! info->executable)
2622
        {
2623
          if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
2624
            return FALSE;
2625
        }
2626
 
2627
      if (plt)
2628
        {
2629
          if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)
2630
              || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
2631
              || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
2632
              || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0))
2633
            return FALSE;
2634
        }
2635
 
2636
      if (relocs)
2637
        {
2638
          if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0)
2639
              || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0)
2640
              || !_bfd_elf_add_dynamic_entry (info, DT_RELAENT,
2641
                                              sizeof (Elf32_External_Rela)))
2642
            return FALSE;
2643
        }
2644
 
2645
      if (reltext)
2646
        {
2647
          if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
2648
            return FALSE;
2649
        }
2650
    }
2651
 
2652
  return TRUE;
2653
}
2654
 
2655
/* Finish up dynamic symbol handling.  We set the contents of various
2656
   dynamic sections here.  */
2657
 
2658
static bfd_boolean
2659
_bfd_cr16_elf_finish_dynamic_symbol (bfd * output_bfd,
2660
                                     struct bfd_link_info * info,
2661
                                     struct elf_link_hash_entry * h,
2662
                                     Elf_Internal_Sym * sym)
2663
{
2664
  bfd * dynobj;
2665
 
2666
  dynobj = elf_hash_table (info)->dynobj;
2667
 
2668
  if (h->got.offset != (bfd_vma) -1)
2669
    {
2670
      asection *        sgot;
2671
      asection *        srel;
2672
      Elf_Internal_Rela rel;
2673
 
2674
      /* This symbol has an entry in the global offset table.  Set it up.  */
2675
 
2676
      sgot = bfd_get_section_by_name (dynobj, ".got");
2677
      srel = bfd_get_section_by_name (dynobj, ".rela.got");
2678
      BFD_ASSERT (sgot != NULL && srel != NULL);
2679
 
2680
      rel.r_offset = (sgot->output_section->vma
2681
                      + sgot->output_offset
2682
                      + (h->got.offset & ~1));
2683
 
2684
      /* If this is a -Bsymbolic link, and the symbol is defined
2685
         locally, we just want to emit a RELATIVE reloc.  Likewise if
2686
         the symbol was forced to be local because of a version file.
2687
         The entry in the global offset table will already have been
2688
         initialized in the relocate_section function.  */
2689
      if (info->executable
2690
          && (info->symbolic || h->dynindx == -1)
2691
          && h->def_regular)
2692
        {
2693
          rel.r_info = ELF32_R_INFO (0, R_CR16_GOT_REGREL20);
2694
          rel.r_addend = (h->root.u.def.value
2695
                          + h->root.u.def.section->output_section->vma
2696
                          + h->root.u.def.section->output_offset);
2697
        }
2698
      else
2699
        {
2700
          bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
2701
          rel.r_info = ELF32_R_INFO (h->dynindx, R_CR16_GOT_REGREL20);
2702
          rel.r_addend = 0;
2703
        }
2704
 
2705
      bfd_elf32_swap_reloca_out (output_bfd, &rel,
2706
                                 (bfd_byte *) ((Elf32_External_Rela *) srel->contents
2707
                                               + srel->reloc_count));
2708
      ++ srel->reloc_count;
2709
    }
2710
 
2711
  if (h->needs_copy)
2712
    {
2713
      asection *        s;
2714
      Elf_Internal_Rela rel;
2715
 
2716
      /* This symbol needs a copy reloc.  Set it up.  */
2717
      BFD_ASSERT (h->dynindx != -1
2718
                  && (h->root.type == bfd_link_hash_defined
2719
                      || h->root.type == bfd_link_hash_defweak));
2720
 
2721
      s = bfd_get_section_by_name (h->root.u.def.section->owner,
2722
                                   ".rela.bss");
2723
      BFD_ASSERT (s != NULL);
2724
 
2725
      rel.r_offset = (h->root.u.def.value
2726
                      + h->root.u.def.section->output_section->vma
2727
                      + h->root.u.def.section->output_offset);
2728
      rel.r_info = ELF32_R_INFO (h->dynindx, R_CR16_GOT_REGREL20);
2729
      rel.r_addend = 0;
2730
      bfd_elf32_swap_reloca_out (output_bfd, &rel,
2731
                                 (bfd_byte *) ((Elf32_External_Rela *) s->contents
2732
                                               + s->reloc_count));
2733
     ++ s->reloc_count;
2734
    }
2735
 
2736
  /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
2737
  if (strcmp (h->root.root.string, "_DYNAMIC") == 0
2738
      || h == elf_hash_table (info)->hgot)
2739
    sym->st_shndx = SHN_ABS;
2740
 
2741
  return TRUE;
2742
}
2743
 
2744
/* Finish up the dynamic sections.  */
2745
 
2746
static bfd_boolean
2747
_bfd_cr16_elf_finish_dynamic_sections (bfd * output_bfd,
2748
                                       struct bfd_link_info * info)
2749
{
2750
  bfd *      dynobj;
2751
  asection * sgot;
2752
  asection * sdyn;
2753
 
2754
  dynobj = elf_hash_table (info)->dynobj;
2755
 
2756
  sgot = bfd_get_section_by_name (dynobj, ".got.plt");
2757
  BFD_ASSERT (sgot != NULL);
2758
  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
2759
 
2760
  if (elf_hash_table (info)->dynamic_sections_created)
2761
    {
2762
      Elf32_External_Dyn * dyncon;
2763
      Elf32_External_Dyn * dynconend;
2764
 
2765
      BFD_ASSERT (sdyn != NULL);
2766
 
2767
      dyncon = (Elf32_External_Dyn *) sdyn->contents;
2768
      dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
2769
 
2770
      for (; dyncon < dynconend; dyncon++)
2771
        {
2772
          Elf_Internal_Dyn dyn;
2773
          const char * name;
2774
          asection * s;
2775
 
2776
          bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
2777
 
2778
          switch (dyn.d_tag)
2779
            {
2780
            default:
2781
              break;
2782
 
2783
            case DT_PLTGOT:
2784
              name = ".got";
2785
              goto get_vma;
2786
 
2787
            case DT_JMPREL:
2788
              name = ".rela.plt";
2789
            get_vma:
2790
              s = bfd_get_section_by_name (output_bfd, name);
2791
              BFD_ASSERT (s != NULL);
2792
              dyn.d_un.d_ptr = s->vma;
2793
              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
2794
              break;
2795
 
2796
            case DT_PLTRELSZ:
2797
              s = bfd_get_section_by_name (output_bfd, ".rela.plt");
2798
              BFD_ASSERT (s != NULL);
2799
              dyn.d_un.d_val = s->size;
2800
              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
2801
              break;
2802
 
2803
            case DT_RELASZ:
2804
              /* My reading of the SVR4 ABI indicates that the
2805
                 procedure linkage table relocs (DT_JMPREL) should be
2806
                 included in the overall relocs (DT_RELA).  This is
2807
                 what Solaris does.  However, UnixWare can not handle
2808
                 that case.  Therefore, we override the DT_RELASZ entry
2809
                 here to make it not include the JMPREL relocs.  Since
2810
                 the linker script arranges for .rela.plt to follow all
2811
                 other relocation sections, we don't have to worry
2812
                 about changing the DT_RELA entry.  */
2813
              s = bfd_get_section_by_name (output_bfd, ".rela.plt");
2814
              if (s != NULL)
2815
                dyn.d_un.d_val -= s->size;
2816
              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
2817
              break;
2818
            }
2819
        }
2820
 
2821
    }
2822
 
2823
  /* Fill in the first three entries in the global offset table.  */
2824
  if (sgot->size > 0)
2825
    {
2826
      if (sdyn == NULL)
2827
        bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
2828
      else
2829
        bfd_put_32 (output_bfd,
2830
                    sdyn->output_section->vma + sdyn->output_offset,
2831
                    sgot->contents);
2832
    }
2833
 
2834
  elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
2835
 
2836
  return TRUE;
2837
}
2838
 
2839
/* Given a .data.rel section and a .emreloc in-memory section, store
2840
   relocation information into the .emreloc section which can be
2841
   used at runtime to relocate the section.  This is called by the
2842
   linker when the --embedded-relocs switch is used.  This is called
2843
   after the add_symbols entry point has been called for all the
2844
   objects, and before the final_link entry point is called.  */
2845
 
2846
bfd_boolean
2847
bfd_cr16_elf32_create_embedded_relocs (bfd *abfd,
2848
                                       struct bfd_link_info *info,
2849
                                       asection *datasec,
2850
                                       asection *relsec,
2851
                                       char **errmsg)
2852
{
2853
  Elf_Internal_Shdr *symtab_hdr;
2854
  Elf_Internal_Sym *isymbuf = NULL;
2855
  Elf_Internal_Rela *internal_relocs = NULL;
2856
  Elf_Internal_Rela *irel, *irelend;
2857
  bfd_byte *p;
2858
  bfd_size_type amt;
2859
 
2860
  BFD_ASSERT (! info->relocatable);
2861
 
2862
  *errmsg = NULL;
2863
 
2864
  if (datasec->reloc_count == 0)
2865
    return TRUE;
2866
 
2867
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2868
 
2869
  /* Get a copy of the native relocations.  */
2870
  internal_relocs = (_bfd_elf_link_read_relocs
2871
                     (abfd, datasec, NULL, NULL, info->keep_memory));
2872
  if (internal_relocs == NULL)
2873
    goto error_return;
2874
 
2875
  amt = (bfd_size_type) datasec->reloc_count * 8;
2876
  relsec->contents = (bfd_byte *) bfd_alloc (abfd, amt);
2877
  if (relsec->contents == NULL)
2878
    goto error_return;
2879
 
2880
  p = relsec->contents;
2881
 
2882
  irelend = internal_relocs + datasec->reloc_count;
2883
  for (irel = internal_relocs; irel < irelend; irel++, p += 8)
2884
    {
2885
      asection *targetsec;
2886
 
2887
      /* We are going to write a four byte longword into the runtime
2888
       reloc section.  The longword will be the address in the data
2889
       section which must be relocated.  It is followed by the name
2890
       of the target section NUL-padded or truncated to 8
2891
       characters.  */
2892
 
2893
      /* We can only relocate absolute longword relocs at run time.  */
2894
      if (!((ELF32_R_TYPE (irel->r_info) == (int) R_CR16_NUM32a)
2895
          || (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_NUM32)))
2896
        {
2897
          *errmsg = _("unsupported reloc type");
2898
          bfd_set_error (bfd_error_bad_value);
2899
          goto error_return;
2900
        }
2901
 
2902
      /* Get the target section referred to by the reloc.  */
2903
      if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
2904
        {
2905
          /* A local symbol.  */
2906
          Elf_Internal_Sym *isym;
2907
 
2908
          /* Read this BFD's local symbols if we haven't done so already.  */
2909
          if (isymbuf == NULL)
2910
            {
2911
              isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
2912
              if (isymbuf == NULL)
2913
                isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
2914
                                                symtab_hdr->sh_info, 0,
2915
                                                NULL, NULL, NULL);
2916
              if (isymbuf == NULL)
2917
                goto error_return;
2918
            }
2919
 
2920
          isym = isymbuf + ELF32_R_SYM (irel->r_info);
2921
          targetsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
2922
        }
2923
      else
2924
        {
2925
          unsigned long indx;
2926
          struct elf_link_hash_entry *h;
2927
 
2928
          /* An external symbol.  */
2929
          indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
2930
          h = elf_sym_hashes (abfd)[indx];
2931
          BFD_ASSERT (h != NULL);
2932
          if (h->root.type == bfd_link_hash_defined
2933
              || h->root.type == bfd_link_hash_defweak)
2934
            targetsec = h->root.u.def.section;
2935
          else
2936
            targetsec = NULL;
2937
        }
2938
 
2939
      bfd_put_32 (abfd, irel->r_offset + datasec->output_offset, p);
2940
      memset (p + 4, 0, 4);
2941
      if ((ELF32_R_TYPE (irel->r_info) == (int) R_CR16_NUM32a)
2942
          && (targetsec != NULL) )
2943
         strncpy ((char *) p + 4, targetsec->output_section->name, 4);
2944
    }
2945
 
2946
  if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
2947
    free (isymbuf);
2948
  if (internal_relocs != NULL
2949
      && elf_section_data (datasec)->relocs != internal_relocs)
2950
    free (internal_relocs);
2951
  return TRUE;
2952
 
2953
error_return:
2954
  if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
2955
    free (isymbuf);
2956
  if (internal_relocs != NULL
2957
      && elf_section_data (datasec)->relocs != internal_relocs)
2958
    free (internal_relocs);
2959
  return FALSE;
2960
}
2961
 
2962
 
2963
/* Classify relocation types, such that combreloc can sort them
2964
   properly.  */
2965
 
2966
static enum elf_reloc_type_class
2967
_bfd_cr16_elf_reloc_type_class (const Elf_Internal_Rela *rela)
2968
{
2969
  switch ((int) ELF32_R_TYPE (rela->r_info))
2970
    {
2971
    case R_CR16_GOT_REGREL20:
2972
    case R_CR16_GOTC_REGREL20:
2973
      return reloc_class_relative;
2974
    default:
2975
      return reloc_class_normal;
2976
    }
2977
}
2978
 
2979
/* Definitions for setting CR16 target vector.  */
2980
#define TARGET_LITTLE_SYM                 bfd_elf32_cr16_vec
2981
#define TARGET_LITTLE_NAME                "elf32-cr16"
2982
#define ELF_ARCH                          bfd_arch_cr16
2983
#define ELF_MACHINE_CODE                  EM_CR16
2984
#define ELF_MACHINE_ALT1                  EM_CR16_OLD
2985
#define ELF_MAXPAGESIZE                   0x1
2986
#define elf_symbol_leading_char           '_'
2987
 
2988
#define bfd_elf32_bfd_reloc_type_lookup   elf_cr16_reloc_type_lookup
2989
#define bfd_elf32_bfd_reloc_name_lookup   elf_cr16_reloc_name_lookup
2990
#define elf_info_to_howto                 elf_cr16_info_to_howto
2991
#define elf_info_to_howto_rel             0
2992
#define elf_backend_relocate_section      elf32_cr16_relocate_section
2993
#define bfd_elf32_bfd_relax_section       elf32_cr16_relax_section
2994
#define bfd_elf32_bfd_get_relocated_section_contents \
2995
                                elf32_cr16_get_relocated_section_contents
2996
#define elf_backend_gc_mark_hook          elf32_cr16_gc_mark_hook
2997
#define elf_backend_gc_sweep_hook         elf32_cr16_gc_sweep_hook
2998
#define elf_backend_can_gc_sections       1
2999
#define elf_backend_rela_normal           1
3000
#define elf_backend_check_relocs          cr16_elf_check_relocs
3001
/* So we can set bits in e_flags.  */
3002
#define elf_backend_final_write_processing \
3003
                                 _bfd_cr16_elf_final_write_processing
3004
#define elf_backend_object_p     _bfd_cr16_elf_object_p
3005
 
3006
#define bfd_elf32_bfd_merge_private_bfd_data \
3007
                                 _bfd_cr16_elf_merge_private_bfd_data
3008
 
3009
 
3010
#define bfd_elf32_bfd_link_hash_table_create \
3011
                                  elf32_cr16_link_hash_table_create
3012
#define bfd_elf32_bfd_link_hash_table_free \
3013
                                  elf32_cr16_link_hash_table_free
3014
 
3015
#define elf_backend_create_dynamic_sections \
3016
                                  _bfd_cr16_elf_create_dynamic_sections
3017
#define elf_backend_adjust_dynamic_symbol \
3018
                                  _bfd_cr16_elf_adjust_dynamic_symbol
3019
#define elf_backend_size_dynamic_sections \
3020
                                  _bfd_cr16_elf_size_dynamic_sections
3021
#define elf_backend_omit_section_dynsym \
3022
      ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
3023
#define elf_backend_finish_dynamic_symbol \
3024
                                   _bfd_cr16_elf_finish_dynamic_symbol
3025
#define elf_backend_finish_dynamic_sections \
3026
                                   _bfd_cr16_elf_finish_dynamic_sections
3027
 
3028
#define elf_backend_reloc_type_class   _bfd_cr16_elf_reloc_type_class
3029
 
3030
 
3031
#define elf_backend_want_got_plt        1
3032
#define elf_backend_plt_readonly        1
3033
#define elf_backend_want_plt_sym        0
3034
#define elf_backend_got_header_size     12
3035
 
3036
#include "elf32-target.h"

powered by: WebSVN 2.1.0

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