libelf_convert.m4

来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· M4 代码 · 共 658 行 · 第 1/2 页

M4
658
字号
/*- * Copyright (c) 2006 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/types.h>#include <assert.h>#include <string.h>#include "elf32.h"#include "elf64.h"#include "libelf.h"#include "_libelf.h"/* WARNING: GENERATED FROM __file__. *//* * Macros to swap various integral quantities. */#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)/* * Write out various integral values.  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 {						\		unsigned char *const _p = (unsigned char *) (P);	\		_p[0]		= (unsigned char) (X);			\		(P)		= _p + 1;				\	} while (0)#define	WRITE_HALF(P,X)	do {						\		uint16_t _t	= (X);					\		unsigned char *const _p	= (unsigned char *) (P);	\		unsigned const char *const _q = (unsigned 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);					\		unsigned char *const _p	= (unsigned char *) (P);	\		unsigned const char *const _q = (unsigned 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);					\		unsigned char *const _p	= (unsigned char *) (P);	\		unsigned const char *const _q = (unsigned 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)/* * Read in various integral values.  The source pointer could be * unaligned.  Values are read in in native byte order.  The source * pointer is incremented appropriately. */#define	READ_BYTE(P,X)	do {						\		const unsigned char *const _p =				\			(const unsigned char *) (P);			\		(X)		= _p[0];				\		(P)		= (P) + 1;				\	} while (0)#define	READ_HALF(P,X)	do {						\		uint16_t _t;						\		unsigned char *const _q = (unsigned char *) &_t;	\		const unsigned char *const _p =				\			(const unsigned 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;						\		unsigned char *const _q = (unsigned char *) &_t;	\		const unsigned char *const _p =				\			(const unsigned 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;						\		unsigned char *const _q = (unsigned char *) &_t;	\		const unsigned char *const _p =				\			(const unsigned 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))divert(-1)/* * Generate conversion routines for converting between in-memory and * file representations of Elf data structures. * * `In-memory' representations of an Elf data structure use natural * alignments and native byte ordering.  This allows arithmetic and * casting to work as expected.  On the other hand the `file' * representation of an ELF data structure could be packed tighter * than its `in-memory' representation, and could be of a differing * byte order.  An additional complication is that `ar' only pads data * to even addresses and so ELF archive member data being read from * inside an `ar' archive could end up at misaligned memory addresses. * * Consequently, casting the `char *' pointers that point to memory * representations (i.e., source pointers for the *_tof() functions * and the destination pointers for the *_tom() functions), is safe, * as these pointers should be correctly aligned for the memory type * already.  However, pointers to file representations have to be * treated as being potentially unaligned and no casting can be done. */include(SRCDIR`/elf_types.m4')/* * `IGNORE'_* flags turn off generation of template code. */define(`IGNORE',  `define(IGNORE_$1`'32,	1)   define(IGNORE_$1`'64,	1)')IGNORE(MOVEP)IGNORE(NOTE)define(IGNORE_BYTE,		1)	/* 'lator, leave 'em bytes alone */define(IGNORE_NOTE,		1)define(IGNORE_SXWORD32,		1)define(IGNORE_XWORD32,		1)/* * `BASE'_XXX flags cause class agnostic template functions * to be generated. */define(`BASE_BYTE',	1)define(`BASE_HALF',	1)define(`BASE_NOTE',	1)define(`BASE_WORD',	1)define(`BASE_LWORD',	1)define(`BASE_SWORD',	1)define(`BASE_XWORD',	1)define(`BASE_SXWORD',	1)/* * `SIZEDEP'_XXX flags cause 32/64 bit variants to be generated * for each primitive type. */define(`SIZEDEP_ADDR',	1)define(`SIZEDEP_OFF',	1)/* * `Primitive' ELF types are those that are an alias for an integral * type.  They have no internal structure. These can be copied using * a `memcpy()', and byteswapped in straightforward way. * * Macro use: * `$1': Name of the ELF type. * `$2': C structure name suffix * `$3': ELF class specifier for symbols, one of [`', `32', `64'] * `$4': ELF class specifier for types, one of [`32', `64'] */define(`MAKEPRIM_TO_F',`static voidlibelf_cvt_$1$3_tof(char *dst, char *src, size_t count, int byteswap){	Elf$4_$2 t, *s = (Elf$4_$2 *) (uintptr_t) src;	size_t c;	if (dst == src && !byteswap)		return;	if (!byteswap) {		(void) memcpy(dst, src, count * sizeof(*s));		return;	}	for (c = 0; c < count; c++) {		t = *s++;		SWAP_$1$3(t);		WRITE_$1$3(dst,t);	}}')define(`MAKEPRIM_TO_M',`static voidlibelf_cvt_$1$3_tom(char *dst, char *src, size_t count, int byteswap){	Elf$4_$2 t, *d = (Elf$4_$2 *) (uintptr_t) dst;	size_t c;	if (dst == src && !byteswap)		return;	if (!byteswap) {		(void) memcpy(dst, src, count * sizeof(*d));		return;	}	for (c = 0; c < count; c++) {		READ_$1$3(src,t);		SWAP_$1$3(t);		*d++ = t;	}}')define(`SWAP_FIELD',  `ifdef(`IGNORE_'$2,`',    `ifelse(BASE_$2,1,      `SWAP_$2(t.$1);			',      `ifelse($2,BYTE,`',        `ifelse($2,IDENT,`',          `SWAP_$2'SZ()`(t.$1);			')')')')')define(`SWAP_MEMBERS',  `ifelse($#,1,`/**/',     `SWAP_FIELD($1)SWAP_MEMBERS(shift($@))')')

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?