(linenum→info "unix/slp.c:2238")

binutils/2.18/bfd/coff-mips.c

    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, 2003, 2004, 2007
    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 3 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., 51 Franklin Street - Fifth Floor, Boston,
   23:    MA 02110-1301, USA.  */
   24: 
   25: #include "sysdep.h"
   26: #include "bfd.h"
   27: #include "bfdlink.h"
   28: #include "libbfd.h"
   29: #include "coff/internal.h"
   30: #include "coff/sym.h"
   31: #include "coff/symconst.h"
   32: #include "coff/ecoff.h"
   33: #include "coff/mips.h"
   34: #include "libcoff.h"
   35: #include "libecoff.h"
   36: ^L
   37: /* Prototypes for static functions.  */
   38: 
   39: static bfd_boolean mips_ecoff_bad_format_hook
   40:   PARAMS ((bfd *abfd, PTR filehdr));
   41: static void mips_ecoff_swap_reloc_in
   42:   PARAMS ((bfd *, PTR, struct internal_reloc *));
   43: static void mips_ecoff_swap_reloc_out
   44:   PARAMS ((bfd *, const struct internal_reloc *, PTR));
   45: static void mips_adjust_reloc_in
   46:   PARAMS ((bfd *, const struct internal_reloc *, arelent *));
   47: static void mips_adjust_reloc_out
   48:   PARAMS ((bfd *, const arelent *, struct internal_reloc *));
   49: static bfd_reloc_status_type mips_generic_reloc
   50:   PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, PTR data,
   51:            asection *section, bfd *output_bfd, char **error));
   52: static bfd_reloc_status_type mips_refhi_reloc
   53:   PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, PTR data,
   54:            asection *section, bfd *output_bfd, char **error));
   55: static bfd_reloc_status_type mips_reflo_reloc
   56:   PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, PTR data,
   57:            asection *section, bfd *output_bfd, char **error));
   58: static bfd_reloc_status_type mips_gprel_reloc
   59:   PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, PTR data,
   60:            asection *section, bfd *output_bfd, char **error));
   61: static void mips_relocate_hi
   62:   PARAMS ((struct internal_reloc *refhi, struct internal_reloc *reflo,
   63:            bfd *input_bfd, asection *input_section, bfd_byte *contents,
   64:            bfd_vma relocation));
   65: static bfd_boolean mips_relocate_section
   66:   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, PTR));
   67: static reloc_howto_type *mips_bfd_reloc_type_lookup
   68:   PARAMS ((bfd *, bfd_reloc_code_real_type));
   69: ^L
   70: /* ECOFF has COFF sections, but the debugging information is stored in
   71:    a completely different format.  ECOFF targets use some of the
   72:    swapping routines from coffswap.h, and some of the generic COFF
   73:    routines in coffgen.c, but, unlike the real COFF targets, do not
   74:    use coffcode.h itself.
   75: 
   76:    Get the generic COFF swapping routines, except for the reloc,
   77:    symbol, and lineno ones.  Give them ECOFF names.  */
   78: #define MIPSECOFF
   79: #define NO_COFF_RELOCS
   80: #define NO_COFF_SYMBOLS
   81: #define NO_COFF_LINENOS
   82: #define coff_swap_filehdr_in mips_ecoff_swap_filehdr_in
   83: #define coff_swap_filehdr_out mips_ecoff_swap_filehdr_out
   84: #define coff_swap_aouthdr_in mips_ecoff_swap_aouthdr_in
   85: #define coff_swap_aouthdr_out mips_ecoff_swap_aouthdr_out
   86: #define coff_swap_scnhdr_in mips_ecoff_swap_scnhdr_in
   87: #define coff_swap_scnhdr_out mips_ecoff_swap_scnhdr_out
   88: #include "coffswap.h"
   89: 
   90: /* Get the ECOFF swapping routines.  */
   91: #define ECOFF_32
   92: #include "ecoffswap.h"
   93: ^L
   94: /* How to process the various relocs types.  */
   95: 
   96: static reloc_howto_type mips_howto_table[] =
   97: {
   98:   /* Reloc type 0 is ignored.  The reloc reading code ensures that
   99:      this is a reference to the .abs section, which will cause
  100:      bfd_perform_relocation to do nothing.  */
  101:   HOWTO (MIPS_R_IGNORE, /* type */
  102:          0,                    /* rightshift */
  103:          0,                    /* size (0 = byte, 1 = short, 2 = long) */
  104:          8,                    /* bitsize */
  105:          FALSE,                        /* pc_relative */
  106:          0,                    /* bitpos */
  107:          complain_overflow_dont, /* complain_on_overflow */
  108:          0,                    /* special_function */
  109:          "IGNORE",             /* name */
  110:          FALSE,                        /* partial_inplace */
  111:          0,                    /* src_mask */
  112:          0,                    /* dst_mask */
  113:          FALSE),               /* pcrel_offset */
  114: 
  115:   /* A 16 bit reference to a symbol, normally from a data section.  */
  116:   HOWTO (MIPS_R_REFHALF,        /* type */
  117:          0,                    /* rightshift */
  118:          1,                    /* size (0 = byte, 1 = short, 2 = long) */
  119:          16,                   /* bitsize */
  120:          FALSE,                        /* pc_relative */
  121:          0,                    /* bitpos */
  122:          complain_overflow_bitfield, /* complain_on_overflow */
  123:          mips_generic_reloc,   /* special_function */
  124:          "REFHALF",            /* name */
  125:          TRUE,                 /* partial_inplace */
  126:          0xffff,               /* src_mask */
  127:          0xffff,               /* dst_mask */
  128:          FALSE),               /* pcrel_offset */
  129: 
  130:   /* A 32 bit reference to a symbol, normally from a data section.  */
  131:   HOWTO (MIPS_R_REFWORD,        /* type */
  132:          0,                    /* rightshift */
  133:          2,                    /* size (0 = byte, 1 = short, 2 = long) */
  134:          32,                   /* bitsize */
  135:          FALSE,                        /* pc_relative */
  136:          0,                    /* bitpos */
  137:          complain_overflow_bitfield, /* complain_on_overflow */
  138:          mips_generic_reloc,   /* special_function */
  139:          "REFWORD",            /* name */
  140:          TRUE,                 /* partial_inplace */
  141:          0xffffffff,           /* src_mask */
  142:          0xffffffff,           /* dst_mask */
  143:          FALSE),               /* pcrel_offset */
  144: 
  145:   /* A 26 bit absolute jump address.  */
  146:   HOWTO (MIPS_R_JMPADDR,        /* type */
  147:          2,                    /* rightshift */
  148:          2,                    /* size (0 = byte, 1 = short, 2 = long) */
  149:          26,                   /* bitsize */
  150:          FALSE,                        /* pc_relative */
  151:          0,                    /* bitpos */
  152:          complain_overflow_dont, /* complain_on_overflow */
  153:                                /* This needs complex overflow
  154:                                    detection, because the upper four
  155:                                    bits must match the PC.  */
  156:          mips_generic_reloc,   /* special_function */
  157:          "JMPADDR",            /* name */
  158:          TRUE,                 /* partial_inplace */
  159:          0x3ffffff,            /* src_mask */
  160:          0x3ffffff,            /* dst_mask */
  161:          FALSE),               /* pcrel_offset */
  162: 
  163:   /* The high 16 bits of a symbol value.  Handled by the function
  164:      mips_refhi_reloc.  */
  165:   HOWTO (MIPS_R_REFHI,          /* type */
  166:          16,                   /* rightshift */
  167:          2,                    /* size (0 = byte, 1 = short, 2 = long) */
  168:          16,                   /* bitsize */
  169:          FALSE,                        /* pc_relative */
  170:          0,                    /* bitpos */
  171:          complain_overflow_bitfield, /* complain_on_overflow */
  172:          mips_refhi_reloc,     /* special_function */
  173:          "REFHI",              /* name */
  174:          TRUE,                 /* partial_inplace */
  175:          0xffff,               /* src_mask */
  176:          0xffff,               /* dst_mask */
  177:          FALSE),               /* pcrel_offset */
  178: 
  179:   /* The low 16 bits of a symbol value.  */
  180:   HOWTO (MIPS_R_REFLO,          /* type */
  181:          0,                    /* rightshift */
  182:          2,                    /* size (0 = byte, 1 = short, 2 = long) */
  183:          16,                   /* bitsize */
  184:          FALSE,                        /* pc_relative */
  185:          0,                    /* bitpos */
  186:          complain_overflow_dont, /* complain_on_overflow */
  187:          mips_reflo_reloc,     /* special_function */
  188:          "REFLO",              /* name */
  189:          TRUE,                 /* partial_inplace */
  190:          0xffff,               /* src_mask */
  191:          0xffff,               /* dst_mask */
  192:          FALSE),               /* pcrel_offset */
  193: 
  194:   /* A reference to an offset from the gp register.  Handled by the
  195:      function mips_gprel_reloc.  */
  196:   HOWTO (MIPS_R_GPREL,          /* type */
  197:          0,                    /* rightshift */
  198:          2,                    /* size (0 = byte, 1 = short, 2 = long) */
  199:          16,                   /* bitsize */
  200:          FALSE,                        /* pc_relative */
  201:          0,                    /* bitpos */
  202:          complain_overflow_signed, /* complain_on_overflow */
  203:          mips_gprel_reloc,     /* special_function */
  204:          "GPREL",              /* name */
  205:          TRUE,                 /* partial_inplace */
  206:          0xffff,               /* src_mask */
  207:          0xffff,               /* dst_mask */
  208:          FALSE),               /* pcrel_offset */
  209: 
  210:   /* A reference to a literal using an offset from the gp register.
  211:      Handled by the function mips_gprel_reloc.  */
  212:   HOWTO (MIPS_R_LITERAL,        /* type */
  213:          0,                    /* rightshift */
  214:          2,                    /* size (0 = byte, 1 = short, 2 = long) */
  215:          16,                   /* bitsize */
  216:          FALSE,                        /* pc_relative */
  217:          0,                    /* bitpos */
  218:          complain_overflow_signed, /* complain_on_overflow */
  219:          mips_gprel_reloc,     /* special_function */
  220:          "LITERAL",            /* name */
  221:          TRUE,                 /* partial_inplace */
  222:          0xffff,               /* src_mask */
  223:          0xffff,               /* dst_mask */
  224:          FALSE),               /* pcrel_offset */
  225: 
  226:   EMPTY_HOWTO (8),
  227:   EMPTY_HOWTO (9),
  228:   EMPTY_HOWTO (10),
  229:   EMPTY_HOWTO (11),
  230: 
  231:   /* FIXME: This relocation is used (internally only) to represent branches
  232:      when assembling.  It should never appear in output files, and
  233:      be removed.  (It used to be used for embedded-PIC support.)  */
  234:   HOWTO (MIPS_R_PCREL16,        /* type */
  235:          2,                    /* rightshift */
  236:          2,                    /* size (0 = byte, 1 = short, 2 = long) */
  237:          16,                   /* bitsize */
  238:          TRUE,                 /* pc_relative */
  239:          0,                    /* bitpos */
  240:          complain_overflow_signed, /* complain_on_overflow */
  241:          mips_generic_reloc,   /* special_function */
  242:          "PCREL16",            /* name */
  243:          TRUE,                 /* partial_inplace */
  244:          0xffff,               /* src_mask */
  245:          0xffff,               /* dst_mask */
  246:          TRUE),                        /* pcrel_offset */
  247: };
  248: 
  249: #define MIPS_HOWTO_COUNT \
  250:   (sizeof mips_howto_table / sizeof mips_howto_table[0])
  251: ^L
  252: /* See whether the magic number matches.  */
  253: 
  254: static bfd_boolean
  255: mips_ecoff_bad_format_hook (abfd, filehdr)
  256:      bfd *abfd;
  257:      PTR filehdr;
  258: {
  259:   struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
  260: 
  261:   switch (internal_f->f_magic)
  262:     {
  263:     case MIPS_MAGIC_1:
  264:       /* I don't know what endianness this implies.  */
  265:       return TRUE;
  266: 
  267:     case MIPS_MAGIC_BIG:
  268:     case MIPS_MAGIC_BIG2:
  269:     case MIPS_MAGIC_BIG3:
  270:       return bfd_big_endian (abfd);
  271: 
  272:     case MIPS_MAGIC_LITTLE:
  273:     case MIPS_MAGIC_LITTLE2:
  274:     case MIPS_MAGIC_LITTLE3:
  275:       return bfd_little_endian (abfd);
  276: 
  277:     default:
  278:       return FALSE;
  279:     }
  280: }
  281: ^L
  282: /* Reloc handling.  MIPS ECOFF relocs are packed into 8 bytes in
  283:    external form.  They use a bit which indicates whether the symbol
  284:    is external.  */
  285: 
  286: /* Swap a reloc in.  */
  287: 
  288: static void
  289: mips_ecoff_swap_reloc_in (abfd, ext_ptr, intern)
  290:      bfd *abfd;
  291:      PTR ext_ptr;
  292:      struct internal_reloc *intern;
  293: {
  294:   const RELOC *ext = (RELOC *) ext_ptr;
  295: 
  296:   intern->r_vaddr = H_GET_32 (abfd, ext->r_vaddr);
  297:   if (bfd_header_big_endian (abfd))
  298:     {
  299:       intern->r_symndx = (((int) ext->r_bits[0]
  300:                            << RELOC_BITS0_SYMNDX_SH_LEFT_BIG)
  301:                           | ((int) ext->r_bits[1]
  302:                              << RELOC_BITS1_SYMNDX_SH_LEFT_BIG)
  303:                           | ((int) ext->r_bits[2]
  304:                              << RELOC_BITS2_SYMNDX_SH_LEFT_BIG));
  305:       intern->r_type = ((ext->r_bits[3] & RELOC_BITS3_TYPE_BIG)
  306:                         >> RELOC_BITS3_TYPE_SH_BIG);
  307:       intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_BIG) != 0;
  308:     }
  309:   else
  310:     {
  311:       intern->r_symndx = (((int) ext->r_bits[0]
  312:                            << RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE)
  313:                           | ((int) ext->r_bits[1]
  314:                              << RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE)
  315:                           | ((int) ext->r_bits[2]
  316:                              << RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE));
  317:       intern->r_type = (((ext->r_bits[3] & RELOC_BITS3_TYPE_LITTLE)
  318:                          >> RELOC_BITS3_TYPE_SH_LITTLE)
  319:                         | ((ext->r_bits[3] & RELOC_BITS3_TYPEHI_LITTLE)
  320:                            << RELOC_BITS3_TYPEHI_SH_LITTLE));
  321:       intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_LITTLE) != 0;
  322:     }
  323: }
  324: 
  325: /* Swap a reloc out.  */
  326: 
  327: static void
  328: mips_ecoff_swap_reloc_out (abfd, intern, dst)
  329:      bfd *abfd;
  330:      const struct internal_reloc *intern;
  331:      PTR dst;
  332: {
  333:   RELOC *ext = (RELOC *) dst;
  334:   long r_symndx;
  335: 
  336:   BFD_ASSERT (intern->r_extern
  337:               || (intern->r_symndx >= 0 && intern->r_symndx <= 12));
  338: 
  339:   r_symndx = intern->r_symndx;
  340: 
  341:   H_PUT_32 (abfd, intern->r_vaddr, ext->r_vaddr);
  342:   if (bfd_header_big_endian (abfd))
  343:     {
  344:       ext->r_bits[0] = r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_BIG;
  345:       ext->r_bits[1] = r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_BIG;
  346:       ext->r_bits[2] = r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_BIG;
  347:       ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_BIG)
  348:                          & RELOC_BITS3_TYPE_BIG)
  349:                         | (intern->r_extern ? RELOC_BITS3_EXTERN_BIG : 0));
  350:     }
  351:   else
  352:     {
  353:       ext->r_bits[0] = r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE;
  354:       ext->r_bits[1] = r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE;
  355:       ext->r_bits[2] = r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE;
  356:       ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_LITTLE)
  357:                          & RELOC_BITS3_TYPE_LITTLE)
  358:                         | ((intern->r_type >> RELOC_BITS3_TYPEHI_SH_LITTLE
  359:                             & RELOC_BITS3_TYPEHI_LITTLE))
  360:                         | (intern->r_extern ? RELOC_BITS3_EXTERN_LITTLE : 0));
  361:     }
  362: }
  363: 
  364: /* Finish canonicalizing a reloc.  Part of this is generic to all
  365:    ECOFF targets, and that part is in ecoff.c.  The rest is done in
  366:    this backend routine.  It must fill in the howto field.  */
  367: 
  368: static void
  369: mips_adjust_reloc_in (abfd, intern, rptr)
  370:      bfd *abfd;
  371:      const struct internal_reloc *intern;
  372:      arelent *rptr;
  373: {
  374:   if (intern->r_type > MIPS_R_PCREL16)
  375:     abort ();
  376: 
  377:   if (! intern->r_extern
  378:       && (intern->r_type == MIPS_R_GPREL
  379:           || intern->r_type == MIPS_R_LITERAL))
  380:     rptr->addend += ecoff_data (abfd)->gp;
  381: 
  382:   /* If the type is MIPS_R_IGNORE, make sure this is a reference to
  383:      the absolute section so that the reloc is ignored.  */
  384:   if (intern->r_type == MIPS_R_IGNORE)
  385:     rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
  386: 
  387:   rptr->howto = &mips_howto_table[intern->r_type];
  388: }
  389: 
  390: /* Make any adjustments needed to a reloc before writing it out.  None
  391:    are needed for MIPS.  */
  392: 
  393: static void
  394: mips_adjust_reloc_out (abfd, rel, intern)
  395:      bfd *abfd ATTRIBUTE_UNUSED;
  396:      const arelent *rel ATTRIBUTE_UNUSED;
  397:      struct internal_reloc *intern ATTRIBUTE_UNUSED;
  398: {
  399: }
  400: 
  401: /* ECOFF relocs are either against external symbols, or against
  402:    sections.  If we are producing relocatable output, and the reloc
  403:    is against an external symbol, and nothing has given us any
  404:    additional addend, the resulting reloc will also be against the
  405:    same symbol.  In such a case, we don't want to change anything
  406:    about the way the reloc is handled, since it will all be done at
  407:    final link time.  Rather than put special case code into
  408:    bfd_perform_relocation, all the reloc types use this howto
  409:    function.  It just short circuits the reloc if producing
  410:    relocatable output against an external symbol.  */
  411: 
  412: static bfd_reloc_status_type
  413: mips_generic_reloc (abfd,
  414:                     reloc_entry,
  415:                     symbol,
  416:                     data,
  417:                     input_section,
  418:                     output_bfd,
  419:                     error_message)
  420:      bfd *abfd ATTRIBUTE_UNUSED;
  421:      arelent *reloc_entry;
  422:      asymbol *symbol;
  423:      PTR data ATTRIBUTE_UNUSED;
  424:      asection *input_section;
  425:      bfd *output_bfd;
  426:      char **error_message ATTRIBUTE_UNUSED;
  427: {
  428:   if (output_bfd != (bfd *) NULL
  429:       && (symbol->flags & BSF_SECTION_SYM) == 0
  430:       && reloc_entry->addend == 0)
  431:     {
  432:       reloc_entry->address += input_section->output_offset;
  433:       return bfd_reloc_ok;
  434:     }
  435: 
  436:   return bfd_reloc_continue;
  437: }
  438: 
  439: /* Do a REFHI relocation.  This has to be done in combination with a
  440:    REFLO reloc, because there is a carry from the REFLO to the REFHI.
  441:    Here we just save the information we need; we do the actual
  442:    relocation when we see the REFLO.  MIPS ECOFF requires that the
  443:    REFLO immediately follow the REFHI.  As a GNU extension, we permit
  444:    an arbitrary number of HI relocs to be associated with a single LO
  445:    reloc.  This extension permits gcc to output the HI and LO relocs
  446:    itself.  */
  447: 
  448: struct mips_hi
  449: {
  450:   struct mips_hi *next;
  451:   bfd_byte *addr;
  452:   bfd_vma addend;
  453: };
  454: 
  455: /* FIXME: This should not be a static variable.  */
  456: 
  457: static struct mips_hi *mips_refhi_list;
  458: 
  459: static bfd_reloc_status_type
  460: mips_refhi_reloc (abfd,
  461:                   reloc_entry,
  462:                   symbol,
  463:                   data,
  464:                   input_section,
  465:                   output_bfd,
  466:                   error_message)
  467:      bfd *abfd ATTRIBUTE_UNUSED;
  468:      arelent *reloc_entry;
  469:      asymbol *symbol;
  470:      PTR data;
  471:      asection *input_section;
  472:      bfd *output_bfd;
  473:      char **error_message ATTRIBUTE_UNUSED;
  474: {
  475:   bfd_reloc_status_type ret;
  476:   bfd_vma relocation;
  477:   struct mips_hi *n;
  478: 
  479:   /* If we're relocating, and this an external symbol, we don't want
  480:      to change anything.  */
  481:   if (output_bfd != (bfd *) NULL
  482:       && (symbol->flags & BSF_SECTION_SYM) == 0
  483:       && reloc_entry->addend == 0)
  484:     {
  485:       reloc_entry->address += input_section->output_offset;
  486:       return bfd_reloc_ok;
  487:     }
  488: 
  489:   ret = bfd_reloc_ok;
  490:   if (bfd_is_und_section (symbol->section)
  491:       && output_bfd == (bfd *) NULL)
  492:     ret = bfd_reloc_undefined;
  493: 
  494:   if (bfd_is_com_section (symbol->section))
  495:     relocation = 0;
  496:   else
  497:     relocation = symbol->value;
  498: 
  499:   relocation += symbol->section->output_section->vma;
  500:   relocation += symbol->section->output_offset;
  501:   relocation += reloc_entry->addend;
  502: 
  503:   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
  504:     return bfd_reloc_outofrange;
  505: 
  506:   /* Save the information, and let REFLO do the actual relocation.  */
  507:   n = (struct mips_hi *) bfd_malloc ((bfd_size_type) sizeof *n);
  508:   if (n == NULL)
  509:     return bfd_reloc_outofrange;
  510:   n->addr = (bfd_byte *) data + reloc_entry->address;
  511:   n->addend = relocation;
  512:   n->next = mips_refhi_list;
  513:   mips_refhi_list = n;
  514: 
  515:   if (output_bfd != (bfd *) NULL)
  516:     reloc_entry->address += input_section->output_offset;
  517: 
  518:   return ret;
  519: }
  520: 
  521: /* Do a REFLO relocation.  This is a straightforward 16 bit inplace
  522:    relocation; this function exists in order to do the REFHI
  523:    relocation described above.  */
  524: 
  525: static bfd_reloc_status_type
  526: mips_reflo_reloc (abfd,
  527:                   reloc_entry,
  528:                   symbol,
  529:                   data,
  530:                   input_section,
  531:                   output_bfd,
  532:                   error_message)
  533:      bfd *abfd;
  534:      arelent *reloc_entry;
  535:      asymbol *symbol;
  536:      PTR data;
  537:      asection *input_section;
  538:      bfd *output_bfd;
  539:      char **error_message;
  540: {
  541:   if (mips_refhi_list != NULL)
  542:     {
  543:       struct mips_hi *l;
  544: 
  545:       l = mips_refhi_list;
  546:       while (l != NULL)
  547:         {
  548:           unsigned long insn;
  549:           unsigned long val;
  550:           unsigned long vallo;
  551:           struct mips_hi *next;
  552: 
  553:           /* Do the REFHI relocation.  Note that we actually don't
  554:              need to know anything about the REFLO itself, except
  555:              where to find the low 16 bits of the addend needed by the
  556:              REFHI.  */
  557:           insn = bfd_get_32 (abfd, l->addr);
  558:           vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address)
  559:                    & 0xffff);
  560:           val = ((in