mirror of
https://github.com/wiiu-env/WiiUPluginSystem.git
synced 2024-11-08 11:55:14 +01:00
3466 lines
71 KiB
C
3466 lines
71 KiB
C
/*-
|
|
* Copyright (c) 2006,2008 Joseph Koshy
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*
|
|
* $Id: elf_types.m4 321 2009-03-07 16:59:14Z jkoshy $
|
|
*/
|
|
|
|
/*
|
|
* ELF types, defined in the "enum Elf_Type" API.
|
|
*
|
|
* The members of the list form a 2-tuple: (name, C-type-suffix).
|
|
* + name is an Elf_Type symbol without the ELF_T_ prefix.
|
|
* + C-type-suffix is the suffix for Elf32_ and Elf64_ type names.
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
* DEFINE_STRUCT(NAME,MEMBERLIST...)
|
|
*
|
|
* Map a type name to its members.
|
|
*
|
|
* Each member-list element comprises of pairs of (field name, type),
|
|
* in the sequence used in the file representation of NAME.
|
|
*
|
|
* Each member list element comprises a pair containing a field name
|
|
* and a basic type. Basic types include IDENT, HALF, WORD, LWORD,
|
|
* ADDR{32,64}, OFF{32,64}, SWORD, XWORD, SXWORD.
|
|
*
|
|
* The last element of a member list is the null element: _,_.
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-
|
|
* Copyright (c) 2006-2011 Joseph Koshy
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*/
|
|
|
|
#include <sys/cdefs.h>
|
|
|
|
#include <assert.h>
|
|
#include <libelf.h>
|
|
#include <string.h>
|
|
|
|
#include "_libelf.h"
|
|
|
|
ELFTC_VCSID("$Id: libelf_convert.m4 2361 2011-12-28 12:03:05Z jkoshy $");
|
|
|
|
/* WARNING: GENERATED FROM libelf_convert.m4. */
|
|
|
|
|
|
|
|
/*
|
|
* C macros to byte swap integral quantities.
|
|
*/
|
|
|
|
#define SWAP_BYTE(X) do { (void) (X); } while (0)
|
|
#define SWAP_IDENT(X) do { (void) (X); } while (0)
|
|
#define SWAP_HALF(X) do { \
|
|
uint16_t _x = (uint16_t) (X); \
|
|
uint16_t _t = _x & 0xFF; \
|
|
_t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
|
|
(X) = _t; \
|
|
} while (0)
|
|
#define SWAP_WORD(X) do { \
|
|
uint32_t _x = (uint32_t) (X); \
|
|
uint32_t _t = _x & 0xFF; \
|
|
_t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
|
|
_t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
|
|
_t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
|
|
(X) = _t; \
|
|
} while (0)
|
|
#define SWAP_ADDR32(X) SWAP_WORD(X)
|
|
#define SWAP_OFF32(X) SWAP_WORD(X)
|
|
#define SWAP_SWORD(X) SWAP_WORD(X)
|
|
#define SWAP_WORD64(X) do { \
|
|
uint64_t _x = (uint64_t) (X); \
|
|
uint64_t _t = _x & 0xFF; \
|
|
_t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
|
|
_t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
|
|
_t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
|
|
_t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
|
|
_t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
|
|
_t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
|
|
_t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
|
|
(X) = _t; \
|
|
} while (0)
|
|
#define SWAP_ADDR64(X) SWAP_WORD64(X)
|
|
#define SWAP_LWORD(X) SWAP_WORD64(X)
|
|
#define SWAP_OFF64(X) SWAP_WORD64(X)
|
|
#define SWAP_SXWORD(X) SWAP_WORD64(X)
|
|
#define SWAP_XWORD(X) SWAP_WORD64(X)
|
|
|
|
/*
|
|
* C macros to write out various integral values.
|
|
*
|
|
* Note:
|
|
* - The destination pointer could be unaligned.
|
|
* - Values are written out in native byte order.
|
|
* - The destination pointer is incremented after the write.
|
|
*/
|
|
#define WRITE_BYTE(P,X) do { \
|
|
char *const _p = (char *) (P); \
|
|
_p[0] = (char) (X); \
|
|
(P) = _p + 1; \
|
|
} while (0)
|
|
#define WRITE_HALF(P,X) do { \
|
|
uint16_t _t = (X); \
|
|
char *const _p = (char *) (P); \
|
|
const char *const _q = (char *) &_t; \
|
|
_p[0] = _q[0]; \
|
|
_p[1] = _q[1]; \
|
|
(P) = _p + 2; \
|
|
} while (0)
|
|
#define WRITE_WORD(P,X) do { \
|
|
uint32_t _t = (X); \
|
|
char *const _p = (char *) (P); \
|
|
const char *const _q = (char *) &_t; \
|
|
_p[0] = _q[0]; \
|
|
_p[1] = _q[1]; \
|
|
_p[2] = _q[2]; \
|
|
_p[3] = _q[3]; \
|
|
(P) = _p + 4; \
|
|
} while (0)
|
|
#define WRITE_ADDR32(P,X) WRITE_WORD(P,X)
|
|
#define WRITE_OFF32(P,X) WRITE_WORD(P,X)
|
|
#define WRITE_SWORD(P,X) WRITE_WORD(P,X)
|
|
#define WRITE_WORD64(P,X) do { \
|
|
uint64_t _t = (X); \
|
|
char *const _p = (char *) (P); \
|
|
const char *const _q = (char *) &_t; \
|
|
_p[0] = _q[0]; \
|
|
_p[1] = _q[1]; \
|
|
_p[2] = _q[2]; \
|
|
_p[3] = _q[3]; \
|
|
_p[4] = _q[4]; \
|
|
_p[5] = _q[5]; \
|
|
_p[6] = _q[6]; \
|
|
_p[7] = _q[7]; \
|
|
(P) = _p + 8; \
|
|
} while (0)
|
|
#define WRITE_ADDR64(P,X) WRITE_WORD64(P,X)
|
|
#define WRITE_LWORD(P,X) WRITE_WORD64(P,X)
|
|
#define WRITE_OFF64(P,X) WRITE_WORD64(P,X)
|
|
#define WRITE_SXWORD(P,X) WRITE_WORD64(P,X)
|
|
#define WRITE_XWORD(P,X) WRITE_WORD64(P,X)
|
|
#define WRITE_IDENT(P,X) do { \
|
|
(void) memcpy((P), (X), sizeof((X))); \
|
|
(P) = (P) + EI_NIDENT; \
|
|
} while (0)
|
|
|
|
/*
|
|
* C macros to read in various integral values.
|
|
*
|
|
* Note:
|
|
* - The source pointer could be unaligned.
|
|
* - Values are read in native byte order.
|
|
* - The source pointer is incremented appropriately.
|
|
*/
|
|
|
|
#define READ_BYTE(P,X) do { \
|
|
const char *const _p = \
|
|
(const char *) (P); \
|
|
(X) = _p[0]; \
|
|
(P) = (P) + 1; \
|
|
} while (0)
|
|
#define READ_HALF(P,X) do { \
|
|
uint16_t _t; \
|
|
char *const _q = (char *) &_t; \
|
|
const char *const _p = \
|
|
(const char *) (P); \
|
|
_q[0] = _p[0]; \
|
|
_q[1] = _p[1]; \
|
|
(P) = (P) + 2; \
|
|
(X) = _t; \
|
|
} while (0)
|
|
#define READ_WORD(P,X) do { \
|
|
uint32_t _t; \
|
|
char *const _q = (char *) &_t; \
|
|
const char *const _p = \
|
|
(const char *) (P); \
|
|
_q[0] = _p[0]; \
|
|
_q[1] = _p[1]; \
|
|
_q[2] = _p[2]; \
|
|
_q[3] = _p[3]; \
|
|
(P) = (P) + 4; \
|
|
(X) = _t; \
|
|
} while (0)
|
|
#define READ_ADDR32(P,X) READ_WORD(P,X)
|
|
#define READ_OFF32(P,X) READ_WORD(P,X)
|
|
#define READ_SWORD(P,X) READ_WORD(P,X)
|
|
#define READ_WORD64(P,X) do { \
|
|
uint64_t _t; \
|
|
char *const _q = (char *) &_t; \
|
|
const char *const _p = \
|
|
(const char *) (P); \
|
|
_q[0] = _p[0]; \
|
|
_q[1] = _p[1]; \
|
|
_q[2] = _p[2]; \
|
|
_q[3] = _p[3]; \
|
|
_q[4] = _p[4]; \
|
|
_q[5] = _p[5]; \
|
|
_q[6] = _p[6]; \
|
|
_q[7] = _p[7]; \
|
|
(P) = (P) + 8; \
|
|
(X) = _t; \
|
|
} while (0)
|
|
#define READ_ADDR64(P,X) READ_WORD64(P,X)
|
|
#define READ_LWORD(P,X) READ_WORD64(P,X)
|
|
#define READ_OFF64(P,X) READ_WORD64(P,X)
|
|
#define READ_SXWORD(P,X) READ_WORD64(P,X)
|
|
#define READ_XWORD(P,X) READ_WORD64(P,X)
|
|
#define READ_IDENT(P,X) do { \
|
|
(void) memcpy((X), (P), sizeof((X))); \
|
|
(P) = (P) + EI_NIDENT; \
|
|
} while (0)
|
|
|
|
#define ROUNDUP2(V,N) (V) = ((((V) + (N) - 1)) & ~((N) - 1))
|
|
|
|
/*[*/
|
|
|
|
static int
|
|
_libelf_cvt_ADDR32_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf32_Addr t, *s = (Elf32_Addr *) (uintptr_t) src;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
if (!byteswap) {
|
|
(void) memcpy(dst, src, count * sizeof(*s));
|
|
return (1);
|
|
}
|
|
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
SWAP_ADDR32(t);
|
|
WRITE_ADDR32(dst,t);
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_ADDR32_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf32_Addr t, *d = (Elf32_Addr *) (uintptr_t) dst;
|
|
size_t c;
|
|
|
|
if (dsz < count * sizeof(Elf32_Addr))
|
|
return (0);
|
|
|
|
if (!byteswap) {
|
|
(void) memcpy(dst, src, count * sizeof(*d));
|
|
return (1);
|
|
}
|
|
|
|
for (c = 0; c < count; c++) {
|
|
READ_ADDR32(src,t);
|
|
SWAP_ADDR32(t);
|
|
*d++ = t;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_ADDR64_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Addr t, *s = (Elf64_Addr *) (uintptr_t) src;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
if (!byteswap) {
|
|
(void) memcpy(dst, src, count * sizeof(*s));
|
|
return (1);
|
|
}
|
|
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
SWAP_ADDR64(t);
|
|
WRITE_ADDR64(dst,t);
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_ADDR64_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Addr t, *d = (Elf64_Addr *) (uintptr_t) dst;
|
|
size_t c;
|
|
|
|
if (dsz < count * sizeof(Elf64_Addr))
|
|
return (0);
|
|
|
|
if (!byteswap) {
|
|
(void) memcpy(dst, src, count * sizeof(*d));
|
|
return (1);
|
|
}
|
|
|
|
for (c = 0; c < count; c++) {
|
|
READ_ADDR64(src,t);
|
|
SWAP_ADDR64(t);
|
|
*d++ = t;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_CAP32_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf32_Cap t, *s;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
s = (Elf32_Cap *) (uintptr_t) src;
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
if (byteswap) {
|
|
/* Swap an Elf32_Cap */
|
|
SWAP_WORD(t.c_tag);
|
|
SWAP_WORD(t.c_un.c_val);
|
|
/**/
|
|
}
|
|
/* Write an Elf32_Cap */
|
|
WRITE_WORD(dst,t.c_tag);
|
|
WRITE_WORD(dst,t.c_un.c_val);
|
|
/**/
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_CAP32_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf32_Cap t, *d;
|
|
char *s,*s0;
|
|
size_t fsz;
|
|
|
|
fsz = elf32_fsize(ELF_T_CAP, (size_t) 1, EV_CURRENT);
|
|
d = ((Elf32_Cap *) (uintptr_t) dst) + (count - 1);
|
|
s0 = (char *) src + (count - 1) * fsz;
|
|
|
|
if (dsz < count * sizeof(Elf32_Cap))
|
|
return (0);
|
|
|
|
while (count--) {
|
|
s = s0;
|
|
/* Read an Elf32_Cap */
|
|
READ_WORD(s,t.c_tag);
|
|
READ_WORD(s,t.c_un.c_val);
|
|
/**/
|
|
if (byteswap) {
|
|
/* Swap an Elf32_Cap */
|
|
SWAP_WORD(t.c_tag);
|
|
SWAP_WORD(t.c_un.c_val);
|
|
/**/
|
|
}
|
|
*d-- = t; s0 -= fsz;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_CAP64_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Cap t, *s;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
s = (Elf64_Cap *) (uintptr_t) src;
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
if (byteswap) {
|
|
/* Swap an Elf64_Cap */
|
|
SWAP_XWORD(t.c_tag);
|
|
SWAP_XWORD(t.c_un.c_val);
|
|
/**/
|
|
}
|
|
/* Write an Elf64_Cap */
|
|
WRITE_XWORD(dst,t.c_tag);
|
|
WRITE_XWORD(dst,t.c_un.c_val);
|
|
/**/
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_CAP64_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Cap t, *d;
|
|
char *s,*s0;
|
|
size_t fsz;
|
|
|
|
fsz = elf64_fsize(ELF_T_CAP, (size_t) 1, EV_CURRENT);
|
|
d = ((Elf64_Cap *) (uintptr_t) dst) + (count - 1);
|
|
s0 = (char *) src + (count - 1) * fsz;
|
|
|
|
if (dsz < count * sizeof(Elf64_Cap))
|
|
return (0);
|
|
|
|
while (count--) {
|
|
s = s0;
|
|
/* Read an Elf64_Cap */
|
|
READ_XWORD(s,t.c_tag);
|
|
READ_XWORD(s,t.c_un.c_val);
|
|
/**/
|
|
if (byteswap) {
|
|
/* Swap an Elf64_Cap */
|
|
SWAP_XWORD(t.c_tag);
|
|
SWAP_XWORD(t.c_un.c_val);
|
|
/**/
|
|
}
|
|
*d-- = t; s0 -= fsz;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_DYN32_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf32_Dyn t, *s;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
s = (Elf32_Dyn *) (uintptr_t) src;
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
if (byteswap) {
|
|
/* Swap an Elf32_Dyn */
|
|
SWAP_SWORD(t.d_tag);
|
|
SWAP_WORD(t.d_un.d_ptr);
|
|
/**/
|
|
}
|
|
/* Write an Elf32_Dyn */
|
|
WRITE_SWORD(dst,t.d_tag);
|
|
WRITE_WORD(dst,t.d_un.d_ptr);
|
|
/**/
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_DYN32_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf32_Dyn t, *d;
|
|
char *s,*s0;
|
|
size_t fsz;
|
|
|
|
fsz = elf32_fsize(ELF_T_DYN, (size_t) 1, EV_CURRENT);
|
|
d = ((Elf32_Dyn *) (uintptr_t) dst) + (count - 1);
|
|
s0 = (char *) src + (count - 1) * fsz;
|
|
|
|
if (dsz < count * sizeof(Elf32_Dyn))
|
|
return (0);
|
|
|
|
while (count--) {
|
|
s = s0;
|
|
/* Read an Elf32_Dyn */
|
|
READ_SWORD(s,t.d_tag);
|
|
READ_WORD(s,t.d_un.d_ptr);
|
|
/**/
|
|
if (byteswap) {
|
|
/* Swap an Elf32_Dyn */
|
|
SWAP_SWORD(t.d_tag);
|
|
SWAP_WORD(t.d_un.d_ptr);
|
|
/**/
|
|
}
|
|
*d-- = t; s0 -= fsz;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_DYN64_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Dyn t, *s;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
s = (Elf64_Dyn *) (uintptr_t) src;
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
if (byteswap) {
|
|
/* Swap an Elf64_Dyn */
|
|
SWAP_SXWORD(t.d_tag);
|
|
SWAP_XWORD(t.d_un.d_ptr);
|
|
/**/
|
|
}
|
|
/* Write an Elf64_Dyn */
|
|
WRITE_SXWORD(dst,t.d_tag);
|
|
WRITE_XWORD(dst,t.d_un.d_ptr);
|
|
/**/
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_DYN64_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Dyn t, *d;
|
|
char *s,*s0;
|
|
size_t fsz;
|
|
|
|
fsz = elf64_fsize(ELF_T_DYN, (size_t) 1, EV_CURRENT);
|
|
d = ((Elf64_Dyn *) (uintptr_t) dst) + (count - 1);
|
|
s0 = (char *) src + (count - 1) * fsz;
|
|
|
|
if (dsz < count * sizeof(Elf64_Dyn))
|
|
return (0);
|
|
|
|
while (count--) {
|
|
s = s0;
|
|
/* Read an Elf64_Dyn */
|
|
READ_SXWORD(s,t.d_tag);
|
|
READ_XWORD(s,t.d_un.d_ptr);
|
|
/**/
|
|
if (byteswap) {
|
|
/* Swap an Elf64_Dyn */
|
|
SWAP_SXWORD(t.d_tag);
|
|
SWAP_XWORD(t.d_un.d_ptr);
|
|
/**/
|
|
}
|
|
*d-- = t; s0 -= fsz;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_EHDR32_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf32_Ehdr t, *s;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
s = (Elf32_Ehdr *) (uintptr_t) src;
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
if (byteswap) {
|
|
/* Swap an Elf32_Ehdr */
|
|
SWAP_IDENT(t.e_ident);
|
|
SWAP_HALF(t.e_type);
|
|
SWAP_HALF(t.e_machine);
|
|
SWAP_WORD(t.e_version);
|
|
SWAP_ADDR32(t.e_entry);
|
|
SWAP_OFF32(t.e_phoff);
|
|
SWAP_OFF32(t.e_shoff);
|
|
SWAP_WORD(t.e_flags);
|
|
SWAP_HALF(t.e_ehsize);
|
|
SWAP_HALF(t.e_phentsize);
|
|
SWAP_HALF(t.e_phnum);
|
|
SWAP_HALF(t.e_shentsize);
|
|
SWAP_HALF(t.e_shnum);
|
|
SWAP_HALF(t.e_shstrndx);
|
|
/**/
|
|
}
|
|
/* Write an Elf32_Ehdr */
|
|
WRITE_IDENT(dst,t.e_ident);
|
|
WRITE_HALF(dst,t.e_type);
|
|
WRITE_HALF(dst,t.e_machine);
|
|
WRITE_WORD(dst,t.e_version);
|
|
WRITE_ADDR32(dst,t.e_entry);
|
|
WRITE_OFF32(dst,t.e_phoff);
|
|
WRITE_OFF32(dst,t.e_shoff);
|
|
WRITE_WORD(dst,t.e_flags);
|
|
WRITE_HALF(dst,t.e_ehsize);
|
|
WRITE_HALF(dst,t.e_phentsize);
|
|
WRITE_HALF(dst,t.e_phnum);
|
|
WRITE_HALF(dst,t.e_shentsize);
|
|
WRITE_HALF(dst,t.e_shnum);
|
|
WRITE_HALF(dst,t.e_shstrndx);
|
|
/**/
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_EHDR32_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf32_Ehdr t, *d;
|
|
char *s,*s0;
|
|
size_t fsz;
|
|
|
|
fsz = elf32_fsize(ELF_T_EHDR, (size_t) 1, EV_CURRENT);
|
|
d = ((Elf32_Ehdr *) (uintptr_t) dst) + (count - 1);
|
|
s0 = (char *) src + (count - 1) * fsz;
|
|
|
|
if (dsz < count * sizeof(Elf32_Ehdr))
|
|
return (0);
|
|
|
|
while (count--) {
|
|
s = s0;
|
|
/* Read an Elf32_Ehdr */
|
|
READ_IDENT(s,t.e_ident);
|
|
READ_HALF(s,t.e_type);
|
|
READ_HALF(s,t.e_machine);
|
|
READ_WORD(s,t.e_version);
|
|
READ_ADDR32(s,t.e_entry);
|
|
READ_OFF32(s,t.e_phoff);
|
|
READ_OFF32(s,t.e_shoff);
|
|
READ_WORD(s,t.e_flags);
|
|
READ_HALF(s,t.e_ehsize);
|
|
READ_HALF(s,t.e_phentsize);
|
|
READ_HALF(s,t.e_phnum);
|
|
READ_HALF(s,t.e_shentsize);
|
|
READ_HALF(s,t.e_shnum);
|
|
READ_HALF(s,t.e_shstrndx);
|
|
/**/
|
|
if (byteswap) {
|
|
/* Swap an Elf32_Ehdr */
|
|
SWAP_IDENT(t.e_ident);
|
|
SWAP_HALF(t.e_type);
|
|
SWAP_HALF(t.e_machine);
|
|
SWAP_WORD(t.e_version);
|
|
SWAP_ADDR32(t.e_entry);
|
|
SWAP_OFF32(t.e_phoff);
|
|
SWAP_OFF32(t.e_shoff);
|
|
SWAP_WORD(t.e_flags);
|
|
SWAP_HALF(t.e_ehsize);
|
|
SWAP_HALF(t.e_phentsize);
|
|
SWAP_HALF(t.e_phnum);
|
|
SWAP_HALF(t.e_shentsize);
|
|
SWAP_HALF(t.e_shnum);
|
|
SWAP_HALF(t.e_shstrndx);
|
|
/**/
|
|
}
|
|
*d-- = t; s0 -= fsz;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_EHDR64_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Ehdr t, *s;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
s = (Elf64_Ehdr *) (uintptr_t) src;
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
if (byteswap) {
|
|
/* Swap an Elf64_Ehdr */
|
|
SWAP_IDENT(t.e_ident);
|
|
SWAP_HALF(t.e_type);
|
|
SWAP_HALF(t.e_machine);
|
|
SWAP_WORD(t.e_version);
|
|
SWAP_ADDR64(t.e_entry);
|
|
SWAP_OFF64(t.e_phoff);
|
|
SWAP_OFF64(t.e_shoff);
|
|
SWAP_WORD(t.e_flags);
|
|
SWAP_HALF(t.e_ehsize);
|
|
SWAP_HALF(t.e_phentsize);
|
|
SWAP_HALF(t.e_phnum);
|
|
SWAP_HALF(t.e_shentsize);
|
|
SWAP_HALF(t.e_shnum);
|
|
SWAP_HALF(t.e_shstrndx);
|
|
/**/
|
|
}
|
|
/* Write an Elf64_Ehdr */
|
|
WRITE_IDENT(dst,t.e_ident);
|
|
WRITE_HALF(dst,t.e_type);
|
|
WRITE_HALF(dst,t.e_machine);
|
|
WRITE_WORD(dst,t.e_version);
|
|
WRITE_ADDR64(dst,t.e_entry);
|
|
WRITE_OFF64(dst,t.e_phoff);
|
|
WRITE_OFF64(dst,t.e_shoff);
|
|
WRITE_WORD(dst,t.e_flags);
|
|
WRITE_HALF(dst,t.e_ehsize);
|
|
WRITE_HALF(dst,t.e_phentsize);
|
|
WRITE_HALF(dst,t.e_phnum);
|
|
WRITE_HALF(dst,t.e_shentsize);
|
|
WRITE_HALF(dst,t.e_shnum);
|
|
WRITE_HALF(dst,t.e_shstrndx);
|
|
/**/
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_EHDR64_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Ehdr t, *d;
|
|
char *s,*s0;
|
|
size_t fsz;
|
|
|
|
fsz = elf64_fsize(ELF_T_EHDR, (size_t) 1, EV_CURRENT);
|
|
d = ((Elf64_Ehdr *) (uintptr_t) dst) + (count - 1);
|
|
s0 = (char *) src + (count - 1) * fsz;
|
|
|
|
if (dsz < count * sizeof(Elf64_Ehdr))
|
|
return (0);
|
|
|
|
while (count--) {
|
|
s = s0;
|
|
/* Read an Elf64_Ehdr */
|
|
READ_IDENT(s,t.e_ident);
|
|
READ_HALF(s,t.e_type);
|
|
READ_HALF(s,t.e_machine);
|
|
READ_WORD(s,t.e_version);
|
|
READ_ADDR64(s,t.e_entry);
|
|
READ_OFF64(s,t.e_phoff);
|
|
READ_OFF64(s,t.e_shoff);
|
|
READ_WORD(s,t.e_flags);
|
|
READ_HALF(s,t.e_ehsize);
|
|
READ_HALF(s,t.e_phentsize);
|
|
READ_HALF(s,t.e_phnum);
|
|
READ_HALF(s,t.e_shentsize);
|
|
READ_HALF(s,t.e_shnum);
|
|
READ_HALF(s,t.e_shstrndx);
|
|
/**/
|
|
if (byteswap) {
|
|
/* Swap an Elf64_Ehdr */
|
|
SWAP_IDENT(t.e_ident);
|
|
SWAP_HALF(t.e_type);
|
|
SWAP_HALF(t.e_machine);
|
|
SWAP_WORD(t.e_version);
|
|
SWAP_ADDR64(t.e_entry);
|
|
SWAP_OFF64(t.e_phoff);
|
|
SWAP_OFF64(t.e_shoff);
|
|
SWAP_WORD(t.e_flags);
|
|
SWAP_HALF(t.e_ehsize);
|
|
SWAP_HALF(t.e_phentsize);
|
|
SWAP_HALF(t.e_phnum);
|
|
SWAP_HALF(t.e_shentsize);
|
|
SWAP_HALF(t.e_shnum);
|
|
SWAP_HALF(t.e_shstrndx);
|
|
/**/
|
|
}
|
|
*d-- = t; s0 -= fsz;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_HALF_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Half t, *s = (Elf64_Half *) (uintptr_t) src;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
if (!byteswap) {
|
|
(void) memcpy(dst, src, count * sizeof(*s));
|
|
return (1);
|
|
}
|
|
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
SWAP_HALF(t);
|
|
WRITE_HALF(dst,t);
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_HALF_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Half t, *d = (Elf64_Half *) (uintptr_t) dst;
|
|
size_t c;
|
|
|
|
if (dsz < count * sizeof(Elf64_Half))
|
|
return (0);
|
|
|
|
if (!byteswap) {
|
|
(void) memcpy(dst, src, count * sizeof(*d));
|
|
return (1);
|
|
}
|
|
|
|
for (c = 0; c < count; c++) {
|
|
READ_HALF(src,t);
|
|
SWAP_HALF(t);
|
|
*d++ = t;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_LWORD_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Lword t, *s = (Elf64_Lword *) (uintptr_t) src;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
if (!byteswap) {
|
|
(void) memcpy(dst, src, count * sizeof(*s));
|
|
return (1);
|
|
}
|
|
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
SWAP_LWORD(t);
|
|
WRITE_LWORD(dst,t);
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_LWORD_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Lword t, *d = (Elf64_Lword *) (uintptr_t) dst;
|
|
size_t c;
|
|
|
|
if (dsz < count * sizeof(Elf64_Lword))
|
|
return (0);
|
|
|
|
if (!byteswap) {
|
|
(void) memcpy(dst, src, count * sizeof(*d));
|
|
return (1);
|
|
}
|
|
|
|
for (c = 0; c < count; c++) {
|
|
READ_LWORD(src,t);
|
|
SWAP_LWORD(t);
|
|
*d++ = t;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_MOVE32_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf32_Move t, *s;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
s = (Elf32_Move *) (uintptr_t) src;
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
if (byteswap) {
|
|
/* Swap an Elf32_Move */
|
|
SWAP_LWORD(t.m_value);
|
|
SWAP_WORD(t.m_info);
|
|
SWAP_WORD(t.m_poffset);
|
|
SWAP_HALF(t.m_repeat);
|
|
SWAP_HALF(t.m_stride);
|
|
/**/
|
|
}
|
|
/* Write an Elf32_Move */
|
|
WRITE_LWORD(dst,t.m_value);
|
|
WRITE_WORD(dst,t.m_info);
|
|
WRITE_WORD(dst,t.m_poffset);
|
|
WRITE_HALF(dst,t.m_repeat);
|
|
WRITE_HALF(dst,t.m_stride);
|
|
/**/
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_MOVE32_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf32_Move t, *d;
|
|
char *s,*s0;
|
|
size_t fsz;
|
|
|
|
fsz = elf32_fsize(ELF_T_MOVE, (size_t) 1, EV_CURRENT);
|
|
d = ((Elf32_Move *) (uintptr_t) dst) + (count - 1);
|
|
s0 = (char *) src + (count - 1) * fsz;
|
|
|
|
if (dsz < count * sizeof(Elf32_Move))
|
|
return (0);
|
|
|
|
while (count--) {
|
|
s = s0;
|
|
/* Read an Elf32_Move */
|
|
READ_LWORD(s,t.m_value);
|
|
READ_WORD(s,t.m_info);
|
|
READ_WORD(s,t.m_poffset);
|
|
READ_HALF(s,t.m_repeat);
|
|
READ_HALF(s,t.m_stride);
|
|
/**/
|
|
if (byteswap) {
|
|
/* Swap an Elf32_Move */
|
|
SWAP_LWORD(t.m_value);
|
|
SWAP_WORD(t.m_info);
|
|
SWAP_WORD(t.m_poffset);
|
|
SWAP_HALF(t.m_repeat);
|
|
SWAP_HALF(t.m_stride);
|
|
/**/
|
|
}
|
|
*d-- = t; s0 -= fsz;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_MOVE64_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Move t, *s;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
s = (Elf64_Move *) (uintptr_t) src;
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
if (byteswap) {
|
|
/* Swap an Elf64_Move */
|
|
SWAP_LWORD(t.m_value);
|
|
SWAP_XWORD(t.m_info);
|
|
SWAP_XWORD(t.m_poffset);
|
|
SWAP_HALF(t.m_repeat);
|
|
SWAP_HALF(t.m_stride);
|
|
/**/
|
|
}
|
|
/* Write an Elf64_Move */
|
|
WRITE_LWORD(dst,t.m_value);
|
|
WRITE_XWORD(dst,t.m_info);
|
|
WRITE_XWORD(dst,t.m_poffset);
|
|
WRITE_HALF(dst,t.m_repeat);
|
|
WRITE_HALF(dst,t.m_stride);
|
|
/**/
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_MOVE64_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Move t, *d;
|
|
char *s,*s0;
|
|
size_t fsz;
|
|
|
|
fsz = elf64_fsize(ELF_T_MOVE, (size_t) 1, EV_CURRENT);
|
|
d = ((Elf64_Move *) (uintptr_t) dst) + (count - 1);
|
|
s0 = (char *) src + (count - 1) * fsz;
|
|
|
|
if (dsz < count * sizeof(Elf64_Move))
|
|
return (0);
|
|
|
|
while (count--) {
|
|
s = s0;
|
|
/* Read an Elf64_Move */
|
|
READ_LWORD(s,t.m_value);
|
|
READ_XWORD(s,t.m_info);
|
|
READ_XWORD(s,t.m_poffset);
|
|
READ_HALF(s,t.m_repeat);
|
|
READ_HALF(s,t.m_stride);
|
|
/**/
|
|
if (byteswap) {
|
|
/* Swap an Elf64_Move */
|
|
SWAP_LWORD(t.m_value);
|
|
SWAP_XWORD(t.m_info);
|
|
SWAP_XWORD(t.m_poffset);
|
|
SWAP_HALF(t.m_repeat);
|
|
SWAP_HALF(t.m_stride);
|
|
/**/
|
|
}
|
|
*d-- = t; s0 -= fsz;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_OFF32_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf32_Off t, *s = (Elf32_Off *) (uintptr_t) src;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
if (!byteswap) {
|
|
(void) memcpy(dst, src, count * sizeof(*s));
|
|
return (1);
|
|
}
|
|
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
SWAP_OFF32(t);
|
|
WRITE_OFF32(dst,t);
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_OFF32_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf32_Off t, *d = (Elf32_Off *) (uintptr_t) dst;
|
|
size_t c;
|
|
|
|
if (dsz < count * sizeof(Elf32_Off))
|
|
return (0);
|
|
|
|
if (!byteswap) {
|
|
(void) memcpy(dst, src, count * sizeof(*d));
|
|
return (1);
|
|
}
|
|
|
|
for (c = 0; c < count; c++) {
|
|
READ_OFF32(src,t);
|
|
SWAP_OFF32(t);
|
|
*d++ = t;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_OFF64_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Off t, *s = (Elf64_Off *) (uintptr_t) src;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
if (!byteswap) {
|
|
(void) memcpy(dst, src, count * sizeof(*s));
|
|
return (1);
|
|
}
|
|
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
SWAP_OFF64(t);
|
|
WRITE_OFF64(dst,t);
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_OFF64_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Off t, *d = (Elf64_Off *) (uintptr_t) dst;
|
|
size_t c;
|
|
|
|
if (dsz < count * sizeof(Elf64_Off))
|
|
return (0);
|
|
|
|
if (!byteswap) {
|
|
(void) memcpy(dst, src, count * sizeof(*d));
|
|
return (1);
|
|
}
|
|
|
|
for (c = 0; c < count; c++) {
|
|
READ_OFF64(src,t);
|
|
SWAP_OFF64(t);
|
|
*d++ = t;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_PHDR32_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf32_Phdr t, *s;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
s = (Elf32_Phdr *) (uintptr_t) src;
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
if (byteswap) {
|
|
/* Swap an Elf32_Phdr */
|
|
SWAP_WORD(t.p_type);
|
|
SWAP_OFF32(t.p_offset);
|
|
SWAP_ADDR32(t.p_vaddr);
|
|
SWAP_ADDR32(t.p_paddr);
|
|
SWAP_WORD(t.p_filesz);
|
|
SWAP_WORD(t.p_memsz);
|
|
SWAP_WORD(t.p_flags);
|
|
SWAP_WORD(t.p_align);
|
|
/**/
|
|
}
|
|
/* Write an Elf32_Phdr */
|
|
WRITE_WORD(dst,t.p_type);
|
|
WRITE_OFF32(dst,t.p_offset);
|
|
WRITE_ADDR32(dst,t.p_vaddr);
|
|
WRITE_ADDR32(dst,t.p_paddr);
|
|
WRITE_WORD(dst,t.p_filesz);
|
|
WRITE_WORD(dst,t.p_memsz);
|
|
WRITE_WORD(dst,t.p_flags);
|
|
WRITE_WORD(dst,t.p_align);
|
|
/**/
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_PHDR32_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf32_Phdr t, *d;
|
|
char *s,*s0;
|
|
size_t fsz;
|
|
|
|
fsz = elf32_fsize(ELF_T_PHDR, (size_t) 1, EV_CURRENT);
|
|
d = ((Elf32_Phdr *) (uintptr_t) dst) + (count - 1);
|
|
s0 = (char *) src + (count - 1) * fsz;
|
|
|
|
if (dsz < count * sizeof(Elf32_Phdr))
|
|
return (0);
|
|
|
|
while (count--) {
|
|
s = s0;
|
|
/* Read an Elf32_Phdr */
|
|
READ_WORD(s,t.p_type);
|
|
READ_OFF32(s,t.p_offset);
|
|
READ_ADDR32(s,t.p_vaddr);
|
|
READ_ADDR32(s,t.p_paddr);
|
|
READ_WORD(s,t.p_filesz);
|
|
READ_WORD(s,t.p_memsz);
|
|
READ_WORD(s,t.p_flags);
|
|
READ_WORD(s,t.p_align);
|
|
/**/
|
|
if (byteswap) {
|
|
/* Swap an Elf32_Phdr */
|
|
SWAP_WORD(t.p_type);
|
|
SWAP_OFF32(t.p_offset);
|
|
SWAP_ADDR32(t.p_vaddr);
|
|
SWAP_ADDR32(t.p_paddr);
|
|
SWAP_WORD(t.p_filesz);
|
|
SWAP_WORD(t.p_memsz);
|
|
SWAP_WORD(t.p_flags);
|
|
SWAP_WORD(t.p_align);
|
|
/**/
|
|
}
|
|
*d-- = t; s0 -= fsz;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_PHDR64_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Phdr t, *s;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
s = (Elf64_Phdr *) (uintptr_t) src;
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
if (byteswap) {
|
|
/* Swap an Elf64_Phdr */
|
|
SWAP_WORD(t.p_type);
|
|
SWAP_WORD(t.p_flags);
|
|
SWAP_OFF64(t.p_offset);
|
|
SWAP_ADDR64(t.p_vaddr);
|
|
SWAP_ADDR64(t.p_paddr);
|
|
SWAP_XWORD(t.p_filesz);
|
|
SWAP_XWORD(t.p_memsz);
|
|
SWAP_XWORD(t.p_align);
|
|
/**/
|
|
}
|
|
/* Write an Elf64_Phdr */
|
|
WRITE_WORD(dst,t.p_type);
|
|
WRITE_WORD(dst,t.p_flags);
|
|
WRITE_OFF64(dst,t.p_offset);
|
|
WRITE_ADDR64(dst,t.p_vaddr);
|
|
WRITE_ADDR64(dst,t.p_paddr);
|
|
WRITE_XWORD(dst,t.p_filesz);
|
|
WRITE_XWORD(dst,t.p_memsz);
|
|
WRITE_XWORD(dst,t.p_align);
|
|
/**/
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_PHDR64_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Phdr t, *d;
|
|
char *s,*s0;
|
|
size_t fsz;
|
|
|
|
fsz = elf64_fsize(ELF_T_PHDR, (size_t) 1, EV_CURRENT);
|
|
d = ((Elf64_Phdr *) (uintptr_t) dst) + (count - 1);
|
|
s0 = (char *) src + (count - 1) * fsz;
|
|
|
|
if (dsz < count * sizeof(Elf64_Phdr))
|
|
return (0);
|
|
|
|
while (count--) {
|
|
s = s0;
|
|
/* Read an Elf64_Phdr */
|
|
READ_WORD(s,t.p_type);
|
|
READ_WORD(s,t.p_flags);
|
|
READ_OFF64(s,t.p_offset);
|
|
READ_ADDR64(s,t.p_vaddr);
|
|
READ_ADDR64(s,t.p_paddr);
|
|
READ_XWORD(s,t.p_filesz);
|
|
READ_XWORD(s,t.p_memsz);
|
|
READ_XWORD(s,t.p_align);
|
|
/**/
|
|
if (byteswap) {
|
|
/* Swap an Elf64_Phdr */
|
|
SWAP_WORD(t.p_type);
|
|
SWAP_WORD(t.p_flags);
|
|
SWAP_OFF64(t.p_offset);
|
|
SWAP_ADDR64(t.p_vaddr);
|
|
SWAP_ADDR64(t.p_paddr);
|
|
SWAP_XWORD(t.p_filesz);
|
|
SWAP_XWORD(t.p_memsz);
|
|
SWAP_XWORD(t.p_align);
|
|
/**/
|
|
}
|
|
*d-- = t; s0 -= fsz;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_REL32_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf32_Rel t, *s;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
s = (Elf32_Rel *) (uintptr_t) src;
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
if (byteswap) {
|
|
/* Swap an Elf32_Rel */
|
|
SWAP_ADDR32(t.r_offset);
|
|
SWAP_WORD(t.r_info);
|
|
/**/
|
|
}
|
|
/* Write an Elf32_Rel */
|
|
WRITE_ADDR32(dst,t.r_offset);
|
|
WRITE_WORD(dst,t.r_info);
|
|
/**/
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_REL32_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf32_Rel t, *d;
|
|
char *s,*s0;
|
|
size_t fsz;
|
|
|
|
fsz = elf32_fsize(ELF_T_REL, (size_t) 1, EV_CURRENT);
|
|
d = ((Elf32_Rel *) (uintptr_t) dst) + (count - 1);
|
|
s0 = (char *) src + (count - 1) * fsz;
|
|
|
|
if (dsz < count * sizeof(Elf32_Rel))
|
|
return (0);
|
|
|
|
while (count--) {
|
|
s = s0;
|
|
/* Read an Elf32_Rel */
|
|
READ_ADDR32(s,t.r_offset);
|
|
READ_WORD(s,t.r_info);
|
|
/**/
|
|
if (byteswap) {
|
|
/* Swap an Elf32_Rel */
|
|
SWAP_ADDR32(t.r_offset);
|
|
SWAP_WORD(t.r_info);
|
|
/**/
|
|
}
|
|
*d-- = t; s0 -= fsz;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_REL64_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Rel t, *s;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
s = (Elf64_Rel *) (uintptr_t) src;
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
if (byteswap) {
|
|
/* Swap an Elf64_Rel */
|
|
SWAP_ADDR64(t.r_offset);
|
|
SWAP_XWORD(t.r_info);
|
|
/**/
|
|
}
|
|
/* Write an Elf64_Rel */
|
|
WRITE_ADDR64(dst,t.r_offset);
|
|
WRITE_XWORD(dst,t.r_info);
|
|
/**/
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_REL64_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Rel t, *d;
|
|
char *s,*s0;
|
|
size_t fsz;
|
|
|
|
fsz = elf64_fsize(ELF_T_REL, (size_t) 1, EV_CURRENT);
|
|
d = ((Elf64_Rel *) (uintptr_t) dst) + (count - 1);
|
|
s0 = (char *) src + (count - 1) * fsz;
|
|
|
|
if (dsz < count * sizeof(Elf64_Rel))
|
|
return (0);
|
|
|
|
while (count--) {
|
|
s = s0;
|
|
/* Read an Elf64_Rel */
|
|
READ_ADDR64(s,t.r_offset);
|
|
READ_XWORD(s,t.r_info);
|
|
/**/
|
|
if (byteswap) {
|
|
/* Swap an Elf64_Rel */
|
|
SWAP_ADDR64(t.r_offset);
|
|
SWAP_XWORD(t.r_info);
|
|
/**/
|
|
}
|
|
*d-- = t; s0 -= fsz;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_RELA32_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf32_Rela t, *s;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
s = (Elf32_Rela *) (uintptr_t) src;
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
if (byteswap) {
|
|
/* Swap an Elf32_Rela */
|
|
SWAP_ADDR32(t.r_offset);
|
|
SWAP_WORD(t.r_info);
|
|
SWAP_SWORD(t.r_addend);
|
|
/**/
|
|
}
|
|
/* Write an Elf32_Rela */
|
|
WRITE_ADDR32(dst,t.r_offset);
|
|
WRITE_WORD(dst,t.r_info);
|
|
WRITE_SWORD(dst,t.r_addend);
|
|
/**/
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_RELA32_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf32_Rela t, *d;
|
|
char *s,*s0;
|
|
size_t fsz;
|
|
|
|
fsz = elf32_fsize(ELF_T_RELA, (size_t) 1, EV_CURRENT);
|
|
d = ((Elf32_Rela *) (uintptr_t) dst) + (count - 1);
|
|
s0 = (char *) src + (count - 1) * fsz;
|
|
|
|
if (dsz < count * sizeof(Elf32_Rela))
|
|
return (0);
|
|
|
|
while (count--) {
|
|
s = s0;
|
|
/* Read an Elf32_Rela */
|
|
READ_ADDR32(s,t.r_offset);
|
|
READ_WORD(s,t.r_info);
|
|
READ_SWORD(s,t.r_addend);
|
|
/**/
|
|
if (byteswap) {
|
|
/* Swap an Elf32_Rela */
|
|
SWAP_ADDR32(t.r_offset);
|
|
SWAP_WORD(t.r_info);
|
|
SWAP_SWORD(t.r_addend);
|
|
/**/
|
|
}
|
|
*d-- = t; s0 -= fsz;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_RELA64_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Rela t, *s;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
s = (Elf64_Rela *) (uintptr_t) src;
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
if (byteswap) {
|
|
/* Swap an Elf64_Rela */
|
|
SWAP_ADDR64(t.r_offset);
|
|
SWAP_XWORD(t.r_info);
|
|
SWAP_SXWORD(t.r_addend);
|
|
/**/
|
|
}
|
|
/* Write an Elf64_Rela */
|
|
WRITE_ADDR64(dst,t.r_offset);
|
|
WRITE_XWORD(dst,t.r_info);
|
|
WRITE_SXWORD(dst,t.r_addend);
|
|
/**/
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_RELA64_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Rela t, *d;
|
|
char *s,*s0;
|
|
size_t fsz;
|
|
|
|
fsz = elf64_fsize(ELF_T_RELA, (size_t) 1, EV_CURRENT);
|
|
d = ((Elf64_Rela *) (uintptr_t) dst) + (count - 1);
|
|
s0 = (char *) src + (count - 1) * fsz;
|
|
|
|
if (dsz < count * sizeof(Elf64_Rela))
|
|
return (0);
|
|
|
|
while (count--) {
|
|
s = s0;
|
|
/* Read an Elf64_Rela */
|
|
READ_ADDR64(s,t.r_offset);
|
|
READ_XWORD(s,t.r_info);
|
|
READ_SXWORD(s,t.r_addend);
|
|
/**/
|
|
if (byteswap) {
|
|
/* Swap an Elf64_Rela */
|
|
SWAP_ADDR64(t.r_offset);
|
|
SWAP_XWORD(t.r_info);
|
|
SWAP_SXWORD(t.r_addend);
|
|
/**/
|
|
}
|
|
*d-- = t; s0 -= fsz;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_SHDR32_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf32_Shdr t, *s;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
s = (Elf32_Shdr *) (uintptr_t) src;
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
if (byteswap) {
|
|
/* Swap an Elf32_Shdr */
|
|
SWAP_WORD(t.sh_name);
|
|
SWAP_WORD(t.sh_type);
|
|
SWAP_WORD(t.sh_flags);
|
|
SWAP_ADDR32(t.sh_addr);
|
|
SWAP_OFF32(t.sh_offset);
|
|
SWAP_WORD(t.sh_size);
|
|
SWAP_WORD(t.sh_link);
|
|
SWAP_WORD(t.sh_info);
|
|
SWAP_WORD(t.sh_addralign);
|
|
SWAP_WORD(t.sh_entsize);
|
|
/**/
|
|
}
|
|
/* Write an Elf32_Shdr */
|
|
WRITE_WORD(dst,t.sh_name);
|
|
WRITE_WORD(dst,t.sh_type);
|
|
WRITE_WORD(dst,t.sh_flags);
|
|
WRITE_ADDR32(dst,t.sh_addr);
|
|
WRITE_OFF32(dst,t.sh_offset);
|
|
WRITE_WORD(dst,t.sh_size);
|
|
WRITE_WORD(dst,t.sh_link);
|
|
WRITE_WORD(dst,t.sh_info);
|
|
WRITE_WORD(dst,t.sh_addralign);
|
|
WRITE_WORD(dst,t.sh_entsize);
|
|
/**/
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_SHDR32_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf32_Shdr t, *d;
|
|
char *s,*s0;
|
|
size_t fsz;
|
|
|
|
fsz = elf32_fsize(ELF_T_SHDR, (size_t) 1, EV_CURRENT);
|
|
d = ((Elf32_Shdr *) (uintptr_t) dst) + (count - 1);
|
|
s0 = (char *) src + (count - 1) * fsz;
|
|
|
|
if (dsz < count * sizeof(Elf32_Shdr))
|
|
return (0);
|
|
|
|
while (count--) {
|
|
s = s0;
|
|
/* Read an Elf32_Shdr */
|
|
READ_WORD(s,t.sh_name);
|
|
READ_WORD(s,t.sh_type);
|
|
READ_WORD(s,t.sh_flags);
|
|
READ_ADDR32(s,t.sh_addr);
|
|
READ_OFF32(s,t.sh_offset);
|
|
READ_WORD(s,t.sh_size);
|
|
READ_WORD(s,t.sh_link);
|
|
READ_WORD(s,t.sh_info);
|
|
READ_WORD(s,t.sh_addralign);
|
|
READ_WORD(s,t.sh_entsize);
|
|
/**/
|
|
if (byteswap) {
|
|
/* Swap an Elf32_Shdr */
|
|
SWAP_WORD(t.sh_name);
|
|
SWAP_WORD(t.sh_type);
|
|
SWAP_WORD(t.sh_flags);
|
|
SWAP_ADDR32(t.sh_addr);
|
|
SWAP_OFF32(t.sh_offset);
|
|
SWAP_WORD(t.sh_size);
|
|
SWAP_WORD(t.sh_link);
|
|
SWAP_WORD(t.sh_info);
|
|
SWAP_WORD(t.sh_addralign);
|
|
SWAP_WORD(t.sh_entsize);
|
|
/**/
|
|
}
|
|
*d-- = t; s0 -= fsz;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_SHDR64_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Shdr t, *s;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
s = (Elf64_Shdr *) (uintptr_t) src;
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
if (byteswap) {
|
|
/* Swap an Elf64_Shdr */
|
|
SWAP_WORD(t.sh_name);
|
|
SWAP_WORD(t.sh_type);
|
|
SWAP_XWORD(t.sh_flags);
|
|
SWAP_ADDR64(t.sh_addr);
|
|
SWAP_OFF64(t.sh_offset);
|
|
SWAP_XWORD(t.sh_size);
|
|
SWAP_WORD(t.sh_link);
|
|
SWAP_WORD(t.sh_info);
|
|
SWAP_XWORD(t.sh_addralign);
|
|
SWAP_XWORD(t.sh_entsize);
|
|
/**/
|
|
}
|
|
/* Write an Elf64_Shdr */
|
|
WRITE_WORD(dst,t.sh_name);
|
|
WRITE_WORD(dst,t.sh_type);
|
|
WRITE_XWORD(dst,t.sh_flags);
|
|
WRITE_ADDR64(dst,t.sh_addr);
|
|
WRITE_OFF64(dst,t.sh_offset);
|
|
WRITE_XWORD(dst,t.sh_size);
|
|
WRITE_WORD(dst,t.sh_link);
|
|
WRITE_WORD(dst,t.sh_info);
|
|
WRITE_XWORD(dst,t.sh_addralign);
|
|
WRITE_XWORD(dst,t.sh_entsize);
|
|
/**/
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_SHDR64_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Shdr t, *d;
|
|
char *s,*s0;
|
|
size_t fsz;
|
|
|
|
fsz = elf64_fsize(ELF_T_SHDR, (size_t) 1, EV_CURRENT);
|
|
d = ((Elf64_Shdr *) (uintptr_t) dst) + (count - 1);
|
|
s0 = (char *) src + (count - 1) * fsz;
|
|
|
|
if (dsz < count * sizeof(Elf64_Shdr))
|
|
return (0);
|
|
|
|
while (count--) {
|
|
s = s0;
|
|
/* Read an Elf64_Shdr */
|
|
READ_WORD(s,t.sh_name);
|
|
READ_WORD(s,t.sh_type);
|
|
READ_XWORD(s,t.sh_flags);
|
|
READ_ADDR64(s,t.sh_addr);
|
|
READ_OFF64(s,t.sh_offset);
|
|
READ_XWORD(s,t.sh_size);
|
|
READ_WORD(s,t.sh_link);
|
|
READ_WORD(s,t.sh_info);
|
|
READ_XWORD(s,t.sh_addralign);
|
|
READ_XWORD(s,t.sh_entsize);
|
|
/**/
|
|
if (byteswap) {
|
|
/* Swap an Elf64_Shdr */
|
|
SWAP_WORD(t.sh_name);
|
|
SWAP_WORD(t.sh_type);
|
|
SWAP_XWORD(t.sh_flags);
|
|
SWAP_ADDR64(t.sh_addr);
|
|
SWAP_OFF64(t.sh_offset);
|
|
SWAP_XWORD(t.sh_size);
|
|
SWAP_WORD(t.sh_link);
|
|
SWAP_WORD(t.sh_info);
|
|
SWAP_XWORD(t.sh_addralign);
|
|
SWAP_XWORD(t.sh_entsize);
|
|
/**/
|
|
}
|
|
*d-- = t; s0 -= fsz;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_SWORD_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Sword t, *s = (Elf64_Sword *) (uintptr_t) src;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
if (!byteswap) {
|
|
(void) memcpy(dst, src, count * sizeof(*s));
|
|
return (1);
|
|
}
|
|
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
SWAP_SWORD(t);
|
|
WRITE_SWORD(dst,t);
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_SWORD_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Sword t, *d = (Elf64_Sword *) (uintptr_t) dst;
|
|
size_t c;
|
|
|
|
if (dsz < count * sizeof(Elf64_Sword))
|
|
return (0);
|
|
|
|
if (!byteswap) {
|
|
(void) memcpy(dst, src, count * sizeof(*d));
|
|
return (1);
|
|
}
|
|
|
|
for (c = 0; c < count; c++) {
|
|
READ_SWORD(src,t);
|
|
SWAP_SWORD(t);
|
|
*d++ = t;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_SXWORD_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Sxword t, *s = (Elf64_Sxword *) (uintptr_t) src;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
if (!byteswap) {
|
|
(void) memcpy(dst, src, count * sizeof(*s));
|
|
return (1);
|
|
}
|
|
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
SWAP_SXWORD(t);
|
|
WRITE_SXWORD(dst,t);
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_SXWORD_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Sxword t, *d = (Elf64_Sxword *) (uintptr_t) dst;
|
|
size_t c;
|
|
|
|
if (dsz < count * sizeof(Elf64_Sxword))
|
|
return (0);
|
|
|
|
if (!byteswap) {
|
|
(void) memcpy(dst, src, count * sizeof(*d));
|
|
return (1);
|
|
}
|
|
|
|
for (c = 0; c < count; c++) {
|
|
READ_SXWORD(src,t);
|
|
SWAP_SXWORD(t);
|
|
*d++ = t;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_SYMINFO32_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf32_Syminfo t, *s;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
s = (Elf32_Syminfo *) (uintptr_t) src;
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
if (byteswap) {
|
|
/* Swap an Elf32_Syminfo */
|
|
SWAP_HALF(t.si_boundto);
|
|
SWAP_HALF(t.si_flags);
|
|
/**/
|
|
}
|
|
/* Write an Elf32_Syminfo */
|
|
WRITE_HALF(dst,t.si_boundto);
|
|
WRITE_HALF(dst,t.si_flags);
|
|
/**/
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_SYMINFO32_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf32_Syminfo t, *d;
|
|
char *s,*s0;
|
|
size_t fsz;
|
|
|
|
fsz = elf32_fsize(ELF_T_SYMINFO, (size_t) 1, EV_CURRENT);
|
|
d = ((Elf32_Syminfo *) (uintptr_t) dst) + (count - 1);
|
|
s0 = (char *) src + (count - 1) * fsz;
|
|
|
|
if (dsz < count * sizeof(Elf32_Syminfo))
|
|
return (0);
|
|
|
|
while (count--) {
|
|
s = s0;
|
|
/* Read an Elf32_Syminfo */
|
|
READ_HALF(s,t.si_boundto);
|
|
READ_HALF(s,t.si_flags);
|
|
/**/
|
|
if (byteswap) {
|
|
/* Swap an Elf32_Syminfo */
|
|
SWAP_HALF(t.si_boundto);
|
|
SWAP_HALF(t.si_flags);
|
|
/**/
|
|
}
|
|
*d-- = t; s0 -= fsz;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_SYMINFO64_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Syminfo t, *s;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
s = (Elf64_Syminfo *) (uintptr_t) src;
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
if (byteswap) {
|
|
/* Swap an Elf64_Syminfo */
|
|
SWAP_HALF(t.si_boundto);
|
|
SWAP_HALF(t.si_flags);
|
|
/**/
|
|
}
|
|
/* Write an Elf64_Syminfo */
|
|
WRITE_HALF(dst,t.si_boundto);
|
|
WRITE_HALF(dst,t.si_flags);
|
|
/**/
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_SYMINFO64_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Syminfo t, *d;
|
|
char *s,*s0;
|
|
size_t fsz;
|
|
|
|
fsz = elf64_fsize(ELF_T_SYMINFO, (size_t) 1, EV_CURRENT);
|
|
d = ((Elf64_Syminfo *) (uintptr_t) dst) + (count - 1);
|
|
s0 = (char *) src + (count - 1) * fsz;
|
|
|
|
if (dsz < count * sizeof(Elf64_Syminfo))
|
|
return (0);
|
|
|
|
while (count--) {
|
|
s = s0;
|
|
/* Read an Elf64_Syminfo */
|
|
READ_HALF(s,t.si_boundto);
|
|
READ_HALF(s,t.si_flags);
|
|
/**/
|
|
if (byteswap) {
|
|
/* Swap an Elf64_Syminfo */
|
|
SWAP_HALF(t.si_boundto);
|
|
SWAP_HALF(t.si_flags);
|
|
/**/
|
|
}
|
|
*d-- = t; s0 -= fsz;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_SYM32_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf32_Sym t, *s;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
s = (Elf32_Sym *) (uintptr_t) src;
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
if (byteswap) {
|
|
/* Swap an Elf32_Sym */
|
|
SWAP_WORD(t.st_name);
|
|
SWAP_ADDR32(t.st_value);
|
|
SWAP_WORD(t.st_size);
|
|
SWAP_BYTE(t.st_info);
|
|
SWAP_BYTE(t.st_other);
|
|
SWAP_HALF(t.st_shndx);
|
|
/**/
|
|
}
|
|
/* Write an Elf32_Sym */
|
|
WRITE_WORD(dst,t.st_name);
|
|
WRITE_ADDR32(dst,t.st_value);
|
|
WRITE_WORD(dst,t.st_size);
|
|
WRITE_BYTE(dst,t.st_info);
|
|
WRITE_BYTE(dst,t.st_other);
|
|
WRITE_HALF(dst,t.st_shndx);
|
|
/**/
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_SYM32_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf32_Sym t, *d;
|
|
char *s,*s0;
|
|
size_t fsz;
|
|
|
|
fsz = elf32_fsize(ELF_T_SYM, (size_t) 1, EV_CURRENT);
|
|
d = ((Elf32_Sym *) (uintptr_t) dst) + (count - 1);
|
|
s0 = (char *) src + (count - 1) * fsz;
|
|
|
|
if (dsz < count * sizeof(Elf32_Sym))
|
|
return (0);
|
|
|
|
while (count--) {
|
|
s = s0;
|
|
/* Read an Elf32_Sym */
|
|
READ_WORD(s,t.st_name);
|
|
READ_ADDR32(s,t.st_value);
|
|
READ_WORD(s,t.st_size);
|
|
READ_BYTE(s,t.st_info);
|
|
READ_BYTE(s,t.st_other);
|
|
READ_HALF(s,t.st_shndx);
|
|
/**/
|
|
if (byteswap) {
|
|
/* Swap an Elf32_Sym */
|
|
SWAP_WORD(t.st_name);
|
|
SWAP_ADDR32(t.st_value);
|
|
SWAP_WORD(t.st_size);
|
|
SWAP_BYTE(t.st_info);
|
|
SWAP_BYTE(t.st_other);
|
|
SWAP_HALF(t.st_shndx);
|
|
/**/
|
|
}
|
|
*d-- = t; s0 -= fsz;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_SYM64_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Sym t, *s;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
s = (Elf64_Sym *) (uintptr_t) src;
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
if (byteswap) {
|
|
/* Swap an Elf64_Sym */
|
|
SWAP_WORD(t.st_name);
|
|
SWAP_BYTE(t.st_info);
|
|
SWAP_BYTE(t.st_other);
|
|
SWAP_HALF(t.st_shndx);
|
|
SWAP_ADDR64(t.st_value);
|
|
SWAP_XWORD(t.st_size);
|
|
/**/
|
|
}
|
|
/* Write an Elf64_Sym */
|
|
WRITE_WORD(dst,t.st_name);
|
|
WRITE_BYTE(dst,t.st_info);
|
|
WRITE_BYTE(dst,t.st_other);
|
|
WRITE_HALF(dst,t.st_shndx);
|
|
WRITE_ADDR64(dst,t.st_value);
|
|
WRITE_XWORD(dst,t.st_size);
|
|
/**/
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_SYM64_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Sym t, *d;
|
|
char *s,*s0;
|
|
size_t fsz;
|
|
|
|
fsz = elf64_fsize(ELF_T_SYM, (size_t) 1, EV_CURRENT);
|
|
d = ((Elf64_Sym *) (uintptr_t) dst) + (count - 1);
|
|
s0 = (char *) src + (count - 1) * fsz;
|
|
|
|
if (dsz < count * sizeof(Elf64_Sym))
|
|
return (0);
|
|
|
|
while (count--) {
|
|
s = s0;
|
|
/* Read an Elf64_Sym */
|
|
READ_WORD(s,t.st_name);
|
|
READ_BYTE(s,t.st_info);
|
|
READ_BYTE(s,t.st_other);
|
|
READ_HALF(s,t.st_shndx);
|
|
READ_ADDR64(s,t.st_value);
|
|
READ_XWORD(s,t.st_size);
|
|
/**/
|
|
if (byteswap) {
|
|
/* Swap an Elf64_Sym */
|
|
SWAP_WORD(t.st_name);
|
|
SWAP_BYTE(t.st_info);
|
|
SWAP_BYTE(t.st_other);
|
|
SWAP_HALF(t.st_shndx);
|
|
SWAP_ADDR64(t.st_value);
|
|
SWAP_XWORD(t.st_size);
|
|
/**/
|
|
}
|
|
*d-- = t; s0 -= fsz;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_WORD_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Word t, *s = (Elf64_Word *) (uintptr_t) src;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
if (!byteswap) {
|
|
(void) memcpy(dst, src, count * sizeof(*s));
|
|
return (1);
|
|
}
|
|
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
SWAP_WORD(t);
|
|
WRITE_WORD(dst,t);
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_WORD_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Word t, *d = (Elf64_Word *) (uintptr_t) dst;
|
|
size_t c;
|
|
|
|
if (dsz < count * sizeof(Elf64_Word))
|
|
return (0);
|
|
|
|
if (!byteswap) {
|
|
(void) memcpy(dst, src, count * sizeof(*d));
|
|
return (1);
|
|
}
|
|
|
|
for (c = 0; c < count; c++) {
|
|
READ_WORD(src,t);
|
|
SWAP_WORD(t);
|
|
*d++ = t;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_XWORD_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Xword t, *s = (Elf64_Xword *) (uintptr_t) src;
|
|
size_t c;
|
|
|
|
(void) dsz;
|
|
|
|
if (!byteswap) {
|
|
(void) memcpy(dst, src, count * sizeof(*s));
|
|
return (1);
|
|
}
|
|
|
|
for (c = 0; c < count; c++) {
|
|
t = *s++;
|
|
SWAP_XWORD(t);
|
|
WRITE_XWORD(dst,t);
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_XWORD_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Xword t, *d = (Elf64_Xword *) (uintptr_t) dst;
|
|
size_t c;
|
|
|
|
if (dsz < count * sizeof(Elf64_Xword))
|
|
return (0);
|
|
|
|
if (!byteswap) {
|
|
(void) memcpy(dst, src, count * sizeof(*d));
|
|
return (1);
|
|
}
|
|
|
|
for (c = 0; c < count; c++) {
|
|
READ_XWORD(src,t);
|
|
SWAP_XWORD(t);
|
|
*d++ = t;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
|
|
static int
|
|
_libelf_cvt_VDEF32_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf32_Verdef t;
|
|
Elf32_Verdaux a;
|
|
const size_t verfsz = 20;
|
|
const size_t auxfsz = 8;
|
|
const size_t vermsz = sizeof(Elf32_Verdef);
|
|
const size_t auxmsz = sizeof(Elf32_Verdaux);
|
|
char * const dstend = dst + dsz;
|
|
char * const srcend = src + count;
|
|
char *dtmp, *dstaux, *srcaux;
|
|
Elf32_Word aux, anext, cnt, vnext;
|
|
|
|
for (dtmp = dst, vnext = ~0;
|
|
vnext != 0 && dtmp + verfsz <= dstend && src + vermsz <= srcend;
|
|
dtmp += vnext, src += vnext) {
|
|
|
|
/* Read in an Elf32_Verdef structure. */
|
|
t = *((Elf32_Verdef *) (uintptr_t) src);
|
|
|
|
aux = t.vd_aux;
|
|
cnt = t.vd_cnt;
|
|
vnext = t.vd_next;
|
|
|
|
if (byteswap) {
|
|
/* Swap an Elf32_Verdef */
|
|
SWAP_HALF(t.vd_version);
|
|
SWAP_HALF(t.vd_flags);
|
|
SWAP_HALF(t.vd_ndx);
|
|
SWAP_HALF(t.vd_cnt);
|
|
SWAP_WORD(t.vd_hash);
|
|
SWAP_WORD(t.vd_aux);
|
|
SWAP_WORD(t.vd_next);
|
|
/**/
|
|
}
|
|
|
|
dst = dtmp;
|
|
/* Write an Elf32_Verdef */
|
|
WRITE_HALF(dst,t.vd_version);
|
|
WRITE_HALF(dst,t.vd_flags);
|
|
WRITE_HALF(dst,t.vd_ndx);
|
|
WRITE_HALF(dst,t.vd_cnt);
|
|
WRITE_WORD(dst,t.vd_hash);
|
|
WRITE_WORD(dst,t.vd_aux);
|
|
WRITE_WORD(dst,t.vd_next);
|
|
/**/
|
|
|
|
if (aux < verfsz)
|
|
return (0);
|
|
|
|
/* Process AUX entries. */
|
|
for (anext = ~0, dstaux = dtmp + aux, srcaux = src + aux;
|
|
cnt != 0 && anext != 0 && dstaux + auxfsz <= dstend &&
|
|
srcaux + auxmsz <= srcend;
|
|
dstaux += anext, srcaux += anext, cnt--) {
|
|
|
|
/* Read in an Elf32_Verdaux structure. */
|
|
a = *((Elf32_Verdaux *) (uintptr_t) srcaux);
|
|
anext = a.vda_next;
|
|
|
|
if (byteswap) {
|
|
/* Swap an Elf32_Verdaux */
|
|
SWAP_WORD(a.vda_name);
|
|
SWAP_WORD(a.vda_next);
|
|
/**/
|
|
}
|
|
|
|
dst = dstaux;
|
|
/* Write an Elf32_Verdaux */
|
|
WRITE_WORD(dst,a.vda_name);
|
|
WRITE_WORD(dst,a.vda_next);
|
|
/**/
|
|
}
|
|
|
|
if (anext || cnt)
|
|
return (0);
|
|
}
|
|
|
|
if (vnext)
|
|
return (0);
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_VDEF32_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf32_Verdef t, *dp;
|
|
Elf32_Verdaux a, *ap;
|
|
const size_t verfsz = 20;
|
|
const size_t auxfsz = 8;
|
|
const size_t vermsz = sizeof(Elf32_Verdef);
|
|
const size_t auxmsz = sizeof(Elf32_Verdaux);
|
|
char * const dstend = dst + dsz;
|
|
char * const srcend = src + count;
|
|
char *dstaux, *s, *srcaux, *stmp;
|
|
Elf32_Word aux, anext, cnt, vnext;
|
|
|
|
for (stmp = src, vnext = ~0;
|
|
vnext != 0 && stmp + verfsz <= srcend && dst + vermsz <= dstend;
|
|
stmp += vnext, dst += vnext) {
|
|
|
|
/* Read in a VDEF structure. */
|
|
s = stmp;
|
|
/* Read an Elf32_Verdef */
|
|
READ_HALF(s,t.vd_version);
|
|
READ_HALF(s,t.vd_flags);
|
|
READ_HALF(s,t.vd_ndx);
|
|
READ_HALF(s,t.vd_cnt);
|
|
READ_WORD(s,t.vd_hash);
|
|
READ_WORD(s,t.vd_aux);
|
|
READ_WORD(s,t.vd_next);
|
|
/**/
|
|
if (byteswap) {
|
|
/* Swap an Elf32_Verdef */
|
|
SWAP_HALF(t.vd_version);
|
|
SWAP_HALF(t.vd_flags);
|
|
SWAP_HALF(t.vd_ndx);
|
|
SWAP_HALF(t.vd_cnt);
|
|
SWAP_WORD(t.vd_hash);
|
|
SWAP_WORD(t.vd_aux);
|
|
SWAP_WORD(t.vd_next);
|
|
/**/
|
|
}
|
|
|
|
dp = (Elf32_Verdef *) (uintptr_t) dst;
|
|
*dp = t;
|
|
|
|
aux = t.vd_aux;
|
|
cnt = t.vd_cnt;
|
|
vnext = t.vd_next;
|
|
|
|
if (aux < vermsz)
|
|
return (0);
|
|
|
|
/* Process AUX entries. */
|
|
for (anext = ~0, dstaux = dst + aux, srcaux = stmp + aux;
|
|
cnt != 0 && anext != 0 && dstaux + auxmsz <= dstend &&
|
|
srcaux + auxfsz <= srcend;
|
|
dstaux += anext, srcaux += anext, cnt--) {
|
|
|
|
s = srcaux;
|
|
/* Read an Elf32_Verdaux */
|
|
READ_WORD(s,a.vda_name);
|
|
READ_WORD(s,a.vda_next);
|
|
/**/
|
|
|
|
if (byteswap) {
|
|
/* Swap an Elf32_Verdaux */
|
|
SWAP_WORD(a.vda_name);
|
|
SWAP_WORD(a.vda_next);
|
|
/**/
|
|
}
|
|
|
|
anext = a.vda_next;
|
|
|
|
ap = ((Elf32_Verdaux *) (uintptr_t) dstaux);
|
|
*ap = a;
|
|
}
|
|
|
|
if (anext || cnt)
|
|
return (0);
|
|
}
|
|
|
|
if (vnext)
|
|
return (0);
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_VDEF64_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Verdef t;
|
|
Elf64_Verdaux a;
|
|
const size_t verfsz = 20;
|
|
const size_t auxfsz = 8;
|
|
const size_t vermsz = sizeof(Elf64_Verdef);
|
|
const size_t auxmsz = sizeof(Elf64_Verdaux);
|
|
char * const dstend = dst + dsz;
|
|
char * const srcend = src + count;
|
|
char *dtmp, *dstaux, *srcaux;
|
|
Elf64_Word aux, anext, cnt, vnext;
|
|
|
|
for (dtmp = dst, vnext = ~0;
|
|
vnext != 0 && dtmp + verfsz <= dstend && src + vermsz <= srcend;
|
|
dtmp += vnext, src += vnext) {
|
|
|
|
/* Read in an Elf64_Verdef structure. */
|
|
t = *((Elf64_Verdef *) (uintptr_t) src);
|
|
|
|
aux = t.vd_aux;
|
|
cnt = t.vd_cnt;
|
|
vnext = t.vd_next;
|
|
|
|
if (byteswap) {
|
|
/* Swap an Elf64_Verdef */
|
|
SWAP_HALF(t.vd_version);
|
|
SWAP_HALF(t.vd_flags);
|
|
SWAP_HALF(t.vd_ndx);
|
|
SWAP_HALF(t.vd_cnt);
|
|
SWAP_WORD(t.vd_hash);
|
|
SWAP_WORD(t.vd_aux);
|
|
SWAP_WORD(t.vd_next);
|
|
/**/
|
|
}
|
|
|
|
dst = dtmp;
|
|
/* Write an Elf64_Verdef */
|
|
WRITE_HALF(dst,t.vd_version);
|
|
WRITE_HALF(dst,t.vd_flags);
|
|
WRITE_HALF(dst,t.vd_ndx);
|
|
WRITE_HALF(dst,t.vd_cnt);
|
|
WRITE_WORD(dst,t.vd_hash);
|
|
WRITE_WORD(dst,t.vd_aux);
|
|
WRITE_WORD(dst,t.vd_next);
|
|
/**/
|
|
|
|
if (aux < verfsz)
|
|
return (0);
|
|
|
|
/* Process AUX entries. */
|
|
for (anext = ~0, dstaux = dtmp + aux, srcaux = src + aux;
|
|
cnt != 0 && anext != 0 && dstaux + auxfsz <= dstend &&
|
|
srcaux + auxmsz <= srcend;
|
|
dstaux += anext, srcaux += anext, cnt--) {
|
|
|
|
/* Read in an Elf64_Verdaux structure. */
|
|
a = *((Elf64_Verdaux *) (uintptr_t) srcaux);
|
|
anext = a.vda_next;
|
|
|
|
if (byteswap) {
|
|
/* Swap an Elf64_Verdaux */
|
|
SWAP_WORD(a.vda_name);
|
|
SWAP_WORD(a.vda_next);
|
|
/**/
|
|
}
|
|
|
|
dst = dstaux;
|
|
/* Write an Elf64_Verdaux */
|
|
WRITE_WORD(dst,a.vda_name);
|
|
WRITE_WORD(dst,a.vda_next);
|
|
/**/
|
|
}
|
|
|
|
if (anext || cnt)
|
|
return (0);
|
|
}
|
|
|
|
if (vnext)
|
|
return (0);
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_VDEF64_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Verdef t, *dp;
|
|
Elf64_Verdaux a, *ap;
|
|
const size_t verfsz = 20;
|
|
const size_t auxfsz = 8;
|
|
const size_t vermsz = sizeof(Elf64_Verdef);
|
|
const size_t auxmsz = sizeof(Elf64_Verdaux);
|
|
char * const dstend = dst + dsz;
|
|
char * const srcend = src + count;
|
|
char *dstaux, *s, *srcaux, *stmp;
|
|
Elf64_Word aux, anext, cnt, vnext;
|
|
|
|
for (stmp = src, vnext = ~0;
|
|
vnext != 0 && stmp + verfsz <= srcend && dst + vermsz <= dstend;
|
|
stmp += vnext, dst += vnext) {
|
|
|
|
/* Read in a VDEF structure. */
|
|
s = stmp;
|
|
/* Read an Elf64_Verdef */
|
|
READ_HALF(s,t.vd_version);
|
|
READ_HALF(s,t.vd_flags);
|
|
READ_HALF(s,t.vd_ndx);
|
|
READ_HALF(s,t.vd_cnt);
|
|
READ_WORD(s,t.vd_hash);
|
|
READ_WORD(s,t.vd_aux);
|
|
READ_WORD(s,t.vd_next);
|
|
/**/
|
|
if (byteswap) {
|
|
/* Swap an Elf64_Verdef */
|
|
SWAP_HALF(t.vd_version);
|
|
SWAP_HALF(t.vd_flags);
|
|
SWAP_HALF(t.vd_ndx);
|
|
SWAP_HALF(t.vd_cnt);
|
|
SWAP_WORD(t.vd_hash);
|
|
SWAP_WORD(t.vd_aux);
|
|
SWAP_WORD(t.vd_next);
|
|
/**/
|
|
}
|
|
|
|
dp = (Elf64_Verdef *) (uintptr_t) dst;
|
|
*dp = t;
|
|
|
|
aux = t.vd_aux;
|
|
cnt = t.vd_cnt;
|
|
vnext = t.vd_next;
|
|
|
|
if (aux < vermsz)
|
|
return (0);
|
|
|
|
/* Process AUX entries. */
|
|
for (anext = ~0, dstaux = dst + aux, srcaux = stmp + aux;
|
|
cnt != 0 && anext != 0 && dstaux + auxmsz <= dstend &&
|
|
srcaux + auxfsz <= srcend;
|
|
dstaux += anext, srcaux += anext, cnt--) {
|
|
|
|
s = srcaux;
|
|
/* Read an Elf64_Verdaux */
|
|
READ_WORD(s,a.vda_name);
|
|
READ_WORD(s,a.vda_next);
|
|
/**/
|
|
|
|
if (byteswap) {
|
|
/* Swap an Elf64_Verdaux */
|
|
SWAP_WORD(a.vda_name);
|
|
SWAP_WORD(a.vda_next);
|
|
/**/
|
|
}
|
|
|
|
anext = a.vda_next;
|
|
|
|
ap = ((Elf64_Verdaux *) (uintptr_t) dstaux);
|
|
*ap = a;
|
|
}
|
|
|
|
if (anext || cnt)
|
|
return (0);
|
|
}
|
|
|
|
if (vnext)
|
|
return (0);
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_VNEED32_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf32_Verneed t;
|
|
Elf32_Vernaux a;
|
|
const size_t verfsz = 16;
|
|
const size_t auxfsz = 16;
|
|
const size_t vermsz = sizeof(Elf32_Verneed);
|
|
const size_t auxmsz = sizeof(Elf32_Vernaux);
|
|
char * const dstend = dst + dsz;
|
|
char * const srcend = src + count;
|
|
char *dtmp, *dstaux, *srcaux;
|
|
Elf32_Word aux, anext, cnt, vnext;
|
|
|
|
for (dtmp = dst, vnext = ~0;
|
|
vnext != 0 && dtmp + verfsz <= dstend && src + vermsz <= srcend;
|
|
dtmp += vnext, src += vnext) {
|
|
|
|
/* Read in an Elf32_Verneed structure. */
|
|
t = *((Elf32_Verneed *) (uintptr_t) src);
|
|
|
|
aux = t.vn_aux;
|
|
cnt = t.vn_cnt;
|
|
vnext = t.vn_next;
|
|
|
|
if (byteswap) {
|
|
/* Swap an Elf32_Verneed */
|
|
SWAP_HALF(t.vn_version);
|
|
SWAP_HALF(t.vn_cnt);
|
|
SWAP_WORD(t.vn_file);
|
|
SWAP_WORD(t.vn_aux);
|
|
SWAP_WORD(t.vn_next);
|
|
/**/
|
|
}
|
|
|
|
dst = dtmp;
|
|
/* Write an Elf32_Verneed */
|
|
WRITE_HALF(dst,t.vn_version);
|
|
WRITE_HALF(dst,t.vn_cnt);
|
|
WRITE_WORD(dst,t.vn_file);
|
|
WRITE_WORD(dst,t.vn_aux);
|
|
WRITE_WORD(dst,t.vn_next);
|
|
/**/
|
|
|
|
if (aux < verfsz)
|
|
return (0);
|
|
|
|
/* Process AUX entries. */
|
|
for (anext = ~0, dstaux = dtmp + aux, srcaux = src + aux;
|
|
cnt != 0 && anext != 0 && dstaux + auxfsz <= dstend &&
|
|
srcaux + auxmsz <= srcend;
|
|
dstaux += anext, srcaux += anext, cnt--) {
|
|
|
|
/* Read in an Elf32_Vernaux structure. */
|
|
a = *((Elf32_Vernaux *) (uintptr_t) srcaux);
|
|
anext = a.vna_next;
|
|
|
|
if (byteswap) {
|
|
/* Swap an Elf32_Vernaux */
|
|
SWAP_WORD(a.vna_hash);
|
|
SWAP_HALF(a.vna_flags);
|
|
SWAP_HALF(a.vna_other);
|
|
SWAP_WORD(a.vna_name);
|
|
SWAP_WORD(a.vna_next);
|
|
/**/
|
|
}
|
|
|
|
dst = dstaux;
|
|
/* Write an Elf32_Vernaux */
|
|
WRITE_WORD(dst,a.vna_hash);
|
|
WRITE_HALF(dst,a.vna_flags);
|
|
WRITE_HALF(dst,a.vna_other);
|
|
WRITE_WORD(dst,a.vna_name);
|
|
WRITE_WORD(dst,a.vna_next);
|
|
/**/
|
|
}
|
|
|
|
if (anext || cnt)
|
|
return (0);
|
|
}
|
|
|
|
if (vnext)
|
|
return (0);
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_VNEED32_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf32_Verneed t, *dp;
|
|
Elf32_Vernaux a, *ap;
|
|
const size_t verfsz = 16;
|
|
const size_t auxfsz = 16;
|
|
const size_t vermsz = sizeof(Elf32_Verneed);
|
|
const size_t auxmsz = sizeof(Elf32_Vernaux);
|
|
char * const dstend = dst + dsz;
|
|
char * const srcend = src + count;
|
|
char *dstaux, *s, *srcaux, *stmp;
|
|
Elf32_Word aux, anext, cnt, vnext;
|
|
|
|
for (stmp = src, vnext = ~0;
|
|
vnext != 0 && stmp + verfsz <= srcend && dst + vermsz <= dstend;
|
|
stmp += vnext, dst += vnext) {
|
|
|
|
/* Read in a VNEED structure. */
|
|
s = stmp;
|
|
/* Read an Elf32_Verneed */
|
|
READ_HALF(s,t.vn_version);
|
|
READ_HALF(s,t.vn_cnt);
|
|
READ_WORD(s,t.vn_file);
|
|
READ_WORD(s,t.vn_aux);
|
|
READ_WORD(s,t.vn_next);
|
|
/**/
|
|
if (byteswap) {
|
|
/* Swap an Elf32_Verneed */
|
|
SWAP_HALF(t.vn_version);
|
|
SWAP_HALF(t.vn_cnt);
|
|
SWAP_WORD(t.vn_file);
|
|
SWAP_WORD(t.vn_aux);
|
|
SWAP_WORD(t.vn_next);
|
|
/**/
|
|
}
|
|
|
|
dp = (Elf32_Verneed *) (uintptr_t) dst;
|
|
*dp = t;
|
|
|
|
aux = t.vn_aux;
|
|
cnt = t.vn_cnt;
|
|
vnext = t.vn_next;
|
|
|
|
if (aux < vermsz)
|
|
return (0);
|
|
|
|
/* Process AUX entries. */
|
|
for (anext = ~0, dstaux = dst + aux, srcaux = stmp + aux;
|
|
cnt != 0 && anext != 0 && dstaux + auxmsz <= dstend &&
|
|
srcaux + auxfsz <= srcend;
|
|
dstaux += anext, srcaux += anext, cnt--) {
|
|
|
|
s = srcaux;
|
|
/* Read an Elf32_Vernaux */
|
|
READ_WORD(s,a.vna_hash);
|
|
READ_HALF(s,a.vna_flags);
|
|
READ_HALF(s,a.vna_other);
|
|
READ_WORD(s,a.vna_name);
|
|
READ_WORD(s,a.vna_next);
|
|
/**/
|
|
|
|
if (byteswap) {
|
|
/* Swap an Elf32_Vernaux */
|
|
SWAP_WORD(a.vna_hash);
|
|
SWAP_HALF(a.vna_flags);
|
|
SWAP_HALF(a.vna_other);
|
|
SWAP_WORD(a.vna_name);
|
|
SWAP_WORD(a.vna_next);
|
|
/**/
|
|
}
|
|
|
|
anext = a.vna_next;
|
|
|
|
ap = ((Elf32_Vernaux *) (uintptr_t) dstaux);
|
|
*ap = a;
|
|
}
|
|
|
|
if (anext || cnt)
|
|
return (0);
|
|
}
|
|
|
|
if (vnext)
|
|
return (0);
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_VNEED64_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Verneed t;
|
|
Elf64_Vernaux a;
|
|
const size_t verfsz = 16;
|
|
const size_t auxfsz = 16;
|
|
const size_t vermsz = sizeof(Elf64_Verneed);
|
|
const size_t auxmsz = sizeof(Elf64_Vernaux);
|
|
char * const dstend = dst + dsz;
|
|
char * const srcend = src + count;
|
|
char *dtmp, *dstaux, *srcaux;
|
|
Elf64_Word aux, anext, cnt, vnext;
|
|
|
|
for (dtmp = dst, vnext = ~0;
|
|
vnext != 0 && dtmp + verfsz <= dstend && src + vermsz <= srcend;
|
|
dtmp += vnext, src += vnext) {
|
|
|
|
/* Read in an Elf64_Verneed structure. */
|
|
t = *((Elf64_Verneed *) (uintptr_t) src);
|
|
|
|
aux = t.vn_aux;
|
|
cnt = t.vn_cnt;
|
|
vnext = t.vn_next;
|
|
|
|
if (byteswap) {
|
|
/* Swap an Elf64_Verneed */
|
|
SWAP_HALF(t.vn_version);
|
|
SWAP_HALF(t.vn_cnt);
|
|
SWAP_WORD(t.vn_file);
|
|
SWAP_WORD(t.vn_aux);
|
|
SWAP_WORD(t.vn_next);
|
|
/**/
|
|
}
|
|
|
|
dst = dtmp;
|
|
/* Write an Elf64_Verneed */
|
|
WRITE_HALF(dst,t.vn_version);
|
|
WRITE_HALF(dst,t.vn_cnt);
|
|
WRITE_WORD(dst,t.vn_file);
|
|
WRITE_WORD(dst,t.vn_aux);
|
|
WRITE_WORD(dst,t.vn_next);
|
|
/**/
|
|
|
|
if (aux < verfsz)
|
|
return (0);
|
|
|
|
/* Process AUX entries. */
|
|
for (anext = ~0, dstaux = dtmp + aux, srcaux = src + aux;
|
|
cnt != 0 && anext != 0 && dstaux + auxfsz <= dstend &&
|
|
srcaux + auxmsz <= srcend;
|
|
dstaux += anext, srcaux += anext, cnt--) {
|
|
|
|
/* Read in an Elf64_Vernaux structure. */
|
|
a = *((Elf64_Vernaux *) (uintptr_t) srcaux);
|
|
anext = a.vna_next;
|
|
|
|
if (byteswap) {
|
|
/* Swap an Elf64_Vernaux */
|
|
SWAP_WORD(a.vna_hash);
|
|
SWAP_HALF(a.vna_flags);
|
|
SWAP_HALF(a.vna_other);
|
|
SWAP_WORD(a.vna_name);
|
|
SWAP_WORD(a.vna_next);
|
|
/**/
|
|
}
|
|
|
|
dst = dstaux;
|
|
/* Write an Elf64_Vernaux */
|
|
WRITE_WORD(dst,a.vna_hash);
|
|
WRITE_HALF(dst,a.vna_flags);
|
|
WRITE_HALF(dst,a.vna_other);
|
|
WRITE_WORD(dst,a.vna_name);
|
|
WRITE_WORD(dst,a.vna_next);
|
|
/**/
|
|
}
|
|
|
|
if (anext || cnt)
|
|
return (0);
|
|
}
|
|
|
|
if (vnext)
|
|
return (0);
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_VNEED64_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
Elf64_Verneed t, *dp;
|
|
Elf64_Vernaux a, *ap;
|
|
const size_t verfsz = 16;
|
|
const size_t auxfsz = 16;
|
|
const size_t vermsz = sizeof(Elf64_Verneed);
|
|
const size_t auxmsz = sizeof(Elf64_Vernaux);
|
|
char * const dstend = dst + dsz;
|
|
char * const srcend = src + count;
|
|
char *dstaux, *s, *srcaux, *stmp;
|
|
Elf64_Word aux, anext, cnt, vnext;
|
|
|
|
for (stmp = src, vnext = ~0;
|
|
vnext != 0 && stmp + verfsz <= srcend && dst + vermsz <= dstend;
|
|
stmp += vnext, dst += vnext) {
|
|
|
|
/* Read in a VNEED structure. */
|
|
s = stmp;
|
|
/* Read an Elf64_Verneed */
|
|
READ_HALF(s,t.vn_version);
|
|
READ_HALF(s,t.vn_cnt);
|
|
READ_WORD(s,t.vn_file);
|
|
READ_WORD(s,t.vn_aux);
|
|
READ_WORD(s,t.vn_next);
|
|
/**/
|
|
if (byteswap) {
|
|
/* Swap an Elf64_Verneed */
|
|
SWAP_HALF(t.vn_version);
|
|
SWAP_HALF(t.vn_cnt);
|
|
SWAP_WORD(t.vn_file);
|
|
SWAP_WORD(t.vn_aux);
|
|
SWAP_WORD(t.vn_next);
|
|
/**/
|
|
}
|
|
|
|
dp = (Elf64_Verneed *) (uintptr_t) dst;
|
|
*dp = t;
|
|
|
|
aux = t.vn_aux;
|
|
cnt = t.vn_cnt;
|
|
vnext = t.vn_next;
|
|
|
|
if (aux < vermsz)
|
|
return (0);
|
|
|
|
/* Process AUX entries. */
|
|
for (anext = ~0, dstaux = dst + aux, srcaux = stmp + aux;
|
|
cnt != 0 && anext != 0 && dstaux + auxmsz <= dstend &&
|
|
srcaux + auxfsz <= srcend;
|
|
dstaux += anext, srcaux += anext, cnt--) {
|
|
|
|
s = srcaux;
|
|
/* Read an Elf64_Vernaux */
|
|
READ_WORD(s,a.vna_hash);
|
|
READ_HALF(s,a.vna_flags);
|
|
READ_HALF(s,a.vna_other);
|
|
READ_WORD(s,a.vna_name);
|
|
READ_WORD(s,a.vna_next);
|
|
/**/
|
|
|
|
if (byteswap) {
|
|
/* Swap an Elf64_Vernaux */
|
|
SWAP_WORD(a.vna_hash);
|
|
SWAP_HALF(a.vna_flags);
|
|
SWAP_HALF(a.vna_other);
|
|
SWAP_WORD(a.vna_name);
|
|
SWAP_WORD(a.vna_next);
|
|
/**/
|
|
}
|
|
|
|
anext = a.vna_next;
|
|
|
|
ap = ((Elf64_Vernaux *) (uintptr_t) dstaux);
|
|
*ap = a;
|
|
}
|
|
|
|
if (anext || cnt)
|
|
return (0);
|
|
}
|
|
|
|
if (vnext)
|
|
return (0);
|
|
|
|
return (1);
|
|
}
|
|
/*]*/
|
|
|
|
/*
|
|
* Sections of type ELF_T_BYTE are never byteswapped, consequently a
|
|
* simple memcpy suffices for both directions of conversion.
|
|
*/
|
|
|
|
static int
|
|
_libelf_cvt_BYTE_tox(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
(void) byteswap;
|
|
if (dsz < count)
|
|
return (0);
|
|
if (dst != src)
|
|
(void) memcpy(dst, src, count);
|
|
return (1);
|
|
}
|
|
|
|
/*
|
|
* Sections of type ELF_T_GNUHASH start with a header containing 4 32-bit
|
|
* words. Bloom filter data comes next, followed by hash buckets and the
|
|
* hash chain.
|
|
*
|
|
* Bloom filter words are 64 bit wide on ELFCLASS64 objects and are 32 bit
|
|
* wide on ELFCLASS32 objects. The other objects in this section are 32
|
|
* bits wide.
|
|
*
|
|
* Argument srcsz denotes the number of bytes to be converted. In the
|
|
* 32-bit case we need to translate srcsz to a count of 32-bit words.
|
|
*/
|
|
|
|
static int
|
|
_libelf_cvt_GNUHASH32_tom(char *dst, size_t dsz, char *src, size_t srcsz,
|
|
int byteswap)
|
|
{
|
|
return (_libelf_cvt_WORD_tom(dst, dsz, src, srcsz / sizeof(uint32_t),
|
|
byteswap));
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_GNUHASH32_tof(char *dst, size_t dsz, char *src, size_t srcsz,
|
|
int byteswap)
|
|
{
|
|
return (_libelf_cvt_WORD_tof(dst, dsz, src, srcsz / sizeof(uint32_t),
|
|
byteswap));
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_GNUHASH64_tom(char *dst, size_t dsz, char *src, size_t srcsz,
|
|
int byteswap)
|
|
{
|
|
size_t sz;
|
|
uint64_t t64, *bloom64;
|
|
Elf_GNU_Hash_Header *gh;
|
|
uint32_t n, nbuckets, nchains, maskwords, shift2, symndx, t32;
|
|
uint32_t *buckets, *chains;
|
|
|
|
sz = 4 * sizeof(uint32_t); /* File header is 4 words long. */
|
|
if (dsz < sizeof(Elf_GNU_Hash_Header) || srcsz < sz)
|
|
return (0);
|
|
|
|
/* Read in the section header and byteswap if needed. */
|
|
READ_WORD(src, nbuckets);
|
|
READ_WORD(src, symndx);
|
|
READ_WORD(src, maskwords);
|
|
READ_WORD(src, shift2);
|
|
|
|
srcsz -= sz;
|
|
|
|
if (byteswap) {
|
|
SWAP_WORD(nbuckets);
|
|
SWAP_WORD(symndx);
|
|
SWAP_WORD(maskwords);
|
|
SWAP_WORD(shift2);
|
|
}
|
|
|
|
/* Check source buffer and destination buffer sizes. */
|
|
sz = nbuckets * sizeof(uint32_t) + maskwords * sizeof(uint64_t);
|
|
if (srcsz < sz || dsz < sz + sizeof(Elf_GNU_Hash_Header))
|
|
return (0);
|
|
|
|
gh = (Elf_GNU_Hash_Header *) (uintptr_t) dst;
|
|
gh->gh_nbuckets = nbuckets;
|
|
gh->gh_symndx = symndx;
|
|
gh->gh_maskwords = maskwords;
|
|
gh->gh_shift2 = shift2;
|
|
|
|
dsz -= sizeof(Elf_GNU_Hash_Header);
|
|
dst += sizeof(Elf_GNU_Hash_Header);
|
|
|
|
bloom64 = (uint64_t *) (uintptr_t) dst;
|
|
|
|
/* Copy bloom filter data. */
|
|
for (n = 0; n < maskwords; n++) {
|
|
READ_XWORD(src, t64);
|
|
if (byteswap)
|
|
SWAP_XWORD(t64);
|
|
bloom64[n] = t64;
|
|
}
|
|
|
|
/* The hash buckets follows the bloom filter. */
|
|
dst += maskwords * sizeof(uint64_t);
|
|
buckets = (uint32_t *) (uintptr_t) dst;
|
|
|
|
for (n = 0; n < nbuckets; n++) {
|
|
READ_WORD(src, t32);
|
|
if (byteswap)
|
|
SWAP_WORD(t32);
|
|
buckets[n] = t32;
|
|
}
|
|
|
|
dst += nbuckets * sizeof(uint32_t);
|
|
|
|
/* The hash chain follows the hash buckets. */
|
|
dsz -= sz;
|
|
srcsz -= sz;
|
|
|
|
if (dsz < srcsz) /* Destination lacks space. */
|
|
return (0);
|
|
|
|
nchains = srcsz / sizeof(uint32_t);
|
|
chains = (uint32_t *) (uintptr_t) dst;
|
|
|
|
for (n = 0; n < nchains; n++) {
|
|
READ_WORD(src, t32);
|
|
if (byteswap)
|
|
SWAP_WORD(t32);
|
|
*chains++ = t32;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_GNUHASH64_tof(char *dst, size_t dsz, char *src, size_t srcsz,
|
|
int byteswap)
|
|
{
|
|
uint32_t *s32;
|
|
size_t sz, hdrsz;
|
|
uint64_t *s64, t64;
|
|
Elf_GNU_Hash_Header *gh;
|
|
uint32_t maskwords, n, nbuckets, nchains, t0, t1, t2, t3, t32;
|
|
|
|
hdrsz = 4 * sizeof(uint32_t); /* Header is 4x32 bits. */
|
|
if (dsz < hdrsz || srcsz < sizeof(Elf_GNU_Hash_Header))
|
|
return (0);
|
|
|
|
gh = (Elf_GNU_Hash_Header *) (uintptr_t) src;
|
|
|
|
t0 = nbuckets = gh->gh_nbuckets;
|
|
t1 = gh->gh_symndx;
|
|
t2 = maskwords = gh->gh_maskwords;
|
|
t3 = gh->gh_shift2;
|
|
|
|
src += sizeof(Elf_GNU_Hash_Header);
|
|
srcsz -= sizeof(Elf_GNU_Hash_Header);
|
|
dsz -= hdrsz;
|
|
|
|
sz = gh->gh_nbuckets * sizeof(uint32_t) + gh->gh_maskwords *
|
|
sizeof(uint64_t);
|
|
|
|
if (srcsz < sz || dsz < sz)
|
|
return (0);
|
|
|
|
/* Write out the header. */
|
|
if (byteswap) {
|
|
SWAP_WORD(t0);
|
|
SWAP_WORD(t1);
|
|
SWAP_WORD(t2);
|
|
SWAP_WORD(t3);
|
|
}
|
|
|
|
WRITE_WORD(dst, t0);
|
|
WRITE_WORD(dst, t1);
|
|
WRITE_WORD(dst, t2);
|
|
WRITE_WORD(dst, t3);
|
|
|
|
/* Copy the bloom filter and the hash table. */
|
|
s64 = (uint64_t *) (uintptr_t) src;
|
|
for (n = 0; n < maskwords; n++) {
|
|
t64 = *s64++;
|
|
if (byteswap)
|
|
SWAP_XWORD(t64);
|
|
WRITE_WORD64(dst, t64);
|
|
}
|
|
|
|
s32 = (uint32_t *) s64;
|
|
for (n = 0; n < nbuckets; n++) {
|
|
t32 = *s32++;
|
|
if (byteswap)
|
|
SWAP_WORD(t32);
|
|
WRITE_WORD(dst, t32);
|
|
}
|
|
|
|
srcsz -= sz;
|
|
dsz -= sz;
|
|
|
|
/* Copy out the hash chains. */
|
|
if (dsz < srcsz)
|
|
return (0);
|
|
|
|
nchains = srcsz / sizeof(uint32_t);
|
|
for (n = 0; n < nchains; n++) {
|
|
t32 = *s32++;
|
|
if (byteswap)
|
|
SWAP_WORD(t32);
|
|
WRITE_WORD(dst, t32);
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
/*
|
|
* Elf_Note structures comprise a fixed size header followed by variable
|
|
* length strings. The fixed size header needs to be byte swapped, but
|
|
* not the strings.
|
|
*
|
|
* Argument count denotes the total number of bytes to be converted.
|
|
* The destination buffer needs to be at least count bytes in size.
|
|
*/
|
|
static int
|
|
_libelf_cvt_NOTE_tom(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
uint32_t namesz, descsz, type;
|
|
Elf_Note *en;
|
|
size_t sz, hdrsz;
|
|
|
|
if (dsz < count) /* Destination buffer is too small. */
|
|
return (0);
|
|
|
|
hdrsz = 3 * sizeof(uint32_t);
|
|
if (count < hdrsz) /* Source too small. */
|
|
return (0);
|
|
|
|
if (!byteswap) {
|
|
(void) memcpy(dst, src, count);
|
|
return (1);
|
|
}
|
|
|
|
/* Process all notes in the section. */
|
|
while (count > hdrsz) {
|
|
/* Read the note header. */
|
|
READ_WORD(src, namesz);
|
|
READ_WORD(src, descsz);
|
|
READ_WORD(src, type);
|
|
|
|
/* Translate. */
|
|
SWAP_WORD(namesz);
|
|
SWAP_WORD(descsz);
|
|
SWAP_WORD(type);
|
|
|
|
/* Copy out the translated note header. */
|
|
en = (Elf_Note *) (uintptr_t) dst;
|
|
en->n_namesz = namesz;
|
|
en->n_descsz = descsz;
|
|
en->n_type = type;
|
|
|
|
dsz -= sizeof(Elf_Note);
|
|
dst += sizeof(Elf_Note);
|
|
count -= hdrsz;
|
|
|
|
ROUNDUP2(namesz, 4);
|
|
ROUNDUP2(descsz, 4);
|
|
|
|
sz = namesz + descsz;
|
|
|
|
if (count < sz || dsz < sz) /* Buffers are too small. */
|
|
return (0);
|
|
|
|
(void) memcpy(dst, src, sz);
|
|
|
|
src += sz;
|
|
dst += sz;
|
|
|
|
count -= sz;
|
|
dsz -= sz;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
static int
|
|
_libelf_cvt_NOTE_tof(char *dst, size_t dsz, char *src, size_t count,
|
|
int byteswap)
|
|
{
|
|
uint32_t namesz, descsz, type;
|
|
Elf_Note *en;
|
|
size_t sz;
|
|
|
|
if (dsz < count)
|
|
return (0);
|
|
|
|
if (!byteswap) {
|
|
(void) memcpy(dst, src, count);
|
|
return (1);
|
|
}
|
|
|
|
while (count > sizeof(Elf_Note)) {
|
|
|
|
en = (Elf_Note *) (uintptr_t) src;
|
|
namesz = en->n_namesz;
|
|
descsz = en->n_descsz;
|
|
type = en->n_type;
|
|
|
|
SWAP_WORD(namesz);
|
|
SWAP_WORD(descsz);
|
|
SWAP_WORD(type);
|
|
|
|
WRITE_WORD(dst, namesz);
|
|
WRITE_WORD(dst, descsz);
|
|
WRITE_WORD(dst, type);
|
|
|
|
src += sizeof(Elf_Note);
|
|
|
|
ROUNDUP2(namesz, 4);
|
|
ROUNDUP2(descsz, 4);
|
|
|
|
sz = namesz + descsz;
|
|
|
|
if (count < sz)
|
|
sz = count;
|
|
|
|
(void) memcpy(dst, src, sz);
|
|
|
|
src += sz;
|
|
dst += sz;
|
|
count -= sz;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
struct converters {
|
|
int (*tof32)(char *dst, size_t dsz, char *src, size_t cnt,
|
|
int byteswap);
|
|
int (*tom32)(char *dst, size_t dsz, char *src, size_t cnt,
|
|
int byteswap);
|
|
int (*tof64)(char *dst, size_t dsz, char *src, size_t cnt,
|
|
int byteswap);
|
|
int (*tom64)(char *dst, size_t dsz, char *src, size_t cnt,
|
|
int byteswap);
|
|
};
|
|
|
|
|
|
static struct converters cvt[ELF_T_NUM] = {
|
|
/*[*/
|
|
[ELF_T_ADDR] = {
|
|
.tof32 = _libelf_cvt_ADDR32_tof,
|
|
.tom32 = _libelf_cvt_ADDR32_tom,
|
|
.tof64 = _libelf_cvt_ADDR64_tof,
|
|
.tom64 = _libelf_cvt_ADDR64_tom
|
|
},
|
|
|
|
[ELF_T_CAP] = {
|
|
.tof32 = _libelf_cvt_CAP32_tof,
|
|
.tom32 = _libelf_cvt_CAP32_tom,
|
|
.tof64 = _libelf_cvt_CAP64_tof,
|
|
.tom64 = _libelf_cvt_CAP64_tom
|
|
},
|
|
|
|
[ELF_T_DYN] = {
|
|
.tof32 = _libelf_cvt_DYN32_tof,
|
|
.tom32 = _libelf_cvt_DYN32_tom,
|
|
.tof64 = _libelf_cvt_DYN64_tof,
|
|
.tom64 = _libelf_cvt_DYN64_tom
|
|
},
|
|
|
|
[ELF_T_EHDR] = {
|
|
.tof32 = _libelf_cvt_EHDR32_tof,
|
|
.tom32 = _libelf_cvt_EHDR32_tom,
|
|
.tof64 = _libelf_cvt_EHDR64_tof,
|
|
.tom64 = _libelf_cvt_EHDR64_tom
|
|
},
|
|
|
|
[ELF_T_GNUHASH] = {
|
|
.tof32 = _libelf_cvt_GNUHASH32_tof,
|
|
.tom32 = _libelf_cvt_GNUHASH32_tom,
|
|
.tof64 = _libelf_cvt_GNUHASH64_tof,
|
|
.tom64 = _libelf_cvt_GNUHASH64_tom
|
|
},
|
|
|
|
[ELF_T_HALF] = {
|
|
.tof32 = _libelf_cvt_HALF_tof,
|
|
.tom32 = _libelf_cvt_HALF_tom,
|
|
.tof64 = _libelf_cvt_HALF_tof,
|
|
.tom64 = _libelf_cvt_HALF_tom
|
|
},
|
|
|
|
[ELF_T_LWORD] = {
|
|
.tof32 = _libelf_cvt_LWORD_tof,
|
|
.tom32 = _libelf_cvt_LWORD_tom,
|
|
.tof64 = _libelf_cvt_LWORD_tof,
|
|
.tom64 = _libelf_cvt_LWORD_tom
|
|
},
|
|
|
|
[ELF_T_MOVE] = {
|
|
.tof32 = _libelf_cvt_MOVE32_tof,
|
|
.tom32 = _libelf_cvt_MOVE32_tom,
|
|
.tof64 = _libelf_cvt_MOVE64_tof,
|
|
.tom64 = _libelf_cvt_MOVE64_tom
|
|
},
|
|
|
|
[ELF_T_OFF] = {
|
|
.tof32 = _libelf_cvt_OFF32_tof,
|
|
.tom32 = _libelf_cvt_OFF32_tom,
|
|
.tof64 = _libelf_cvt_OFF64_tof,
|
|
.tom64 = _libelf_cvt_OFF64_tom
|
|
},
|
|
|
|
[ELF_T_PHDR] = {
|
|
.tof32 = _libelf_cvt_PHDR32_tof,
|
|
.tom32 = _libelf_cvt_PHDR32_tom,
|
|
.tof64 = _libelf_cvt_PHDR64_tof,
|
|
.tom64 = _libelf_cvt_PHDR64_tom
|
|
},
|
|
|
|
[ELF_T_REL] = {
|
|
.tof32 = _libelf_cvt_REL32_tof,
|
|
.tom32 = _libelf_cvt_REL32_tom,
|
|
.tof64 = _libelf_cvt_REL64_tof,
|
|
.tom64 = _libelf_cvt_REL64_tom
|
|
},
|
|
|
|
[ELF_T_RELA] = {
|
|
.tof32 = _libelf_cvt_RELA32_tof,
|
|
.tom32 = _libelf_cvt_RELA32_tom,
|
|
.tof64 = _libelf_cvt_RELA64_tof,
|
|
.tom64 = _libelf_cvt_RELA64_tom
|
|
},
|
|
|
|
[ELF_T_SHDR] = {
|
|
.tof32 = _libelf_cvt_SHDR32_tof,
|
|
.tom32 = _libelf_cvt_SHDR32_tom,
|
|
.tof64 = _libelf_cvt_SHDR64_tof,
|
|
.tom64 = _libelf_cvt_SHDR64_tom
|
|
},
|
|
|
|
[ELF_T_SWORD] = {
|
|
.tof32 = _libelf_cvt_SWORD_tof,
|
|
.tom32 = _libelf_cvt_SWORD_tom,
|
|
.tof64 = _libelf_cvt_SWORD_tof,
|
|
.tom64 = _libelf_cvt_SWORD_tom
|
|
},
|
|
|
|
[ELF_T_SXWORD] = {
|
|
.tof32 = NULL,
|
|
.tom32 = NULL,
|
|
.tof64 = _libelf_cvt_SXWORD_tof,
|
|
.tom64 = _libelf_cvt_SXWORD_tom
|
|
},
|
|
|
|
[ELF_T_SYMINFO] = {
|
|
.tof32 = _libelf_cvt_SYMINFO32_tof,
|
|
.tom32 = _libelf_cvt_SYMINFO32_tom,
|
|
.tof64 = _libelf_cvt_SYMINFO64_tof,
|
|
.tom64 = _libelf_cvt_SYMINFO64_tom
|
|
},
|
|
|
|
[ELF_T_SYM] = {
|
|
.tof32 = _libelf_cvt_SYM32_tof,
|
|
.tom32 = _libelf_cvt_SYM32_tom,
|
|
.tof64 = _libelf_cvt_SYM64_tof,
|
|
.tom64 = _libelf_cvt_SYM64_tom
|
|
},
|
|
|
|
[ELF_T_VDEF] = {
|
|
.tof32 = _libelf_cvt_VDEF32_tof,
|
|
.tom32 = _libelf_cvt_VDEF32_tom,
|
|
.tof64 = _libelf_cvt_VDEF64_tof,
|
|
.tom64 = _libelf_cvt_VDEF64_tom
|
|
},
|
|
|
|
[ELF_T_VNEED] = {
|
|
.tof32 = _libelf_cvt_VNEED32_tof,
|
|
.tom32 = _libelf_cvt_VNEED32_tom,
|
|
.tof64 = _libelf_cvt_VNEED64_tof,
|
|
.tom64 = _libelf_cvt_VNEED64_tom
|
|
},
|
|
|
|
[ELF_T_WORD] = {
|
|
.tof32 = _libelf_cvt_WORD_tof,
|
|
.tom32 = _libelf_cvt_WORD_tom,
|
|
.tof64 = _libelf_cvt_WORD_tof,
|
|
.tom64 = _libelf_cvt_WORD_tom
|
|
},
|
|
|
|
[ELF_T_XWORD] = {
|
|
.tof32 = NULL,
|
|
.tom32 = NULL,
|
|
.tof64 = _libelf_cvt_XWORD_tof,
|
|
.tom64 = _libelf_cvt_XWORD_tom
|
|
},
|
|
|
|
|
|
/*]*/
|
|
|
|
/*
|
|
* Types that need hand-coded converters follow.
|
|
*/
|
|
|
|
[ELF_T_BYTE] = {
|
|
.tof32 = _libelf_cvt_BYTE_tox,
|
|
.tom32 = _libelf_cvt_BYTE_tox,
|
|
.tof64 = _libelf_cvt_BYTE_tox,
|
|
.tom64 = _libelf_cvt_BYTE_tox
|
|
},
|
|
|
|
[ELF_T_NOTE] = {
|
|
.tof32 = _libelf_cvt_NOTE_tof,
|
|
.tom32 = _libelf_cvt_NOTE_tom,
|
|
.tof64 = _libelf_cvt_NOTE_tof,
|
|
.tom64 = _libelf_cvt_NOTE_tom
|
|
}
|
|
};
|
|
|
|
int (*_libelf_get_translator(Elf_Type t, int direction, int elfclass))
|
|
(char *_dst, size_t dsz, char *_src, size_t _cnt, int _byteswap)
|
|
{
|
|
assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64);
|
|
assert(direction == ELF_TOFILE || direction == ELF_TOMEMORY);
|
|
|
|
if (t >= ELF_T_NUM ||
|
|
(elfclass != ELFCLASS32 && elfclass != ELFCLASS64) ||
|
|
(direction != ELF_TOFILE && direction != ELF_TOMEMORY))
|
|
return (NULL);
|
|
|
|
return ((elfclass == ELFCLASS32) ?
|
|
(direction == ELF_TOFILE ? cvt[t].tof32 : cvt[t].tom32) :
|
|
(direction == ELF_TOFILE ? cvt[t].tof64 : cvt[t].tom64));
|
|
}
|