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