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