1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* PPC specific symbolic name handling. 2fd2e84cb31fa7585baa7daa9dae03a8ac725ae05Mark Wielaard Copyright (C) 2004, 2005, 2007, 2014, 2015 Red Hat, Inc. 3de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is part of elfutils. 4b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Written by Ulrich Drepper <drepper@redhat.com>, 2004. 5b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 6de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is free software; you can redistribute it and/or modify 7de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard it under the terms of either 8b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 9de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * the GNU Lesser General Public License as published by the Free 10de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard Software Foundation; either version 3 of the License, or (at 11de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard your option) any later version 12de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 13de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard or 14de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 15de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * the GNU General Public License as published by the Free 16de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard Software Foundation; either version 2 of the License, or (at 17de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard your option) any later version 18de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 19de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard or both in parallel, as here. 20de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 21de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard elfutils is distributed in the hope that it will be useful, but 22361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper WITHOUT ANY WARRANTY; without even the implied warranty of 23361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper General Public License for more details. 25361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper 26de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard You should have received copies of the GNU General Public License and 27de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard the GNU Lesser General Public License along with this program. If 28de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard not, see <http://www.gnu.org/licenses/>. */ 29b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 30b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#ifdef HAVE_CONFIG_H 31b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper# include <config.h> 32b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif 33b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 34b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <assert.h> 35b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <elf.h> 36b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stddef.h> 37653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath#include <string.h> 38b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 39cd60ea83050d9fb48c3204005f475df460f433b6Roland McGrath#define BACKEND ppc_ 40cd60ea83050d9fb48c3204005f475df460f433b6Roland McGrath#include "libebl_CPU.h" 41b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 42b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 43b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Check for the simple reloc types. */ 44b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperElf_Type 45cd60ea83050d9fb48c3204005f475df460f433b6Roland McGrathppc_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type) 46b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 47b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch (type) 48b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 49b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case R_PPC_ADDR32: 50b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case R_PPC_UADDR32: 51b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return ELF_T_WORD; 52b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case R_PPC_UADDR16: 53b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return ELF_T_HALF; 54b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 55b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return ELF_T_NUM; 56b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 57b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 58b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 59b03b05785914250d53d31e966373617f6104bd9dUlrich Drepper 60b03b05785914250d53d31e966373617f6104bd9dUlrich Drepperconst char * 61b03b05785914250d53d31e966373617f6104bd9dUlrich Drepperppc_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)), 62b03b05785914250d53d31e966373617f6104bd9dUlrich Drepper size_t len __attribute__ ((unused))) 63b03b05785914250d53d31e966373617f6104bd9dUlrich Drepper{ 64b03b05785914250d53d31e966373617f6104bd9dUlrich Drepper switch (tag) 65b03b05785914250d53d31e966373617f6104bd9dUlrich Drepper { 66b03b05785914250d53d31e966373617f6104bd9dUlrich Drepper case DT_PPC_GOT: 67b03b05785914250d53d31e966373617f6104bd9dUlrich Drepper return "PPC_GOT"; 68b03b05785914250d53d31e966373617f6104bd9dUlrich Drepper default: 69b03b05785914250d53d31e966373617f6104bd9dUlrich Drepper break; 70b03b05785914250d53d31e966373617f6104bd9dUlrich Drepper } 71b03b05785914250d53d31e966373617f6104bd9dUlrich Drepper return NULL; 72b03b05785914250d53d31e966373617f6104bd9dUlrich Drepper} 73b03b05785914250d53d31e966373617f6104bd9dUlrich Drepper 74b03b05785914250d53d31e966373617f6104bd9dUlrich Drepper 75b03b05785914250d53d31e966373617f6104bd9dUlrich Drepperbool 76b03b05785914250d53d31e966373617f6104bd9dUlrich Drepperppc_dynamic_tag_check (int64_t tag) 77b03b05785914250d53d31e966373617f6104bd9dUlrich Drepper{ 78b03b05785914250d53d31e966373617f6104bd9dUlrich Drepper return tag == DT_PPC_GOT; 79b03b05785914250d53d31e966373617f6104bd9dUlrich Drepper} 80b03b05785914250d53d31e966373617f6104bd9dUlrich Drepper 81b03b05785914250d53d31e966373617f6104bd9dUlrich Drepper 82f8873cb86317d18399593eb95947e0c543bc9d72Roland McGrath/* Look for DT_PPC_GOT. */ 83f8873cb86317d18399593eb95947e0c543bc9d72Roland McGrathstatic bool 84712c8faddc08844fb1f2814c8b6e817f03b0698eMark Wielaardfind_dyn_got (Elf *elf, GElf_Addr *addr) 85f8873cb86317d18399593eb95947e0c543bc9d72Roland McGrath{ 86712c8faddc08844fb1f2814c8b6e817f03b0698eMark Wielaard size_t phnum; 87712c8faddc08844fb1f2814c8b6e817f03b0698eMark Wielaard if (elf_getphdrnum (elf, &phnum) != 0) 88712c8faddc08844fb1f2814c8b6e817f03b0698eMark Wielaard return false; 89712c8faddc08844fb1f2814c8b6e817f03b0698eMark Wielaard 90712c8faddc08844fb1f2814c8b6e817f03b0698eMark Wielaard for (size_t i = 0; i < phnum; ++i) 91f8873cb86317d18399593eb95947e0c543bc9d72Roland McGrath { 92c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper GElf_Phdr phdr_mem; 93c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem); 94c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper if (phdr == NULL || phdr->p_type != PT_DYNAMIC) 95c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper continue; 96c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper 97c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper Elf_Scn *scn = gelf_offscn (elf, phdr->p_offset); 98f8873cb86317d18399593eb95947e0c543bc9d72Roland McGrath GElf_Shdr shdr_mem; 99f8873cb86317d18399593eb95947e0c543bc9d72Roland McGrath GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 100c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper Elf_Data *data = elf_getdata (scn, NULL); 101d973206f716d441634f3b937be9c8c5b8b6250dbMark Wielaard if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC && data != NULL 102d973206f716d441634f3b937be9c8c5b8b6250dbMark Wielaard && shdr->sh_entsize != 0) 103c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper for (unsigned int j = 0; j < shdr->sh_size / shdr->sh_entsize; ++j) 104c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper { 105c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper GElf_Dyn dyn_mem; 106c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem); 107c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper if (dyn != NULL && dyn->d_tag == DT_PPC_GOT) 108c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper { 109c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper *addr = dyn->d_un.d_ptr; 110c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper return true; 111c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper } 112c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper } 113c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper 114c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper /* There is only one PT_DYNAMIC entry. */ 115c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper break; 116f8873cb86317d18399593eb95947e0c543bc9d72Roland McGrath } 117f8873cb86317d18399593eb95947e0c543bc9d72Roland McGrath 118f8873cb86317d18399593eb95947e0c543bc9d72Roland McGrath return false; 119f8873cb86317d18399593eb95947e0c543bc9d72Roland McGrath} 120f8873cb86317d18399593eb95947e0c543bc9d72Roland McGrath 121c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper 122f8873cb86317d18399593eb95947e0c543bc9d72Roland McGrath/* Check whether given symbol's st_value and st_size are OK despite failing 123f8873cb86317d18399593eb95947e0c543bc9d72Roland McGrath normal checks. */ 124653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrathbool 125c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepperppc_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr, const GElf_Sym *sym, 126c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper const char *name, const GElf_Shdr *destshdr) 127653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath{ 128653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath if (name == NULL) 129653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath return false; 130653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 131c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper if (strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0) 132653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath { 133cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath /* In -msecure-plt mode, DT_PPC_GOT is present and must match. */ 134f8873cb86317d18399593eb95947e0c543bc9d72Roland McGrath GElf_Addr gotaddr; 135712c8faddc08844fb1f2814c8b6e817f03b0698eMark Wielaard if (find_dyn_got (elf, &gotaddr)) 136f8873cb86317d18399593eb95947e0c543bc9d72Roland McGrath return sym->st_value == gotaddr; 137cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath 138cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath /* In -mbss-plt mode, any place in the section is valid. */ 139cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath return true; 140653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath } 141653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 142653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath const char *sname = elf_strptr (elf, ehdr->e_shstrndx, destshdr->sh_name); 143653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath if (sname == NULL) 144653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath return false; 145653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 146fd2e84cb31fa7585baa7daa9dae03a8ac725ae05Mark Wielaard /* Small data area. Normally points to .sdata, in which case we 147fd2e84cb31fa7585baa7daa9dae03a8ac725ae05Mark Wielaard check it is at an offset of 0x8000. It might however fall in the 148fd2e84cb31fa7585baa7daa9dae03a8ac725ae05Mark Wielaard .data section, in which case we cannot check the offset. The 149fd2e84cb31fa7585baa7daa9dae03a8ac725ae05Mark Wielaard size always should be zero. */ 150c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper if (strcmp (name, "_SDA_BASE_") == 0) 151fd2e84cb31fa7585baa7daa9dae03a8ac725ae05Mark Wielaard return (((strcmp (sname, ".sdata") == 0 152fd2e84cb31fa7585baa7daa9dae03a8ac725ae05Mark Wielaard && sym->st_value == destshdr->sh_addr + 0x8000) 153fd2e84cb31fa7585baa7daa9dae03a8ac725ae05Mark Wielaard || strcmp (sname, ".data") == 0) 154653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath && sym->st_size == 0); 155653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 156c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper if (strcmp (name, "_SDA2_BASE_") == 0) 157c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper return (strcmp (sname, ".sdata2") == 0 158653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath && sym->st_value == destshdr->sh_addr + 0x8000 159653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath && sym->st_size == 0); 160653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 161653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath return false; 162653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath} 163653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath 164c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803Ulrich Drepper 165653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath/* Check if backend uses a bss PLT in this file. */ 166653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrathbool 167712c8faddc08844fb1f2814c8b6e817f03b0698eMark Wielaardppc_bss_plt_p (Elf *elf) 168653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath{ 169f8873cb86317d18399593eb95947e0c543bc9d72Roland McGrath GElf_Addr addr; 170712c8faddc08844fb1f2814c8b6e817f03b0698eMark Wielaard return ! find_dyn_got (elf, &addr); 171653d3763e986da9f1c8a92ff9103d85c534754cdRoland McGrath} 172