~ubuntu-branches/ubuntu/quantal/gclcvs/quantal

« back to all changes in this revision

Viewing changes to binutils/bfd/coff-mips.c

  • Committer: Bazaar Package Importer
  • Author(s): Camm Maguire
  • Date: 2004-06-24 15:13:46 UTC
  • Revision ID: james.westby@ubuntu.com-20040624151346-xh0xaaktyyp7aorc
Tags: 2.7.0-26
C_GC_OFFSET is 2 on m68k-linux

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* BFD back-end for MIPS Extended-Coff files.
 
2
   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
 
3
   2000, 2001, 2002
 
4
   Free Software Foundation, Inc.
 
5
   Original version by Per Bothner.
 
6
   Full support added by Ian Lance Taylor, ian@cygnus.com.
 
7
 
 
8
This file is part of BFD, the Binary File Descriptor library.
 
9
 
 
10
This program is free software; you can redistribute it and/or modify
 
11
it under the terms of the GNU General Public License as published by
 
12
the Free Software Foundation; either version 2 of the License, or
 
13
(at your option) any later version.
 
14
 
 
15
This program is distributed in the hope that it will be useful,
 
16
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
18
GNU General Public License for more details.
 
19
 
 
20
You should have received a copy of the GNU General Public License
 
21
along with this program; if not, write to the Free Software
 
22
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
23
 
 
24
#include "bfd.h"
 
25
#include "sysdep.h"
 
26
#include "bfdlink.h"
 
27
#include "libbfd.h"
 
28
#include "coff/internal.h"
 
29
#include "coff/sym.h"
 
30
#include "coff/symconst.h"
 
31
#include "coff/ecoff.h"
 
32
#include "coff/mips.h"
 
33
#include "libcoff.h"
 
34
#include "libecoff.h"
 
35
 
 
36
/* Prototypes for static functions.  */
 
37
 
 
38
static boolean mips_ecoff_bad_format_hook PARAMS ((bfd *abfd, PTR filehdr));
 
39
static void mips_ecoff_swap_reloc_in PARAMS ((bfd *, PTR,
 
40
                                              struct internal_reloc *));
 
41
static void mips_ecoff_swap_reloc_out PARAMS ((bfd *,
 
42
                                               const struct internal_reloc *,
 
43
                                               PTR));
 
44
static void mips_adjust_reloc_in PARAMS ((bfd *,
 
45
                                          const struct internal_reloc *,
 
46
                                          arelent *));
 
47
static void mips_adjust_reloc_out PARAMS ((bfd *, const arelent *,
 
48
                                           struct internal_reloc *));
 
49
static bfd_reloc_status_type mips_generic_reloc PARAMS ((bfd *abfd,
 
50
                                                         arelent *reloc,
 
51
                                                         asymbol *symbol,
 
52
                                                         PTR data,
 
53
                                                         asection *section,
 
54
                                                         bfd *output_bfd,
 
55
                                                         char **error));
 
56
static bfd_reloc_status_type mips_refhi_reloc PARAMS ((bfd *abfd,
 
57
                                                       arelent *reloc,
 
58
                                                       asymbol *symbol,
 
59
                                                       PTR data,
 
60
                                                       asection *section,
 
61
                                                       bfd *output_bfd,
 
62
                                                       char **error));
 
63
static bfd_reloc_status_type mips_reflo_reloc PARAMS ((bfd *abfd,
 
64
                                                       arelent *reloc,
 
65
                                                       asymbol *symbol,
 
66
                                                       PTR data,
 
67
                                                       asection *section,
 
68
                                                       bfd *output_bfd,
 
69
                                                       char **error));
 
70
static bfd_reloc_status_type mips_gprel_reloc PARAMS ((bfd *abfd,
 
71
                                                       arelent *reloc,
 
72
                                                       asymbol *symbol,
 
73
                                                       PTR data,
 
74
                                                       asection *section,
 
75
                                                       bfd *output_bfd,
 
76
                                                       char **error));
 
77
static bfd_reloc_status_type mips_relhi_reloc PARAMS ((bfd *abfd,
 
78
                                                       arelent *reloc,
 
79
                                                       asymbol *symbol,
 
80
                                                       PTR data,
 
81
                                                       asection *section,
 
82
                                                       bfd *output_bfd,
 
83
                                                       char **error));
 
84
static bfd_reloc_status_type mips_rello_reloc PARAMS ((bfd *abfd,
 
85
                                                       arelent *reloc,
 
86
                                                       asymbol *symbol,
 
87
                                                       PTR data,
 
88
                                                       asection *section,
 
89
                                                       bfd *output_bfd,
 
90
                                                       char **error));
 
91
static bfd_reloc_status_type mips_switch_reloc PARAMS ((bfd *abfd,
 
92
                                                        arelent *reloc,
 
93
                                                        asymbol *symbol,
 
94
                                                        PTR data,
 
95
                                                        asection *section,
 
96
                                                        bfd *output_bfd,
 
97
                                                        char **error));
 
98
static void mips_relocate_hi PARAMS ((struct internal_reloc *refhi,
 
99
                                      struct internal_reloc *reflo,
 
100
                                      bfd *input_bfd,
 
101
                                      asection *input_section,
 
102
                                      bfd_byte *contents,
 
103
                                      size_t adjust,
 
104
                                      bfd_vma relocation,
 
105
                                      boolean pcrel));
 
106
static boolean mips_relocate_section PARAMS ((bfd *, struct bfd_link_info *,
 
107
                                              bfd *, asection *,
 
108
                                              bfd_byte *, PTR));
 
109
static boolean mips_read_relocs PARAMS ((bfd *, asection *));
 
110
static boolean mips_relax_section PARAMS ((bfd *, asection *,
 
111
                                           struct bfd_link_info *,
 
112
                                           boolean *));
 
113
static boolean mips_relax_pcrel16 PARAMS ((struct bfd_link_info *, bfd *,
 
114
                                           asection *,
 
115
                                           struct ecoff_link_hash_entry *,
 
116
                                           bfd_byte *, bfd_vma));
 
117
static reloc_howto_type *mips_bfd_reloc_type_lookup
 
118
  PARAMS ((bfd *, bfd_reloc_code_real_type));
 
119
 
 
120
/* ECOFF has COFF sections, but the debugging information is stored in
 
121
   a completely different format.  ECOFF targets use some of the
 
122
   swapping routines from coffswap.h, and some of the generic COFF
 
123
   routines in coffgen.c, but, unlike the real COFF targets, do not
 
124
   use coffcode.h itself.
 
125
 
 
126
   Get the generic COFF swapping routines, except for the reloc,
 
127
   symbol, and lineno ones.  Give them ECOFF names.  */
 
128
#define MIPSECOFF
 
129
#define NO_COFF_RELOCS
 
130
#define NO_COFF_SYMBOLS
 
131
#define NO_COFF_LINENOS
 
132
#define coff_swap_filehdr_in mips_ecoff_swap_filehdr_in
 
133
#define coff_swap_filehdr_out mips_ecoff_swap_filehdr_out
 
134
#define coff_swap_aouthdr_in mips_ecoff_swap_aouthdr_in
 
135
#define coff_swap_aouthdr_out mips_ecoff_swap_aouthdr_out
 
136
#define coff_swap_scnhdr_in mips_ecoff_swap_scnhdr_in
 
137
#define coff_swap_scnhdr_out mips_ecoff_swap_scnhdr_out
 
138
#include "coffswap.h"
 
139
 
 
140
/* Get the ECOFF swapping routines.  */
 
141
#define ECOFF_32
 
142
#include "ecoffswap.h"
 
143
 
 
144
/* How to process the various relocs types.  */
 
145
 
 
146
static reloc_howto_type mips_howto_table[] =
 
147
{
 
148
  /* Reloc type 0 is ignored.  The reloc reading code ensures that
 
149
     this is a reference to the .abs section, which will cause
 
150
     bfd_perform_relocation to do nothing.  */
 
151
  HOWTO (MIPS_R_IGNORE, /* type */
 
152
         0,                     /* rightshift */
 
153
         0,                     /* size (0 = byte, 1 = short, 2 = long) */
 
154
         8,                     /* bitsize */
 
155
         false,                 /* pc_relative */
 
156
         0,                     /* bitpos */
 
157
         complain_overflow_dont, /* complain_on_overflow */
 
158
         0,                     /* special_function */
 
159
         "IGNORE",              /* name */
 
160
         false,                 /* partial_inplace */
 
161
         0,                     /* src_mask */
 
162
         0,                     /* dst_mask */
 
163
         false),                /* pcrel_offset */
 
164
 
 
165
  /* A 16 bit reference to a symbol, normally from a data section.  */
 
166
  HOWTO (MIPS_R_REFHALF,        /* type */
 
167
         0,                     /* rightshift */
 
168
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
 
169
         16,                    /* bitsize */
 
170
         false,                 /* pc_relative */
 
171
         0,                     /* bitpos */
 
172
         complain_overflow_bitfield, /* complain_on_overflow */
 
173
         mips_generic_reloc,    /* special_function */
 
174
         "REFHALF",             /* name */
 
175
         true,                  /* partial_inplace */
 
176
         0xffff,                /* src_mask */
 
177
         0xffff,                /* dst_mask */
 
178
         false),                /* pcrel_offset */
 
179
 
 
180
  /* A 32 bit reference to a symbol, normally from a data section.  */
 
181
  HOWTO (MIPS_R_REFWORD,        /* type */
 
182
         0,                     /* rightshift */
 
183
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
184
         32,                    /* bitsize */
 
185
         false,                 /* pc_relative */
 
186
         0,                     /* bitpos */
 
187
         complain_overflow_bitfield, /* complain_on_overflow */
 
188
         mips_generic_reloc,    /* special_function */
 
189
         "REFWORD",             /* name */
 
190
         true,                  /* partial_inplace */
 
191
         0xffffffff,            /* src_mask */
 
192
         0xffffffff,            /* dst_mask */
 
193
         false),                /* pcrel_offset */
 
194
 
 
195
  /* A 26 bit absolute jump address.  */
 
196
  HOWTO (MIPS_R_JMPADDR,        /* type */
 
197
         2,                     /* rightshift */
 
198
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
199
         26,                    /* bitsize */
 
200
         false,                 /* pc_relative */
 
201
         0,                     /* bitpos */
 
202
         complain_overflow_dont, /* complain_on_overflow */
 
203
                                /* This needs complex overflow
 
204
                                   detection, because the upper four
 
205
                                   bits must match the PC.  */
 
206
         mips_generic_reloc,    /* special_function */
 
207
         "JMPADDR",             /* name */
 
208
         true,                  /* partial_inplace */
 
209
         0x3ffffff,             /* src_mask */
 
210
         0x3ffffff,             /* dst_mask */
 
211
         false),                /* pcrel_offset */
 
212
 
 
213
  /* The high 16 bits of a symbol value.  Handled by the function
 
214
     mips_refhi_reloc.  */
 
215
  HOWTO (MIPS_R_REFHI,          /* type */
 
216
         16,                    /* rightshift */
 
217
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
218
         16,                    /* bitsize */
 
219
         false,                 /* pc_relative */
 
220
         0,                     /* bitpos */
 
221
         complain_overflow_bitfield, /* complain_on_overflow */
 
222
         mips_refhi_reloc,      /* special_function */
 
223
         "REFHI",               /* name */
 
224
         true,                  /* partial_inplace */
 
225
         0xffff,                /* src_mask */
 
226
         0xffff,                /* dst_mask */
 
227
         false),                /* pcrel_offset */
 
228
 
 
229
  /* The low 16 bits of a symbol value.  */
 
230
  HOWTO (MIPS_R_REFLO,          /* type */
 
231
         0,                     /* rightshift */
 
232
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
233
         16,                    /* bitsize */
 
234
         false,                 /* pc_relative */
 
235
         0,                     /* bitpos */
 
236
         complain_overflow_dont, /* complain_on_overflow */
 
237
         mips_reflo_reloc,      /* special_function */
 
238
         "REFLO",               /* name */
 
239
         true,                  /* partial_inplace */
 
240
         0xffff,                /* src_mask */
 
241
         0xffff,                /* dst_mask */
 
242
         false),                /* pcrel_offset */
 
243
 
 
244
  /* A reference to an offset from the gp register.  Handled by the
 
245
     function mips_gprel_reloc.  */
 
246
  HOWTO (MIPS_R_GPREL,          /* type */
 
247
         0,                     /* rightshift */
 
248
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
249
         16,                    /* bitsize */
 
250
         false,                 /* pc_relative */
 
251
         0,                     /* bitpos */
 
252
         complain_overflow_signed, /* complain_on_overflow */
 
253
         mips_gprel_reloc,      /* special_function */
 
254
         "GPREL",               /* name */
 
255
         true,                  /* partial_inplace */
 
256
         0xffff,                /* src_mask */
 
257
         0xffff,                /* dst_mask */
 
258
         false),                /* pcrel_offset */
 
259
 
 
260
  /* A reference to a literal using an offset from the gp register.
 
261
     Handled by the function mips_gprel_reloc.  */
 
262
  HOWTO (MIPS_R_LITERAL,        /* type */
 
263
         0,                     /* rightshift */
 
264
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
265
         16,                    /* bitsize */
 
266
         false,                 /* pc_relative */
 
267
         0,                     /* bitpos */
 
268
         complain_overflow_signed, /* complain_on_overflow */
 
269
         mips_gprel_reloc,      /* special_function */
 
270
         "LITERAL",             /* name */
 
271
         true,                  /* partial_inplace */
 
272
         0xffff,                /* src_mask */
 
273
         0xffff,                /* dst_mask */
 
274
         false),                /* pcrel_offset */
 
275
 
 
276
  EMPTY_HOWTO (8),
 
277
  EMPTY_HOWTO (9),
 
278
  EMPTY_HOWTO (10),
 
279
  EMPTY_HOWTO (11),
 
280
 
 
281
  /* This reloc is a Cygnus extension used when generating position
 
282
     independent code for embedded systems.  It represents a 16 bit PC
 
283
     relative reloc rightshifted twice as used in the MIPS branch
 
284
     instructions.  */
 
285
  HOWTO (MIPS_R_PCREL16,        /* type */
 
286
         2,                     /* rightshift */
 
287
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
288
         16,                    /* bitsize */
 
289
         true,                  /* pc_relative */
 
290
         0,                     /* bitpos */
 
291
         complain_overflow_signed, /* complain_on_overflow */
 
292
         mips_generic_reloc,    /* special_function */
 
293
         "PCREL16",             /* name */
 
294
         true,                  /* partial_inplace */
 
295
         0xffff,                /* src_mask */
 
296
         0xffff,                /* dst_mask */
 
297
         true),                 /* pcrel_offset */
 
298
 
 
299
  /* This reloc is a Cygnus extension used when generating position
 
300
     independent code for embedded systems.  It represents the high 16
 
301
     bits of a PC relative reloc.  The next reloc must be
 
302
     MIPS_R_RELLO, and the addend is formed from the addends of the
 
303
     two instructions, just as in MIPS_R_REFHI and MIPS_R_REFLO.  The
 
304
     final value is actually PC relative to the location of the
 
305
     MIPS_R_RELLO reloc, not the MIPS_R_RELHI reloc.  */
 
306
  HOWTO (MIPS_R_RELHI,          /* type */
 
307
         16,                    /* rightshift */
 
308
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
309
         16,                    /* bitsize */
 
310
         true,                  /* pc_relative */
 
311
         0,                     /* bitpos */
 
312
         complain_overflow_bitfield, /* complain_on_overflow */
 
313
         mips_relhi_reloc,      /* special_function */
 
314
         "RELHI",               /* name */
 
315
         true,                  /* partial_inplace */
 
316
         0xffff,                /* src_mask */
 
317
         0xffff,                /* dst_mask */
 
318
         true),                 /* pcrel_offset */
 
319
 
 
320
  /* This reloc is a Cygnus extension used when generating position
 
321
     independent code for embedded systems.  It represents the low 16
 
322
     bits of a PC relative reloc.  */
 
323
  HOWTO (MIPS_R_RELLO,          /* type */
 
324
         0,                     /* rightshift */
 
325
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
326
         16,                    /* bitsize */
 
327
         true,                  /* pc_relative */
 
328
         0,                     /* bitpos */
 
329
         complain_overflow_dont, /* complain_on_overflow */
 
330
         mips_rello_reloc,      /* special_function */
 
331
         "RELLO",               /* name */
 
332
         true,                  /* partial_inplace */
 
333
         0xffff,                /* src_mask */
 
334
         0xffff,                /* dst_mask */
 
335
         true),                 /* pcrel_offset */
 
336
 
 
337
  EMPTY_HOWTO (15),
 
338
  EMPTY_HOWTO (16),
 
339
  EMPTY_HOWTO (17),
 
340
  EMPTY_HOWTO (18),
 
341
  EMPTY_HOWTO (19),
 
342
  EMPTY_HOWTO (20),
 
343
  EMPTY_HOWTO (21),
 
344
 
 
345
  /* This reloc is a Cygnus extension used when generating position
 
346
     independent code for embedded systems.  It represents an entry in
 
347
     a switch table, which is the difference between two symbols in
 
348
     the .text section.  The symndx is actually the offset from the
 
349
     reloc address to the subtrahend.  See include/coff/mips.h for
 
350
     more details.  */
 
351
  HOWTO (MIPS_R_SWITCH,         /* type */
 
352
         0,                     /* rightshift */
 
353
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
354
         32,                    /* bitsize */
 
355
         true,                  /* pc_relative */
 
356
         0,                     /* bitpos */
 
357
         complain_overflow_dont, /* complain_on_overflow */
 
358
         mips_switch_reloc,     /* special_function */
 
359
         "SWITCH",              /* name */
 
360
         true,                  /* partial_inplace */
 
361
         0xffffffff,            /* src_mask */
 
362
         0xffffffff,            /* dst_mask */
 
363
         true)                  /* pcrel_offset */
 
364
};
 
365
 
 
366
#define MIPS_HOWTO_COUNT \
 
367
  (sizeof mips_howto_table / sizeof mips_howto_table[0])
 
368
 
 
369
/* When the linker is doing relaxing, it may change an external PCREL16
 
370
   reloc.  This typically represents an instruction like
 
371
       bal foo
 
372
   We change it to
 
373
       .set  noreorder
 
374
       bal   $L1
 
375
       lui   $at,%hi(foo - $L1)
 
376
     $L1:
 
377
       addiu $at,%lo(foo - $L1)
 
378
       addu  $at,$at,$31
 
379
       jalr  $at
 
380
   PCREL16_EXPANSION_ADJUSTMENT is the number of bytes this changes the
 
381
   instruction by.  */
 
382
 
 
383
#define PCREL16_EXPANSION_ADJUSTMENT (4 * 4)
 
384
 
 
385
/* See whether the magic number matches.  */
 
386
 
 
387
static boolean
 
388
mips_ecoff_bad_format_hook (abfd, filehdr)
 
389
     bfd *abfd;
 
390
     PTR filehdr;
 
391
{
 
392
  struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
 
393
 
 
394
  switch (internal_f->f_magic)
 
395
    {
 
396
    case MIPS_MAGIC_1:
 
397
      /* I don't know what endianness this implies.  */
 
398
      return true;
 
399
 
 
400
    case MIPS_MAGIC_BIG:
 
401
    case MIPS_MAGIC_BIG2:
 
402
    case MIPS_MAGIC_BIG3:
 
403
      return bfd_big_endian (abfd);
 
404
 
 
405
    case MIPS_MAGIC_LITTLE:
 
406
    case MIPS_MAGIC_LITTLE2:
 
407
    case MIPS_MAGIC_LITTLE3:
 
408
      return bfd_little_endian (abfd);
 
409
 
 
410
    default:
 
411
      return false;
 
412
    }
 
413
}
 
414
 
 
415
/* Reloc handling.  MIPS ECOFF relocs are packed into 8 bytes in
 
416
   external form.  They use a bit which indicates whether the symbol
 
417
   is external.  */
 
418
 
 
419
/* Swap a reloc in.  */
 
420
 
 
421
static void
 
422
mips_ecoff_swap_reloc_in (abfd, ext_ptr, intern)
 
423
     bfd *abfd;
 
424
     PTR ext_ptr;
 
425
     struct internal_reloc *intern;
 
426
{
 
427
  const RELOC *ext = (RELOC *) ext_ptr;
 
428
 
 
429
  intern->r_vaddr = H_GET_32 (abfd, ext->r_vaddr);
 
430
  if (bfd_header_big_endian (abfd))
 
431
    {
 
432
      intern->r_symndx = (((int) ext->r_bits[0]
 
433
                           << RELOC_BITS0_SYMNDX_SH_LEFT_BIG)
 
434
                          | ((int) ext->r_bits[1]
 
435
                             << RELOC_BITS1_SYMNDX_SH_LEFT_BIG)
 
436
                          | ((int) ext->r_bits[2]
 
437
                             << RELOC_BITS2_SYMNDX_SH_LEFT_BIG));
 
438
      intern->r_type = ((ext->r_bits[3] & RELOC_BITS3_TYPE_BIG)
 
439
                        >> RELOC_BITS3_TYPE_SH_BIG);
 
440
      intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_BIG) != 0;
 
441
    }
 
442
  else
 
443
    {
 
444
      intern->r_symndx = (((int) ext->r_bits[0]
 
445
                           << RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE)
 
446
                          | ((int) ext->r_bits[1]
 
447
                             << RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE)
 
448
                          | ((int) ext->r_bits[2]
 
449
                             << RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE));
 
450
      intern->r_type = (((ext->r_bits[3] & RELOC_BITS3_TYPE_LITTLE)
 
451
                         >> RELOC_BITS3_TYPE_SH_LITTLE)
 
452
                        | ((ext->r_bits[3] & RELOC_BITS3_TYPEHI_LITTLE)
 
453
                           << RELOC_BITS3_TYPEHI_SH_LITTLE));
 
454
      intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_LITTLE) != 0;
 
455
    }
 
456
 
 
457
  /* If this is a MIPS_R_SWITCH reloc, or an internal MIPS_R_RELHI or
 
458
     MIPS_R_RELLO reloc, r_symndx is actually the offset from the
 
459
     reloc address to the base of the difference (see
 
460
     include/coff/mips.h for more details).  We copy symndx into the
 
461
     r_offset field so as not to confuse ecoff_slurp_reloc_table in
 
462
     ecoff.c.  In adjust_reloc_in we then copy r_offset into the reloc
 
463
     addend.  */
 
464
  if (intern->r_type == MIPS_R_SWITCH
 
465
      || (! intern->r_extern
 
466
          && (intern->r_type == MIPS_R_RELLO
 
467
              || intern->r_type == MIPS_R_RELHI)))
 
468
    {
 
469
      BFD_ASSERT (! intern->r_extern);
 
470
      intern->r_offset = intern->r_symndx;
 
471
      if (intern->r_offset & 0x800000)
 
472
        intern->r_offset -= 0x1000000;
 
473
      intern->r_symndx = RELOC_SECTION_TEXT;
 
474
    }
 
475
}
 
476
 
 
477
/* Swap a reloc out.  */
 
478
 
 
479
static void
 
480
mips_ecoff_swap_reloc_out (abfd, intern, dst)
 
481
     bfd *abfd;
 
482
     const struct internal_reloc *intern;
 
483
     PTR dst;
 
484
{
 
485
  RELOC *ext = (RELOC *) dst;
 
486
  long r_symndx;
 
487
 
 
488
  BFD_ASSERT (intern->r_extern
 
489
              || (intern->r_symndx >= 0 && intern->r_symndx <= 12));
 
490
 
 
491
  /* If this is a MIPS_R_SWITCH reloc, or an internal MIPS_R_RELLO or
 
492
     MIPS_R_RELHI reloc, we actually want to write the contents of
 
493
     r_offset out as the symbol index.  This undoes the change made by
 
494
     mips_ecoff_swap_reloc_in.  */
 
495
  if (intern->r_type != MIPS_R_SWITCH
 
496
      && (intern->r_extern
 
497
          || (intern->r_type != MIPS_R_RELHI
 
498
              && intern->r_type != MIPS_R_RELLO)))
 
499
    r_symndx = intern->r_symndx;
 
500
  else
 
501
    {
 
502
      BFD_ASSERT (intern->r_symndx == RELOC_SECTION_TEXT);
 
503
      r_symndx = intern->r_offset & 0xffffff;
 
504
    }
 
505
 
 
506
  H_PUT_32 (abfd, intern->r_vaddr, ext->r_vaddr);
 
507
  if (bfd_header_big_endian (abfd))
 
508
    {
 
509
      ext->r_bits[0] = r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_BIG;
 
510
      ext->r_bits[1] = r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_BIG;
 
511
      ext->r_bits[2] = r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_BIG;
 
512
      ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_BIG)
 
513
                         & RELOC_BITS3_TYPE_BIG)
 
514
                        | (intern->r_extern ? RELOC_BITS3_EXTERN_BIG : 0));
 
515
    }
 
516
  else
 
517
    {
 
518
      ext->r_bits[0] = r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE;
 
519
      ext->r_bits[1] = r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE;
 
520
      ext->r_bits[2] = r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE;
 
521
      ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_LITTLE)
 
522
                         & RELOC_BITS3_TYPE_LITTLE)
 
523
                        | ((intern->r_type >> RELOC_BITS3_TYPEHI_SH_LITTLE
 
524
                            & RELOC_BITS3_TYPEHI_LITTLE))
 
525
                        | (intern->r_extern ? RELOC_BITS3_EXTERN_LITTLE : 0));
 
526
    }
 
527
}
 
528
 
 
529
/* Finish canonicalizing a reloc.  Part of this is generic to all
 
530
   ECOFF targets, and that part is in ecoff.c.  The rest is done in
 
531
   this backend routine.  It must fill in the howto field.  */
 
532
 
 
533
static void
 
534
mips_adjust_reloc_in (abfd, intern, rptr)
 
535
     bfd *abfd;
 
536
     const struct internal_reloc *intern;
 
537
     arelent *rptr;
 
538
{
 
539
  if (intern->r_type > MIPS_R_SWITCH)
 
540
    abort ();
 
541
 
 
542
  if (! intern->r_extern
 
543
      && (intern->r_type == MIPS_R_GPREL
 
544
          || intern->r_type == MIPS_R_LITERAL))
 
545
    rptr->addend += ecoff_data (abfd)->gp;
 
546
 
 
547
  /* If the type is MIPS_R_IGNORE, make sure this is a reference to
 
548
     the absolute section so that the reloc is ignored.  */
 
549
  if (intern->r_type == MIPS_R_IGNORE)
 
550
    rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
 
551
 
 
552
  /* If this is a MIPS_R_SWITCH reloc, or an internal MIPS_R_RELHI or
 
553
     MIPS_R_RELLO reloc, we want the addend field of the BFD relocto
 
554
     hold the value which was originally in the symndx field of the
 
555
     internal MIPS ECOFF reloc.  This value was copied into
 
556
     intern->r_offset by mips_swap_reloc_in, and here we copy it into
 
557
     the addend field.  */
 
558
  if (intern->r_type == MIPS_R_SWITCH
 
559
      || (! intern->r_extern
 
560
          && (intern->r_type == MIPS_R_RELHI
 
561
              || intern->r_type == MIPS_R_RELLO)))
 
562
    rptr->addend = intern->r_offset;
 
563
 
 
564
  rptr->howto = &mips_howto_table[intern->r_type];
 
565
}
 
566
 
 
567
/* Make any adjustments needed to a reloc before writing it out.  None
 
568
   are needed for MIPS.  */
 
569
 
 
570
static void
 
571
mips_adjust_reloc_out (abfd, rel, intern)
 
572
     bfd *abfd ATTRIBUTE_UNUSED;
 
573
     const arelent *rel;
 
574
     struct internal_reloc *intern;
 
575
{
 
576
  /* For a MIPS_R_SWITCH reloc, or an internal MIPS_R_RELHI or
 
577
     MIPS_R_RELLO reloc, we must copy rel->addend into
 
578
     intern->r_offset.  This will then be written out as the symbol
 
579
     index by mips_ecoff_swap_reloc_out.  This operation parallels the
 
580
     action of mips_adjust_reloc_in.  */
 
581
  if (intern->r_type == MIPS_R_SWITCH
 
582
      || (! intern->r_extern
 
583
          && (intern->r_type == MIPS_R_RELHI
 
584
              || intern->r_type == MIPS_R_RELLO)))
 
585
    intern->r_offset = rel->addend;
 
586
}
 
587
 
 
588
/* ECOFF relocs are either against external symbols, or against
 
589
   sections.  If we are producing relocateable output, and the reloc
 
590
   is against an external symbol, and nothing has given us any
 
591
   additional addend, the resulting reloc will also be against the
 
592
   same symbol.  In such a case, we don't want to change anything
 
593
   about the way the reloc is handled, since it will all be done at
 
594
   final link time.  Rather than put special case code into
 
595
   bfd_perform_relocation, all the reloc types use this howto
 
596
   function.  It just short circuits the reloc if producing
 
597
   relocateable output against an external symbol.  */
 
598
 
 
599
static bfd_reloc_status_type
 
600
mips_generic_reloc (abfd,
 
601
                    reloc_entry,
 
602
                    symbol,
 
603
                    data,
 
604
                    input_section,
 
605
                    output_bfd,
 
606
                    error_message)
 
607
     bfd *abfd ATTRIBUTE_UNUSED;
 
608
     arelent *reloc_entry;
 
609
     asymbol *symbol;
 
610
     PTR data ATTRIBUTE_UNUSED;
 
611
     asection *input_section;
 
612
     bfd *output_bfd;
 
613
     char **error_message ATTRIBUTE_UNUSED;
 
614
{
 
615
  if (output_bfd != (bfd *) NULL
 
616
      && (symbol->flags & BSF_SECTION_SYM) == 0
 
617
      && reloc_entry->addend == 0)
 
618
    {
 
619
      reloc_entry->address += input_section->output_offset;
 
620
      return bfd_reloc_ok;
 
621
    }
 
622
 
 
623
  return bfd_reloc_continue;
 
624
}
 
625
 
 
626
/* Do a REFHI relocation.  This has to be done in combination with a
 
627
   REFLO reloc, because there is a carry from the REFLO to the REFHI.
 
628
   Here we just save the information we need; we do the actual
 
629
   relocation when we see the REFLO.  MIPS ECOFF requires that the
 
630
   REFLO immediately follow the REFHI.  As a GNU extension, we permit
 
631
   an arbitrary number of HI relocs to be associated with a single LO
 
632
   reloc.  This extension permits gcc to output the HI and LO relocs
 
633
   itself.  */
 
634
 
 
635
struct mips_hi
 
636
{
 
637
  struct mips_hi *next;
 
638
  bfd_byte *addr;
 
639
  bfd_vma addend;
 
640
};
 
641
 
 
642
/* FIXME: This should not be a static variable.  */
 
643
 
 
644
static struct mips_hi *mips_refhi_list;
 
645
 
 
646
static bfd_reloc_status_type
 
647
mips_refhi_reloc (abfd,
 
648
                  reloc_entry,
 
649
                  symbol,
 
650
                  data,
 
651
                  input_section,
 
652
                  output_bfd,
 
653
                  error_message)
 
654
     bfd *abfd ATTRIBUTE_UNUSED;
 
655
     arelent *reloc_entry;
 
656
     asymbol *symbol;
 
657
     PTR data;
 
658
     asection *input_section;
 
659
     bfd *output_bfd;
 
660
     char **error_message ATTRIBUTE_UNUSED;
 
661
{
 
662
  bfd_reloc_status_type ret;
 
663
  bfd_vma relocation;
 
664
  struct mips_hi *n;
 
665
 
 
666
  /* If we're relocating, and this an external symbol, we don't want
 
667
     to change anything.  */
 
668
  if (output_bfd != (bfd *) NULL
 
669
      && (symbol->flags & BSF_SECTION_SYM) == 0
 
670
      && reloc_entry->addend == 0)
 
671
    {
 
672
      reloc_entry->address += input_section->output_offset;
 
673
      return bfd_reloc_ok;
 
674
    }
 
675
 
 
676
  ret = bfd_reloc_ok;
 
677
  if (bfd_is_und_section (symbol->section)
 
678
      && output_bfd == (bfd *) NULL)
 
679
    ret = bfd_reloc_undefined;
 
680
 
 
681
  if (bfd_is_com_section (symbol->section))
 
682
    relocation = 0;
 
683
  else
 
684
    relocation = symbol->value;
 
685
 
 
686
  relocation += symbol->section->output_section->vma;
 
687
  relocation += symbol->section->output_offset;
 
688
  relocation += reloc_entry->addend;
 
689
 
 
690
  if (reloc_entry->address > input_section->_cooked_size)
 
691
    return bfd_reloc_outofrange;
 
692
 
 
693
  /* Save the information, and let REFLO do the actual relocation.  */
 
694
  n = (struct mips_hi *) bfd_malloc ((bfd_size_type) sizeof *n);
 
695
  if (n == NULL)
 
696
    return bfd_reloc_outofrange;
 
697
  n->addr = (bfd_byte *) data + reloc_entry->address;
 
698
  n->addend = relocation;
 
699
  n->next = mips_refhi_list;
 
700
  mips_refhi_list = n;
 
701
 
 
702
  if (output_bfd != (bfd *) NULL)
 
703
    reloc_entry->address += input_section->output_offset;
 
704
 
 
705
  return ret;
 
706
}
 
707
 
 
708
/* Do a REFLO relocation.  This is a straightforward 16 bit inplace
 
709
   relocation; this function exists in order to do the REFHI
 
710
   relocation described above.  */
 
711
 
 
712
static bfd_reloc_status_type
 
713
mips_reflo_reloc (abfd,
 
714
                  reloc_entry,
 
715
                  symbol,
 
716
                  data,
 
717
                  input_section,
 
718
                  output_bfd,
 
719
                  error_message)
 
720
     bfd *abfd;
 
721
     arelent *reloc_entry;
 
722
     asymbol *symbol;
 
723
     PTR data;
 
724
     asection *input_section;
 
725
     bfd *output_bfd;
 
726
     char **error_message;
 
727
{
 
728
  if (mips_refhi_list != NULL)
 
729
    {
 
730
      struct mips_hi *l;
 
731
 
 
732
      l = mips_refhi_list;
 
733
      while (l != NULL)
 
734
        {
 
735
          unsigned long insn;
 
736
          unsigned long val;
 
737
          unsigned long vallo;
 
738
          struct mips_hi *next;
 
739
 
 
740
          /* Do the REFHI relocation.  Note that we actually don't
 
741
             need to know anything about the REFLO itself, except
 
742
             where to find the low 16 bits of the addend needed by the
 
743
             REFHI.  */
 
744
          insn = bfd_get_32 (abfd, l->addr);
 
745
          vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address)
 
746
                   & 0xffff);
 
747
          val = ((insn & 0xffff) << 16) + vallo;
 
748
          val += l->addend;
 
749
 
 
750
          /* The low order 16 bits are always treated as a signed
 
751
             value.  Therefore, a negative value in the low order bits
 
752
             requires an adjustment in the high order bits.  We need
 
753
             to make this adjustment in two ways: once for the bits we
 
754
             took from the data, and once for the bits we are putting
 
755
             back in to the data.  */
 
756
          if ((vallo & 0x8000) != 0)
 
757
            val -= 0x10000;
 
758
          if ((val & 0x8000) != 0)
 
759
            val += 0x10000;
 
760
 
 
761
          insn = (insn &~ (unsigned) 0xffff) | ((val >> 16) & 0xffff);
 
762
          bfd_put_32 (abfd, (bfd_vma) insn, l->addr);
 
763
 
 
764
          next = l->next;
 
765
          free (l);
 
766
          l = next;
 
767
        }
 
768
 
 
769
      mips_refhi_list = NULL;
 
770
    }
 
771
 
 
772
  /* Now do the REFLO reloc in the usual way.  */
 
773
  return mips_generic_reloc (abfd, reloc_entry, symbol, data,
 
774
                              input_section, output_bfd, error_message);
 
775
}
 
776
 
 
777
/* Do a GPREL relocation.  This is a 16 bit value which must become
 
778
   the offset from the gp register.  */
 
779
 
 
780
static bfd_reloc_status_type
 
781
mips_gprel_reloc (abfd,
 
782
                  reloc_entry,
 
783
                  symbol,
 
784
                  data,
 
785
                  input_section,
 
786
                  output_bfd,
 
787
                  error_message)
 
788
     bfd *abfd;
 
789
     arelent *reloc_entry;
 
790
     asymbol *symbol;
 
791
     PTR data;
 
792
     asection *input_section;
 
793
     bfd *output_bfd;
 
794
     char **error_message;
 
795
{
 
796
  boolean relocateable;
 
797
  bfd_vma gp;
 
798
  bfd_vma relocation;
 
799
  unsigned long val;
 
800
  unsigned long insn;
 
801
 
 
802
  /* If we're relocating, and this is an external symbol with no
 
803
     addend, we don't want to change anything.  We will only have an
 
804
     addend if this is a newly created reloc, not read from an ECOFF
 
805
     file.  */
 
806
  if (output_bfd != (bfd *) NULL
 
807
      && (symbol->flags & BSF_SECTION_SYM) == 0
 
808
      && reloc_entry->addend == 0)
 
809
    {
 
810
      reloc_entry->address += input_section->output_offset;
 
811
      return bfd_reloc_ok;
 
812
    }
 
813
 
 
814
  if (output_bfd != (bfd *) NULL)
 
815
    relocateable = true;
 
816
  else
 
817
    {
 
818
      relocateable = false;
 
819
      output_bfd = symbol->section->output_section->owner;
 
820
    }
 
821
 
 
822
  if (bfd_is_und_section (symbol->section) && ! relocateable)
 
823
    return bfd_reloc_undefined;
 
824
 
 
825
  /* We have to figure out the gp value, so that we can adjust the
 
826
     symbol value correctly.  We look up the symbol _gp in the output
 
827
     BFD.  If we can't find it, we're stuck.  We cache it in the ECOFF
 
828
     target data.  We don't need to adjust the symbol value for an
 
829
     external symbol if we are producing relocateable output.  */
 
830
  gp = _bfd_get_gp_value (output_bfd);
 
831
  if (gp == 0
 
832
      && (! relocateable
 
833
          || (symbol->flags & BSF_SECTION_SYM) != 0))
 
834
    {
 
835
      if (relocateable)
 
836
        {
 
837
          /* Make up a value.  */
 
838
          gp = symbol->section->output_section->vma + 0x4000;
 
839
          _bfd_set_gp_value (output_bfd, gp);
 
840
        }
 
841
      else
 
842
        {
 
843
          unsigned int count;
 
844
          asymbol **sym;
 
845
          unsigned int i;
 
846
 
 
847
          count = bfd_get_symcount (output_bfd);
 
848
          sym = bfd_get_outsymbols (output_bfd);
 
849
 
 
850
          if (sym == (asymbol **) NULL)
 
851
            i = count;
 
852
          else
 
853
            {
 
854
              for (i = 0; i < count; i++, sym++)
 
855
                {
 
856
                  register const char *name;
 
857
 
 
858
                  name = bfd_asymbol_name (*sym);
 
859
                  if (*name == '_' && strcmp (name, "_gp") == 0)
 
860
                    {
 
861
                      gp = bfd_asymbol_value (*sym);
 
862
                      _bfd_set_gp_value (output_bfd, gp);
 
863
                      break;
 
864
                    }
 
865
                }
 
866
            }
 
867
 
 
868
          if (i >= count)
 
869
            {
 
870
              /* Only get the error once.  */
 
871
              gp = 4;
 
872
              _bfd_set_gp_value (output_bfd, gp);
 
873
              *error_message =
 
874
                (char *) _("GP relative relocation when _gp not defined");
 
875
              return bfd_reloc_dangerous;
 
876
            }
 
877
        }
 
878
    }
 
879
 
 
880
  if (bfd_is_com_section (symbol->section))
 
881
    relocation = 0;
 
882
  else
 
883
    relocation = symbol->value;
 
884
 
 
885
  relocation += symbol->section->output_section->vma;
 
886
  relocation += symbol->section->output_offset;
 
887
 
 
888
  if (reloc_entry->address > input_section->_cooked_size)
 
889
    return bfd_reloc_outofrange;
 
890
 
 
891
  insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
 
892
 
 
893
  /* Set val to the offset into the section or symbol.  */
 
894
  val = ((insn & 0xffff) + reloc_entry->addend) & 0xffff;
 
895
  if (val & 0x8000)
 
896
    val -= 0x10000;
 
897
 
 
898
  /* Adjust val for the final section location and GP value.  If we
 
899
     are producing relocateable output, we don't want to do this for
 
900
     an external symbol.  */
 
901
  if (! relocateable
 
902
      || (symbol->flags & BSF_SECTION_SYM) != 0)
 
903
    val += relocation - gp;
 
904
 
 
905
  insn = (insn &~ (unsigned) 0xffff) | (val & 0xffff);
 
906
  bfd_put_32 (abfd, (bfd_vma) insn, (bfd_byte *) data + reloc_entry->address);
 
907
 
 
908
  if (relocateable)
 
909
    reloc_entry->address += input_section->output_offset;
 
910
 
 
911
  /* Make sure it fit in 16 bits.  */
 
912
  if ((long) val >= 0x8000 || (long) val < -0x8000)
 
913
    return bfd_reloc_overflow;
 
914
 
 
915
  return bfd_reloc_ok;
 
916
}
 
917
 
 
918
/* Do a RELHI relocation.  We do this in conjunction with a RELLO
 
919
   reloc, just as REFHI and REFLO are done together.  RELHI and RELLO
 
920
   are Cygnus extensions used when generating position independent
 
921
   code for embedded systems.  */
 
922
 
 
923
/* FIXME: This should not be a static variable.  */
 
924
 
 
925
static struct mips_hi *mips_relhi_list;
 
926
 
 
927
static bfd_reloc_status_type
 
928
mips_relhi_reloc (abfd,
 
929
                  reloc_entry,
 
930
                  symbol,
 
931
                  data,
 
932
                  input_section,
 
933
                  output_bfd,
 
934
                  error_message)
 
935
     bfd *abfd ATTRIBUTE_UNUSED;
 
936
     arelent *reloc_entry;
 
937
     asymbol *symbol;
 
938
     PTR data;
 
939
     asection *input_section;
 
940
     bfd *output_bfd;
 
941
     char **error_message ATTRIBUTE_UNUSED;
 
942
{
 
943
  bfd_reloc_status_type ret;
 
944
  bfd_vma relocation;
 
945
  struct mips_hi *n;
 
946
 
 
947
  /* If this is a reloc against a section symbol, then it is correct
 
948
     in the object file.  The only time we want to change this case is
 
949
     when we are relaxing, and that is handled entirely by
 
950
     mips_relocate_section and never calls this function.  */
 
951
  if ((symbol->flags & BSF_SECTION_SYM) != 0)
 
952
    {
 
953
      if (output_bfd != (bfd *) NULL)
 
954
        reloc_entry->address += input_section->output_offset;
 
955
      return bfd_reloc_ok;
 
956
    }
 
957
 
 
958
  /* This is an external symbol.  If we're relocating, we don't want
 
959
     to change anything.  */
 
960
  if (output_bfd != (bfd *) NULL)
 
961
    {
 
962
      reloc_entry->address += input_section->output_offset;
 
963
      return bfd_reloc_ok;
 
964
    }
 
965
 
 
966
  ret = bfd_reloc_ok;
 
967
  if (bfd_is_und_section (symbol->section)
 
968
      && output_bfd == (bfd *) NULL)
 
969
    ret = bfd_reloc_undefined;
 
970
 
 
971
  if (bfd_is_com_section (symbol->section))
 
972
    relocation = 0;
 
973
  else
 
974
    relocation = symbol->value;
 
975
 
 
976
  relocation += symbol->section->output_section->vma;
 
977
  relocation += symbol->section->output_offset;
 
978
  relocation += reloc_entry->addend;
 
979
 
 
980
  if (reloc_entry->address > input_section->_cooked_size)
 
981
    return bfd_reloc_outofrange;
 
982
 
 
983
  /* Save the information, and let RELLO do the actual relocation.  */
 
984
  n = (struct mips_hi *) bfd_malloc ((bfd_size_type) sizeof *n);
 
985
  if (n == NULL)
 
986
    return bfd_reloc_outofrange;
 
987
  n->addr = (bfd_byte *) data + reloc_entry->address;
 
988
  n->addend = relocation;
 
989
  n->next = mips_relhi_list;
 
990
  mips_relhi_list = n;
 
991
 
 
992
  if (output_bfd != (bfd *) NULL)
 
993
    reloc_entry->address += input_section->output_offset;
 
994
 
 
995
  return ret;
 
996
}
 
997
 
 
998
/* Do a RELLO relocation.  This is a straightforward 16 bit PC
 
999
   relative relocation; this function exists in order to do the RELHI
 
1000
   relocation described above.  */
 
1001
 
 
1002
static bfd_reloc_status_type
 
1003
mips_rello_reloc (abfd,
 
1004
                  reloc_entry,
 
1005
                  symbol,
 
1006
                  data,
 
1007
                  input_section,
 
1008
                  output_bfd,
 
1009
                  error_message)
 
1010
     bfd *abfd;
 
1011
     arelent *reloc_entry;
 
1012
     asymbol *symbol;
 
1013
     PTR data;
 
1014
     asection *input_section;
 
1015
     bfd *output_bfd;
 
1016
     char **error_message;
 
1017
{
 
1018
  if (mips_relhi_list != NULL)
 
1019
    {
 
1020
      struct mips_hi *l;
 
1021
 
 
1022
      l = mips_relhi_list;
 
1023
      while (l != NULL)
 
1024
        {
 
1025
          unsigned long insn;
 
1026
          unsigned long val;
 
1027
          unsigned long vallo;
 
1028
          struct mips_hi *next;
 
1029
 
 
1030
          /* Do the RELHI relocation.  Note that we actually don't
 
1031
             need to know anything about the RELLO itself, except
 
1032
             where to find the low 16 bits of the addend needed by the
 
1033
             RELHI.  */
 
1034
          insn = bfd_get_32 (abfd, l->addr);
 
1035
          vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address)
 
1036
                   & 0xffff);
 
1037
          val = ((insn & 0xffff) << 16) + vallo;
 
1038
          val += l->addend;
 
1039
 
 
1040
          /* If the symbol is defined, make val PC relative.  If the
 
1041
             symbol is not defined we don't want to do this, because
 
1042
             we don't want the value in the object file to incorporate
 
1043
             the address of the reloc.  */
 
1044
          if (! bfd_is_und_section (bfd_get_section (symbol))
 
1045
              && ! bfd_is_com_section (bfd_get_section (symbol)))
 
1046
            val -= (input_section->output_section->vma
 
1047
                    + input_section->output_offset
 
1048
                    + reloc_entry->address);
 
1049
 
 
1050
          /* The low order 16 bits are always treated as a signed
 
1051
             value.  Therefore, a negative value in the low order bits
 
1052
             requires an adjustment in the high order bits.  We need
 
1053
             to make this adjustment in two ways: once for the bits we
 
1054
             took from the data, and once for the bits we are putting
 
1055
             back in to the data.  */
 
1056
          if ((vallo & 0x8000) != 0)
 
1057
            val -= 0x10000;
 
1058
          if ((val & 0x8000) != 0)
 
1059
            val += 0x10000;
 
1060
 
 
1061
          insn = (insn &~ (unsigned) 0xffff) | ((val >> 16) & 0xffff);
 
1062
          bfd_put_32 (abfd, (bfd_vma) insn, l->addr);
 
1063
 
 
1064
          next = l->next;
 
1065
          free (l);
 
1066
          l = next;
 
1067
        }
 
1068
 
 
1069
      mips_relhi_list = NULL;
 
1070
    }
 
1071
 
 
1072
  /* If this is a reloc against a section symbol, then it is correct
 
1073
     in the object file.  The only time we want to change this case is
 
1074
     when we are relaxing, and that is handled entirely by
 
1075
     mips_relocate_section and never calls this function.  */
 
1076
  if ((symbol->flags & BSF_SECTION_SYM) != 0)
 
1077
    {
 
1078
      if (output_bfd != (bfd *) NULL)
 
1079
        reloc_entry->address += input_section->output_offset;
 
1080
      return bfd_reloc_ok;
 
1081
    }
 
1082
 
 
1083
  /* bfd_perform_relocation does not handle pcrel_offset relocations
 
1084
     correctly when generating a relocateable file, so handle them
 
1085
     directly here.  */
 
1086
  if (output_bfd != (bfd *) NULL)
 
1087
    {
 
1088
      reloc_entry->address += input_section->output_offset;
 
1089
      return bfd_reloc_ok;
 
1090
    }
 
1091
 
 
1092
  /* Now do the RELLO reloc in the usual way.  */
 
1093
  return mips_generic_reloc (abfd, reloc_entry, symbol, data,
 
1094
                              input_section, output_bfd, error_message);
 
1095
}
 
1096
 
 
1097
/* This is the special function for the MIPS_R_SWITCH reloc.  This
 
1098
   special reloc is normally correct in the object file, and only
 
1099
   requires special handling when relaxing.  We don't want
 
1100
   bfd_perform_relocation to tamper with it at all.  */
 
1101
 
 
1102
static bfd_reloc_status_type
 
1103
mips_switch_reloc (abfd,
 
1104
                   reloc_entry,
 
1105
                   symbol,
 
1106
                   data,
 
1107
                   input_section,
 
1108
                   output_bfd,
 
1109
                   error_message)
 
1110
     bfd *abfd ATTRIBUTE_UNUSED;
 
1111
     arelent *reloc_entry ATTRIBUTE_UNUSED;
 
1112
     asymbol *symbol ATTRIBUTE_UNUSED;
 
1113
     PTR data ATTRIBUTE_UNUSED;
 
1114
     asection *input_section ATTRIBUTE_UNUSED;
 
1115
     bfd *output_bfd ATTRIBUTE_UNUSED;
 
1116
     char **error_message ATTRIBUTE_UNUSED;
 
1117
{
 
1118
  return bfd_reloc_ok;
 
1119
}
 
1120
 
 
1121
/* Get the howto structure for a generic reloc type.  */
 
1122
 
 
1123
static reloc_howto_type *
 
1124
mips_bfd_reloc_type_lookup (abfd, code)
 
1125
     bfd *abfd ATTRIBUTE_UNUSED;
 
1126
     bfd_reloc_code_real_type code;
 
1127
{
 
1128
  int mips_type;
 
1129
 
 
1130
  switch (code)
 
1131
    {
 
1132
    case BFD_RELOC_16:
 
1133
      mips_type = MIPS_R_REFHALF;
 
1134
      break;
 
1135
    case BFD_RELOC_32:
 
1136
    case BFD_RELOC_CTOR:
 
1137
      mips_type = MIPS_R_REFWORD;
 
1138
      break;
 
1139
    case BFD_RELOC_MIPS_JMP:
 
1140
      mips_type = MIPS_R_JMPADDR;
 
1141
      break;
 
1142
    case BFD_RELOC_HI16_S:
 
1143
      mips_type = MIPS_R_REFHI;
 
1144
      break;
 
1145
    case BFD_RELOC_LO16:
 
1146
      mips_type = MIPS_R_REFLO;
 
1147
      break;
 
1148
    case BFD_RELOC_GPREL16:
 
1149
      mips_type = MIPS_R_GPREL;
 
1150
      break;
 
1151
    case BFD_RELOC_MIPS_LITERAL:
 
1152
      mips_type = MIPS_R_LITERAL;
 
1153
      break;
 
1154
    case BFD_RELOC_16_PCREL_S2:
 
1155
      mips_type = MIPS_R_PCREL16;
 
1156
      break;
 
1157
    case BFD_RELOC_PCREL_HI16_S:
 
1158
      mips_type = MIPS_R_RELHI;
 
1159
      break;
 
1160
    case BFD_RELOC_PCREL_LO16:
 
1161
      mips_type = MIPS_R_RELLO;
 
1162
      break;
 
1163
    case BFD_RELOC_GPREL32:
 
1164
      mips_type = MIPS_R_SWITCH;
 
1165
      break;
 
1166
    default:
 
1167
      return (reloc_howto_type *) NULL;
 
1168
    }
 
1169
 
 
1170
  return &mips_howto_table[mips_type];
 
1171
}
 
1172
 
 
1173
/* A helper routine for mips_relocate_section which handles the REFHI
 
1174
   and RELHI relocations.  The REFHI relocation must be followed by a
 
1175
   REFLO relocation (and RELHI by a RELLO), and the addend used is
 
1176
   formed from the addends of both instructions.  */
 
1177
 
 
1178
static void
 
1179
mips_relocate_hi (refhi, reflo, input_bfd, input_section, contents, adjust,
 
1180
                  relocation, pcrel)
 
1181
     struct internal_reloc *refhi;
 
1182
     struct internal_reloc *reflo;
 
1183
     bfd *input_bfd;
 
1184
     asection *input_section;
 
1185
     bfd_byte *contents;
 
1186
     size_t adjust;
 
1187
     bfd_vma relocation;
 
1188
     boolean pcrel;
 
1189
{
 
1190
  unsigned long insn;
 
1191
  unsigned long val;
 
1192
  unsigned long vallo;
 
1193
 
 
1194
  if (refhi == NULL)
 
1195
    return;
 
1196
 
 
1197
  insn = bfd_get_32 (input_bfd,
 
1198
                     contents + adjust + refhi->r_vaddr - input_section->vma);
 
1199
  if (reflo == NULL)
 
1200
    vallo = 0;
 
1201
  else
 
1202
    vallo = (bfd_get_32 (input_bfd,
 
1203
                         contents + adjust + reflo->r_vaddr - input_section->vma)
 
1204
             & 0xffff);
 
1205
 
 
1206
  val = ((insn & 0xffff) << 16) + vallo;
 
1207
  val += relocation;
 
1208
 
 
1209
  /* The low order 16 bits are always treated as a signed value.
 
1210
     Therefore, a negative value in the low order bits requires an
 
1211
     adjustment in the high order bits.  We need to make this
 
1212
     adjustment in two ways: once for the bits we took from the data,
 
1213
     and once for the bits we are putting back in to the data.  */
 
1214
  if ((vallo & 0x8000) != 0)
 
1215
    val -= 0x10000;
 
1216
 
 
1217
  if (pcrel)
 
1218
    val -= (input_section->output_section->vma
 
1219
            + input_section->output_offset
 
1220
            + (reflo->r_vaddr - input_section->vma + adjust));
 
1221
 
 
1222
  if ((val & 0x8000) != 0)
 
1223
    val += 0x10000;
 
1224
 
 
1225
  insn = (insn &~ (unsigned) 0xffff) | ((val >> 16) & 0xffff);
 
1226
  bfd_put_32 (input_bfd, (bfd_vma) insn,
 
1227
              contents + adjust + refhi->r_vaddr - input_section->vma);
 
1228
}
 
1229
 
 
1230
/* Relocate a section while linking a MIPS ECOFF file.  */
 
1231
 
 
1232
static boolean
 
1233
mips_relocate_section (output_bfd, info, input_bfd, input_section,
 
1234
                       contents, external_relocs)
 
1235
     bfd *output_bfd;
 
1236
     struct bfd_link_info *info;
 
1237
     bfd *input_bfd;
 
1238
     asection *input_section;
 
1239
     bfd_byte *contents;
 
1240
     PTR external_relocs;
 
1241
{
 
1242
  asection **symndx_to_section;
 
1243
  struct ecoff_link_hash_entry **sym_hashes;
 
1244
  bfd_vma gp;
 
1245
  boolean gp_undefined;
 
1246
  size_t adjust;
 
1247
  long *offsets;
 
1248
  struct external_reloc *ext_rel;
 
1249
  struct external_reloc *ext_rel_end;
 
1250
  unsigned int i;
 
1251
  boolean got_lo;
 
1252
  struct internal_reloc lo_int_rel;
 
1253
  bfd_size_type amt;
 
1254
 
 
1255
  BFD_ASSERT (input_bfd->xvec->byteorder
 
1256
              == output_bfd->xvec->byteorder);
 
1257
 
 
1258
  /* We keep a table mapping the symndx found in an internal reloc to
 
1259
     the appropriate section.  This is faster than looking up the
 
1260
     section by name each time.  */
 
1261
  symndx_to_section = ecoff_data (input_bfd)->symndx_to_section;
 
1262
  if (symndx_to_section == (asection **) NULL)
 
1263
    {
 
1264
      amt = NUM_RELOC_SECTIONS * sizeof (asection *);
 
1265
      symndx_to_section = (asection **) bfd_alloc (input_bfd, amt);
 
1266
      if (!symndx_to_section)
 
1267
        return false;
 
1268
 
 
1269
      symndx_to_section[RELOC_SECTION_NONE] = NULL;
 
1270
      symndx_to_section[RELOC_SECTION_TEXT] =
 
1271
        bfd_get_section_by_name (input_bfd, ".text");
 
1272
      symndx_to_section[RELOC_SECTION_RDATA] =
 
1273
        bfd_get_section_by_name (input_bfd, ".rdata");
 
1274
      symndx_to_section[RELOC_SECTION_DATA] =
 
1275
        bfd_get_section_by_name (input_bfd, ".data");
 
1276
      symndx_to_section[RELOC_SECTION_SDATA] =
 
1277
        bfd_get_section_by_name (input_bfd, ".sdata");
 
1278
      symndx_to_section[RELOC_SECTION_SBSS] =
 
1279
        bfd_get_section_by_name (input_bfd, ".sbss");
 
1280
      symndx_to_section[RELOC_SECTION_BSS] =
 
1281
        bfd_get_section_by_name (input_bfd, ".bss");
 
1282
      symndx_to_section[RELOC_SECTION_INIT] =
 
1283
        bfd_get_section_by_name (input_bfd, ".init");
 
1284
      symndx_to_section[RELOC_SECTION_LIT8] =
 
1285
        bfd_get_section_by_name (input_bfd, ".lit8");
 
1286
      symndx_to_section[RELOC_SECTION_LIT4] =
 
1287
        bfd_get_section_by_name (input_bfd, ".lit4");
 
1288
      symndx_to_section[RELOC_SECTION_XDATA] = NULL;
 
1289
      symndx_to_section[RELOC_SECTION_PDATA] = NULL;
 
1290
      symndx_to_section[RELOC_SECTION_FINI] =
 
1291
        bfd_get_section_by_name (input_bfd, ".fini");
 
1292
      symndx_to_section[RELOC_SECTION_LITA] = NULL;
 
1293
      symndx_to_section[RELOC_SECTION_ABS] = NULL;
 
1294
 
 
1295
      ecoff_data (input_bfd)->symndx_to_section = symndx_to_section;
 
1296
    }
 
1297
 
 
1298
  sym_hashes = ecoff_data (input_bfd)->sym_hashes;
 
1299
 
 
1300
  gp = _bfd_get_gp_value (output_bfd);
 
1301
  if (gp == 0)
 
1302
    gp_undefined = true;
 
1303
  else
 
1304
    gp_undefined = false;
 
1305
 
 
1306
  got_lo = false;
 
1307
 
 
1308
  adjust = 0;
 
1309
 
 
1310
  if (ecoff_section_data (input_bfd, input_section) == NULL)
 
1311
    offsets = NULL;
 
1312
  else
 
1313
    offsets = ecoff_section_data (input_bfd, input_section)->offsets;
 
1314
 
 
1315
  ext_rel = (struct external_reloc *) external_relocs;
 
1316
  ext_rel_end = ext_rel + input_section->reloc_count;
 
1317
  for (i = 0; ext_rel < ext_rel_end; ext_rel++, i++)
 
1318
    {
 
1319
      struct internal_reloc int_rel;
 
1320
      boolean use_lo = false;
 
1321
      bfd_vma addend;
 
1322
      reloc_howto_type *howto;
 
1323
      struct ecoff_link_hash_entry *h = NULL;
 
1324
      asection *s = NULL;
 
1325
      bfd_vma relocation;
 
1326
      bfd_reloc_status_type r;
 
1327
 
 
1328
      if (! got_lo)
 
1329
        mips_ecoff_swap_reloc_in (input_bfd, (PTR) ext_rel, &int_rel);
 
1330
      else
 
1331
        {
 
1332
          int_rel = lo_int_rel;
 
1333
          got_lo = false;
 
1334
        }
 
1335
 
 
1336
      BFD_ASSERT (int_rel.r_type
 
1337
                  < sizeof mips_howto_table / sizeof mips_howto_table[0]);
 
1338
 
 
1339
      /* The REFHI and RELHI relocs requires special handling.  they
 
1340
         must be followed by a REFLO or RELLO reloc, respectively, and
 
1341
         the addend is formed from both relocs.  */
 
1342
      if (int_rel.r_type == MIPS_R_REFHI
 
1343
          || int_rel.r_type == MIPS_R_RELHI)
 
1344
        {
 
1345
          struct external_reloc *lo_ext_rel;
 
1346
 
 
1347
          /* As a GNU extension, permit an arbitrary number of REFHI
 
1348
             or RELHI relocs before the REFLO or RELLO reloc.  This
 
1349
             permits gcc to emit the HI and LO relocs itself.  */
 
1350
          for (lo_ext_rel = ext_rel + 1;
 
1351
               lo_ext_rel < ext_rel_end;
 
1352
               lo_ext_rel++)
 
1353
            {
 
1354
              mips_ecoff_swap_reloc_in (input_bfd, (PTR) lo_ext_rel,
 
1355
                                        &lo_int_rel);
 
1356
              if (lo_int_rel.r_type != int_rel.r_type)
 
1357
                break;
 
1358
            }
 
1359
 
 
1360
          if (lo_ext_rel < ext_rel_end
 
1361
              && (lo_int_rel.r_type
 
1362
                  == (int_rel.r_type == MIPS_R_REFHI
 
1363
                      ? MIPS_R_REFLO
 
1364
                      : MIPS_R_RELLO))
 
1365
              && int_rel.r_extern == lo_int_rel.r_extern
 
1366
              && int_rel.r_symndx == lo_int_rel.r_symndx)
 
1367
            {
 
1368
              use_lo = true;
 
1369
              if (lo_ext_rel == ext_rel + 1)
 
1370
                got_lo = true;
 
1371
            }
 
1372
        }
 
1373
 
 
1374
      howto = &mips_howto_table[int_rel.r_type];
 
1375
 
 
1376
      /* The SWITCH reloc must be handled specially.  This reloc is
 
1377
         marks the location of a difference between two portions of an
 
1378
         object file.  The symbol index does not reference a symbol,
 
1379
         but is actually the offset from the reloc to the subtrahend
 
1380
         of the difference.  This reloc is correct in the object file,
 
1381
         and needs no further adjustment, unless we are relaxing.  If
 
1382
         we are relaxing, we may have to add in an offset.  Since no
 
1383
         symbols are involved in this reloc, we handle it completely
 
1384
         here.  */
 
1385
      if (int_rel.r_type == MIPS_R_SWITCH)
 
1386
        {
 
1387
          if (offsets != NULL
 
1388
              && offsets[i] != 0)
 
1389
            {
 
1390
              r = _bfd_relocate_contents (howto, input_bfd,
 
1391
                                          (bfd_vma) offsets[i],
 
1392
                                          (contents
 
1393
                                           + adjust
 
1394
                                           + int_rel.r_vaddr
 
1395
                                           - input_section->vma));
 
1396
              BFD_ASSERT (r == bfd_reloc_ok);
 
1397
            }
 
1398
 
 
1399
          continue;
 
1400
        }
 
1401
 
 
1402
      if (int_rel.r_extern)
 
1403
        {
 
1404
          h = sym_hashes[int_rel.r_symndx];
 
1405
          /* If h is NULL, that means that there is a reloc against an
 
1406
             external symbol which we thought was just a debugging
 
1407
             symbol.  This should not happen.  */
 
1408
          if (h == (struct ecoff_link_hash_entry *) NULL)
 
1409
            abort ();
 
1410
        }
 
1411
      else
 
1412
        {
 
1413
          if (int_rel.r_symndx < 0 || int_rel.r_symndx >= NUM_RELOC_SECTIONS)
 
1414
            s = NULL;
 
1415
          else
 
1416
            s = symndx_to_section[int_rel.r_symndx];
 
1417
 
 
1418
          if (s == (asection *) NULL)
 
1419
            abort ();
 
1420
        }
 
1421
 
 
1422
      /* The GPREL reloc uses an addend: the difference in the GP
 
1423
         values.  */
 
1424
      if (int_rel.r_type != MIPS_R_GPREL
 
1425
          && int_rel.r_type != MIPS_R_LITERAL)
 
1426
        addend = 0;
 
1427
      else
 
1428
        {
 
1429
          if (gp_undefined)
 
1430
            {
 
1431
              if (! ((*info->callbacks->reloc_dangerous)
 
1432
                     (info, _("GP relative relocation used when GP not defined"),
 
1433
                      input_bfd, input_section,
 
1434
                      int_rel.r_vaddr - input_section->vma)))
 
1435
                return false;
 
1436
              /* Only give the error once per link.  */
 
1437
              gp = 4;
 
1438
              _bfd_set_gp_value (output_bfd, gp);
 
1439
              gp_undefined = false;
 
1440
            }
 
1441
          if (! int_rel.r_extern)
 
1442
            {
 
1443
              /* This is a relocation against a section.  The current
 
1444
                 addend in the instruction is the difference between
 
1445
                 INPUT_SECTION->vma and the GP value of INPUT_BFD.  We
 
1446
                 must change this to be the difference between the
 
1447
                 final definition (which will end up in RELOCATION)
 
1448
                 and the GP value of OUTPUT_BFD (which is in GP).  */
 
1449
              addend = ecoff_data (input_bfd)->gp - gp;
 
1450
            }
 
1451
          else if (! info->relocateable
 
1452
                   || h->root.type == bfd_link_hash_defined
 
1453
                   || h->root.type == bfd_link_hash_defweak)
 
1454
            {
 
1455
              /* This is a relocation against a defined symbol.  The
 
1456
                 current addend in the instruction is simply the
 
1457
                 desired offset into the symbol (normally zero).  We
 
1458
                 are going to change this into a relocation against a
 
1459
                 defined symbol, so we want the instruction to hold
 
1460
                 the difference between the final definition of the
 
1461
                 symbol (which will end up in RELOCATION) and the GP
 
1462
                 value of OUTPUT_BFD (which is in GP).  */
 
1463
              addend = - gp;
 
1464
            }
 
1465
          else
 
1466
            {
 
1467
              /* This is a relocation against an undefined or common
 
1468
                 symbol.  The current addend in the instruction is
 
1469
                 simply the desired offset into the symbol (normally
 
1470
                 zero).  We are generating relocateable output, and we
 
1471
                 aren't going to define this symbol, so we just leave
 
1472
                 the instruction alone.  */
 
1473
              addend = 0;
 
1474
            }
 
1475
        }
 
1476
 
 
1477
      /* If we are relaxing, mips_relax_section may have set
 
1478
         offsets[i] to some value.  A value of 1 means we must expand
 
1479
         a PC relative branch into a multi-instruction of sequence,
 
1480
         and any other value is an addend.  */
 
1481
      if (offsets != NULL
 
1482
          && offsets[i] != 0)
 
1483
        {
 
1484
          BFD_ASSERT (! info->relocateable);
 
1485
          BFD_ASSERT (int_rel.r_type == MIPS_R_PCREL16
 
1486
                      || int_rel.r_type == MIPS_R_RELHI
 
1487
                      || int_rel.r_type == MIPS_R_RELLO);
 
1488
          if (offsets[i] != 1)
 
1489
            addend += offsets[i];
 
1490
          else
 
1491
            {
 
1492
              bfd_byte *here;
 
1493
 
 
1494
              BFD_ASSERT (int_rel.r_extern
 
1495
                          && int_rel.r_type == MIPS_R_PCREL16);
 
1496
 
 
1497
              /* Move the rest of the instructions up.  */
 
1498
              here = (contents
 
1499
                      + adjust
 
1500
                      + int_rel.r_vaddr
 
1501
                      - input_section->vma);
 
1502
              memmove (here + PCREL16_EXPANSION_ADJUSTMENT, here,
 
1503
                       (size_t) (input_section->_raw_size
 
1504
                                 - (int_rel.r_vaddr - input_section->vma)));
 
1505
 
 
1506
              /* Generate the new instructions.  */
 
1507
              if (! mips_relax_pcrel16 (info, input_bfd, input_section,
 
1508
                                        h, here,
 
1509
                                        (input_section->output_section->vma
 
1510
                                         + input_section->output_offset
 
1511
                                         + (int_rel.r_vaddr
 
1512
                                            - input_section->vma)
 
1513
                                         + adjust)))
 
1514
                return false;
 
1515
 
 
1516
              /* We must adjust everything else up a notch.  */
 
1517
              adjust += PCREL16_EXPANSION_ADJUSTMENT;
 
1518
 
 
1519
              /* mips_relax_pcrel16 handles all the details of this
 
1520
                 relocation.  */
 
1521
              continue;
 
1522
            }
 
1523
        }
 
1524
 
 
1525
      /* If we are relaxing, and this is a reloc against the .text
 
1526
         segment, we may need to adjust it if some branches have been
 
1527
         expanded.  The reloc types which are likely to occur in the
 
1528
         .text section are handled efficiently by mips_relax_section,
 
1529
         and thus do not need to be handled here.  */
 
1530
      if (ecoff_data (input_bfd)->debug_info.adjust != NULL
 
1531
          && ! int_rel.r_extern
 
1532
          && int_rel.r_symndx == RELOC_SECTION_TEXT
 
1533
          && (strcmp (bfd_get_section_name (input_bfd, input_section),
 
1534
                      ".text") != 0
 
1535
              || (int_rel.r_type != MIPS_R_PCREL16
 
1536
                  && int_rel.r_type != MIPS_R_SWITCH
 
1537
                  && int_rel.r_type != MIPS_R_RELHI
 
1538
                  && int_rel.r_type != MIPS_R_RELLO)))
 
1539
        {
 
1540
          bfd_vma adr;
 
1541
          struct ecoff_value_adjust *a;
 
1542
 
 
1543
          /* We need to get the addend so that we know whether we need
 
1544
             to adjust the address.  */
 
1545
          BFD_ASSERT (int_rel.r_type == MIPS_R_REFWORD);
 
1546
 
 
1547
          adr = bfd_get_32 (input_bfd,
 
1548
                            (contents
 
1549
                             + adjust
 
1550
                             + int_rel.r_vaddr
 
1551
                             - input_section->vma));
 
1552
 
 
1553
          for (a = ecoff_data (input_bfd)->debug_info.adjust;
 
1554
               a != (struct ecoff_value_adjust *) NULL;
 
1555
               a = a->next)
 
1556
            {
 
1557
              if (adr >= a->start && adr < a->end)
 
1558
                addend += a->adjust;
 
1559
            }
 
1560
        }
 
1561
 
 
1562
      if (info->relocateable)
 
1563
        {
 
1564
          /* We are generating relocateable output, and must convert
 
1565
             the existing reloc.  */
 
1566
          if (int_rel.r_extern)
 
1567
            {
 
1568
              if ((h->root.type == bfd_link_hash_defined
 
1569
                   || h->root.type == bfd_link_hash_defweak)
 
1570
                  && ! bfd_is_abs_section (h->root.u.def.section))
 
1571
                {
 
1572
                  const char *name;
 
1573
 
 
1574
                  /* This symbol is defined in the output.  Convert
 
1575
                     the reloc from being against the symbol to being
 
1576
                     against the section.  */
 
1577
 
 
1578
                  /* Clear the r_extern bit.  */
 
1579
                  int_rel.r_extern = 0;
 
1580
 
 
1581
                  /* Compute a new r_symndx value.  */
 
1582
                  s = h->root.u.def.section;
 
1583
                  name = bfd_get_section_name (output_bfd,
 
1584
                                               s->output_section);
 
1585
 
 
1586
                  int_rel.r_symndx = -1;
 
1587
                  switch (name[1])
 
1588
                    {
 
1589
                    case 'b':
 
1590
                      if (strcmp (name, ".bss") == 0)
 
1591
                        int_rel.r_symndx = RELOC_SECTION_BSS;
 
1592
                      break;
 
1593
                    case 'd':
 
1594
                      if (strcmp (name, ".data") == 0)
 
1595
                        int_rel.r_symndx = RELOC_SECTION_DATA;
 
1596
                      break;
 
1597
                    case 'f':
 
1598
                      if (strcmp (name, ".fini") == 0)
 
1599
                        int_rel.r_symndx = RELOC_SECTION_FINI;
 
1600
                      break;
 
1601
                    case 'i':
 
1602
                      if (strcmp (name, ".init") == 0)
 
1603
                        int_rel.r_symndx = RELOC_SECTION_INIT;
 
1604
                      break;
 
1605
                    case 'l':
 
1606
                      if (strcmp (name, ".lit8") == 0)
 
1607
                        int_rel.r_symndx = RELOC_SECTION_LIT8;
 
1608
                      else if (strcmp (name, ".lit4") == 0)
 
1609
                        int_rel.r_symndx = RELOC_SECTION_LIT4;
 
1610
                      break;
 
1611
                    case 'r':
 
1612
                      if (strcmp (name, ".rdata") == 0)
 
1613
                        int_rel.r_symndx = RELOC_SECTION_RDATA;
 
1614
                      break;
 
1615
                    case 's':
 
1616
                      if (strcmp (name, ".sdata") == 0)
 
1617
                        int_rel.r_symndx = RELOC_SECTION_SDATA;
 
1618
                      else if (strcmp (name, ".sbss") == 0)
 
1619
                        int_rel.r_symndx = RELOC_SECTION_SBSS;
 
1620
                      break;
 
1621
                    case 't':
 
1622
                      if (strcmp (name, ".text") == 0)
 
1623
                        int_rel.r_symndx = RELOC_SECTION_TEXT;
 
1624
                      break;
 
1625
                    }
 
1626
 
 
1627
                  if (int_rel.r_symndx == -1)
 
1628
                    abort ();
 
1629
 
 
1630
                  /* Add the section VMA and the symbol value.  */
 
1631
                  relocation = (h->root.u.def.value
 
1632
                                + s->output_section->vma
 
1633
                                + s->output_offset);
 
1634
 
 
1635
                  /* For a PC relative relocation, the object file
 
1636
                     currently holds just the addend.  We must adjust
 
1637
                     by the address to get the right value.  */
 
1638
                  if (howto->pc_relative)
 
1639
                    {
 
1640
                      relocation -= int_rel.r_vaddr - input_section->vma;
 
1641
 
 
1642
                      /* If we are converting a RELHI or RELLO reloc
 
1643
                         from being against an external symbol to
 
1644
                         being against a section, we must put a
 
1645
                         special value into the r_offset field.  This
 
1646
                         value is the old addend.  The r_offset for
 
1647
                         both the RELHI and RELLO relocs are the same,
 
1648
                         and we set both when we see RELHI.  */
 
1649
                      if (int_rel.r_type == MIPS_R_RELHI)
 
1650
                        {
 
1651
                          long addhi, addlo;
 
1652
 
 
1653
                          addhi = bfd_get_32 (input_bfd,
 
1654
                                              (contents
 
1655
                                               + adjust
 
1656
                                               + int_rel.r_vaddr
 
1657
                                               - input_section->vma));
 
1658
                          addhi &= 0xffff;
 
1659
                          if (addhi & 0x8000)
 
1660
                            addhi -= 0x10000;
 
1661
                          addhi <<= 16;
 
1662
 
 
1663
                          if (! use_lo)
 
1664
                            addlo = 0;
 
1665
                          else
 
1666
                            {
 
1667
                              addlo = bfd_get_32 (input_bfd,
 
1668
                                                  (contents
 
1669
                                                   + adjust
 
1670
                                                   + lo_int_rel.r_vaddr
 
1671
                                                   - input_section->vma));
 
1672
                              addlo &= 0xffff;
 
1673
                              if (addlo & 0x8000)
 
1674
                                addlo -= 0x10000;
 
1675
 
 
1676
                              lo_int_rel.r_offset = addhi + addlo;
 
1677
                            }
 
1678
 
 
1679
                          int_rel.r_offset = addhi + addlo;
 
1680
                        }
 
1681
                    }
 
1682
 
 
1683
                  h = NULL;
 
1684
                }
 
1685
              else
 
1686
                {
 
1687
                  /* Change the symndx value to the right one for the
 
1688
                     output BFD.  */
 
1689
                  int_rel.r_symndx = h->indx;
 
1690
                  if (int_rel.r_symndx == -1)
 
1691
                    {
 
1692
                      /* This symbol is not being written out.  */
 
1693
                      if (! ((*info->callbacks->unattached_reloc)
 
1694
                             (info, h->root.root.string, input_bfd,
 
1695
                              input_section,
 
1696
                              int_rel.r_vaddr - input_section->vma)))
 
1697
                        return false;
 
1698
                      int_rel.r_symndx = 0;
 
1699
                    }
 
1700
                  relocation = 0;
 
1701
                }
 
1702
            }
 
1703
          else
 
1704
            {
 
1705
              /* This is a relocation against a section.  Adjust the
 
1706
                 value by the amount the section moved.  */
 
1707
              relocation = (s->output_section->vma
 
1708
                            + s->output_offset
 
1709
                            - s->vma);
 
1710
            }
 
1711
 
 
1712
          relocation += addend;
 
1713
          addend = 0;
 
1714
 
 
1715
          /* Adjust a PC relative relocation by removing the reference
 
1716
             to the original address in the section and including the
 
1717
             reference to the new address.  However, external RELHI
 
1718
             and RELLO relocs are PC relative, but don't include any
 
1719
             reference to the address.  The addend is merely an
 
1720
             addend.  */
 
1721
          if (howto->pc_relative
 
1722
              && (! int_rel.r_extern
 
1723
                  || (int_rel.r_type != MIPS_R_RELHI
 
1724
                      && int_rel.r_type != MIPS_R_RELLO)))
 
1725
            relocation -= (input_section->output_section->vma
 
1726
                           + input_section->output_offset
 
1727
                           - input_section->vma);
 
1728
 
 
1729
          /* Adjust the contents.  */
 
1730
          if (relocation == 0)
 
1731
            r = bfd_reloc_ok;
 
1732
          else
 
1733
            {
 
1734
              if (int_rel.r_type != MIPS_R_REFHI
 
1735
                  && int_rel.r_type != MIPS_R_RELHI)
 
1736
                r = _bfd_relocate_contents (howto, input_bfd, relocation,
 
1737
                                            (contents
 
1738
                                             + adjust
 
1739
                                             + int_rel.r_vaddr
 
1740
                                             - input_section->vma));
 
1741
              else
 
1742
                {
 
1743
                  mips_relocate_hi (&int_rel,
 
1744
                                    use_lo ? &lo_int_rel : NULL,
 
1745
                                    input_bfd, input_section, contents,
 
1746
                                    adjust, relocation,
 
1747
                                    int_rel.r_type == MIPS_R_RELHI);
 
1748
                  r = bfd_reloc_ok;
 
1749
                }
 
1750
            }
 
1751
 
 
1752
          /* Adjust the reloc address.  */
 
1753
          int_rel.r_vaddr += (input_section->output_section->vma
 
1754
                              + input_section->output_offset
 
1755
                              - input_section->vma);
 
1756
 
 
1757
          /* Save the changed reloc information.  */
 
1758
          mips_ecoff_swap_reloc_out (input_bfd, &int_rel, (PTR) ext_rel);
 
1759
        }
 
1760
      else
 
1761
        {
 
1762
          /* We are producing a final executable.  */
 
1763
          if (int_rel.r_extern)
 
1764
            {
 
1765
              /* This is a reloc against a symbol.  */
 
1766
              if (h->root.type == bfd_link_hash_defined
 
1767
                  || h->root.type == bfd_link_hash_defweak)
 
1768
                {
 
1769
                  asection *hsec;
 
1770
 
 
1771
                  hsec = h->root.u.def.section;
 
1772
                  relocation = (h->root.u.def.value
 
1773
                                + hsec->output_section->vma
 
1774
                                + hsec->output_offset);
 
1775
                }
 
1776
              else
 
1777
                {
 
1778
                  if (! ((*info->callbacks->undefined_symbol)
 
1779
                         (info, h->root.root.string, input_bfd,
 
1780
                          input_section,
 
1781
                          int_rel.r_vaddr - input_section->vma, true)))
 
1782
                    return false;
 
1783
                  relocation = 0;
 
1784
                }
 
1785
            }
 
1786
          else
 
1787
            {
 
1788
              /* This is a reloc against a section.  */
 
1789
              relocation = (s->output_section->vma
 
1790
                            + s->output_offset
 
1791
                            - s->vma);
 
1792
 
 
1793
              /* A PC relative reloc is already correct in the object
 
1794
                 file.  Make it look like a pcrel_offset relocation by
 
1795
                 adding in the start address.  */
 
1796
              if (howto->pc_relative)
 
1797
                {
 
1798
                  if (int_rel.r_type != MIPS_R_RELHI || ! use_lo)
 
1799
                    relocation += int_rel.r_vaddr + adjust;
 
1800
                  else
 
1801
                    relocation += lo_int_rel.r_vaddr + adjust;
 
1802
                }
 
1803
            }
 
1804
 
 
1805
          if (int_rel.r_type != MIPS_R_REFHI
 
1806
              && int_rel.r_type != MIPS_R_RELHI)
 
1807
            r = _bfd_final_link_relocate (howto,
 
1808
                                          input_bfd,
 
1809
                                          input_section,
 
1810
                                          contents,
 
1811
                                          (int_rel.r_vaddr
 
1812
                                           - input_section->vma
 
1813
                                           + adjust),
 
1814
                                          relocation,
 
1815
                                          addend);
 
1816
          else
 
1817
            {
 
1818
              mips_relocate_hi (&int_rel,
 
1819
                                use_lo ? &lo_int_rel : NULL,
 
1820
                                input_bfd, input_section, contents, adjust,
 
1821
                                relocation,
 
1822
                                int_rel.r_type == MIPS_R_RELHI);
 
1823
              r = bfd_reloc_ok;
 
1824
            }
 
1825
        }
 
1826
 
 
1827
      /* MIPS_R_JMPADDR requires peculiar overflow detection.  The
 
1828
         instruction provides a 28 bit address (the two lower bits are
 
1829
         implicit zeroes) which is combined with the upper four bits
 
1830
         of the instruction address.  */
 
1831
      if (r == bfd_reloc_ok
 
1832
          && int_rel.r_type == MIPS_R_JMPADDR
 
1833
          && (((relocation
 
1834
                + addend
 
1835
                + (int_rel.r_extern ? 0 : s->vma))
 
1836
               & 0xf0000000)
 
1837
              != ((input_section->output_section->vma
 
1838
                   + input_section->output_offset
 
1839
                   + (int_rel.r_vaddr - input_section->vma)
 
1840
                   + adjust)
 
1841
                  & 0xf0000000)))
 
1842
        r = bfd_reloc_overflow;
 
1843
 
 
1844
      if (r != bfd_reloc_ok)
 
1845
        {
 
1846
          switch (r)
 
1847
            {
 
1848
            default:
 
1849
            case bfd_reloc_outofrange:
 
1850
              abort ();
 
1851
            case bfd_reloc_overflow:
 
1852
              {
 
1853
                const char *name;
 
1854
 
 
1855
                if (int_rel.r_extern)
 
1856
                  name = h->root.root.string;
 
1857
                else
 
1858
                  name = bfd_section_name (input_bfd, s);
 
1859
                if (! ((*info->callbacks->reloc_overflow)
 
1860
                       (info, name, howto->name, (bfd_vma) 0,
 
1861
                        input_bfd, input_section,
 
1862
                        int_rel.r_vaddr - input_section->vma)))
 
1863
                  return false;
 
1864
              }
 
1865
              break;
 
1866
            }
 
1867
        }
 
1868
    }
 
1869
 
 
1870
  return true;
 
1871
}
 
1872
 
 
1873
/* Read in the relocs for a section.  */
 
1874
 
 
1875
static boolean
 
1876
mips_read_relocs (abfd, sec)
 
1877
     bfd *abfd;
 
1878
     asection *sec;
 
1879
{
 
1880
  struct ecoff_section_tdata *section_tdata;
 
1881
  bfd_size_type amt;
 
1882
 
 
1883
  section_tdata = ecoff_section_data (abfd, sec);
 
1884
  if (section_tdata == (struct ecoff_section_tdata *) NULL)
 
1885
    {
 
1886
      amt = sizeof (struct ecoff_section_tdata);
 
1887
      sec->used_by_bfd = (PTR) bfd_alloc (abfd, amt);
 
1888
      if (sec->used_by_bfd == NULL)
 
1889
        return false;
 
1890
 
 
1891
      section_tdata = ecoff_section_data (abfd, sec);
 
1892
      section_tdata->external_relocs = NULL;
 
1893
      section_tdata->contents = NULL;
 
1894
      section_tdata->offsets = NULL;
 
1895
    }
 
1896
 
 
1897
  if (section_tdata->external_relocs == NULL)
 
1898
    {
 
1899
      amt = ecoff_backend (abfd)->external_reloc_size;
 
1900
      amt *= sec->reloc_count;
 
1901
      section_tdata->external_relocs = (PTR) bfd_alloc (abfd, amt);
 
1902
      if (section_tdata->external_relocs == NULL && amt != 0)
 
1903
        return false;
 
1904
 
 
1905
      if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0
 
1906
          || bfd_bread (section_tdata->external_relocs, amt, abfd) != amt)
 
1907
        return false;
 
1908
    }
 
1909
 
 
1910
  return true;
 
1911
}
 
1912
 
 
1913
/* Relax a section when linking a MIPS ECOFF file.  This is used for
 
1914
   embedded PIC code, which always uses PC relative branches which
 
1915
   only have an 18 bit range on MIPS.  If a branch is not in range, we
 
1916
   generate a long instruction sequence to compensate.  Each time we
 
1917
   find a branch to expand, we have to check all the others again to
 
1918
   make sure they are still in range.  This is slow, but it only has
 
1919
   to be done when -relax is passed to the linker.
 
1920
 
 
1921
   This routine figures out which branches need to expand; the actual
 
1922
   expansion is done in mips_relocate_section when the section
 
1923
   contents are relocated.  The information is stored in the offsets
 
1924
   field of the ecoff_section_tdata structure.  An offset of 1 means
 
1925
   that the branch must be expanded into a multi-instruction PC
 
1926
   relative branch (such an offset will only occur for a PC relative
 
1927
   branch to an external symbol).  Any other offset must be a multiple
 
1928
   of four, and is the amount to change the branch by (such an offset
 
1929
   will only occur for a PC relative branch within the same section).
 
1930
 
 
1931
   We do not modify the section relocs or contents themselves so that
 
1932
   if memory usage becomes an issue we can discard them and read them
 
1933
   again.  The only information we must save in memory between this
 
1934
   routine and the mips_relocate_section routine is the table of
 
1935
   offsets.  */
 
1936
 
 
1937
static boolean
 
1938
mips_relax_section (abfd, sec, info, again)
 
1939
     bfd *abfd;
 
1940
     asection *sec;
 
1941
     struct bfd_link_info *info;
 
1942
     boolean *again;
 
1943
{
 
1944
  struct ecoff_section_tdata *section_tdata;
 
1945
  bfd_byte *contents = NULL;
 
1946
  long *offsets;
 
1947
  struct external_reloc *ext_rel;
 
1948
  struct external_reloc *ext_rel_end;
 
1949
  unsigned int i;
 
1950
 
 
1951
  /* Assume we are not going to need another pass.  */
 
1952
  *again = false;
 
1953
 
 
1954
  /* If we are not generating an ECOFF file, this is much too
 
1955
     confusing to deal with.  */
 
1956
  if (info->hash->creator->flavour != bfd_get_flavour (abfd))
 
1957
    return true;
 
1958
 
 
1959
  /* If there are no relocs, there is nothing to do.  */
 
1960
  if (sec->reloc_count == 0)
 
1961
    return true;
 
1962
 
 
1963
  /* We are only interested in PC relative relocs, and why would there
 
1964
     ever be one from anything but the .text section?  */
 
1965
  if (strcmp (bfd_get_section_name (abfd, sec), ".text") != 0)
 
1966
    return true;
 
1967
 
 
1968
  /* Read in the relocs, if we haven't already got them.  */
 
1969
  section_tdata = ecoff_section_data (abfd, sec);
 
1970
  if (section_tdata == (struct ecoff_section_tdata *) NULL
 
1971
      || section_tdata->external_relocs == NULL)
 
1972
    {
 
1973
      if (! mips_read_relocs (abfd, sec))
 
1974
        goto error_return;
 
1975
      section_tdata = ecoff_section_data (abfd, sec);
 
1976
    }
 
1977
 
 
1978
  if (sec->_cooked_size == 0)
 
1979
    {
 
1980
      /* We must initialize _cooked_size only the first time we are
 
1981
         called.  */
 
1982
      sec->_cooked_size = sec->_raw_size;
 
1983
    }
 
1984
 
 
1985
  contents = section_tdata->contents;
 
1986
  offsets = section_tdata->offsets;
 
1987
 
 
1988
  /* Look for any external PC relative relocs.  Internal PC relative
 
1989
     relocs are already correct in the object file, so they certainly
 
1990
     can not overflow.  */
 
1991
  ext_rel = (struct external_reloc *) section_tdata->external_relocs;
 
1992
  ext_rel_end = ext_rel + sec->reloc_count;
 
1993
  for (i = 0; ext_rel < ext_rel_end; ext_rel++, i++)
 
1994
    {
 
1995
      struct internal_reloc int_rel;
 
1996
      struct ecoff_link_hash_entry *h;
 
1997
      asection *hsec;
 
1998
      bfd_signed_vma relocation;
 
1999
      struct external_reloc *adj_ext_rel;
 
2000
      unsigned int adj_i;
 
2001
      unsigned long ext_count;
 
2002
      struct ecoff_link_hash_entry **adj_h_ptr;
 
2003
      struct ecoff_link_hash_entry **adj_h_ptr_end;
 
2004
      struct ecoff_value_adjust *adjust;
 
2005
      bfd_size_type amt;
 
2006
 
 
2007
      /* If we have already expanded this reloc, we certainly don't
 
2008
         need to do it again.  */
 
2009
      if (offsets != (long *) NULL && offsets[i] == 1)
 
2010
        continue;
 
2011
 
 
2012
      /* Quickly check that this reloc is external PCREL16.  */
 
2013
      if (bfd_header_big_endian (abfd))
 
2014
        {
 
2015
          if ((ext_rel->r_bits[3] & RELOC_BITS3_EXTERN_BIG) == 0
 
2016
              || (((ext_rel->r_bits[3] & RELOC_BITS3_TYPE_BIG)
 
2017
                   >> RELOC_BITS3_TYPE_SH_BIG)
 
2018
                  != MIPS_R_PCREL16))
 
2019
            continue;
 
2020
        }
 
2021
      else
 
2022
        {
 
2023
          if ((ext_rel->r_bits[3] & RELOC_BITS3_EXTERN_LITTLE) == 0
 
2024
              || (((ext_rel->r_bits[3] & RELOC_BITS3_TYPE_LITTLE)
 
2025
                   >> RELOC_BITS3_TYPE_SH_LITTLE)
 
2026
                  != MIPS_R_PCREL16))
 
2027
            continue;
 
2028
        }
 
2029
 
 
2030
      mips_ecoff_swap_reloc_in (abfd, (PTR) ext_rel, &int_rel);
 
2031
 
 
2032
      h = ecoff_data (abfd)->sym_hashes[int_rel.r_symndx];
 
2033
      if (h == (struct ecoff_link_hash_entry *) NULL)
 
2034
        abort ();
 
2035
 
 
2036
      if (h->root.type != bfd_link_hash_defined
 
2037
          && h->root.type != bfd_link_hash_defweak)
 
2038
        {
 
2039
          /* Just ignore undefined symbols.  These will presumably
 
2040
             generate an error later in the link.  */
 
2041
          continue;
 
2042
        }
 
2043
 
 
2044
      /* Get the value of the symbol.  */
 
2045
      hsec = h->root.u.def.section;
 
2046
      relocation = (h->root.u.def.value
 
2047
                    + hsec->output_section->vma
 
2048
                    + hsec->output_offset);
 
2049
 
 
2050
      /* Subtract out the current address.  */
 
2051
      relocation -= (sec->output_section->vma
 
2052
                     + sec->output_offset
 
2053
                     + (int_rel.r_vaddr - sec->vma));
 
2054
 
 
2055
      /* The addend is stored in the object file.  In the normal case
 
2056
         of ``bal symbol'', the addend will be -4.  It will only be
 
2057
         different in the case of ``bal symbol+constant''.  To avoid
 
2058
         always reading in the section contents, we don't check the
 
2059
         addend in the object file (we could easily check the contents
 
2060
         if we happen to have already read them in, but I fear that
 
2061
         this could be confusing).  This means we will screw up if
 
2062
         there is a branch to a symbol that is in range, but added to
 
2063
         a constant which puts it out of range; in such a case the
 
2064
         link will fail with a reloc overflow error.  Since the
 
2065
         compiler will never generate such code, it should be easy
 
2066
         enough to work around it by changing the assembly code in the
 
2067
         source file.  */
 
2068
      relocation -= 4;
 
2069
 
 
2070
      /* Now RELOCATION is the number we want to put in the object
 
2071
         file.  See whether it fits.  */
 
2072
      if (relocation >= -0x20000 && relocation < 0x20000)
 
2073
        continue;
 
2074
 
 
2075
      /* Now that we know this reloc needs work, which will rarely
 
2076
         happen, go ahead and grab the section contents.  */
 
2077
      if (contents == (bfd_byte *) NULL)
 
2078
        {
 
2079
          if (info->keep_memory)
 
2080
            contents = (bfd_byte *) bfd_alloc (abfd, sec->_raw_size);
 
2081
          else
 
2082
            contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
 
2083
          if (contents == (bfd_byte *) NULL)
 
2084
            goto error_return;
 
2085
          if (! bfd_get_section_contents (abfd, sec, (PTR) contents,
 
2086
                                          (file_ptr) 0, sec->_raw_size))
 
2087
            goto error_return;
 
2088
          if (info->keep_memory)
 
2089
            section_tdata->contents = contents;
 
2090
        }
 
2091
 
 
2092
      /* We only support changing the bal instruction.  It would be
 
2093
         possible to handle other PC relative branches, but some of
 
2094
         them (the conditional branches) would require a different
 
2095
         length instruction sequence which would complicate both this
 
2096
         routine and mips_relax_pcrel16.  It could be written if
 
2097
         somebody felt it were important.  Ignoring this reloc will
 
2098
         presumably cause a reloc overflow error later on.  */
 
2099
      if (bfd_get_32 (abfd, contents + int_rel.r_vaddr - sec->vma)
 
2100
          != 0x0411ffff) /* bgezal $0,. == bal .  */
 
2101
        continue;
 
2102
 
 
2103
      /* Bother.  We need to expand this reloc, and we will need to
 
2104
         make another relaxation pass since this change may put other
 
2105
         relocs out of range.  We need to examine the local branches
 
2106
         and we need to allocate memory to hold the offsets we must
 
2107
         add to them.  We also need to adjust the values of all
 
2108
         symbols in the object file following this location.  */
 
2109
 
 
2110
      sec->_cooked_size += PCREL16_EXPANSION_ADJUSTMENT;
 
2111
      *again = true;
 
2112
 
 
2113
      if (offsets == (long *) NULL)
 
2114
        {
 
2115
          bfd_size_type size;
 
2116
 
 
2117
          size = (bfd_size_type) sec->reloc_count * sizeof (long);
 
2118
          offsets = (long *) bfd_zalloc (abfd, size);
 
2119
          if (offsets == (long *) NULL)
 
2120
            goto error_return;
 
2121
          section_tdata->offsets = offsets;
 
2122
        }
 
2123
 
 
2124
      offsets[i] = 1;
 
2125
 
 
2126
      /* Now look for all PC relative references that cross this reloc
 
2127
         and adjust their offsets.  */
 
2128
      adj_ext_rel = (struct external_reloc *) section_tdata->external_relocs;
 
2129
      for (adj_i = 0; adj_ext_rel < ext_rel_end; adj_ext_rel++, adj_i++)
 
2130
        {
 
2131
          struct internal_reloc adj_int_rel;
 
2132
          bfd_vma start, stop;
 
2133
          int change;
 
2134
 
 
2135
          mips_ecoff_swap_reloc_in (abfd, (PTR) adj_ext_rel, &adj_int_rel);
 
2136
 
 
2137
          if (adj_int_rel.r_type == MIPS_R_PCREL16)
 
2138
            {
 
2139
              unsigned long insn;
 
2140
 
 
2141
              /* We only care about local references.  External ones
 
2142
                 will be relocated correctly anyhow.  */
 
2143
              if (adj_int_rel.r_extern)
 
2144
                continue;
 
2145
 
 
2146
              /* We are only interested in a PC relative reloc within
 
2147
                 this section.  FIXME: Cross section PC relative
 
2148
                 relocs may not be handled correctly; does anybody
 
2149
                 care?  */
 
2150
              if (adj_int_rel.r_symndx != RELOC_SECTION_TEXT)
 
2151
                continue;
 
2152
 
 
2153
              start = adj_int_rel.r_vaddr;
 
2154
 
 
2155
              insn = bfd_get_32 (abfd,
 
2156
                                 contents + adj_int_rel.r_vaddr - sec->vma);
 
2157
 
 
2158
              stop = (insn & 0xffff) << 2;
 
2159
              if ((stop & 0x20000) != 0)
 
2160
                stop -= 0x40000;
 
2161
              stop += adj_int_rel.r_vaddr + 4;
 
2162
            }
 
2163
          else if (adj_int_rel.r_type == MIPS_R_RELHI)
 
2164
            {
 
2165
              struct internal_reloc rello;
 
2166
              long addhi, addlo;
 
2167
 
 
2168
              /* The next reloc must be MIPS_R_RELLO, and we handle
 
2169
                 them together.  */
 
2170
              BFD_ASSERT (adj_ext_rel + 1 < ext_rel_end);
 
2171
 
 
2172
              mips_ecoff_swap_reloc_in (abfd, (PTR) (adj_ext_rel + 1), &rello);
 
2173
 
 
2174
              BFD_ASSERT (rello.r_type == MIPS_R_RELLO);
 
2175
 
 
2176
              addhi = bfd_get_32 (abfd,
 
2177
                                   contents + adj_int_rel.r_vaddr - sec->vma);
 
2178
              addhi &= 0xffff;
 
2179
              if (addhi & 0x8000)
 
2180
                addhi -= 0x10000;
 
2181
              addhi <<= 16;
 
2182
 
 
2183
              addlo = bfd_get_32 (abfd, contents + rello.r_vaddr - sec->vma);
 
2184
              addlo &= 0xffff;
 
2185
              if (addlo & 0x8000)
 
2186
                addlo -= 0x10000;
 
2187
 
 
2188
              if (adj_int_rel.r_extern)
 
2189
                {
 
2190
                  /* The value we want here is
 
2191
                       sym - RELLOaddr + addend
 
2192
                     which we can express as
 
2193
                       sym - (RELLOaddr - addend)
 
2194
                     Therefore if we are expanding the area between
 
2195
                     RELLOaddr and RELLOaddr - addend we must adjust
 
2196
                     the addend.  This is admittedly ambiguous, since
 
2197
                     we might mean (sym + addend) - RELLOaddr, but in
 
2198
                     practice we don't, and there is no way to handle
 
2199
                     that case correctly since at this point we have
 
2200
                     no idea whether any reloc is being expanded
 
2201
                     between sym and sym + addend.  */
 
2202
                  start = rello.r_vaddr - (addhi + addlo);
 
2203
                  stop = rello.r_vaddr;
 
2204
                }
 
2205
              else
 
2206
                {
 
2207
                  /* An internal RELHI/RELLO pair represents the
 
2208
                     difference between two addresses, $LC0 - foo.
 
2209
                     The symndx value is actually the difference
 
2210
                     between the reloc address and $LC0.  This lets us
 
2211
                     compute $LC0, and, by considering the addend,
 
2212
                     foo.  If the reloc we are expanding falls between
 
2213
                     those two relocs, we must adjust the addend.  At
 
2214
                     this point, the symndx value is actually in the
 
2215
                     r_offset field, where it was put by
 
2216
                     mips_ecoff_swap_reloc_in.  */
 
2217
                  start = rello.r_vaddr - adj_int_rel.r_offset;
 
2218
                  stop = start + addhi + addlo;
 
2219
                }
 
2220
            }
 
2221
          else if (adj_int_rel.r_type == MIPS_R_SWITCH)
 
2222
            {
 
2223
              /* A MIPS_R_SWITCH reloc represents a word of the form
 
2224
                   .word $L3-$LS12
 
2225
                 The value in the object file is correct, assuming the
 
2226
                 original value of $L3.  The symndx value is actually
 
2227
                 the difference between the reloc address and $LS12.
 
2228
                 This lets us compute the original value of $LS12 as
 
2229
                   vaddr - symndx
 
2230
                 and the original value of $L3 as
 
2231
                   vaddr - symndx + addend
 
2232
                 where addend is the value from the object file.  At
 
2233
                 this point, the symndx value is actually found in the
 
2234
                 r_offset field, since it was moved by
 
2235
                 mips_ecoff_swap_reloc_in.  */
 
2236
              start = adj_int_rel.r_vaddr - adj_int_rel.r_offset;
 
2237
              stop = start + bfd_get_32 (abfd,
 
2238
                                         (contents
 
2239
                                          + adj_int_rel.r_vaddr
 
2240
                                          - sec->vma));
 
2241
            }
 
2242
          else
 
2243
            continue;
 
2244
 
 
2245
          /* If the range expressed by this reloc, which is the
 
2246
             distance between START and STOP crosses the reloc we are
 
2247
             expanding, we must adjust the offset.  The sign of the
 
2248
             adjustment depends upon the direction in which the range
 
2249
             crosses the reloc being expanded.  */
 
2250
          if (start <= int_rel.r_vaddr && stop > int_rel.r_vaddr)
 
2251
            change = PCREL16_EXPANSION_ADJUSTMENT;
 
2252
          else if (start > int_rel.r_vaddr && stop <= int_rel.r_vaddr)
 
2253
            change = - PCREL16_EXPANSION_ADJUSTMENT;
 
2254
          else
 
2255
            change = 0;
 
2256
 
 
2257
          offsets[adj_i] += change;
 
2258
 
 
2259
          if (adj_int_rel.r_type == MIPS_R_RELHI)
 
2260
            {
 
2261
              adj_ext_rel++;
 
2262
              adj_i++;
 
2263
              offsets[adj_i] += change;
 
2264
            }
 
2265
        }
 
2266
 
 
2267
      /* Find all symbols in this section defined by this object file
 
2268
         and adjust their values.  Note that we decide whether to
 
2269
         adjust the value based on the value stored in the ECOFF EXTR
 
2270
         structure, because the value stored in the hash table may
 
2271
         have been changed by an earlier expanded reloc and thus may
 
2272
         no longer correctly indicate whether the symbol is before or
 
2273
         after the expanded reloc.  */
 
2274
      ext_count = ecoff_data (abfd)->debug_info.symbolic_header.iextMax;
 
2275
      adj_h_ptr = ecoff_data (abfd)->sym_hashes;
 
2276
      adj_h_ptr_end = adj_h_ptr + ext_count;
 
2277
      for (; adj_h_ptr < adj_h_ptr_end; adj_h_ptr++)
 
2278
        {
 
2279
          struct ecoff_link_hash_entry *adj_h;
 
2280
 
 
2281
          adj_h = *adj_h_ptr;
 
2282
          if (adj_h != (struct ecoff_link_hash_entry *) NULL
 
2283
              && (adj_h->root.type == bfd_link_hash_defined
 
2284
                  || adj_h->root.type == bfd_link_hash_defweak)
 
2285
              && adj_h->root.u.def.section == sec
 
2286
              && adj_h->esym.asym.value > int_rel.r_vaddr)
 
2287
            adj_h->root.u.def.value += PCREL16_EXPANSION_ADJUSTMENT;
 
2288
        }
 
2289
 
 
2290
      /* Add an entry to the symbol value adjust list.  This is used
 
2291
         by bfd_ecoff_debug_accumulate to adjust the values of
 
2292
         internal symbols and FDR's.  */
 
2293
      amt = sizeof (struct ecoff_value_adjust);
 
2294
      adjust = (struct ecoff_value_adjust *) bfd_alloc (abfd, amt);
 
2295
      if (adjust == (struct ecoff_value_adjust *) NULL)
 
2296
        goto error_return;
 
2297
 
 
2298
      adjust->start = int_rel.r_vaddr;
 
2299
      adjust->end = sec->vma + sec->_raw_size;
 
2300
      adjust->adjust = PCREL16_EXPANSION_ADJUSTMENT;
 
2301
 
 
2302
      adjust->next = ecoff_data (abfd)->debug_info.adjust;
 
2303
      ecoff_data (abfd)->debug_info.adjust = adjust;
 
2304
    }
 
2305
 
 
2306
  if (contents != (bfd_byte *) NULL && ! info->keep_memory)
 
2307
    free (contents);
 
2308
 
 
2309
  return true;
 
2310
 
 
2311
 error_return:
 
2312
  if (contents != (bfd_byte *) NULL && ! info->keep_memory)
 
2313
    free (contents);
 
2314
  return false;
 
2315
}
 
2316
 
 
2317
/* This routine is called from mips_relocate_section when a PC
 
2318
   relative reloc must be expanded into the five instruction sequence.
 
2319
   It handles all the details of the expansion, including resolving
 
2320
   the reloc.  */
 
2321
 
 
2322
static boolean
 
2323
mips_relax_pcrel16 (info, input_bfd, input_section, h, location, address)
 
2324
     struct bfd_link_info *info ATTRIBUTE_UNUSED;
 
2325
     bfd *input_bfd;
 
2326
     asection *input_section ATTRIBUTE_UNUSED;
 
2327
     struct ecoff_link_hash_entry *h;
 
2328
     bfd_byte *location;
 
2329
     bfd_vma address;
 
2330
{
 
2331
  bfd_vma relocation;
 
2332
 
 
2333
  /* 0x0411ffff is bgezal $0,. == bal .  */
 
2334
  BFD_ASSERT (bfd_get_32 (input_bfd, location) == 0x0411ffff);
 
2335
 
 
2336
  /* We need to compute the distance between the symbol and the
 
2337
     current address plus eight.  */
 
2338
  relocation = (h->root.u.def.value
 
2339
                + h->root.u.def.section->output_section->vma
 
2340
                + h->root.u.def.section->output_offset);
 
2341
  relocation -= address + 8;
 
2342
 
 
2343
  /* If the lower half is negative, increment the upper 16 half.  */
 
2344
  if ((relocation & 0x8000) != 0)
 
2345
    relocation += 0x10000;
 
2346
 
 
2347
  bfd_put_32 (input_bfd, (bfd_vma) 0x04110001, location); /* bal .+8 */
 
2348
  bfd_put_32 (input_bfd,
 
2349
              0x3c010000 | ((relocation >> 16) & 0xffff), /* lui $at,XX */
 
2350
              location + 4);
 
2351
  bfd_put_32 (input_bfd,
 
2352
              0x24210000 | (relocation & 0xffff), /* addiu $at,$at,XX */
 
2353
              location + 8);
 
2354
  bfd_put_32 (input_bfd,
 
2355
              (bfd_vma) 0x003f0821, location + 12); /* addu $at,$at,$ra */
 
2356
  bfd_put_32 (input_bfd,
 
2357
              (bfd_vma) 0x0020f809, location + 16); /* jalr $at */
 
2358
 
 
2359
  return true;
 
2360
}
 
2361
 
 
2362
/* Given a .sdata section and a .rel.sdata in-memory section, store
 
2363
   relocation information into the .rel.sdata section which can be
 
2364
   used at runtime to relocate the section.  This is called by the
 
2365
   linker when the --embedded-relocs switch is used.  This is called
 
2366
   after the add_symbols entry point has been called for all the
 
2367
   objects, and before the final_link entry point is called.  This
 
2368
   function presumes that the object was compiled using
 
2369
   -membedded-pic.  */
 
2370
 
 
2371
boolean
 
2372
bfd_mips_ecoff_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
 
2373
     bfd *abfd;
 
2374
     struct bfd_link_info *info;
 
2375
     asection *datasec;
 
2376
     asection *relsec;
 
2377
     char **errmsg;
 
2378
{
 
2379
  struct ecoff_link_hash_entry **sym_hashes;
 
2380
  struct ecoff_section_tdata *section_tdata;
 
2381
  struct external_reloc *ext_rel;
 
2382
  struct external_reloc *ext_rel_end;
 
2383
  bfd_byte *p;
 
2384
  bfd_size_type amt;
 
2385
 
 
2386
  BFD_ASSERT (! info->relocateable);
 
2387
 
 
2388
  *errmsg = NULL;
 
2389
 
 
2390
  if (datasec->reloc_count == 0)
 
2391
    return true;
 
2392
 
 
2393
  sym_hashes = ecoff_data (abfd)->sym_hashes;
 
2394
 
 
2395
  if (! mips_read_relocs (abfd, datasec))
 
2396
    return false;
 
2397
 
 
2398
  amt = (bfd_size_type) datasec->reloc_count * 4;
 
2399
  relsec->contents = (bfd_byte *) bfd_alloc (abfd, amt);
 
2400
  if (relsec->contents == NULL)
 
2401
    return false;
 
2402
 
 
2403
  p = relsec->contents;
 
2404
 
 
2405
  section_tdata = ecoff_section_data (abfd, datasec);
 
2406
  ext_rel = (struct external_reloc *) section_tdata->external_relocs;
 
2407
  ext_rel_end = ext_rel + datasec->reloc_count;
 
2408
  for (; ext_rel < ext_rel_end; ext_rel++, p += 4)
 
2409
    {
 
2410
      struct internal_reloc int_rel;
 
2411
      boolean text_relative;
 
2412
 
 
2413
      mips_ecoff_swap_reloc_in (abfd, (PTR) ext_rel, &int_rel);
 
2414
 
 
2415
      /* We are going to write a four byte word into the runtime reloc
 
2416
         section.  The word will be the address in the data section
 
2417
         which must be relocated.  This must be on a word boundary,
 
2418
         which means the lower two bits must be zero.  We use the
 
2419
         least significant bit to indicate how the value in the data
 
2420
         section must be relocated.  A 0 means that the value is
 
2421
         relative to the text section, while a 1 indicates that the
 
2422
         value is relative to the data section.  Given that we are
 
2423
         assuming the code was compiled using -membedded-pic, there
 
2424
         should not be any other possibilities.  */
 
2425
 
 
2426
      /* We can only relocate REFWORD relocs at run time.  */
 
2427
      if (int_rel.r_type != MIPS_R_REFWORD)
 
2428
        {
 
2429
          *errmsg = _("unsupported reloc type");
 
2430
          bfd_set_error (bfd_error_bad_value);
 
2431
          return false;
 
2432
        }
 
2433
 
 
2434
      if (int_rel.r_extern)
 
2435
        {
 
2436
          struct ecoff_link_hash_entry *h;
 
2437
 
 
2438
          h = sym_hashes[int_rel.r_symndx];
 
2439
          /* If h is NULL, that means that there is a reloc against an
 
2440
             external symbol which we thought was just a debugging
 
2441
             symbol.  This should not happen.  */
 
2442
          if (h == (struct ecoff_link_hash_entry *) NULL)
 
2443
            abort ();
 
2444
          if ((h->root.type == bfd_link_hash_defined
 
2445
               || h->root.type == bfd_link_hash_defweak)
 
2446
              && (h->root.u.def.section->flags & SEC_CODE) != 0)
 
2447
            text_relative = true;
 
2448
          else
 
2449
            text_relative = false;
 
2450
        }
 
2451
      else
 
2452
        {
 
2453
          switch (int_rel.r_symndx)
 
2454
            {
 
2455
            case RELOC_SECTION_TEXT:
 
2456
              text_relative = true;
 
2457
              break;
 
2458
            case RELOC_SECTION_SDATA:
 
2459
            case RELOC_SECTION_SBSS:
 
2460
            case RELOC_SECTION_LIT8:
 
2461
              text_relative = false;
 
2462
              break;
 
2463
            default:
 
2464
              /* No other sections should appear in -membedded-pic
 
2465
                 code.  */
 
2466
              *errmsg = _("reloc against unsupported section");
 
2467
              bfd_set_error (bfd_error_bad_value);
 
2468
              return false;
 
2469
            }
 
2470
        }
 
2471
 
 
2472
      if ((int_rel.r_offset & 3) != 0)
 
2473
        {
 
2474
          *errmsg = _("reloc not properly aligned");
 
2475
          bfd_set_error (bfd_error_bad_value);
 
2476
          return false;
 
2477
        }
 
2478
 
 
2479
      bfd_put_32 (abfd,
 
2480
                  (int_rel.r_vaddr - datasec->vma + datasec->output_offset
 
2481
                   + (text_relative ? 0 : 1)),
 
2482
                  p);
 
2483
    }
 
2484
 
 
2485
  return true;
 
2486
}
 
2487
 
 
2488
/* This is the ECOFF backend structure.  The backend field of the
 
2489
   target vector points to this.  */
 
2490
 
 
2491
static const struct ecoff_backend_data mips_ecoff_backend_data =
 
2492
{
 
2493
  /* COFF backend structure.  */
 
2494
  {
 
2495
    (void (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR))) bfd_void, /* aux_in */
 
2496
    (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_in */
 
2497
    (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_in */
 
2498
    (unsigned (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR)))bfd_void,/*aux_out*/
 
2499
    (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_out */
 
2500
    (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_out */
 
2501
    (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* reloc_out */
 
2502
    mips_ecoff_swap_filehdr_out, mips_ecoff_swap_aouthdr_out,
 
2503
    mips_ecoff_swap_scnhdr_out,
 
2504
    FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, FILNMLEN, true, false, 4, false, 2,
 
2505
    mips_ecoff_swap_filehdr_in, mips_ecoff_swap_aouthdr_in,
 
2506
    mips_ecoff_swap_scnhdr_in, NULL,
 
2507
    mips_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook,
 
2508
    _bfd_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags,
 
2509
    _bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table,
 
2510
    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
2511
    NULL, NULL
 
2512
  },
 
2513
  /* Supported architecture.  */
 
2514
  bfd_arch_mips,
 
2515
  /* Initial portion of armap string.  */
 
2516
  "__________",
 
2517
  /* The page boundary used to align sections in a demand-paged
 
2518
     executable file.  E.g., 0x1000.  */
 
2519
  0x1000,
 
2520
  /* True if the .rdata section is part of the text segment, as on the
 
2521
     Alpha.  False if .rdata is part of the data segment, as on the
 
2522
     MIPS.  */
 
2523
  false,
 
2524
  /* Bitsize of constructor entries.  */
 
2525
  32,
 
2526
  /* Reloc to use for constructor entries.  */
 
2527
  &mips_howto_table[MIPS_R_REFWORD],
 
2528
  {
 
2529
    /* Symbol table magic number.  */
 
2530
    magicSym,
 
2531
    /* Alignment of debugging information.  E.g., 4.  */
 
2532
    4,
 
2533
    /* Sizes of external symbolic information.  */
 
2534
    sizeof (struct hdr_ext),
 
2535
    sizeof (struct dnr_ext),
 
2536
    sizeof (struct pdr_ext),
 
2537
    sizeof (struct sym_ext),
 
2538
    sizeof (struct opt_ext),
 
2539
    sizeof (struct fdr_ext),
 
2540
    sizeof (struct rfd_ext),
 
2541
    sizeof (struct ext_ext),
 
2542
    /* Functions to swap in external symbolic data.  */
 
2543
    ecoff_swap_hdr_in,
 
2544
    ecoff_swap_dnr_in,
 
2545
    ecoff_swap_pdr_in,
 
2546
    ecoff_swap_sym_in,
 
2547
    ecoff_swap_opt_in,
 
2548
    ecoff_swap_fdr_in,
 
2549
    ecoff_swap_rfd_in,
 
2550
    ecoff_swap_ext_in,
 
2551
    _bfd_ecoff_swap_tir_in,
 
2552
    _bfd_ecoff_swap_rndx_in,
 
2553
    /* Functions to swap out external symbolic data.  */
 
2554
    ecoff_swap_hdr_out,
 
2555
    ecoff_swap_dnr_out,
 
2556
    ecoff_swap_pdr_out,
 
2557
    ecoff_swap_sym_out,
 
2558
    ecoff_swap_opt_out,
 
2559
    ecoff_swap_fdr_out,
 
2560
    ecoff_swap_rfd_out,
 
2561
    ecoff_swap_ext_out,
 
2562
    _bfd_ecoff_swap_tir_out,
 
2563
    _bfd_ecoff_swap_rndx_out,
 
2564
    /* Function to read in symbolic data.  */
 
2565
    _bfd_ecoff_slurp_symbolic_info
 
2566
  },
 
2567
  /* External reloc size.  */
 
2568
  RELSZ,
 
2569
  /* Reloc swapping functions.  */
 
2570
  mips_ecoff_swap_reloc_in,
 
2571
  mips_ecoff_swap_reloc_out,
 
2572
  /* Backend reloc tweaking.  */
 
2573
  mips_adjust_reloc_in,
 
2574
  mips_adjust_reloc_out,
 
2575
  /* Relocate section contents while linking.  */
 
2576
  mips_relocate_section,
 
2577
  /* Do final adjustments to filehdr and aouthdr.  */
 
2578
  NULL,
 
2579
  /* Read an element from an archive at a given file position.  */
 
2580
  _bfd_get_elt_at_filepos
 
2581
};
 
2582
 
 
2583
/* Looking up a reloc type is MIPS specific.  */
 
2584
#define _bfd_ecoff_bfd_reloc_type_lookup mips_bfd_reloc_type_lookup
 
2585
 
 
2586
/* Getting relocated section contents is generic.  */
 
2587
#define _bfd_ecoff_bfd_get_relocated_section_contents \
 
2588
  bfd_generic_get_relocated_section_contents
 
2589
 
 
2590
/* Handling file windows is generic.  */
 
2591
#define _bfd_ecoff_get_section_contents_in_window \
 
2592
  _bfd_generic_get_section_contents_in_window
 
2593
 
 
2594
/* Relaxing sections is MIPS specific.  */
 
2595
#define _bfd_ecoff_bfd_relax_section mips_relax_section
 
2596
 
 
2597
/* GC of sections is not done.  */
 
2598
#define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_sections
 
2599
 
 
2600
/* Merging of sections is not done.  */
 
2601
#define _bfd_ecoff_bfd_merge_sections bfd_generic_merge_sections
 
2602
 
 
2603
#define _bfd_ecoff_bfd_discard_group bfd_generic_discard_group
 
2604
 
 
2605
extern const bfd_target ecoff_big_vec;
 
2606
 
 
2607
const bfd_target ecoff_little_vec =
 
2608
{
 
2609
  "ecoff-littlemips",           /* name */
 
2610
  bfd_target_ecoff_flavour,
 
2611
  BFD_ENDIAN_LITTLE,            /* data byte order is little */
 
2612
  BFD_ENDIAN_LITTLE,            /* header byte order is little */
 
2613
 
 
2614
  (HAS_RELOC | EXEC_P |         /* object flags */
 
2615
   HAS_LINENO | HAS_DEBUG |
 
2616
   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
 
2617
 
 
2618
  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
 
2619
  0,                            /* leading underscore */
 
2620
  ' ',                          /* ar_pad_char */
 
2621
  15,                           /* ar_max_namelen */
 
2622
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
 
2623
     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
 
2624
     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
 
2625
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
 
2626
     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
 
2627
     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
 
2628
 
 
2629
  {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
 
2630
     _bfd_ecoff_archive_p, _bfd_dummy_target},
 
2631
  {bfd_false, _bfd_ecoff_mkobject,  /* bfd_set_format */
 
2632
     _bfd_generic_mkarchive, bfd_false},
 
2633
  {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
 
2634
     _bfd_write_archive_contents, bfd_false},
 
2635
 
 
2636
     BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
 
2637
     BFD_JUMP_TABLE_COPY (_bfd_ecoff),
 
2638
     BFD_JUMP_TABLE_CORE (_bfd_nocore),
 
2639
     BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
 
2640
     BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
 
2641
     BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
 
2642
     BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
 
2643
     BFD_JUMP_TABLE_LINK (_bfd_ecoff),
 
2644
     BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
 
2645
 
 
2646
  & ecoff_big_vec,
 
2647
 
 
2648
  (PTR) &mips_ecoff_backend_data
 
2649
};
 
2650
 
 
2651
const bfd_target ecoff_big_vec =
 
2652
{
 
2653
  "ecoff-bigmips",              /* name */
 
2654
  bfd_target_ecoff_flavour,
 
2655
  BFD_ENDIAN_BIG,               /* data byte order is big */
 
2656
  BFD_ENDIAN_BIG,               /* header byte order is big */
 
2657
 
 
2658
  (HAS_RELOC | EXEC_P |         /* object flags */
 
2659
   HAS_LINENO | HAS_DEBUG |
 
2660
   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
 
2661
 
 
2662
  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
 
2663
  0,                            /* leading underscore */
 
2664
  ' ',                          /* ar_pad_char */
 
2665
  15,                           /* ar_max_namelen */
 
2666
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
 
2667
     bfd_getb32, bfd_getb_signed_32, bfd_putb32,
 
2668
     bfd_getb16, bfd_getb_signed_16, bfd_putb16,
 
2669
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
 
2670
     bfd_getb32, bfd_getb_signed_32, bfd_putb32,
 
2671
     bfd_getb16, bfd_getb_signed_16, bfd_putb16,
 
2672
 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
 
2673
    _bfd_ecoff_archive_p, _bfd_dummy_target},
 
2674
 {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */
 
2675
    _bfd_generic_mkarchive, bfd_false},
 
2676
 {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
 
2677
    _bfd_write_archive_contents, bfd_false},
 
2678
 
 
2679
     BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
 
2680
     BFD_JUMP_TABLE_COPY (_bfd_ecoff),
 
2681
     BFD_JUMP_TABLE_CORE (_bfd_nocore),
 
2682
     BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
 
2683
     BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
 
2684
     BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
 
2685
     BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
 
2686
     BFD_JUMP_TABLE_LINK (_bfd_ecoff),
 
2687
     BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
 
2688
 
 
2689
  & ecoff_little_vec,
 
2690
 
 
2691
  (PTR) &mips_ecoff_backend_data
 
2692
};
 
2693
 
 
2694
const bfd_target ecoff_biglittle_vec =
 
2695
{
 
2696
  "ecoff-biglittlemips",                /* name */
 
2697
  bfd_target_ecoff_flavour,
 
2698
  BFD_ENDIAN_LITTLE,            /* data byte order is little */
 
2699
  BFD_ENDIAN_BIG,               /* header byte order is big */
 
2700
 
 
2701
  (HAS_RELOC | EXEC_P |         /* object flags */
 
2702
   HAS_LINENO | HAS_DEBUG |
 
2703
   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
 
2704
 
 
2705
  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
 
2706
  0,                            /* leading underscore */
 
2707
  ' ',                          /* ar_pad_char */
 
2708
  15,                           /* ar_max_namelen */
 
2709
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
 
2710
     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
 
2711
     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
 
2712
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
 
2713
     bfd_getb32, bfd_getb_signed_32, bfd_putb32,
 
2714
     bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
 
2715
 
 
2716
  {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
 
2717
     _bfd_ecoff_archive_p, _bfd_dummy_target},
 
2718
  {bfd_false, _bfd_ecoff_mkobject,  /* bfd_set_format */
 
2719
     _bfd_generic_mkarchive, bfd_false},
 
2720
  {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
 
2721
     _bfd_write_archive_contents, bfd_false},
 
2722
 
 
2723
     BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
 
2724
     BFD_JUMP_TABLE_COPY (_bfd_ecoff),
 
2725
     BFD_JUMP_TABLE_CORE (_bfd_nocore),
 
2726
     BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
 
2727
     BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
 
2728
     BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
 
2729
     BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
 
2730
     BFD_JUMP_TABLE_LINK (_bfd_ecoff),
 
2731
     BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
 
2732
 
 
2733
  NULL,
 
2734
 
 
2735
  (PTR) &mips_ecoff_backend_data
 
2736
};