1 /* Copyright (C) 2001, 2002, 2004, 2009 Red Hat, Inc.
2 Written by Jakub Jelinek <jakub@redhat.com>, 2001.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
32 sparc_adjust_dyn (DSO *dso, int n, GElf_Dyn *dyn, GElf_Addr start,
35 if (dyn->d_tag == DT_PLTGOT)
39 for (i = 1; i < dso->ehdr.e_shnum; ++i)
40 if (! strcmp (strptr (dso, dso->ehdr.e_shstrndx,
41 dso->shdr[i].sh_name), ".got"))
45 data = read_ube32 (dso, dso->shdr[i].sh_addr);
46 /* .got[0] points to _DYNAMIC, it needs to be adjusted. */
47 if (data == dso->shdr[n].sh_addr && data >= start)
48 write_be32 (dso, dso->shdr[i].sh_addr, data + adjust);
57 sparc_adjust_rel (DSO *dso, GElf_Rel *rel, GElf_Addr start,
60 error (0, 0, "%s: Sparc doesn't support REL relocs", dso->filename);
65 sparc_adjust_rela (DSO *dso, GElf_Rela *rela, GElf_Addr start,
68 if (GELF_R_TYPE (rela->r_info) == R_SPARC_RELATIVE)
72 if ((Elf32_Addr) rela->r_addend >= start)
73 rela->r_addend += (Elf32_Sword) adjust;
77 GElf_Addr val = read_ube32 (dso, rela->r_offset);
80 write_be32 (dso, rela->r_offset, val + adjust);
87 sparc_prelink_rel (struct prelink_info *info, GElf_Rel *rel,
90 error (0, 0, "%s: Sparc doesn't support REL relocs", info->dso->filename);
95 sparc_fixup_plt (DSO *dso, GElf_Rela *rela, GElf_Addr value)
97 Elf32_Sword disp = value - rela->r_offset;
99 if (disp >= -0x800000 && disp < 0x800000)
104 write_be32 (dso, rela->r_offset, 0x30800000 | ((disp >> 2) & 0x3fffff));
105 write_be32 (dso, rela->r_offset + 4, 0x01000000);
106 write_be32 (dso, rela->r_offset + 8, 0x01000000);
110 /* sethi %hi(value), %g1
111 jmpl %g1 + %lo(value), %g0
113 write_be32 (dso, rela->r_offset, 0x03000000 | ((value >> 10) & 0x3fffff));
114 write_be32 (dso, rela->r_offset + 4, 0x81c06000 | (value & 0x3ff));
115 write_be32 (dso, rela->r_offset + 8, 0x01000000);
120 sparc_prelink_rela (struct prelink_info *info, GElf_Rela *rela,
123 DSO *dso = info->dso;
126 if (GELF_R_TYPE (rela->r_info) == R_SPARC_NONE)
128 else if (GELF_R_TYPE (rela->r_info) == R_SPARC_RELATIVE)
130 /* 32-bit SPARC handles RELATIVE relocs as
131 *(int *)rela->r_offset += l_addr + rela->r_addend.
132 RELATIVE relocs against .got traditionally used to have the
133 addend in memory pointed by r_offset and 0 r_addend,
134 other RELATIVE relocs and more recent .got RELATIVE relocs
135 too have 0 in memory and non-zero r_addend. For prelinking,
136 we need the value in memory to be already relocated for
137 l_addr == 0 case, so we have to make sure r_addend will be 0. */
138 if (rela->r_addend == 0)
140 value = read_ube32 (dso, rela->r_offset);
141 value += rela->r_addend;
143 write_be32 (dso, rela->r_offset, value);
144 /* Tell prelink_rela routine it should update the relocation. */
147 value = info->resolve (info, GELF_R_SYM (rela->r_info),
148 GELF_R_TYPE (rela->r_info));
149 value += rela->r_addend;
150 switch (GELF_R_TYPE (rela->r_info))
152 case R_SPARC_GLOB_DAT:
155 write_be32 (dso, rela->r_offset, value);
157 case R_SPARC_JMP_SLOT:
158 sparc_fixup_plt (dso, rela, value);
161 write_8 (dso, rela->r_offset, value);
165 write_be16 (dso, rela->r_offset, value);
168 write_be32 (dso, rela->r_offset,
169 (value & 0x3ff) | (read_ube32 (dso, rela->r_offset) & ~0x3ff));
172 write_be32 (dso, rela->r_offset,
173 ((value >> 10) & 0x3fffff)
174 | (read_ube32 (dso, rela->r_offset) & 0xffc00000));
177 write_8 (dso, rela->r_offset, value - rela->r_offset);
180 write_be16 (dso, rela->r_offset, value - rela->r_offset);
183 write_be32 (dso, rela->r_offset, value - rela->r_offset);
185 case R_SPARC_WDISP30:
186 write_be32 (dso, rela->r_offset,
187 (((value - rela->r_offset) >> 2) & 0x3fffffff)
188 | (read_ube32 (dso, rela->r_offset) & 0xc0000000));
190 case R_SPARC_TLS_DTPOFF32:
191 write_be32 (dso, rela->r_offset, value + rela->r_addend);
193 /* DTPMOD32 and TPOFF32 is impossible to predict in shared libraries
194 unless prelink sets the rules. */
195 case R_SPARC_TLS_DTPMOD32:
196 if (dso->ehdr.e_type == ET_EXEC)
198 error (0, 0, "%s: R_SPARC_TLS_DTPMOD32 reloc in executable?",
203 case R_SPARC_TLS_TPOFF32:
204 if (dso->ehdr.e_type == ET_EXEC && info->resolvetls)
205 write_be32 (dso, rela->r_offset,
206 value + rela->r_addend - info->resolvetls->offset);
208 case R_SPARC_TLS_LE_HIX22:
209 if (dso->ehdr.e_type == ET_EXEC && info->resolvetls)
210 write_be32 (dso, rela->r_offset,
211 (read_ube32 (dso, rela->r_offset) & 0xffc00000)
212 | (((~(value + rela->r_addend - info->resolvetls->offset))
215 case R_SPARC_TLS_LE_LOX10:
216 if (dso->ehdr.e_type == ET_EXEC && info->resolvetls)
217 write_be32 (dso, rela->r_offset,
218 (read_ube32 (dso, rela->r_offset) & 0xffffe000) | 0x1c00
219 | ((value + rela->r_addend - info->resolvetls->offset)
223 if (dso->ehdr.e_type == ET_EXEC)
224 /* COPY relocs are handled specially in generic code. */
226 error (0, 0, "%s: R_SPARC_COPY reloc in shared library?", dso->filename);
229 error (0, 0, "%s: Unknown sparc relocation type %d", dso->filename,
230 (int) GELF_R_TYPE (rela->r_info));
237 sparc_apply_conflict_rela (struct prelink_info *info, GElf_Rela *rela,
238 char *buf, GElf_Addr dest_addr)
240 switch (GELF_R_TYPE (rela->r_info))
244 buf_write_be32 (buf, rela->r_addend);
248 buf_write_be16 (buf, rela->r_addend);
251 buf_write_8 (buf, rela->r_addend);
260 sparc_apply_rel (struct prelink_info *info, GElf_Rel *rel, char *buf)
262 error (0, 0, "%s: Sparc doesn't support REL relocs", info->dso->filename);
267 sparc_apply_rela (struct prelink_info *info, GElf_Rela *rela, char *buf)
271 value = info->resolve (info, GELF_R_SYM (rela->r_info),
272 GELF_R_TYPE (rela->r_info));
273 value += rela->r_addend;
274 switch (GELF_R_TYPE (rela->r_info))
279 value -= rela->r_offset;
280 case R_SPARC_GLOB_DAT:
283 buf_write_be32 (buf, value);
286 value -= rela->r_offset;
289 buf_write_be16 (buf, value);
292 value -= rela->r_offset;
294 buf_write_8 (buf, value);
297 buf_write_be32 (buf, (buf_read_ube32 (buf) & ~0x3ff) | (value & 0x3ff));
300 buf_write_be32 (buf, (buf_read_ube32 (buf) & 0xffc00000)
301 | ((value >> 10) & 0x3fffff));
303 case R_SPARC_WDISP30:
304 buf_write_be32 (buf, (buf_read_ube32 (buf) & 0xc0000000)
305 | (((value - rela->r_offset) >> 2) & 0x3fffffff));
307 case R_SPARC_RELATIVE:
308 error (0, 0, "%s: R_SPARC_RELATIVE in ET_EXEC object?",
309 info->dso->filename);
318 sparc_prelink_conflict_rel (DSO *dso, struct prelink_info *info,
319 GElf_Rel *rel, GElf_Addr reladdr)
321 error (0, 0, "%s: Sparc doesn't support REL relocs", dso->filename);
326 sparc_prelink_conflict_rela (DSO *dso, struct prelink_info *info,
327 GElf_Rela *rela, GElf_Addr relaaddr)
330 struct prelink_conflict *conflict;
331 struct prelink_tls *tls;
335 if (GELF_R_TYPE (rela->r_info) == R_SPARC_RELATIVE
336 || GELF_R_TYPE (rela->r_info) == R_SPARC_NONE
338 /* Fast path: nothing to do. */
340 conflict = prelink_conflict (info, GELF_R_SYM (rela->r_info),
341 GELF_R_TYPE (rela->r_info));
342 if (conflict == NULL)
344 if (info->curtls == NULL)
346 switch (GELF_R_TYPE (rela->r_info))
348 /* Even local DTPMOD32 and TPOFF32 relocs need conflicts. */
349 case R_SPARC_TLS_DTPMOD32:
350 case R_SPARC_TLS_TPOFF32:
351 case R_SPARC_TLS_LE_HIX22:
352 case R_SPARC_TLS_LE_LOX10:
359 else if (conflict->ifunc)
361 error (0, 0, "%s: STT_GNU_IFUNC not handled on SPARC yet",
367 /* DTPOFF32 wants to see only real conflicts, not lookups
368 with reloc_class RTYPE_CLASS_TLS. */
369 if (GELF_R_TYPE (rela->r_info) == R_SPARC_TLS_DTPOFF32
370 && conflict->lookup.tls == conflict->conflict.tls
371 && conflict->lookupval == conflict->conflictval)
374 value = conflict_lookup_value (conflict);
376 ret = prelink_conflict_add_rela (info);
379 ret->r_offset = rela->r_offset;
380 value += rela->r_addend;
381 r_type = GELF_R_TYPE (rela->r_info);
385 value -= rela->r_offset;
386 case R_SPARC_GLOB_DAT:
391 value -= rela->r_offset;
396 value -= rela->r_offset;
400 /* Attempt to transform all reloc which read-modify-write into
403 value = (read_ube32 (dso, rela->r_offset) & ~0x3ff) | (value & 0x3ff);
407 value = (read_ube32 (dso, rela->r_offset) & 0xffc00000)
408 | ((value >> 10) & 0x3fffff);
411 case R_SPARC_WDISP30:
412 value = (read_ube32 (dso, rela->r_offset) & 0xc0000000)
413 | (((value - rela->r_offset) >> 2) & 0x3fffffff);
418 case R_SPARC_JMP_SLOT:
420 case R_SPARC_TLS_DTPMOD32:
421 case R_SPARC_TLS_DTPOFF32:
422 case R_SPARC_TLS_TPOFF32:
423 case R_SPARC_TLS_LE_HIX22:
424 case R_SPARC_TLS_LE_LOX10:
426 && (conflict->reloc_class != RTYPE_CLASS_TLS
427 || conflict->lookup.tls == NULL))
429 error (0, 0, "%s: TLS reloc not resolving to STT_TLS symbol",
434 tls = conflict ? conflict->lookup.tls : info->curtls;
435 switch (GELF_R_TYPE (rela->r_info))
437 case R_SPARC_TLS_DTPMOD32:
440 case R_SPARC_TLS_DTPOFF32:
442 case R_SPARC_TLS_TPOFF32:
443 value -= tls->offset;
445 case R_SPARC_TLS_LE_HIX22:
446 value -= tls->offset;
447 value = (read_ube32 (dso, rela->r_offset) & 0xffc00000)
448 | (((~value) >> 10) & 0x3fffff);
450 case R_SPARC_TLS_LE_LOX10:
451 value -= tls->offset;
452 value = (read_ube32 (dso, rela->r_offset) & 0xffffe000) | 0x1c00
458 error (0, 0, "%s: Unknown Sparc relocation type %d", dso->filename,
462 ret->r_info = GELF_R_INFO (0, r_type);
463 ret->r_addend = (Elf32_Sword) value;
468 sparc_rel_to_rela (DSO *dso, GElf_Rel *rel, GElf_Rela *rela)
470 error (0, 0, "%s: Sparc doesn't support REL relocs", dso->filename);
475 sparc_need_rel_to_rela (DSO *dso, int first, int last)
481 sparc_arch_prelink (struct prelink_info *info)
487 sparc_undo_prelink_rela (DSO *dso, GElf_Rela *rela, GElf_Addr relaaddr)
491 switch (GELF_R_TYPE (rela->r_info))
495 case R_SPARC_RELATIVE:
496 /* 32-bit SPARC handles RELATIVE relocs as
497 *(int *)rela->r_offset += l_addr + rela->r_addend.
498 RELATIVE relocs against .got traditionally used to have the
499 addend in memory pointed by r_offset and 0 r_addend,
500 other RELATIVE relocs and more recent RELATIVE relocs have 0
501 in memory and non-zero r_addend.
502 Always store 0 to memory when doing undo. */
503 assert (rela->r_addend == 0);
504 rela->r_addend = (Elf32_Sword) read_ube32 (dso, rela->r_offset);
505 write_be32 (dso, rela->r_offset, 0);
506 /* Tell undo_prelink_rela routine it should update the
509 case R_SPARC_GLOB_DAT:
513 case R_SPARC_TLS_DTPMOD32:
514 case R_SPARC_TLS_DTPOFF32:
515 case R_SPARC_TLS_TPOFF32:
516 write_be32 (dso, rela->r_offset, 0);
518 case R_SPARC_JMP_SLOT:
519 sec = addr_to_sec (dso, rela->r_offset);
524 write_be32 (dso, rela->r_offset,
526 | ((rela->r_offset - dso->shdr[sec].sh_addr)
528 write_be32 (dso, rela->r_offset + 4,
530 | (((dso->shdr[sec].sh_addr - rela->r_offset - 4) >> 2)
536 write_8 (dso, rela->r_offset, 0);
541 write_be16 (dso, rela->r_offset, 0);
544 write_be32 (dso, rela->r_offset,
545 read_ube32 (dso, rela->r_offset) & ~0x3ff);
547 case R_SPARC_TLS_LE_LOX10:
548 write_be32 (dso, rela->r_offset,
549 read_ube32 (dso, rela->r_offset) & 0xffffe000);
552 case R_SPARC_TLS_LE_HIX22:
553 write_be32 (dso, rela->r_offset,
554 read_ube32 (dso, rela->r_offset) & 0xffc00000);
556 case R_SPARC_WDISP30:
557 write_be32 (dso, rela->r_offset,
558 read_ube32 (dso, rela->r_offset) & 0xc0000000);
561 if (dso->ehdr.e_type == ET_EXEC)
562 /* COPY relocs are handled specially in generic code. */
564 error (0, 0, "%s: R_SPARC_COPY reloc in shared library?", dso->filename);
567 error (0, 0, "%s: Unknown sparc relocation type %d", dso->filename,
568 (int) GELF_R_TYPE (rela->r_info));
575 sparc_reloc_size (int reloc_type)
593 sparc_reloc_class (int reloc_type)
597 case R_SPARC_COPY: return RTYPE_CLASS_COPY;
598 case R_SPARC_JMP_SLOT: return RTYPE_CLASS_PLT;
599 case R_SPARC_TLS_DTPMOD32:
600 case R_SPARC_TLS_DTPOFF32:
601 case R_SPARC_TLS_TPOFF32:
602 case R_SPARC_TLS_LE_HIX22:
603 case R_SPARC_TLS_LE_LOX10:
604 return RTYPE_CLASS_TLS;
605 default: return RTYPE_CLASS_VALID;
613 .alternate_machine = { EM_SPARC32PLUS },
614 .R_JMP_SLOT = R_SPARC_JMP_SLOT,
615 .R_COPY = R_SPARC_COPY,
616 .R_RELATIVE = R_SPARC_RELATIVE,
617 .rtype_class_valid = RTYPE_CLASS_VALID,
618 .dynamic_linker = "/lib/ld-linux.so.2",
619 .adjust_dyn = sparc_adjust_dyn,
620 .adjust_rel = sparc_adjust_rel,
621 .adjust_rela = sparc_adjust_rela,
622 .prelink_rel = sparc_prelink_rel,
623 .prelink_rela = sparc_prelink_rela,
624 .prelink_conflict_rel = sparc_prelink_conflict_rel,
625 .prelink_conflict_rela = sparc_prelink_conflict_rela,
626 .apply_conflict_rela = sparc_apply_conflict_rela,
627 .apply_rel = sparc_apply_rel,
628 .apply_rela = sparc_apply_rela,
629 .rel_to_rela = sparc_rel_to_rela,
630 .need_rel_to_rela = sparc_need_rel_to_rela,
631 .reloc_size = sparc_reloc_size,
632 .reloc_class = sparc_reloc_class,
634 .arch_prelink = sparc_arch_prelink,
635 .undo_prelink_rela = sparc_undo_prelink_rela,
636 /* Although TASK_UNMAPPED_BASE is 0x70000000, we leave some
637 area so that mmap of /etc/ld.so.cache and ld.so's malloc
638 does not take some library's VA slot.
639 Also, if this guard area isn't too small, typically
640 even dlopened libraries will get the slots they desire. */
641 .mmap_base = 0x71000000LL,
642 .mmap_end = 0x80000000LL,
643 .max_page_size = 0x10000,