1164190Sjkoshy/*-
2164190Sjkoshy * Copyright (c) 2006 Joseph Koshy
3164190Sjkoshy * All rights reserved.
4164190Sjkoshy *
5164190Sjkoshy * Redistribution and use in source and binary forms, with or without
6164190Sjkoshy * modification, are permitted provided that the following conditions
7164190Sjkoshy * are met:
8164190Sjkoshy * 1. Redistributions of source code must retain the above copyright
9164190Sjkoshy *    notice, this list of conditions and the following disclaimer.
10164190Sjkoshy * 2. Redistributions in binary form must reproduce the above copyright
11164190Sjkoshy *    notice, this list of conditions and the following disclaimer in the
12164190Sjkoshy *    documentation and/or other materials provided with the distribution.
13164190Sjkoshy *
14164190Sjkoshy * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15164190Sjkoshy * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16164190Sjkoshy * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17164190Sjkoshy * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18164190Sjkoshy * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19164190Sjkoshy * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20164190Sjkoshy * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21164190Sjkoshy * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22164190Sjkoshy * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23164190Sjkoshy * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24164190Sjkoshy * SUCH DAMAGE.
25164190Sjkoshy */
26164190Sjkoshy
27164190Sjkoshy#include <sys/cdefs.h>
28164190Sjkoshy__FBSDID("$FreeBSD$");
29164190Sjkoshy
30164190Sjkoshy#include <ar.h>
31164190Sjkoshy#include <libelf.h>
32164190Sjkoshy#include <string.h>
33164190Sjkoshy
34164190Sjkoshy#include "_libelf.h"
35164190Sjkoshy
36164190SjkoshyElf *
37164190Sjkoshyelf_memory(char *image, size_t sz)
38164190Sjkoshy{
39164190Sjkoshy	Elf *e;
40164190Sjkoshy
41164190Sjkoshy	if (LIBELF_PRIVATE(version) == EV_NONE) {
42164190Sjkoshy		LIBELF_SET_ERROR(SEQUENCE, 0);
43164190Sjkoshy		return (NULL);
44164190Sjkoshy	}
45164190Sjkoshy
46164190Sjkoshy	if (image == NULL || sz == 0) {
47164190Sjkoshy		LIBELF_SET_ERROR(ARGUMENT, 0);
48164190Sjkoshy		return (NULL);
49164190Sjkoshy	}
50164190Sjkoshy
51164190Sjkoshy	if ((e = _libelf_allocate_elf()) == NULL)
52164190Sjkoshy		return (NULL);
53164190Sjkoshy
54164190Sjkoshy	e->e_cmd = ELF_C_READ;
55164190Sjkoshy	e->e_rawfile = image;
56164190Sjkoshy	e->e_rawsize = sz;
57164190Sjkoshy
58164190Sjkoshy#undef	LIBELF_IS_ELF
59164190Sjkoshy#define	LIBELF_IS_ELF(P) ((P)[EI_MAG0] == ELFMAG0 && 		\
60164190Sjkoshy	(P)[EI_MAG1] == ELFMAG1 && (P)[EI_MAG2] == ELFMAG2 &&	\
61164190Sjkoshy	(P)[EI_MAG3] == ELFMAG3)
62164190Sjkoshy
63164190Sjkoshy	if (sz > EI_NIDENT && LIBELF_IS_ELF(image)) {
64164190Sjkoshy		_libelf_init_elf(e, ELF_K_ELF);
65164190Sjkoshy		e->e_class = image[EI_CLASS];
66164190Sjkoshy		e->e_byteorder = image[EI_DATA];
67164190Sjkoshy		e->e_version = image[EI_VERSION];
68164190Sjkoshy
69164190Sjkoshy		if (e->e_version > EV_CURRENT) {
70164190Sjkoshy			e = _libelf_release_elf(e);
71164190Sjkoshy			LIBELF_SET_ERROR(VERSION, 0);
72164190Sjkoshy			return (NULL);
73164190Sjkoshy		}
74164190Sjkoshy
75164190Sjkoshy		if ((e->e_byteorder != ELFDATA2LSB && e->e_byteorder !=
76164190Sjkoshy 		    ELFDATA2MSB) || (e->e_class != ELFCLASS32 && e->e_class !=
77164190Sjkoshy		    ELFCLASS64)) {
78164190Sjkoshy			e = _libelf_release_elf(e);
79164190Sjkoshy			LIBELF_SET_ERROR(HEADER, 0);
80164190Sjkoshy			return (NULL);
81164190Sjkoshy		}
82164190Sjkoshy
83164190Sjkoshy	} else if (sz >= SARMAG &&
84164190Sjkoshy	    strncmp(image, ARMAG, (size_t) SARMAG) == 0) {
85164190Sjkoshy		_libelf_init_elf(e, ELF_K_AR);
86164190Sjkoshy		e = _libelf_ar_open(e);
87164190Sjkoshy	} else
88164190Sjkoshy		_libelf_init_elf(e, ELF_K_NONE);
89164190Sjkoshy
90164190Sjkoshy	return (e);
91164190Sjkoshy}
92