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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [bfd/] [elf32-cr16.c] - Blame information for rev 818

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

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

powered by: WebSVN 2.1.0

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