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 + -
显示快捷键?