Line data Source code
1 : /* Common code for ebl reloc functions.
2 : Copyright (C) 2005, 2006 Red Hat, Inc.
3 : This file is part of elfutils.
4 :
5 : This file is free software; you can redistribute it and/or modify
6 : it under the terms of either
7 :
8 : * the GNU Lesser General Public License as published by the Free
9 : Software Foundation; either version 3 of the License, or (at
10 : your option) any later version
11 :
12 : or
13 :
14 : * the GNU General Public License as published by the Free
15 : Software Foundation; either version 2 of the License, or (at
16 : your option) any later version
17 :
18 : or both in parallel, as here.
19 :
20 : elfutils is distributed in the hope that it will be useful, but
21 : WITHOUT ANY WARRANTY; without even the implied warranty of
22 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 : General Public License for more details.
24 :
25 : You should have received copies of the GNU General Public License and
26 : the GNU Lesser General Public License along with this program. If
27 : not, see <http://www.gnu.org/licenses/>. */
28 :
29 : #include "libebl_CPU.h"
30 : #include <assert.h>
31 :
32 : #define R_TYPE(name) PASTE (RELOC_PREFIX, name)
33 : #define PASTE(a, b) PASTE_1 (a, b)
34 : #define PASTE_1(a, b) a##b
35 : #define R_NAME(name) R_NAME_1 (RELOC_PREFIX, name)
36 : #define R_NAME_1(prefix, type) R_NAME_2 (prefix, type)
37 : #define R_NAME_2(prefix, type) #prefix #type
38 :
39 : #define RELOC_TYPES STRINGIFIED_PASTE (BACKEND, reloc.def)
40 : #define STRINGIFIED_PASTE(a, b) STRINGIFY (PASTE (a, b))
41 : #define STRINGIFY(x) STRINGIFY_1 (x)
42 : #define STRINGIFY_1(x) #x
43 :
44 : /* Provide a table of reloc type names, in a PIC-friendly fashion. */
45 :
46 : static const struct EBLHOOK(reloc_nametable)
47 : {
48 : char zero[1];
49 : #define RELOC_TYPE(type, uses) \
50 : char name_##type[sizeof R_NAME (type)];
51 : #include RELOC_TYPES
52 : #undef RELOC_TYPE
53 : } EBLHOOK(reloc_nametable) =
54 : {
55 : { '\0' },
56 : #define RELOC_TYPE(type, uses) R_NAME (type),
57 : #include RELOC_TYPES
58 : #undef RELOC_TYPE
59 : };
60 : #define reloc_namestr (&EBLHOOK(reloc_nametable).zero)
61 :
62 : static const uint_fast16_t EBLHOOK(reloc_nameidx)[] =
63 : {
64 : #define RELOC_TYPE(type, uses) \
65 : [R_TYPE (type)] = offsetof (struct EBLHOOK(reloc_nametable), name_##type),
66 : #include RELOC_TYPES
67 : #undef RELOC_TYPE
68 : };
69 : #define nreloc \
70 : ((int) (sizeof EBLHOOK(reloc_nameidx) / sizeof EBLHOOK(reloc_nameidx)[0]))
71 :
72 : #define REL (1 << (ET_REL - 1))
73 : #define EXEC (1 << (ET_EXEC - 1))
74 : #define DYN (1 << (ET_DYN - 1))
75 : static const uint8_t EBLHOOK(reloc_valid)[] =
76 : {
77 : #define RELOC_TYPE(type, uses) [R_TYPE (type)] = uses,
78 : #include RELOC_TYPES
79 : #undef RELOC_TYPE
80 : };
81 : #undef REL
82 : #undef EXEC
83 : #undef DYN
84 :
85 : const char *
86 78227 : EBLHOOK(reloc_type_name) (int reloc,
87 : char *buf __attribute__ ((unused)),
88 : size_t len __attribute__ ((unused)))
89 : {
90 : #ifdef RELOC_TYPE_ID
91 0 : reloc = RELOC_TYPE_ID (reloc);
92 : #endif
93 :
94 78227 : if (reloc >= 0 && reloc < nreloc && EBLHOOK(reloc_nameidx)[reloc] != 0)
95 78227 : return reloc_namestr[EBLHOOK(reloc_nameidx)[reloc]];
96 : return NULL;
97 : }
98 :
99 : bool
100 236470 : EBLHOOK(reloc_type_check) (int reloc)
101 : {
102 : #ifdef RELOC_TYPE_ID
103 90 : reloc = RELOC_TYPE_ID (reloc);
104 : #endif
105 :
106 236470 : return reloc >= 0 && reloc < nreloc && EBLHOOK(reloc_nameidx)[reloc] != 0;
107 : }
108 :
109 : bool
110 158261 : EBLHOOK(reloc_valid_use) (Elf *elf, int reloc)
111 : {
112 158261 : uint8_t uses;
113 :
114 158261 : GElf_Ehdr ehdr_mem;
115 158261 : GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
116 158261 : assert (ehdr != NULL);
117 158261 : uint8_t type = ehdr->e_type;
118 :
119 : #ifdef RELOC_TYPE_ID
120 90 : reloc = RELOC_TYPE_ID (reloc);
121 : #endif
122 :
123 158261 : uses = EBLHOOK(reloc_valid)[reloc];
124 158261 : return type > ET_NONE && type < ET_CORE && (uses & (1 << (type - 1)));
125 : }
126 :
127 : #ifndef NO_COPY_RELOC
128 : bool
129 158341 : EBLHOOK(copy_reloc_p) (int reloc)
130 : {
131 158341 : return reloc == R_TYPE (COPY);
132 : }
133 : #endif
134 :
135 : bool
136 158261 : EBLHOOK(none_reloc_p) (int reloc)
137 : {
138 158261 : return reloc == R_TYPE (NONE);
139 : }
140 :
141 : #ifndef NO_RELATIVE_RELOC
142 : bool
143 0 : EBLHOOK(relative_reloc_p) (int reloc)
144 : {
145 0 : return reloc == R_TYPE (RELATIVE);
146 : }
147 : #endif
148 :
149 : static void
150 : EBLHOOK(init_reloc) (Ebl *ebl)
151 : {
152 1599 : ebl->reloc_type_name = EBLHOOK(reloc_type_name);
153 1599 : ebl->reloc_type_check = EBLHOOK(reloc_type_check);
154 1599 : ebl->reloc_valid_use = EBLHOOK(reloc_valid_use);
155 1599 : ebl->none_reloc_p = EBLHOOK(none_reloc_p);
156 : #ifndef NO_COPY_RELOC
157 1597 : ebl->copy_reloc_p = EBLHOOK(copy_reloc_p);
158 : #endif
159 : #ifndef NO_RELATIVE_RELOC
160 1595 : ebl->relative_reloc_p = EBLHOOK(relative_reloc_p);
161 : #endif
162 : }
|