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@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
determine_kind(void * buf,size_t len)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 *
allocate_elf(int fildes,void * map_address,off_t offset,size_t maxsize,Elf_Cmd cmd,Elf * parent,Elf_Kind kind,size_t extra)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
libelf_acquire_all(Elf * elf)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
libelf_release_all(Elf * elf)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