1164190Sjkoshy/*- 2164190Sjkoshy * Copyright (c) 2006 Joseph Koshy 3164190Sjkoshy * All rights reserved. 4164190Sjkoshy * 5164190Sjkoshy * Redistribution and use in source and binary forms, with or without 6164190Sjkoshy * modification, are permitted provided that the following conditions 7164190Sjkoshy * are met: 8164190Sjkoshy * 1. Redistributions of source code must retain the above copyright 9164190Sjkoshy * notice, this list of conditions and the following disclaimer. 10164190Sjkoshy * 2. Redistributions in binary form must reproduce the above copyright 11164190Sjkoshy * notice, this list of conditions and the following disclaimer in the 12164190Sjkoshy * documentation and/or other materials provided with the distribution. 13164190Sjkoshy * 14164190Sjkoshy * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15164190Sjkoshy * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16164190Sjkoshy * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17164190Sjkoshy * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18164190Sjkoshy * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19164190Sjkoshy * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20164190Sjkoshy * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21164190Sjkoshy * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22164190Sjkoshy * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23164190Sjkoshy * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24164190Sjkoshy * SUCH DAMAGE. 25164190Sjkoshy */ 26164190Sjkoshy 27164190Sjkoshy#include <sys/cdefs.h> 28164190Sjkoshy__FBSDID("$FreeBSD$"); 29164190Sjkoshy 30164190Sjkoshy#include <sys/types.h> 31164190Sjkoshy 32164190Sjkoshy#include <machine/elf.h> 33164190Sjkoshy#include <machine/endian.h> 34164190Sjkoshy 35164190Sjkoshy#include <libelf.h> 36164190Sjkoshy#include <osreldate.h> 37164190Sjkoshy 38164190Sjkoshy#include "_libelf.h" 39164190Sjkoshy 40164190Sjkoshystruct align { 41164190Sjkoshy int a32; 42164190Sjkoshy int a64; 43164190Sjkoshy}; 44164190Sjkoshy 45164190Sjkoshy#ifdef __GNUC__ 46164190Sjkoshy#define MALIGN(N) { \ 47164190Sjkoshy .a32 = __alignof__(Elf32_##N), \ 48164190Sjkoshy .a64 = __alignof__(Elf64_##N) \ 49164190Sjkoshy } 50164190Sjkoshy#define MALIGN64(V) { \ 51164190Sjkoshy .a32 = 0, \ 52164190Sjkoshy .a64 = __alignof__(Elf64_##V) \ 53164190Sjkoshy } 54210332Skaiw#define MALIGN_WORD() { \ 55210332Skaiw .a32 = __alignof__(int32_t), \ 56210332Skaiw .a64 = __alignof__(int64_t) \ 57210332Skaiw } 58164190Sjkoshy#else 59164190Sjkoshy#error Need the __alignof__ builtin. 60164190Sjkoshy#endif 61164190Sjkoshy#define UNSUPPORTED() { \ 62164190Sjkoshy .a32 = 0, \ 63164190Sjkoshy .a64 = 0 \ 64164190Sjkoshy } 65164190Sjkoshy 66164190Sjkoshystatic struct align malign[ELF_T_NUM] = { 67164190Sjkoshy [ELF_T_ADDR] = MALIGN(Addr), 68164190Sjkoshy [ELF_T_BYTE] = { .a32 = 1, .a64 = 1 }, 69165316Sjkoshy#if __FreeBSD_version >= 700025 70164190Sjkoshy [ELF_T_CAP] = MALIGN(Cap), 71164190Sjkoshy#endif 72164190Sjkoshy [ELF_T_DYN] = MALIGN(Dyn), 73164190Sjkoshy [ELF_T_EHDR] = MALIGN(Ehdr), 74164190Sjkoshy [ELF_T_HALF] = MALIGN(Half), 75165316Sjkoshy#if __FreeBSD_version >= 700025 76164190Sjkoshy [ELF_T_LWORD] = MALIGN(Lword), 77164190Sjkoshy [ELF_T_MOVE] = MALIGN(Move), 78164190Sjkoshy#endif 79164190Sjkoshy [ELF_T_MOVEP] = UNSUPPORTED(), 80165316Sjkoshy#if __FreeBSD_version >= 700025 81164190Sjkoshy [ELF_T_NOTE] = MALIGN(Nhdr), 82164190Sjkoshy#endif 83164190Sjkoshy [ELF_T_OFF] = MALIGN(Off), 84164190Sjkoshy [ELF_T_PHDR] = MALIGN(Phdr), 85164190Sjkoshy [ELF_T_REL] = MALIGN(Rel), 86164190Sjkoshy [ELF_T_RELA] = MALIGN(Rela), 87164190Sjkoshy [ELF_T_SHDR] = MALIGN(Shdr), 88164190Sjkoshy [ELF_T_SWORD] = MALIGN(Sword), 89164190Sjkoshy [ELF_T_SXWORD] = MALIGN64(Sxword), 90164190Sjkoshy [ELF_T_SYM] = MALIGN(Sym), 91165316Sjkoshy#if __FreeBSD_version >= 700025 92164190Sjkoshy [ELF_T_SYMINFO] = MALIGN(Syminfo), 93164190Sjkoshy#endif 94164190Sjkoshy#if __FreeBSD_version >= 700009 95164190Sjkoshy [ELF_T_VDEF] = MALIGN(Verdef), 96164190Sjkoshy [ELF_T_VNEED] = MALIGN(Verneed), 97164190Sjkoshy#endif 98164190Sjkoshy [ELF_T_WORD] = MALIGN(Word), 99210332Skaiw [ELF_T_XWORD] = MALIGN64(Xword), 100210332Skaiw#if __FreeBSD_version >= 800062 101210332Skaiw [ELF_T_GNUHASH] = MALIGN_WORD() 102210332Skaiw#endif 103164190Sjkoshy}; 104164190Sjkoshy 105164190Sjkoshyint 106164190Sjkoshy_libelf_malign(Elf_Type t, int elfclass) 107164190Sjkoshy{ 108164190Sjkoshy if (t >= ELF_T_NUM || (int) t < 0) 109164190Sjkoshy return (0); 110164190Sjkoshy 111164190Sjkoshy return (elfclass == ELFCLASS32 ? malign[t].a32 : 112164190Sjkoshy malign[t].a64); 113164190Sjkoshy} 114164190Sjkoshy 115164190Sjkoshy#define FALIGN(A32,A64) { .a32 = (A32), .a64 = (A64) } 116164190Sjkoshy 117164190Sjkoshystatic struct align falign[ELF_T_NUM] = { 118164190Sjkoshy [ELF_T_ADDR] = FALIGN(4,8), 119164190Sjkoshy [ELF_T_BYTE] = FALIGN(1,1), 120165316Sjkoshy#if __FreeBSD_version >= 700025 121164190Sjkoshy [ELF_T_CAP] = FALIGN(4,8), 122164190Sjkoshy#endif 123164190Sjkoshy [ELF_T_DYN] = FALIGN(4,8), 124164190Sjkoshy [ELF_T_EHDR] = FALIGN(4,8), 125164190Sjkoshy [ELF_T_HALF] = FALIGN(2,2), 126165316Sjkoshy#if __FreeBSD_version >= 700025 127164190Sjkoshy [ELF_T_LWORD] = FALIGN(8,8), 128164190Sjkoshy [ELF_T_MOVE] = FALIGN(8,8), 129164190Sjkoshy#endif 130164190Sjkoshy [ELF_T_MOVEP] = UNSUPPORTED(), 131165316Sjkoshy#if __FreeBSD_version >= 700025 132179240Sjb [ELF_T_NOTE] = FALIGN(1,1), 133164190Sjkoshy#endif 134164190Sjkoshy [ELF_T_OFF] = FALIGN(4,8), 135164190Sjkoshy [ELF_T_PHDR] = FALIGN(4,8), 136164190Sjkoshy [ELF_T_REL] = FALIGN(4,8), 137164190Sjkoshy [ELF_T_RELA] = FALIGN(4,8), 138164190Sjkoshy [ELF_T_SHDR] = FALIGN(4,8), 139164190Sjkoshy [ELF_T_SWORD] = FALIGN(4,4), 140164190Sjkoshy [ELF_T_SXWORD] = FALIGN(0,8), 141164190Sjkoshy [ELF_T_SYM] = FALIGN(4,8), 142165316Sjkoshy#if __FreeBSD_version >= 700025 143164190Sjkoshy [ELF_T_SYMINFO] = FALIGN(2,2), 144164190Sjkoshy#endif 145164190Sjkoshy#if __FreeBSD_version >= 700009 146164190Sjkoshy [ELF_T_VDEF] = FALIGN(4,4), 147164190Sjkoshy [ELF_T_VNEED] = FALIGN(4,4), 148164190Sjkoshy#endif 149164190Sjkoshy [ELF_T_WORD] = FALIGN(4,4), 150210332Skaiw [ELF_T_XWORD] = FALIGN(0,8), 151210332Skaiw#if __FreeBSD_version >= 800062 152210332Skaiw [ELF_T_GNUHASH] = FALIGN(4,8) 153210332Skaiw#endif 154164190Sjkoshy}; 155164190Sjkoshy 156164190Sjkoshyint 157164190Sjkoshy_libelf_falign(Elf_Type t, int elfclass) 158164190Sjkoshy{ 159164190Sjkoshy if (t >= ELF_T_NUM || (int) t < 0) 160164190Sjkoshy return (0); 161164190Sjkoshy 162164190Sjkoshy return (elfclass == ELFCLASS32 ? falign[t].a32 : 163164190Sjkoshy falign[t].a64); 164164190Sjkoshy} 165