libelf_convert.m4

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

M4
658
字号
define(`SWAP_STRUCT',  `pushdef(`SZ',$2)/* Swap an Elf$2_$1 */			SWAP_MEMBERS(Elf$2_$1_DEF)popdef(`SZ')')define(`WRITE_FIELD',  `ifelse(BASE_$2,1,    `WRITE_$2(dst,t.$1);		',    `ifelse($2,IDENT,      `WRITE_$2(dst,t.$1);		',      `WRITE_$2'SZ()`(dst,t.$1);		')')')define(`WRITE_MEMBERS',  `ifelse($#,1,`/**/',    `WRITE_FIELD($1)WRITE_MEMBERS(shift($@))')')define(`WRITE_STRUCT',  `pushdef(`SZ',$2)/* Write an Elf$2_$1 */		WRITE_MEMBERS(Elf$2_$1_DEF)popdef(`SZ')')define(`READ_FIELD',  `ifelse(BASE_$2,1,    `READ_$2(s,t.$1);		',    `ifelse($2,IDENT,      `READ_$2(s,t.$1);		',      `READ_$2'SZ()`(s,t.$1);		')')')define(`READ_MEMBERS',  `ifelse($#,1,`/**/',    `READ_FIELD($1)READ_MEMBERS(shift($@))')')define(`READ_STRUCT',  `pushdef(`SZ',$2)/* Read an Elf$2_$1 */		READ_MEMBERS(Elf$2_$1_DEF)popdef(`SZ')')/* * Converters for non-integral ELF data structures. * * When converting data to file representation, the source pointer * will be naturally aligned for a data structure's in-memory * representation.  When converting data to memory, the destination * pointer will be similarly aligned. * * For in-place conversions, when converting to file representations, * the source buffer is large enough to hold `file' data.  When * converting from file to memory, we need to be careful to work * `backwards', to avoid overwriting unconverted data. * * Macro use: * `$1': Name of the ELF type. * `$2': C structure name suffix. * `$3': ELF class specifier, one of [`', `32', `64'] */define(`MAKE_TO_F',  `ifdef(`IGNORE_'$1$3,`',`static voidlibelf_cvt$3_$1_tof(char *dst, char *src, size_t count, int byteswap){	Elf$3_$2	t, *s;	size_t c;	s = (Elf$3_$2 *) (uintptr_t) src;	for (c = 0; c < count; c++) {		t = *s++;		if (byteswap) {			SWAP_STRUCT($2,$3)		}		WRITE_STRUCT($2,$3)	}}')')define(`MAKE_TO_M',  `ifdef(`IGNORE_'$1$3,`',`static voidlibelf_cvt$3_$1_tom(char *dst, char *src, size_t count, int byteswap){	Elf$3_$2	 t, *d;	unsigned char	*s,*s0;	size_t		fsz;	fsz = elf$3_fsize(ELF_T_$1, (size_t) 1, EV_CURRENT);	d   = ((Elf$3_$2 *) (uintptr_t) dst) + (count - 1);	s0  = (unsigned char *) src + (count - 1) * fsz;	while (count--) {		s = s0;		READ_STRUCT($2,$3)		if (byteswap) {			SWAP_STRUCT($2,$3)		}		*d-- = t; s0 -= fsz;	}}')')/* * Make type convertor functions from the type definition * of the ELF type: * - if the type is a base (i.e., `primitive') type: *   - if it is marked as to be ignored (i.e., `IGNORE_'TYPE) *     is defined, we skip the code generation step. *   - if the type is declared as `SIZEDEP', then 32 and 64 bit *     variants of the conversion functions are generated. *   - otherwise a 32 bit variant is generated. * - if the type is a structure type, we generate 32 and 64 bit *   variants of the conversion functions. */define(`MAKE_TYPE_CONVERTER',  `ifdef(`BASE'_$1,    `ifdef(`IGNORE_'$1,`',      `MAKEPRIM_TO_F($1,$2,`',64)       MAKEPRIM_TO_M($1,$2,`',64)')',    `ifdef(`SIZEDEP_'$1,      `MAKEPRIM_TO_F($1,$2,32,32)dnl       MAKEPRIM_TO_M($1,$2,32,32)dnl       MAKEPRIM_TO_F($1,$2,64,64)dnl       MAKEPRIM_TO_M($1,$2,64,64)',      `MAKE_TO_F($1,$2,32)dnl       MAKE_TO_F($1,$2,64)dnl       MAKE_TO_M($1,$2,32)dnl       MAKE_TO_M($1,$2,64)')')')define(`MAKE_TYPE_CONVERTERS',  `ifelse($#,1,`',    `MAKE_TYPE_CONVERTER($1)MAKE_TYPE_CONVERTERS(shift($@))')')divert(0)/* * Sections of type ELF_T_BYTE are never byteswapped, consequently a * simple memcpy suffices for both directions of conversion. */static voidlibelf_cvt_BYTE_tox(char *dst, char *src, size_t count, int byteswap){	(void) byteswap;	if (dst != src)		(void) memcpy(dst, src, count);}/* * 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. */static voidlibelf_cvt_NOTE_tom(char *dst, char *src, size_t count, int byteswap){	uint32_t namesz, descsz, type;	Elf_Note *en;	size_t sz;	if (dst == src && !byteswap)		return;	if (!byteswap) {		(void) memcpy(dst, src, count);		return;	}	while (count > sizeof(Elf_Note)) {		READ_WORD(src, namesz);		READ_WORD(src, descsz);		READ_WORD(src, type);		if (byteswap) {			SWAP_WORD(namesz);			SWAP_WORD(descsz);			SWAP_WORD(type);		}		en = (Elf_Note *) (uintptr_t) dst;		en->n_namesz = namesz;		en->n_descsz = descsz;		en->n_type = type;		dst += 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;	}}static voidlibelf_cvt_NOTE_tof(char *dst, char *src, size_t count, int byteswap){	uint32_t namesz, descsz, type;	Elf_Note *en;	size_t sz;	if (dst == src && !byteswap)		return;	if (!byteswap) {		(void) memcpy(dst, src, count);		return;	}	while (count > sizeof(Elf_Note)) {		en = (Elf_Note *) (uintptr_t) src;		namesz = en->n_namesz;		descsz = en->n_descsz;		type = en->n_type;		if (byteswap) {			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;	}}MAKE_TYPE_CONVERTERS(ELF_TYPE_LIST)struct converters {	void	(*tof32)(char *dst, char *src, size_t cnt, int byteswap);	void	(*tom32)(char *dst, char *src, size_t cnt, int byteswap);	void	(*tof64)(char *dst, char *src, size_t cnt, int byteswap);	void	(*tom64)(char *dst, char *src, size_t cnt, int byteswap);};divert(-1)define(`CONV',  `ifdef(`IGNORE_'$1$2,    `.$3$2 = NULL',    `ifdef(`BASE_'$1,      `ifdef(`IGNORE_'$1,	`.$3$2 = NULL',        `.$3$2 = libelf_cvt_$1_$3')',      `ifdef(`SIZEDEP_'$1,        `.$3$2 = libelf_cvt_$1$2_$3',        `.$3$2 = libelf_cvt$2_$1_$3')')')')define(`CONVERTER_NAME',  `[ELF_T_$1] = {        CONV($1,32,tof), CONV($1,32,tom),        CONV($1,64,tof), CONV($1,64,tom) },')')define(`CONVERTER_NAMES',  `ifelse($#,1,`',    `CONVERTER_NAME($1)CONVERTER_NAMES(shift($@))')')undefine(`IGNORE_BYTE32')undefine(`IGNORE_BYTE64')divert(0)static struct converters cvt[ELF_T_NUM] = {CONVERTER_NAMES(ELF_TYPE_LIST)	/*	 * Types that needs 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	}};void (*_libelf_get_translator(Elf_Type t, int direction, int elfclass)) (char *_dst, 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));}

⌨️ 快捷键说明

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