• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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