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