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