1 /* $NetBSD: libelf_xlate.c,v 1.2 2009/12/20 23:23:46 thorpej Exp $ */
4 * Copyright (c) 2006 Joseph Koshy
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 /* __FBSDID("$FreeBSD: src/lib/libelf/libelf_xlate.c,v 1.3.2.1.2.1 2009/10/25 01:10:29 kensmith Exp $"); */
38 * Translate to/from the file representation of ELF objects.
40 * Translation could potentially involve the following
43 * - an endianness conversion,
44 * - a change of layout, as the file representation of ELF objects
45 * can differ from their in-memory representation.
46 * - a change in representation due to a layout version change.
50 _libelf_xlate(Elf_Data
*dst
, const Elf_Data
*src
, unsigned int encoding
,
51 int elfclass
, int direction
)
53 size_t cnt
, dsz
, fsz
, msz
;
54 uintptr_t sb
, se
, db
, de
;
56 if (encoding
== ELFDATANONE
)
57 encoding
= _libelf_host_byteorder();
59 if ((encoding
!= ELFDATA2LSB
&& encoding
!= ELFDATA2MSB
) ||
60 dst
== NULL
|| src
== NULL
|| dst
== src
) {
61 LIBELF_SET_ERROR(ARGUMENT
, 0);
65 assert(elfclass
== ELFCLASS32
|| elfclass
== ELFCLASS64
);
66 assert(direction
== ELF_TOFILE
|| direction
== ELF_TOMEMORY
);
68 if (dst
->d_version
!= src
->d_version
) {
69 LIBELF_SET_ERROR(UNIMPL
, 0);
73 if (src
->d_buf
== NULL
|| dst
->d_buf
== NULL
) {
74 LIBELF_SET_ERROR(DATA
, 0);
78 if ((int) src
->d_type
< 0 || src
->d_type
>= ELF_T_NUM
) {
79 LIBELF_SET_ERROR(DATA
, 0);
83 if ((fsz
= (elfclass
== ELFCLASS32
? elf32_fsize
: elf64_fsize
)
84 (src
->d_type
, (size_t) 1, src
->d_version
)) == 0)
87 msz
= _libelf_msize(src
->d_type
, elfclass
, src
->d_version
);
91 if (src
->d_size
% (direction
== ELF_TOMEMORY
? fsz
: msz
)) {
92 LIBELF_SET_ERROR(DATA
, 0);
97 * Determine the number of objects that need to be converted, and
98 * the space required for the converted objects in the destination
101 if (direction
== ELF_TOMEMORY
) {
102 cnt
= src
->d_size
/ fsz
;
105 cnt
= src
->d_size
/ msz
;
109 if (dst
->d_size
< dsz
) {
110 LIBELF_SET_ERROR(DATA
, 0);
114 sb
= (uintptr_t) src
->d_buf
;
115 se
= sb
+ src
->d_size
;
116 db
= (uintptr_t) dst
->d_buf
;
117 de
= db
+ dst
->d_size
;
120 * Check for overlapping buffers. Note that db == sb is
123 if (db
!= sb
&& de
> sb
&& se
> db
) {
124 LIBELF_SET_ERROR(DATA
, 0);
128 if ((direction
== ELF_TOMEMORY
? db
: sb
) %
129 _libelf_malign(src
->d_type
, elfclass
)) {
130 LIBELF_SET_ERROR(DATA
, 0);
134 dst
->d_type
= src
->d_type
;
137 if (src
->d_size
== 0 ||
138 (db
== sb
&& encoding
== _libelf_host_byteorder() && fsz
== msz
))
139 return (dst
); /* nothing more to do */
141 (_libelf_get_translator(src
->d_type
, direction
, elfclass
))(dst
->d_buf
,
142 src
->d_buf
, cnt
, encoding
!= _libelf_host_byteorder());