common-reloc.c revision e47ab76f02c2a4f4d802ec298969ba67956435fe
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 (R_TYPE (name))
21#define R_NAME_1(type)	#type
22
23#define RELOC_TYPES		STRINGIFIED_PASTE (BACKEND, reloc.def)
24#define STRINGIFIED_PASTE(a, b)	STRINGIFY (PASTE (a, b))
25#define STRINGIFY(x)		STRINGIFY_1 (x)
26#define STRINGIFY_1(x)		#x
27
28/* Provide a table of reloc type names, in a PIC-friendly fashion.  */
29
30static const struct EBLHOOK(reloc_nametable)
31{
32  char zero;
33#define	RELOC_TYPE(type, uses) \
34  char name_##type[sizeof R_NAME (type)];
35#include RELOC_TYPES
36#undef RELOC_TYPE
37} EBLHOOK(reloc_nametable) =
38  {
39    '\0',
40#define	RELOC_TYPE(type, uses) R_NAME (type),
41#include RELOC_TYPES
42#undef RELOC_TYPE
43  };
44#define reloc_namestr (&EBLHOOK(reloc_nametable).zero)
45
46static const uint_fast16_t EBLHOOK(reloc_nameidx)[] =
47{
48#define	RELOC_TYPE(type, uses) \
49  [R_TYPE (type)] = offsetof (struct EBLHOOK(reloc_nametable), name_##type),
50#include RELOC_TYPES
51#undef RELOC_TYPE
52};
53#define nreloc \
54  ((int) (sizeof EBLHOOK(reloc_nameidx) / sizeof EBLHOOK(reloc_nameidx)[0]))
55
56#define REL	(1 << (ET_REL - 1))
57#define EXEC	(1 << (ET_EXEC - 1))
58#define DYN	(1 << (ET_DYN - 1))
59static const uint8_t EBLHOOK(reloc_valid)[] =
60{
61#define	RELOC_TYPE(type, uses) [R_TYPE (type)] = uses,
62#include RELOC_TYPES
63#undef RELOC_TYPE
64};
65#undef REL
66#undef EXEC
67#undef DYN
68
69const char *
70EBLHOOK(reloc_type_name) (int reloc,
71			  char *buf __attribute__ ((unused)),
72			  size_t len __attribute__ ((unused)))
73{
74  if (reloc >= 0 && reloc < nreloc && EBLHOOK(reloc_nameidx)[reloc] != 0)
75    return &reloc_namestr[EBLHOOK(reloc_nameidx)[reloc]];
76  return NULL;
77}
78
79bool
80EBLHOOK(reloc_type_check) (int reloc)
81{
82  return reloc >= 0 && reloc < nreloc && EBLHOOK(reloc_nameidx)[reloc] != 0;
83}
84
85bool
86EBLHOOK(reloc_valid_use) (Elf *elf, int reloc)
87{
88  uint8_t uses = EBLHOOK(reloc_valid)[reloc];
89
90  GElf_Ehdr ehdr_mem;
91  GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
92  assert (ehdr != NULL);
93  uint8_t type = ehdr->e_type;
94
95  return type > ET_NONE && type < ET_CORE && (uses & (1 << (type - 1)));
96}
97
98
99bool
100EBLHOOK(copy_reloc_p) (int reloc)
101{
102  return reloc == R_TYPE (COPY);
103}
104
105static void
106EBLHOOK(init_reloc) (Ebl *ebl)
107{
108  ebl->reloc_type_name = EBLHOOK(reloc_type_name);
109  ebl->reloc_type_check = EBLHOOK(reloc_type_check);
110  ebl->reloc_valid_use = EBLHOOK(reloc_valid_use);
111  ebl->copy_reloc_p = EBLHOOK(copy_reloc_p);
112}
113