Date: Thu, 24 Aug 2006 21:02:20 GMT From: John Birrell <jb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 104986 for review Message-ID: <200608242102.k7OL2KOR042029@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=104986 Change 104986 by jb@jb_freebsd2 on 2006/08/24 21:01:44 IFlibbsdelf Affected files ... .. //depot/projects/dtrace/src/lib/libelf/Makefile#10 integrate .. //depot/projects/dtrace/src/lib/libelf/elf_begin.c#3 integrate .. //depot/projects/dtrace/src/lib/libelf/elf_errmsg.c#7 integrate .. //depot/projects/dtrace/src/lib/libelf/gelf_newehdr.3#5 integrate .. //depot/projects/dtrace/src/lib/libelf/gelf_xlate.c#3 integrate .. //depot/projects/dtrace/src/lib/libelf/gelf_xlatetof.3#2 integrate .. //depot/projects/dtrace/src/lib/libelf/libelf.c#3 integrate .. //depot/projects/dtrace/src/lib/libelf/libelf.h#6 integrate .. //depot/projects/dtrace/src/lib/libelf/libelf_allocate.c#2 integrate .. //depot/projects/dtrace/src/lib/libelf/libelf_convert.m4#8 integrate .. //depot/projects/dtrace/src/lib/libelf/libelf_ehdr.c#5 integrate .. //depot/projects/dtrace/src/lib/libelf/libelf_fsize.m4#2 integrate .. //depot/projects/dtrace/src/lib/libelf/libelf_msize.m4#2 integrate Differences ... ==== //depot/projects/dtrace/src/lib/libelf/Makefile#10 (text+ko) ==== @@ -54,6 +54,8 @@ OBJS+= libelf_convert.o libelf_msize.o +OSRELDATE!= sysctl -n kern.osreldate + WARNS?= 9 MAN= elf.3 \ @@ -153,4 +155,4 @@ # Keep this suffixes line after the include of bsd.lib.mk .SUFFIXES: .m4 .c .m4.c: - m4 -D SRCDIR=${.CURDIR} ${.IMPSRC} > ${.TARGET} + m4 -D SRCDIR=${.CURDIR} -D OSRELDATE=${OSRELDATE} ${.IMPSRC} > ${.TARGET} ==== //depot/projects/dtrace/src/lib/libelf/elf_begin.c#3 (text+ko) ==== @@ -154,7 +154,6 @@ if ((e = _libelf_allocate_elf()) != NULL) { e->e_byteorder = LIBELF_PRIVATE(byteorder); - e->e_class = LIBELF_PRIVATE(class); e->e_fd = fd; e->e_kind = ELF_K_ELF; e->e_cmd = c; ==== //depot/projects/dtrace/src/lib/libelf/elf_errmsg.c#7 (text+ko) ==== @@ -41,8 +41,9 @@ DEFINE_ERROR(NONE, "No Error"), DEFINE_ERROR(ARCHIVE, "Malformed ar(1) archive"), DEFINE_ERROR(ARGUMENT, "Invalid argument"), + DEFINE_ERROR(CLASS, "ELF class mismatch"), + DEFINE_ERROR(DATA, "Invalid data buffer descriptor"), DEFINE_ERROR(HEADER, "Missing or malformed ELF header"), - DEFINE_ERROR(CLASS, "ELF class mismatch"), DEFINE_ERROR(MMAP, "File mapping failed"), DEFINE_ERROR(MODE, "Incorrect ELF descriptor mode"), DEFINE_ERROR(RESOURCE, "Resource exhaustion"), ==== //depot/projects/dtrace/src/lib/libelf/gelf_newehdr.3#5 (text+ko) ==== @@ -78,7 +78,7 @@ If a fresh header structure is allocated, the following members of the structure will be set to zero except the following: .Bl -tag -width indent -.It Va e_ident +.It Va "e_ident[EI_MAG0..EI_MAG3]" Identification bytes at offsets .Dv EI_MAG0 , .Dv EI_MAG1 , @@ -86,17 +86,24 @@ and .Dv EI_MAG3 are set to the ELF signature. -The byte at offset +.It Va "e_ident[EI_CLASS]" +The identification byte at offset .Dv EI_CLASS -is set to the default ELF class for the host, -the byte at offset +is set to the ELF class associated with the function being called +or to argument +.Ar elfclass +for function +.Fn gelf_newehdr . +.It Va "e_ident[EI_DATA]" +The identification byte at offset .Dv EI_DATA is set to -.Dv ELFDATANONE , -and byte at offset +.Dv ELFDATANONE . +.It Va "e_ident[EI_VERSION]" +The identification byte at offset .Dv EI_VERSION -is set to -.Dv EV_NONE . +is set to the ELF library's operating version set by a prior call to +.Xr elf_version 3 . .It Va e_machine is set to .Dv EM_NONE . @@ -104,8 +111,8 @@ is set to .Dv ELF_K_ELF . .It Va e_version -is set to -.Dv EV_NONE . +is set to the ELF library's operating version set by a prior call to +.Xr elf_version 3 . .El .Pp The application is responsible for changing these values ==== //depot/projects/dtrace/src/lib/libelf/gelf_xlate.c#3 (text+ko) ==== @@ -54,13 +54,14 @@ libelf_xlate(Elf_Data *dst, const Elf_Data *src, unsigned int encoding, int elfclass, int direction) { - size_t cnt, fsz, msz; + size_t cnt, dsz, fsz, msz; uintptr_t sb, se, db, de; if (encoding == ELFDATANONE) encoding = LIBELF_PRIVATE(byteorder); - if (encoding != ELFDATA2LSB && encoding != ELFDATA2MSB) { + if ((encoding != ELFDATA2LSB && encoding != ELFDATA2MSB) || + dst == NULL || src == NULL || dst == src) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } @@ -73,8 +74,14 @@ return (NULL); } - if (src->d_buf == NULL || dst->d_buf == NULL) { - LIBELF_SET_ERROR(ARGUMENT, 0); + if (src->d_buf == NULL || dst->d_buf == NULL || + src->d_size == 0) { + LIBELF_SET_ERROR(DATA, 0); + return (NULL); + } + + if ((int) src->d_type < 0 || src->d_type >= ELF_T_NUM) { + LIBELF_SET_ERROR(DATA, 0); return (NULL); } @@ -87,14 +94,15 @@ assert(msz > 0); if (src->d_size % (direction == ELF_TOMEMORY ? fsz : msz)) { - LIBELF_SET_ERROR(ARGUMENT, 0); + LIBELF_SET_ERROR(DATA, 0); return (NULL); } cnt = src->d_size / msz; + dsz = cnt * fsz; - if (dst->d_size < cnt * fsz) { - LIBELF_SET_ERROR(ARGUMENT, 0); + if (dst->d_size < dsz) { + LIBELF_SET_ERROR(DATA, 0); return (NULL); } @@ -103,15 +111,21 @@ db = (uintptr_t) dst->d_buf; de = db + dst->d_size; - /* Check for overlapping buffers. Note that db == sb is allowed. */ - if ((db > sb && db < se) || (de > sb && de <= se)) { - LIBELF_SET_ERROR(ARGUMENT, 0); + /* + * Check for overlapping buffers. Note that db == sb is + * allowed, in which case the source buffer must also be large + * enough for `n' target objects. For file to native + * conversions, an in-place conversion is not always possible. + */ + if ((db == sb && dsz < src->d_size) || + (db != sb && de > sb && se > db)) { + LIBELF_SET_ERROR(DATA, 0); return (NULL); } if ((direction == ELF_TOMEMORY ? db : sb) % _libelf_malign(src->d_type, elfclass)) { - LIBELF_SET_ERROR(ARGUMENT, 0); + LIBELF_SET_ERROR(DATA, 0); return (NULL); } @@ -155,11 +169,19 @@ Elf_Data * gelf_xlatetom(Elf *e, Elf_Data *dst, const Elf_Data *src, unsigned int encoding) { - return libelf_xlate(dst, src, encoding, e->e_class, ELF_TOMEMORY); + if (e != NULL) + return (libelf_xlate(dst, src, encoding, e->e_class, + ELF_TOMEMORY)); + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); } Elf_Data * gelf_xlatetof(Elf *e, Elf_Data *dst, const Elf_Data *src, unsigned int encoding) { - return libelf_xlate(dst, src, encoding, e->e_class, ELF_TOFILE); + if (e != NULL) + return (libelf_xlate(dst, src, encoding, e->e_class, + ELF_TOFILE)); + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); } ==== //depot/projects/dtrace/src/lib/libelf/gelf_xlatetof.3#2 (text+ko) ==== @@ -181,11 +181,18 @@ These functions may fail with the following errors: .Bl -tag -width "[ELF_E_RESOURCE]" .It Bq Er ELF_E_ARGUMENT -Either of arguments +One of arguments +.Ar src , +.Ar dst +or +.Ar elf +was NULL. +.It Bq Er ELF_E_ARGUMENT +Arguments .Ar src -or +and .Ar dst -were NULL. +were equal. .It Bq Er ELF_E_ARGUMENT The desired encoding parameter was not one of .Dv ELFDATANONE , @@ -194,26 +201,34 @@ .Dv ELFDATA2MSB . .It Bq Er ELF_E_ARGUMENT The +.Ar d_type +field of argument .Ar src -argument was of an unsupported type. -.It Bq Er ELF_E_ARGUMENT +specified an unsupported type. +.It Bq Er ELF_E_DATA +The +.Ar src +argument had a zero +.Va d_size +field. +.It Bq Er ELF_E_DATA The .Ar src argument specified a buffer size that was not an integral multiple of its underlying type. -.It Bq Er ELF_E_ARGUMENT +.It Bq Er ELF_E_DATA The .Ar dst argument specified a buffer size that was too small. -.It Bq Er ELF_E_ARGUMENT +.It Bq Er ELF_E_DATA Argument .Ar dst specified a destination buffer that overlaps with the source buffer. -.It Bq Er ELF_E_ARGUMENT +.It Bq Er ELF_E_DATA The destination buffer for a conversion to memory had an alignment inappropriate for the underlying ELF type. -.It Bq Er ELF_E_ARGUMENT +.It Bq Er ELF_E_DATA The source buffer for a conversion to file had an alignment inappropriate for the underlying ELF type. .It Bq Er ELF_E_UNIMPL ==== //depot/projects/dtrace/src/lib/libelf/libelf.c#3 (text+ko) ==== @@ -27,7 +27,7 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -#include <sys/types.h> +#include <sys/param.h> #include <machine/elf.h> #include <machine/endian.h> @@ -87,8 +87,10 @@ [ELF_T_SXWORD] = ALIGN64(Sxword), [ELF_T_SYMINFO] = UNSUPPORTED(), [ELF_T_SYM] = ALIGNMENT(Sym), +#if __FreeBSD_version >= 700009 [ELF_T_VDEF] = ALIGNMENT(Verdef), [ELF_T_VNEED] = ALIGNMENT(Verneed), +#endif [ELF_T_WORD] = ALIGNMENT(Word), [ELF_T_XWORD] = ALIGN64(Xword) }; ==== //depot/projects/dtrace/src/lib/libelf/libelf.h#6 (text+ko) ==== @@ -141,6 +141,7 @@ ELF_E_ARCHIVE, /* Malformed ar(1) archive */ ELF_E_ARGUMENT, /* Invalid argument */ ELF_E_CLASS, /* Mismatched ELF class */ + ELF_E_DATA, /* Invalid data buffer descriptor */ ELF_E_HEADER, /* Missing or malformed ELF header */ ELF_E_MMAP, /* File mapping failed */ ELF_E_MODE, /* Wrong mode for ELF descriptor */ ==== //depot/projects/dtrace/src/lib/libelf/libelf_allocate.c#2 (text+ko) ==== @@ -50,15 +50,17 @@ return NULL; } - e->e_kind = ELF_K_NONE; - e->e_class = ELFCLASSNONE; - e->e_cmd = ELF_C_NULL; - e->e_byteorder = ELFDATANONE; - e->e_parent = NULL; - e->e_rawfile = NULL; - e->e_rawsize = 0; - e->e_fd = -1; e->e_activations = 1; + e->e_byteorder = ELFDATANONE; + e->e_class = ELFCLASSNONE; + e->e_cmd = ELF_C_NULL; + e->e_fd = -1; + e->e_flags = 0; + e->e_kind = ELF_K_NONE; + e->e_parent = NULL; + e->e_rawfile = NULL; + e->e_rawsize = 0; + e->e_version = LIBELF_PRIVATE(version); (void) memset(&e->e_u, 0, sizeof(e->e_u)); ==== //depot/projects/dtrace/src/lib/libelf/libelf_convert.m4#8 (text+ko) ==== @@ -1,4 +1,4 @@ -//depot/projects/dtrace/src/lib/libelf/libelf_convert.m4#4 - edit change 103978 (text+ko) +//depot/user/jkoshy/projects/libbsdelf/src/libelf_convert.m4#10 - edit change 104937 (text+ko) /*- * Copyright (c) 2006 Joseph Koshy * All rights reserved. @@ -45,33 +45,33 @@ */ #define SWAP_HALF(X) do { \ - uint16_t _t = (uint16_t) (X); \ - (X) = \ - (_t & 0x00FF) << 8 | \ - (_t & 0xFF00) >> 8; \ + 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 _t = (uint32_t) (X); \ - (X) = \ - (_t & 0x000000FFUL) << 24 | \ - (_t & 0x0000FF00UL) << 8 | \ - (_t & 0x00FF0000UL) >> 8 | \ - (_t & 0xFF000000UL) >> 24; \ + 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 _t = (uint64_t) (X); \ - (X) = \ - (_t & 0x00000000000000FFULL) << 56 | \ - (_t & 0x000000000000FF00ULL) << 40 | \ - (_t & 0x0000000000FF0000ULL) << 24 | \ - (_t & 0x00000000FF000000ULL) << 8 | \ - (_t & 0x000000FF00000000ULL) >> 8 | \ - (_t & 0x0000FF0000000000ULL) >> 24 | \ - (_t & 0x00FF000000000000ULL) >> 40 | \ - (_t & 0xFF00000000000000ULL) >> 56; \ + 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_OFF64(X) SWAP_WORD64(X) @@ -205,9 +205,16 @@ * 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 additinal complication is that `ar' only pads data + * 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') @@ -226,6 +233,11 @@ IGNORE(NOTE) IGNORE(SYMINFO) +ifelse(eval(OSRELDATE < 700009),1, + `IGNORE(VDEF) + IGNORE(VNEED)', + `') + define(IGNORE_BYTE, 1) define(IGNORE_SXWORD32, 1) define(IGNORE_XWORD32, 1) @@ -250,24 +262,34 @@ 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 void libelf_cvt_$1$3_tof(char *dst, char *src, int count, int byteswap) { - Elf64_$2 t; + Elf$4_$2 t, *s = (Elf$4_$2 *) (uintptr_t) src; int c; if (dst == src && !byteswap) return; if (!byteswap) { - (void) memcpy(dst, src, count * sizeof(t)); + (void) memcpy(dst, src, count * sizeof(*s)); return; } for (c = 0; c < count; c++) { - memcpy(&t, src, sizeof(t)); - src += sizeof(t); + t = *s++; SWAP_$1$3(t); WRITE_$1$3(dst,t); } @@ -278,22 +300,21 @@ static void libelf_cvt_$1$3_tom(char *dst, char *src, int count, int byteswap) { - Elf64_$2 t; + Elf$4_$2 t, *d = (Elf$4_$2 *) (uintptr_t) dst; int c; if (dst == src && !byteswap) return; if (!byteswap) { - (void) memcpy(dst, src, count * sizeof(t)); + (void) memcpy(dst, src, count * sizeof(*d)); return; } for (c = 0; c < count; c++) { READ_$1$3(src,t); SWAP_$1$3(t); - memcpy(dst, &t, sizeof(t)); - dst += sizeof(t); + *d++ = t; } } ') @@ -362,6 +383,11 @@ * 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', @@ -369,12 +395,12 @@ static void libelf_cvt$3_$1_tof(char *dst, char *src, int count, int byteswap) { - Elf$3_$2 t; + Elf$3_$2 t, *s; int c; + s = (Elf$3_$2 *) (uintptr_t) src; for (c = 0; c < count; c++) { - memcpy(&t, src, sizeof(t)); - src += sizeof(t); + t = *s++; if (byteswap) { SWAP_STRUCT($2,$3) } @@ -388,36 +414,48 @@ static void libelf_cvt$3_$1_tom(char *dst, char *src, int count, int byteswap) { - Elf$3_$2 t; - unsigned char *s; - int i; + Elf$3_$2 t, *d; + unsigned char *s,*s0; size_t fsz; fsz = elf$3_fsize(ELF_T_$1, 1, EV_CURRENT); + d = ((Elf$3_$2 *) (uintptr_t) dst) + (count - 1); + s0 = (unsigned char *) src + (count - 1) * fsz; - for (i = 0; i < count; i++) { - s = (unsigned char *) src; + while (count--) { + s = s0; READ_STRUCT($2,$3) if (byteswap) { SWAP_STRUCT($2,$3) } - memcpy(dst, &t, sizeof(t)); - dst += sizeof(t); - src += fsz; + *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,`') - MAKEPRIM_TO_M($1,$2,`')')', + `MAKEPRIM_TO_F($1,$2,`',64) + MAKEPRIM_TO_M($1,$2,`',64)')', `ifdef(`SIZEDEP_'$1, - `MAKEPRIM_TO_F($1,$2,32)dnl - MAKEPRIM_TO_M($1,$2,32)dnl - MAKEPRIM_TO_F($1,$2,64)dnl - MAKEPRIM_TO_M($1,$2,64)', + `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 ==== //depot/projects/dtrace/src/lib/libelf/libelf_ehdr.c#5 (text+ko) ==== @@ -42,7 +42,7 @@ eh->e_ident[EI_MAG1] = ELFMAG1; \ eh->e_ident[EI_MAG2] = ELFMAG2; \ eh->e_ident[EI_MAG3] = ELFMAG3; \ - eh->e_ident[EI_CLASS] = LIBELF_PRIVATE(class); \ + eh->e_ident[EI_CLASS] = ELFCLASS##SZ; \ eh->e_ident[EI_DATA] = ELFDATANONE; \ eh->e_ident[EI_VERSION] = LIBELF_PRIVATE(version); \ eh->e_machine = EM_NONE; \ ==== //depot/projects/dtrace/src/lib/libelf/libelf_fsize.m4#2 (text+ko) ==== @@ -53,6 +53,10 @@ define(`XWORD_SIZE32', 0) define(`SXWORD_SIZE32', 0) +ifelse(eval(OSRELDATE < 700009),1, + `define(`VDEF_SIZE', 0) + define(`VNEED_SIZE', 0)',`') + /* * FSZ{32,64} define the sizes of 32 and 64 bit file structures respectively. */ ==== //depot/projects/dtrace/src/lib/libelf/libelf_msize.m4#2 (text+ko) ==== @@ -60,6 +60,10 @@ define(SXWORD_SIZE32, 0) define(XWORD_SIZE32, 0) +ifelse(eval(OSRELDATE < 700009),1, + `define(`VDEF_SIZE', 0) + define(`VNEED_SIZE', 0)',`') + define(`DEFINE_ELF_MSIZE', `ifdef($1`_SIZE', `define($1_SIZE32,$1_SIZE)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200608242102.k7OL2KOR042029>