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