Home | History | Annotate | Download | only in backends
      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;
     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 EBLHOOK(reloc_type_name) (int reloc,
     87 			  char *buf __attribute__ ((unused)),
     88 			  size_t len __attribute__ ((unused)))
     89 {
     90 #ifdef RELOC_TYPE_ID
     91   reloc = RELOC_TYPE_ID (reloc);
     92 #endif
     93 
     94   if (reloc >= 0 && reloc < nreloc && EBLHOOK(reloc_nameidx)[reloc] != 0)
     95     return &reloc_namestr[EBLHOOK(reloc_nameidx)[reloc]];
     96   return NULL;
     97 }
     98 
     99 bool
    100 EBLHOOK(reloc_type_check) (int reloc)
    101 {
    102 #ifdef RELOC_TYPE_ID
    103   reloc = RELOC_TYPE_ID (reloc);
    104 #endif
    105 
    106   return reloc >= 0 && reloc < nreloc && EBLHOOK(reloc_nameidx)[reloc] != 0;
    107 }
    108 
    109 bool
    110 EBLHOOK(reloc_valid_use) (Elf *elf, int reloc)
    111 {
    112   uint8_t uses;
    113 
    114   GElf_Ehdr ehdr_mem;
    115   GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
    116   assert (ehdr != NULL);
    117   uint8_t type = ehdr->e_type;
    118 
    119 #ifdef RELOC_TYPE_ID
    120   reloc = RELOC_TYPE_ID (reloc);
    121 #endif
    122 
    123   uses = EBLHOOK(reloc_valid)[reloc];
    124   return type > ET_NONE && type < ET_CORE && (uses & (1 << (type - 1)));
    125 }
    126 
    127 #ifndef NO_COPY_RELOC
    128 bool
    129 EBLHOOK(copy_reloc_p) (int reloc)
    130 {
    131   return reloc == R_TYPE (COPY);
    132 }
    133 #endif
    134 
    135 bool
    136 EBLHOOK(none_reloc_p) (int reloc)
    137 {
    138   return reloc == R_TYPE (NONE);
    139 }
    140 
    141 #ifndef NO_RELATIVE_RELOC
    142 bool
    143 EBLHOOK(relative_reloc_p) (int reloc)
    144 {
    145   return reloc == R_TYPE (RELATIVE);
    146 }
    147 #endif
    148 
    149 static void
    150 EBLHOOK(init_reloc) (Ebl *ebl)
    151 {
    152   ebl->reloc_type_name = EBLHOOK(reloc_type_name);
    153   ebl->reloc_type_check = EBLHOOK(reloc_type_check);
    154   ebl->reloc_valid_use = EBLHOOK(reloc_valid_use);
    155   ebl->none_reloc_p = EBLHOOK(none_reloc_p);
    156 #ifndef NO_COPY_RELOC
    157   ebl->copy_reloc_p = EBLHOOK(copy_reloc_p);
    158 #endif
    159 #ifndef NO_RELATIVE_RELOC
    160   ebl->relative_reloc_p = EBLHOOK(relative_reloc_p);
    161 #endif
    162 }
    163