2 * Copyright (c) 2006,2008 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
27 #include <sys/cdefs.h>
37 * Translate to/from the file representation of ELF objects.
39 * Translation could potentially involve the following
42 * - an endianness conversion,
43 * - a change of layout, as the file representation of ELF objects
44 * can differ from their in-memory representation.
45 * - a change in representation due to a layout version change.
49 _libelf_xlate(Elf_Data
*dst
, const Elf_Data
*src
, unsigned int encoding
,
50 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_PRIVATE(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 byteswap
= encoding
!= LIBELF_PRIVATE(byteorder
);
139 if (src
->d_size
== 0 ||
140 (db
== sb
&& !byteswap
&& fsz
== msz
))
141 return (dst
); /* nothing more to do */
143 if (!(_libelf_get_translator(src
->d_type
, direction
, elfclass
))
144 (dst
->d_buf
, dsz
, src
->d_buf
, cnt
, byteswap
)) {
145 LIBELF_SET_ERROR(DATA
, 0);