ppc_symbol.c revision b08d5a8fb42f4586d756068065186b5af7e48da
1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* PPC specific symbolic name handling. 2b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Copyright (C) 2004, 2005 Red Hat, Inc. 3b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Written by Ulrich Drepper <drepper@redhat.com>, 2004. 4b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 5b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper This program is Open Source software; you can redistribute it and/or 6b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper modify it under the terms of the Open Software License version 1.0 as 7b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper published by the Open Source Initiative. 8b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 9b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper You should have received a copy of the Open Software License along 10b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper with this program; if not, you may obtain a copy of the Open Software 11b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper License version 1.0 from http://www.opensource.org/licenses/osl.php or 12b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper by writing the Open Source Initiative c/o Lawrence Rosen, Esq., 13b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3001 King Ranch Road, Ukiah, CA 95482. */ 14b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 15b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#ifdef HAVE_CONFIG_H 16b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper# include <config.h> 17b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif 18b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 19b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <assert.h> 20b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <elf.h> 21b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stddef.h> 22b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 23b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <libebl_ppc.h> 24b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 25b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 26b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Return of the backend. */ 27b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperconst char * 28b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperppc_backend_name (void) 29b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 30b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return "ppc"; 31b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 32b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 33b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 34b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Relocation mapping table. */ 35b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic struct 36b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 37b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *name; 38b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper enum { both = 0, rel = 1, exec = 2 } appear; 39b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} reloc_map_table[] = 40b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 41b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper // XXX Check all the appear values. 42b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_NONE] = { "R_PPC_NONE", both }, 43b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_ADDR32] = { "R_PPC_ADDR32", both }, 44b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_ADDR24] = { "R_PPC_ADDR24", both }, 45b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_ADDR16] = { "R_PPC_ADDR16", both }, 46b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_ADDR16_LO] = { "R_PPC_ADDR16_LO", both }, 47b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_ADDR16_HI] = { "R_PPC_ADDR16_HI", both }, 48b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_ADDR16_HA] = { "R_PPC_ADDR16_HA", both }, 49b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_ADDR14] = { "R_PPC_ADDR14", exec }, 50b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_ADDR14_BRTAKEN] = { "R_PPC_ADDR14_BRTAKEN", exec }, 51b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_ADDR14_BRNTAKEN] = { "R_PPC_ADDR14_BRNTAKEN", exec }, 52b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_REL24] = { "R_PPC_REL24", both }, 53b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_REL14] = { "R_PPC_REL14", both }, 54b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_REL14_BRTAKEN] = { "R_PPC_REL14_BRTAKEN", exec }, 55b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_REL14_BRNTAKEN] = { "R_PPC_REL14_BRNTAKEN", exec }, 56b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_GOT16] = { "R_PPC_GOT16", rel }, 57b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_GOT16_LO] = { "R_PPC_GOT16_LO", rel }, 58b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_GOT16_HI] = { "R_PPC_GOT16_HI", rel }, 59b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_GOT16_HA] = { "R_PPC_GOT16_HA", rel }, 60b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_PLTREL24] = { "R_PPC_PLTREL24", rel }, 61b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_COPY] = { "R_PPC_COPY", exec }, 62b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_GLOB_DAT] = { "R_PPC_GLOB_DAT", exec }, 63b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_JMP_SLOT] = { "R_PPC_JMP_SLOT", exec }, 64b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_RELATIVE] = { "R_PPC_RELATIVE", exec }, 65b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_LOCAL24PC] = { "R_PPC_LOCAL24PC", rel }, 66b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_UADDR32] = { "R_PPC_UADDR32", exec }, 67b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_UADDR16] = { "R_PPC_UADDR16", exec }, 68b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_REL32] = { "R_PPC_REL32", exec }, 69b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_PLT32] = { "R_PPC_PLT32", exec }, 70b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_PLTREL32] = { "R_PPC_PLTREL32", both }, 71b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_PLT16_LO] = { "R_PPC_PLT16_LO", both }, 72b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_PLT16_HI] = { "R_PPC_PLT16_HI", both }, 73b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_PLT16_HA] = { "R_PPC_PLT16_HA", both }, 74b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_SDAREL16] = { "R_PPC_SDAREL16", both }, 75b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_SECTOFF] = { "R_PPC_SECTOFF", both }, 76b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_SECTOFF_LO] = { "R_PPC_SECTOFF_LO", both }, 77b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_SECTOFF_HI] = { "R_PPC_SECTOFF_HI", both }, 78b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_SECTOFF_HA] = { "R_PPC_SECTOFF_HA", both }, 79b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_TLS] = { "R_PPC_TLS", both }, 80b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_DTPMOD32] = { "R_PPC_DTPMOD32", exec }, 81b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_TPREL16] = { "R_PPC_TPREL16", rel }, 82b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_TPREL16_LO] = { "R_PPC_TPREL16_LO", rel }, 83b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_TPREL16_HI] = { "R_PPC_TPREL16_HI", rel }, 84b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_TPREL16_HA] = { "R_PPC_TPREL16_HA", rel }, 85b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_TPREL32] = { "R_PPC_TPREL32", exec }, 86b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_DTPREL16] = { "R_PPC_DTPREL16", rel }, 87b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_DTPREL16_LO] = { "R_PPC_DTPREL16_LO", rel }, 88b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_DTPREL16_HI] = { "R_PPC_DTPREL16_HI", rel }, 89b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_DTPREL16_HA] = { "R_PPC_DTPREL16_HA", rel }, 90b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_DTPREL32] = { "R_PPC_DTPREL32", exec }, 91b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_GOT_TLSGD16] = { "R_PPC_GOT_TLSGD16", exec }, 92b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_GOT_TLSGD16_LO] = { "R_PPC_GOT_TLSGD16_LO", exec }, 93b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_GOT_TLSGD16_HI] = { "R_PPC_GOT_TLSGD16_HI", exec }, 94b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_GOT_TLSGD16_HA] = { "R_PPC_GOT_TLSGD16_HA", exec }, 95b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_GOT_TLSLD16] = { "R_PPC_GOT_TLSLD16", exec }, 96b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_GOT_TLSLD16_LO] = { "R_PPC_GOT_TLSLD16_LO", exec }, 97b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_GOT_TLSLD16_HI] = { "R_PPC_GOT_TLSLD16_HI", exec }, 98b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_GOT_TLSLD16_HA] = { "R_PPC_GOT_TLSLD16_HA", exec }, 99b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_GOT_TPREL16] = { "R_PPC_GOT_TPREL16", exec }, 100b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_GOT_TPREL16_LO] = { "R_PPC_GOT_TPREL16_LO", exec }, 101b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_GOT_TPREL16_HI] = { "R_PPC_GOT_TPREL16_HI", exec }, 102b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_GOT_TPREL16_HA] = { "R_PPC_GOT_TPREL16_HA", exec }, 103b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_GOT_DTPREL16] = { "R_PPC_GOT_DTPREL16", exec }, 104b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_GOT_DTPREL16_LO] = { "R_PPC_GOT_DTPREL16_LO", exec }, 105b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_GOT_DTPREL16_HI] = { "R_PPC_GOT_DTPREL16_HI", exec }, 106b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper [R_PPC_GOT_DTPREL16_HA] = { "R_PPC_GOT_DTPREL16_HA", exec } 107b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper }; 108b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 109b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 110b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Determine relocation type string for PPC. */ 111b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperconst char * 112b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperppc_reloc_type_name (int type, char *buf __attribute__ ((unused)), 113b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t len __attribute__ ((unused))) 114b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 115b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (type < 0 || type >= R_PPC_NUM) 116b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return NULL; 117b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 118b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return reloc_map_table[type].name; 119b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 120b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 121b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 122b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Check for correct relocation type. */ 123b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperbool 124b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperppc_reloc_type_check (int type) 125b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 126b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return (type >= R_PPC_NONE && type < R_PPC_NUM 127b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper && reloc_map_table[type].name != NULL) ? true : false; 128b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 129b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 130b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 131b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Check for correct relocation type use. */ 132b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperbool 133b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperppc_reloc_valid_use (Elf *elf, int type) 134b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 135b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (type < R_PPC_NONE || type >= R_PPC_NUM 136b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper || reloc_map_table[type].name == NULL) 137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return false; 138b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 139b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Elf32_Ehdr *ehdr = elf32_getehdr (elf); 140b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (ehdr != NULL); 141b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 142b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (reloc_map_table[type].appear == rel) 143b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return ehdr->e_type == ET_REL; 144b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 145b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (reloc_map_table[type].appear == exec) 146b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return ehdr->e_type != ET_REL; 147b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 148b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (reloc_map_table[type].appear == both); 149b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return true; 150b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 151b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 152b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 153b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Check for the simple reloc types. */ 154b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperElf_Type 155b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperppc_reloc_simple_type (Elf *elf __attribute__ ((unused)), int type) 156b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 157b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch (type) 158b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 159b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case R_PPC_ADDR32: 160b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case R_PPC_UADDR32: 161b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return ELF_T_WORD; 162b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case R_PPC_UADDR16: 163b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return ELF_T_HALF; 164b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 165b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return ELF_T_NUM; 166b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 167b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 168b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 169b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Check whether given relocation is a copy relocation. */ 170b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperbool 171b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperppc_copy_reloc_p (int reloc) 172b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 173b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return reloc == R_PPC_COPY; 174b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 175