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
32 ELFTC_VCSID("$Id: libelf_xlate.c 3174 2015-03-27 17:13:41Z emaste $");
35 * Translate to/from the file representation of ELF objects.
37 * Translation could potentially involve the following
40 * - an endianness conversion,
41 * - a change of layout, as the file representation of ELF objects
42 * can differ from their in-memory representation.
43 * - a change in representation due to a layout version change.
47 _libelf_xlate(Elf_Data
*dst
, const Elf_Data
*src
, unsigned int encoding
,
48 int elfclass
, int direction
)
51 size_t cnt
, dsz
, fsz
, msz
;
52 uintptr_t sb
, se
, db
, de
;
54 if (encoding
== ELFDATANONE
)
55 encoding
= LIBELF_PRIVATE(byteorder
);
57 if ((encoding
!= ELFDATA2LSB
&& encoding
!= ELFDATA2MSB
) ||
58 dst
== NULL
|| src
== NULL
|| dst
== src
) {
59 LIBELF_SET_ERROR(ARGUMENT
, 0);
63 assert(elfclass
== ELFCLASS32
|| elfclass
== ELFCLASS64
);
64 assert(direction
== ELF_TOFILE
|| direction
== ELF_TOMEMORY
);
66 if (dst
->d_version
!= src
->d_version
) {
67 LIBELF_SET_ERROR(UNIMPL
, 0);
71 if (src
->d_buf
== NULL
|| dst
->d_buf
== NULL
) {
72 LIBELF_SET_ERROR(DATA
, 0);
76 if ((int) src
->d_type
< 0 || src
->d_type
>= ELF_T_NUM
) {
77 LIBELF_SET_ERROR(DATA
, 0);
81 if ((fsz
= (elfclass
== ELFCLASS32
? elf32_fsize
: elf64_fsize
)
82 (src
->d_type
, (size_t) 1, src
->d_version
)) == 0)
85 msz
= _libelf_msize(src
->d_type
, elfclass
, src
->d_version
);
89 if (src
->d_size
% (direction
== ELF_TOMEMORY
? fsz
: msz
)) {
90 LIBELF_SET_ERROR(DATA
, 0);
95 * Determine the number of objects that need to be converted, and
96 * the space required for the converted objects in the destination
99 if (direction
== ELF_TOMEMORY
) {
100 cnt
= (size_t) src
->d_size
/ fsz
;
103 cnt
= (size_t) src
->d_size
/ msz
;
107 if (dst
->d_size
< dsz
) {
108 LIBELF_SET_ERROR(DATA
, 0);
112 sb
= (uintptr_t) src
->d_buf
;
113 se
= sb
+ (size_t) src
->d_size
;
114 db
= (uintptr_t) dst
->d_buf
;
115 de
= db
+ (size_t) dst
->d_size
;
118 * Check for overlapping buffers. Note that db == sb is
121 if (db
!= sb
&& de
> sb
&& se
> db
) {
122 LIBELF_SET_ERROR(DATA
, 0);
126 if ((direction
== ELF_TOMEMORY
? db
: sb
) %
127 _libelf_malign(src
->d_type
, elfclass
)) {
128 LIBELF_SET_ERROR(DATA
, 0);
132 dst
->d_type
= src
->d_type
;
135 byteswap
= encoding
!= LIBELF_PRIVATE(byteorder
);
137 if (src
->d_size
== 0 ||
138 (db
== sb
&& !byteswap
&& fsz
== msz
))
139 return (dst
); /* nothing more to do */
141 if (!(_libelf_get_translator(src
->d_type
, direction
, elfclass
))
142 (dst
->d_buf
, dsz
, src
->d_buf
, cnt
, byteswap
)) {
143 LIBELF_SET_ERROR(DATA
, 0);