Home | History | Annotate | Download | only in src
      1 /* Copyright (C) 2001, 2002, 2003, 2004 Red Hat, Inc.
      2    Written by Ulrich Drepper <drepper (at) redhat.com>, 2001.
      3 
      4    This program is Open Source software; you can redistribute it and/or
      5    modify it under the terms of the Open Software License version 1.0 as
      6    published by the Open Source Initiative.
      7 
      8    You should have received a copy of the Open Software License along
      9    with this program; if not, you may obtain a copy of the Open Software
     10    License version 1.0 from http://www.opensource.org/licenses/osl.php or
     11    by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
     12    3001 King Ranch Road, Ukiah, CA 95482.   */
     13 
     14 #ifdef HAVE_CONFIG_H
     15 # include <config.h>
     16 #endif
     17 
     18 #include <assert.h>
     19 #include <error.h>
     20 #include <libintl.h>
     21 #include <stdlib.h>
     22 #include <string.h>
     23 
     24 // XXX For debugging
     25 #include <stdio.h>
     26 
     27 #include <system.h>
     28 #include "ld.h"
     29 #include "list.h"
     30 /* x86 is little endian.  */
     31 #define UNALIGNED_ACCESS_CLASS LITTLE_ENDIAN
     32 #include "unaligned.h"
     33 #include "xelf.h"
     34 
     35 
     36 /* The old callbacks.  */
     37 static int (*old_open_outfile) (struct ld_state *, int, int, int);
     38 
     39 
     40 static int
     41 elf_i386_open_outfile (struct ld_state *statep, int machine, int klass,
     42 		       int data)
     43 {
     44   /* This backend only handles 32-bit object files.  */
     45   /* XXX For now just use the generic backend.  */
     46   return old_open_outfile (statep, EM_386, ELFCLASS32, ELFDATA2LSB);
     47 }
     48 
     49 
     50 /* Process relocations for the output in a relocatable file.  This
     51    only means adjusting offset and symbol indices.  */
     52 static void
     53 elf_i386_relocate_section (struct ld_state *statep, Elf_Scn *outscn,
     54 			   struct scninfo *firstp,
     55 			   const Elf32_Word *dblindirect)
     56 {
     57   struct scninfo *runp;
     58   Elf_Data *data;
     59 
     60   /* Iterate over all the input sections.  Appropriate data buffers in the
     61      output sections were already created.  I get them iteratively, too.  */
     62   runp = firstp;
     63   data = NULL;
     64   do
     65     {
     66       Elf_Data *reltgtdata;
     67       Elf_Data *insymdata;
     68       Elf_Data *inxndxdata = NULL;
     69       size_t maxcnt;
     70       size_t cnt;
     71       const Elf32_Word *symindirect;
     72       struct symbol **symref;
     73       struct usedfiles *file = runp->fileinfo;
     74       XElf_Shdr *shdr = &SCNINFO_SHDR (runp->shdr);
     75 
     76       /* Get the output section data buffer for this input section.  */
     77       data = elf_getdata (outscn, data);
     78       assert (data != NULL);
     79 
     80       /* Get the data for section in the input file this relocation
     81 	 section is relocating.  Since these buffers are reused in the
     82 	 output modifying these buffers has the correct result.  */
     83       reltgtdata = elf_getdata (file->scninfo[shdr->sh_info].scn, NULL);
     84 
     85       /* Get the data for the input section symbol table for this
     86 	 relocation section.  */
     87       insymdata = elf_getdata (file->scninfo[shdr->sh_link].scn, NULL);
     88       assert (insymdata != NULL);
     89 
     90       /* And the extended section index table.  */
     91       inxndxdata = runp->fileinfo->xndxdata;
     92 
     93       /* Number of relocations.  */
     94       maxcnt = shdr->sh_size / shdr->sh_entsize;
     95 
     96       /* Array directing local symbol table offsets to output symbol
     97 	 table offsets.  */
     98       symindirect = file->symindirect;
     99 
    100       /* References to the symbol records.  */
    101       symref = file->symref;
    102 
    103       /* Iterate over all the relocations in the section.  */
    104       for (cnt = 0; cnt < maxcnt; ++cnt)
    105 	{
    106 	  XElf_Rel_vardef (rel);
    107 	  Elf32_Word si;
    108 	  XElf_Sym_vardef (sym);
    109 	  Elf32_Word xndx;
    110 
    111 	  /* Get the relocation data itself.  x86 uses Rel
    112 	     relocations.  In case we have to handle Rela as well the
    113 	     whole loop probably should be duplicated.  */
    114 	  xelf_getrel (data, cnt, rel);
    115 	  assert (rel != NULL);
    116 
    117 	  /* Compute the symbol index in the output file.  */
    118 	  si = symindirect[XELF_R_SYM (rel->r_info)];
    119 	  if (si == 0)
    120 	    {
    121 	      /* This happens if the symbol is locally undefined or
    122 		 superceded by some other definition.  */
    123 	      assert (symref[XELF_R_SYM (rel->r_info)] != NULL);
    124 	      si = symref[XELF_R_SYM (rel->r_info)]->outsymidx;
    125 	    }
    126 	  /* Take reordering performed to sort the symbol table into
    127 	     account.  */
    128 	  si = dblindirect[si];
    129 
    130 	  /* Get the symbol table entry.  */
    131 	  xelf_getsymshndx (insymdata, inxndxdata, XELF_R_SYM (rel->r_info),
    132 			    sym, xndx);
    133 	  if (sym->st_shndx != SHN_XINDEX)
    134 	    xndx = sym->st_shndx;
    135 	  assert (xndx < SHN_LORESERVE || xndx > SHN_HIRESERVE);
    136 
    137 	  /* We fortunately don't have to do much.  The relocations
    138 	     mostly get only updates of the offset.  Only is a
    139 	     relocation referred to a section do we have to do
    140 	     something.  In this case the reference to the sections
    141 	     has no direct equivalent since the part the input section
    142 	     contributes need not start at the same offset as in the
    143 	     input file.  Therefore we have to adjust the addend which
    144 	     in the case of Rel relocations is in the target section
    145 	     itself.  */
    146 	  if (XELF_ST_TYPE (sym->st_info) == STT_SECTION)
    147 	    {
    148 	      Elf32_Word toadd;
    149 
    150 	      /* We expect here on R_386_32 relocations.  */
    151 	      assert (XELF_R_TYPE (rel->r_info) == R_386_32);
    152 
    153 	      /* Avoid writing to the section memory if this is
    154 		 effectively a no-op since it might save a
    155 		 copy-on-write operation.  */
    156 	      toadd = file->scninfo[xndx].offset;
    157 	      if (toadd != 0)
    158 		add_4ubyte_unaligned (reltgtdata->d_buf + rel->r_offset,
    159 				      toadd);
    160 	    }
    161 
    162 	  /* Adjust the offset for the position of the input section
    163 	     content in the output section.  */
    164 	  rel->r_offset += file->scninfo[shdr->sh_info].offset;
    165 
    166 	  /* And finally adjust the index of the symbol in the output
    167 	     symbol table.  */
    168 	  rel->r_info = XELF_R_INFO (si, XELF_R_TYPE (rel->r_info));
    169 
    170 	  /* Store the result.  */
    171 	  (void) xelf_update_rel (data, cnt, rel);
    172 	}
    173 
    174       runp = runp->next;
    175     }
    176   while (runp != firstp);
    177 }
    178 
    179 
    180 /* Each PLT entry has 16 bytes.  We need one entry as overhead for
    181    the code to set up the call into the runtime relocation.  */
    182 #define PLT_ENTRY_SIZE 16
    183 
    184 static void
    185 elf_i386_initialize_plt (struct ld_state *statep, Elf_Scn *scn)
    186 {
    187   Elf_Data *data;
    188   XElf_Shdr_vardef (shdr);
    189 
    190   /* Change the entry size in the section header.  */
    191   xelf_getshdr (scn, shdr);
    192   assert (shdr != NULL);
    193   shdr->sh_entsize = PLT_ENTRY_SIZE;
    194   (void) xelf_update_shdr (scn, shdr);
    195 
    196   data = elf_newdata (scn);
    197   if (data == NULL)
    198     error (EXIT_FAILURE, 0, gettext ("cannot allocate PLT section: %s"),
    199 	   elf_errmsg (-1));
    200 
    201   /* We need one special PLT entry (performing the jump to the runtime
    202      relocation routines) and one for each function we call in a DSO.  */
    203   data->d_size = (1 + statep->nplt) * PLT_ENTRY_SIZE;
    204   data->d_buf = xcalloc (1, data->d_size);
    205   data->d_align = 8;
    206   data->d_off = 0;
    207 
    208   statep->nplt_used = 1;
    209 }
    210 
    211 
    212 static void
    213 elf_i386_initialize_pltrel (struct ld_state *statep, Elf_Scn *scn)
    214 {
    215   Elf_Data *data;
    216 
    217   data = elf_newdata (scn);
    218   if (data == NULL)
    219     error (EXIT_FAILURE, 0, gettext ("cannot allocate PLTREL section: %s"),
    220 	   elf_errmsg (-1));
    221 
    222   /* One relocation per PLT entry.  */
    223   data->d_size = statep->nplt * sizeof (Elf32_Rel);
    224   data->d_buf = xcalloc (1, data->d_size);
    225   data->d_type = ELF_T_REL;
    226   data->d_align = 4;
    227   data->d_off = 0;
    228 }
    229 
    230 
    231 static void
    232 elf_i386_initialize_got (struct ld_state *statep, Elf_Scn *scn)
    233 {
    234   Elf_Data *data;
    235 
    236   /* If we have no .plt we don't need the special entries we normally
    237      create for it.  The other contents is created later.  */
    238   if (statep->ngot + statep->nplt == 0)
    239     return;
    240 
    241   data = elf_newdata (scn);
    242   if (data == NULL)
    243     error (EXIT_FAILURE, 0, gettext ("cannot allocate GOT section: %s"),
    244 	   elf_errmsg (-1));
    245 
    246   /* We construct the .got section in pieces.  Here we only add the data
    247      structures which are used by the PLT.  This includes three reserved
    248      entries at the beginning (the first will contain a pointer to the
    249      .dynamic section), and one word for each PLT entry.  */
    250   data->d_size = (3 + statep->ngot + statep->nplt) * sizeof (Elf32_Addr);
    251   data->d_buf = xcalloc (1, data->d_size);
    252   data->d_align = sizeof (Elf32_Addr);
    253   data->d_off = 0;
    254 }
    255 
    256 
    257 /* The first entry in an absolute procedure linkage table looks like
    258    this.  See the SVR4 ABI i386 supplement to see how this works.  */
    259 static const unsigned char elf_i386_plt0_entry[PLT_ENTRY_SIZE] =
    260 {
    261   0xff, 0x35,	/* pushl contents of address */
    262   0, 0, 0, 0,	/* replaced with address of .got + 4.  */
    263   0xff, 0x25,	/* jmp indirect */
    264   0, 0, 0, 0,	/* replaced with address of .got + 8.  */
    265   0, 0, 0, 0	/* pad out to 16 bytes.  */
    266 };
    267 
    268 /* Type describing the first PLT entry in non-PIC.  */
    269 struct plt0_entry
    270 {
    271   /* First a 'push' of the second GOT entry.  */
    272   unsigned char push_instr[2];
    273   uint32_t gotp4_addr;
    274   /* Second, a 'jmp indirect' to the third GOT entry.  */
    275   unsigned char jmp_instr[2];
    276   uint32_t gotp8_addr;
    277   /* Padding.  */
    278   unsigned char padding[4];
    279 } __attribute__ ((packed));
    280 
    281 /* The first entry in a PIC procedure linkage table look like this.  */
    282 static const unsigned char elf_i386_pic_plt0_entry[PLT_ENTRY_SIZE] =
    283 {
    284   0xff, 0xb3, 4, 0, 0, 0,	/* pushl 4(%ebx) */
    285   0xff, 0xa3, 8, 0, 0, 0,	/* jmp *8(%ebx) */
    286   0, 0, 0, 0			/* pad out to 16 bytes.  */
    287 };
    288 
    289 /* Contents of all but the first PLT entry in executable.  */
    290 static const unsigned char elf_i386_plt_entry[PLT_ENTRY_SIZE] =
    291 {
    292   0xff, 0x25,   /* jmp indirect */
    293   0, 0, 0, 0,   /* replaced with address of this symbol in .got.  */
    294   0x68,         /* pushl immediate */
    295   0, 0, 0, 0,   /* replaced with offset into relocation table.  */
    296   0xe9,         /* jmp relative */
    297   0, 0, 0, 0    /* replaced with offset to start of .plt.  */
    298 };
    299 
    300 /* Contents of all but the first PLT entry in DSOs.  */
    301 static const unsigned char elf_i386_pic_plt_entry[PLT_ENTRY_SIZE] =
    302 {
    303   0xff, 0xa3,	/* jmp *offset(%ebx) */
    304   0, 0, 0, 0,	/* replaced with offset of this symbol in .got.  */
    305   0x68,		/* pushl immediate */
    306   0, 0, 0, 0,	/* replaced with offset into relocation table.  */
    307   0xe9,		/* jmp relative */
    308   0, 0, 0, 0	/* replaced with offset to start of .plt.  */
    309 };
    310 
    311 /* Type describing a PLT entry.  */
    312 struct plt_entry
    313 {
    314   /* The first instruction is 'jmp indirect' or 'jmp *offset(%ebs)'.  */
    315   unsigned char jmp_instr[2];
    316   uint32_t offset_got;
    317   /* The second instruction is 'push immediate'.  */
    318   unsigned char push_instr;
    319   uint32_t push_imm;
    320   /* Finally a 'jmp relative'.  */
    321   unsigned char jmp_instr2;
    322   uint32_t plt0_offset;
    323 } __attribute__ ((packed));
    324 
    325 
    326 static void
    327 elf_i386_finalize_plt (struct ld_state *statep, size_t nsym, size_t nsym_dyn)
    328 {
    329   Elf_Scn *scn;
    330   XElf_Shdr_vardef (shdr);
    331   Elf_Data *data;
    332   Elf_Data *symdata = NULL;
    333   Elf_Data *dynsymdata;
    334   size_t cnt;
    335   const bool build_dso = statep->file_type == dso_file_type;
    336 
    337   if (unlikely (statep->nplt + statep->ngot == 0))
    338     /* Nothing to be done.  */
    339     return;
    340 
    341   /* Get the address of the got section.  */
    342   scn = elf_getscn (statep->outelf, statep->gotscnidx);
    343   xelf_getshdr (scn, shdr);
    344   data = elf_getdata (scn, NULL);
    345   assert (shdr != NULL && data != NULL);
    346   Elf32_Addr gotaddr = shdr->sh_addr;
    347 
    348   /* Now create the initial values for the .got section.  The first
    349      word contains the address of the .dynamic section.  */
    350   xelf_getshdr (elf_getscn (statep->outelf, statep->dynamicscnidx), shdr);
    351   assert (shdr != NULL);
    352   ((Elf32_Word *) data->d_buf)[0] = shdr->sh_addr;
    353 
    354   /* The second and third entry are left empty for use by the dynamic
    355      linker.  The following entries are pointers to the instructions
    356      following the initial jmp instruction in the corresponding PLT
    357      entry.  Since the first PLT entry is special the first used one
    358      has the index 1.  */
    359   scn = elf_getscn (statep->outelf, statep->pltscnidx);
    360   xelf_getshdr (scn, shdr);
    361   assert (shdr != NULL);
    362 
    363   dynsymdata = elf_getdata (elf_getscn (statep->outelf, statep->dynsymscnidx),
    364 			    NULL);
    365   assert (dynsymdata != NULL);
    366 
    367   if (statep->symscnidx != 0)
    368     {
    369       symdata = elf_getdata (elf_getscn (statep->outelf, statep->symscnidx),
    370 			     NULL);
    371       assert (symdata != NULL);
    372     }
    373 
    374   for (cnt = 0; cnt < statep->nplt; ++cnt)
    375     {
    376       assert ((4 + cnt) * sizeof (Elf32_Word) <= data->d_size);
    377 
    378       /* Address in the PLT.  */
    379       Elf32_Addr pltentryaddr = shdr->sh_addr + (1 + cnt) * PLT_ENTRY_SIZE;
    380 
    381       /* Point the GOT entry at the PLT entry, after the initial jmp.  */
    382       ((Elf32_Word *) data->d_buf)[3 + cnt] = pltentryaddr + 6;
    383 
    384       /* The value of the symbol is the address of the corresponding PLT
    385 	 entry.  Store the address, also for the normal symbol table if
    386 	 this is necessary.  */
    387       ((Elf32_Sym *) dynsymdata->d_buf)[1 + cnt].st_value = pltentryaddr;
    388 
    389       if (symdata != NULL)
    390 	((Elf32_Sym *) symdata->d_buf)[nsym - statep->nplt + cnt].st_value
    391 	  = pltentryaddr;
    392     }
    393 
    394   /* Create the .plt section.  */
    395   scn = elf_getscn (statep->outelf, statep->pltscnidx);
    396   data = elf_getdata (scn, NULL);
    397   assert (data != NULL);
    398 
    399   /* Create the first entry.  */
    400   assert (data->d_size >= PLT_ENTRY_SIZE);
    401   if (build_dso)
    402     /* Copy the entry.  It's complete, no relocation needed.  */
    403     memcpy (data->d_buf, elf_i386_pic_plt0_entry, PLT_ENTRY_SIZE);
    404   else
    405     {
    406       /* Copy the skeleton.  */
    407       memcpy (data->d_buf, elf_i386_plt0_entry, PLT_ENTRY_SIZE);
    408 
    409       /* And fill in the addresses.  */
    410       struct plt0_entry *addr = (struct plt0_entry *) data->d_buf;
    411       addr->gotp4_addr = target_bswap_32 (gotaddr + 4);
    412       addr->gotp8_addr = target_bswap_32 (gotaddr + 8);
    413     }
    414 
    415   /* For DSOs we need GOT offsets, otherwise the GOT address.  */
    416   Elf32_Addr gotaddr_off = build_dso ? 0 : gotaddr;
    417 
    418   /* Create the remaining entries.  */
    419   const unsigned char *plt_template
    420     = build_dso ? elf_i386_pic_plt_entry : elf_i386_plt_entry;
    421 
    422   for (cnt = 0; cnt < statep->nplt; ++cnt)
    423     {
    424       struct plt_entry *addr;
    425 
    426       /* Copy the template.  */
    427       assert (data->d_size >= (2 + cnt) * PLT_ENTRY_SIZE);
    428       addr = (struct plt_entry *) ((char *) data->d_buf
    429 				   + (1 + cnt) * PLT_ENTRY_SIZE);
    430       memcpy (addr, plt_template, PLT_ENTRY_SIZE);
    431 
    432       /* And once more, fill in the addresses.  First the address of
    433 	 this symbol in .got.  */
    434       addr->offset_got = target_bswap_32 (gotaddr_off
    435 					  + (3 + cnt) * sizeof (Elf32_Addr));
    436       /* Offset into relocation table.  */
    437       addr->push_imm = target_bswap_32 (cnt * sizeof (Elf32_Rel));
    438       /* Offset to start of .plt.  */
    439       addr->plt0_offset = target_bswap_32 (-(2 + cnt) * PLT_ENTRY_SIZE);
    440     }
    441 
    442   /* Create the .rel.plt section data.  It simply means relocations
    443      addressing the corresponding entry in the .got section.  The
    444      section name is misleading.  */
    445   scn = elf_getscn (statep->outelf, statep->pltrelscnidx);
    446   xelf_getshdr (scn, shdr);
    447   data = elf_getdata (scn, NULL);
    448   assert (shdr != NULL && data != NULL);
    449 
    450   /* Update the sh_link to point to the section being modified.  We
    451      point it here (correctly) to the .got section.  Some linkers
    452      (e.g., the GNU binutils linker) point to the .plt section.  This
    453      is wrong since the .plt section isn't modified even though the
    454      name .rel.plt suggests that this is correct.  */
    455   shdr->sh_link = statep->dynsymscnidx;
    456   shdr->sh_info = statep->gotscnidx;
    457   (void) xelf_update_shdr (scn, shdr);
    458 
    459   for (cnt = 0; cnt < statep->nplt; ++cnt)
    460     {
    461       XElf_Rel_vardef (rel);
    462 
    463       assert ((1 + cnt) * sizeof (Elf32_Rel) <= data->d_size);
    464       xelf_getrel_ptr (data, cnt, rel);
    465       rel->r_offset = gotaddr + (3 + cnt) * sizeof (Elf32_Addr);
    466       /* The symbol table entries for the functions from DSOs are at
    467 	 the end of the symbol table.  */
    468       rel->r_info = XELF_R_INFO (1 + cnt, R_386_JMP_SLOT);
    469       (void) xelf_update_rel (data, cnt, rel);
    470     }
    471 }
    472 
    473 
    474 static int
    475 elf_i386_rel_type (struct ld_state *statep __attribute__ ((__unused__)))
    476 {
    477   /* ELF/i386 uses REL.  */
    478   return DT_REL;
    479 }
    480 
    481 
    482 static void
    483 elf_i386_count_relocations (struct ld_state *statep, struct scninfo *scninfo)
    484 {
    485   /* We go through the list of input sections and count those relocations
    486      which are not handled by the linker.  At the same time we have to
    487      see how many GOT entries we need and how much .bss space is needed
    488      for copy relocations.  */
    489   Elf_Data *data = elf_getdata (scninfo->scn, NULL);
    490   XElf_Shdr *shdr = &SCNINFO_SHDR (scninfo->shdr);
    491   size_t maxcnt = shdr->sh_size / shdr->sh_entsize;
    492   size_t relsize = 0;
    493   size_t cnt;
    494   struct symbol *sym;
    495 
    496   assert (shdr->sh_type == SHT_REL);
    497 
    498   for (cnt = 0; cnt < maxcnt; ++cnt)
    499     {
    500       XElf_Rel_vardef (rel);
    501 
    502       xelf_getrel (data, cnt, rel);
    503       /* XXX Should we complain about failing accesses?  */
    504       if (rel != NULL)
    505 	{
    506 	  int r_sym = XELF_R_SYM (rel->r_info);
    507 
    508 	  switch (XELF_R_TYPE (rel->r_info))
    509 	    {
    510 	    case R_386_GOT32:
    511 	      if (! scninfo->fileinfo->symref[r_sym]->defined)
    512 		relsize += sizeof (Elf32_Rel);
    513 
    514 	      /* This relocation is not emitted in the output file but
    515 		 requires a GOT entry.  */
    516 	      ++statep->ngot;
    517 	      ++statep->nrel_got;
    518 
    519 	      /* FALLTHROUGH */
    520 
    521 	    case R_386_GOTOFF:
    522 	    case R_386_GOTPC:
    523 	      statep->need_got = true;
    524 	      break;
    525 
    526 	    case R_386_32:
    527 	    case R_386_PC32:
    528 	      /* These relocations cause text relocations in DSOs.  */
    529 	      if (linked_from_dso_p (scninfo, r_sym))
    530 		{
    531 		  if (statep->file_type == dso_file_type)
    532 		    {
    533 		      relsize += sizeof (Elf32_Rel);
    534 		      statep->dt_flags |= DF_TEXTREL;
    535 		    }
    536 		  else
    537 		    {
    538 		      /* Non-function objects from a DSO need to get a
    539 			 copy relocation.  */
    540 		      sym = scninfo->fileinfo->symref[r_sym];
    541 
    542 		      /* Only do this if we have not requested a copy
    543 			 relocation already.  */
    544 		      if (unlikely (sym->type != STT_FUNC) && ! sym->need_copy)
    545 			{
    546 			  sym->need_copy = 1;
    547 			  ++statep->ncopy;
    548 			  relsize += sizeof (Elf32_Rel);
    549 			}
    550 		    }
    551 		}
    552 	      else if (statep->file_type == dso_file_type
    553 		       && r_sym >= SCNINFO_SHDR (scninfo->fileinfo->scninfo[shdr->sh_link].shdr).sh_info
    554 		       && scninfo->fileinfo->symref[r_sym]->outdynsymidx != 0
    555 		       && XELF_R_TYPE (rel->r_info) == R_386_32)
    556 		relsize += sizeof (Elf32_Rel);
    557 	      break;
    558 
    559 	    case R_386_PLT32:
    560 	      /* We might need a PLT entry.  But we cannot say for sure
    561 		 here since one of the symbols might turn up being
    562 		 defined in the executable (if we create such a thing).
    563 		 If a DSO is created we still might use a local
    564 		 definition.
    565 
    566 		 If the symbol is not defined and we are not creating
    567 		 a statically linked binary, then we need in any case
    568 		 a PLT entry.  */
    569 	      if (! scninfo->fileinfo->symref[r_sym]->defined)
    570 		{
    571 		  assert (!statep->statically);
    572 
    573 		  sym = scninfo->fileinfo->symref[r_sym];
    574 		  sym->type = STT_FUNC;
    575 		  sym->in_dso = 1;
    576 		  sym->defined = 1;
    577 
    578 		  /* Remove from the list of unresolved symbols.  */
    579 		  --statep->nunresolved;
    580 		  if (! sym->weak)
    581 		    --statep->nunresolved_nonweak;
    582 		  CDBL_LIST_DEL (statep->unresolved, sym);
    583 
    584 		  /* Add to the list of symbols we expect from a DSO.  */
    585 		  ++statep->nplt;
    586 		  ++statep->nfrom_dso;
    587 		  CDBL_LIST_ADD_REAR (statep->from_dso, sym);
    588 		}
    589 	      break;
    590 
    591 	    case R_386_TLS_GD:
    592 	    case R_386_TLS_LDM:
    593 	    case R_386_TLS_GD_32:
    594 	    case R_386_TLS_GD_PUSH:
    595 	    case R_386_TLS_GD_CALL:
    596 	    case R_386_TLS_GD_POP:
    597 	    case R_386_TLS_LDM_32:
    598 	    case R_386_TLS_LDM_PUSH:
    599 	    case R_386_TLS_LDM_CALL:
    600 	    case R_386_TLS_LDM_POP:
    601 	    case R_386_TLS_LDO_32:
    602 	    case R_386_TLS_IE_32:
    603 	    case R_386_TLS_LE_32:
    604 	      /* XXX */
    605 	      abort ();
    606 	      break;
    607 
    608 	    case R_386_NONE:
    609 	      /* Nothing to be done.  */
    610 	      break;
    611 
    612 	      /* These relocation should never be generated by an
    613 		 assembler.  */
    614 	    case R_386_COPY:
    615 	    case R_386_GLOB_DAT:
    616 	    case R_386_JMP_SLOT:
    617 	    case R_386_RELATIVE:
    618 	    case R_386_TLS_DTPMOD32:
    619 	    case R_386_TLS_DTPOFF32:
    620 	    case R_386_TLS_TPOFF32:
    621 	      /* Unknown relocation.  */
    622 	    default:
    623 	      abort ();
    624 	    }
    625 	}
    626     }
    627 
    628   scninfo->relsize = relsize;
    629 }
    630 
    631 
    632 static void
    633 elf_i386_create_relocations (struct ld_state *statep,
    634 			     const Elf32_Word *dblindirect)
    635 {
    636   /* Get the address of the got section.  */
    637   Elf_Scn *pltscn = elf_getscn (statep->outelf, statep->pltscnidx);
    638   Elf32_Shdr *shdr = elf32_getshdr (pltscn);
    639   assert (shdr != NULL);
    640   Elf32_Addr pltaddr = shdr->sh_addr;
    641 
    642   Elf_Scn *gotscn = elf_getscn (statep->outelf, statep->gotscnidx);
    643   shdr = elf32_getshdr (gotscn);
    644   assert (shdr != NULL);
    645   Elf32_Addr gotaddr = shdr->sh_addr;
    646 
    647   Elf_Scn *reldynscn = elf_getscn (statep->outelf, statep->reldynscnidx);
    648   Elf_Data *reldyndata = elf_getdata (reldynscn, NULL);
    649 
    650   size_t nreldyn = 0;
    651 #define ngot_used (3 + statep->nplt + nreldyn)
    652 
    653   struct scninfo *first = statep->rellist->next;
    654   struct scninfo *runp = first;
    655   do
    656     {
    657       XElf_Shdr *rshdr = &SCNINFO_SHDR (runp->shdr);
    658       Elf_Data *reldata = elf_getdata (runp->scn, NULL);
    659       int nrels = rshdr->sh_size / rshdr->sh_entsize;
    660 
    661       /* We will need the following vlaues a couple of times.  Help
    662 	 the compiler and improve readability.  */
    663       struct symbol **symref = runp->fileinfo->symref;
    664       struct scninfo *scninfo = runp->fileinfo->scninfo;
    665 
    666       /* This is the offset of the input section we are looking at in
    667 	 the output file.  */
    668       XElf_Addr inscnoffset = scninfo[rshdr->sh_info].offset;
    669 
    670       /* The target section.  We use the data from the input file.  */
    671       Elf_Data *data = elf_getdata (scninfo[rshdr->sh_info].scn, NULL);
    672 
    673       /* We cannot handle relocations against merge-able sections.  */
    674       assert ((SCNINFO_SHDR (scninfo[rshdr->sh_link].shdr).sh_flags
    675 	       & SHF_MERGE) == 0);
    676 
    677       /* Cache the access to the symbol table data.  */
    678       Elf_Data *symdata = elf_getdata (scninfo[rshdr->sh_link].scn, NULL);
    679 
    680       int cnt;
    681       for (cnt = 0; cnt < nrels; ++cnt)
    682 	{
    683 	  XElf_Rel_vardef (rel);
    684 	  XElf_Rel *rel2;
    685 	  xelf_getrel (reldata, cnt, rel);
    686 	  assert (rel != NULL);
    687 	  XElf_Addr reladdr = inscnoffset + rel->r_offset;
    688 	  XElf_Addr value;
    689 
    690 	  size_t idx = XELF_R_SYM (rel->r_info);
    691 	  if (idx < runp->fileinfo->nlocalsymbols)
    692 	    {
    693 	      XElf_Sym_vardef (sym);
    694 	      xelf_getsym (symdata, idx, sym);
    695 
    696 	      /* The value just depends on the position of the referenced
    697 		 section in the output file and the addend.  */
    698 	      value = scninfo[sym->st_shndx].offset + sym->st_value;
    699 	    }
    700 	  else if (symref[idx]->in_dso)
    701 	    {
    702 	      /* MERGE.VALUE contains the PLT index.  We have to add 1 since
    703 		 there is this one special PLT entry at the beginning.  */
    704 	      assert (symref[idx]->merge.value != 0
    705 		      || symref[idx]->type != STT_FUNC);
    706 	      value = pltaddr + symref[idx]->merge.value * PLT_ENTRY_SIZE;
    707 	    }
    708 	  else
    709 	    value = symref[idx]->merge.value;
    710 
    711 	  /* Address of the relocated memory in the data buffer.  */
    712 	  void *relloc = (char *) data->d_buf + rel->r_offset;
    713 
    714 	  switch (XELF_R_TYPE (rel->r_info))
    715 	    {
    716 	      /* These three cases can be handled together since the
    717 		 symbol associated with the R_386_GOTPC relocation is
    718 		 _GLOBAL_OFFSET_TABLE_ which has a value corresponding
    719 		 to the address of the GOT and the address of the PLT
    720 		 entry required for R_386_PLT32 is computed above.  */
    721 	    case R_386_PC32:
    722 	    case R_386_GOTPC:
    723 	    case R_386_PLT32:
    724 	      value -= reladdr;
    725 	      /* FALLTHROUGH */
    726 
    727 	    case R_386_32:
    728 	      if (linked_from_dso_p (scninfo, idx)
    729 		  && statep->file_type != dso_file_type
    730 		  && symref[idx]->type != STT_FUNC)
    731 		{
    732 		  value = (ld_state.copy_section->offset
    733 			   + symref[idx]->merge.value);
    734 
    735 		  if (unlikely (symref[idx]->need_copy))
    736 		    {
    737 		      /* Add a relocation to initialize the GOT entry.  */
    738 		      assert (symref[idx]->outdynsymidx != 0);
    739 #if NATIVE_ELF != 0
    740 		      xelf_getrel_ptr (reldyndata, nreldyn, rel2);
    741 #else
    742 		      rel2 = &rel_mem;
    743 #endif
    744 		      rel2->r_offset = value;
    745 		      rel2->r_info
    746 			= XELF_R_INFO (symref[idx]->outdynsymidx, R_386_COPY);
    747 		      (void) xelf_update_rel (reldyndata, nreldyn, rel2);
    748 		      ++nreldyn;
    749 
    750 		      /* Update the symbol table record for the new
    751 			 address.  */
    752 		      Elf32_Word symidx = symref[idx]->outdynsymidx;
    753 		      Elf_Scn *symscn = elf_getscn (statep->outelf,
    754 						    statep->dynsymscnidx);
    755 		      Elf_Data *outsymdata = elf_getdata (symscn, NULL);
    756 		      assert (outsymdata != NULL);
    757 		      XElf_Sym_vardef (sym);
    758 		      xelf_getsym (outsymdata, symidx, sym);
    759 		      sym->st_value = value;
    760 		      sym->st_shndx = statep->copy_section->outscnndx;
    761 		      (void) xelf_update_sym (outsymdata, symidx, sym);
    762 
    763 		      symidx = symref[idx]->outsymidx;
    764 		      if (symidx != 0)
    765 			{
    766 			  symidx = statep->dblindirect[symidx];
    767 			  symscn = elf_getscn (statep->outelf,
    768 					       statep->symscnidx);
    769 			  outsymdata = elf_getdata (symscn, NULL);
    770 			  assert (outsymdata != NULL);
    771 			  xelf_getsym (outsymdata, symidx, sym);
    772 			  sym->st_value = value;
    773 			  sym->st_shndx = statep->copy_section->outscnndx;
    774 			  (void) xelf_update_sym (outsymdata, symidx, sym);
    775 			}
    776 
    777 		      /* Remember that we set up the copy relocation.  */
    778 		      symref[idx]->need_copy = 0;
    779 		    }
    780 		}
    781 	      else if (statep->file_type == dso_file_type
    782 		       && idx >= SCNINFO_SHDR (scninfo[rshdr->sh_link].shdr).sh_info
    783 		       && symref[idx]->outdynsymidx != 0)
    784 		{
    785 #if NATIVE_ELF != 0
    786 		  xelf_getrel_ptr (reldyndata, nreldyn, rel2);
    787 #else
    788 		  rel2 = &rel_mem;
    789 #endif
    790 		  rel2->r_offset = value;
    791 		  rel2->r_info
    792 		    = XELF_R_INFO (symref[idx]->outdynsymidx, R_386_32);
    793 		  (void) xelf_update_rel (reldyndata, nreldyn, rel2);
    794 		  ++nreldyn;
    795 
    796 		  value = 0;
    797 		}
    798 	      add_4ubyte_unaligned (relloc, value);
    799 	      break;
    800 
    801 	    case R_386_GOT32:
    802 	      store_4ubyte_unaligned (relloc, ngot_used * sizeof (Elf32_Addr));
    803 
    804 	      /* Add a relocation to initialize the GOT entry.  */
    805 #if NATIVE_ELF != 0
    806 	      xelf_getrel_ptr (reldyndata, nreldyn, rel2);
    807 #else
    808 	      rel2 = &rel_mem;
    809 #endif
    810 	      rel2->r_offset = gotaddr + ngot_used * sizeof (Elf32_Addr);
    811 	      rel2->r_info
    812 		= XELF_R_INFO (symref[idx]->outdynsymidx, R_386_GLOB_DAT);
    813 	      (void) xelf_update_rel (reldyndata, nreldyn, rel2);
    814 	      ++nreldyn;
    815 	      break;
    816 
    817 	    case R_386_GOTOFF:
    818 	      add_4ubyte_unaligned (relloc, value - gotaddr);
    819 	      break;
    820 
    821 	    case R_386_32PLT:
    822 	    case R_386_TLS_TPOFF:
    823 	    case R_386_TLS_IE:
    824 	    case R_386_TLS_GOTIE:
    825 	    case R_386_TLS_LE:
    826 	    case R_386_TLS_GD:
    827 	    case R_386_TLS_LDM:
    828 	    case R_386_16:
    829 	    case R_386_PC16:
    830 	    case R_386_8:
    831 	    case R_386_PC8:
    832 	    case R_386_TLS_GD_32:
    833 	    case R_386_TLS_GD_PUSH:
    834 	    case R_386_TLS_GD_CALL:
    835 	    case R_386_TLS_GD_POP:
    836 	    case R_386_TLS_LDM_32:
    837 	    case R_386_TLS_LDM_PUSH:
    838 	    case R_386_TLS_LDM_CALL:
    839 	    case R_386_TLS_LDM_POP:
    840 	    case R_386_TLS_LDO_32:
    841 	    case R_386_TLS_IE_32:
    842 	    case R_386_TLS_LE_32:
    843 	      // XXX For now fall through
    844  printf("ignored relocation %d\n", (int) XELF_R_TYPE (rel->r_info));
    845 	      break;
    846 
    847 	    case R_386_NONE:
    848 	      /* Nothing to do.  */
    849 	      break;
    850 
    851 	    case R_386_COPY:
    852 	    case R_386_JMP_SLOT:
    853 	    case R_386_RELATIVE:
    854 	    case R_386_GLOB_DAT:
    855 	    case R_386_TLS_DTPMOD32:
    856 	    case R_386_TLS_DTPOFF32:
    857 	    case R_386_TLS_TPOFF32:
    858 	    default:
    859 	      /* Should not happen.  */
    860 	      abort ();
    861 	    }
    862 	}
    863     }
    864   while ((runp = runp->next) != first);
    865 }
    866 
    867 
    868 int
    869 elf_i386_ld_init (struct ld_state *statep)
    870 {
    871   /* We have a few callbacks available.  */
    872   old_open_outfile = statep->callbacks.open_outfile;
    873   statep->callbacks.open_outfile = elf_i386_open_outfile;
    874 
    875   statep->callbacks.relocate_section  = elf_i386_relocate_section;
    876 
    877   statep->callbacks.initialize_plt = elf_i386_initialize_plt;
    878   statep->callbacks.initialize_pltrel = elf_i386_initialize_pltrel;
    879 
    880   statep->callbacks.initialize_got = elf_i386_initialize_got;
    881 
    882   statep->callbacks.finalize_plt = elf_i386_finalize_plt;
    883 
    884   statep->callbacks.rel_type = elf_i386_rel_type;
    885 
    886   statep->callbacks.count_relocations = elf_i386_count_relocations;
    887 
    888   statep->callbacks.create_relocations = elf_i386_create_relocations;
    889 
    890   return 0;
    891 }
    892