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