1/*- 2 * Copyright (c) 2006 Joseph Koshy 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD$"); 29 30#include <sys/types.h> 31 32#include <machine/elf.h> 33#include <machine/endian.h> 34 35#include <libelf.h> 36#include <osreldate.h> 37 38#include "_libelf.h" 39 40struct align { 41 int a32; 42 int a64; 43}; 44 45#ifdef __GNUC__ 46#define MALIGN(N) { \ 47 .a32 = __alignof__(Elf32_##N), \ 48 .a64 = __alignof__(Elf64_##N) \ 49 } 50#define MALIGN64(V) { \ 51 .a32 = 0, \ 52 .a64 = __alignof__(Elf64_##V) \ 53 } 54#define MALIGN_WORD() { \ 55 .a32 = __alignof__(int32_t), \ 56 .a64 = __alignof__(int64_t) \ 57 } 58#else 59#error Need the __alignof__ builtin. 60#endif 61#define UNSUPPORTED() { \ 62 .a32 = 0, \ 63 .a64 = 0 \ 64 } 65 66static struct align malign[ELF_T_NUM] = { 67 [ELF_T_ADDR] = MALIGN(Addr), 68 [ELF_T_BYTE] = { .a32 = 1, .a64 = 1 }, 69#if __FreeBSD_version >= 700025 70 [ELF_T_CAP] = MALIGN(Cap), 71#endif 72 [ELF_T_DYN] = MALIGN(Dyn), 73 [ELF_T_EHDR] = MALIGN(Ehdr), 74 [ELF_T_HALF] = MALIGN(Half), 75#if __FreeBSD_version >= 700025 76 [ELF_T_LWORD] = MALIGN(Lword), 77 [ELF_T_MOVE] = MALIGN(Move), 78#endif 79 [ELF_T_MOVEP] = UNSUPPORTED(), 80#if __FreeBSD_version >= 700025 81 [ELF_T_NOTE] = MALIGN(Nhdr), 82#endif 83 [ELF_T_OFF] = MALIGN(Off), 84 [ELF_T_PHDR] = MALIGN(Phdr), 85 [ELF_T_REL] = MALIGN(Rel), 86 [ELF_T_RELA] = MALIGN(Rela), 87 [ELF_T_SHDR] = MALIGN(Shdr), 88 [ELF_T_SWORD] = MALIGN(Sword), 89 [ELF_T_SXWORD] = MALIGN64(Sxword), 90 [ELF_T_SYM] = MALIGN(Sym), 91#if __FreeBSD_version >= 700025 92 [ELF_T_SYMINFO] = MALIGN(Syminfo), 93#endif 94#if __FreeBSD_version >= 700009 95 [ELF_T_VDEF] = MALIGN(Verdef), 96 [ELF_T_VNEED] = MALIGN(Verneed), 97#endif 98 [ELF_T_WORD] = MALIGN(Word), 99 [ELF_T_XWORD] = MALIGN64(Xword), 100#if __FreeBSD_version >= 800062 101 [ELF_T_GNUHASH] = MALIGN_WORD() 102#endif 103}; 104 105int 106_libelf_malign(Elf_Type t, int elfclass) 107{ 108 if (t >= ELF_T_NUM || (int) t < 0) 109 return (0); 110 111 return (elfclass == ELFCLASS32 ? malign[t].a32 : 112 malign[t].a64); 113} 114 115#define FALIGN(A32,A64) { .a32 = (A32), .a64 = (A64) } 116 117static struct align falign[ELF_T_NUM] = { 118 [ELF_T_ADDR] = FALIGN(4,8), 119 [ELF_T_BYTE] = FALIGN(1,1), 120#if __FreeBSD_version >= 700025 121 [ELF_T_CAP] = FALIGN(4,8), 122#endif 123 [ELF_T_DYN] = FALIGN(4,8), 124 [ELF_T_EHDR] = FALIGN(4,8), 125 [ELF_T_HALF] = FALIGN(2,2), 126#if __FreeBSD_version >= 700025 127 [ELF_T_LWORD] = FALIGN(8,8), 128 [ELF_T_MOVE] = FALIGN(8,8), 129#endif 130 [ELF_T_MOVEP] = UNSUPPORTED(), 131#if __FreeBSD_version >= 700025 132 [ELF_T_NOTE] = FALIGN(1,1), 133#endif 134 [ELF_T_OFF] = FALIGN(4,8), 135 [ELF_T_PHDR] = FALIGN(4,8), 136 [ELF_T_REL] = FALIGN(4,8), 137 [ELF_T_RELA] = FALIGN(4,8), 138 [ELF_T_SHDR] = FALIGN(4,8), 139 [ELF_T_SWORD] = FALIGN(4,4), 140 [ELF_T_SXWORD] = FALIGN(0,8), 141 [ELF_T_SYM] = FALIGN(4,8), 142#if __FreeBSD_version >= 700025 143 [ELF_T_SYMINFO] = FALIGN(2,2), 144#endif 145#if __FreeBSD_version >= 700009 146 [ELF_T_VDEF] = FALIGN(4,4), 147 [ELF_T_VNEED] = FALIGN(4,4), 148#endif 149 [ELF_T_WORD] = FALIGN(4,4), 150 [ELF_T_XWORD] = FALIGN(0,8), 151#if __FreeBSD_version >= 800062 152 [ELF_T_GNUHASH] = FALIGN(4,8) 153#endif 154}; 155 156int 157_libelf_falign(Elf_Type t, int elfclass) 158{ 159 if (t >= ELF_T_NUM || (int) t < 0) 160 return (0); 161 162 return (elfclass == ELFCLASS32 ? falign[t].a32 : 163 falign[t].a64); 164} 165