Back to index

cell-binutils  2.17cvs20070401
elf32-bfin.c
Go to the documentation of this file.
00001 /* ADI Blackfin BFD support for 32-bit ELF.
00002    Copyright 2005, 2006, 2007 Free Software Foundation, Inc.
00003 
00004    This file is part of BFD, the Binary File Descriptor library.
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010 
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015 
00016    You should have received a copy of the GNU General Public License
00017    along with this program; if not, write to the Free Software
00018    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
00019    USA.  */
00020 
00021 #include "bfd.h"
00022 #include "sysdep.h"
00023 #include "libbfd.h"
00024 #include "elf-bfd.h"
00025 #include "elf/bfin.h"
00026 #include "elf/dwarf2.h"
00027 #include "hashtab.h"
00028 
00029 /* FUNCTION : bfin_pltpc_reloc
00030    ABSTRACT : TODO : figure out how to handle pltpc relocs.  */
00031 static bfd_reloc_status_type
00032 bfin_pltpc_reloc (
00033      bfd *abfd ATTRIBUTE_UNUSED,
00034      arelent *reloc_entry ATTRIBUTE_UNUSED,
00035      asymbol *symbol ATTRIBUTE_UNUSED,
00036      PTR data ATTRIBUTE_UNUSED,
00037      asection *input_section ATTRIBUTE_UNUSED,
00038      bfd *output_bfd ATTRIBUTE_UNUSED,
00039      char **error_message ATTRIBUTE_UNUSED)
00040 {
00041   bfd_reloc_status_type flag = bfd_reloc_ok;
00042   return flag;
00043 }
00044 
00045 
00046 static bfd_reloc_status_type
00047 bfin_pcrel24_reloc (bfd *abfd,
00048                     arelent *reloc_entry,
00049                     asymbol *symbol,
00050                     PTR data,
00051                     asection *input_section,
00052                     bfd *output_bfd,
00053                     char **error_message ATTRIBUTE_UNUSED)
00054 {
00055   bfd_vma relocation;
00056   bfd_size_type addr = reloc_entry->address;
00057   bfd_vma output_base = 0;
00058   reloc_howto_type *howto = reloc_entry->howto;
00059   asection *output_section;
00060   bfd_boolean relocatable = (output_bfd != NULL);
00061 
00062   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
00063     return bfd_reloc_outofrange;
00064 
00065   if (bfd_is_und_section (symbol->section)
00066       && (symbol->flags & BSF_WEAK) == 0
00067       && !relocatable)
00068     return bfd_reloc_undefined;
00069 
00070   if (bfd_is_com_section (symbol->section))
00071     relocation = 0;
00072   else
00073     relocation = symbol->value;
00074 
00075   output_section = symbol->section->output_section;
00076 
00077   if (relocatable)
00078     output_base = 0;
00079   else
00080     output_base = output_section->vma;
00081 
00082   if (!relocatable || !strcmp (symbol->name, symbol->section->name))
00083     relocation += output_base + symbol->section->output_offset;
00084 
00085   if (!relocatable && !strcmp (symbol->name, symbol->section->name))
00086     relocation += reloc_entry->addend;
00087 
00088   relocation -= input_section->output_section->vma + input_section->output_offset;
00089   relocation -= reloc_entry->address;
00090 
00091   if (howto->complain_on_overflow != complain_overflow_dont)
00092     {
00093       bfd_reloc_status_type status;
00094       status = bfd_check_overflow (howto->complain_on_overflow,
00095                                howto->bitsize,
00096                                howto->rightshift,
00097                                bfd_arch_bits_per_address(abfd),
00098                                relocation);
00099       if (status != bfd_reloc_ok)
00100        return status;
00101     }
00102 
00103   /* if rightshift is 1 and the number odd, return error.  */
00104   if (howto->rightshift && (relocation & 0x01))
00105     {
00106       fprintf(stderr, "relocation should be even number\n");
00107       return bfd_reloc_overflow;
00108     }
00109 
00110   relocation >>= (bfd_vma) howto->rightshift;
00111   /* Shift everything up to where it's going to be used.  */
00112 
00113   relocation <<= (bfd_vma) howto->bitpos;
00114 
00115   if (relocatable)
00116     {
00117       reloc_entry->address += input_section->output_offset;
00118       reloc_entry->addend += symbol->section->output_offset;
00119     }
00120 
00121   {
00122     short x;
00123 
00124     /* We are getting reloc_entry->address 2 byte off from
00125        the start of instruction. Assuming absolute postion
00126        of the reloc data. But, following code had been written assuming
00127        reloc address is starting at begining of instruction.
00128        To compensate that I have increased the value of
00129        relocation by 1 (effectively 2) and used the addr -2 instead of addr.  */
00130 
00131     relocation += 1;
00132     x = bfd_get_16 (abfd, (bfd_byte *) data + addr - 2);
00133     x = (x & 0xff00) | ((relocation >> 16) & 0xff);
00134     bfd_put_16 (abfd, x, (unsigned char *) data + addr - 2);
00135 
00136     x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
00137     x = relocation & 0xFFFF;
00138     bfd_put_16 (abfd, x, (unsigned char *) data + addr );
00139   }
00140   return bfd_reloc_ok;
00141 }
00142 
00143 static bfd_reloc_status_type
00144 bfin_imm16_reloc (bfd *abfd,
00145                 arelent *reloc_entry,
00146                 asymbol *symbol,
00147                 PTR data,
00148                 asection *input_section,
00149                 bfd *output_bfd,
00150                 char **error_message ATTRIBUTE_UNUSED)
00151 {
00152   bfd_vma relocation, x;
00153   bfd_size_type reloc_addr = reloc_entry->address;
00154   bfd_vma output_base = 0;
00155   reloc_howto_type *howto = reloc_entry->howto;
00156   asection *output_section;
00157   bfd_boolean relocatable = (output_bfd != NULL);
00158 
00159   /* Is the address of the relocation really within the section?  */
00160   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
00161     return bfd_reloc_outofrange;
00162 
00163   if (bfd_is_und_section (symbol->section)
00164       && (symbol->flags & BSF_WEAK) == 0
00165       && !relocatable)
00166     return bfd_reloc_undefined;
00167 
00168   output_section = symbol->section->output_section;
00169   relocation = symbol->value;
00170 
00171   /* Convert input-section-relative symbol value to absolute.  */
00172   if (relocatable)
00173     output_base = 0;
00174   else
00175     output_base = output_section->vma;
00176 
00177   if (!relocatable || !strcmp (symbol->name, symbol->section->name))
00178     relocation += output_base + symbol->section->output_offset;
00179 
00180   /* Add in supplied addend.  */
00181   relocation += reloc_entry->addend;
00182 
00183   if (relocatable)
00184     {
00185       reloc_entry->address += input_section->output_offset;
00186       reloc_entry->addend += symbol->section->output_offset;
00187     }
00188   else
00189     {
00190       reloc_entry->addend = 0;
00191     }
00192 
00193   if (howto->complain_on_overflow != complain_overflow_dont)
00194     {
00195       bfd_reloc_status_type flag;
00196       flag = bfd_check_overflow (howto->complain_on_overflow,
00197                              howto->bitsize,
00198                              howto->rightshift,
00199                              bfd_arch_bits_per_address(abfd),
00200                              relocation);
00201       if (flag != bfd_reloc_ok)
00202        return flag;
00203     }
00204 
00205   /* Here the variable relocation holds the final address of the
00206      symbol we are relocating against, plus any addend.  */
00207 
00208   relocation >>= (bfd_vma) howto->rightshift;
00209   x = relocation;
00210   bfd_put_16 (abfd, x, (unsigned char *) data + reloc_addr);
00211   return bfd_reloc_ok;
00212 }
00213 
00214 
00215 static bfd_reloc_status_type
00216 bfin_byte4_reloc (bfd *abfd,
00217                   arelent *reloc_entry,
00218                   asymbol *symbol,
00219                   PTR data,
00220                   asection *input_section,
00221                   bfd *output_bfd,
00222                   char **error_message ATTRIBUTE_UNUSED)
00223 {
00224   bfd_vma relocation, x;
00225   bfd_size_type addr = reloc_entry->address;
00226   bfd_vma output_base = 0;
00227   asection *output_section;
00228   bfd_boolean relocatable = (output_bfd != NULL);
00229 
00230   /* Is the address of the relocation really within the section?  */
00231   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
00232     return bfd_reloc_outofrange;
00233 
00234   if (bfd_is_und_section (symbol->section)
00235       && (symbol->flags & BSF_WEAK) == 0
00236       && !relocatable)
00237     return bfd_reloc_undefined;
00238 
00239   output_section = symbol->section->output_section;
00240   relocation = symbol->value;
00241   /* Convert input-section-relative symbol value to absolute.  */
00242   if (relocatable)
00243     output_base = 0;
00244   else
00245     output_base = output_section->vma;
00246 
00247   if ((symbol->name
00248        && symbol->section->name
00249        && !strcmp (symbol->name, symbol->section->name))
00250       || !relocatable)
00251     {
00252       relocation += output_base + symbol->section->output_offset;
00253     }
00254 
00255   relocation += reloc_entry->addend;
00256 
00257   if (relocatable)
00258     {
00259       /* This output will be relocatable ... like ld -r. */
00260       reloc_entry->address += input_section->output_offset;
00261       reloc_entry->addend += symbol->section->output_offset;
00262     }
00263   else
00264     {
00265       reloc_entry->addend = 0;
00266     }
00267 
00268   /* Here the variable relocation holds the final address of the
00269      symbol we are relocating against, plus any addend.  */
00270   x = relocation & 0xFFFF0000;
00271   x >>=16;
00272   bfd_put_16 (abfd, x, (unsigned char *) data + addr + 2);
00273 
00274   x = relocation & 0x0000FFFF;
00275   bfd_put_16 (abfd, x, (unsigned char *) data + addr);
00276   return bfd_reloc_ok;
00277 }
00278 
00279 /* bfin_bfd_reloc handles the blackfin arithmetic relocations.
00280    Use this instead of bfd_perform_relocation.  */
00281 static bfd_reloc_status_type
00282 bfin_bfd_reloc (bfd *abfd,
00283               arelent *reloc_entry,
00284               asymbol *symbol,
00285               PTR data,
00286               asection *input_section,
00287               bfd *output_bfd,
00288               char **error_message ATTRIBUTE_UNUSED)
00289 {
00290   bfd_vma relocation;
00291   bfd_size_type addr = reloc_entry->address;
00292   bfd_vma output_base = 0;
00293   reloc_howto_type *howto = reloc_entry->howto;
00294   asection *output_section;
00295   bfd_boolean relocatable = (output_bfd != NULL);
00296 
00297   /* Is the address of the relocation really within the section?  */
00298   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
00299     return bfd_reloc_outofrange;
00300 
00301   if (bfd_is_und_section (symbol->section)
00302       && (symbol->flags & BSF_WEAK) == 0
00303       && !relocatable)
00304     return bfd_reloc_undefined;
00305 
00306   /* Get symbol value.  (Common symbols are special.)  */
00307   if (bfd_is_com_section (symbol->section))
00308     relocation = 0;
00309   else
00310     relocation = symbol->value;
00311 
00312   output_section = symbol->section->output_section;
00313 
00314   /* Convert input-section-relative symbol value to absolute.  */
00315   if (relocatable)
00316     output_base = 0;
00317   else
00318     output_base = output_section->vma;
00319 
00320   if (!relocatable || !strcmp (symbol->name, symbol->section->name))
00321     relocation += output_base + symbol->section->output_offset;
00322 
00323   if (!relocatable && !strcmp (symbol->name, symbol->section->name))
00324     {
00325       /* Add in supplied addend.  */
00326       relocation += reloc_entry->addend;
00327     }
00328 
00329   /* Here the variable relocation holds the final address of the
00330      symbol we are relocating against, plus any addend.  */
00331 
00332   if (howto->pc_relative == TRUE)
00333     {
00334       relocation -= input_section->output_section->vma + input_section->output_offset;
00335 
00336       if (howto->pcrel_offset == TRUE)
00337         relocation -= reloc_entry->address;
00338     }
00339 
00340   if (relocatable)
00341     {
00342       reloc_entry->address += input_section->output_offset;
00343       reloc_entry->addend += symbol->section->output_offset;
00344     }
00345 
00346   if (howto->complain_on_overflow != complain_overflow_dont)
00347     {
00348       bfd_reloc_status_type status;
00349 
00350       status = bfd_check_overflow (howto->complain_on_overflow,
00351                                   howto->bitsize,
00352                                   howto->rightshift,
00353                                   bfd_arch_bits_per_address(abfd),
00354                                   relocation);
00355       if (status != bfd_reloc_ok)
00356        return status;
00357     }
00358 
00359   /* If rightshift is 1 and the number odd, return error.  */
00360   if (howto->rightshift && (relocation & 0x01))
00361     {
00362       fprintf(stderr, "relocation should be even number\n");
00363       return bfd_reloc_overflow;
00364     }
00365 
00366   relocation >>= (bfd_vma) howto->rightshift;
00367 
00368   /* Shift everything up to where it's going to be used.  */
00369 
00370   relocation <<= (bfd_vma) howto->bitpos;
00371 
00372 #define DOIT(x)                                                       \
00373   x = ( (x & ~howto->dst_mask) | (relocation & howto->dst_mask))
00374 
00375   /* handle 8 and 16 bit relocations here. */
00376   switch (howto->size)
00377     {
00378     case 0:
00379       {
00380         char x = bfd_get_8 (abfd, (char *) data + addr);
00381         DOIT (x);
00382         bfd_put_8 (abfd, x, (unsigned char *) data + addr);
00383       }
00384       break;
00385 
00386     case 1:
00387       {
00388         unsigned short x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
00389         DOIT (x);
00390         bfd_put_16 (abfd, (bfd_vma) x, (unsigned char *) data + addr);
00391       }
00392       break;
00393 
00394     default:
00395       return bfd_reloc_other;
00396     }
00397 
00398   return bfd_reloc_ok;
00399 }
00400 
00401 /* HOWTO Table for blackfin.
00402    Blackfin relocations are fairly complicated.
00403    Some of the salient features are
00404    a. Even numbered offsets. A number of (not all) relocations are
00405       even numbered. This means that the rightmost bit is not stored.
00406       Needs to right shift by 1 and check to see if value is not odd
00407    b. A relocation can be an expression. An expression takes on
00408       a variety of relocations arranged in a stack.
00409    As a result, we cannot use the standard generic function as special
00410    function. We will have our own, which is very similar to the standard
00411    generic function except that it understands how to get the value from
00412    the relocation stack. .  */
00413 
00414 #define BFIN_RELOC_MIN 0
00415 #define BFIN_RELOC_MAX 0x21
00416 #define BFIN_GNUEXT_RELOC_MIN 0x40
00417 #define BFIN_GNUEXT_RELOC_MAX 0x43
00418 #define BFIN_ARELOC_MIN 0xE0
00419 #define BFIN_ARELOC_MAX 0xF3
00420 
00421 static reloc_howto_type bfin_howto_table [] =
00422 {
00423   /* This reloc does nothing. .  */
00424   HOWTO (R_unused0,         /* type.  */
00425         0,                  /* rightshift.  */
00426         2,                  /* size (0 = byte, 1 = short, 2 = long).  */
00427         32,                 /* bitsize.  */
00428         FALSE,                     /* pc_relative.  */
00429         0,                  /* bitpos.  */
00430         complain_overflow_bitfield, /* complain_on_overflow.  */
00431         bfd_elf_generic_reloc,     /* special_function.  */
00432         "R_unused0",        /* name.  */
00433         FALSE,                     /* partial_inplace.  */
00434         0,                  /* src_mask.  */
00435         0,                  /* dst_mask.  */
00436         FALSE),             /* pcrel_offset.  */
00437 
00438   HOWTO (R_pcrel5m2,        /* type.  */
00439         1,                  /* rightshift.  */
00440         1,                  /* size (0 = byte, 1 = short, 2 = long)..  */
00441         4,                  /* bitsize.  */
00442         TRUE,               /* pc_relative.  */
00443         0,                  /* bitpos.  */
00444         complain_overflow_unsigned, /* complain_on_overflow.  */
00445         bfin_bfd_reloc,     /* special_function.  */
00446         "R_pcrel5m2",              /* name.  */
00447         FALSE,                     /* partial_inplace.  */
00448         0,                  /* src_mask.  */
00449         0x0000000F,         /* dst_mask.  */
00450         FALSE),             /* pcrel_offset.  */
00451 
00452   HOWTO (R_unused1,         /* type.  */
00453         0,                  /* rightshift.  */
00454         2,                  /* size (0 = byte, 1 = short, 2 = long).  */
00455         32,                 /* bitsize.  */
00456         FALSE,                     /* pc_relative.  */
00457         0,                  /* bitpos.  */
00458         complain_overflow_bitfield, /* complain_on_overflow.  */
00459         bfd_elf_generic_reloc,     /* special_function.  */
00460         "R_unused1",        /* name.  */
00461         FALSE,                     /* partial_inplace.  */
00462         0,                  /* src_mask.  */
00463         0,                  /* dst_mask.  */
00464         FALSE),             /* pcrel_offset.  */
00465 
00466   HOWTO (R_pcrel10,         /* type.  */
00467         1,                  /* rightshift.  */
00468         1,                  /* size (0 = byte, 1 = short, 2 = long).  */
00469         10,                 /* bitsize.  */
00470         TRUE,               /* pc_relative.  */
00471         0,                  /* bitpos.  */
00472         complain_overflow_signed, /* complain_on_overflow.  */
00473         bfin_bfd_reloc,     /* special_function.  */
00474         "R_pcrel10",        /* name.  */
00475         FALSE,                     /* partial_inplace.  */
00476         0,                  /* src_mask.  */
00477         0x000003FF,         /* dst_mask.  */
00478         TRUE),                     /* pcrel_offset.  */
00479 
00480   HOWTO (R_pcrel12_jump,    /* type.  */
00481         1,                  /* rightshift.  */
00482                             /* the offset is actually 13 bit
00483                                aligned on a word boundary so
00484                                only 12 bits have to be used.
00485                                Right shift the rightmost bit..  */
00486         1,                  /* size (0 = byte, 1 = short, 2 = long).  */
00487         12,                 /* bitsize.  */
00488         TRUE,               /* pc_relative.  */
00489         0,                  /* bitpos.  */
00490         complain_overflow_signed, /* complain_on_overflow.  */
00491         bfin_bfd_reloc,     /* special_function.  */
00492         "R_pcrel12_jump",   /* name.  */
00493         FALSE,                     /* partial_inplace.  */
00494         0,                  /* src_mask.  */
00495         0x0FFF,             /* dst_mask.  */
00496         TRUE),                     /* pcrel_offset.  */
00497 
00498   HOWTO (R_rimm16,          /* type.  */
00499         0,                  /* rightshift.  */
00500         1,                  /* size (0 = byte, 1 = short, 2 = long).  */
00501         16,                 /* bitsize.  */
00502         FALSE,                     /* pc_relative.  */
00503         0,                  /* bitpos.  */
00504         complain_overflow_signed, /* complain_on_overflow.  */
00505         bfin_imm16_reloc,   /* special_function.  */
00506         "R_rimm16",         /* name.  */
00507         FALSE,                     /* partial_inplace.  */
00508         0,                  /* src_mask.  */
00509         0x0000FFFF,         /* dst_mask.  */
00510         TRUE),                     /* pcrel_offset.  */
00511 
00512   HOWTO (R_luimm16,         /* type.  */
00513         0,                  /* rightshift.  */
00514         1,                  /* size (0 = byte, 1 = short, 2 = long).  */
00515         16,                 /* bitsize.  */
00516         FALSE,                     /* pc_relative.  */
00517         0,                  /* bitpos.  */
00518         complain_overflow_dont, /* complain_on_overflow.  */
00519         bfin_imm16_reloc,   /* special_function.  */
00520         "R_luimm16",        /* name.  */
00521         FALSE,                     /* partial_inplace.  */
00522         0,                  /* src_mask.  */
00523         0x0000FFFF,         /* dst_mask.  */
00524         TRUE),                     /* pcrel_offset.  */
00525 
00526   HOWTO (R_huimm16,         /* type.  */
00527         16,                 /* rightshift.  */
00528         1,                  /* size (0 = byte, 1 = short, 2 = long).  */
00529         16,                 /* bitsize.  */
00530         FALSE,                     /* pc_relative.  */
00531         0,                  /* bitpos.  */
00532         complain_overflow_unsigned, /* complain_on_overflow.  */
00533         bfin_imm16_reloc,   /* special_function.  */
00534         "R_huimm16",        /* name.  */
00535         FALSE,                     /* partial_inplace.  */
00536         0,                  /* src_mask.  */
00537         0x0000FFFF,         /* dst_mask.  */
00538         TRUE),                     /* pcrel_offset.  */
00539 
00540   HOWTO (R_pcrel12_jump_s,  /* type.  */
00541         1,                  /* rightshift.  */
00542         1,                  /* size (0 = byte, 1 = short, 2 = long).  */
00543         12,                 /* bitsize.  */
00544         TRUE,               /* pc_relative.  */
00545         0,                  /* bitpos.  */
00546         complain_overflow_signed, /* complain_on_overflow.  */
00547         bfin_bfd_reloc,     /* special_function.  */
00548         "R_pcrel12_jump_s", /* name.  */
00549         FALSE,                     /* partial_inplace.  */
00550         0,                  /* src_mask.  */
00551         0x00000FFF,         /* dst_mask.  */
00552         TRUE),                     /* pcrel_offset.  */
00553 
00554   HOWTO (R_pcrel24_jump_x,  /* type.  */
00555          1,                 /* rightshift.  */
00556          2,                 /* size (0 = byte, 1 = short, 2 = long).  */
00557          24,                /* bitsize.  */
00558          TRUE,                     /* pc_relative.  */
00559          0,                 /* bitpos.  */
00560          complain_overflow_signed, /* complain_on_overflow.  */
00561          bfin_pcrel24_reloc,       /* special_function.  */
00562          "R_pcrel24_jump_x",       /* name.  */
00563         FALSE,                     /* partial_inplace.  */
00564         0,                  /* src_mask.  */
00565         0x00FFFFFF,         /* dst_mask.  */
00566         TRUE),                     /* pcrel_offset.  */
00567 
00568   HOWTO (R_pcrel24,         /* type.  */
00569         1,                  /* rightshift.  */
00570         2,                  /* size (0 = byte, 1 = short, 2 = long).  */
00571         24,                 /* bitsize.  */
00572         TRUE,               /* pc_relative.  */
00573         0,                  /* bitpos.  */
00574         complain_overflow_signed, /* complain_on_overflow.  */
00575         bfin_pcrel24_reloc, /* special_function.  */
00576         "R_pcrel24",        /* name.  */
00577         FALSE,                     /* partial_inplace.  */
00578         0,                  /* src_mask.  */
00579         0x00FFFFFF,         /* dst_mask.  */
00580         TRUE),                     /* pcrel_offset.  */
00581 
00582   HOWTO (R_unusedb,         /* type.  */
00583         0,                  /* rightshift.  */
00584         2,                  /* size (0 = byte, 1 = short, 2 = long).  */
00585         32,                 /* bitsize.  */
00586         FALSE,                     /* pc_relative.  */
00587         0,                  /* bitpos.  */
00588         complain_overflow_dont, /* complain_on_overflow.  */
00589         bfd_elf_generic_reloc,     /* special_function.  */
00590         "R_unusedb",        /* name.  */
00591         FALSE,                     /* partial_inplace.  */
00592         0,                  /* src_mask.  */
00593         0,                  /* dst_mask.  */
00594         FALSE),             /* pcrel_offset.  */
00595 
00596   HOWTO (R_unusedc,         /* type.  */
00597         0,                  /* rightshift.  */
00598         2,                  /* size (0 = byte, 1 = short, 2 = long).  */
00599         32,                 /* bitsize.  */
00600         FALSE,                     /* pc_relative.  */
00601         0,                  /* bitpos.  */
00602         complain_overflow_dont, /* complain_on_overflow.  */
00603         bfd_elf_generic_reloc,     /* special_function.  */
00604         "R_unusedc",        /* name.  */
00605         FALSE,                     /* partial_inplace.  */
00606         0,                  /* src_mask.  */
00607         0,                  /* dst_mask.  */
00608         FALSE),             /* pcrel_offset.  */
00609 
00610   HOWTO (R_pcrel24_jump_l,  /* type.  */
00611         1,                  /* rightshift.  */
00612         2,                  /* size (0 = byte, 1 = short, 2 = long).  */
00613         24,                 /* bitsize.  */
00614         TRUE,               /* pc_relative.  */
00615         0,                  /* bitpos.  */
00616         complain_overflow_signed, /* complain_on_overflow.  */
00617         bfin_pcrel24_reloc, /* special_function.  */
00618         "R_pcrel24_jump_l", /* name.  */
00619         FALSE,                     /* partial_inplace.  */
00620         0,                  /* src_mask.  */
00621         0x00FFFFFF,         /* dst_mask.  */
00622         TRUE),                     /* pcrel_offset.  */
00623 
00624   HOWTO (R_pcrel24_call_x,  /* type.  */
00625         1,                  /* rightshift.  */
00626         2,                  /* size (0 = byte, 1 = short, 2 = long).  */
00627         24,                 /* bitsize.  */
00628         TRUE,               /* pc_relative.  */
00629         0,                  /* bitpos.  */
00630         complain_overflow_signed, /* complain_on_overflow.  */
00631         bfin_pcrel24_reloc, /* special_function.  */
00632         "R_pcrel24_call_x", /* name.  */
00633         FALSE,                     /* partial_inplace.  */
00634         0,                  /* src_mask.  */
00635         0x00FFFFFF,         /* dst_mask.  */
00636         TRUE),                     /* pcrel_offset.  */
00637 
00638   HOWTO (R_var_eq_symb,            /* type.  */
00639         0,                  /* rightshift.  */
00640         2,                  /* size (0 = byte, 1 = short, 2 = long).  */
00641         32,                 /* bitsize.  */
00642         FALSE,                     /* pc_relative.  */
00643         0,                  /* bitpos.  */
00644         complain_overflow_bitfield, /* complain_on_overflow.  */
00645         bfin_bfd_reloc,     /* special_function.  */
00646         "R_var_eq_symb",           /* name.  */
00647         FALSE,                     /* partial_inplace.  */
00648         0,                  /* src_mask.  */
00649         0,                  /* dst_mask.  */
00650         FALSE),             /* pcrel_offset.  */
00651 
00652   HOWTO (R_byte_data,              /* type.  */
00653         0,                  /* rightshift.  */
00654         0,                  /* size (0 = byte, 1 = short, 2 = long).  */
00655         8,                  /* bitsize.  */
00656         FALSE,                     /* pc_relative.  */
00657         0,                  /* bitpos.  */
00658         complain_overflow_unsigned, /* complain_on_overflow.  */
00659         bfin_bfd_reloc,     /* special_function.  */
00660         "R_byte_data",             /* name.  */
00661         FALSE,                     /* partial_inplace.  */
00662         0,                  /* src_mask.  */
00663         0xFF,               /* dst_mask.  */
00664         TRUE),                     /* pcrel_offset.  */
00665 
00666   HOWTO (R_byte2_data,             /* type.  */
00667         0,                  /* rightshift.  */
00668         1,                  /* size (0 = byte, 1 = short, 2 = long).  */
00669         16,                 /* bitsize.  */
00670         FALSE,                     /* pc_relative.  */
00671         0,                  /* bitpos.  */
00672         complain_overflow_signed, /* complain_on_overflow.  */
00673         bfin_bfd_reloc,     /* special_function.  */
00674         "R_byte2_data",     /* name.  */
00675         FALSE,                     /* partial_inplace.  */
00676         0,                  /* src_mask.  */
00677         0xFFFF,             /* dst_mask.  */
00678         TRUE),                     /* pcrel_offset.  */
00679 
00680   HOWTO (R_byte4_data,             /* type.  */
00681         0,                  /* rightshift.  */
00682         2,                  /* size (0 = byte, 1 = short, 2 = long).  */
00683         32,                 /* bitsize.  */
00684         FALSE,                     /* pc_relative.  */
00685         0,                  /* bitpos.  */
00686         complain_overflow_unsigned, /* complain_on_overflow.  */
00687         bfin_byte4_reloc,   /* special_function.  */
00688         "R_byte4_data",     /* name.  */
00689         FALSE,                     /* partial_inplace.  */
00690         0,                  /* src_mask.  */
00691         0xFFFFFFFF,         /* dst_mask.  */
00692         TRUE),                     /* pcrel_offset.  */
00693 
00694   HOWTO (R_pcrel11,         /* type.  */
00695         1,                  /* rightshift.  */
00696         1,                  /* size (0 = byte, 1 = short, 2 = long).  */
00697         10,                 /* bitsize.  */
00698         TRUE,               /* pc_relative.  */
00699         0,                  /* bitpos.  */
00700         complain_overflow_unsigned, /* complain_on_overflow.  */
00701         bfin_bfd_reloc,     /* special_function.  */
00702         "R_pcrel11",        /* name.  */
00703         FALSE,                     /* partial_inplace.  */
00704         0,                  /* src_mask.  */
00705         0x000003FF,         /* dst_mask.  */
00706         FALSE),             /* pcrel_offset.  */
00707 
00708 
00709   /* A 18-bit signed operand with the GOT offset for the address of
00710      the symbol.  */
00711   HOWTO (R_BFIN_GOT17M4,        /* type */
00712         2,                  /* rightshift */
00713         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00714         16,                 /* bitsize */
00715         FALSE,                     /* pc_relative */
00716         0,                  /* bitpos */
00717         complain_overflow_signed, /* complain_on_overflow */
00718         bfd_elf_generic_reloc,     /* special_function */
00719         "R_BFIN_GOT12",            /* name */
00720         FALSE,                     /* partial_inplace */
00721         0xffff,              /* src_mask */
00722         0xffff,              /* dst_mask */
00723         FALSE),              /* pcrel_offset */
00724 
00725   /* The upper 16 bits of the GOT offset for the address of the
00726      symbol.  */
00727   HOWTO (R_BFIN_GOTHI,              /* type */
00728         0,                  /* rightshift */
00729         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00730         16,                 /* bitsize */
00731         FALSE,                     /* pc_relative */
00732         0,                  /* bitpos */
00733         complain_overflow_dont, /* complain_on_overflow */
00734         bfd_elf_generic_reloc,     /* special_function */
00735         "R_BFIN_GOTHI",            /* name */
00736         FALSE,                     /* partial_inplace */
00737         0xffff,                     /* src_mask */
00738         0xffff,             /* dst_mask */
00739         FALSE),              /* pcrel_offset */
00740 
00741   /* The lower 16 bits of the GOT offset for the address of the
00742      symbol.  */
00743   HOWTO (R_BFIN_GOTLO,              /* type */
00744         0,                  /* rightshift */
00745         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00746         16,                 /* bitsize */
00747         FALSE,                     /* pc_relative */
00748         0,                  /* bitpos */
00749         complain_overflow_dont, /* complain_on_overflow */
00750         bfd_elf_generic_reloc,     /* special_function */
00751         "R_BFIN_GOTLO",            /* name */
00752         FALSE,                     /* partial_inplace */
00753         0xffff,             /* src_mask */
00754         0xffff,             /* dst_mask */
00755         FALSE),              /* pcrel_offset */
00756 
00757   /* The 32-bit address of the canonical descriptor of a function.  */
00758   HOWTO (R_BFIN_FUNCDESC,   /* type */
00759         0,                  /* rightshift */
00760         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00761         32,                 /* bitsize */
00762         FALSE,                     /* pc_relative */
00763         0,                  /* bitpos */
00764         complain_overflow_bitfield, /* complain_on_overflow */
00765         bfd_elf_generic_reloc,     /* special_function */
00766         "R_BFIN_FUNCDESC",  /* name */
00767         FALSE,                     /* partial_inplace */
00768         0xffffffff,         /* src_mask */
00769         0xffffffff,         /* dst_mask */
00770         FALSE),             /* pcrel_offset */
00771 
00772   /* A 12-bit signed operand with the GOT offset for the address of
00773      canonical descriptor of a function.  */
00774   HOWTO (R_BFIN_FUNCDESC_GOT17M4,  /* type */
00775         2,                  /* rightshift */
00776         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00777         16,                 /* bitsize */
00778         FALSE,                     /* pc_relative */
00779         0,                  /* bitpos */
00780         complain_overflow_signed, /* complain_on_overflow */
00781         bfd_elf_generic_reloc,     /* special_function */
00782         "R_BFIN_FUNCDESC_GOT17M4", /* name */
00783         FALSE,                     /* partial_inplace */
00784         0xffff,              /* src_mask */
00785         0xffff,              /* dst_mask */
00786         FALSE),              /* pcrel_offset */
00787 
00788   /* The upper 16 bits of the GOT offset for the address of the
00789      canonical descriptor of a function.  */
00790   HOWTO (R_BFIN_FUNCDESC_GOTHI,    /* type */
00791         0,                  /* rightshift */
00792         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00793         16,                 /* bitsize */
00794         FALSE,                     /* pc_relative */
00795         0,                  /* bitpos */
00796         complain_overflow_dont, /* complain_on_overflow */
00797         bfd_elf_generic_reloc,     /* special_function */
00798         "R_BFIN_FUNCDESC_GOTHI", /* name */
00799         FALSE,                     /* partial_inplace */
00800         0xffff,             /* src_mask */
00801         0xffff,             /* dst_mask */
00802         FALSE),              /* pcrel_offset */
00803 
00804   /* The lower 16 bits of the GOT offset for the address of the
00805      canonical descriptor of a function.  */
00806   HOWTO (R_BFIN_FUNCDESC_GOTLO,    /* type */
00807         0,                  /* rightshift */
00808         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00809         16,                 /* bitsize */
00810         FALSE,                     /* pc_relative */
00811         0,                  /* bitpos */
00812         complain_overflow_dont, /* complain_on_overflow */
00813         bfd_elf_generic_reloc,     /* special_function */
00814         "R_BFIN_FUNCDESC_GOTLO", /* name */
00815         FALSE,                     /* partial_inplace */
00816         0xffff,             /* src_mask */
00817         0xffff,             /* dst_mask */
00818         FALSE),              /* pcrel_offset */
00819 
00820   /* The 32-bit address of the canonical descriptor of a function.  */
00821   HOWTO (R_BFIN_FUNCDESC_VALUE,    /* type */
00822         0,                  /* rightshift */
00823         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00824         64,                 /* bitsize */
00825         FALSE,                     /* pc_relative */
00826         0,                  /* bitpos */
00827         complain_overflow_bitfield, /* complain_on_overflow */
00828         bfd_elf_generic_reloc,     /* special_function */
00829         "R_BFIN_FUNCDESC_VALUE", /* name */
00830         FALSE,                     /* partial_inplace */
00831         0xffffffff,         /* src_mask */
00832         0xffffffff,         /* dst_mask */
00833         FALSE),             /* pcrel_offset */
00834 
00835   /* A 12-bit signed operand with the GOT offset for the address of
00836      canonical descriptor of a function.  */
00837   HOWTO (R_BFIN_FUNCDESC_GOTOFF17M4, /* type */
00838         2,                  /* rightshift */
00839         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00840         16,                 /* bitsize */
00841         FALSE,                     /* pc_relative */
00842         0,                  /* bitpos */
00843         complain_overflow_signed, /* complain_on_overflow */
00844         bfd_elf_generic_reloc,     /* special_function */
00845         "R_BFIN_FUNCDESC_GOTOFF17M4", /* name */
00846         FALSE,                     /* partial_inplace */
00847         0xffff,              /* src_mask */
00848         0xffff,              /* dst_mask */
00849         FALSE),              /* pcrel_offset */
00850 
00851   /* The upper 16 bits of the GOT offset for the address of the
00852      canonical descriptor of a function.  */
00853   HOWTO (R_BFIN_FUNCDESC_GOTOFFHI, /* type */
00854         0,                  /* rightshift */
00855         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00856         16,                 /* bitsize */
00857         FALSE,                     /* pc_relative */
00858         0,                  /* bitpos */
00859         complain_overflow_dont, /* complain_on_overflow */
00860         bfd_elf_generic_reloc,     /* special_function */
00861         "R_BFIN_FUNCDESC_GOTOFFHI", /* name */
00862         FALSE,                     /* partial_inplace */
00863         0xffff,             /* src_mask */
00864         0xffff,             /* dst_mask */
00865         FALSE),              /* pcrel_offset */
00866 
00867   /* The lower 16 bits of the GOT offset for the address of the
00868      canonical descriptor of a function.  */
00869   HOWTO (R_BFIN_FUNCDESC_GOTOFFLO, /* type */
00870         0,                  /* rightshift */
00871         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00872         16,                 /* bitsize */
00873         FALSE,                     /* pc_relative */
00874         0,                  /* bitpos */
00875         complain_overflow_dont, /* complain_on_overflow */
00876         bfd_elf_generic_reloc,     /* special_function */
00877         "R_BFIN_FUNCDESC_GOTOFFLO", /* name */
00878         FALSE,                     /* partial_inplace */
00879         0xffff,             /* src_mask */
00880         0xffff,             /* dst_mask */
00881         FALSE),              /* pcrel_offset */
00882 
00883   /* A 12-bit signed operand with the GOT offset for the address of
00884      the symbol.  */
00885   HOWTO (R_BFIN_GOTOFF17M4,     /* type */
00886         2,                  /* rightshift */
00887         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00888         16,                 /* bitsize */
00889         FALSE,                     /* pc_relative */
00890         0,                  /* bitpos */
00891         complain_overflow_signed, /* complain_on_overflow */
00892         bfd_elf_generic_reloc,     /* special_function */
00893         "R_BFIN_GOTOFF17M4",       /* name */
00894         FALSE,                     /* partial_inplace */
00895         0xffff,              /* src_mask */
00896         0xffff,              /* dst_mask */
00897         FALSE),              /* pcrel_offset */
00898 
00899   /* The upper 16 bits of the GOT offset for the address of the
00900      symbol.  */
00901   HOWTO (R_BFIN_GOTOFFHI,        /* type */
00902         0,                  /* rightshift */
00903         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00904         16,                 /* bitsize */
00905         FALSE,                     /* pc_relative */
00906         0,                  /* bitpos */
00907         complain_overflow_dont, /* complain_on_overflow */
00908         bfd_elf_generic_reloc,     /* special_function */
00909         "R_BFIN_GOTOFFHI",  /* name */
00910         FALSE,                     /* partial_inplace */
00911         0xffff,             /* src_mask */
00912         0xffff,             /* dst_mask */
00913         FALSE),              /* pcrel_offset */
00914 
00915   /* The lower 16 bits of the GOT offset for the address of the
00916      symbol.  */
00917   HOWTO (R_BFIN_GOTOFFLO,   /* type */
00918         0,                  /* rightshift */
00919         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00920         16,                 /* bitsize */
00921         FALSE,                     /* pc_relative */
00922         0,                  /* bitpos */
00923         complain_overflow_dont, /* complain_on_overflow */
00924         bfd_elf_generic_reloc,     /* special_function */
00925         "R_BFIN_GOTOFFLO",  /* name */
00926         FALSE,                     /* partial_inplace */
00927         0xffff,             /* src_mask */
00928         0xffff,             /* dst_mask */
00929         FALSE),              /* pcrel_offset */
00930 };
00931 
00932 static reloc_howto_type bfin_gnuext_howto_table [] =
00933 {
00934   HOWTO (R_pltpc,           /* type.  */
00935         0,                  /* rightshift.  */
00936         1,                  /* size (0 = byte, 1 = short, 2 = long).  */
00937         16,                 /* bitsize.  */
00938         FALSE,                     /* pc_relative.  */
00939         0,                  /* bitpos.  */
00940         complain_overflow_bitfield, /* complain_on_overflow.  */
00941         bfin_pltpc_reloc,   /* special_function.  */
00942         "R_pltpc",          /* name.  */
00943         FALSE,                     /* partial_inplace.  */
00944         0xffff,             /* src_mask.  */
00945         0xffff,             /* dst_mask.  */
00946         FALSE),             /* pcrel_offset.  */
00947 
00948   HOWTO (R_got,                    /* type.  */
00949         0,                  /* rightshift.  */
00950         1,                  /* size (0 = byte, 1 = short, 2 = long).  */
00951         16,                 /* bitsize.  */
00952         FALSE,                     /* pc_relative.  */
00953         0,                  /* bitpos.  */
00954         complain_overflow_bitfield, /* complain_on_overflow.  */
00955         bfd_elf_generic_reloc,     /* special_function.  */
00956         "R_got",            /* name.  */
00957         FALSE,                     /* partial_inplace.  */
00958         0x7fff,             /* src_mask.  */
00959         0x7fff,             /* dst_mask.  */
00960         FALSE),             /* pcrel_offset.  */
00961 
00962 /* GNU extension to record C++ vtable hierarchy.  */
00963   HOWTO (R_BFIN_GNU_VTINHERIT, /* type.  */
00964          0,                     /* rightshift.  */
00965          2,                     /* size (0 = byte, 1 = short, 2 = long).  */
00966          0,                     /* bitsize.  */
00967          FALSE,                 /* pc_relative.  */
00968          0,                     /* bitpos.  */
00969          complain_overflow_dont, /* complain_on_overflow.  */
00970          NULL,                  /* special_function.  */
00971          "R_BFIN_GNU_VTINHERIT", /* name.  */
00972          FALSE,                 /* partial_inplace.  */
00973          0,                     /* src_mask.  */
00974          0,                     /* dst_mask.  */
00975          FALSE),                /* pcrel_offset.  */
00976 
00977 /* GNU extension to record C++ vtable member usage.  */
00978   HOWTO (R_BFIN_GNU_VTENTRY,       /* type.  */
00979          0,                     /* rightshift.  */
00980          2,                     /* size (0 = byte, 1 = short, 2 = long).  */
00981          0,                     /* bitsize.  */
00982          FALSE,                 /* pc_relative.  */
00983          0,                 /* bitpos.  */
00984          complain_overflow_dont, /* complain_on_overflow.  */
00985          _bfd_elf_rel_vtable_reloc_fn, /* special_function.  */
00986          "R_BFIN_GNU_VTENTRY",     /* name.  */
00987          FALSE,                 /* partial_inplace.  */
00988          0,                     /* src_mask.  */
00989          0,                     /* dst_mask.  */
00990          FALSE)                 /* pcrel_offset.  */
00991 };
00992 
00993 struct bfin_reloc_map
00994 {
00995   bfd_reloc_code_real_type  bfd_reloc_val;
00996   unsigned int                     bfin_reloc_val;
00997 };
00998 
00999 static const struct bfin_reloc_map bfin_reloc_map [] =
01000 {
01001   { BFD_RELOC_NONE,                R_unused0 },
01002   { BFD_RELOC_BFIN_5_PCREL,        R_pcrel5m2 },
01003   { BFD_RELOC_NONE,                R_unused1 },
01004   { BFD_RELOC_BFIN_10_PCREL,              R_pcrel10 },
01005   { BFD_RELOC_BFIN_12_PCREL_JUMP,  R_pcrel12_jump },
01006   { BFD_RELOC_BFIN_16_IMM,         R_rimm16 },
01007   { BFD_RELOC_BFIN_16_LOW,         R_luimm16 },
01008   { BFD_RELOC_BFIN_16_HIGH,        R_huimm16 },
01009   { BFD_RELOC_BFIN_12_PCREL_JUMP_S,       R_pcrel12_jump_s },
01010   { BFD_RELOC_24_PCREL,                   R_pcrel24 },
01011   { BFD_RELOC_24_PCREL,                   R_pcrel24 },
01012   { BFD_RELOC_BFIN_24_PCREL_JUMP_L,       R_pcrel24_jump_l },
01013   { BFD_RELOC_NONE,                R_unusedb },
01014   { BFD_RELOC_NONE,                R_unusedc },
01015   { BFD_RELOC_BFIN_24_PCREL_CALL_X,       R_pcrel24_call_x },
01016   { BFD_RELOC_8,                   R_byte_data },
01017   { BFD_RELOC_16,                  R_byte2_data },
01018   { BFD_RELOC_32,                  R_byte4_data },
01019   { BFD_RELOC_BFIN_11_PCREL,              R_pcrel11 },
01020   { BFD_RELOC_BFIN_GOT,                   R_got },
01021   { BFD_RELOC_BFIN_PLTPC,          R_pltpc },
01022 
01023   { BFD_RELOC_BFIN_GOT17M4,      R_BFIN_GOT17M4 },
01024   { BFD_RELOC_BFIN_GOTHI,      R_BFIN_GOTHI },
01025   { BFD_RELOC_BFIN_GOTLO,      R_BFIN_GOTLO },
01026   { BFD_RELOC_BFIN_FUNCDESC,   R_BFIN_FUNCDESC },
01027   { BFD_RELOC_BFIN_FUNCDESC_GOT17M4, R_BFIN_FUNCDESC_GOT17M4 },
01028   { BFD_RELOC_BFIN_FUNCDESC_GOTHI, R_BFIN_FUNCDESC_GOTHI },
01029   { BFD_RELOC_BFIN_FUNCDESC_GOTLO, R_BFIN_FUNCDESC_GOTLO },
01030   { BFD_RELOC_BFIN_FUNCDESC_VALUE, R_BFIN_FUNCDESC_VALUE },
01031   { BFD_RELOC_BFIN_FUNCDESC_GOTOFF17M4, R_BFIN_FUNCDESC_GOTOFF17M4 },
01032   { BFD_RELOC_BFIN_FUNCDESC_GOTOFFHI, R_BFIN_FUNCDESC_GOTOFFHI },
01033   { BFD_RELOC_BFIN_FUNCDESC_GOTOFFLO, R_BFIN_FUNCDESC_GOTOFFLO },
01034   { BFD_RELOC_BFIN_GOTOFF17M4,   R_BFIN_GOTOFF17M4 },
01035   { BFD_RELOC_BFIN_GOTOFFHI,   R_BFIN_GOTOFFHI },
01036   { BFD_RELOC_BFIN_GOTOFFLO,   R_BFIN_GOTOFFLO },
01037 
01038   { BFD_RELOC_VTABLE_INHERIT,             R_BFIN_GNU_VTINHERIT },
01039   { BFD_RELOC_VTABLE_ENTRY,        R_BFIN_GNU_VTENTRY },
01040 };
01041 
01042 
01043 static void
01044 bfin_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
01045                     arelent *cache_ptr,
01046                     Elf_Internal_Rela *dst)
01047 {
01048   unsigned int r_type;
01049 
01050   r_type = ELF32_R_TYPE (dst->r_info);
01051 
01052   if (r_type <= BFIN_RELOC_MAX)
01053     cache_ptr->howto = &bfin_howto_table [r_type];
01054 
01055   else if (r_type >= BFIN_GNUEXT_RELOC_MIN && r_type <= BFIN_GNUEXT_RELOC_MAX)
01056     cache_ptr->howto = &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];
01057 
01058   else
01059     cache_ptr->howto = (reloc_howto_type *) NULL;
01060 }
01061 
01062 /* Given a BFD reloc type, return the howto.  */
01063 static reloc_howto_type *
01064 bfin_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
01065                          bfd_reloc_code_real_type code)
01066 {
01067   unsigned int i;
01068   unsigned int r_type = BFIN_RELOC_MIN;
01069 
01070   for (i = sizeof (bfin_reloc_map) / sizeof (bfin_reloc_map[0]); --i;)
01071     if (bfin_reloc_map[i].bfd_reloc_val == code)
01072       r_type = bfin_reloc_map[i].bfin_reloc_val;
01073 
01074   if (r_type <= BFIN_RELOC_MAX && r_type > BFIN_RELOC_MIN)
01075     return &bfin_howto_table [r_type];
01076 
01077   else if (r_type >= BFIN_GNUEXT_RELOC_MIN && r_type <= BFIN_GNUEXT_RELOC_MAX)
01078    return &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];
01079 
01080   return (reloc_howto_type *) NULL;
01081 }
01082 
01083 static reloc_howto_type *
01084 bfin_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
01085                          const char *r_name)
01086 {
01087   unsigned int i;
01088 
01089   for (i = 0;
01090        i < (sizeof (bfin_howto_table)
01091            / sizeof (bfin_howto_table[0]));
01092        i++)
01093     if (bfin_howto_table[i].name != NULL
01094        && strcasecmp (bfin_howto_table[i].name, r_name) == 0)
01095       return &bfin_howto_table[i];
01096 
01097   for (i = 0;
01098        i < (sizeof (bfin_gnuext_howto_table)
01099            / sizeof (bfin_gnuext_howto_table[0]));
01100        i++)
01101     if (bfin_gnuext_howto_table[i].name != NULL
01102        && strcasecmp (bfin_gnuext_howto_table[i].name, r_name) == 0)
01103       return &bfin_gnuext_howto_table[i];
01104 
01105   return NULL;
01106 }
01107 
01108 /* Given a bfin relocation type, return the howto.  */
01109 static reloc_howto_type *
01110 bfin_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
01111                          unsigned int r_type)
01112 {
01113   if (r_type <= BFIN_RELOC_MAX)
01114     return &bfin_howto_table [r_type];
01115 
01116   else if (r_type >= BFIN_GNUEXT_RELOC_MIN && r_type <= BFIN_GNUEXT_RELOC_MAX)
01117    return &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];
01118 
01119   return (reloc_howto_type *) NULL;
01120 }
01121 
01122 /* Return TRUE if the name is a local label.
01123    bfin local labels begin with L$.  */
01124 static bfd_boolean
01125 bfin_is_local_label_name (
01126      bfd *abfd ATTRIBUTE_UNUSED,
01127      const char *label)
01128 {
01129   if (label[0] == 'L' && label[1] == '$' )
01130     return TRUE;
01131 
01132   return _bfd_elf_is_local_label_name (abfd, label);
01133 }
01134 
01135 extern const bfd_target bfd_elf32_bfinfdpic_vec;
01136 #define IS_FDPIC(bfd) ((bfd)->xvec == &bfd_elf32_bfinfdpic_vec)
01137 
01138 /* An extension of the elf hash table data structure, containing some
01139    additional Blackfin-specific data.  */
01140 struct bfinfdpic_elf_link_hash_table
01141 {
01142   struct elf_link_hash_table elf;
01143 
01144   /* A pointer to the .got section.  */
01145   asection *sgot;
01146   /* A pointer to the .rel.got section.  */
01147   asection *sgotrel;
01148   /* A pointer to the .rofixup section.  */
01149   asection *sgotfixup;
01150   /* A pointer to the .plt section.  */
01151   asection *splt;
01152   /* A pointer to the .rel.plt section.  */
01153   asection *spltrel;
01154   /* GOT base offset.  */
01155   bfd_vma got0;
01156   /* Location of the first non-lazy PLT entry, i.e., the number of
01157      bytes taken by lazy PLT entries.  */
01158   bfd_vma plt0;
01159   /* A hash table holding information about which symbols were
01160      referenced with which PIC-related relocations.  */
01161   struct htab *relocs_info;
01162 };
01163 
01164 /* Get the Blackfin ELF linker hash table from a link_info structure.  */
01165 
01166 #define bfinfdpic_hash_table(info) \
01167   ((struct bfinfdpic_elf_link_hash_table *) ((info)->hash))
01168 
01169 #define bfinfdpic_got_section(info) \
01170   (bfinfdpic_hash_table (info)->sgot)
01171 #define bfinfdpic_gotrel_section(info) \
01172   (bfinfdpic_hash_table (info)->sgotrel)
01173 #define bfinfdpic_gotfixup_section(info) \
01174   (bfinfdpic_hash_table (info)->sgotfixup)
01175 #define bfinfdpic_plt_section(info) \
01176   (bfinfdpic_hash_table (info)->splt)
01177 #define bfinfdpic_pltrel_section(info) \
01178   (bfinfdpic_hash_table (info)->spltrel)
01179 #define bfinfdpic_relocs_info(info) \
01180   (bfinfdpic_hash_table (info)->relocs_info)
01181 #define bfinfdpic_got_initial_offset(info) \
01182   (bfinfdpic_hash_table (info)->got0)
01183 #define bfinfdpic_plt_initial_offset(info) \
01184   (bfinfdpic_hash_table (info)->plt0)
01185 
01186 /* Create a Blackfin ELF linker hash table.  */
01187 
01188 static struct bfd_link_hash_table *
01189 bfinfdpic_elf_link_hash_table_create (bfd *abfd)
01190 {
01191   struct bfinfdpic_elf_link_hash_table *ret;
01192   bfd_size_type amt = sizeof (struct bfinfdpic_elf_link_hash_table);
01193 
01194   ret = bfd_zalloc (abfd, amt);
01195   if (ret == NULL)
01196     return NULL;
01197 
01198   if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
01199                                   _bfd_elf_link_hash_newfunc,
01200                                   sizeof (struct elf_link_hash_entry)))
01201     {
01202       free (ret);
01203       return NULL;
01204     }
01205 
01206   return &ret->elf.root;
01207 }
01208 
01209 /* Decide whether a reference to a symbol can be resolved locally or
01210    not.  If the symbol is protected, we want the local address, but
01211    its function descriptor must be assigned by the dynamic linker.  */
01212 #define BFINFDPIC_SYM_LOCAL(INFO, H) \
01213   (_bfd_elf_symbol_refs_local_p ((H), (INFO), 1) \
01214    || ! elf_hash_table (INFO)->dynamic_sections_created)
01215 #define BFINFDPIC_FUNCDESC_LOCAL(INFO, H) \
01216   ((H)->dynindx == -1 || ! elf_hash_table (INFO)->dynamic_sections_created)
01217 
01218 /* This structure collects information on what kind of GOT, PLT or
01219    function descriptors are required by relocations that reference a
01220    certain symbol.  */
01221 struct bfinfdpic_relocs_info
01222 {
01223   /* The index of the symbol, as stored in the relocation r_info, if
01224      we have a local symbol; -1 otherwise.  */
01225   long symndx;
01226   union
01227   {
01228     /* The input bfd in which the symbol is defined, if it's a local
01229        symbol.  */
01230     bfd *abfd;
01231     /* If symndx == -1, the hash table entry corresponding to a global
01232        symbol (even if it turns out to bind locally, in which case it
01233        should ideally be replaced with section's symndx + addend).  */
01234     struct elf_link_hash_entry *h;
01235   } d;
01236   /* The addend of the relocation that references the symbol.  */
01237   bfd_vma addend;
01238 
01239   /* The fields above are used to identify an entry.  The fields below
01240      contain information on how an entry is used and, later on, which
01241      locations it was assigned.  */
01242   /* The following 2 fields record whether the symbol+addend above was
01243      ever referenced with a GOT relocation.  The 17M4 suffix indicates a
01244      GOT17M4 relocation; hilo is used for GOTLO/GOTHI pairs.  */
01245   unsigned got17m4:1;
01246   unsigned gothilo:1;
01247   /* Whether a FUNCDESC relocation references symbol+addend.  */
01248   unsigned fd:1;
01249   /* Whether a FUNCDESC_GOT relocation references symbol+addend.  */
01250   unsigned fdgot17m4:1;
01251   unsigned fdgothilo:1;
01252   /* Whether a FUNCDESC_GOTOFF relocation references symbol+addend.  */
01253   unsigned fdgoff17m4:1;
01254   unsigned fdgoffhilo:1;
01255   /* Whether symbol+addend is referenced with GOTOFF17M4, GOTOFFLO or
01256      GOTOFFHI relocations.  The addend doesn't really matter, since we
01257      envision that this will only be used to check whether the symbol
01258      is mapped to the same segment as the got.  */
01259   unsigned gotoff:1;
01260   /* Whether symbol+addend is referenced by a LABEL24 relocation.  */
01261   unsigned call:1;
01262   /* Whether symbol+addend is referenced by a 32 or FUNCDESC_VALUE
01263      relocation.  */
01264   unsigned sym:1;
01265   /* Whether we need a PLT entry for a symbol.  Should be implied by
01266      something like:
01267      (call && symndx == -1 && ! BFINFDPIC_SYM_LOCAL (info, d.h))  */
01268   unsigned plt:1;
01269   /* Whether a function descriptor should be created in this link unit
01270      for symbol+addend.  Should be implied by something like:
01271      (plt || fdgotoff17m4 || fdgotofflohi
01272       || ((fd || fdgot17m4 || fdgothilo)
01273           && (symndx != -1 || BFINFDPIC_FUNCDESC_LOCAL (info, d.h))))  */
01274   unsigned privfd:1;
01275   /* Whether a lazy PLT entry is needed for this symbol+addend.
01276      Should be implied by something like:
01277      (privfd && symndx == -1 && ! BFINFDPIC_SYM_LOCAL (info, d.h)
01278       && ! (info->flags & DF_BIND_NOW))  */
01279   unsigned lazyplt:1;
01280   /* Whether we've already emitted GOT relocations and PLT entries as
01281      needed for this symbol.  */
01282   unsigned done:1;
01283 
01284   /* The number of R_byte4_data, R_BFIN_FUNCDESC and R_BFIN_FUNCDESC_VALUE
01285      relocations referencing the symbol.  */
01286   unsigned relocs32, relocsfd, relocsfdv;
01287 
01288   /* The number of .rofixups entries and dynamic relocations allocated
01289      for this symbol, minus any that might have already been used.  */
01290   unsigned fixups, dynrelocs;
01291 
01292   /* The offsets of the GOT entries assigned to symbol+addend, to the
01293      function descriptor's address, and to a function descriptor,
01294      respectively.  Should be zero if unassigned.  The offsets are
01295      counted from the value that will be assigned to the PIC register,
01296      not from the beginning of the .got section.  */
01297   bfd_signed_vma got_entry, fdgot_entry, fd_entry;
01298   /* The offsets of the PLT entries assigned to symbol+addend,
01299      non-lazy and lazy, respectively.  If unassigned, should be
01300      (bfd_vma)-1.  */
01301   bfd_vma plt_entry, lzplt_entry;
01302 };
01303 
01304 /* Compute a hash with the key fields of an bfinfdpic_relocs_info entry.  */
01305 static hashval_t
01306 bfinfdpic_relocs_info_hash (const void *entry_)
01307 {
01308   const struct bfinfdpic_relocs_info *entry = entry_;
01309 
01310   return (entry->symndx == -1
01311          ? (long) entry->d.h->root.root.hash
01312          : entry->symndx + (long) entry->d.abfd->id * 257) + entry->addend;
01313 }
01314 
01315 /* Test whether the key fields of two bfinfdpic_relocs_info entries are
01316    identical.  */
01317 static int
01318 bfinfdpic_relocs_info_eq (const void *entry1, const void *entry2)
01319 {
01320   const struct bfinfdpic_relocs_info *e1 = entry1;
01321   const struct bfinfdpic_relocs_info *e2 = entry2;
01322 
01323   return e1->symndx == e2->symndx && e1->addend == e2->addend
01324     && (e1->symndx == -1 ? e1->d.h == e2->d.h : e1->d.abfd == e2->d.abfd);
01325 }
01326 
01327 /* Find or create an entry in a hash table HT that matches the key
01328    fields of the given ENTRY.  If it's not found, memory for a new
01329    entry is allocated in ABFD's obstack.  */
01330 static struct bfinfdpic_relocs_info *
01331 bfinfdpic_relocs_info_find (struct htab *ht,
01332                         bfd *abfd,
01333                         const struct bfinfdpic_relocs_info *entry,
01334                         enum insert_option insert)
01335 {
01336   struct bfinfdpic_relocs_info **loc =
01337     (struct bfinfdpic_relocs_info **) htab_find_slot (ht, entry, insert);
01338 
01339   if (! loc)
01340     return NULL;
01341 
01342   if (*loc)
01343     return *loc;
01344 
01345   *loc = bfd_zalloc (abfd, sizeof (**loc));
01346 
01347   if (! *loc)
01348     return *loc;
01349 
01350   (*loc)->symndx = entry->symndx;
01351   (*loc)->d = entry->d;
01352   (*loc)->addend = entry->addend;
01353   (*loc)->plt_entry = (bfd_vma)-1;
01354   (*loc)->lzplt_entry = (bfd_vma)-1;
01355 
01356   return *loc;
01357 }
01358 
01359 /* Obtain the address of the entry in HT associated with H's symbol +
01360    addend, creating a new entry if none existed.  ABFD is only used
01361    for memory allocation purposes.  */
01362 inline static struct bfinfdpic_relocs_info *
01363 bfinfdpic_relocs_info_for_global (struct htab *ht,
01364                              bfd *abfd,
01365                              struct elf_link_hash_entry *h,
01366                              bfd_vma addend,
01367                              enum insert_option insert)
01368 {
01369   struct bfinfdpic_relocs_info entry;
01370 
01371   entry.symndx = -1;
01372   entry.d.h = h;
01373   entry.addend = addend;
01374 
01375   return bfinfdpic_relocs_info_find (ht, abfd, &entry, insert);
01376 }
01377 
01378 /* Obtain the address of the entry in HT associated with the SYMNDXth
01379    local symbol of the input bfd ABFD, plus the addend, creating a new
01380    entry if none existed.  */
01381 inline static struct bfinfdpic_relocs_info *
01382 bfinfdpic_relocs_info_for_local (struct htab *ht,
01383                             bfd *abfd,
01384                             long symndx,
01385                             bfd_vma addend,
01386                             enum insert_option insert)
01387 {
01388   struct bfinfdpic_relocs_info entry;
01389 
01390   entry.symndx = symndx;
01391   entry.d.abfd = abfd;
01392   entry.addend = addend;
01393 
01394   return bfinfdpic_relocs_info_find (ht, abfd, &entry, insert);
01395 }
01396 
01397 /* Merge fields set by check_relocs() of two entries that end up being
01398    mapped to the same (presumably global) symbol.  */
01399 
01400 inline static void
01401 bfinfdpic_pic_merge_early_relocs_info (struct bfinfdpic_relocs_info *e2,
01402                                   struct bfinfdpic_relocs_info const *e1)
01403 {
01404   e2->got17m4 |= e1->got17m4;
01405   e2->gothilo |= e1->gothilo;
01406   e2->fd |= e1->fd;
01407   e2->fdgot17m4 |= e1->fdgot17m4;
01408   e2->fdgothilo |= e1->fdgothilo;
01409   e2->fdgoff17m4 |= e1->fdgoff17m4;
01410   e2->fdgoffhilo |= e1->fdgoffhilo;
01411   e2->gotoff |= e1->gotoff;
01412   e2->call |= e1->call;
01413   e2->sym |= e1->sym;
01414 }
01415 
01416 /* Every block of 65535 lazy PLT entries shares a single call to the
01417    resolver, inserted in the 32768th lazy PLT entry (i.e., entry #
01418    32767, counting from 0).  All other lazy PLT entries branch to it
01419    in a single instruction.  */
01420 
01421 #define LZPLT_RESOLVER_EXTRA 10
01422 #define LZPLT_NORMAL_SIZE 6
01423 #define LZPLT_ENTRIES 1362
01424 
01425 #define BFINFDPIC_LZPLT_BLOCK_SIZE ((bfd_vma) LZPLT_NORMAL_SIZE * LZPLT_ENTRIES + LZPLT_RESOLVER_EXTRA)
01426 #define BFINFDPIC_LZPLT_RESOLV_LOC (LZPLT_NORMAL_SIZE * LZPLT_ENTRIES / 2)
01427 
01428 /* Add a dynamic relocation to the SRELOC section.  */
01429 
01430 inline static bfd_vma
01431 _bfinfdpic_add_dyn_reloc (bfd *output_bfd, asection *sreloc, bfd_vma offset,
01432                       int reloc_type, long dynindx, bfd_vma addend,
01433                       struct bfinfdpic_relocs_info *entry)
01434 {
01435   Elf_Internal_Rela outrel;
01436   bfd_vma reloc_offset;
01437 
01438   outrel.r_offset = offset;
01439   outrel.r_info = ELF32_R_INFO (dynindx, reloc_type);
01440   outrel.r_addend = addend;
01441 
01442   reloc_offset = sreloc->reloc_count * sizeof (Elf32_External_Rel);
01443   BFD_ASSERT (reloc_offset < sreloc->size);
01444   bfd_elf32_swap_reloc_out (output_bfd, &outrel,
01445                          sreloc->contents + reloc_offset);
01446   sreloc->reloc_count++;
01447 
01448   /* If the entry's index is zero, this relocation was probably to a
01449      linkonce section that got discarded.  We reserved a dynamic
01450      relocation, but it was for another entry than the one we got at
01451      the time of emitting the relocation.  Unfortunately there's no
01452      simple way for us to catch this situation, since the relocation
01453      is cleared right before calling relocate_section, at which point
01454      we no longer know what the relocation used to point to.  */
01455   if (entry->symndx)
01456     {
01457       BFD_ASSERT (entry->dynrelocs > 0);
01458       entry->dynrelocs--;
01459     }
01460 
01461   return reloc_offset;
01462 }
01463 
01464 /* Add a fixup to the ROFIXUP section.  */
01465 
01466 static bfd_vma
01467 _bfinfdpic_add_rofixup (bfd *output_bfd, asection *rofixup, bfd_vma offset,
01468                      struct bfinfdpic_relocs_info *entry)
01469 {
01470   bfd_vma fixup_offset;
01471 
01472   if (rofixup->flags & SEC_EXCLUDE)
01473     return -1;
01474 
01475   fixup_offset = rofixup->reloc_count * 4;
01476   if (rofixup->contents)
01477     {
01478       BFD_ASSERT (fixup_offset < rofixup->size);
01479       bfd_put_32 (output_bfd, offset, rofixup->contents + fixup_offset);
01480     }
01481   rofixup->reloc_count++;
01482 
01483   if (entry && entry->symndx)
01484     {
01485       /* See discussion about symndx == 0 in _bfinfdpic_add_dyn_reloc
01486         above.  */
01487       BFD_ASSERT (entry->fixups > 0);
01488       entry->fixups--;
01489     }
01490 
01491   return fixup_offset;
01492 }
01493 
01494 /* Find the segment number in which OSEC, and output section, is
01495    located.  */
01496 
01497 static unsigned
01498 _bfinfdpic_osec_to_segment (bfd *output_bfd, asection *osec)
01499 {
01500   struct elf_segment_map *m;
01501   Elf_Internal_Phdr *p;
01502 
01503   /* Find the segment that contains the output_section.  */
01504   for (m = elf_tdata (output_bfd)->segment_map,
01505         p = elf_tdata (output_bfd)->phdr;
01506        m != NULL;
01507        m = m->next, p++)
01508     {
01509       int i;
01510 
01511       for (i = m->count - 1; i >= 0; i--)
01512        if (m->sections[i] == osec)
01513          break;
01514 
01515       if (i >= 0)
01516        break;
01517     }
01518 
01519   return p - elf_tdata (output_bfd)->phdr;
01520 }
01521 
01522 inline static bfd_boolean
01523 _bfinfdpic_osec_readonly_p (bfd *output_bfd, asection *osec)
01524 {
01525   unsigned seg = _bfinfdpic_osec_to_segment (output_bfd, osec);
01526 
01527   return ! (elf_tdata (output_bfd)->phdr[seg].p_flags & PF_W);
01528 }
01529 
01530 /* Generate relocations for GOT entries, function descriptors, and
01531    code for PLT and lazy PLT entries.  */
01532 
01533 inline static bfd_boolean
01534 _bfinfdpic_emit_got_relocs_plt_entries (struct bfinfdpic_relocs_info *entry,
01535                                    bfd *output_bfd,
01536                                    struct bfd_link_info *info,
01537                                    asection *sec,
01538                                    Elf_Internal_Sym *sym,
01539                                    bfd_vma addend)
01540 
01541 {
01542   bfd_vma fd_lazy_rel_offset = (bfd_vma)-1;
01543   int dynindx = -1;
01544 
01545   if (entry->done)
01546     return TRUE;
01547   entry->done = 1;
01548 
01549   if (entry->got_entry || entry->fdgot_entry || entry->fd_entry)
01550     {
01551       /* If the symbol is dynamic, consider it for dynamic
01552         relocations, otherwise decay to section + offset.  */
01553       if (entry->symndx == -1 && entry->d.h->dynindx != -1)
01554        dynindx = entry->d.h->dynindx;
01555       else
01556        {
01557          if (sec->output_section
01558              && ! bfd_is_abs_section (sec->output_section)
01559              && ! bfd_is_und_section (sec->output_section))
01560            dynindx = elf_section_data (sec->output_section)->dynindx;
01561          else
01562            dynindx = 0;
01563        }
01564     }
01565 
01566   /* Generate relocation for GOT entry pointing to the symbol.  */
01567   if (entry->got_entry)
01568     {
01569       int idx = dynindx;
01570       bfd_vma ad = addend;
01571 
01572       /* If the symbol is dynamic but binds locally, use
01573         section+offset.  */
01574       if (sec && (entry->symndx != -1
01575                 || BFINFDPIC_SYM_LOCAL (info, entry->d.h)))
01576        {
01577          if (entry->symndx == -1)
01578            ad += entry->d.h->root.u.def.value;
01579          else
01580            ad += sym->st_value;
01581          ad += sec->output_offset;
01582          if (sec->output_section && elf_section_data (sec->output_section))
01583            idx = elf_section_data (sec->output_section)->dynindx;
01584          else
01585            idx = 0;
01586        }
01587 
01588       /* If we're linking an executable at a fixed address, we can
01589         omit the dynamic relocation as long as the symbol is local to
01590         this module.  */
01591       if (info->executable && !info->pie
01592          && (entry->symndx != -1
01593              || BFINFDPIC_SYM_LOCAL (info, entry->d.h)))
01594        {
01595          if (sec)
01596            ad += sec->output_section->vma;
01597          if (entry->symndx != -1
01598              || entry->d.h->root.type != bfd_link_hash_undefweak)
01599            _bfinfdpic_add_rofixup (output_bfd,
01600                                bfinfdpic_gotfixup_section (info),
01601                                bfinfdpic_got_section (info)->output_section
01602                                ->vma
01603                                + bfinfdpic_got_section (info)->output_offset
01604                                + bfinfdpic_got_initial_offset (info)
01605                                + entry->got_entry, entry);
01606        }
01607       else
01608        _bfinfdpic_add_dyn_reloc (output_bfd, bfinfdpic_gotrel_section (info),
01609                              _bfd_elf_section_offset
01610                              (output_bfd, info,
01611                               bfinfdpic_got_section (info),
01612                               bfinfdpic_got_initial_offset (info)
01613                               + entry->got_entry)
01614                              + bfinfdpic_got_section (info)
01615                              ->output_section->vma
01616                              + bfinfdpic_got_section (info)->output_offset,
01617                              R_byte4_data, idx, ad, entry);
01618 
01619       bfd_put_32 (output_bfd, ad,
01620                 bfinfdpic_got_section (info)->contents
01621                 + bfinfdpic_got_initial_offset (info)
01622                 + entry->got_entry);
01623     }
01624 
01625   /* Generate relocation for GOT entry pointing to a canonical
01626      function descriptor.  */
01627   if (entry->fdgot_entry)
01628     {
01629       int reloc, idx;
01630       bfd_vma ad = 0;
01631 
01632       if (! (entry->symndx == -1
01633             && entry->d.h->root.type == bfd_link_hash_undefweak
01634             && BFINFDPIC_SYM_LOCAL (info, entry->d.h)))
01635        {
01636          /* If the symbol is dynamic and there may be dynamic symbol
01637             resolution because we are, or are linked with, a shared
01638             library, emit a FUNCDESC relocation such that the dynamic
01639             linker will allocate the function descriptor.  If the
01640             symbol needs a non-local function descriptor but binds
01641             locally (e.g., its visibility is protected, emit a
01642             dynamic relocation decayed to section+offset.  */
01643          if (entry->symndx == -1
01644              && ! BFINFDPIC_FUNCDESC_LOCAL (info, entry->d.h)
01645              && BFINFDPIC_SYM_LOCAL (info, entry->d.h)
01646              && !(info->executable && !info->pie))
01647            {
01648              reloc = R_BFIN_FUNCDESC;
01649              idx = elf_section_data (entry->d.h->root.u.def.section
01650                                   ->output_section)->dynindx;
01651              ad = entry->d.h->root.u.def.section->output_offset
01652               + entry->d.h->root.u.def.value;
01653            }
01654          else if (entry->symndx == -1
01655                  && ! BFINFDPIC_FUNCDESC_LOCAL (info, entry->d.h))
01656            {
01657              reloc = R_BFIN_FUNCDESC;
01658              idx = dynindx;
01659              ad = addend;
01660              if (ad)
01661               return FALSE;
01662            }
01663          else
01664            {
01665              /* Otherwise, we know we have a private function descriptor,
01666                so reference it directly.  */
01667              if (elf_hash_table (info)->dynamic_sections_created)
01668               BFD_ASSERT (entry->privfd);
01669              reloc = R_byte4_data;
01670              idx = elf_section_data (bfinfdpic_got_section (info)
01671                                   ->output_section)->dynindx;
01672              ad = bfinfdpic_got_section (info)->output_offset
01673               + bfinfdpic_got_initial_offset (info) + entry->fd_entry;
01674            }
01675 
01676          /* If there is room for dynamic symbol resolution, emit the
01677             dynamic relocation.  However, if we're linking an
01678             executable at a fixed location, we won't have emitted a
01679             dynamic symbol entry for the got section, so idx will be
01680             zero, which means we can and should compute the address
01681             of the private descriptor ourselves.  */
01682          if (info->executable && !info->pie
01683              && (entry->symndx != -1
01684                 || BFINFDPIC_FUNCDESC_LOCAL (info, entry->d.h)))
01685            {
01686              ad += bfinfdpic_got_section (info)->output_section->vma;
01687              _bfinfdpic_add_rofixup (output_bfd,
01688                                  bfinfdpic_gotfixup_section (info),
01689                                  bfinfdpic_got_section (info)
01690                                  ->output_section->vma
01691                                  + bfinfdpic_got_section (info)
01692                                  ->output_offset
01693                                  + bfinfdpic_got_initial_offset (info)
01694                                  + entry->fdgot_entry, entry);
01695            }
01696          else
01697            _bfinfdpic_add_dyn_reloc (output_bfd,
01698                                  bfinfdpic_gotrel_section (info),
01699                                  _bfd_elf_section_offset
01700                                  (output_bfd, info,
01701                                   bfinfdpic_got_section (info),
01702                                   bfinfdpic_got_initial_offset (info)
01703                                   + entry->fdgot_entry)
01704                                  + bfinfdpic_got_section (info)
01705                                  ->output_section->vma
01706                                  + bfinfdpic_got_section (info)
01707                                  ->output_offset,
01708                                  reloc, idx, ad, entry);
01709        }
01710 
01711       bfd_put_32 (output_bfd, ad,
01712                 bfinfdpic_got_section (info)->contents
01713                 + bfinfdpic_got_initial_offset (info)
01714                 + entry->fdgot_entry);
01715     }
01716 
01717   /* Generate relocation to fill in a private function descriptor in
01718      the GOT.  */
01719   if (entry->fd_entry)
01720     {
01721       int idx = dynindx;
01722       bfd_vma ad = addend;
01723       bfd_vma ofst;
01724       long lowword, highword;
01725 
01726       /* If the symbol is dynamic but binds locally, use
01727         section+offset.  */
01728       if (sec && (entry->symndx != -1
01729                 || BFINFDPIC_SYM_LOCAL (info, entry->d.h)))
01730        {
01731          if (entry->symndx == -1)
01732            ad += entry->d.h->root.u.def.value;
01733          else
01734            ad += sym->st_value;
01735          ad += sec->output_offset;
01736          if (sec->output_section && elf_section_data (sec->output_section))
01737            idx = elf_section_data (sec->output_section)->dynindx;
01738          else
01739            idx = 0;
01740        }
01741 
01742       /* If we're linking an executable at a fixed address, we can
01743         omit the dynamic relocation as long as the symbol is local to
01744         this module.  */
01745       if (info->executable && !info->pie
01746          && (entry->symndx != -1 || BFINFDPIC_SYM_LOCAL (info, entry->d.h)))
01747        {
01748          if (sec)
01749            ad += sec->output_section->vma;
01750          ofst = 0;
01751          if (entry->symndx != -1
01752              || entry->d.h->root.type != bfd_link_hash_undefweak)
01753            {
01754              _bfinfdpic_add_rofixup (output_bfd,
01755                                  bfinfdpic_gotfixup_section (info),
01756                                  bfinfdpic_got_section (info)
01757                                  ->output_section->vma
01758                                  + bfinfdpic_got_section (info)
01759                                  ->output_offset
01760                                  + bfinfdpic_got_initial_offset (info)
01761                                  + entry->fd_entry, entry);
01762              _bfinfdpic_add_rofixup (output_bfd,
01763                                  bfinfdpic_gotfixup_section (info),
01764                                  bfinfdpic_got_section (info)
01765                                  ->output_section->vma
01766                                  + bfinfdpic_got_section (info)
01767                                  ->output_offset
01768                                  + bfinfdpic_got_initial_offset (info)
01769                                  + entry->fd_entry + 4, entry);
01770            }
01771        }
01772       else
01773        {
01774          ofst
01775            = _bfinfdpic_add_dyn_reloc (output_bfd,
01776                                    entry->lazyplt
01777                                    ? bfinfdpic_pltrel_section (info)
01778                                    : bfinfdpic_gotrel_section (info),
01779                                    _bfd_elf_section_offset
01780                                    (output_bfd, info,
01781                                     bfinfdpic_got_section (info),
01782                                     bfinfdpic_got_initial_offset (info)
01783                                     + entry->fd_entry)
01784                                    + bfinfdpic_got_section (info)
01785                                    ->output_section->vma
01786                                    + bfinfdpic_got_section (info)
01787                                    ->output_offset,
01788                                    R_BFIN_FUNCDESC_VALUE, idx, ad, entry);
01789        }
01790 
01791       /* If we've omitted the dynamic relocation, just emit the fixed
01792         addresses of the symbol and of the local GOT base offset.  */
01793       if (info->executable && !info->pie && sec && sec->output_section)
01794        {
01795          lowword = ad;
01796          highword = bfinfdpic_got_section (info)->output_section->vma
01797            + bfinfdpic_got_section (info)->output_offset
01798            + bfinfdpic_got_initial_offset (info);
01799        }
01800       else if (entry->lazyplt)
01801        {
01802          if (ad)
01803            return FALSE;
01804 
01805          fd_lazy_rel_offset = ofst;
01806 
01807          /* A function descriptor used for lazy or local resolving is
01808             initialized such that its high word contains the output
01809             section index in which the PLT entries are located, and
01810             the low word contains the address of the lazy PLT entry
01811             entry point, that must be within the memory region
01812             assigned to that section.  */
01813          lowword = entry->lzplt_entry + 4
01814            + bfinfdpic_plt_section (info)->output_offset
01815            + bfinfdpic_plt_section (info)->output_section->vma;
01816          highword = _bfinfdpic_osec_to_segment
01817            (output_bfd, bfinfdpic_plt_section (info)->output_section);
01818        }
01819       else
01820        {
01821          /* A function descriptor for a local function gets the index
01822             of the section.  For a non-local function, it's
01823             disregarded.  */
01824          lowword = ad;
01825          if (entry->symndx == -1 && entry->d.h->dynindx != -1
01826              && entry->d.h->dynindx == idx)
01827            highword = 0;
01828          else
01829            highword = _bfinfdpic_osec_to_segment
01830              (output_bfd, sec->output_section);
01831        }
01832 
01833       bfd_put_32 (output_bfd, lowword,
01834                 bfinfdpic_got_section (info)->contents
01835                 + bfinfdpic_got_initial_offset (info)
01836                 + entry->fd_entry);
01837       bfd_put_32 (output_bfd, highword,
01838                 bfinfdpic_got_section (info)->contents
01839                 + bfinfdpic_got_initial_offset (info)
01840                 + entry->fd_entry + 4);
01841     }
01842 
01843   /* Generate code for the PLT entry.  */
01844   if (entry->plt_entry != (bfd_vma) -1)
01845     {
01846       bfd_byte *plt_code = bfinfdpic_plt_section (info)->contents
01847        + entry->plt_entry;
01848 
01849       BFD_ASSERT (entry->fd_entry);
01850 
01851       /* Figure out what kind of PLT entry we need, depending on the
01852         location of the function descriptor within the GOT.  */
01853       if (entry->fd_entry >= -(1 << (18 - 1))
01854          && entry->fd_entry + 4 < (1 << (18 - 1)))
01855        {
01856          /* P1 = [P3 + fd_entry]; P3 = [P3 + fd_entry + 4] */
01857          bfd_put_32 (output_bfd,
01858                     0xe519 | ((entry->fd_entry << 14) & 0xFFFF0000),
01859                     plt_code);
01860          bfd_put_32 (output_bfd,
01861                     0xe51b | (((entry->fd_entry + 4) << 14) & 0xFFFF0000),
01862                     plt_code + 4);
01863          plt_code += 8;
01864        }
01865       else
01866        {
01867          /* P1.L = fd_entry; P1.H = fd_entry;
01868             P3 = P3 + P1;
01869             P1 = [P3];
01870             P3 = [P3 + 4];  */
01871          bfd_put_32 (output_bfd,
01872                     0xe109 | (entry->fd_entry << 16),
01873                     plt_code);
01874          bfd_put_32 (output_bfd,
01875                     0xe149 | (entry->fd_entry & 0xFFFF0000),
01876                     plt_code + 4);
01877          bfd_put_16 (output_bfd, 0x5ad9, plt_code + 8);
01878          bfd_put_16 (output_bfd, 0x9159, plt_code + 10);
01879          bfd_put_16 (output_bfd, 0xac5b, plt_code + 12);
01880          plt_code += 14;
01881        }
01882       /* JUMP (P1) */
01883       bfd_put_16 (output_bfd, 0x0051, plt_code);
01884     }
01885 
01886   /* Generate code for the lazy PLT entry.  */
01887   if (entry->lzplt_entry != (bfd_vma) -1)
01888     {
01889       bfd_byte *lzplt_code = bfinfdpic_plt_section (info)->contents
01890        + entry->lzplt_entry;
01891       bfd_vma resolverStub_addr;
01892 
01893       bfd_put_32 (output_bfd, fd_lazy_rel_offset, lzplt_code);
01894       lzplt_code += 4;
01895 
01896       resolverStub_addr = entry->lzplt_entry / BFINFDPIC_LZPLT_BLOCK_SIZE
01897        * BFINFDPIC_LZPLT_BLOCK_SIZE + BFINFDPIC_LZPLT_RESOLV_LOC;
01898       if (resolverStub_addr >= bfinfdpic_plt_initial_offset (info))
01899        resolverStub_addr = bfinfdpic_plt_initial_offset (info) - LZPLT_NORMAL_SIZE - LZPLT_RESOLVER_EXTRA;
01900 
01901       if (entry->lzplt_entry == resolverStub_addr)
01902        {
01903          /* This is a lazy PLT entry that includes a resolver call.
01904             P2 = [P3];
01905             R3 = [P3 + 4];
01906             JUMP (P2);  */
01907          bfd_put_32 (output_bfd,
01908                     0xa05b915a,
01909                     lzplt_code);
01910          bfd_put_16 (output_bfd, 0x0052, lzplt_code + 4);
01911        }
01912       else
01913        {
01914          /* JUMP.S  resolverStub */
01915          bfd_put_16 (output_bfd,
01916                     0x2000
01917                     | (((resolverStub_addr - entry->lzplt_entry)
01918                        / 2) & (((bfd_vma)1 << 12) - 1)),
01919                     lzplt_code);
01920        }
01921     }
01922 
01923   return TRUE;
01924 }
01925 
01926 
01927 /* Look through the relocs for a section during the first phase, and
01928    allocate space in the global offset table or procedure linkage
01929    table.  */
01930 
01931 static bfd_boolean
01932 bfin_check_relocs (bfd * abfd,
01933                  struct bfd_link_info *info,
01934                  asection *sec,
01935                    const Elf_Internal_Rela *relocs)
01936 {
01937   bfd *dynobj;
01938   Elf_Internal_Shdr *symtab_hdr;
01939   struct elf_link_hash_entry **sym_hashes;
01940   bfd_signed_vma *local_got_refcounts;
01941   const Elf_Internal_Rela *rel;
01942   const Elf_Internal_Rela *rel_end;
01943   asection *sgot;
01944   asection *srelgot;
01945   asection *sreloc;
01946   if (info->relocatable)
01947     return TRUE;
01948 
01949   dynobj = elf_hash_table (info)->dynobj;
01950   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
01951   sym_hashes = elf_sym_hashes (abfd);
01952   local_got_refcounts = elf_local_got_refcounts (abfd);
01953 
01954   sgot = NULL;
01955   srelgot = NULL;
01956   sreloc = NULL;
01957 
01958   rel_end = relocs + sec->reloc_count;
01959   for (rel = relocs; rel < rel_end; rel++)
01960     {
01961       unsigned long r_symndx;
01962       struct elf_link_hash_entry *h;
01963 
01964       r_symndx = ELF32_R_SYM (rel->r_info);
01965       if (r_symndx < symtab_hdr->sh_info)
01966        h = NULL;
01967       else
01968        h = sym_hashes[r_symndx - symtab_hdr->sh_info];
01969 
01970       switch (ELF32_R_TYPE (rel->r_info))
01971        {
01972        /* This relocation describes the C++ object vtable hierarchy.
01973            Reconstruct it for later use during GC.  */
01974         case R_BFIN_GNU_VTINHERIT:
01975           if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
01976             return FALSE;
01977           break;
01978 
01979         /* This relocation describes which C++ vtable entries
01980            are actually used.  Record for later use during GC.  */
01981         case R_BFIN_GNU_VTENTRY:
01982           if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
01983             return FALSE;
01984           break;
01985 
01986        case R_got:
01987          if (h != NULL
01988              && strcmp (h->root.root.string, "__GLOBAL_OFFSET_TABLE_") == 0)
01989            break;
01990          /* Fall through.  */
01991 
01992          if (dynobj == NULL)
01993            {
01994              /* Create the .got section.  */
01995              elf_hash_table (info)->dynobj = dynobj = abfd;
01996              if (!_bfd_elf_create_got_section (dynobj, info))
01997               return FALSE;
01998            }
01999 
02000          if (sgot == NULL)
02001            {
02002              sgot = bfd_get_section_by_name (dynobj, ".got");
02003              BFD_ASSERT (sgot != NULL);
02004            }
02005 
02006          if (srelgot == NULL && (h != NULL || info->shared))
02007            {
02008              srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
02009              if (srelgot == NULL)
02010               {
02011                 flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
02012                                 | SEC_IN_MEMORY | SEC_LINKER_CREATED
02013                                 | SEC_READONLY);
02014                 srelgot = bfd_make_section_with_flags (dynobj, ".rela.got",
02015                                                   flags);
02016                 if (srelgot == NULL
02017                     || !bfd_set_section_alignment (dynobj, srelgot, 2))
02018                   return FALSE;
02019               }
02020            }
02021 
02022          if (h != NULL)
02023            {
02024              if (h->got.refcount == 0)
02025               {
02026                 /* Make sure this symbol is output as a dynamic symbol.  */
02027                 if (h->dynindx == -1 && !h->forced_local)
02028                   {
02029                     if (!bfd_elf_link_record_dynamic_symbol (info, h))
02030                      return FALSE;
02031                   }
02032 
02033                 /* Allocate space in the .got section.  */
02034                 sgot->size += 4;
02035                 /* Allocate relocation space.  */
02036                 srelgot->size += sizeof (Elf32_External_Rela);
02037               }
02038              h->got.refcount++;
02039            }
02040          else
02041            {
02042              /* This is a global offset table entry for a local symbol.  */
02043              if (local_got_refcounts == NULL)
02044               {
02045                 bfd_size_type size;
02046 
02047                 size = symtab_hdr->sh_info;
02048                 size *= sizeof (bfd_signed_vma);
02049                 local_got_refcounts = ((bfd_signed_vma *)
02050                                     bfd_zalloc (abfd, size));
02051                 if (local_got_refcounts == NULL)
02052                   return FALSE;
02053                 elf_local_got_refcounts (abfd) = local_got_refcounts;
02054               }
02055              if (local_got_refcounts[r_symndx] == 0)
02056               {
02057                 sgot->size += 4;
02058                 if (info->shared)
02059                   {
02060                     /* If we are generating a shared object, we need to
02061                        output a R_68K_RELATIVE reloc so that the dynamic
02062                        linker can adjust this GOT entry.  */
02063                     srelgot->size += sizeof (Elf32_External_Rela);
02064                   }
02065               }
02066              local_got_refcounts[r_symndx]++;
02067            }
02068          break;
02069 
02070        default:
02071          break;
02072        }
02073     }
02074 
02075   return TRUE;
02076 }
02077 
02078 static enum elf_reloc_type_class
02079 elf32_bfin_reloc_type_class (const Elf_Internal_Rela * rela)
02080 {
02081   switch ((int) ELF32_R_TYPE (rela->r_info))
02082     {
02083     default:
02084       return reloc_class_normal;
02085     }
02086 }
02087 
02088 /* Relocate an Blackfin ELF section.
02089 
02090    The RELOCATE_SECTION function is called by the new ELF backend linker
02091    to handle the relocations for a section.
02092 
02093    The relocs are always passed as Rela structures; if the section
02094    actually uses Rel structures, the r_addend field will always be
02095    zero.
02096 
02097    This function is responsible for adjusting the section contents as
02098    necessary, and (if using Rela relocs and generating a relocatable
02099    output file) adjusting the reloc addend as necessary.
02100 
02101    This function does not have to worry about setting the reloc
02102    address or the reloc symbol index.
02103 
02104    LOCAL_SYMS is a pointer to the swapped in local symbols.
02105 
02106    LOCAL_SECTIONS is an array giving the section in the input file
02107    corresponding to the st_shndx field of each local symbol.
02108 
02109    The global hash table entry for the global symbols can be found
02110    via elf_sym_hashes (input_bfd).
02111 
02112    When generating relocatable output, this function must handle
02113    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
02114    going to be the section symbol corresponding to the output
02115    section, which means that the addend must be adjusted
02116    accordingly.  */
02117 
02118 static bfd_boolean
02119 bfinfdpic_relocate_section (bfd * output_bfd,
02120                          struct bfd_link_info *info,
02121                          bfd * input_bfd,
02122                          asection * input_section,
02123                          bfd_byte * contents,
02124                          Elf_Internal_Rela * relocs,
02125                          Elf_Internal_Sym * local_syms,
02126                          asection ** local_sections)
02127 {
02128   Elf_Internal_Shdr *symtab_hdr;
02129   struct elf_link_hash_entry **sym_hashes;
02130   Elf_Internal_Rela *rel;
02131   Elf_Internal_Rela *relend;
02132   unsigned isec_segment, got_segment, plt_segment,
02133     check_segment[2];
02134   int silence_segment_error = !(info->shared || info->pie);
02135 
02136   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
02137   sym_hashes = elf_sym_hashes (input_bfd);
02138   relend     = relocs + input_section->reloc_count;
02139 
02140   isec_segment = _bfinfdpic_osec_to_segment (output_bfd,
02141                                         input_section->output_section);
02142   if (IS_FDPIC (output_bfd) && bfinfdpic_got_section (info))
02143     got_segment = _bfinfdpic_osec_to_segment (output_bfd,
02144                                          bfinfdpic_got_section (info)
02145                                          ->output_section);
02146   else
02147     got_segment = -1;
02148   if (IS_FDPIC (output_bfd) && elf_hash_table (info)->dynamic_sections_created)
02149     plt_segment = _bfinfdpic_osec_to_segment (output_bfd,
02150                                          bfinfdpic_plt_section (info)
02151                                          ->output_section);
02152   else
02153     plt_segment = -1;
02154 
02155   for (rel = relocs; rel < relend; rel ++)
02156     {
02157       reloc_howto_type *howto;
02158       unsigned long r_symndx;
02159       Elf_Internal_Sym *sym;
02160       asection *sec;
02161       struct elf_link_hash_entry *h;
02162       bfd_vma relocation;
02163       bfd_reloc_status_type r;
02164       const char * name = NULL;
02165       int r_type;
02166       asection *osec;
02167       struct bfinfdpic_relocs_info *picrel;
02168       bfd_vma orig_addend = rel->r_addend;
02169 
02170       r_type = ELF32_R_TYPE (rel->r_info);
02171 
02172       if (r_type == R_BFIN_GNU_VTINHERIT
02173          || r_type == R_BFIN_GNU_VTENTRY)
02174        continue;
02175 
02176       r_symndx = ELF32_R_SYM (rel->r_info);
02177       howto = bfin_reloc_type_lookup (input_bfd, r_type);
02178       if (howto == NULL)
02179        {
02180          bfd_set_error (bfd_error_bad_value);
02181          return FALSE;
02182        }
02183 
02184       h      = NULL;
02185       sym    = NULL;
02186       sec    = NULL;
02187 
02188       if (r_symndx < symtab_hdr->sh_info)
02189        {
02190          sym = local_syms + r_symndx;
02191          osec = sec = local_sections [r_symndx];
02192          relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
02193 
02194          name = bfd_elf_string_from_elf_section
02195            (input_bfd, symtab_hdr->sh_link, sym->st_name);
02196          name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
02197        }
02198       else
02199        {
02200          bfd_boolean warned;
02201          bfd_boolean unresolved_reloc;
02202 
02203          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
02204                                r_symndx, symtab_hdr, sym_hashes,
02205                                h, sec, relocation,
02206                                unresolved_reloc, warned);
02207          osec = sec;
02208        }
02209 
02210       if (sec != NULL && elf_discarded_section (sec))
02211        {
02212          /* For relocs against symbols from removed linkonce sections,
02213             or sections discarded by a linker script, we just want the
02214             section contents zeroed.  Avoid any special processing.  */
02215          _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
02216          rel->r_info = 0;
02217          rel->r_addend = 0;
02218          continue;
02219        }
02220 
02221       if (info->relocatable)
02222        continue;
02223 
02224       if (h != NULL
02225          && (h->root.type == bfd_link_hash_defined
02226              || h->root.type == bfd_link_hash_defweak)
02227          && !BFINFDPIC_SYM_LOCAL (info, h))
02228        {
02229          osec = sec = NULL;
02230          relocation = 0;
02231        }
02232 
02233       switch (r_type)
02234        {
02235        case R_pcrel24:
02236        case R_pcrel24_jump_l:
02237        case R_byte4_data:
02238          if (! IS_FDPIC (output_bfd))
02239            goto non_fdpic;
02240 
02241        case R_BFIN_GOT17M4:
02242        case R_BFIN_GOTHI:
02243        case R_BFIN_GOTLO:
02244        case R_BFIN_FUNCDESC_GOT17M4:
02245        case R_BFIN_FUNCDESC_GOTHI:
02246        case R_BFIN_FUNCDESC_GOTLO:
02247        case R_BFIN_GOTOFF17M4:
02248        case R_BFIN_GOTOFFHI:
02249        case R_BFIN_GOTOFFLO:
02250        case R_BFIN_FUNCDESC_GOTOFF17M4:
02251        case R_BFIN_FUNCDESC_GOTOFFHI:
02252        case R_BFIN_FUNCDESC_GOTOFFLO:
02253        case R_BFIN_FUNCDESC:
02254        case R_BFIN_FUNCDESC_VALUE:
02255          if (h != NULL)
02256            picrel = bfinfdpic_relocs_info_for_global (bfinfdpic_relocs_info
02257                                                  (info), input_bfd, h,
02258                                                  orig_addend, INSERT);
02259          else
02260            /* In order to find the entry we created before, we must
02261               use the original addend, not the one that may have been
02262               modified by _bfd_elf_rela_local_sym().  */
02263            picrel = bfinfdpic_relocs_info_for_local (bfinfdpic_relocs_info
02264                                                 (info), input_bfd, r_symndx,
02265                                                 orig_addend, INSERT);
02266          if (! picrel)
02267            return FALSE;
02268 
02269          if (!_bfinfdpic_emit_got_relocs_plt_entries (picrel, output_bfd, info,
02270                                                  osec, sym,
02271                                                  rel->r_addend))
02272            {
02273              (*_bfd_error_handler)
02274               (_("%B: relocation at `%A+0x%x' references symbol `%s' with nonzero addend"),
02275                input_bfd, input_section, rel->r_offset, name);
02276              return FALSE;
02277 
02278            }
02279 
02280          break;
02281 
02282        default:
02283        non_fdpic:
02284          picrel = NULL;
02285          if (h && ! BFINFDPIC_SYM_LOCAL (info, h))
02286            {
02287              info->callbacks->warning
02288               (info, _("relocation references symbol not defined in the module"),
02289                name, input_bfd, input_section, rel->r_offset);
02290              return FALSE;
02291            }
02292          break;
02293        }
02294 
02295       switch (r_type)
02296        {
02297        case R_pcrel24:
02298        case R_pcrel24_jump_l:
02299          check_segment[0] = isec_segment;
02300          if (! IS_FDPIC (output_bfd))
02301            check_segment[1] = isec_segment;
02302          else if (picrel->plt)
02303            {
02304              relocation = bfinfdpic_plt_section (info)->output_section->vma
02305               + bfinfdpic_plt_section (info)->output_offset
02306               + picrel->plt_entry;
02307              check_segment[1] = plt_segment;
02308            }
02309          /* We don't want to warn on calls to undefined weak symbols,
02310             as calls to them must be protected by non-NULL tests
02311             anyway, and unprotected calls would invoke undefined
02312             behavior.  */
02313          else if (picrel->symndx == -1
02314                  && picrel->d.h->root.type == bfd_link_hash_undefweak)
02315            check_segment[1] = check_segment[0];
02316          else
02317            check_segment[1] = sec
02318              ? _bfinfdpic_osec_to_segment (output_bfd, sec->output_section)
02319              : (unsigned)-1;
02320          break;
02321 
02322        case R_BFIN_GOT17M4:
02323        case R_BFIN_GOTHI:
02324        case R_BFIN_GOTLO:
02325          relocation = picrel->got_entry;
02326          check_segment[0] = check_segment[1] = got_segment;
02327          break;
02328 
02329        case R_BFIN_FUNCDESC_GOT17M4:
02330        case R_BFIN_FUNCDESC_GOTHI:
02331        case R_BFIN_FUNCDESC_GOTLO:
02332          relocation = picrel->fdgot_entry;
02333          check_segment[0] = check_segment[1] = got_segment;
02334          break;
02335 
02336        case R_BFIN_GOTOFFHI:
02337        case R_BFIN_GOTOFF17M4:
02338        case R_BFIN_GOTOFFLO:
02339          relocation -= bfinfdpic_got_section (info)->output_section->vma
02340            + bfinfdpic_got_section (info)->output_offset
02341            + bfinfdpic_got_initial_offset (info);
02342          check_segment[0] = got_segment;
02343          check_segment[1] = sec
02344            ? _bfinfdpic_osec_to_segment (output_bfd, sec->output_section)
02345            : (unsigned)-1;
02346          break;
02347 
02348        case R_BFIN_FUNCDESC_GOTOFF17M4:
02349        case R_BFIN_FUNCDESC_GOTOFFHI:
02350        case R_BFIN_FUNCDESC_GOTOFFLO:
02351          relocation = picrel->fd_entry;
02352          check_segment[0] = check_segment[1] = got_segment;
02353          break;
02354 
02355        case R_BFIN_FUNCDESC:
02356          {
02357            int dynindx;
02358            bfd_vma addend = rel->r_addend;
02359 
02360            if (! (h && h->root.type == bfd_link_hash_undefweak
02361                  && BFINFDPIC_SYM_LOCAL (info, h)))
02362              {
02363               /* If the symbol is dynamic and there may be dynamic
02364                  symbol resolution because we are or are linked with a
02365                  shared library, emit a FUNCDESC relocation such that
02366                  the dynamic linker will allocate the function
02367                  descriptor.  If the symbol needs a non-local function
02368                  descriptor but binds locally (e.g., its visibility is
02369                  protected, emit a dynamic relocation decayed to
02370                  section+offset.  */
02371               if (h && ! BFINFDPIC_FUNCDESC_LOCAL (info, h)
02372                   && BFINFDPIC_SYM_LOCAL (info, h)
02373                   && !(info->executable && !info->pie))
02374                 {
02375                   dynindx = elf_section_data (h->root.u.def.section
02376                                           ->output_section)->dynindx;
02377                   addend += h->root.u.def.section->output_offset
02378                     + h->root.u.def.value;
02379                 }
02380               else if (h && ! BFINFDPIC_FUNCDESC_LOCAL (info, h))
02381                 {
02382                   if (addend)
02383                     {
02384                      info->callbacks->warning
02385                        (info, _("R_BFIN_FUNCDESC references dynamic symbol with nonzero addend"),
02386                         name, input_bfd, input_section, rel->r_offset);
02387                      return FALSE;
02388                     }
02389                   dynindx = h->dynindx;
02390                 }
02391               else
02392                 {
02393                   /* Otherwise, we know we have a private function
02394                      descriptor, so reference it directly.  */
02395                   BFD_ASSERT (picrel->privfd);
02396                   r_type = R_byte4_data;
02397                   dynindx = elf_section_data (bfinfdpic_got_section (info)
02398                                           ->output_section)->dynindx;
02399                   addend = bfinfdpic_got_section (info)->output_offset
02400                     + bfinfdpic_got_initial_offset (info)
02401                     + picrel->fd_entry;
02402                 }
02403 
02404               /* If there is room for dynamic symbol resolution, emit
02405                  the dynamic relocation.  However, if we're linking an
02406                  executable at a fixed location, we won't have emitted a
02407                  dynamic symbol entry for the got section, so idx will
02408                  be zero, which means we can and should compute the
02409                  address of the private descriptor ourselves.  */
02410               if (info->executable && !info->pie
02411                   && (!h || BFINFDPIC_FUNCDESC_LOCAL (info, h)))
02412                 {
02413                   addend += bfinfdpic_got_section (info)->output_section->vma;
02414                   if ((bfd_get_section_flags (output_bfd,
02415                                           input_section->output_section)
02416                       & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
02417                     {
02418                      if (_bfinfdpic_osec_readonly_p (output_bfd,
02419                                                  input_section
02420                                                  ->output_section))
02421                        {
02422                          info->callbacks->warning
02423                            (info,
02424                             _("cannot emit fixups in read-only section"),
02425                             name, input_bfd, input_section, rel->r_offset);
02426                          return FALSE;
02427                        }
02428                      _bfinfdpic_add_rofixup (output_bfd,
02429                                           bfinfdpic_gotfixup_section
02430                                           (info),
02431                                           _bfd_elf_section_offset
02432                                           (output_bfd, info,
02433                                           input_section, rel->r_offset)
02434                                           + input_section
02435                                           ->output_section->vma
02436                                           + input_section->output_offset,
02437                                           picrel);
02438                     }
02439                 }
02440               else if ((bfd_get_section_flags (output_bfd,
02441                                            input_section->output_section)
02442                        & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
02443                 {
02444                   bfd_vma offset;
02445 
02446                   if (_bfinfdpic_osec_readonly_p (output_bfd,
02447                                              input_section
02448                                              ->output_section))
02449                     {
02450                      info->callbacks->warning
02451                        (info,
02452                         _("cannot emit dynamic relocations in read-only section"),
02453                         name, input_bfd, input_section, rel->r_offset);
02454                      return FALSE;
02455                     }
02456                   offset = _bfd_elf_section_offset (output_bfd, info,
02457                                                 input_section, rel->r_offset);
02458                   /* Only output a reloc for a not deleted entry.  */
02459                   if (offset >= (bfd_vma) -2)
02460                     _bfinfdpic_add_dyn_reloc (output_bfd,
02461                                           bfinfdpic_gotrel_section (info),
02462                                           0,
02463                                           R_unused0,
02464                                           dynindx, addend, picrel);
02465                   else
02466                     _bfinfdpic_add_dyn_reloc (output_bfd,
02467                                           bfinfdpic_gotrel_section (info),
02468                                           offset + input_section
02469                                           ->output_section->vma
02470                                           + input_section->output_offset,
02471                                           r_type,
02472                                           dynindx, addend, picrel);
02473                 }
02474               else
02475                 addend += bfinfdpic_got_section (info)->output_section->vma;
02476              }
02477 
02478            /* We want the addend in-place because dynamic
02479               relocations are REL.  Setting relocation to it should
02480               arrange for it to be installed.  */
02481            relocation = addend - rel->r_addend;
02482          }
02483          check_segment[0] = check_segment[1] = got_segment;
02484          break;
02485 
02486        case R_byte4_data:
02487          if (! IS_FDPIC (output_bfd))
02488            {
02489              check_segment[0] = check_segment[1] = -1;
02490              break;
02491            }
02492          /* Fall through.  */
02493        case R_BFIN_FUNCDESC_VALUE:
02494          {
02495            int dynindx;
02496            bfd_vma addend = rel->r_addend;
02497 
02498            /* If the symbol is dynamic but binds locally, use
02499               section+offset.  */
02500            if (h && ! BFINFDPIC_SYM_LOCAL (info, h))
02501              {
02502               if (addend && r_type == R_BFIN_FUNCDESC_VALUE)
02503                 {
02504                   info->callbacks->warning
02505                     (info, _("R_BFIN_FUNCDESC_VALUE references dynamic symbol with nonzero addend"),
02506                      name, input_bfd, input_section, rel->r_offset);
02507                   return FALSE;
02508                 }
02509               dynindx = h->dynindx;
02510              }
02511            else
02512              {
02513               if (h)
02514                 addend += h->root.u.def.value;
02515               else
02516                 addend += sym->st_value;
02517               if (osec)
02518                 addend += osec->output_offset;
02519               if (osec && osec->output_section
02520                   && ! bfd_is_abs_section (osec->output_section)
02521                   && ! bfd_is_und_section (osec->output_section))
02522                 dynindx = elf_section_data (osec->output_section)->dynindx;
02523               else
02524                 dynindx = 0;
02525              }
02526 
02527            /* If we're linking an executable at a fixed address, we
02528               can omit the dynamic relocation as long as the symbol
02529               is defined in the current link unit (which is implied
02530               by its output section not being NULL).  */
02531            if (info->executable && !info->pie
02532               && (!h || BFINFDPIC_SYM_LOCAL (info, h)))
02533              {
02534               if (osec)
02535                 addend += osec->output_section->vma;
02536               if (IS_FDPIC (input_bfd)
02537                   && (bfd_get_section_flags (output_bfd,
02538                                           input_section->output_section)
02539                      & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
02540                 {
02541                   if (_bfinfdpic_osec_readonly_p (output_bfd,
02542                                              input_section
02543                                              ->output_section))
02544                     {
02545                      info->callbacks->warning
02546                        (info,
02547                         _("cannot emit fixups in read-only section"),
02548                         name, input_bfd, input_section, rel->r_offset);
02549                      return FALSE;
02550                     }
02551                   if (!h || h->root.type != bfd_link_hash_undefweak)
02552                     {
02553                      _bfinfdpic_add_rofixup (output_bfd,
02554                                           bfinfdpic_gotfixup_section
02555                                           (info),
02556                                           _bfd_elf_section_offset
02557                                           (output_bfd, info,
02558                                           input_section, rel->r_offset)
02559                                           + input_section
02560                                           ->output_section->vma
02561                                           + input_section->output_offset,
02562                                           picrel);
02563                      if (r_type == R_BFIN_FUNCDESC_VALUE)
02564                        _bfinfdpic_add_rofixup
02565                          (output_bfd,
02566                           bfinfdpic_gotfixup_section (info),
02567                           _bfd_elf_section_offset
02568                           (output_bfd, info,
02569                            input_section, rel->r_offset)
02570                           + input_section->output_section->vma
02571                           + input_section->output_offset + 4, picrel);
02572                     }
02573                 }
02574              }
02575            else
02576              {
02577               if ((bfd_get_section_flags (output_bfd,
02578                                        input_section->output_section)
02579                    & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
02580                 {
02581                   if (_bfinfdpic_osec_readonly_p (output_bfd,
02582                                              input_section
02583                                              ->output_section))
02584                     {
02585                      info->callbacks->warning
02586                        (info,
02587                         _("cannot emit dynamic relocations in read-only section"),
02588                         name, input_bfd, input_section, rel->r_offset);
02589                      return FALSE;
02590                     }
02591                   _bfinfdpic_add_dyn_reloc (output_bfd,
02592                                          bfinfdpic_gotrel_section (info),
02593                                          _bfd_elf_section_offset
02594                                          (output_bfd, info,
02595                                           input_section, rel->r_offset)
02596                                          + input_section
02597                                          ->output_section->vma
02598                                          + input_section->output_offset,
02599                                          r_type, dynindx, addend, picrel);
02600                 }
02601               else if (osec)
02602                 addend += osec->output_section->vma;
02603               /* We want the addend in-place because dynamic
02604                  relocations are REL.  Setting relocation to it
02605                  should arrange for it to be installed.  */
02606               relocation = addend - rel->r_addend;
02607              }
02608 
02609            if (r_type == R_BFIN_FUNCDESC_VALUE)
02610              {
02611               /* If we've omitted the dynamic relocation, just emit
02612                  the fixed addresses of the symbol and of the local
02613                  GOT base offset.  */
02614               if (info->executable && !info->pie
02615                   && (!h || BFINFDPIC_SYM_LOCAL (info, h)))
02616                 bfd_put_32 (output_bfd,
02617                            bfinfdpic_got_section (info)->output_section->vma
02618                            + bfinfdpic_got_section (info)->output_offset
02619                            + bfinfdpic_got_initial_offset (info),
02620                            contents + rel->r_offset + 4);
02621               else
02622                 /* A function descriptor used for lazy or local
02623                    resolving is initialized such that its high word
02624                    contains the output section index in which the
02625                    PLT entries are located, and the low word
02626                    contains the offset of the lazy PLT entry entry
02627                    point into that section.  */
02628                 bfd_put_32 (output_bfd,
02629                            h && ! BFINFDPIC_SYM_LOCAL (info, h)
02630                            ? 0
02631                            : _bfinfdpic_osec_to_segment (output_bfd,
02632                                                      sec
02633                                                      ->output_section),
02634                            contents + rel->r_offset + 4);
02635              }
02636          }
02637          check_segment[0] = check_segment[1] = got_segment;
02638          break;
02639 
02640        default:
02641          check_segment[0] = isec_segment;
02642          check_segment[1] = sec
02643            ? _bfinfdpic_osec_to_segment (output_bfd, sec->output_section)
02644            : (unsigned)-1;
02645          break;
02646        }
02647 
02648       if (check_segment[0] != check_segment[1] && IS_FDPIC (output_bfd))
02649        {
02650 #if 1 /* If you take this out, remove the #error from fdpic-static-6.d
02651         in the ld testsuite.  */
02652          /* This helps catch problems in GCC while we can't do more
02653             than static linking.  The idea is to test whether the
02654             input file basename is crt0.o only once.  */
02655          if (silence_segment_error == 1)
02656            silence_segment_error =
02657              (strlen (input_bfd->filename) == 6
02658               && strcmp (input_bfd->filename, "crt0.o") == 0)
02659              || (strlen (input_bfd->filename) > 6
02660                 && strcmp (input_bfd->filename
02661                           + strlen (input_bfd->filename) - 7,
02662                           "/crt0.o") == 0)
02663              ? -1 : 0;
02664 #endif
02665          if (!silence_segment_error
02666              /* We don't want duplicate errors for undefined
02667                symbols.  */
02668              && !(picrel && picrel->symndx == -1
02669                  && picrel->d.h->root.type == bfd_link_hash_undefined))
02670            info->callbacks->warning
02671              (info,
02672               (info->shared || info->pie)
02673               ? _("relocations between different segments are not supported")
02674               : _("warning: relocation references a different segment"),
02675               name, input_bfd, input_section, rel->r_offset);
02676          if (!silence_segment_error && (info->shared || info->pie))
02677            return FALSE;
02678          elf_elfheader (output_bfd)->e_flags |= EF_BFIN_PIC;
02679        }
02680 
02681       switch (r_type)
02682        {
02683        case R_BFIN_GOTOFFHI:
02684          /* We need the addend to be applied before we shift the
02685             value right.  */
02686          relocation += rel->r_addend;
02687          /* Fall through.  */
02688        case R_BFIN_GOTHI:
02689        case R_BFIN_FUNCDESC_GOTHI:
02690        case R_BFIN_FUNCDESC_GOTOFFHI:
02691          relocation >>= 16;
02692          /* Fall through.  */
02693 
02694        case R_BFIN_GOTLO:
02695        case R_BFIN_FUNCDESC_GOTLO:
02696        case R_BFIN_GOTOFFLO:
02697        case R_BFIN_FUNCDESC_GOTOFFLO:
02698          relocation &= 0xffff;
02699          break;
02700 
02701        default:
02702          break;
02703        }
02704 
02705       switch (r_type)
02706        {
02707        case R_pcrel24:
02708        case R_pcrel24_jump_l:
02709          if (! IS_FDPIC (output_bfd) || ! picrel->plt)
02710            break;
02711          /* Fall through.  */
02712 
02713          /* When referencing a GOT entry, a function descriptor or a
02714             PLT, we don't want the addend to apply to the reference,
02715             but rather to the referenced symbol.  The actual entry
02716             will have already been created taking the addend into
02717             account, so cancel it out here.  */
02718        case R_BFIN_GOT17M4:
02719        case R_BFIN_GOTHI:
02720        case R_BFIN_GOTLO:
02721        case R_BFIN_FUNCDESC_GOT17M4:
02722        case R_BFIN_FUNCDESC_GOTHI:
02723        case R_BFIN_FUNCDESC_GOTLO:
02724        case R_BFIN_FUNCDESC_GOTOFF17M4:
02725        case R_BFIN_FUNCDESC_GOTOFFHI:
02726        case R_BFIN_FUNCDESC_GOTOFFLO:
02727          /* Note that we only want GOTOFFHI, not GOTOFFLO or GOTOFF17M4
02728             here, since we do want to apply the addend to the others.
02729             Note that we've applied the addend to GOTOFFHI before we
02730             shifted it right.  */
02731        case R_BFIN_GOTOFFHI:
02732          relocation -= rel->r_addend;
02733          break;
02734 
02735        default:
02736          break;
02737        }
02738 
02739       if (r_type == R_pcrel24
02740          || r_type == R_pcrel24_jump_l)
02741        {
02742          bfd_vma x;
02743          bfd_vma address = rel->r_offset;
02744 
02745          relocation += rel->r_addend;
02746 
02747          /* Perform usual pc-relative correction.  */
02748          relocation -= input_section->output_section->vma + input_section->output_offset;
02749          relocation -= address;
02750 
02751          /* We are getting reloc_entry->address 2 byte off from
02752             the start of instruction. Assuming absolute postion
02753             of the reloc data. But, following code had been written assuming
02754             reloc address is starting at begining of instruction.
02755             To compensate that I have increased the value of
02756             relocation by 1 (effectively 2) and used the addr -2 instead of addr.  */
02757 
02758          relocation += 2;
02759          address -= 2;
02760 
02761          relocation >>= 1;
02762 
02763          x = bfd_get_16 (input_bfd, contents + address);
02764          x = (x & 0xff00) | ((relocation >> 16) & 0xff);
02765          bfd_put_16 (input_bfd, x, contents + address);
02766 
02767          x = bfd_get_16 (input_bfd, contents + address + 2);
02768          x = relocation & 0xFFFF;
02769          bfd_put_16 (input_bfd, x, contents + address + 2);
02770          r = bfd_reloc_ok;
02771        }
02772       else
02773        r = _bfd_final_link_relocate (howto, input_bfd, input_section,
02774                                   contents, rel->r_offset,
02775                                   relocation, rel->r_addend);
02776 
02777       if (r != bfd_reloc_ok)
02778        {
02779          const char * msg = (const char *) NULL;
02780 
02781          switch (r)
02782            {
02783            case bfd_reloc_overflow:
02784              r = info->callbacks->reloc_overflow
02785               (info, (h ? &h->root : NULL), name, howto->name,
02786                (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
02787              break;
02788 
02789            case bfd_reloc_undefined:
02790              r = info->callbacks->undefined_symbol
02791               (info, name, input_bfd, input_section, rel->r_offset, TRUE);
02792              break;
02793 
02794            case bfd_reloc_outofrange:
02795              msg = _("internal error: out of range error");
02796              break;
02797 
02798            case bfd_reloc_notsupported:
02799              msg = _("internal error: unsupported relocation error");
02800              break;
02801 
02802            case bfd_reloc_dangerous:
02803              msg = _("internal error: dangerous relocation");
02804              break;
02805 
02806            default:
02807              msg = _("internal error: unknown error");
02808              break;
02809            }
02810 
02811          if (msg)
02812            r = info->callbacks->warning
02813              (info, msg, name, input_bfd, input_section, rel->r_offset);
02814 
02815          if (! r)
02816            return FALSE;
02817        }
02818     }
02819 
02820   return TRUE;
02821 }
02822 
02823 static bfd_boolean
02824 bfin_relocate_section (bfd * output_bfd,
02825                      struct bfd_link_info *info,
02826                      bfd * input_bfd,
02827                      asection * input_section,
02828                      bfd_byte * contents,
02829                      Elf_Internal_Rela * relocs,
02830                      Elf_Internal_Sym * local_syms,
02831                      asection ** local_sections)
02832 {
02833   bfd *dynobj;
02834   Elf_Internal_Shdr *symtab_hdr;
02835   struct elf_link_hash_entry **sym_hashes;
02836   bfd_vma *local_got_offsets;
02837   asection *sgot;
02838   asection *sreloc;
02839   Elf_Internal_Rela *rel;
02840   Elf_Internal_Rela *relend;
02841   int i = 0;
02842 
02843   dynobj = elf_hash_table (info)->dynobj;
02844   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
02845   sym_hashes = elf_sym_hashes (input_bfd);
02846   local_got_offsets = elf_local_got_offsets (input_bfd);
02847 
02848   sgot = NULL;
02849   sreloc = NULL;
02850 
02851   rel = relocs;
02852   relend = relocs + input_section->reloc_count;
02853   for (; rel < relend; rel++, i++)
02854     {
02855       int r_type;
02856       reloc_howto_type *howto;
02857       unsigned long r_symndx;
02858       struct elf_link_hash_entry *h;
02859       Elf_Internal_Sym *sym;
02860       asection *sec;
02861       bfd_vma relocation = 0;
02862       bfd_boolean unresolved_reloc;
02863       bfd_reloc_status_type r;
02864       bfd_vma address;
02865 
02866       r_type = ELF32_R_TYPE (rel->r_info);
02867       if (r_type < 0 || r_type >= 243)
02868        {
02869          bfd_set_error (bfd_error_bad_value);
02870          return FALSE;
02871        }
02872 
02873       if (r_type == R_BFIN_GNU_VTENTRY
02874           || r_type == R_BFIN_GNU_VTINHERIT)
02875        continue;
02876 
02877       howto = bfin_reloc_type_lookup (input_bfd, r_type);
02878       if (howto == NULL)
02879        {
02880          bfd_set_error (bfd_error_bad_value);
02881          return FALSE;
02882        }
02883       r_symndx = ELF32_R_SYM (rel->r_info);
02884 
02885       h = NULL;
02886       sym = NULL;
02887       sec = NULL;
02888       unresolved_reloc = FALSE;
02889 
02890       if (r_symndx < symtab_hdr->sh_info)
02891        {
02892          sym = local_syms + r_symndx;
02893          sec = local_sections[r_symndx];
02894          relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
02895        }
02896       else
02897        {
02898          bfd_boolean warned;
02899 
02900          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
02901                                r_symndx, symtab_hdr, sym_hashes,
02902                                h, sec, relocation,
02903                                unresolved_reloc, warned);
02904        }
02905 
02906       if (sec != NULL && elf_discarded_section (sec))
02907        {
02908          /* For relocs against symbols from removed linkonce sections,
02909             or sections discarded by a linker script, we just want the
02910             section contents zeroed.  Avoid any special processing.  */
02911          _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
02912          rel->r_info = 0;
02913          rel->r_addend = 0;
02914          continue;
02915        }
02916 
02917       if (info->relocatable)
02918        continue;
02919 
02920       address = rel->r_offset;
02921 
02922       /* Then, process normally.  */
02923       switch (r_type)
02924        {
02925        case R_BFIN_GNU_VTINHERIT:
02926        case R_BFIN_GNU_VTENTRY:
02927          return bfd_reloc_ok;
02928 
02929        case R_got:
02930          /* Relocation is to the address of the entry for this symbol
02931             in the global offset table.  */
02932          if (h != NULL
02933              && strcmp (h->root.root.string, "__GLOBAL_OFFSET_TABLE_") == 0)
02934            goto do_default;
02935          /* Fall through.  */
02936          /* Relocation is the offset of the entry for this symbol in
02937             the global offset table.  */
02938 
02939          {
02940            bfd_vma off;
02941 
02942            if (sgot == NULL)
02943              {
02944               sgot = bfd_get_section_by_name (dynobj, ".got");
02945               BFD_ASSERT (sgot != NULL);
02946              }
02947 
02948            if (h != NULL)
02949              {
02950               bfd_boolean dyn;
02951 
02952               off = h->got.offset;
02953               BFD_ASSERT (off != (bfd_vma) - 1);
02954               dyn = elf_hash_table (info)->dynamic_sections_created;
02955 
02956               if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
02957                   || (info->shared
02958                      && (info->symbolic
02959                          || h->dynindx == -1
02960                          || h->forced_local)
02961                      && h->def_regular))
02962                 {
02963                   /* This is actually a static link, or it is a
02964                      -Bsymbolic link and the symbol is defined
02965                      locally, or the symbol was forced to be local
02966                      because of a version file..  We must initialize
02967                      this entry in the global offset table.  Since
02968                      the offset must always be a multiple of 4, we
02969                      use the least significant bit to record whether
02970                      we have initialized it already.
02971 
02972                      When doing a dynamic link, we create a .rela.got
02973                      relocation entry to initialize the value.  This
02974                      is done in the finish_dynamic_symbol routine.  */
02975                   if ((off & 1) != 0)
02976                     off &= ~1;
02977                   else
02978                     {
02979                      bfd_put_32 (output_bfd, relocation,
02980                                 sgot->contents + off);
02981                      h->got.offset |= 1;
02982                     }
02983                 }
02984               else
02985                 unresolved_reloc = FALSE;
02986              }
02987            else
02988              {
02989               BFD_ASSERT (local_got_offsets != NULL);
02990               off = local_got_offsets[r_symndx];
02991               BFD_ASSERT (off != (bfd_vma) - 1);
02992 
02993               /* The offset must always be a multiple of 4.  We use
02994                  the least significant bit to record whether we have
02995                  already generated the necessary reloc.  */
02996               if ((off & 1) != 0)
02997                 off &= ~1;
02998               else
02999                 {
03000                   bfd_put_32 (output_bfd, relocation, sgot->contents + off);
03001 
03002                   if (info->shared)
03003                     {
03004                      asection *s;
03005                      Elf_Internal_Rela outrel;
03006                      bfd_byte *loc;
03007 
03008                      s = bfd_get_section_by_name (dynobj, ".rela.got");
03009                      BFD_ASSERT (s != NULL);
03010 
03011                      outrel.r_offset = (sgot->output_section->vma
03012                                       + sgot->output_offset + off);
03013                      outrel.r_info =
03014                        ELF32_R_INFO (0, R_pcrel24);
03015                      outrel.r_addend = relocation;
03016                      loc = s->contents;
03017                      loc +=
03018                        s->reloc_count++ * sizeof (Elf32_External_Rela);
03019                      bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
03020                     }
03021 
03022                   local_got_offsets[r_symndx] |= 1;
03023                 }
03024              }
03025 
03026            relocation = sgot->output_offset + off;
03027            rel->r_addend = 0;
03028             /* bfin : preg = [preg + 17bitdiv4offset] relocation is div by 4.  */
03029             relocation /= 4;
03030          }
03031          goto do_default;
03032 
03033        case R_pcrel24:
03034        case R_pcrel24_jump_l:
03035          {
03036            bfd_vma x;
03037 
03038            relocation += rel->r_addend;
03039 
03040            /* Perform usual pc-relative correction.  */
03041            relocation -= input_section->output_section->vma + input_section->output_offset;
03042            relocation -= address;
03043 
03044            /* We are getting reloc_entry->address 2 byte off from
03045               the start of instruction. Assuming absolute postion
03046               of the reloc data. But, following code had been written assuming
03047               reloc address is starting at begining of instruction.
03048               To compensate that I have increased the value of
03049               relocation by 1 (effectively 2) and used the addr -2 instead of addr.  */
03050 
03051            relocation += 2;
03052            address -= 2;
03053 
03054            relocation >>= 1;
03055 
03056            x = bfd_get_16 (input_bfd, contents + address);
03057            x = (x & 0xff00) | ((relocation >> 16) & 0xff);
03058            bfd_put_16 (input_bfd, x, contents + address);
03059 
03060            x = bfd_get_16 (input_bfd, contents + address + 2);
03061            x = relocation & 0xFFFF;
03062            bfd_put_16 (input_bfd, x, contents + address + 2);
03063            r = bfd_reloc_ok;
03064          }
03065          break;
03066 
03067        default:
03068        do_default:
03069          r = _bfd_final_link_relocate (howto, input_bfd, input_section,
03070                                    contents, address,
03071                                    relocation, rel->r_addend);
03072 
03073          break;
03074        }
03075 
03076       /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
03077          because such sections are not SEC_ALLOC and thus ld.so will
03078          not process them.  */
03079       if (unresolved_reloc
03080          && !((input_section->flags & SEC_DEBUGGING) != 0 && h->def_dynamic))
03081        {
03082          (*_bfd_error_handler)
03083            (_("%B(%A+0x%lx): unresolvable relocation against symbol `%s'"),
03084             input_bfd,
03085             input_section, (long) rel->r_offset, h->root.root.string);
03086          return FALSE;
03087        }
03088 
03089       if (r != bfd_reloc_ok)
03090        {
03091          const char *name;
03092 
03093          if (h != NULL)
03094            name = h->root.root.string;
03095          else
03096            {
03097              name = bfd_elf_string_from_elf_section (input_bfd,
03098                                                 symtab_hdr->sh_link,
03099                                                 sym->st_name);
03100              if (name == NULL)
03101               return FALSE;
03102              if (*name == '\0')
03103               name = bfd_section_name (input_bfd, sec);
03104            }
03105 
03106          if (r == bfd_reloc_overflow)
03107            {
03108              if (!(info->callbacks->reloc_overflow
03109                   (info, (h ? &h->root : NULL), name, howto->name,
03110                    (bfd_vma) 0, input_bfd, input_section, rel->r_offset)))
03111               return FALSE;
03112            }
03113          else
03114            {
03115              (*_bfd_error_handler)
03116               (_("%B(%A+0x%lx): reloc against `%s': error %d"),
03117                input_bfd, input_section,
03118                (long) rel->r_offset, name, (int) r);
03119              return FALSE;
03120            }
03121        }
03122     }
03123 
03124   return TRUE;
03125 }
03126 
03127 static asection *
03128 bfin_gc_mark_hook (asection * sec,
03129                  struct bfd_link_info *info,
03130                  Elf_Internal_Rela * rel,
03131                  struct elf_link_hash_entry *h,
03132                    Elf_Internal_Sym * sym)
03133 {
03134   if (h != NULL)
03135     switch (ELF32_R_TYPE (rel->r_info))
03136       {
03137       case R_BFIN_GNU_VTINHERIT:
03138       case R_BFIN_GNU_VTENTRY:
03139        return NULL;
03140       }
03141 
03142   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
03143 }
03144 
03145 /* Update the got entry reference counts for the section being removed.  */
03146 
03147 static bfd_boolean
03148 bfin_gc_sweep_hook (bfd * abfd,
03149                   struct bfd_link_info *info,
03150                   asection * sec,
03151                     const Elf_Internal_Rela * relocs)
03152 {
03153   Elf_Internal_Shdr *symtab_hdr;
03154   struct elf_link_hash_entry **sym_hashes;
03155   bfd_signed_vma *local_got_refcounts;
03156   const Elf_Internal_Rela *rel, *relend;
03157   bfd *dynobj;
03158   asection *sgot;
03159   asection *srelgot;
03160 
03161   dynobj = elf_hash_table (info)->dynobj;
03162   if (dynobj == NULL)
03163     return TRUE;
03164 
03165   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
03166   sym_hashes = elf_sym_hashes (abfd);
03167   local_got_refcounts = elf_local_got_refcounts (abfd);
03168 
03169   sgot = bfd_get_section_by_name (dynobj, ".got");
03170   srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
03171 
03172   relend = relocs + sec->reloc_count;
03173   for (rel = relocs; rel < relend; rel++)
03174     {
03175       unsigned long r_symndx;
03176       struct elf_link_hash_entry *h;
03177 
03178       switch (ELF32_R_TYPE (rel->r_info))
03179        {
03180        case R_got:
03181          r_symndx = ELF32_R_SYM (rel->r_info);
03182          if (r_symndx >= symtab_hdr->sh_info)
03183            {
03184              h = sym_hashes[r_symndx - symtab_hdr->sh_info];
03185              if (h->got.refcount > 0)
03186               {
03187                 --h->got.refcount;
03188                 if (h->got.refcount == 0)
03189                   {
03190                     /* We don't need the .got entry any more.  */
03191                     sgot->size -= 4;
03192                     srelgot->size -= sizeof (Elf32_External_Rela);
03193                   }
03194               }
03195            }
03196          else if (local_got_refcounts != NULL)
03197            {
03198              if (local_got_refcounts[r_symndx] > 0)
03199               {
03200                 --local_got_refcounts[r_symndx];
03201                 if (local_got_refcounts[r_symndx] == 0)
03202                   {
03203                     /* We don't need the .got entry any more.  */
03204                     sgot->size -= 4;
03205                     if (info->shared)
03206                      srelgot->size -= sizeof (Elf32_External_Rela);
03207                   }
03208               }
03209            }
03210          break;
03211        default:
03212          break;
03213        }
03214     }
03215   return TRUE;
03216 }
03217 
03218 /* We need dynamic symbols for every section, since segments can
03219    relocate independently.  */
03220 static bfd_boolean
03221 _bfinfdpic_link_omit_section_dynsym (bfd *output_bfd ATTRIBUTE_UNUSED,
03222                                 struct bfd_link_info *info
03223                                 ATTRIBUTE_UNUSED,
03224                                 asection *p ATTRIBUTE_UNUSED)
03225 {
03226   switch (elf_section_data (p)->this_hdr.sh_type)
03227     {
03228     case SHT_PROGBITS:
03229     case SHT_NOBITS:
03230       /* If sh_type is yet undecided, assume it could be
03231         SHT_PROGBITS/SHT_NOBITS.  */
03232     case SHT_NULL:
03233       return FALSE;
03234 
03235       /* There shouldn't be section relative relocations
03236         against any other section.  */
03237     default:
03238       return TRUE;
03239     }
03240 }
03241 
03242 /* Create  a .got section, as well as its additional info field.  This
03243    is almost entirely copied from
03244    elflink.c:_bfd_elf_create_got_section().  */
03245 
03246 static bfd_boolean
03247 _bfin_create_got_section (bfd *abfd, struct bfd_link_info *info)
03248 {
03249   flagword flags, pltflags;
03250   asection *s;
03251   struct elf_link_hash_entry *h;
03252   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
03253   int ptralign;
03254   int offset;
03255 
03256   /* This function may be called more than once.  */
03257   s = bfd_get_section_by_name (abfd, ".got");
03258   if (s != NULL && (s->flags & SEC_LINKER_CREATED) != 0)
03259     return TRUE;
03260 
03261   /* Machine specific: although pointers are 32-bits wide, we want the
03262      GOT to be aligned to a 64-bit boundary, such that function
03263      descriptors in it can be accessed with 64-bit loads and
03264      stores.  */
03265   ptralign = 3;
03266 
03267   flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
03268           | SEC_LINKER_CREATED);
03269   pltflags = flags;
03270 
03271   s = bfd_make_section_with_flags (abfd, ".got", flags);
03272   if (s == NULL
03273       || !bfd_set_section_alignment (abfd, s, ptralign))
03274     return FALSE;
03275 
03276   if (bed->want_got_plt)
03277     {
03278       s = bfd_make_section_with_flags (abfd, ".got.plt", flags);
03279       if (s == NULL
03280          || !bfd_set_section_alignment (abfd, s, ptralign))
03281        return FALSE;
03282     }
03283 
03284   if (bed->want_got_sym)
03285     {
03286       /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
03287         (or .got.plt) section.  We don't do this in the linker script
03288         because we don't want to define the symbol if we are not creating
03289         a global offset table.  */
03290       h = _bfd_elf_define_linkage_sym (abfd, info, s, "__GLOBAL_OFFSET_TABLE_");
03291       elf_hash_table (info)->hgot = h;
03292       if (h == NULL)
03293        return FALSE;
03294 
03295       /* Machine-specific: we want the symbol for executables as
03296         well.  */
03297       if (! bfd_elf_link_record_dynamic_symbol (info, h))
03298        return FALSE;
03299     }
03300 
03301   /* The first bit of the global offset table is the header.  */
03302   s->size += bed->got_header_size;
03303 
03304   /* This is the machine-specific part.  Create and initialize section
03305      data for the got.  */
03306   if (IS_FDPIC (abfd))
03307     {
03308       bfinfdpic_got_section (info) = s;
03309       bfinfdpic_relocs_info (info) = htab_try_create (1,
03310                                                 bfinfdpic_relocs_info_hash,
03311                                                 bfinfdpic_relocs_info_eq,
03312                                                 (htab_del) NULL);
03313       if (! bfinfdpic_relocs_info (info))
03314        return FALSE;
03315 
03316       s = bfd_make_section_with_flags (abfd, ".rel.got",
03317                                    (flags | SEC_READONLY));
03318       if (s == NULL
03319          || ! bfd_set_section_alignment (abfd, s, 2))
03320        return FALSE;
03321 
03322       bfinfdpic_gotrel_section (info) = s;
03323 
03324       /* Machine-specific.  */
03325       s = bfd_make_section_with_flags (abfd, ".rofixup",
03326                                    (flags | SEC_READONLY));
03327       if (s == NULL
03328          || ! bfd_set_section_alignment (abfd, s, 2))
03329        return FALSE;
03330 
03331       bfinfdpic_gotfixup_section (info) = s;
03332       offset = -2048;
03333       flags = BSF_GLOBAL;
03334     }
03335   else
03336     {
03337       offset = 2048;
03338       flags = BSF_GLOBAL | BSF_WEAK;
03339     }
03340 
03341   return TRUE;
03342 }
03343 
03344 /* Make sure the got and plt sections exist, and that our pointers in
03345    the link hash table point to them.  */
03346 
03347 static bfd_boolean
03348 elf32_bfinfdpic_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
03349 {
03350   /* This is mostly copied from
03351      elflink.c:_bfd_elf_create_dynamic_sections().  */
03352   flagword flags, pltflags;
03353   asection *s;
03354   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
03355 
03356   /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and
03357      .rel[a].bss sections.  */
03358 
03359   flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
03360           | SEC_LINKER_CREATED);
03361 
03362   pltflags = flags;
03363   pltflags |= SEC_CODE;
03364   if (bed->plt_not_loaded)
03365     pltflags &= ~ (SEC_CODE | SEC_LOAD | SEC_HAS_CONTENTS);
03366   if (bed->plt_readonly)
03367     pltflags |= SEC_READONLY;
03368 
03369   s = bfd_make_section_with_flags (abfd, ".plt", pltflags);
03370   if (s == NULL
03371       || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
03372     return FALSE;
03373   /* Blackfin-specific: remember it.  */
03374   bfinfdpic_plt_section (info) = s;
03375 
03376   if (bed->want_plt_sym)
03377     {
03378       /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
03379         .plt section.  */
03380       struct elf_link_hash_entry *h;
03381       struct bfd_link_hash_entry *bh = NULL;
03382 
03383       if (! (_bfd_generic_link_add_one_symbol
03384             (info, abfd, "__PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s, 0, NULL,
03385              FALSE, get_elf_backend_data (abfd)->collect, &bh)))
03386        return FALSE;
03387       h = (struct elf_link_hash_entry *) bh;
03388       h->def_regular = 1;
03389       h->type = STT_OBJECT;
03390 
03391       if (! info->executable
03392          && ! bfd_elf_link_record_dynamic_symbol (info, h))
03393        return FALSE;
03394     }
03395 
03396   /* Blackfin-specific: we want rel relocations for the plt.  */
03397   s = bfd_make_section_with_flags (abfd, ".rel.plt", flags | SEC_READONLY);
03398   if (s == NULL
03399       || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
03400     return FALSE;
03401   /* Blackfin-specific: remember it.  */
03402   bfinfdpic_pltrel_section (info) = s;
03403 
03404   /* Blackfin-specific: we want to create the GOT in the Blackfin way.  */
03405   if (! _bfin_create_got_section (abfd, info))
03406     return FALSE;
03407 
03408   /* Blackfin-specific: make sure we created everything we wanted.  */
03409   BFD_ASSERT (bfinfdpic_got_section (info) && bfinfdpic_gotrel_section (info)
03410              /* && bfinfdpic_gotfixup_section (info) */
03411              && bfinfdpic_plt_section (info)
03412              && bfinfdpic_pltrel_section (info));
03413 
03414   if (bed->want_dynbss)
03415     {
03416       /* The .dynbss section is a place to put symbols which are defined
03417         by dynamic objects, are referenced by regular objects, and are
03418         not functions.  We must allocate space for them in the process
03419         image and use a R_*_COPY reloc to tell the dynamic linker to
03420         initialize them at run time.  The linker script puts the .dynbss
03421         section into the .bss section of the final image.  */
03422       s = bfd_make_section_with_flags (abfd, ".dynbss",
03423                                    SEC_ALLOC | SEC_LINKER_CREATED);
03424       if (s == NULL)
03425        return FALSE;
03426 
03427       /* The .rel[a].bss section holds copy relocs.  This section is not
03428      normally needed.  We need to create it here, though, so that the
03429      linker will map it to an output section.  We can't just create it
03430      only if we need it, because we will not know whether we need it
03431      until we have seen all the input files, and the first time the
03432      main linker code calls BFD after examining all the input files
03433      (size_dynamic_sections) the input sections have already been
03434      mapped to the output sections.  If the section turns out not to
03435      be needed, we can discard it later.  We will never need this
03436      section when generating a shared object, since they do not use
03437      copy relocs.  */
03438       if (! info->shared)
03439        {
03440          s = bfd_make_section_with_flags (abfd,
03441                                       (bed->default_use_rela_p
03442                                        ? ".rela.bss" : ".rel.bss"),
03443                                       flags | SEC_READONLY);
03444          if (s == NULL
03445              || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
03446            return FALSE;
03447        }
03448     }
03449 
03450   return TRUE;
03451 }
03452 
03453 /* The name of the dynamic interpreter.  This is put in the .interp
03454    section.  */
03455 
03456 #define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1"
03457 
03458 #define DEFAULT_STACK_SIZE 0x20000
03459 
03460 /* This structure is used to collect the number of entries present in
03461    each addressable range of the got.  */
03462 struct _bfinfdpic_dynamic_got_info
03463 {
03464   /* Several bits of information about the current link.  */
03465   struct bfd_link_info *info;
03466   /* Total size needed for GOT entries within the 18- or 32-bit
03467      ranges.  */
03468   bfd_vma got17m4, gothilo;
03469   /* Total size needed for function descriptor entries within the 18-
03470      or 32-bit ranges.  */
03471   bfd_vma fd17m4, fdhilo;
03472   /* Total size needed function descriptor entries referenced in PLT
03473      entries, that would be profitable to place in offsets close to
03474      the PIC register.  */
03475   bfd_vma fdplt;
03476   /* Total size needed by lazy PLT entries.  */
03477   bfd_vma lzplt;
03478   /* Number of relocations carried over from input object files.  */
03479   unsigned long relocs;
03480   /* Number of fixups introduced by relocations in input object files.  */
03481   unsigned long fixups;
03482 };
03483 
03484 /* Compute the total GOT size required by each symbol in each range.
03485    Symbols may require up to 4 words in the GOT: an entry pointing to
03486    the symbol, an entry pointing to its function descriptor, and a
03487    private function descriptors taking two words.  */
03488 
03489 static int
03490 _bfinfdpic_count_got_plt_entries (void **entryp, void *dinfo_)
03491 {
03492   struct bfinfdpic_relocs_info *entry = *entryp;
03493   struct _bfinfdpic_dynamic_got_info *dinfo = dinfo_;
03494   unsigned relocs = 0, fixups = 0;
03495 
03496   /* Allocate space for a GOT entry pointing to the symbol.  */
03497   if (entry->got17m4)
03498     dinfo->got17m4 += 4;
03499   else if (entry->gothilo)
03500     dinfo->gothilo += 4;
03501   else
03502     entry->relocs32--;
03503   entry->relocs32++;
03504 
03505   /* Allocate space for a GOT entry pointing to the function
03506      descriptor.  */
03507   if (entry->fdgot17m4)
03508     dinfo->got17m4 += 4;
03509   else if (entry->fdgothilo)
03510     dinfo->gothilo += 4;
03511   else
03512     entry->relocsfd--;
03513   entry->relocsfd++;
03514 
03515   /* Decide whether we need a PLT entry, a function descriptor in the
03516      GOT, and a lazy PLT entry for this symbol.  */
03517   entry->plt = entry->call
03518     && entry->symndx == -1 && ! BFINFDPIC_SYM_LOCAL (dinfo->info, entry->d.h)
03519     && elf_hash_table (dinfo->info)->dynamic_sections_created;
03520   entry->privfd = entry->plt
03521     || entry->fdgoff17m4 || entry->fdgoffhilo
03522     || ((entry->fd || entry->fdgot17m4 || entry->fdgothilo)
03523        && (entry->symndx != -1
03524            || BFINFDPIC_FUNCDESC_LOCAL (dinfo->info, entry->d.h)));
03525   entry->lazyplt = entry->privfd
03526     && entry->symndx == -1 && ! BFINFDPIC_SYM_LOCAL (dinfo->info, entry->d.h)
03527     && ! (dinfo->info->flags & DF_BIND_NOW)
03528     && elf_hash_table (dinfo->info)->dynamic_sections_created;
03529 
03530   /* Allocate space for a function descriptor.  */
03531   if (entry->fdgoff17m4)
03532     dinfo->fd17m4 += 8;
03533   else if (entry->privfd && entry->plt)
03534     dinfo->fdplt += 8;
03535   else if (entry->privfd)
03536     dinfo->fdhilo += 8;
03537   else
03538     entry->relocsfdv--;
03539   entry->relocsfdv++;
03540 
03541   if (entry->lazyplt)
03542     dinfo->lzplt += LZPLT_NORMAL_SIZE;
03543 
03544   if (!dinfo->info->executable || dinfo->info->pie)
03545     relocs = entry->relocs32 + entry->relocsfd + entry->relocsfdv;
03546   else
03547     {
03548       if (entry->symndx != -1 || BFINFDPIC_SYM_LOCAL (dinfo->info, entry->d.h))
03549        {
03550          if (entry->symndx != -1
03551              || entry->d.h->root.type != bfd_link_hash_undefweak)
03552            fixups += entry->relocs32 + 2 * entry->relocsfdv;
03553        }
03554       else
03555        relocs += entry->relocs32 + entry->relocsfdv;
03556 
03557       if (entry->symndx != -1
03558          || BFINFDPIC_FUNCDESC_LOCAL (dinfo->info, entry->d.h))
03559        {
03560          if (entry->symndx != -1
03561              || entry->d.h->root.type != bfd_link_hash_undefweak)
03562            fixups += entry->relocsfd;
03563        }
03564       else
03565        relocs += entry->relocsfd;
03566     }
03567 
03568   entry->dynrelocs += relocs;
03569   entry->fixups += fixups;
03570   dinfo->relocs += relocs;
03571   dinfo->fixups += fixups;
03572 
03573   return 1;
03574 }
03575 
03576 /* This structure is used to assign offsets to got entries, function
03577    descriptors, plt entries and lazy plt entries.  */
03578 
03579 struct _bfinfdpic_dynamic_got_plt_info
03580 {
03581   /* Summary information collected with _bfinfdpic_count_got_plt_entries.  */
03582   struct _bfinfdpic_dynamic_got_info g;
03583 
03584   /* For each addressable range, we record a MAX (positive) and MIN
03585      (negative) value.  CUR is used to assign got entries, and it's
03586      incremented from an initial positive value to MAX, then from MIN
03587      to FDCUR (unless FDCUR wraps around first).  FDCUR is used to
03588      assign function descriptors, and it's decreased from an initial
03589      non-positive value to MIN, then from MAX down to CUR (unless CUR
03590      wraps around first).  All of MIN, MAX, CUR and FDCUR always point
03591      to even words.  ODD, if non-zero, indicates an odd word to be
03592      used for the next got entry, otherwise CUR is used and
03593      incremented by a pair of words, wrapping around when it reaches
03594      MAX.  FDCUR is decremented (and wrapped) before the next function
03595      descriptor is chosen.  FDPLT indicates the number of remaining
03596      slots that can be used for function descriptors used only by PLT
03597      entries.  */
03598   struct _bfinfdpic_dynamic_got_alloc_data
03599   {
03600     bfd_signed_vma max, cur, odd, fdcur, min;
03601     bfd_vma fdplt;
03602   } got17m4, gothilo;
03603 };
03604 
03605 /* Determine the positive and negative ranges to be used by each
03606    offset range in the GOT.  FDCUR and CUR, that must be aligned to a
03607    double-word boundary, are the minimum (negative) and maximum
03608    (positive) GOT offsets already used by previous ranges, except for
03609    an ODD entry that may have been left behind.  GOT and FD indicate
03610    the size of GOT entries and function descriptors that must be
03611    placed within the range from -WRAP to WRAP.  If there's room left,
03612    up to FDPLT bytes should be reserved for additional function
03613    descriptors.  */
03614 
03615 inline static bfd_signed_vma
03616 _bfinfdpic_compute_got_alloc_data (struct _bfinfdpic_dynamic_got_alloc_data *gad,
03617                                bfd_signed_vma fdcur,
03618                                bfd_signed_vma odd,
03619                                bfd_signed_vma cur,
03620                                bfd_vma got,
03621                                bfd_vma fd,
03622                                bfd_vma fdplt,
03623                                bfd_vma wrap)
03624 {
03625   bfd_signed_vma wrapmin = -wrap;
03626 
03627   /* Start at the given initial points.  */
03628   gad->fdcur = fdcur;
03629   gad->cur = cur;
03630 
03631   /* If we had an incoming odd word and we have any got entries that
03632      are going to use it, consume it, otherwise leave gad->odd at
03633      zero.  We might force gad->odd to zero and return the incoming
03634      odd such that it is used by the next range, but then GOT entries
03635      might appear to be out of order and we wouldn't be able to
03636      shorten the GOT by one word if it turns out to end with an
03637      unpaired GOT entry.  */
03638   if (odd && got)
03639     {
03640       gad->odd = odd;
03641       got -= 4;
03642       odd = 0;
03643     }
03644   else
03645     gad->odd = 0;
03646 
03647   /* If we're left with an unpaired GOT entry, compute its location
03648      such that we can return it.  Otherwise, if got doesn't require an
03649      odd number of words here, either odd was already zero in the
03650      block above, or it was set to zero because got was non-zero, or
03651      got was already zero.  In the latter case, we want the value of
03652      odd to carry over to the return statement, so we don't want to
03653      reset odd unless the condition below is true.  */
03654   if (got & 4)
03655     {
03656       odd = cur + got;
03657       got += 4;
03658     }
03659 
03660   /* Compute the tentative boundaries of this range.  */
03661   gad->max = cur + got;
03662   gad->min = fdcur - fd;
03663   gad->fdplt = 0;
03664 
03665   /* If function descriptors took too much space, wrap some of them
03666      around.  */
03667   if (gad->min < wrapmin)
03668     {
03669       gad->max += wrapmin - gad->min;
03670       gad->min = wrapmin;
03671     }
03672   /* If there is space left and we have function descriptors
03673      referenced in PLT entries that could take advantage of shorter
03674      offsets, place them here.  */
03675   else if (fdplt && gad->min > wrapmin)
03676     {
03677       bfd_vma fds;
03678       if ((bfd_vma) (gad->min - wrapmin) < fdplt)
03679        fds = gad->min - wrapmin;
03680       else
03681        fds = fdplt;
03682 
03683       fdplt -= fds;
03684       gad->min -= fds;
03685       gad->fdplt += fds;
03686     }
03687 
03688   /* If GOT entries took too much space, wrap some of them around.
03689      This may well cause gad->min to become lower than wrapmin.  This
03690      will cause a relocation overflow later on, so we don't have to
03691      report it here . */
03692   if ((bfd_vma) gad->max > wrap)
03693     {
03694       gad->min -= gad->max - wrap;
03695       gad->max = wrap;
03696     }
03697   /* If there is more space left, try to place some more function
03698      descriptors for PLT entries.  */
03699   else if (fdplt && (bfd_vma) gad->max < wrap)
03700     {
03701       bfd_vma fds;
03702       if ((bfd_vma) (wrap - gad->max) < fdplt)
03703        fds = wrap - gad->max;
03704       else
03705        fds = fdplt;
03706 
03707       fdplt -= fds;
03708       gad->max += fds;
03709       gad->fdplt += fds;
03710     }
03711 
03712   /* If odd was initially computed as an offset past the wrap point,
03713      wrap it around.  */
03714   if (odd > gad->max)
03715     odd = gad->min + odd - gad->max;
03716 
03717   /* _bfinfdpic_get_got_entry() below will always wrap gad->cur if needed
03718      before returning, so do it here too.  This guarantees that,
03719      should cur and fdcur meet at the wrap point, they'll both be
03720      equal to min.  */
03721   if (gad->cur == gad->max)
03722     gad->cur = gad->min;
03723 
03724   return odd;
03725 }
03726 
03727 /* Compute the location of the next GOT entry, given the allocation
03728    data for a range.  */
03729 
03730 inline static bfd_signed_vma
03731 _bfinfdpic_get_got_entry (struct _bfinfdpic_dynamic_got_alloc_data *gad)
03732 {
03733   bfd_signed_vma ret;
03734 
03735   if (gad->odd)
03736     {
03737       /* If there was an odd word left behind, use it.  */
03738       ret = gad->odd;
03739       gad->odd = 0;
03740     }
03741   else
03742     {
03743       /* Otherwise, use the word pointed to by cur, reserve the next
03744         as an odd word, and skip to the next pair of words, possibly
03745         wrapping around.  */
03746       ret = gad->cur;
03747       gad->odd = gad->cur + 4;
03748       gad->cur += 8;
03749       if (gad->cur == gad->max)
03750        gad->cur = gad->min;
03751     }
03752 
03753   return ret;
03754 }
03755 
03756 /* Compute the location of the next function descriptor entry in the
03757    GOT, given the allocation data for a range.  */
03758 
03759 inline static bfd_signed_vma
03760 _bfinfdpic_get_fd_entry (struct _bfinfdpic_dynamic_got_alloc_data *gad)
03761 {
03762   /* If we're at the bottom, wrap around, and only then allocate the
03763      next pair of words.  */
03764   if (gad->fdcur == gad->min)
03765     gad->fdcur = gad->max;
03766   return gad->fdcur -= 8;
03767 }
03768 
03769 /* Assign GOT offsets for every GOT entry and function descriptor.
03770    Doing everything in a single pass is tricky.  */
03771 
03772 static int
03773 _bfinfdpic_assign_got_entries (void **entryp, void *info_)
03774 {
03775   struct bfinfdpic_relocs_info *entry = *entryp;
03776   struct _bfinfdpic_dynamic_got_plt_info *dinfo = info_;
03777 
03778   if (entry->got17m4)
03779     entry->got_entry = _bfinfdpic_get_got_entry (&dinfo->got17m4);
03780   else if (entry->gothilo)
03781     entry->got_entry = _bfinfdpic_get_got_entry (&dinfo->gothilo);
03782 
03783   if (entry->fdgot17m4)
03784     entry->fdgot_entry = _bfinfdpic_get_got_entry (&dinfo->got17m4);
03785   else if (entry->fdgothilo)
03786     entry->fdgot_entry = _bfinfdpic_get_got_entry (&dinfo->gothilo);
03787 
03788   if (entry->fdgoff17m4)
03789     entry->fd_entry = _bfinfdpic_get_fd_entry (&dinfo->got17m4);
03790   else if (entry->plt && dinfo->got17m4.fdplt)
03791     {
03792       dinfo->got17m4.fdplt -= 8;
03793       entry->fd_entry = _bfinfdpic_get_fd_entry (&dinfo->got17m4);
03794     }
03795   else if (entry->plt)
03796     {
03797       dinfo->gothilo.fdplt -= 8;
03798       entry->fd_entry = _bfinfdpic_get_fd_entry (&dinfo->gothilo);
03799     }
03800   else if (entry->privfd)
03801     entry->fd_entry = _bfinfdpic_get_fd_entry (&dinfo->gothilo);
03802 
03803   return 1;
03804 }
03805 
03806 /* Assign GOT offsets to private function descriptors used by PLT
03807    entries (or referenced by 32-bit offsets), as well as PLT entries
03808    and lazy PLT entries.  */
03809 
03810 static int
03811 _bfinfdpic_assign_plt_entries (void **entryp, void *info_)
03812 {
03813   struct bfinfdpic_relocs_info *entry = *entryp;
03814   struct _bfinfdpic_dynamic_got_plt_info *dinfo = info_;
03815 
03816   /* If this symbol requires a local function descriptor, allocate
03817      one.  */
03818   if (entry->privfd && entry->fd_entry == 0)
03819     {
03820       if (dinfo->got17m4.fdplt)
03821        {
03822          entry->fd_entry = _bfinfdpic_get_fd_entry (&dinfo->got17m4);
03823          dinfo->got17m4.fdplt -= 8;
03824        }
03825       else
03826        {
03827          BFD_ASSERT (dinfo->gothilo.fdplt);
03828          entry->fd_entry = _bfinfdpic_get_fd_entry (&dinfo->gothilo);
03829          dinfo->gothilo.fdplt -= 8;
03830        }
03831     }
03832 
03833   if (entry->plt)
03834     {
03835       int size;
03836 
03837       /* We use the section's raw size to mark the location of the
03838         next PLT entry.  */
03839       entry->plt_entry = bfinfdpic_plt_section (dinfo->g.info)->size;
03840 
03841       /* Figure out the length of this PLT entry based on the
03842         addressing mode we need to reach the function descriptor.  */
03843       BFD_ASSERT (entry->fd_entry);
03844       if (entry->fd_entry >= -(1 << (18 - 1))
03845          && entry->fd_entry + 4 < (1 << (18 - 1)))
03846        size = 10;
03847       else
03848        size = 16;
03849 
03850       bfinfdpic_plt_section (dinfo->g.info)->size += size;
03851     }
03852 
03853   if (entry->lazyplt)
03854     {
03855       entry->lzplt_entry = dinfo->g.lzplt;
03856       dinfo->g.lzplt += LZPLT_NORMAL_SIZE;
03857       /* If this entry is the one that gets the resolver stub, account
03858         for the additional instruction.  */
03859       if (entry->lzplt_entry % BFINFDPIC_LZPLT_BLOCK_SIZE
03860          == BFINFDPIC_LZPLT_RESOLV_LOC)
03861        dinfo->g.lzplt += LZPLT_RESOLVER_EXTRA;
03862     }
03863 
03864   return 1;
03865 }
03866 
03867 /* Follow indirect and warning hash entries so that each got entry
03868    points to the final symbol definition.  P must point to a pointer
03869    to the hash table we're traversing.  Since this traversal may
03870    modify the hash table, we set this pointer to NULL to indicate
03871    we've made a potentially-destructive change to the hash table, so
03872    the traversal must be restarted.  */
03873 static int
03874 _bfinfdpic_resolve_final_relocs_info (void **entryp, void *p)
03875 {
03876   struct bfinfdpic_relocs_info *entry = *entryp;
03877   htab_t *htab = p;
03878 
03879   if (entry->symndx == -1)
03880     {
03881       struct elf_link_hash_entry *h = entry->d.h;
03882       struct bfinfdpic_relocs_info *oentry;
03883 
03884       while (h->root.type == bfd_link_hash_indirect
03885             || h->root.type == bfd_link_hash_warning)
03886        h = (struct elf_link_hash_entry *)h->root.u.i.link;
03887 
03888       if (entry->d.h == h)
03889        return 1;
03890 
03891       oentry = bfinfdpic_relocs_info_for_global (*htab, 0, h, entry->addend,
03892                                           NO_INSERT);
03893 
03894       if (oentry)
03895        {
03896          /* Merge the two entries.  */
03897          bfinfdpic_pic_merge_early_relocs_info (oentry, entry);
03898          htab_clear_slot (*htab, entryp);
03899          return 1;
03900        }
03901 
03902       entry->d.h = h;
03903 
03904       /* If we can't find this entry with the new bfd hash, re-insert
03905         it, and get the traversal restarted.  */
03906       if (! htab_find (*htab, entry))
03907        {
03908          htab_clear_slot (*htab, entryp);
03909          entryp = htab_find_slot (*htab, entry, INSERT);
03910          if (! *entryp)
03911            *entryp = entry;
03912          /* Abort the traversal, since the whole table may have
03913             moved, and leave it up to the parent to restart the
03914             process.  */
03915          *(htab_t *)p = NULL;
03916          return 0;
03917        }
03918     }
03919 
03920   return 1;
03921 }
03922 
03923 /* Set the sizes of the dynamic sections.  */
03924 
03925 static bfd_boolean
03926 elf32_bfinfdpic_size_dynamic_sections (bfd *output_bfd,
03927                                   struct bfd_link_info *info)
03928 {
03929   bfd *dynobj;
03930   asection *s;
03931   struct _bfinfdpic_dynamic_got_plt_info gpinfo;
03932   bfd_signed_vma odd;
03933   bfd_vma limit;
03934 
03935   dynobj = elf_hash_table (info)->dynobj;
03936   BFD_ASSERT (dynobj != NULL);
03937 
03938   if (elf_hash_table (info)->dynamic_sections_created)
03939     {
03940       /* Set the contents of the .interp section to the interpreter.  */
03941       if (info->executable)
03942        {
03943          s = bfd_get_section_by_name (dynobj, ".interp");
03944          BFD_ASSERT (s != NULL);
03945          s->size = sizeof ELF_DYNAMIC_INTERPRETER;
03946          s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
03947        }
03948     }
03949 
03950   memset (&gpinfo, 0, sizeof (gpinfo));
03951   gpinfo.g.info = info;
03952 
03953   for (;;)
03954     {
03955       htab_t relocs = bfinfdpic_relocs_info (info);
03956 
03957       htab_traverse (relocs, _bfinfdpic_resolve_final_relocs_info, &relocs);
03958 
03959       if (relocs == bfinfdpic_relocs_info (info))
03960        break;
03961     }
03962 
03963   htab_traverse (bfinfdpic_relocs_info (info), _bfinfdpic_count_got_plt_entries,
03964                &gpinfo.g);
03965 
03966   odd = 12;
03967   /* Compute the total size taken by entries in the 18-bit range,
03968      to tell how many PLT function descriptors we can bring into it
03969      without causing it to overflow.  */
03970   limit = odd + gpinfo.g.got17m4 + gpinfo.g.fd17m4;
03971   if (limit < (bfd_vma)1 << 18)
03972     limit = ((bfd_vma)1 << 18) - limit;
03973   else
03974     limit = 0;
03975   if (gpinfo.g.fdplt < limit)
03976     limit = gpinfo.g.fdplt;
03977 
03978   /* Determine the ranges of GOT offsets that we can use for each
03979      range of addressing modes.  */
03980   odd = _bfinfdpic_compute_got_alloc_data (&gpinfo.got17m4,
03981                                      0,
03982                                      odd,
03983                                      16,
03984                                      gpinfo.g.got17m4,
03985                                      gpinfo.g.fd17m4,
03986                                      limit,
03987                                      (bfd_vma)1 << (18-1));
03988   odd = _bfinfdpic_compute_got_alloc_data (&gpinfo.gothilo,
03989                                      gpinfo.got17m4.min,
03990                                      odd,
03991                                      gpinfo.got17m4.max,
03992                                      gpinfo.g.gothilo,
03993                                      gpinfo.g.fdhilo,
03994                                      gpinfo.g.fdplt - gpinfo.got17m4.fdplt,
03995                                      (bfd_vma)1 << (32-1));
03996 
03997   /* Now assign (most) GOT offsets.  */
03998   htab_traverse (bfinfdpic_relocs_info (info), _bfinfdpic_assign_got_entries,
03999                &gpinfo);
04000 
04001   bfinfdpic_got_section (info)->size = gpinfo.gothilo.max
04002     - gpinfo.gothilo.min
04003     /* If an odd word is the last word of the GOT, we don't need this
04004        word to be part of the GOT.  */
04005     - (odd + 4 == gpinfo.gothilo.max ? 4 : 0);
04006   if (bfinfdpic_got_section (info)->size == 0)
04007     bfinfdpic_got_section (info)->flags |= SEC_EXCLUDE;
04008   else if (bfinfdpic_got_section (info)->size == 12
04009           && ! elf_hash_table (info)->dynamic_sections_created)
04010     {
04011       bfinfdpic_got_section (info)->flags |= SEC_EXCLUDE;
04012       bfinfdpic_got_section (info)->size = 0;
04013     }
04014   else
04015     {
04016       bfinfdpic_got_section (info)->contents =
04017        (bfd_byte *) bfd_zalloc (dynobj,
04018                              bfinfdpic_got_section (info)->size);
04019       if (bfinfdpic_got_section (info)->contents == NULL)
04020        return FALSE;
04021     }
04022 
04023   if (elf_hash_table (info)->dynamic_sections_created)
04024     /* Subtract the number of lzplt entries, since those will generate
04025        relocations in the pltrel section.  */
04026     bfinfdpic_gotrel_section (info)->size =
04027       (gpinfo.g.relocs - gpinfo.g.lzplt / LZPLT_NORMAL_SIZE)
04028       * get_elf_backend_data (output_bfd)->s->sizeof_rel;
04029   else
04030     BFD_ASSERT (gpinfo.g.relocs == 0);
04031   if (bfinfdpic_gotrel_section (info)->size == 0)
04032     bfinfdpic_gotrel_section (info)->flags |= SEC_EXCLUDE;
04033   else
04034     {
04035       bfinfdpic_gotrel_section (info)->contents =
04036        (bfd_byte *) bfd_zalloc (dynobj,
04037                              bfinfdpic_gotrel_section (info)->size);
04038       if (bfinfdpic_gotrel_section (info)->contents == NULL)
04039        return FALSE;
04040     }
04041 
04042   bfinfdpic_gotfixup_section (info)->size = (gpinfo.g.fixups + 1) * 4;
04043   if (bfinfdpic_gotfixup_section (info)->size == 0)
04044     bfinfdpic_gotfixup_section (info)->flags |= SEC_EXCLUDE;
04045   else
04046     {
04047       bfinfdpic_gotfixup_section (info)->contents =
04048        (bfd_byte *) bfd_zalloc (dynobj,
04049                              bfinfdpic_gotfixup_section (info)->size);
04050       if (bfinfdpic_gotfixup_section (info)->contents == NULL)
04051        return FALSE;
04052     }
04053 
04054   if (elf_hash_table (info)->dynamic_sections_created)
04055     {
04056       bfinfdpic_pltrel_section (info)->size =
04057        gpinfo.g.lzplt / LZPLT_NORMAL_SIZE * get_elf_backend_data (output_bfd)->s->sizeof_rel;
04058       if (bfinfdpic_pltrel_section (info)->size == 0)
04059        bfinfdpic_pltrel_section (info)->flags |= SEC_EXCLUDE;
04060       else
04061        {
04062          bfinfdpic_pltrel_section (info)->contents =
04063            (bfd_byte *) bfd_zalloc (dynobj,
04064                                  bfinfdpic_pltrel_section (info)->size);
04065          if (bfinfdpic_pltrel_section (info)->contents == NULL)
04066            return FALSE;
04067        }
04068     }
04069 
04070   /* Add 4 bytes for every block of at most 65535 lazy PLT entries,
04071      such that there's room for the additional instruction needed to
04072      call the resolver.  Since _bfinfdpic_assign_got_entries didn't
04073      account for them, our block size is 4 bytes smaller than the real
04074      block size.  */
04075   if (elf_hash_table (info)->dynamic_sections_created)
04076     {
04077       bfinfdpic_plt_section (info)->size = gpinfo.g.lzplt
04078        + ((gpinfo.g.lzplt + (BFINFDPIC_LZPLT_BLOCK_SIZE - 4) - LZPLT_NORMAL_SIZE)
04079           / (BFINFDPIC_LZPLT_BLOCK_SIZE - 4) * LZPLT_RESOLVER_EXTRA);
04080     }
04081 
04082   /* Reset it, such that _bfinfdpic_assign_plt_entries() can use it to
04083      actually assign lazy PLT entries addresses.  */
04084   gpinfo.g.lzplt = 0;
04085 
04086   /* Save information that we're going to need to generate GOT and PLT
04087      entries.  */
04088   bfinfdpic_got_initial_offset (info) = -gpinfo.gothilo.min;
04089 
04090   if (get_elf_backend_data (output_bfd)->want_got_sym)
04091     elf_hash_table (info)->hgot->root.u.def.value
04092       += bfinfdpic_got_initial_offset (info);
04093 
04094   if (elf_hash_table (info)->dynamic_sections_created)
04095     bfinfdpic_plt_initial_offset (info) =
04096       bfinfdpic_plt_section (info)->size;
04097 
04098   htab_traverse (bfinfdpic_relocs_info (info), _bfinfdpic_assign_plt_entries,
04099                &gpinfo);
04100 
04101   /* Allocate the PLT section contents only after
04102      _bfinfdpic_assign_plt_entries has a chance to add the size of the
04103      non-lazy PLT entries.  */
04104   if (elf_hash_table (info)->dynamic_sections_created)
04105     {
04106       if (bfinfdpic_plt_section (info)->size == 0)
04107        bfinfdpic_plt_section (info)->flags |= SEC_EXCLUDE;
04108       else
04109        {
04110          bfinfdpic_plt_section (info)->contents =
04111            (bfd_byte *) bfd_zalloc (dynobj,
04112                                  bfinfdpic_plt_section (info)->size);
04113          if (bfinfdpic_plt_section (info)->contents == NULL)
04114            return FALSE;
04115        }
04116     }
04117 
04118   if (elf_hash_table (info)->dynamic_sections_created)
04119     {
04120       if (bfinfdpic_got_section (info)->size)
04121        if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0))
04122          return FALSE;
04123 
04124       if (bfinfdpic_pltrel_section (info)->size)
04125        if (!_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
04126            || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_REL)
04127            || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0))
04128          return FALSE;
04129 
04130       if (bfinfdpic_gotrel_section (info)->size)
04131        if (!_bfd_elf_add_dynamic_entry (info, DT_REL, 0)
04132            || !_bfd_elf_add_dynamic_entry (info, DT_RELSZ, 0)
04133            || !_bfd_elf_add_dynamic_entry (info, DT_RELENT,
04134                                        sizeof (Elf32_External_Rel)))
04135          return FALSE;
04136     }
04137 
04138   return TRUE;
04139 }
04140 
04141 static bfd_boolean
04142 elf32_bfinfdpic_always_size_sections (bfd *output_bfd,
04143                                  struct bfd_link_info *info)
04144 {
04145   if (!info->relocatable)
04146     {
04147       struct elf_link_hash_entry *h;
04148 
04149       /* Force a PT_GNU_STACK segment to be created.  */
04150       if (! elf_tdata (output_bfd)->stack_flags)
04151        elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X;
04152 
04153       /* Define __stacksize if it's not defined yet.  */
04154       h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize",
04155                             FALSE, FALSE, FALSE);
04156       if (! h || h->root.type != bfd_link_hash_defined
04157          || h->type != STT_OBJECT
04158          || !h->def_regular)
04159        {
04160          struct bfd_link_hash_entry *bh = NULL;
04161 
04162          if (!(_bfd_generic_link_add_one_symbol
04163               (info, output_bfd, "__stacksize",
04164                BSF_GLOBAL, bfd_abs_section_ptr, DEFAULT_STACK_SIZE,
04165                (const char *) NULL, FALSE,
04166                get_elf_backend_data (output_bfd)->collect, &bh)))
04167            return FALSE;
04168 
04169          h = (struct elf_link_hash_entry *) bh;
04170          h->def_regular = 1;
04171          h->type = STT_OBJECT;
04172        }
04173     }
04174 
04175   return TRUE;
04176 }
04177 
04178 static bfd_boolean
04179 elf32_bfinfdpic_modify_program_headers (bfd *output_bfd,
04180                                    struct bfd_link_info *info)
04181 {
04182   struct elf_obj_tdata *tdata = elf_tdata (output_bfd);
04183   struct elf_segment_map *m;
04184   Elf_Internal_Phdr *p;
04185 
04186   /* objcopy and strip preserve what's already there using
04187      elf32_bfinfdpic_copy_private_bfd_data ().  */
04188   if (! info)
04189     return TRUE;
04190 
04191   for (p = tdata->phdr, m = tdata->segment_map; m != NULL; m = m->next, p++)
04192     if (m->p_type == PT_GNU_STACK)
04193       break;
04194 
04195   if (m)
04196     {
04197       struct elf_link_hash_entry *h;
04198 
04199       /* Obtain the pointer to the __stacksize symbol.  */
04200       h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize",
04201                             FALSE, FALSE, FALSE);
04202       if (h)
04203        {
04204          while (h->root.type == bfd_link_hash_indirect
04205                || h->root.type == bfd_link_hash_warning)
04206            h = (struct elf_link_hash_entry *) h->root.u.i.link;
04207          BFD_ASSERT (h->root.type == bfd_link_hash_defined);
04208        }
04209 
04210       /* Set the header p_memsz from the symbol value.  We
04211         intentionally ignore the symbol section.  */
04212       if (h && h->root.type == bfd_link_hash_defined)
04213        p->p_memsz = h->root.u.def.value;
04214       else
04215        p->p_memsz = DEFAULT_STACK_SIZE;
04216 
04217       p->p_align = 8;
04218     }
04219 
04220   return TRUE;
04221 }
04222 
04223 static bfd_boolean
04224 elf32_bfinfdpic_finish_dynamic_sections (bfd *output_bfd,
04225                                    struct bfd_link_info *info)
04226 {
04227   bfd *dynobj;
04228   asection *sdyn;
04229 
04230   dynobj = elf_hash_table (info)->dynobj;
04231 
04232   if (bfinfdpic_got_section (info))
04233     {
04234       BFD_ASSERT (bfinfdpic_gotrel_section (info)->size
04235                 == (bfinfdpic_gotrel_section (info)->reloc_count
04236                     * sizeof (Elf32_External_Rel)));
04237 
04238       if (bfinfdpic_gotfixup_section (info))
04239        {
04240          struct elf_link_hash_entry *hgot = elf_hash_table (info)->hgot;
04241          bfd_vma got_value = hgot->root.u.def.value
04242            + hgot->root.u.def.section->output_section->vma
04243            + hgot->root.u.def.section->output_offset;
04244 
04245          _bfinfdpic_add_rofixup (output_bfd, bfinfdpic_gotfixup_section (info),
04246                              got_value, 0);
04247 
04248          if (bfinfdpic_gotfixup_section (info)->size
04249              != (bfinfdpic_gotfixup_section (info)->reloc_count * 4))
04250            {
04251              (*_bfd_error_handler)
04252               ("LINKER BUG: .rofixup section size mismatch");
04253              return FALSE;
04254            }
04255        }
04256     }
04257   if (elf_hash_table (info)->dynamic_sections_created)
04258     {
04259       BFD_ASSERT (bfinfdpic_pltrel_section (info)->size
04260                 == (bfinfdpic_pltrel_section (info)->reloc_count
04261                     * sizeof (Elf32_External_Rel)));
04262     }
04263 
04264   sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
04265 
04266   if (elf_hash_table (info)->dynamic_sections_created)
04267     {
04268       Elf32_External_Dyn * dyncon;
04269       Elf32_External_Dyn * dynconend;
04270 
04271       BFD_ASSERT (sdyn != NULL);
04272 
04273       dyncon = (Elf32_External_Dyn *) sdyn->contents;
04274       dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
04275 
04276       for (; dyncon < dynconend; dyncon++)
04277        {
04278          Elf_Internal_Dyn dyn;
04279 
04280          bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
04281 
04282          switch (dyn.d_tag)
04283            {
04284            default:
04285              break;
04286 
04287            case DT_PLTGOT:
04288              dyn.d_un.d_ptr = bfinfdpic_got_section (info)->output_section->vma
04289               + bfinfdpic_got_section (info)->output_offset
04290               + bfinfdpic_got_initial_offset (info);
04291              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
04292              break;
04293 
04294            case DT_JMPREL:
04295              dyn.d_un.d_ptr = bfinfdpic_pltrel_section (info)
04296               ->output_section->vma
04297               + bfinfdpic_pltrel_section (info)->output_offset;
04298              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
04299              break;
04300 
04301            case DT_PLTRELSZ:
04302              dyn.d_un.d_val = bfinfdpic_pltrel_section (info)->size;
04303              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
04304              break;
04305            }
04306        }
04307     }
04308 
04309   return TRUE;
04310 }
04311 
04312 /* Adjust a symbol defined by a dynamic object and referenced by a
04313    regular object.  */
04314 
04315 static bfd_boolean
04316 elf32_bfinfdpic_adjust_dynamic_symbol
04317 (struct bfd_link_info *info ATTRIBUTE_UNUSED,
04318  struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
04319 {
04320   bfd * dynobj;
04321 
04322   dynobj = elf_hash_table (info)->dynobj;
04323 
04324   /* Make sure we know what is going on here.  */
04325   BFD_ASSERT (dynobj != NULL
04326              && (h->u.weakdef != NULL
04327                 || (h->def_dynamic
04328                     && h->ref_regular
04329                     && !h->def_regular)));
04330 
04331   /* If this is a weak symbol, and there is a real definition, the
04332      processor independent code will have arranged for us to see the
04333      real definition first, and we can just use the same value.  */
04334   if (h->u.weakdef != NULL)
04335     {
04336       BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
04337                 || h->u.weakdef->root.type == bfd_link_hash_defweak);
04338       h->root.u.def.section = h->u.weakdef->root.u.def.section;
04339       h->root.u.def.value = h->u.weakdef->root.u.def.value;
04340     }
04341 
04342   return TRUE;
04343 }
04344 
04345 /* Perform any actions needed for dynamic symbols.  */
04346 
04347 static bfd_boolean
04348 elf32_bfinfdpic_finish_dynamic_symbol
04349 (bfd *output_bfd ATTRIBUTE_UNUSED,
04350  struct bfd_link_info *info ATTRIBUTE_UNUSED,
04351  struct elf_link_hash_entry *h ATTRIBUTE_UNUSED,
04352  Elf_Internal_Sym *sym ATTRIBUTE_UNUSED)
04353 {
04354   return TRUE;
04355 }
04356 
04357 /* Decide whether to attempt to turn absptr or lsda encodings in
04358    shared libraries into pcrel within the given input section.  */
04359 
04360 static bfd_boolean
04361 bfinfdpic_elf_use_relative_eh_frame
04362 (bfd *input_bfd ATTRIBUTE_UNUSED,
04363  struct bfd_link_info *info ATTRIBUTE_UNUSED,
04364  asection *eh_frame_section ATTRIBUTE_UNUSED)
04365 {
04366   /* We can't use PC-relative encodings in FDPIC binaries, in general.  */
04367   return FALSE;
04368 }
04369 
04370 /* Adjust the contents of an eh_frame_hdr section before they're output.  */
04371 
04372 static bfd_byte
04373 bfinfdpic_elf_encode_eh_address (bfd *abfd,
04374                             struct bfd_link_info *info,
04375                             asection *osec, bfd_vma offset,
04376                             asection *loc_sec, bfd_vma loc_offset,
04377                             bfd_vma *encoded)
04378 {
04379   struct elf_link_hash_entry *h;
04380 
04381   h = elf_hash_table (info)->hgot;
04382   BFD_ASSERT (h && h->root.type == bfd_link_hash_defined);
04383 
04384   if (! h || (_bfinfdpic_osec_to_segment (abfd, osec)
04385              == _bfinfdpic_osec_to_segment (abfd, loc_sec->output_section)))
04386     return _bfd_elf_encode_eh_address (abfd, info, osec, offset,
04387                                    loc_sec, loc_offset, encoded);
04388 
04389   BFD_ASSERT (_bfinfdpic_osec_to_segment (abfd, osec)
04390              == (_bfinfdpic_osec_to_segment
04391                 (abfd, h->root.u.def.section->output_section)));
04392 
04393   *encoded = osec->vma + offset
04394     - (h->root.u.def.value
04395        + h->root.u.def.section->output_section->vma
04396        + h->root.u.def.section->output_offset);
04397 
04398   return DW_EH_PE_datarel | DW_EH_PE_sdata4;
04399 }
04400 
04401 
04402 
04403 /* Look through the relocs for a section during the first phase.
04404 
04405    Besides handling virtual table relocs for gc, we have to deal with
04406    all sorts of PIC-related relocations.  We describe below the
04407    general plan on how to handle such relocations, even though we only
04408    collect information at this point, storing them in hash tables for
04409    perusal of later passes.
04410 
04411    32 relocations are propagated to the linker output when creating
04412    position-independent output.  LO16 and HI16 relocations are not
04413    supposed to be encountered in this case.
04414 
04415    LABEL16 should always be resolvable by the linker, since it's only
04416    used by branches.
04417 
04418    LABEL24, on the other hand, is used by calls.  If it turns out that
04419    the target of a call is a dynamic symbol, a PLT entry must be
04420    created for it, which triggers the creation of a private function
04421    descriptor and, unless lazy binding is disabled, a lazy PLT entry.
04422 
04423    GPREL relocations require the referenced symbol to be in the same
04424    segment as _gp, but this can only be checked later.
04425 
04426    All GOT, GOTOFF and FUNCDESC relocations require a .got section to
04427    exist.  LABEL24 might as well, since it may require a PLT entry,
04428    that will require a got.
04429 
04430    Non-FUNCDESC GOT relocations require a GOT entry to be created
04431    regardless of whether the symbol is dynamic.  However, since a
04432    global symbol that turns out to not be exported may have the same
04433    address of a non-dynamic symbol, we don't assign GOT entries at
04434    this point, such that we can share them in this case.  A relocation
04435    for the GOT entry always has to be created, be it to offset a
04436    private symbol by the section load address, be it to get the symbol
04437    resolved dynamically.
04438 
04439    FUNCDESC GOT relocations require a GOT entry to be created, and
04440    handled as if a FUNCDESC relocation was applied to the GOT entry in
04441    an object file.
04442 
04443    FUNCDESC relocations referencing a symbol that turns out to NOT be
04444    dynamic cause a private function descriptor to be created.  The
04445    FUNCDESC relocation then decays to a 32 relocation that points at
04446    the private descriptor.  If the symbol is dynamic, the FUNCDESC
04447    relocation is propagated to the linker output, such that the
04448    dynamic linker creates the canonical descriptor, pointing to the
04449    dynamically-resolved definition of the function.
04450 
04451    Non-FUNCDESC GOTOFF relocations must always refer to non-dynamic
04452    symbols that are assigned to the same segment as the GOT, but we
04453    can only check this later, after we know the complete set of
04454    symbols defined and/or exported.
04455 
04456    FUNCDESC GOTOFF relocations require a function descriptor to be
04457    created and, unless lazy binding is disabled or the symbol is not
04458    dynamic, a lazy PLT entry.  Since we can't tell at this point
04459    whether a symbol is going to be dynamic, we have to decide later
04460    whether to create a lazy PLT entry or bind the descriptor directly
04461    to the private function.
04462 
04463    FUNCDESC_VALUE relocations are not supposed to be present in object
04464    files, but they may very well be simply propagated to the linker
04465    output, since they have no side effect.
04466 
04467 
04468    A function descriptor always requires a FUNCDESC_VALUE relocation.
04469    Whether it's in .plt.rel or not depends on whether lazy binding is
04470    enabled and on whether the referenced symbol is dynamic.
04471 
04472    The existence of a lazy PLT requires the resolverStub lazy PLT
04473    entry to be present.
04474 
04475 
04476    As for assignment of GOT, PLT and lazy PLT entries, and private
04477    descriptors, we might do them all sequentially, but we can do
04478    better than that.  For example, we can place GOT entries and
04479    private function descriptors referenced using 12-bit operands
04480    closer to the PIC register value, such that these relocations don't
04481    overflow.  Those that are only referenced with LO16 relocations
04482    could come next, but we may as well place PLT-required function
04483    descriptors in the 12-bit range to make them shorter.  Symbols
04484    referenced with LO16/HI16 may come next, but we may place
04485    additional function descriptors in the 16-bit range if we can
04486    reliably tell that we've already placed entries that are ever
04487    referenced with only LO16.  PLT entries are therefore generated as
04488    small as possible, while not introducing relocation overflows in
04489    GOT or FUNCDESC_GOTOFF relocations.  Lazy PLT entries could be
04490    generated before or after PLT entries, but not intermingled with
04491    them, such that we can have more lazy PLT entries in range for a
04492    branch to the resolverStub.  The resolverStub should be emitted at
04493    the most distant location from the first lazy PLT entry such that
04494    it's still in range for a branch, or closer, if there isn't a need
04495    for so many lazy PLT entries.  Additional lazy PLT entries may be
04496    emitted after the resolverStub, as long as branches are still in
04497    range.  If the branch goes out of range, longer lazy PLT entries
04498    are emitted.
04499 
04500    We could further optimize PLT and lazy PLT entries by giving them
04501    priority in assignment to closer-to-gr17 locations depending on the
04502    number of occurrences of references to them (assuming a function
04503    that's called more often is more important for performance, so its
04504    PLT entry should be faster), or taking hints from the compiler.
04505    Given infinite time and money... :-)  */
04506 
04507 static bfd_boolean
04508 bfinfdpic_check_relocs (bfd *abfd, struct bfd_link_info *info,
04509                      asection *sec, const Elf_Internal_Rela *relocs)
04510 {
04511   Elf_Internal_Shdr *symtab_hdr;
04512   struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
04513   const Elf_Internal_Rela *rel;
04514   const Elf_Internal_Rela *rel_end;
04515   bfd *dynobj;
04516   struct bfinfdpic_relocs_info *picrel;
04517 
04518   if (info->relocatable)
04519     return TRUE;
04520 
04521   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
04522   sym_hashes = elf_sym_hashes (abfd);
04523   sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym);
04524   if (!elf_bad_symtab (abfd))
04525     sym_hashes_end -= symtab_hdr->sh_info;
04526 
04527   dynobj = elf_hash_table (info)->dynobj;
04528   rel_end = relocs + sec->reloc_count;
04529   for (rel = relocs; rel < rel_end; rel++)
04530     {
04531       struct elf_link_hash_entry *h;
04532       unsigned long r_symndx;
04533 
04534       r_symndx = ELF32_R_SYM (rel->r_info);
04535       if (r_symndx < symtab_hdr->sh_info)
04536         h = NULL;
04537       else
04538         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
04539 
04540       switch (ELF32_R_TYPE (rel->r_info))
04541        {
04542        case R_BFIN_GOT17M4:
04543        case R_BFIN_GOTHI:
04544        case R_BFIN_GOTLO:
04545        case R_BFIN_FUNCDESC_GOT17M4:
04546        case R_BFIN_FUNCDESC_GOTHI:
04547        case R_BFIN_FUNCDESC_GOTLO:
04548        case R_BFIN_GOTOFF17M4:
04549        case R_BFIN_GOTOFFHI:
04550        case R_BFIN_GOTOFFLO:
04551        case R_BFIN_FUNCDESC_GOTOFF17M4:
04552        case R_BFIN_FUNCDESC_GOTOFFHI:
04553        case R_BFIN_FUNCDESC_GOTOFFLO:
04554        case R_BFIN_FUNCDESC:
04555        case R_BFIN_FUNCDESC_VALUE:
04556          if (! IS_FDPIC (abfd))
04557            goto bad_reloc;
04558          /* Fall through.  */
04559        case R_pcrel24:
04560        case R_pcrel24_jump_l:
04561        case R_byte4_data:
04562          if (IS_FDPIC (abfd) && ! dynobj)
04563            {
04564              elf_hash_table (info)->dynobj = dynobj = abfd;
04565              if (! _bfin_create_got_section (abfd, info))
04566               return FALSE;
04567            }
04568          if (! IS_FDPIC (abfd))
04569            {
04570              picrel = NULL;
04571              break;
04572            }
04573          if (h != NULL)
04574            {
04575              if (h->dynindx == -1)
04576               switch (ELF_ST_VISIBILITY (h->other))
04577                 {
04578                 case STV_INTERNAL:
04579                 case STV_HIDDEN:
04580                   break;
04581                 default:
04582                   bfd_elf_link_record_dynamic_symbol (info, h);
04583                   break;
04584                 }
04585              picrel
04586               = bfinfdpic_relocs_info_for_global (bfinfdpic_relocs_info (info),
04587                                              abfd, h,
04588                                              rel->r_addend, INSERT);
04589            }
04590          else
04591            picrel = bfinfdpic_relocs_info_for_local (bfinfdpic_relocs_info
04592                                                (info), abfd, r_symndx,
04593                                                rel->r_addend, INSERT);
04594          if (! picrel)
04595            return FALSE;
04596          break;
04597 
04598        default:
04599          picrel = NULL;
04600          break;
04601        }
04602 
04603       switch (ELF32_R_TYPE (rel->r_info))
04604         {
04605        case R_pcrel24:
04606        case R_pcrel24_jump_l:
04607          if (IS_FDPIC (abfd))
04608            picrel->call = 1;
04609          break;
04610 
04611        case R_BFIN_FUNCDESC_VALUE:
04612          picrel->relocsfdv++;
04613          if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
04614            picrel->relocs32--;
04615          /* Fall through.  */
04616 
04617        case R_byte4_data:
04618          if (! IS_FDPIC (abfd))
04619            break;
04620 
04621          picrel->sym = 1;
04622          if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
04623            picrel->relocs32++;
04624          break;
04625 
04626        case R_BFIN_GOT17M4:
04627          picrel->got17m4 = 1;
04628          break;
04629 
04630        case R_BFIN_GOTHI:
04631        case R_BFIN_GOTLO:
04632          picrel->gothilo = 1;
04633          break;
04634 
04635        case R_BFIN_FUNCDESC_GOT17M4:
04636          picrel->fdgot17m4 = 1;
04637          break;
04638 
04639        case R_BFIN_FUNCDESC_GOTHI:
04640        case R_BFIN_FUNCDESC_GOTLO:
04641          picrel->fdgothilo = 1;
04642          break;
04643 
04644        case R_BFIN_GOTOFF17M4:
04645        case R_BFIN_GOTOFFHI:
04646        case R_BFIN_GOTOFFLO:
04647          picrel->gotoff = 1;
04648          break;
04649 
04650        case R_BFIN_FUNCDESC_GOTOFF17M4:
04651          picrel->fdgoff17m4 = 1;
04652          break;
04653 
04654        case R_BFIN_FUNCDESC_GOTOFFHI:
04655        case R_BFIN_FUNCDESC_GOTOFFLO:
04656          picrel->fdgoffhilo = 1;
04657          break;
04658 
04659        case R_BFIN_FUNCDESC:
04660          picrel->fd = 1;
04661          picrel->relocsfd++;
04662          break;
04663 
04664         /* This relocation describes the C++ object vtable hierarchy.
04665            Reconstruct it for later use during GC.  */
04666         case R_BFIN_GNU_VTINHERIT:
04667           if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
04668             return FALSE;
04669           break;
04670 
04671         /* This relocation describes which C++ vtable entries are actually
04672            used.  Record for later use during GC.  */
04673         case R_BFIN_GNU_VTENTRY:
04674           if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
04675             return FALSE;
04676           break;
04677 
04678        case R_huimm16:
04679        case R_luimm16:
04680        case R_pcrel12_jump_s:
04681        case R_pcrel10:
04682          break;
04683 
04684        default:
04685        bad_reloc:
04686          (*_bfd_error_handler)
04687            (_("%B: unsupported relocation type %i"),
04688             abfd, ELF32_R_TYPE (rel->r_info));
04689          return FALSE;
04690         }
04691     }
04692 
04693   return TRUE;
04694 }
04695 
04696 /* Set the right machine number for a Blackfin ELF file.  */
04697 
04698 static bfd_boolean
04699 elf32_bfin_object_p (bfd *abfd)
04700 {
04701   bfd_default_set_arch_mach (abfd, bfd_arch_bfin, 0);
04702   return (((elf_elfheader (abfd)->e_flags & EF_BFIN_FDPIC) != 0)
04703          == (IS_FDPIC (abfd)));
04704 }
04705 
04706 static bfd_boolean
04707 elf32_bfin_set_private_flags (bfd * abfd, flagword flags)
04708 {
04709   elf_elfheader (abfd)->e_flags = flags;
04710   elf_flags_init (abfd) = TRUE;
04711   return TRUE;
04712 }
04713 
04714 /* Copy backend specific data from one object module to another.  */
04715 
04716 static bfd_boolean
04717 bfin_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
04718 {
04719   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
04720       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
04721     return TRUE;
04722 
04723   BFD_ASSERT (!elf_flags_init (obfd)
04724              || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
04725 
04726   elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
04727   elf_flags_init (obfd) = TRUE;
04728   return TRUE;
04729 }
04730 
04731 static bfd_boolean
04732 elf32_bfinfdpic_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
04733 {
04734   unsigned i;
04735 
04736   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
04737       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
04738     return TRUE;
04739 
04740   if (! bfin_elf_copy_private_bfd_data (ibfd, obfd))
04741     return FALSE;
04742 
04743   if (! elf_tdata (ibfd) || ! elf_tdata (ibfd)->phdr
04744       || ! elf_tdata (obfd) || ! elf_tdata (obfd)->phdr)
04745     return TRUE;
04746 
04747   /* Copy the stack size.  */
04748   for (i = 0; i < elf_elfheader (ibfd)->e_phnum; i++)
04749     if (elf_tdata (ibfd)->phdr[i].p_type == PT_GNU_STACK)
04750       {
04751        Elf_Internal_Phdr *iphdr = &elf_tdata (ibfd)->phdr[i];
04752 
04753        for (i = 0; i < elf_elfheader (obfd)->e_phnum; i++)
04754          if (elf_tdata (obfd)->phdr[i].p_type == PT_GNU_STACK)
04755            {
04756              memcpy (&elf_tdata (obfd)->phdr[i], iphdr, sizeof (*iphdr));
04757 
04758              /* Rewrite the phdrs, since we're only called after they
04759                were first written.  */
04760              if (bfd_seek (obfd, (bfd_signed_vma) get_elf_backend_data (obfd)
04761                          ->s->sizeof_ehdr, SEEK_SET) != 0
04762                 || get_elf_backend_data (obfd)->s
04763                 ->write_out_phdrs (obfd, elf_tdata (obfd)->phdr,
04764                                  elf_elfheader (obfd)->e_phnum) != 0)
04765               return FALSE;
04766              break;
04767            }
04768 
04769        break;
04770       }
04771 
04772   return TRUE;
04773 }
04774 
04775 
04776 /* Display the flags field.  */
04777 static bfd_boolean
04778 elf32_bfin_print_private_bfd_data (bfd * abfd, PTR ptr)
04779 {
04780   FILE *file = (FILE *) ptr;
04781   flagword flags;
04782 
04783   BFD_ASSERT (abfd != NULL && ptr != NULL);
04784 
04785   /* Print normal ELF private data.  */
04786   _bfd_elf_print_private_bfd_data (abfd, ptr);
04787 
04788   flags = elf_elfheader (abfd)->e_flags;
04789 
04790   /* xgettext:c-format */
04791   fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
04792 
04793   if (flags & EF_BFIN_PIC)
04794     fprintf (file, " -fpic");
04795 
04796   if (flags & EF_BFIN_FDPIC)
04797     fprintf (file, " -mfdpic");
04798 
04799   fputc ('\n', file);
04800 
04801   return TRUE;
04802 }
04803 
04804 /* Merge backend specific data from an object file to the output
04805    object file when linking.  */
04806 
04807 static bfd_boolean
04808 elf32_bfin_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
04809 {
04810   flagword old_flags, old_partial;
04811   flagword new_flags, new_partial;
04812   bfd_boolean error = FALSE;
04813 
04814   new_flags = elf_elfheader (ibfd)->e_flags;
04815   old_flags = elf_elfheader (obfd)->e_flags;
04816 
04817   if (new_flags & EF_BFIN_FDPIC)
04818     new_flags &= ~EF_BFIN_PIC;
04819 
04820 #ifdef DEBUG
04821   (*_bfd_error_handler) ("old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s, filename = %s",
04822                       old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no",
04823                       bfd_get_filename (ibfd));
04824 #endif
04825 
04826   if (!elf_flags_init (obfd))                    /* First call, no flags set.  */
04827     {
04828       elf_flags_init (obfd) = TRUE;
04829       old_flags = new_flags;
04830     }
04831 
04832   else if (new_flags == old_flags)        /* Compatible flags are ok.  */
04833     ;
04834 
04835   else                                    /* Possibly incompatible flags.  */
04836     {
04837       /* We don't have to do anything if the pic flags are the same, or the new
04838          module(s) were compiled with -mlibrary-pic.  */
04839       new_partial = (new_flags & EF_BFIN_PIC_FLAGS);
04840       old_partial = (old_flags & EF_BFIN_PIC_FLAGS);
04841       if (new_partial == old_partial)
04842        ;
04843 
04844       /* If we have mixtures of -fpic and -fPIC, or in both bits.  */
04845       else if (new_partial != 0 && old_partial != 0)
04846        old_flags |= new_partial;
04847 
04848       /* One module was compiled for pic and the other was not, see if we have
04849          had any relocations that are not pic-safe.  */
04850       else
04851        old_flags |= new_partial;
04852 
04853     }
04854 
04855   /* Update the old flags now with changes made above.  */
04856   elf_elfheader (obfd)->e_flags = old_flags;
04857 
04858   if (((new_flags & EF_BFIN_FDPIC) == 0)
04859       != (! IS_FDPIC (ibfd)))
04860     {
04861       error = TRUE;
04862       if (IS_FDPIC (obfd))
04863        (*_bfd_error_handler)
04864          (_("%s: cannot link non-fdpic object file into fdpic executable"),
04865           bfd_get_filename (ibfd));
04866       else
04867        (*_bfd_error_handler)
04868          (_("%s: cannot link fdpic object file into non-fdpic executable"),
04869           bfd_get_filename (ibfd));
04870     }
04871 
04872   if (error)
04873     bfd_set_error (bfd_error_bad_value);
04874 
04875   return !error;
04876 }
04877 
04878 /* bfin ELF linker hash entry.  */
04879 
04880 struct bfin_link_hash_entry
04881 {
04882   struct elf_link_hash_entry root;
04883 
04884   /* Number of PC relative relocs copied for this symbol.  */
04885   struct bfin_pcrel_relocs_copied *pcrel_relocs_copied;
04886 };
04887 
04888 /* bfin ELF linker hash table.  */
04889 
04890 struct bfin_link_hash_table
04891 {
04892   struct elf_link_hash_table root;
04893 
04894   /* Small local sym to section mapping cache.  */
04895   struct sym_sec_cache sym_sec;
04896 };
04897 
04898 #define bfin_hash_entry(ent) ((struct bfin_link_hash_entry *) (ent))
04899 
04900 static struct bfd_hash_entry *
04901 bfin_link_hash_newfunc (struct bfd_hash_entry *entry,
04902                      struct bfd_hash_table *table, const char *string)
04903 {
04904   struct bfd_hash_entry *ret = entry;
04905 
04906   /* Allocate the structure if it has not already been allocated by a
04907      subclass.  */
04908   if (ret == NULL)
04909     ret = bfd_hash_allocate (table, sizeof (struct bfin_link_hash_entry));
04910   if (ret == NULL)
04911     return ret;
04912 
04913   /* Call the allocation method of the superclass.  */
04914   ret = _bfd_elf_link_hash_newfunc (ret, table, string);
04915   if (ret != NULL)
04916     bfin_hash_entry (ret)->pcrel_relocs_copied = NULL;
04917 
04918   return ret;
04919 }
04920 
04921 /* Create an bfin ELF linker hash table.  */
04922 
04923 static struct bfd_link_hash_table *
04924 bfin_link_hash_table_create (bfd * abfd)
04925 {
04926   struct bfin_link_hash_table *ret;
04927   bfd_size_type amt = sizeof (struct bfin_link_hash_table);
04928 
04929   ret = bfd_zalloc (abfd, amt);
04930   if (ret == NULL)
04931     return NULL;
04932 
04933   if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
04934                                   bfin_link_hash_newfunc,
04935                                   sizeof (struct elf_link_hash_entry)))
04936     {
04937       free (ret);
04938       return NULL;
04939     }
04940 
04941   ret->sym_sec.abfd = NULL;
04942 
04943   return &ret->root.root;
04944 }
04945 
04946 /* The size in bytes of an entry in the procedure linkage table.  */
04947 
04948 /* Finish up the dynamic sections.  */
04949 
04950 static bfd_boolean
04951 bfin_finish_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
04952                               struct bfd_link_info *info)
04953 {
04954   bfd *dynobj;
04955   asection *sdyn;
04956 
04957   dynobj = elf_hash_table (info)->dynobj;
04958 
04959   sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
04960 
04961   if (elf_hash_table (info)->dynamic_sections_created)
04962     {
04963       Elf32_External_Dyn *dyncon, *dynconend;
04964 
04965       BFD_ASSERT (sdyn != NULL);
04966 
04967       dyncon = (Elf32_External_Dyn *) sdyn->contents;
04968       dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
04969       for (; dyncon < dynconend; dyncon++)
04970        {
04971          Elf_Internal_Dyn dyn;
04972 
04973          bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
04974 
04975        }
04976 
04977     }
04978   return TRUE;
04979 }
04980 
04981 /* Finish up dynamic symbol handling.  We set the contents of various
04982    dynamic sections here.  */
04983 
04984 static bfd_boolean
04985 bfin_finish_dynamic_symbol (bfd * output_bfd,
04986                             struct bfd_link_info *info,
04987                             struct elf_link_hash_entry *h,
04988                             Elf_Internal_Sym * sym)
04989 {
04990   bfd *dynobj;
04991 
04992   dynobj = elf_hash_table (info)->dynobj;
04993 
04994   if (h->got.offset != (bfd_vma) - 1)
04995     {
04996       asection *sgot;
04997       asection *srela;
04998       Elf_Internal_Rela rela;
04999       bfd_byte *loc;
05000 
05001       /* This symbol has an entry in the global offset table.
05002          Set it up.  */
05003 
05004       sgot = bfd_get_section_by_name (dynobj, ".got");
05005       srela = bfd_get_section_by_name (dynobj, ".rela.got");
05006       BFD_ASSERT (sgot != NULL && srela != NULL);
05007 
05008       rela.r_offset = (sgot->output_section->vma
05009                      + sgot->output_offset
05010                      + (h->got.offset & ~(bfd_vma) 1));
05011 
05012       /* If this is a -Bsymbolic link, and the symbol is defined
05013          locally, we just want to emit a RELATIVE reloc.  Likewise if
05014          the symbol was forced to be local because of a version file.
05015          The entry in the global offset table will already have been
05016          initialized in the relocate_section function.  */
05017       if (info->shared
05018          && (info->symbolic
05019              || h->dynindx == -1 || h->forced_local) && h->def_regular)
05020        {
05021          fprintf(stderr, "*** check this relocation %s\n", __FUNCTION__);
05022          rela.r_info = ELF32_R_INFO (0, R_pcrel24);
05023          rela.r_addend = bfd_get_signed_32 (output_bfd,
05024                                         (sgot->contents
05025                                          +
05026                                          (h->got.
05027                                           offset & ~(bfd_vma) 1)));
05028        }
05029       else
05030        {
05031          bfd_put_32 (output_bfd, (bfd_vma) 0,
05032                     sgot->contents + (h->got.offset & ~(bfd_vma) 1));
05033          rela.r_info = ELF32_R_INFO (h->dynindx, R_got);
05034          rela.r_addend = 0;
05035        }
05036 
05037       loc = srela->contents;
05038       loc += srela->reloc_count++ * sizeof (Elf32_External_Rela);
05039       bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
05040     }
05041 
05042   if (h->needs_copy)
05043     {
05044       BFD_ASSERT (0);
05045     }
05046   /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
05047   if (strcmp (h->root.root.string, "__DYNAMIC") == 0
05048       || h == elf_hash_table (info)->hgot)
05049     sym->st_shndx = SHN_ABS;
05050 
05051   return TRUE;
05052 }
05053 
05054 /* Adjust a symbol defined by a dynamic object and referenced by a
05055    regular object.  The current definition is in some section of the
05056    dynamic object, but we're not including those sections.  We have to
05057    change the definition to something the rest of the link can
05058    understand.  */
05059 
05060 static bfd_boolean
05061 bfin_adjust_dynamic_symbol (struct bfd_link_info *info,
05062                             struct elf_link_hash_entry *h)
05063 {
05064   bfd *dynobj;
05065   asection *s;
05066   unsigned int power_of_two;
05067 
05068   dynobj = elf_hash_table (info)->dynobj;
05069 
05070   /* Make sure we know what is going on here.  */
05071   BFD_ASSERT (dynobj != NULL
05072              && (h->needs_plt
05073                 || h->u.weakdef != NULL
05074                 || (h->def_dynamic && h->ref_regular && !h->def_regular)));
05075 
05076   /* If this is a function, put it in the procedure linkage table.  We
05077      will fill in the contents of the procedure linkage table later,
05078      when we know the address of the .got section.  */
05079   if (h->type == STT_FUNC || h->needs_plt)
05080     {
05081       BFD_ASSERT(0);
05082     }
05083 
05084   /* If this is a weak symbol, and there is a real definition, the
05085      processor independent code will have arranged for us to see the
05086      real definition first, and we can just use the same value.  */
05087   if (h->u.weakdef != NULL)
05088     {
05089       BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
05090                 || h->u.weakdef->root.type == bfd_link_hash_defweak);
05091       h->root.u.def.section = h->u.weakdef->root.u.def.section;
05092       h->root.u.def.value = h->u.weakdef->root.u.def.value;
05093       return TRUE;
05094     }
05095 
05096   /* This is a reference to a symbol defined by a dynamic object which
05097      is not a function.  */
05098 
05099   /* If we are creating a shared library, we must presume that the
05100      only references to the symbol are via the global offset table.
05101      For such cases we need not do anything here; the relocations will
05102      be handled correctly by relocate_section.  */
05103   if (info->shared)
05104     return TRUE;
05105 
05106   /* We must allocate the symbol in our .dynbss section, which will
05107      become part of the .bss section of the executable.  There will be
05108      an entry for this symbol in the .dynsym section.  The dynamic
05109      object will contain position independent code, so all references
05110      from the dynamic object to this symbol will go through the global
05111      offset table.  The dynamic linker will use the .dynsym entry to
05112      determine the address it must put in the global offset table, so
05113      both the dynamic object and the regular object will refer to the
05114      same memory location for the variable.  */
05115 
05116   s = bfd_get_section_by_name (dynobj, ".dynbss");
05117   BFD_ASSERT (s != NULL);
05118 
05119   /* We must generate a R_68K_COPY reloc to tell the dynamic linker to
05120      copy the initial value out of the dynamic object and into the
05121      runtime process image.  We need to remember the offset into the
05122      .rela.bss section we are going to use.  */
05123   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
05124     {
05125       asection *srel;
05126 
05127       srel = bfd_get_section_by_name (dynobj, ".rela.bss");
05128       BFD_ASSERT (srel != NULL);
05129       srel->size += sizeof (Elf32_External_Rela);
05130       h->needs_copy = 1;
05131     }
05132 
05133   /* We need to figure out the alignment required for this symbol.  I
05134      have no idea how ELF linkers handle this.  */
05135   power_of_two = bfd_log2 (h->size);
05136   if (power_of_two > 3)
05137     power_of_two = 3;
05138 
05139   /* Apply the required alignment.  */
05140   s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
05141   if (power_of_two > bfd_get_section_alignment (dynobj, s))
05142     {
05143       if (!bfd_set_section_alignment (dynobj, s, power_of_two))
05144        return FALSE;
05145     }
05146 
05147   /* Define the symbol as being at this point in the section.  */
05148   h->root.u.def.section = s;
05149   h->root.u.def.value = s->size;
05150 
05151   /* Increment the section size to make room for the symbol.  */
05152   s->size += h->size;
05153 
05154   return TRUE;
05155 }
05156 
05157 /* The bfin linker needs to keep track of the number of relocs that it
05158    decides to copy in check_relocs for each symbol.  This is so that it
05159    can discard PC relative relocs if it doesn't need them when linking
05160    with -Bsymbolic.  We store the information in a field extending the
05161    regular ELF linker hash table.  */
05162 
05163 /* This structure keeps track of the number of PC relative relocs we have
05164    copied for a given symbol.  */
05165 
05166 struct bfin_pcrel_relocs_copied
05167 {
05168   /* Next section.  */
05169   struct bfin_pcrel_relocs_copied *next;
05170   /* A section in dynobj.  */
05171   asection *section;
05172   /* Number of relocs copied in this section.  */
05173   bfd_size_type count;
05174 };
05175 
05176 /* This function is called via elf_link_hash_traverse if we are
05177    creating a shared object.  In the -Bsymbolic case it discards the
05178    space allocated to copy PC relative relocs against symbols which
05179    are defined in regular objects.  For the normal shared case, it
05180    discards space for pc-relative relocs that have become local due to
05181    symbol visibility changes.  We allocated space for them in the
05182    check_relocs routine, but we won't fill them in in the
05183    relocate_section routine.
05184 
05185    We also check whether any of the remaining relocations apply
05186    against a readonly section, and set the DF_TEXTREL flag in this
05187    case.  */
05188 
05189 static bfd_boolean
05190 bfin_discard_copies (struct elf_link_hash_entry *h, PTR inf)
05191 {
05192   struct bfd_link_info *info = (struct bfd_link_info *) inf;
05193   struct bfin_pcrel_relocs_copied *s;
05194 
05195   if (h->root.type == bfd_link_hash_warning)
05196     h = (struct elf_link_hash_entry *) h->root.u.i.link;
05197 
05198   if (!h->def_regular || (!info->symbolic && !h->forced_local))
05199     {
05200       if ((info->flags & DF_TEXTREL) == 0)
05201        {
05202          /* Look for relocations against read-only sections.  */
05203          for (s = bfin_hash_entry (h)->pcrel_relocs_copied;
05204               s != NULL; s = s->next)
05205            if ((s->section->flags & SEC_READONLY) != 0)
05206              {
05207               info->flags |= DF_TEXTREL;
05208               break;
05209              }
05210        }
05211 
05212       return TRUE;
05213     }
05214 
05215   for (s = bfin_hash_entry (h)->pcrel_relocs_copied;
05216        s != NULL; s = s->next)
05217     s->section->size -= s->count * sizeof (Elf32_External_Rela);
05218 
05219   return TRUE;
05220 }
05221 
05222 static bfd_boolean
05223 bfin_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
05224                             struct bfd_link_info *info)
05225 {
05226   bfd *dynobj;
05227   asection *s;
05228   bfd_boolean relocs;
05229 
05230   dynobj = elf_hash_table (info)->dynobj;
05231   BFD_ASSERT (dynobj != NULL);
05232 
05233   if (elf_hash_table (info)->dynamic_sections_created)
05234     {
05235       /* Set the contents of the .interp section to the interpreter.  */
05236       if (info->executable)
05237        {
05238          s = bfd_get_section_by_name (dynobj, ".interp");
05239          BFD_ASSERT (s != NULL);
05240          s->size = sizeof ELF_DYNAMIC_INTERPRETER;
05241          s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
05242        }
05243     }
05244   else
05245     {
05246       /* We may have created entries in the .rela.got section.
05247          However, if we are not creating the dynamic sections, we will
05248          not actually use these entries.  Reset the size of .rela.got,
05249          which will cause it to get stripped from the output file
05250          below.  */
05251       s = bfd_get_section_by_name (dynobj, ".rela.got");
05252       if (s != NULL)
05253        s->size = 0;
05254     }
05255 
05256   /* If this is a -Bsymbolic shared link, then we need to discard all
05257      PC relative relocs against symbols defined in a regular object.
05258      For the normal shared case we discard the PC relative relocs
05259      against symbols that have become local due to visibility changes.
05260      We allocated space for them in the check_relocs routine, but we
05261      will not fill them in in the relocate_section routine.  */
05262   if (info->shared)
05263     elf_link_hash_traverse (elf_hash_table (info),
05264                          bfin_discard_copies, (PTR) info);
05265 
05266   /* The check_relocs and adjust_dynamic_symbol entry points have
05267      determined the sizes of the various dynamic sections.  Allocate
05268      memory for them.  */
05269   relocs = FALSE;
05270   for (s = dynobj->sections; s != NULL; s = s->next)
05271     {
05272       const char *name;
05273       bfd_boolean strip;
05274 
05275       if ((s->flags & SEC_LINKER_CREATED) == 0)
05276        continue;
05277 
05278       /* It's OK to base decisions on the section name, because none
05279          of the dynobj section names depend upon the input files.  */
05280       name = bfd_get_section_name (dynobj, s);
05281 
05282       strip = FALSE;
05283 
05284        if (CONST_STRNEQ (name, ".rela"))
05285        {
05286          if (s->size == 0)
05287            {
05288              /* If we don't need this section, strip it from the
05289                 output file.  This is mostly to handle .rela.bss and
05290                 .rela.plt.  We must create both sections in
05291                 create_dynamic_sections, because they must be created
05292                 before the linker maps input sections to output
05293                 sections.  The linker does that before
05294                 adjust_dynamic_symbol is called, and it is that
05295                 function which decides whether anything needs to go
05296                 into these sections.  */
05297              strip = TRUE;
05298            }
05299          else
05300            {
05301              relocs = TRUE;
05302 
05303              /* We use the reloc_count field as a counter if we need
05304                 to copy relocs into the output file.  */
05305              s->reloc_count = 0;
05306            }
05307        }
05308       else if (! CONST_STRNEQ (name, ".got"))
05309        {
05310          /* It's not one of our sections, so don't allocate space.  */
05311          continue;
05312        }
05313 
05314       if (strip)
05315        {
05316          s->flags |= SEC_EXCLUDE;
05317          continue;
05318        }
05319 
05320       /* Allocate memory for the section contents.  */
05321       /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
05322          Unused entries should be reclaimed before the section's contents
05323          are written out, but at the moment this does not happen.  Thus in
05324          order to prevent writing out garbage, we initialise the section's
05325          contents to zero.  */
05326       s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
05327       if (s->contents == NULL && s->size != 0)
05328        return FALSE;
05329     }
05330 
05331   if (elf_hash_table (info)->dynamic_sections_created)
05332     {
05333       /* Add some entries to the .dynamic section.  We fill in the
05334          values later, in bfin_finish_dynamic_sections, but we
05335          must add the entries now so that we get the correct size for
05336          the .dynamic section.  The DT_DEBUG entry is filled in by the
05337          dynamic linker and used by the debugger.  */
05338 #define add_dynamic_entry(TAG, VAL) \
05339   _bfd_elf_add_dynamic_entry (info, TAG, VAL)
05340 
05341       if (!info->shared)
05342        {
05343          if (!add_dynamic_entry (DT_DEBUG, 0))
05344            return FALSE;
05345        }
05346 
05347 
05348       if (relocs)
05349        {
05350          if (!add_dynamic_entry (DT_RELA, 0)
05351              || !add_dynamic_entry (DT_RELASZ, 0)
05352              || !add_dynamic_entry (DT_RELAENT,
05353                                  sizeof (Elf32_External_Rela)))
05354            return FALSE;
05355        }
05356 
05357       if ((info->flags & DF_TEXTREL) != 0)
05358        {
05359          if (!add_dynamic_entry (DT_TEXTREL, 0))
05360            return FALSE;
05361        }
05362     }
05363 #undef add_dynamic_entry
05364 
05365   return TRUE;
05366 }
05367 
05368 /* Given a .data section and a .emreloc in-memory section, store
05369    relocation information into the .emreloc section which can be
05370    used at runtime to relocate the section.  This is called by the
05371    linker when the --embedded-relocs switch is used.  This is called
05372    after the add_symbols entry point has been called for all the
05373    objects, and before the final_link entry point is called.  */
05374 
05375 bfd_boolean bfd_bfin_elf32_create_embedded_relocs
05376   PARAMS ((bfd *, struct bfd_link_info *, asection *, asection *, char **));
05377 
05378 bfd_boolean
05379 bfd_bfin_elf32_create_embedded_relocs (
05380      bfd *abfd,
05381      struct bfd_link_info *info,
05382      asection *datasec,
05383      asection *relsec,
05384      char **errmsg)
05385 {
05386   Elf_Internal_Shdr *symtab_hdr;
05387   Elf_Internal_Sym *isymbuf = NULL;
05388   Elf_Internal_Rela *internal_relocs = NULL;
05389   Elf_Internal_Rela *irel, *irelend;
05390   bfd_byte *p;
05391   bfd_size_type amt;
05392 
05393   BFD_ASSERT (! info->relocatable);
05394 
05395   *errmsg = NULL;
05396 
05397   if (datasec->reloc_count == 0)
05398     return TRUE;
05399 
05400   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
05401 
05402   /* Get a copy of the native relocations.  */
05403   internal_relocs = (_bfd_elf_link_read_relocs
05404                    (abfd, datasec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
05405                     info->keep_memory));
05406   if (internal_relocs == NULL)
05407     goto error_return;
05408 
05409   amt = (bfd_size_type) datasec->reloc_count * 12;
05410   relsec->contents = (bfd_byte *) bfd_alloc (abfd, amt);
05411   if (relsec->contents == NULL)
05412     goto error_return;
05413 
05414   p = relsec->contents;
05415 
05416   irelend = internal_relocs + datasec->reloc_count;
05417   for (irel = internal_relocs; irel < irelend; irel++, p += 12)
05418     {
05419       asection *targetsec;
05420 
05421       /* We are going to write a four byte longword into the runtime
05422        reloc section.  The longword will be the address in the data
05423        section which must be relocated.  It is followed by the name
05424        of the target section NUL-padded or truncated to 8
05425        characters.  */
05426 
05427       /* We can only relocate absolute longword relocs at run time.  */
05428       if (ELF32_R_TYPE (irel->r_info) != (int) R_byte4_data)
05429        {
05430          *errmsg = _("unsupported reloc type");
05431          bfd_set_error (bfd_error_bad_value);
05432          goto error_return;
05433        }
05434 
05435       /* Get the target section referred to by the reloc.  */
05436       if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
05437        {
05438          /* A local symbol.  */
05439          Elf_Internal_Sym *isym;
05440 
05441          /* Read this BFD's local symbols if we haven't done so already.  */
05442          if (isymbuf == NULL)
05443            {
05444              isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
05445              if (isymbuf == NULL)
05446               isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
05447                                           symtab_hdr->sh_info, 0,
05448                                           NULL, NULL, NULL);
05449              if (isymbuf == NULL)
05450               goto error_return;
05451            }
05452 
05453          isym = isymbuf + ELF32_R_SYM (irel->r_info);
05454          targetsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
05455        }
05456       else
05457        {
05458          unsigned long indx;
05459          struct elf_link_hash_entry *h;
05460 
05461          /* An external symbol.  */
05462          indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
05463          h = elf_sym_hashes (abfd)[indx];
05464          BFD_ASSERT (h != NULL);
05465          if (h->root.type == bfd_link_hash_defined
05466              || h->root.type == bfd_link_hash_defweak)
05467            targetsec = h->root.u.def.section;
05468          else
05469            targetsec = NULL;
05470        }
05471 
05472       bfd_put_32 (abfd, irel->r_offset + datasec->output_offset, p);
05473       memset (p + 4, 0, 8);
05474       if (targetsec != NULL)
05475        strncpy ((char *) p + 4, targetsec->output_section->name, 8);
05476     }
05477 
05478   if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
05479     free (isymbuf);
05480   if (internal_relocs != NULL
05481       && elf_section_data (datasec)->relocs != internal_relocs)
05482     free (internal_relocs);
05483   return TRUE;
05484 
05485 error_return:
05486   if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
05487     free (isymbuf);
05488   if (internal_relocs != NULL
05489       && elf_section_data (datasec)->relocs != internal_relocs)
05490     free (internal_relocs);
05491   return FALSE;
05492 }
05493 
05494 #define TARGET_LITTLE_SYM          bfd_elf32_bfin_vec
05495 #define TARGET_LITTLE_NAME         "elf32-bfin"
05496 #define ELF_ARCH                   bfd_arch_bfin
05497 #define ELF_MACHINE_CODE           EM_BLACKFIN
05498 #define ELF_MAXPAGESIZE                   0x1000
05499 #define elf_symbol_leading_char           '_'
05500 
05501 #define bfd_elf32_bfd_reloc_type_lookup   bfin_bfd_reloc_type_lookup
05502 #define bfd_elf32_bfd_reloc_name_lookup \
05503                                    bfin_bfd_reloc_name_lookup
05504 #define elf_info_to_howto          bfin_info_to_howto
05505 #define elf_info_to_howto_rel             0
05506 #define elf_backend_object_p              elf32_bfin_object_p
05507 
05508 #define bfd_elf32_bfd_is_local_label_name \
05509                                         bfin_is_local_label_name
05510 #define bfin_hash_table(p) \
05511   ((struct bfin_link_hash_table *) (p)->hash)
05512 
05513 
05514 
05515 #define elf_backend_create_dynamic_sections \
05516                                         _bfd_elf_create_dynamic_sections
05517 #define bfd_elf32_bfd_link_hash_table_create \
05518                                         bfin_link_hash_table_create
05519 #define bfd_elf32_bfd_final_link        bfd_elf_gc_common_final_link
05520 
05521 #define elf_backend_check_relocs        bfin_check_relocs
05522 #define elf_backend_adjust_dynamic_symbol \
05523                                         bfin_adjust_dynamic_symbol
05524 #define elf_backend_size_dynamic_sections \
05525                                         bfin_size_dynamic_sections
05526 #define elf_backend_relocate_section    bfin_relocate_section
05527 #define elf_backend_finish_dynamic_symbol \
05528                                         bfin_finish_dynamic_symbol
05529 #define elf_backend_finish_dynamic_sections \
05530                                         bfin_finish_dynamic_sections
05531 #define elf_backend_gc_mark_hook        bfin_gc_mark_hook
05532 #define elf_backend_gc_sweep_hook       bfin_gc_sweep_hook
05533 #define bfd_elf32_bfd_merge_private_bfd_data \
05534                                         elf32_bfin_merge_private_bfd_data
05535 #define bfd_elf32_bfd_set_private_flags \
05536                                         elf32_bfin_set_private_flags
05537 #define bfd_elf32_bfd_print_private_bfd_data \
05538                                         elf32_bfin_print_private_bfd_data
05539 #define elf_backend_reloc_type_class    elf32_bfin_reloc_type_class
05540 #define elf_backend_can_gc_sections 1
05541 #define elf_backend_can_refcount 1
05542 #define elf_backend_want_got_plt 0
05543 #define elf_backend_plt_readonly 1
05544 #define elf_backend_want_plt_sym 0
05545 #define elf_backend_got_header_size     12
05546 #define elf_backend_rela_normal         1
05547 
05548 #include "elf32-target.h"
05549 
05550 #undef TARGET_LITTLE_SYM
05551 #define TARGET_LITTLE_SYM          bfd_elf32_bfinfdpic_vec
05552 #undef TARGET_LITTLE_NAME
05553 #define TARGET_LITTLE_NAME         "elf32-bfinfdpic"
05554 #undef elf32_bed
05555 #define       elf32_bed            elf32_bfinfdpic_bed
05556 
05557 #undef elf_backend_gc_sweep_hook
05558 
05559 #undef elf_backend_got_header_size
05560 #define elf_backend_got_header_size     0
05561 
05562 #undef elf_backend_relocate_section
05563 #define elf_backend_relocate_section    bfinfdpic_relocate_section
05564 #undef elf_backend_check_relocs
05565 #define elf_backend_check_relocs        bfinfdpic_check_relocs
05566 
05567 #undef bfd_elf32_bfd_link_hash_table_create
05568 #define bfd_elf32_bfd_link_hash_table_create \
05569               bfinfdpic_elf_link_hash_table_create
05570 #undef elf_backend_always_size_sections
05571 #define elf_backend_always_size_sections \
05572               elf32_bfinfdpic_always_size_sections
05573 #undef elf_backend_modify_program_headers
05574 #define elf_backend_modify_program_headers \
05575               elf32_bfinfdpic_modify_program_headers
05576 #undef bfd_elf32_bfd_copy_private_bfd_data
05577 #define bfd_elf32_bfd_copy_private_bfd_data \
05578               elf32_bfinfdpic_copy_private_bfd_data
05579 
05580 #undef elf_backend_create_dynamic_sections
05581 #define elf_backend_create_dynamic_sections \
05582               elf32_bfinfdpic_create_dynamic_sections
05583 #undef elf_backend_adjust_dynamic_symbol
05584 #define elf_backend_adjust_dynamic_symbol \
05585               elf32_bfinfdpic_adjust_dynamic_symbol
05586 #undef elf_backend_size_dynamic_sections
05587 #define elf_backend_size_dynamic_sections \
05588               elf32_bfinfdpic_size_dynamic_sections
05589 #undef elf_backend_finish_dynamic_symbol
05590 #define elf_backend_finish_dynamic_symbol \
05591               elf32_bfinfdpic_finish_dynamic_symbol
05592 #undef elf_backend_finish_dynamic_sections
05593 #define elf_backend_finish_dynamic_sections \
05594               elf32_bfinfdpic_finish_dynamic_sections
05595 
05596 #undef elf_backend_can_make_relative_eh_frame
05597 #define elf_backend_can_make_relative_eh_frame \
05598               bfinfdpic_elf_use_relative_eh_frame
05599 #undef elf_backend_can_make_lsda_relative_eh_frame
05600 #define elf_backend_can_make_lsda_relative_eh_frame \
05601               bfinfdpic_elf_use_relative_eh_frame
05602 #undef elf_backend_encode_eh_address
05603 #define elf_backend_encode_eh_address \
05604               bfinfdpic_elf_encode_eh_address
05605 
05606 #undef elf_backend_may_use_rel_p
05607 #define elf_backend_may_use_rel_p       1
05608 #undef elf_backend_may_use_rela_p
05609 #define elf_backend_may_use_rela_p      1
05610 /* We use REL for dynamic relocations only.  */
05611 #undef elf_backend_default_use_rela_p
05612 #define elf_backend_default_use_rela_p  1
05613 
05614 #undef elf_backend_omit_section_dynsym
05615 #define elf_backend_omit_section_dynsym _bfinfdpic_link_omit_section_dynsym
05616 
05617 #include "elf32-target.h"