• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (C) 2001, 2002, 2003, 2004 Red Hat, Inc.
2    Written by Ulrich Drepper <drepper@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
elf_i386_open_outfile(struct ld_state * statep,int machine,int klass,int data)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
elf_i386_relocate_section(struct ld_state * statep,Elf_Scn * outscn,struct scninfo * firstp,const Elf32_Word * dblindirect)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
elf_i386_initialize_plt(struct ld_state * statep,Elf_Scn * scn)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
elf_i386_initialize_pltrel(struct ld_state * statep,Elf_Scn * scn)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
elf_i386_initialize_got(struct ld_state * statep,Elf_Scn * scn)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
elf_i386_finalize_plt(struct ld_state * statep,size_t nsym,size_t nsym_dyn)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
elf_i386_rel_type(struct ld_state * statep)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
elf_i386_count_relocations(struct ld_state * statep,struct scninfo * scninfo)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
elf_i386_create_relocations(struct ld_state * statep,const Elf32_Word * dblindirect)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
elf_i386_ld_init(struct ld_state * statep)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