0.119 release preparation.
[platform/upstream/elfutils.git] / backends / common-reloc.c
1 /* Common code for ebl reloc functions.
2    Copyright (C) 2005 Red Hat, Inc.
3
4    This program is Open Source software; you can redistribute it and/or
5    modify it under the terms of the Open Software License version 1.0 as
6    published by the Open Source Initiative.
7
8    You should have received a copy of the Open Software License along
9    with this program; if not, you may obtain a copy of the Open Software
10    License version 1.0 from http://www.opensource.org/licenses/osl.php or
11    by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
12    3001 King Ranch Road, Ukiah, CA 95482.   */
13
14 #include "libebl_CPU.h"
15 #include <assert.h>
16
17 #define R_TYPE(name)            PASTE (RELOC_PREFIX, name)
18 #define PASTE(a, b)             PASTE_1 (a, b)
19 #define PASTE_1(a, b)           a##b
20 #define R_NAME(name)            R_NAME_1 (RELOC_PREFIX, name)
21 #define R_NAME_1(prefix, type)  R_NAME_2 (prefix, type)
22 #define R_NAME_2(prefix, type)  #prefix #type
23
24 #define RELOC_TYPES             STRINGIFIED_PASTE (BACKEND, reloc.def)
25 #define STRINGIFIED_PASTE(a, b) STRINGIFY (PASTE (a, b))
26 #define STRINGIFY(x)            STRINGIFY_1 (x)
27 #define STRINGIFY_1(x)          #x
28
29 /* Provide a table of reloc type names, in a PIC-friendly fashion.  */
30
31 static const struct EBLHOOK(reloc_nametable)
32 {
33   char zero;
34 #define RELOC_TYPE(type, uses) \
35   char name_##type[sizeof R_NAME (type)];
36 #include RELOC_TYPES
37 #undef RELOC_TYPE
38 } EBLHOOK(reloc_nametable) =
39   {
40     '\0',
41 #define RELOC_TYPE(type, uses) R_NAME (type),
42 #include RELOC_TYPES
43 #undef RELOC_TYPE
44   };
45 #define reloc_namestr (&EBLHOOK(reloc_nametable).zero)
46
47 static const uint_fast16_t EBLHOOK(reloc_nameidx)[] =
48 {
49 #define RELOC_TYPE(type, uses) \
50   [R_TYPE (type)] = offsetof (struct EBLHOOK(reloc_nametable), name_##type),
51 #include RELOC_TYPES
52 #undef RELOC_TYPE
53 };
54 #define nreloc \
55   ((int) (sizeof EBLHOOK(reloc_nameidx) / sizeof EBLHOOK(reloc_nameidx)[0]))
56
57 #define REL     (1 << (ET_REL - 1))
58 #define EXEC    (1 << (ET_EXEC - 1))
59 #define DYN     (1 << (ET_DYN - 1))
60 static const uint8_t EBLHOOK(reloc_valid)[] =
61 {
62 #define RELOC_TYPE(type, uses) [R_TYPE (type)] = uses,
63 #include RELOC_TYPES
64 #undef RELOC_TYPE
65 };
66 #undef REL
67 #undef EXEC
68 #undef DYN
69
70 const char *
71 EBLHOOK(reloc_type_name) (int reloc,
72                           char *buf __attribute__ ((unused)),
73                           size_t len __attribute__ ((unused)))
74 {
75   if (reloc >= 0 && reloc < nreloc && EBLHOOK(reloc_nameidx)[reloc] != 0)
76     return &reloc_namestr[EBLHOOK(reloc_nameidx)[reloc]];
77   return NULL;
78 }
79
80 bool
81 EBLHOOK(reloc_type_check) (int reloc)
82 {
83   return reloc >= 0 && reloc < nreloc && EBLHOOK(reloc_nameidx)[reloc] != 0;
84 }
85
86 bool
87 EBLHOOK(reloc_valid_use) (Elf *elf, int reloc)
88 {
89   uint8_t uses = EBLHOOK(reloc_valid)[reloc];
90
91   GElf_Ehdr ehdr_mem;
92   GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
93   assert (ehdr != NULL);
94   uint8_t type = ehdr->e_type;
95
96   return type > ET_NONE && type < ET_CORE && (uses & (1 << (type - 1)));
97 }
98
99
100 bool
101 EBLHOOK(copy_reloc_p) (int reloc)
102 {
103   return reloc == R_TYPE (COPY);
104 }
105
106 static void
107 EBLHOOK(init_reloc) (Ebl *ebl)
108 {
109   ebl->reloc_type_name = EBLHOOK(reloc_type_name);
110   ebl->reloc_type_check = EBLHOOK(reloc_type_check);
111   ebl->reloc_valid_use = EBLHOOK(reloc_valid_use);
112   ebl->copy_reloc_p = EBLHOOK(copy_reloc_p);
113 }