2 * Copyright (c) 2006 Joseph Koshy
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * Translate to/from the file representation of ELF objects.
35 * Translation could potentially involve the following
38 * - an endianness conversion,
39 * - a change of layout, as the file representation of ELF objects
40 * can differ from their in-memory representation.
41 * - a change in representation due to a layout version change.
45 _libelf_xlate(Elf_Data
*dst
, const Elf_Data
*src
, unsigned int encoding
,
46 int elfclass
, int direction
)
48 size_t cnt
, dsz
, fsz
, msz
;
49 uintptr_t sb
, se
, db
, de
;
51 if (encoding
== ELFDATANONE
)
52 encoding
= LIBELF_PRIVATE(byteorder
);
54 if ((encoding
!= ELFDATA2LSB
&& encoding
!= ELFDATA2MSB
) ||
55 dst
== NULL
|| src
== NULL
|| dst
== src
) {
56 LIBELF_SET_ERROR(ARGUMENT
, 0);
60 assert(elfclass
== ELFCLASS32
|| elfclass
== ELFCLASS64
);
61 assert(direction
== ELF_TOFILE
|| direction
== ELF_TOMEMORY
);
63 if (dst
->d_version
!= src
->d_version
) {
64 LIBELF_SET_ERROR(UNIMPL
, 0);
68 if (src
->d_buf
== NULL
|| dst
->d_buf
== NULL
||
70 LIBELF_SET_ERROR(DATA
, 0);
74 if ((int) src
->d_type
< 0 || src
->d_type
>= ELF_T_NUM
) {
75 LIBELF_SET_ERROR(DATA
, 0);
79 if ((fsz
= (elfclass
== ELFCLASS32
? elf32_fsize
: elf64_fsize
)(src
->d_type
,
80 (size_t) 1, src
->d_version
)) == 0)
83 msz
= _libelf_msize(src
->d_type
, elfclass
, src
->d_version
);
87 if (src
->d_size
% (direction
== ELF_TOMEMORY
? fsz
: msz
)) {
88 LIBELF_SET_ERROR(DATA
, 0);
93 * Determine the number of objects that need to be converted, and
94 * the space required for the converted objects in the destination
97 if (direction
== ELF_TOMEMORY
) {
98 cnt
= src
->d_size
/ fsz
;
101 cnt
= src
->d_size
/ msz
;
105 if (dst
->d_size
< dsz
) {
106 LIBELF_SET_ERROR(DATA
, 0);
110 sb
= (uintptr_t) src
->d_buf
;
111 se
= sb
+ src
->d_size
;
112 db
= (uintptr_t) dst
->d_buf
;
113 de
= db
+ dst
->d_size
;
116 * Check for overlapping buffers. Note that db == sb is
119 if (db
!= sb
&& de
> sb
&& se
> db
) {
120 LIBELF_SET_ERROR(DATA
, 0);
124 if ((direction
== ELF_TOMEMORY
? db
: sb
) %
125 _libelf_malign(src
->d_type
, elfclass
)) {
126 LIBELF_SET_ERROR(DATA
, 0);
130 dst
->d_type
= src
->d_type
;
133 if (db
== sb
&& encoding
== LIBELF_PRIVATE(byteorder
) &&
135 return (dst
); /* nothing more to do */
137 (_libelf_get_translator(src
->d_type
, direction
, elfclass
))(dst
->d_buf
,
138 src
->d_buf
, cnt
, encoding
!= LIBELF_PRIVATE(byteorder
));