1 /* Common definitions for handling files in memory or only on disk. 2 Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc. 3 Written by Ulrich Drepper <drepper (at) redhat.com>, 1998. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation, version 2. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, write to the Free Software Foundation, 16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 17 18 #ifndef _COMMON_H 19 #define _COMMON_H 1 20 21 #include <ar.h> 22 //#include <byteswap.h> 23 //#include <endian.h> 24 #include <stdlib.h> 25 #include <string.h> 26 27 28 static inline Elf_Kind 29 determine_kind (void *buf, size_t len) 30 { 31 /* First test for an archive. */ 32 if (len >= SARMAG && memcmp (buf, ARMAG, SARMAG) == 0) 33 return ELF_K_AR; 34 35 /* Next try ELF files. */ 36 if (len >= EI_NIDENT && memcmp (buf, ELFMAG, SELFMAG) == 0) 37 { 38 /* Could be an ELF file. */ 39 int eclass = (int) ((unsigned char *) buf)[EI_CLASS]; 40 int data = (int) ((unsigned char *) buf)[EI_DATA]; 41 int version = (int) ((unsigned char *) buf)[EI_VERSION]; 42 43 if (eclass > ELFCLASSNONE && eclass < ELFCLASSNUM 44 && data > ELFDATANONE && data < ELFDATANUM 45 && version > EV_NONE && version < EV_NUM) 46 return ELF_K_ELF; 47 } 48 49 /* We do not know this file type. */ 50 return ELF_K_NONE; 51 } 52 53 54 /* Allocate an Elf descriptor and fill in the generic information. */ 55 static inline Elf * 56 allocate_elf (int fildes, void *map_address, off_t offset, size_t maxsize, 57 Elf_Cmd cmd, Elf *parent, Elf_Kind kind, size_t extra) 58 { 59 Elf *result = (Elf *) calloc (1, sizeof (Elf) + extra); 60 if (result == NULL) 61 __libelf_seterrno (ELF_E_NOMEM); 62 else 63 { 64 result->kind = kind; 65 result->ref_count = 1; 66 result->cmd = cmd; 67 result->fildes = fildes; 68 result->start_offset = offset; 69 result->maximum_size = maxsize; 70 result->map_address = map_address; 71 result->parent = parent; 72 73 rwlock_init (result->lock); 74 } 75 76 return result; 77 } 78 79 80 /* Acquire lock for the descriptor and all children. */ 81 static void 82 libelf_acquire_all (Elf *elf) 83 { 84 rwlock_wrlock (elf->lock); 85 86 if (elf->kind == ELF_K_AR) 87 { 88 Elf *child = elf->state.ar.children; 89 90 while (child != NULL) 91 { 92 if (child->ref_count != 0) 93 libelf_acquire_all (child); 94 child = child->next; 95 } 96 } 97 } 98 99 /* Release own lock and those of the children. */ 100 static void 101 libelf_release_all (Elf *elf) 102 { 103 if (elf->kind == ELF_K_AR) 104 { 105 Elf *child = elf->state.ar.children; 106 107 while (child != NULL) 108 { 109 if (child->ref_count != 0) 110 libelf_release_all (child); 111 child = child->next; 112 } 113 } 114 115 rwlock_unlock (elf->lock); 116 } 117 118 119 /* Macro to convert endianess in place. It determines the function it 120 has to use itself. */ 121 #define CONVERT(Var) \ 122 (Var) = (sizeof (Var) == 1 \ 123 ? (Var) \ 124 : (sizeof (Var) == 2 \ 125 ? bswap_16 (Var) \ 126 : (sizeof (Var) == 4 \ 127 ? bswap_32 (Var) \ 128 : bswap_64 (Var)))) 129 130 #define CONVERT_TO(Dst, Var) \ 131 (Dst) = (sizeof (Var) == 1 \ 132 ? (Var) \ 133 : (sizeof (Var) == 2 \ 134 ? bswap_16 (Var) \ 135 : (sizeof (Var) == 4 \ 136 ? bswap_32 (Var) \ 137 : bswap_64 (Var)))) 138 139 140 #if __BYTE_ORDER == __LITTLE_ENDIAN 141 # define MY_ELFDATA ELFDATA2LSB 142 #else 143 # define MY_ELFDATA ELFDATA2MSB 144 #endif 145 146 #endif /* common.h */ 147