Home | History | Annotate | Download | only in libelf
      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