diff options
| author | Ed Maste <emaste@FreeBSD.org> | 2014-12-22 20:32:23 +0000 |
|---|---|---|
| committer | Ed Maste <emaste@FreeBSD.org> | 2014-12-22 20:32:23 +0000 |
| commit | 5eccfb5cf5403e9e564066e0a75d80534b49e91d (patch) | |
| tree | 78347950207dea134308b7c9d4843204e80507e0 /libelf | |
| parent | 5265ace0e440a23fb522c516f4ee20f43eaed2b3 (diff) | |
Diffstat (limited to 'libelf')
35 files changed, 464 insertions, 349 deletions
diff --git a/libelf/_libelf.h b/libelf/_libelf.h index fba2f97fd670..d5803a4e44ff 100644 --- a/libelf/_libelf.h +++ b/libelf/_libelf.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: _libelf.h 2365 2011-12-29 04:36:44Z jkoshy $ + * $Id: _libelf.h 3011 2014-03-23 03:32:42Z jkoshy $ */ #ifndef __LIBELF_H_ @@ -48,7 +48,7 @@ struct _libelf_globals { int libelf_error; int libelf_fillchar; unsigned int libelf_version; - char libelf_msg[LIBELF_MSG_SIZE]; + unsigned char libelf_msg[LIBELF_MSG_SIZE]; }; extern struct _libelf_globals _libelf; @@ -71,14 +71,14 @@ extern struct _libelf_globals _libelf; * Flags for library internal use. These use the upper 16 bits of the * `e_flags' field. */ -#define LIBELF_F_API_MASK 0x00FFFF /* Flags defined by the API. */ -#define LIBELF_F_AR_HEADER 0x010000 /* translated header available */ -#define LIBELF_F_AR_VARIANT_SVR4 0x020000 /* BSD style ar(1) archive */ -#define LIBELF_F_DATA_MALLOCED 0x040000 /* whether data was malloc'ed */ -#define LIBELF_F_RAWFILE_MALLOC 0x080000 /* whether e_rawfile was malloc'ed */ -#define LIBELF_F_RAWFILE_MMAP 0x100000 /* whether e_rawfile was mmap'ed */ -#define LIBELF_F_SHDRS_LOADED 0x200000 /* whether all shdrs were read in */ -#define LIBELF_F_SPECIAL_FILE 0x400000 /* non-regular file */ +#define LIBELF_F_API_MASK 0x00FFFFU /* Flags defined by the API. */ +#define LIBELF_F_AR_HEADER 0x010000U /* translated header available */ +#define LIBELF_F_AR_VARIANT_SVR4 0x020000U /* BSD style ar(1) archive */ +#define LIBELF_F_DATA_MALLOCED 0x040000U /* whether data was malloc'ed */ +#define LIBELF_F_RAWFILE_MALLOC 0x080000U /* whether e_rawfile was malloc'ed */ +#define LIBELF_F_RAWFILE_MMAP 0x100000U /* whether e_rawfile was mmap'ed */ +#define LIBELF_F_SHDRS_LOADED 0x200000U /* whether all shdrs were read in */ +#define LIBELF_F_SPECIAL_FILE 0x400000U /* non-regular file */ struct _Elf { int e_activations; /* activation count */ @@ -89,7 +89,7 @@ struct _Elf { unsigned int e_flags; /* ELF_F_* & LIBELF_F_* flags */ Elf_Kind e_kind; /* ELF_K_* */ Elf *e_parent; /* non-NULL for archive members */ - char *e_rawfile; /* uninterpreted bytes */ + unsigned char *e_rawfile; /* uninterpreted bytes */ size_t e_rawsize; /* size of uninterpreted bytes */ unsigned int e_version; /* file version */ @@ -99,16 +99,16 @@ struct _Elf { */ union { Elf_Arhdr *e_arhdr; /* translated header */ - char *e_rawhdr; /* untranslated header */ + unsigned char *e_rawhdr; /* untranslated header */ } e_hdr; union { struct { /* ar(1) archives */ off_t e_next; /* set by elf_rand()/elf_next() */ int e_nchildren; - char *e_rawstrtab; /* file name strings */ + unsigned char *e_rawstrtab; /* file name strings */ size_t e_rawstrtabsz; - char *e_rawsymtab; /* symbol table */ + unsigned char *e_rawsymtab; /* symbol table */ size_t e_rawsymtabsz; Elf_Arsym *e_symtab; size_t e_symtabsz; @@ -162,21 +162,31 @@ enum { ELF_TOMEMORY }; -#define LIBELF_COPY_U32(DST,SRC,NAME) do { \ - if ((SRC)->NAME > UINT_MAX) { \ - LIBELF_SET_ERROR(RANGE, 0); \ - return (0); \ - } \ - (DST)->NAME = (SRC)->NAME; \ + +/* + * The LIBELF_COPY macros are used to copy fields from a GElf_* + * structure to their 32-bit counterparts, while checking for out of + * range values. + * + * - LIBELF_COPY_U32 :: copy an unsigned 32 bit field. + * - LIBELF_COPY_S32 :: copy a signed 32 bit field. + */ + +#define LIBELF_COPY_U32(DST, SRC, NAME) do { \ + if ((SRC)->NAME > UINT32_MAX) { \ + LIBELF_SET_ERROR(RANGE, 0); \ + return (0); \ + } \ + (DST)->NAME = (SRC)->NAME & 0xFFFFFFFFU; \ } while (0) -#define LIBELF_COPY_S32(DST,SRC,NAME) do { \ - if ((SRC)->NAME > INT_MAX || \ - (SRC)->NAME < INT_MIN) { \ - LIBELF_SET_ERROR(RANGE, 0); \ - return (0); \ - } \ - (DST)->NAME = (SRC)->NAME; \ +#define LIBELF_COPY_S32(DST, SRC, NAME) do { \ + if ((SRC)->NAME > INT32_MAX || \ + (SRC)->NAME < INT32_MIN) { \ + LIBELF_SET_ERROR(RANGE, 0); \ + return (0); \ + } \ + (DST)->NAME = (int32_t) (SRC)->NAME; \ } while (0) @@ -191,22 +201,22 @@ Elf_Scn *_libelf_allocate_scn(Elf *_e, size_t _ndx); Elf_Arhdr *_libelf_ar_gethdr(Elf *_e); Elf *_libelf_ar_open(Elf *_e, int _reporterror); Elf *_libelf_ar_open_member(int _fd, Elf_Cmd _c, Elf *_ar); -int _libelf_ar_get_member(char *_s, size_t _sz, int _base, size_t *_ret); Elf_Arsym *_libelf_ar_process_bsd_symtab(Elf *_ar, size_t *_dst); Elf_Arsym *_libelf_ar_process_svr4_symtab(Elf *_ar, size_t *_dst); -unsigned long _libelf_checksum(Elf *_e, int _elfclass); +long _libelf_checksum(Elf *_e, int _elfclass); void *_libelf_ehdr(Elf *_e, int _elfclass, int _allocate); -int _libelf_falign(Elf_Type _t, int _elfclass); +unsigned int _libelf_falign(Elf_Type _t, int _elfclass); size_t _libelf_fsize(Elf_Type _t, int _elfclass, unsigned int _version, size_t count); int (*_libelf_get_translator(Elf_Type _t, int _direction, int _elfclass)) - (char *_dst, size_t dsz, char *_src, size_t _cnt, int _byteswap); + (unsigned char *_dst, size_t dsz, unsigned char *_src, + size_t _cnt, int _byteswap); void *_libelf_getphdr(Elf *_e, int _elfclass); void *_libelf_getshdr(Elf_Scn *_scn, int _elfclass); void _libelf_init_elf(Elf *_e, Elf_Kind _kind); int _libelf_load_section_headers(Elf *e, void *ehdr); -int _libelf_malign(Elf_Type _t, int _elfclass); -Elf *_libelf_memory(char *_image, size_t _sz, int _reporterror); +unsigned int _libelf_malign(Elf_Type _t, int _elfclass); +Elf *_libelf_memory(unsigned char *_image, size_t _sz, int _reporterror); size_t _libelf_msize(Elf_Type _t, int _elfclass, unsigned int _version); void *_libelf_newphdr(Elf *_e, int _elfclass, size_t _count); Elf *_libelf_open_object(int _fd, Elf_Cmd _c, int _reporterror); diff --git a/libelf/_libelf_ar.h b/libelf/_libelf_ar.h index d6b15a7501ef..45a7e16be863 100644 --- a/libelf/_libelf_ar.h +++ b/libelf/_libelf_ar.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: _libelf_ar.h 2032 2011-10-23 09:07:00Z jkoshy $ + * $Id: _libelf_ar.h 3013 2014-03-23 06:16:59Z jkoshy $ */ #ifndef __LIBELF_AR_H_ @@ -42,15 +42,16 @@ (sizeof(LIBELF_AR_BSD_EXTENDED_NAME_PREFIX) - 1) #define IS_EXTENDED_BSD_NAME(NAME) \ - (strncmp((NAME), LIBELF_AR_BSD_EXTENDED_NAME_PREFIX, \ + (strncmp((const char *) (NAME), \ + LIBELF_AR_BSD_EXTENDED_NAME_PREFIX, \ LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE) == 0) -char *_libelf_ar_get_string(const char *_buf, size_t _sz, int _rawname, - int _svr4names); +unsigned char *_libelf_ar_get_string(const char *_buf, size_t _sz, + unsigned int _rawname, int _svr4names); char *_libelf_ar_get_raw_name(const struct ar_hdr *_arh); char *_libelf_ar_get_translated_name(const struct ar_hdr *_arh, Elf *_ar); -int _libelf_ar_get_number(const char *_buf, size_t _sz, int _base, - size_t *_ret); +int _libelf_ar_get_number(const char *_buf, size_t _sz, + unsigned int _base, size_t *_ret); #endif /* __LIBELF_AR_H_ */ diff --git a/libelf/elf.3 b/libelf/elf.3 index 462e72854177..97677eb205d6 100644 --- a/libelf/elf.3 +++ b/libelf/elf.3 @@ -21,9 +21,9 @@ .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" -.\" $Id: elf.3 2885 2013-01-11 02:11:28Z jkoshy $ +.\" $Id: elf.3 3082 2014-07-28 09:13:33Z jkoshy $ .\" -.Dd August 14, 2011 +.Dd July 28, 2014 .Os .Dt ELF 3 .Sh NAME @@ -367,6 +367,11 @@ section entries. .Xc .It Dv SHT_DYNSYM Ta Dv ELF_T_SYM Ta Symbols for dynamic linking. .It Dv SHT_FINI_ARRAY Ta Dv ELF_T_ADDR Ta Termination function pointers. +.It Dv SHT_GNU_HASH Ta Dv ELF_T_GNUHASH Ta GNU hash sections. +.It Dv SHT_GNU_LIBLIST Ta Dv ELF_T_WORD Ta List of libraries to be pre-linked. +.It Dv SHT_GNU_verdef Ta Dv ELF_T_VDEF Ta Symbol version definitions. +.It Dv SHT_GNU_verneed Ta Dv ELF_T_VNEED Ta Symbol versioning requirements. +.It Dv SHT_GNU_versym Ta Dv ELF_T_HALF Ta Version symbols. .It Dv SHT_GROUP Ta Dv ELF_T_WORD Ta Section group marker. .It Dv SHT_HASH Ta Dv ELF_T_HASH Ta Symbol hashes. .It Dv SHT_INIT_ARRAY Ta Dv ELF_T_ADDR Ta Initialization function pointers. @@ -383,12 +388,31 @@ See .It Dv SHT_STRTAB Ta Dv ELF_T_BYTE Ta String tables. .It Dv SHT_SYMTAB Ta Dv ELF_T_SYM Ta Symbol tables. .It Dv SHT_SYMTAB_SHNDX Ta Dv ELF_T_WORD Ta Used with extended section numbering. -.It Dv SHT_GNU_verdef Ta Dv ELF_T_VDEF Ta Symbol version definitions. -.It Dv SHT_GNU_verneed Ta Dv ELF_T_VNEED Ta Symbol versioning requirements. -.It Dv SHT_GNU_versym Ta Dv ELF_T_HALF Ta Version symbols. +.It Dv SHT_SUNW_dof Ta Dv ELF_T_BYTE Ta Xo +Used by +.Xr dtrace 1 . +.Xc .It Dv SHT_SUNW_move Ta Dv ELF_T_MOVE Ta ELF move records. .It Dv SHT_SUNW_syminfo Ta Dv ELF_T_SYMINFO Ta Additional symbol flags. +.It Dv SHT_SUNW_verdef Ta Dv ELF_T_VDEF Ta Xo +Same as +.Dv SHT_GNU_verdef . +.Xc +.It Dv SHT_SUNW_verneed Ta Dv ELF_T_VNEED Ta Xo +Same as +.Dv SHT_GNU_verneed . +.Xc +.It Dv SHT_SUNW_versym Ta Dv ELF_T_HALF Ta Xo +Same as +.Dv SHT_GNU_versym . +.Xc .El +.Pp +Section types in the range +.Ns [ Dv SHT_LOOS , +.Dv SHT_HIUSER ] +are otherwise considered to be of type +.Dv ELF_T_BYTE . .TE .Ss Functional Grouping This section contains a brief overview of the available functionality diff --git a/libelf/elf_data.c b/libelf/elf_data.c index 06a3577dc5dd..9960b77bea27 100644 --- a/libelf/elf_data.c +++ b/libelf/elf_data.c @@ -31,7 +31,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: elf_data.c 2921 2013-03-04 16:19:22Z jkoshy $"); +ELFTC_VCSID("$Id: elf_data.c 3009 2014-03-23 01:49:59Z jkoshy $"); Elf_Data * elf_getdata(Elf_Scn *s, Elf_Data *ed) @@ -39,10 +39,11 @@ elf_getdata(Elf_Scn *s, Elf_Data *ed) Elf *e; unsigned int sh_type; int elfclass, elftype; - size_t fsz, msz, count; + size_t count, fsz, msz; struct _Libelf_Data *d; uint64_t sh_align, sh_offset, sh_size; - int (*xlate)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); + int (*xlate)(unsigned char *_d, size_t _dsz, unsigned char *_s, + size_t _c, int _swap); d = (struct _Libelf_Data *) ed; @@ -108,11 +109,23 @@ elf_getdata(Elf_Scn *s, Elf_Data *ed) return (NULL); } - count = sh_size / fsz; + if (sh_size / fsz > SIZE_MAX) { + LIBELF_SET_ERROR(RANGE, 0); + return (NULL); + } + + count = (size_t) (sh_size / fsz); msz = _libelf_msize(elftype, elfclass, e->e_version); + if (count > 0 && msz > SIZE_MAX / count) { + LIBELF_SET_ERROR(RANGE, 0); + return (NULL); + } + assert(msz > 0); + assert(count <= SIZE_MAX); + assert(msz * count <= SIZE_MAX); if ((d = _libelf_allocate_data(s)) == NULL) return (NULL); @@ -129,7 +142,7 @@ elf_getdata(Elf_Scn *s, Elf_Data *ed) return (&d->d_data); } - if ((d->d_data.d_buf = malloc(msz*count)) == NULL) { + if ((d->d_data.d_buf = malloc(msz * count)) == NULL) { (void) _libelf_release_data(d); LIBELF_SET_ERROR(RESOURCE, 0); return (NULL); @@ -138,7 +151,7 @@ elf_getdata(Elf_Scn *s, Elf_Data *ed) d->d_flags |= LIBELF_F_DATA_MALLOCED; xlate = _libelf_get_translator(elftype, ELF_TOMEMORY, elfclass); - if (!(*xlate)(d->d_data.d_buf, d->d_data.d_size, + if (!(*xlate)(d->d_data.d_buf, (size_t) d->d_data.d_size, e->e_rawfile + sh_offset, count, e->e_byteorder != LIBELF_PRIVATE(byteorder))) { _libelf_release_data(d); diff --git a/libelf/elf_errmsg.c b/libelf/elf_errmsg.c index adcaa74b29ba..409862cc1557 100644 --- a/libelf/elf_errmsg.c +++ b/libelf/elf_errmsg.c @@ -32,13 +32,13 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: elf_errmsg.c 2225 2011-11-26 18:55:54Z jkoshy $"); +ELFTC_VCSID("$Id: elf_errmsg.c 3012 2014-03-23 03:41:38Z jkoshy $"); /* * Retrieve a human readable translation for an error message. */ -const char *_libelf_errors[] = { +static const char *_libelf_errors[] = { #define DEFINE_ERROR(N,S) [ELF_E_##N] = S DEFINE_ERROR(NONE, "No Error"), DEFINE_ERROR(ARCHIVE, "Malformed ar(1) archive"), @@ -76,7 +76,7 @@ elf_errmsg(int error) if (error < ELF_E_NONE || error >= ELF_E_NUM) return _libelf_errors[ELF_E_NUM]; if (oserr) { - (void) snprintf(LIBELF_PRIVATE(msg), + (void) snprintf((char *) LIBELF_PRIVATE(msg), sizeof(LIBELF_PRIVATE(msg)), "%s: %s", _libelf_errors[error], strerror(oserr)); return (const char *)&LIBELF_PRIVATE(msg); diff --git a/libelf/elf_flag.c b/libelf/elf_flag.c index ab9d24a0ecea..89af3160da6a 100644 --- a/libelf/elf_flag.c +++ b/libelf/elf_flag.c @@ -30,7 +30,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: elf_flag.c 2272 2011-12-03 17:07:31Z jkoshy $"); +ELFTC_VCSID("$Id: elf_flag.c 2988 2014-03-17 08:51:49Z jkoshy $"); unsigned int elf_flagarhdr(Elf_Arhdr *a, Elf_Cmd c, unsigned int flags) @@ -111,7 +111,7 @@ elf_flagehdr(Elf *e, Elf_Cmd c, unsigned int flags) unsigned int elf_flagelf(Elf *e, Elf_Cmd c, unsigned int flags) { - int r; + unsigned int r; if (e == NULL) return (0); @@ -173,7 +173,7 @@ elf_flagphdr(Elf *e, Elf_Cmd c, unsigned int flags) unsigned int elf_flagscn(Elf_Scn *s, Elf_Cmd c, unsigned int flags) { - int r; + unsigned int r; if (s == NULL) return (0); diff --git a/libelf/elf_memory.c b/libelf/elf_memory.c index 9c4755d0f59b..d70f6e094912 100644 --- a/libelf/elf_memory.c +++ b/libelf/elf_memory.c @@ -28,7 +28,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: elf_memory.c 2368 2011-12-29 06:34:28Z jkoshy $"); +ELFTC_VCSID("$Id: elf_memory.c 3013 2014-03-23 06:16:59Z jkoshy $"); Elf * elf_memory(char *image, size_t sz) @@ -43,5 +43,5 @@ elf_memory(char *image, size_t sz) return (NULL); } - return (_libelf_memory(image, sz, 1)); + return (_libelf_memory((unsigned char *) image, sz, 1)); } diff --git a/libelf/elf_next.c b/libelf/elf_next.c index 605a593dd9e3..7da8ba6fe857 100644 --- a/libelf/elf_next.c +++ b/libelf/elf_next.c @@ -32,7 +32,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: elf_next.c 2225 2011-11-26 18:55:54Z jkoshy $"); +ELFTC_VCSID("$Id: elf_next.c 2989 2014-03-17 09:56:46Z jkoshy $"); Elf_Cmd elf_next(Elf *e) @@ -48,13 +48,17 @@ elf_next(Elf *e) return (ELF_C_NULL); } - assert (parent->e_kind == ELF_K_AR); - assert (parent->e_cmd == ELF_C_READ); + assert(parent->e_kind == ELF_K_AR); + assert(parent->e_cmd == ELF_C_READ); assert(e->e_rawfile > parent->e_rawfile); - next = e->e_rawfile - parent->e_rawfile + e->e_rawsize; + next = e->e_rawfile - parent->e_rawfile + (off_t) e->e_rawsize; next = (next + 1) & ~1; /* round up to an even boundary */ + /* + * Setup the 'e_next' field of the archive descriptor for the + * next call to 'elf_begin()'. + */ parent->e_u.e_ar.e_next = (next >= (off_t) parent->e_rawsize) ? (off_t) 0 : next; diff --git a/libelf/elf_open.c b/libelf/elf_open.c index b039431571fb..5aad459f4002 100644 --- a/libelf/elf_open.c +++ b/libelf/elf_open.c @@ -63,5 +63,5 @@ elf_openmemory(char *image, size_t sz) return (NULL); } - return (_libelf_memory(image, sz, 0)); + return (_libelf_memory((unsigned char *) image, sz, 0)); } diff --git a/libelf/elf_rand.c b/libelf/elf_rand.c index f48f01745802..8c36ff809702 100644 --- a/libelf/elf_rand.c +++ b/libelf/elf_rand.c @@ -31,7 +31,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: elf_rand.c 2225 2011-11-26 18:55:54Z jkoshy $"); +ELFTC_VCSID("$Id: elf_rand.c 2991 2014-03-17 09:57:04Z jkoshy $"); off_t elf_rand(Elf *ar, off_t offset) @@ -40,7 +40,7 @@ elf_rand(Elf *ar, off_t offset) if (ar == NULL || ar->e_kind != ELF_K_AR || (offset & 1) || offset < SARMAG || - offset + sizeof(struct ar_hdr) >= ar->e_rawsize) { + (size_t) offset + sizeof(struct ar_hdr) >= ar->e_rawsize) { LIBELF_SET_ERROR(ARGUMENT, 0); return 0; } diff --git a/libelf/elf_rawfile.c b/libelf/elf_rawfile.c index 76cfd7fa3435..a5b5b3ed5f7f 100644 --- a/libelf/elf_rawfile.c +++ b/libelf/elf_rawfile.c @@ -30,13 +30,13 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: elf_rawfile.c 2225 2011-11-26 18:55:54Z jkoshy $"); +ELFTC_VCSID("$Id: elf_rawfile.c 3013 2014-03-23 06:16:59Z jkoshy $"); char * elf_rawfile(Elf *e, size_t *sz) { - char *ptr; size_t size; + unsigned char *ptr; size = e ? e->e_rawsize : 0; ptr = NULL; @@ -49,5 +49,5 @@ elf_rawfile(Elf *e, size_t *sz) if (sz) *sz = size; - return (ptr); + return ((char *) ptr); } diff --git a/libelf/elf_scn.c b/libelf/elf_scn.c index 357fbb33d847..f80711579d59 100644 --- a/libelf/elf_scn.c +++ b/libelf/elf_scn.c @@ -36,7 +36,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: elf_scn.c 2225 2011-11-26 18:55:54Z jkoshy $"); +ELFTC_VCSID("$Id: elf_scn.c 3013 2014-03-23 06:16:59Z jkoshy $"); /* * Load an ELF section table and create a list of Elf_Scn structures. @@ -44,14 +44,15 @@ ELFTC_VCSID("$Id: elf_scn.c 2225 2011-11-26 18:55:54Z jkoshy $"); int _libelf_load_section_headers(Elf *e, void *ehdr) { - int ec, swapbytes; - size_t fsz, i, shnum; + Elf_Scn *scn; uint64_t shoff; - char *src; Elf32_Ehdr *eh32; Elf64_Ehdr *eh64; - Elf_Scn *scn; - int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); + int ec, swapbytes; + unsigned char *src; + size_t fsz, i, shnum; + int (*xlator)(unsigned char *_d, size_t _dsz, unsigned char *_s, + size_t _c, int _swap); assert(e != NULL); assert(ehdr != NULL); @@ -104,8 +105,8 @@ _libelf_load_section_headers(Elf *e, void *ehdr) if ((scn = _libelf_allocate_scn(e, i)) == NULL) return (0); - (*xlator)((char *) &scn->s_shdr, sizeof(scn->s_shdr), src, - (size_t) 1, swapbytes); + (*xlator)((unsigned char *) &scn->s_shdr, sizeof(scn->s_shdr), + src, (size_t) 1, swapbytes); if (ec == ELFCLASS32) { scn->s_offset = scn->s_rawoff = diff --git a/libelf/elf_strptr.c b/libelf/elf_strptr.c index c79970dc8907..e2a6b2899f58 100644 --- a/libelf/elf_strptr.c +++ b/libelf/elf_strptr.c @@ -31,7 +31,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: elf_strptr.c 2271 2011-12-03 17:06:35Z jkoshy $"); +ELFTC_VCSID("$Id: elf_strptr.c 2990 2014-03-17 09:56:58Z jkoshy $"); /* * Convert an ELF section#,offset pair to a string pointer. @@ -42,8 +42,8 @@ elf_strptr(Elf *e, size_t scndx, size_t offset) { Elf_Scn *s; Elf_Data *d; - size_t alignment, count; GElf_Shdr shdr; + uint64_t alignment, count; if (e == NULL || e->e_kind != ELF_K_ELF) { LIBELF_SET_ERROR(ARGUMENT, 0); @@ -90,7 +90,7 @@ elf_strptr(Elf *e, size_t scndx, size_t offset) * account 'holes' in coverage of the section introduced * by alignment requirements. */ - count = (size_t) 0; /* cumulative count of bytes seen */ + count = (uint64_t) 0; /* cumulative count of bytes seen */ while ((d = elf_getdata(s, d)) != NULL && count <= offset) { if (d->d_buf == NULL || d->d_size == 0) diff --git a/libelf/elf_update.c b/libelf/elf_update.c index b589233c8e4a..70a7c2e21e25 100644 --- a/libelf/elf_update.c +++ b/libelf/elf_update.c @@ -41,7 +41,7 @@ #include <sys/mman.h> #endif -ELFTC_VCSID("$Id: elf_update.c 2931 2013-03-23 11:41:07Z jkoshy $"); +ELFTC_VCSID("$Id: elf_update.c 3013 2014-03-23 06:16:59Z jkoshy $"); /* * Layout strategy: @@ -110,14 +110,13 @@ SLIST_HEAD(_Elf_Extent_List, _Elf_Extent); static int _libelf_compute_section_extents(Elf *e, Elf_Scn *s, off_t rc) { - int ec; Elf_Data *d; size_t fsz, msz; + int ec, elftype; uint32_t sh_type; uint64_t d_align; Elf32_Shdr *shdr32; Elf64_Shdr *shdr64; - unsigned int elftype; struct _Libelf_Data *ld; uint64_t scn_size, scn_alignment; uint64_t sh_align, sh_entsize, sh_offset, sh_size; @@ -253,7 +252,7 @@ _libelf_compute_section_extents(Elf *e, Elf_Scn *s, off_t rc) scn_size = roundup2(scn_size, d->d_align); d->d_off = scn_size; fsz = _libelf_fsize(d->d_type, ec, d->d_version, - d->d_size / msz); + (size_t) d->d_size / msz); scn_size += fsz; } @@ -307,7 +306,7 @@ computeoffset: * Compute the new offset for the section based on * the section's alignment needs. */ - sh_offset = roundup(rc, sh_align); + sh_offset = roundup((uint64_t) rc, sh_align); /* * Update the section header. @@ -471,7 +470,7 @@ _libelf_resync_sections(Elf *e, off_t rc, struct _Elf_Extent_List *extents) return ((off_t) -1); if ((size_t) rc < s->s_offset + s->s_size) - rc = s->s_offset + s->s_size; + rc = (off_t) (s->s_offset + s->s_size); } return (rc); @@ -529,17 +528,22 @@ _libelf_resync_elf(Elf *e, struct _Elf_Extent_List *extents) if (ec == ELFCLASS32) { eh_byteorder = eh32->e_ident[EI_DATA]; eh_class = eh32->e_ident[EI_CLASS]; - phoff = (uint64_t) eh32->e_phoff; - shoff = (uint64_t) eh32->e_shoff; + phoff = (off_t) eh32->e_phoff; + shoff = (off_t) eh32->e_shoff; eh_version = eh32->e_version; } else { eh_byteorder = eh64->e_ident[EI_DATA]; eh_class = eh64->e_ident[EI_CLASS]; - phoff = eh64->e_phoff; - shoff = eh64->e_shoff; + phoff = (off_t) eh64->e_phoff; + shoff = (off_t) eh64->e_shoff; eh_version = eh64->e_version; } + if (phoff < 0 || shoff < 0) { + LIBELF_SET_ERROR(HEADER, 0); + return ((off_t) -1); + } + if (eh_version == EV_NONE) eh_version = EV_CURRENT; @@ -564,18 +568,20 @@ _libelf_resync_elf(Elf *e, struct _Elf_Extent_List *extents) e->e_byteorder = eh_byteorder; #define INITIALIZE_EHDR(E,EC,V) do { \ + unsigned int _version = (unsigned int) (V); \ (E)->e_ident[EI_MAG0] = ELFMAG0; \ (E)->e_ident[EI_MAG1] = ELFMAG1; \ (E)->e_ident[EI_MAG2] = ELFMAG2; \ (E)->e_ident[EI_MAG3] = ELFMAG3; \ - (E)->e_ident[EI_CLASS] = (EC); \ - (E)->e_ident[EI_VERSION] = (V); \ - (E)->e_ehsize = _libelf_fsize(ELF_T_EHDR, (EC), (V), \ - (size_t) 1); \ - (E)->e_phentsize = (phnum == 0) ? 0 : _libelf_fsize( \ - ELF_T_PHDR, (EC), (V), (size_t) 1); \ - (E)->e_shentsize = _libelf_fsize(ELF_T_SHDR, (EC), (V), \ - (size_t) 1); \ + (E)->e_ident[EI_CLASS] = (unsigned char) (EC); \ + (E)->e_ident[EI_VERSION] = (_version & 0xFFU); \ + (E)->e_ehsize = (uint16_t) _libelf_fsize(ELF_T_EHDR, \ + (EC), _version, (size_t) 1); \ + (E)->e_phentsize = (uint16_t) ((phnum == 0) ? 0 : \ + _libelf_fsize(ELF_T_PHDR, (EC), _version, \ + (size_t) 1)); \ + (E)->e_shentsize = (uint16_t) _libelf_fsize(ELF_T_SHDR, \ + (EC), _version, (size_t) 1); \ } while (0) if (ec == ELFCLASS32) @@ -585,9 +591,10 @@ _libelf_resync_elf(Elf *e, struct _Elf_Extent_List *extents) (void) elf_flagehdr(e, ELF_C_SET, ELF_F_DIRTY); - rc += _libelf_fsize(ELF_T_EHDR, ec, eh_version, (size_t) 1); + rc += (off_t) _libelf_fsize(ELF_T_EHDR, ec, eh_version, (size_t) 1); - if (!_libelf_insert_extent(extents, ELF_EXTENT_EHDR, 0, rc, ehdr)) + if (!_libelf_insert_extent(extents, ELF_EXTENT_EHDR, 0, (uint64_t) rc, + ehdr)) return ((off_t) -1); /* @@ -608,20 +615,20 @@ _libelf_resync_elf(Elf *e, struct _Elf_Extent_List *extents) return ((off_t) -1); } - if (phoff % align) { + if (phoff % (off_t) align) { LIBELF_SET_ERROR(LAYOUT, 0); return ((off_t) -1); } } else - phoff = roundup(rc, align); + phoff = roundup(rc, (off_t) align); - rc = phoff + fsz; + rc = phoff + (off_t) fsz; phdr = _libelf_getphdr(e, ec); - if (!_libelf_insert_extent(extents, ELF_EXTENT_PHDR, phoff, - fsz, phdr)) + if (!_libelf_insert_extent(extents, ELF_EXTENT_PHDR, + (uint64_t) phoff, fsz, phdr)) return ((off_t) -1); } else phoff = 0; @@ -656,18 +663,18 @@ _libelf_resync_elf(Elf *e, struct _Elf_Extent_List *extents) align = _libelf_falign(ELF_T_SHDR, ec); if (e->e_flags & ELF_F_LAYOUT) { - if (shoff % align) { + if (shoff % (off_t) align) { LIBELF_SET_ERROR(LAYOUT, 0); return ((off_t) -1); } } else - shoff = roundup(rc, align); + shoff = roundup(rc, (off_t) align); - if (shoff + fsz > (size_t) rc) - rc = shoff + fsz; + if (shoff + (off_t) fsz > rc) + rc = shoff + (off_t) fsz; - if (!_libelf_insert_extent(extents, ELF_EXTENT_SHDR, shoff, - fsz, NULL)) + if (!_libelf_insert_extent(extents, ELF_EXTENT_SHDR, + (uint64_t) shoff, fsz, NULL)) return ((off_t) -1); } else shoff = 0; @@ -700,22 +707,23 @@ _libelf_resync_elf(Elf *e, struct _Elf_Extent_List *extents) * Write out the contents of an ELF section. */ -static size_t -_libelf_write_scn(Elf *e, char *nf, struct _Elf_Extent *ex) +static off_t +_libelf_write_scn(Elf *e, unsigned char *nf, struct _Elf_Extent *ex) { int ec; + off_t rc; Elf_Scn *s; int elftype; Elf_Data *d, dst; uint32_t sh_type; struct _Libelf_Data *ld; uint64_t sh_off, sh_size; - size_t fsz, msz, nobjects, rc; + size_t fsz, msz, nobjects; assert(ex->ex_type == ELF_EXTENT_SECTION); s = ex->ex_desc; - rc = ex->ex_start; + rc = (off_t) ex->ex_start; if ((ec = e->e_class) == ELFCLASS32) { sh_type = s->s_shdr.s_shdr32.sh_type; @@ -756,18 +764,20 @@ _libelf_write_scn(Elf *e, char *nf, struct _Elf_Extent *ex) if ((uint64_t) rc < sh_off + d->d_off) (void) memset(nf + rc, - LIBELF_PRIVATE(fillchar), sh_off + - d->d_off - rc); - rc = sh_off + d->d_off; + LIBELF_PRIVATE(fillchar), + (size_t) (sh_off + d->d_off - + (uint64_t) rc)); + rc = (off_t) (sh_off + d->d_off); assert(d->d_buf != NULL); assert(d->d_type == ELF_T_BYTE); assert(d->d_version == e->e_version); (void) memcpy(nf + rc, - e->e_rawfile + s->s_rawoff + d->d_off, d->d_size); + e->e_rawfile + s->s_rawoff + d->d_off, + (size_t) d->d_size); - rc += d->d_size; + rc += (off_t) d->d_size; } return (rc); @@ -789,15 +799,16 @@ _libelf_write_scn(Elf *e, char *nf, struct _Elf_Extent *ex) if ((uint64_t) rc < sh_off + d->d_off) (void) memset(nf + rc, - LIBELF_PRIVATE(fillchar), sh_off + d->d_off - rc); + LIBELF_PRIVATE(fillchar), + (size_t) (sh_off + d->d_off - (uint64_t) rc)); - rc = sh_off + d->d_off; + rc = (off_t) (sh_off + d->d_off); assert(d->d_buf != NULL); assert(d->d_version == e->e_version); assert(d->d_size % msz == 0); - nobjects = d->d_size / msz; + nobjects = (size_t) (d->d_size / msz); fsz = _libelf_fsize(d->d_type, ec, e->e_version, nobjects); @@ -808,10 +819,10 @@ _libelf_write_scn(Elf *e, char *nf, struct _Elf_Extent *ex) NULL) return ((off_t) -1); - rc += fsz; + rc += (off_t) fsz; } - return ((off_t) rc); + return (rc); } /* @@ -819,7 +830,7 @@ _libelf_write_scn(Elf *e, char *nf, struct _Elf_Extent *ex) */ static off_t -_libelf_write_ehdr(Elf *e, char *nf, struct _Elf_Extent *ex) +_libelf_write_ehdr(Elf *e, unsigned char *nf, struct _Elf_Extent *ex) { int ec; void *ehdr; @@ -860,7 +871,7 @@ _libelf_write_ehdr(Elf *e, char *nf, struct _Elf_Extent *ex) */ static off_t -_libelf_write_phdr(Elf *e, char *nf, struct _Elf_Extent *ex) +_libelf_write_phdr(Elf *e, unsigned char *nf, struct _Elf_Extent *ex) { int ec; void *ehdr; @@ -909,7 +920,7 @@ _libelf_write_phdr(Elf *e, char *nf, struct _Elf_Extent *ex) NULL) return ((off_t) -1); - return (phoff + fsz); + return ((off_t) (phoff + fsz)); } /* @@ -917,7 +928,7 @@ _libelf_write_phdr(Elf *e, char *nf, struct _Elf_Extent *ex) */ static off_t -_libelf_write_shdr(Elf *e, char *nf, struct _Elf_Extent *ex) +_libelf_write_shdr(Elf *e, unsigned char *nf, struct _Elf_Extent *ex) { int ec; void *ehdr; @@ -969,7 +980,7 @@ _libelf_write_shdr(Elf *e, char *nf, struct _Elf_Extent *ex) return ((off_t) -1); } - return (ex->ex_start + nscn * fsz); + return ((off_t) (ex->ex_start + nscn * fsz)); } /* @@ -993,9 +1004,9 @@ static off_t _libelf_write_elf(Elf *e, off_t newsize, struct _Elf_Extent_List *extents) { off_t nrc, rc; - char *newfile; Elf_Scn *scn, *tscn; struct _Elf_Extent *ex; + unsigned char *newfile; assert(e->e_kind == ELF_K_ELF); assert(e->e_cmd == ELF_C_RDWR || e->e_cmd == ELF_C_WRITE); @@ -1012,7 +1023,7 @@ _libelf_write_elf(Elf *e, off_t newsize, struct _Elf_Extent_List *extents) /* Fill inter-extent gaps. */ if (ex->ex_start > (size_t) rc) (void) memset(newfile + rc, LIBELF_PRIVATE(fillchar), - ex->ex_start - rc); + (size_t) (ex->ex_start - (uint64_t) rc)); switch (ex->ex_type) { case ELF_EXTENT_EHDR: @@ -1103,7 +1114,7 @@ _libelf_write_elf(Elf *e, off_t newsize, struct _Elf_Extent_List *extents) #endif /* ELFTC_HAVE_MMAP */ /* Record the new size of the file. */ - e->e_rawsize = newsize; + e->e_rawsize = (size_t) newsize; } else { /* File opened in ELF_C_WRITE mode. */ assert(e->e_rawfile == NULL); diff --git a/libelf/gelf_cap.c b/libelf/gelf_cap.c index a1c1417be1fa..9925d1bd214f 100644 --- a/libelf/gelf_cap.c +++ b/libelf/gelf_cap.c @@ -32,7 +32,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: gelf_cap.c 2272 2011-12-03 17:07:31Z jkoshy $"); +ELFTC_VCSID("$Id: gelf_cap.c 2995 2014-03-18 02:16:31Z jkoshy $"); GElf_Cap * gelf_getcap(Elf_Data *ed, int ndx, GElf_Cap *dst) @@ -72,7 +72,7 @@ gelf_getcap(Elf_Data *ed, int ndx, GElf_Cap *dst) assert(msz > 0); - if (msz * ndx >= d->d_data.d_size) { + if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } @@ -131,7 +131,7 @@ gelf_update_cap(Elf_Data *ed, int ndx, GElf_Cap *gc) msz = _libelf_msize(ELF_T_CAP, ec, e->e_version); assert(msz > 0); - if (msz * ndx >= d->d_data.d_size) { + if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } diff --git a/libelf/gelf_dyn.c b/libelf/gelf_dyn.c index 263102603397..4e09afd12ce2 100644 --- a/libelf/gelf_dyn.c +++ b/libelf/gelf_dyn.c @@ -32,7 +32,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: gelf_dyn.c 2272 2011-12-03 17:07:31Z jkoshy $"); +ELFTC_VCSID("$Id: gelf_dyn.c 2998 2014-03-18 17:19:00Z jkoshy $"); GElf_Dyn * gelf_getdyn(Elf_Data *ed, int ndx, GElf_Dyn *dst) @@ -71,8 +71,9 @@ gelf_getdyn(Elf_Data *ed, int ndx, GElf_Dyn *dst) msz = _libelf_msize(ELF_T_DYN, ec, e->e_version); assert(msz > 0); + assert(ndx >= 0); - if (msz * ndx >= d->d_data.d_size) { + if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } @@ -128,9 +129,11 @@ gelf_update_dyn(Elf_Data *ed, int ndx, GElf_Dyn *ds) } msz = _libelf_msize(ELF_T_DYN, ec, e->e_version); + assert(msz > 0); + assert(ndx >= 0); - if (msz * ndx >= d->d_data.d_size) { + if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } diff --git a/libelf/gelf_move.c b/libelf/gelf_move.c index d9e8993deee4..2b734eba53b8 100644 --- a/libelf/gelf_move.c +++ b/libelf/gelf_move.c @@ -32,7 +32,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: gelf_move.c 2272 2011-12-03 17:07:31Z jkoshy $"); +ELFTC_VCSID("$Id: gelf_move.c 2998 2014-03-18 17:19:00Z jkoshy $"); GElf_Move * gelf_getmove(Elf_Data *ed, int ndx, GElf_Move *dst) @@ -71,8 +71,9 @@ gelf_getmove(Elf_Data *ed, int ndx, GElf_Move *dst) msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version); assert(msz > 0); + assert(ndx >= 0); - if (msz * ndx >= d->d_data.d_size) { + if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } @@ -131,9 +132,11 @@ gelf_update_move(Elf_Data *ed, int ndx, GElf_Move *gm) } msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version); + assert(msz > 0); + assert(ndx >= 0); - if (msz * ndx >= d->d_data.d_size) { + if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } diff --git a/libelf/gelf_rel.c b/libelf/gelf_rel.c index eb057177d4cc..3b798c042201 100644 --- a/libelf/gelf_rel.c +++ b/libelf/gelf_rel.c @@ -32,7 +32,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: gelf_rel.c 2272 2011-12-03 17:07:31Z jkoshy $"); +ELFTC_VCSID("$Id: gelf_rel.c 2998 2014-03-18 17:19:00Z jkoshy $"); GElf_Rel * gelf_getrel(Elf_Data *ed, int ndx, GElf_Rel *dst) @@ -71,8 +71,9 @@ gelf_getrel(Elf_Data *ed, int ndx, GElf_Rel *dst) msz = _libelf_msize(ELF_T_REL, ec, e->e_version); assert(msz > 0); + assert(ndx >= 0); - if (msz * ndx >= d->d_data.d_size) { + if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } @@ -130,9 +131,11 @@ gelf_update_rel(Elf_Data *ed, int ndx, GElf_Rel *dr) } msz = _libelf_msize(ELF_T_REL, ec, e->e_version); + assert(msz > 0); + assert(ndx >= 0); - if (msz * ndx >= d->d_data.d_size) { + if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } @@ -147,8 +150,9 @@ gelf_update_rel(Elf_Data *ed, int ndx, GElf_Rel *dr) LIBELF_SET_ERROR(RANGE, 0); return (0); } - rel32->r_info = ELF32_R_INFO(ELF64_R_SYM(dr->r_info), - ELF64_R_TYPE(dr->r_info)); + rel32->r_info = ELF32_R_INFO( + (Elf32_Word) ELF64_R_SYM(dr->r_info), + (Elf32_Word) ELF64_R_TYPE(dr->r_info)); } else { rel64 = (Elf64_Rel *) d->d_data.d_buf + ndx; diff --git a/libelf/gelf_rela.c b/libelf/gelf_rela.c index cb61bdc2e2df..ed289a674d1f 100644 --- a/libelf/gelf_rela.c +++ b/libelf/gelf_rela.c @@ -32,7 +32,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: gelf_rela.c 2272 2011-12-03 17:07:31Z jkoshy $"); +ELFTC_VCSID("$Id: gelf_rela.c 2998 2014-03-18 17:19:00Z jkoshy $"); GElf_Rela * gelf_getrela(Elf_Data *ed, int ndx, GElf_Rela *dst) @@ -71,8 +71,9 @@ gelf_getrela(Elf_Data *ed, int ndx, GElf_Rela *dst) msz = _libelf_msize(ELF_T_RELA, ec, e->e_version); assert(msz > 0); + assert(ndx >= 0); - if (msz * ndx >= d->d_data.d_size) { + if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } @@ -131,9 +132,11 @@ gelf_update_rela(Elf_Data *ed, int ndx, GElf_Rela *dr) } msz = _libelf_msize(ELF_T_RELA, ec, e->e_version); + assert(msz > 0); + assert(ndx >= 0); - if (msz * ndx >= d->d_data.d_size) { + if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } @@ -148,8 +151,9 @@ gelf_update_rela(Elf_Data *ed, int ndx, GElf_Rela *dr) LIBELF_SET_ERROR(RANGE, 0); return (0); } - rela32->r_info = ELF32_R_INFO(ELF64_R_SYM(dr->r_info), - ELF64_R_TYPE(dr->r_info)); + rela32->r_info = ELF32_R_INFO( + (Elf32_Word) ELF64_R_SYM(dr->r_info), + (Elf32_Word) ELF64_R_TYPE(dr->r_info)); LIBELF_COPY_S32(rela32, dr, r_addend); } else { diff --git a/libelf/gelf_sym.c b/libelf/gelf_sym.c index 4a490d9ee079..e32a1869cea7 100644 --- a/libelf/gelf_sym.c +++ b/libelf/gelf_sym.c @@ -32,7 +32,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: gelf_sym.c 2272 2011-12-03 17:07:31Z jkoshy $"); +ELFTC_VCSID("$Id: gelf_sym.c 2999 2014-03-18 17:19:06Z jkoshy $"); GElf_Sym * gelf_getsym(Elf_Data *ed, int ndx, GElf_Sym *dst) @@ -71,25 +71,23 @@ gelf_getsym(Elf_Data *ed, int ndx, GElf_Sym *dst) msz = _libelf_msize(ELF_T_SYM, ec, e->e_version); assert(msz > 0); + assert(ndx >= 0); - if (msz * ndx >= d->d_data.d_size) { + if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if (ec == ELFCLASS32) { - sym32 = (Elf32_Sym *) d->d_data.d_buf + ndx; dst->st_name = sym32->st_name; dst->st_value = (Elf64_Addr) sym32->st_value; dst->st_size = (Elf64_Xword) sym32->st_size; - dst->st_info = ELF64_ST_INFO(ELF32_ST_BIND(sym32->st_info), - ELF32_ST_TYPE(sym32->st_info)); + dst->st_info = sym32->st_info; dst->st_other = sym32->st_other; dst->st_shndx = sym32->st_shndx; } else { - sym64 = (Elf64_Sym *) d->d_data.d_buf + ndx; *dst = *sym64; @@ -133,9 +131,11 @@ gelf_update_sym(Elf_Data *ed, int ndx, GElf_Sym *gs) } msz = _libelf_msize(ELF_T_SYM, ec, e->e_version); + assert(msz > 0); + assert(ndx >= 0); - if (msz * ndx >= d->d_data.d_size) { + if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } diff --git a/libelf/gelf_syminfo.c b/libelf/gelf_syminfo.c index bb2063d9a2d4..e54258292aa1 100644 --- a/libelf/gelf_syminfo.c +++ b/libelf/gelf_syminfo.c @@ -31,7 +31,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: gelf_syminfo.c 2272 2011-12-03 17:07:31Z jkoshy $"); +ELFTC_VCSID("$Id: gelf_syminfo.c 2998 2014-03-18 17:19:00Z jkoshy $"); GElf_Syminfo * gelf_getsyminfo(Elf_Data *ed, int ndx, GElf_Syminfo *dst) @@ -70,8 +70,9 @@ gelf_getsyminfo(Elf_Data *ed, int ndx, GElf_Syminfo *dst) msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version); assert(msz > 0); + assert(ndx >= 0); - if (msz * ndx >= d->d_data.d_size) { + if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } @@ -128,9 +129,11 @@ gelf_update_syminfo(Elf_Data *ed, int ndx, GElf_Syminfo *gs) } msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version); + assert(msz > 0); + assert(ndx >= 0); - if (msz * ndx >= d->d_data.d_size) { + if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } diff --git a/libelf/gelf_symshndx.c b/libelf/gelf_symshndx.c index 9cf3b7578183..69fabe55ce03 100644 --- a/libelf/gelf_symshndx.c +++ b/libelf/gelf_symshndx.c @@ -31,7 +31,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: gelf_symshndx.c 2283 2011-12-04 04:07:24Z jkoshy $"); +ELFTC_VCSID("$Id: gelf_symshndx.c 2998 2014-03-18 17:19:00Z jkoshy $"); GElf_Sym * gelf_getsymshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *dst, @@ -74,8 +74,9 @@ gelf_getsymshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *dst, msz = _libelf_msize(ELF_T_WORD, ec, e->e_version); assert(msz > 0); + assert(ndx >= 0); - if (msz * ndx >= id->d_size) { + if (msz * (size_t) ndx >= id->d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } @@ -123,9 +124,11 @@ gelf_update_symshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *gs, } msz = _libelf_msize(ELF_T_WORD, ec, e->e_version); + assert(msz > 0); + assert(ndx >= 0); - if (msz * ndx >= id->d_size) { + if (msz * (size_t) ndx >= id->d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } diff --git a/libelf/libelf.h b/libelf/libelf.h index d3219d7ce251..41e7224956fc 100644 --- a/libelf/libelf.h +++ b/libelf/libelf.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: libelf.h 2366 2011-12-29 06:12:14Z jkoshy $ + * $Id: libelf.h 2988 2014-03-17 08:51:49Z jkoshy $ */ #ifndef _LIBELF_H_ @@ -129,7 +129,7 @@ typedef struct { /* * Members that are not part of the public API. */ - int ar_flags; + unsigned int ar_flags; } Elf_Arhdr; /* diff --git a/libelf/libelf_align.c b/libelf/libelf_align.c index 9550c5bd49ea..817fd1588565 100644 --- a/libelf/libelf_align.c +++ b/libelf/libelf_align.c @@ -32,11 +32,11 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: libelf_align.c 2225 2011-11-26 18:55:54Z jkoshy $"); +ELFTC_VCSID("$Id: libelf_align.c 3006 2014-03-22 08:10:07Z jkoshy $"); struct align { - int a32; - int a64; + unsigned int a32; + unsigned int a64; }; #ifdef __GNUC__ @@ -87,7 +87,7 @@ static struct align malign[ELF_T_NUM] = { [ELF_T_GNUHASH] = MALIGN_WORD() }; -int +unsigned int _libelf_malign(Elf_Type t, int elfclass) { if (t >= ELF_T_NUM || (int) t < 0) @@ -126,7 +126,7 @@ static struct align falign[ELF_T_NUM] = { [ELF_T_GNUHASH] = FALIGN(4,8) }; -int +unsigned int _libelf_falign(Elf_Type t, int elfclass) { if (t >= ELF_T_NUM || (int) t < 0) diff --git a/libelf/libelf_ar.c b/libelf/libelf_ar.c index c990d6dc971a..0830dd6fc069 100644 --- a/libelf/libelf_ar.c +++ b/libelf/libelf_ar.c @@ -35,7 +35,7 @@ #include "_libelf.h" #include "_libelf_ar.h" -ELFTC_VCSID("$Id: libelf_ar.c 2225 2011-11-26 18:55:54Z jkoshy $"); +ELFTC_VCSID("$Id: libelf_ar.c 3013 2014-03-23 06:16:59Z jkoshy $"); #define LIBELF_NALLOC_SIZE 16 @@ -110,8 +110,8 @@ Elf_Arhdr * _libelf_ar_gethdr(Elf *e) { Elf *parent; - char *namelen; Elf_Arhdr *eh; + char *namelen; size_t n, nlen; struct ar_hdr *arh; @@ -192,7 +192,7 @@ _libelf_ar_gethdr(Elf *e) } e->e_flags &= ~LIBELF_F_AR_HEADER; - e->e_hdr.e_rawhdr = (char *) arh; + e->e_hdr.e_rawhdr = (unsigned char *) arh; return (NULL); } @@ -201,10 +201,10 @@ Elf * _libelf_ar_open_member(int fd, Elf_Cmd c, Elf *elf) { Elf *e; - char *member, *namelen; - size_t nsz, sz; off_t next; + size_t nsz, sz; struct ar_hdr *arh; + char *member, *namelen; assert(elf->e_kind == ELF_K_AR); @@ -249,12 +249,12 @@ _libelf_ar_open_member(int fd, Elf_Cmd c, Elf *elf) member = (char *) (arh + 1); - if ((e = elf_memory((char *) member, sz)) == NULL) + if ((e = elf_memory(member, sz)) == NULL) return (NULL); e->e_fd = fd; e->e_cmd = c; - e->e_hdr.e_rawhdr = (char *) arh; + e->e_hdr.e_rawhdr = (unsigned char *) arh; elf->e_u.e_ar.e_nchildren++; e->e_parent = elf; @@ -274,9 +274,10 @@ _libelf_ar_open_member(int fd, Elf_Cmd c, Elf *elf) */ /* - * A helper macro to read in a 'long' value from the archive. We use - * memcpy() since the source pointer may be misaligned with respect to - * the natural alignment for a C 'long'. + * A helper macro to read in a 'long' value from the archive. + * + * We use memcpy() since the source pointer may be misaligned with + * respect to the natural alignment for a C 'long'. */ #define GET_LONG(P, V)do { \ memcpy(&(V), (P), sizeof(long)); \ @@ -287,9 +288,10 @@ Elf_Arsym * _libelf_ar_process_bsd_symtab(Elf *e, size_t *count) { Elf_Arsym *symtab, *sym; + unsigned int n, nentries; unsigned char *end, *p, *p0, *s, *s0; - const unsigned int entrysize = 2 * sizeof(long); - long arraysize, fileoffset, n, nentries, stroffset, strtabsize; + const size_t entrysize = 2 * sizeof(long); + long arraysize, fileoffset, stroffset, strtabsize; assert(e != NULL); assert(count != NULL); @@ -313,7 +315,8 @@ _libelf_ar_process_bsd_symtab(Elf *e, size_t *count) */ GET_LONG(p, arraysize); - if (p0 + arraysize >= end || (arraysize % entrysize != 0)) + if (arraysize < 0 || p0 + arraysize >= end || + ((size_t) arraysize % entrysize != 0)) goto symtaberror; /* @@ -323,10 +326,10 @@ _libelf_ar_process_bsd_symtab(Elf *e, size_t *count) GET_LONG(s, strtabsize); s0 = s; /* Start of string table. */ - if (s0 + strtabsize > end) + if (strtabsize < 0 || s0 + strtabsize > end) goto symtaberror; - nentries = arraysize / entrysize; + nentries = (size_t) arraysize / entrysize; /* * Allocate space for the returned Elf_Arsym array. @@ -341,12 +344,16 @@ _libelf_ar_process_bsd_symtab(Elf *e, size_t *count) GET_LONG(p, stroffset); GET_LONG(p, fileoffset); + if (stroffset < 0 || fileoffset < 0 || + (size_t) fileoffset >= e->e_rawsize) + goto symtaberror; + s = s0 + stroffset; if (s >= end) goto symtaberror; - sym->as_off = fileoffset; + sym->as_off = (off_t) fileoffset; sym->as_hash = elf_hash((char *) s); sym->as_name = (char *) s; } @@ -393,7 +400,8 @@ symtaberror: Elf_Arsym * _libelf_ar_process_svr4_symtab(Elf *e, size_t *count) { - size_t n, nentries, off; + uint32_t off; + size_t n, nentries; Elf_Arsym *symtab, *sym; unsigned char *p, *s, *end; @@ -424,15 +432,14 @@ _libelf_ar_process_svr4_symtab(Elf *e, size_t *count) s = p + (nentries * INTSZ); /* start of the string table. */ for (n = nentries, sym = symtab; n > 0; n--) { - if (s >= end) goto symtaberror; - off = 0; - GET_WORD(p, off); + if (off >= e->e_rawsize) + goto symtaberror; - sym->as_off = off; + sym->as_off = (off_t) off; sym->as_hash = elf_hash((char *) s); sym->as_name = (char *) s; diff --git a/libelf/libelf_ar_util.c b/libelf/libelf_ar_util.c index 958fbbf49022..7e6ec4068f69 100644 --- a/libelf/libelf_ar_util.c +++ b/libelf/libelf_ar_util.c @@ -34,21 +34,23 @@ #include "_libelf.h" #include "_libelf_ar.h" -ELFTC_VCSID("$Id: libelf_ar_util.c 2365 2011-12-29 04:36:44Z jkoshy $"); +ELFTC_VCSID("$Id: libelf_ar_util.c 3013 2014-03-23 06:16:59Z jkoshy $"); /* * Convert a string bounded by `start' and `start+sz' (exclusive) to a * number in the specified base. */ int -_libelf_ar_get_number(const char *s, size_t sz, int base, size_t *ret) +_libelf_ar_get_number(const char *src, size_t sz, unsigned int base, + size_t *ret) { - int c, v; size_t r; - const char *e; + unsigned int c, v; + const unsigned char *e, *s; assert(base <= 10); + s = (const unsigned char *) src; e = s + sz; /* skip leading blanks */ @@ -79,17 +81,18 @@ _libelf_ar_get_number(const char *s, size_t sz, int base, size_t *ret) char * _libelf_ar_get_translated_name(const struct ar_hdr *arh, Elf *ar) { - char c, *s; + char *s; + unsigned char c; size_t len, offset; - const char *buf, *p, *q, *r; + const unsigned char *buf, *p, *q, *r; const size_t bufsize = sizeof(arh->ar_name); assert(arh != NULL); assert(ar->e_kind == ELF_K_AR); - assert((const char *) arh >= ar->e_rawfile && - (const char *) arh < ar->e_rawfile + ar->e_rawsize); + assert((const unsigned char *) arh >= ar->e_rawfile && + (const unsigned char *) arh < ar->e_rawfile + ar->e_rawsize); - buf = arh->ar_name; + buf = (const unsigned char *) arh->ar_name; /* * Check for extended naming. @@ -104,8 +107,8 @@ _libelf_ar_get_translated_name(const struct ar_hdr *arh, Elf *ar) * the archive string table where the actual name * resides. */ - if (_libelf_ar_get_number(buf + 1, bufsize - 1, 10, - &offset) == 0) { + if (_libelf_ar_get_number((const char *) (buf + 1), + bufsize - 1, 10, &offset) == 0) { LIBELF_SET_ERROR(ARCHIVE, 0); return (NULL); } @@ -120,21 +123,21 @@ _libelf_ar_get_translated_name(const struct ar_hdr *arh, Elf *ar) for (; p < r && *p != '/'; p++) ; - len = p - q + 1; /* space for the trailing NUL */ + len = (size_t) (p - q + 1); /* space for the trailing NUL */ if ((s = malloc(len)) == NULL) { LIBELF_SET_ERROR(RESOURCE, 0); return (NULL); } - (void) strncpy(s, q, len - 1); + (void) strncpy(s, (const char *) q, len - 1); s[len - 1] = '\0'; return (s); } else if (IS_EXTENDED_BSD_NAME(buf)) { r = buf + LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE; - if (_libelf_ar_get_number(r, bufsize - + if (_libelf_ar_get_number((const char *) r, bufsize - LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE, 10, &len) == 0) { LIBELF_SET_ERROR(ARCHIVE, 0); @@ -153,9 +156,9 @@ _libelf_ar_get_translated_name(const struct ar_hdr *arh, Elf *ar) /* * The file name follows the archive header. */ - q = (const char *) (arh + 1); + q = (const unsigned char *) (arh + 1); - (void) strncpy(s, q, len); + (void) strncpy(s, (const char *) q, len); s[len] = '\0'; return (s); @@ -183,10 +186,10 @@ _libelf_ar_get_translated_name(const struct ar_hdr *arh, Elf *ar) q--; } - len = q - buf + 2; /* Add space for a trailing NUL. */ + len = (size_t) (q - buf + 2); /* Space for a trailing NUL. */ } else { /* The buffer only had blanks. */ - buf = ""; + buf = (const unsigned char *) ""; len = 1; } @@ -195,7 +198,7 @@ _libelf_ar_get_translated_name(const struct ar_hdr *arh, Elf *ar) return (NULL); } - (void) strncpy(s, buf, len - 1); + (void) strncpy(s, (const char *) buf, len - 1); s[len - 1] = '\0'; return (s); @@ -229,8 +232,8 @@ _libelf_ar_open(Elf *e, int reporterror) { size_t sz; int scanahead; - char *s, *end; struct ar_hdr arh; + unsigned char *s, *end; _libelf_init_elf(e, ELF_K_AR); @@ -264,7 +267,7 @@ _libelf_ar_open(Elf *e, int reporterror) (void) memcpy(&(ARH), (S), sizeof((ARH))); \ if ((ARH).ar_fmag[0] != '`' || (ARH).ar_fmag[1] != '\n') \ goto error; \ - if (_libelf_ar_get_number((ARH).ar_size, \ + if (_libelf_ar_get_number((char *) (ARH).ar_size, \ sizeof((ARH).ar_size), 10, &(SZ)) == 0) \ goto error; \ } while (0) diff --git a/libelf/libelf_checksum.c b/libelf/libelf_checksum.c index 8f84aa4d0f05..f05f9a936404 100644 --- a/libelf/libelf_checksum.c +++ b/libelf/libelf_checksum.c @@ -30,7 +30,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: libelf_checksum.c 2225 2011-11-26 18:55:54Z jkoshy $"); +ELFTC_VCSID("$Id: libelf_checksum.c 3003 2014-03-22 07:43:10Z jkoshy $"); static unsigned long _libelf_sum(unsigned long c, const unsigned char *s, size_t size) @@ -44,7 +44,7 @@ _libelf_sum(unsigned long c, const unsigned char *s, size_t size) return (c); } -unsigned long +long _libelf_checksum(Elf *e, int elfclass) { size_t shn; @@ -90,11 +90,11 @@ _libelf_checksum(Elf *e, int elfclass) d = NULL; while ((d = elf_rawdata(scn, d)) != NULL) checksum = _libelf_sum(checksum, - (unsigned char *) d->d_buf, d->d_size); + (unsigned char *) d->d_buf, (size_t) d->d_size); } /* * Return a 16-bit checksum compatible with Solaris. */ - return (((checksum >> 16) & 0xFFFFUL) + (checksum & 0xFFFFUL)); + return (long) (((checksum >> 16) & 0xFFFFUL) + (checksum & 0xFFFFUL)); } diff --git a/libelf/libelf_convert.m4 b/libelf/libelf_convert.m4 index 0e0e4fd8ff35..fc9cf394a24d 100644 --- a/libelf/libelf_convert.m4 +++ b/libelf/libelf_convert.m4 @@ -32,7 +32,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: libelf_convert.m4 2361 2011-12-28 12:03:05Z jkoshy $"); +ELFTC_VCSID("$Id: libelf_convert.m4 3009 2014-03-23 01:49:59Z jkoshy $"); /* WARNING: GENERATED FROM __file__. */ @@ -143,8 +143,8 @@ define(`SIZEDEP_OFF', 1) # Generates a pair of conversion functions. define(`MAKEPRIMFUNCS',` static int -_libelf_cvt_$1$4_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) +_libelf_cvt_$1$4_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) { Elf$3_$2 t, *s = (Elf$3_$2 *) (uintptr_t) src; size_t c; @@ -166,8 +166,8 @@ _libelf_cvt_$1$4_tof(char *dst, size_t dsz, char *src, size_t count, } static int -_libelf_cvt_$1$4_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) +_libelf_cvt_$1$4_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) { Elf$3_$2 t, *d = (Elf$3_$2 *) (uintptr_t) dst; size_t c; @@ -267,8 +267,8 @@ define(`READ_STRUCT', # `$3': ELF class specifier, one of [`', `32', `64'] define(`MAKECOMPFUNCS', `ifdef(`NOFUNC_'$1$3,`',` static int -_libelf_cvt_$1$3_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) +_libelf_cvt_$1$3_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) { Elf$3_$2 t, *s; size_t c; @@ -288,16 +288,16 @@ _libelf_cvt_$1$3_tof(char *dst, size_t dsz, char *src, size_t count, } static int -_libelf_cvt_$1$3_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) +_libelf_cvt_$1$3_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) { - Elf$3_$2 t, *d; - char *s,*s0; + 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 = (char *) src + (count - 1) * fsz; + s0 = src + (count - 1) * fsz; if (dsz < count * sizeof(Elf$3_$2)) return (0); @@ -398,8 +398,8 @@ define(`MAKE_VERSION_CONVERTERS', # conversion function. define(`MAKE_VERSION_CONVERTER',` static int -_libelf_cvt_$1$5_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) +_libelf_cvt_$1$5_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) { Elf$5_$2 t; Elf$5_$3 a; @@ -407,12 +407,12 @@ _libelf_cvt_$1$5_tof(char *dst, size_t dsz, char *src, size_t count, const size_t auxfsz = FSZ(Elf$5_$3_DEF); const size_t vermsz = sizeof(Elf$5_$2); const size_t auxmsz = sizeof(Elf$5_$3); - char * const dstend = dst + dsz; - char * const srcend = src + count; - char *dtmp, *dstaux, *srcaux; + unsigned char * const dstend = dst + dsz; + unsigned char * const srcend = src + count; + unsigned char *dtmp, *dstaux, *srcaux; Elf$5_Word aux, anext, cnt, vnext; - for (dtmp = dst, vnext = ~0; + for (dtmp = dst, vnext = ~0U; vnext != 0 && dtmp + verfsz <= dstend && src + vermsz <= srcend; dtmp += vnext, src += vnext) { @@ -434,7 +434,7 @@ _libelf_cvt_$1$5_tof(char *dst, size_t dsz, char *src, size_t count, return (0); /* Process AUX entries. */ - for (anext = ~0, dstaux = dtmp + aux, srcaux = src + aux; + for (anext = ~0U, dstaux = dtmp + aux, srcaux = src + aux; cnt != 0 && anext != 0 && dstaux + auxfsz <= dstend && srcaux + auxmsz <= srcend; dstaux += anext, srcaux += anext, cnt--) { @@ -462,8 +462,8 @@ _libelf_cvt_$1$5_tof(char *dst, size_t dsz, char *src, size_t count, } static int -_libelf_cvt_$1$5_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) +_libelf_cvt_$1$5_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) { Elf$5_$2 t, *dp; Elf$5_$3 a, *ap; @@ -471,12 +471,12 @@ _libelf_cvt_$1$5_tom(char *dst, size_t dsz, char *src, size_t count, const size_t auxfsz = FSZ(Elf$5_$3_DEF); const size_t vermsz = sizeof(Elf$5_$2); const size_t auxmsz = sizeof(Elf$5_$3); - char * const dstend = dst + dsz; - char * const srcend = src + count; - char *dstaux, *s, *srcaux, *stmp; + unsigned char * const dstend = dst + dsz; + unsigned char * const srcend = src + count; + unsigned char *dstaux, *s, *srcaux, *stmp; Elf$5_Word aux, anext, cnt, vnext; - for (stmp = src, vnext = ~0; + for (stmp = src, vnext = ~0U; vnext != 0 && stmp + verfsz <= srcend && dst + vermsz <= dstend; stmp += vnext, dst += vnext) { @@ -498,7 +498,7 @@ _libelf_cvt_$1$5_tom(char *dst, size_t dsz, char *src, size_t count, return (0); /* Process AUX entries. */ - for (anext = ~0, dstaux = dst + aux, srcaux = stmp + aux; + for (anext = ~0U, dstaux = dst + aux, srcaux = stmp + aux; cnt != 0 && anext != 0 && dstaux + auxmsz <= dstend && srcaux + auxfsz <= srcend; dstaux += anext, srcaux += anext, cnt--) { @@ -536,22 +536,23 @@ divert(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; \ + uint32_t _t = _x & 0xFFU; \ + _t <<= 8U; _x >>= 8U; _t |= _x & 0xFFU; \ + (X) = (uint16_t) _t; \ } while (0) -#define SWAP_WORD(X) do { \ +#define _SWAP_WORD(X, T) 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; \ + (X) = (T) _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 { \ +#define SWAP_ADDR32(X) _SWAP_WORD(X, Elf32_Addr) +#define SWAP_OFF32(X) _SWAP_WORD(X, Elf32_Off) +#define SWAP_SWORD(X) _SWAP_WORD(X, Elf32_Sword) +#define SWAP_WORD(X) _SWAP_WORD(X, Elf32_Word) +#define _SWAP_WORD64(X, T) do { \ uint64_t _x = (uint64_t) (X); \ uint64_t _t = _x & 0xFF; \ _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ @@ -561,13 +562,13 @@ divert(0) _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - (X) = _t; \ + (X) = (T) _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) +#define SWAP_ADDR64(X) _SWAP_WORD64(X, Elf64_Addr) +#define SWAP_LWORD(X) _SWAP_WORD64(X, Elf64_Lword) +#define SWAP_OFF64(X) _SWAP_WORD64(X, Elf64_Off) +#define SWAP_SXWORD(X) _SWAP_WORD64(X, Elf64_Sxword) +#define SWAP_XWORD(X) _SWAP_WORD64(X, Elf64_Xword) /* * C macros to write out various integral values. @@ -578,22 +579,22 @@ divert(0) * - The destination pointer is incremented after the write. */ #define WRITE_BYTE(P,X) do { \ - char *const _p = (char *) (P); \ - _p[0] = (char) (X); \ + 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); \ - char *const _p = (char *) (P); \ - const char *const _q = (char *) &_t; \ + unsigned char *const _p = (unsigned char *) (P); \ + const unsigned 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); \ - char *const _p = (char *) (P); \ - const char *const _q = (char *) &_t; \ +#define WRITE_WORD(P,X) do { \ + uint32_t _t = (uint32_t) (X); \ + unsigned char *const _p = (unsigned char *) (P); \ + const unsigned char *const _q = (unsigned char *) &_t; \ _p[0] = _q[0]; \ _p[1] = _q[1]; \ _p[2] = _q[2]; \ @@ -604,9 +605,9 @@ divert(0) #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; \ + uint64_t _t = (uint64_t) (X); \ + unsigned char *const _p = (unsigned char *) (P); \ + const unsigned char *const _q = (unsigned char *) &_t; \ _p[0] = _q[0]; \ _p[1] = _q[1]; \ _p[2] = _q[2]; \ @@ -637,41 +638,42 @@ divert(0) */ #define READ_BYTE(P,X) do { \ - const char *const _p = \ - (const char *) (P); \ + 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; \ - char *const _q = (char *) &_t; \ - const char *const _p = \ - (const char *) (P); \ + 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 { \ +#define _READ_WORD(P,X,T) do { \ uint32_t _t; \ - char *const _q = (char *) &_t; \ - const char *const _p = \ - (const char *) (P); \ + 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; \ + (X) = (T) _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 { \ +#define READ_ADDR32(P,X) _READ_WORD(P, X, Elf32_Addr) +#define READ_OFF32(P,X) _READ_WORD(P, X, Elf32_Off) +#define READ_SWORD(P,X) _READ_WORD(P, X, Elf32_Sword) +#define READ_WORD(P,X) _READ_WORD(P, X, Elf32_Word) +#define _READ_WORD64(P,X,T) do { \ uint64_t _t; \ - char *const _q = (char *) &_t; \ - const char *const _p = \ - (const char *) (P); \ + 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]; \ @@ -681,13 +683,13 @@ divert(0) _q[6] = _p[6]; \ _q[7] = _p[7]; \ (P) = (P) + 8; \ - (X) = _t; \ + (X) = (T) _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_ADDR64(P,X) _READ_WORD64(P, X, Elf64_Addr) +#define READ_LWORD(P,X) _READ_WORD64(P, X, Elf64_Lword) +#define READ_OFF64(P,X) _READ_WORD64(P, X, Elf64_Off) +#define READ_SXWORD(P,X) _READ_WORD64(P, X, Elf64_Sxword) +#define READ_XWORD(P,X) _READ_WORD64(P, X, Elf64_Xword) #define READ_IDENT(P,X) do { \ (void) memcpy((X), (P), sizeof((X))); \ (P) = (P) + EI_NIDENT; \ @@ -707,8 +709,8 @@ MAKE_VERSION_CONVERTERS(VNEED,Verneed,Vernaux,vn) */ static int -_libelf_cvt_BYTE_tox(char *dst, size_t dsz, char *src, size_t count, - int byteswap) +_libelf_cvt_BYTE_tox(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) { (void) byteswap; if (dsz < count) @@ -732,24 +734,24 @@ _libelf_cvt_BYTE_tox(char *dst, size_t dsz, char *src, size_t count, */ static int -_libelf_cvt_GNUHASH32_tom(char *dst, size_t dsz, char *src, size_t srcsz, - int byteswap) +_libelf_cvt_GNUHASH32_tom(unsigned char *dst, size_t dsz, unsigned 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) +_libelf_cvt_GNUHASH32_tof(unsigned char *dst, size_t dsz, unsigned 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) +_libelf_cvt_GNUHASH64_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t srcsz, int byteswap) { size_t sz; uint64_t t64, *bloom64; @@ -834,8 +836,8 @@ _libelf_cvt_GNUHASH64_tom(char *dst, size_t dsz, char *src, size_t srcsz, } static int -_libelf_cvt_GNUHASH64_tof(char *dst, size_t dsz, char *src, size_t srcsz, - int byteswap) +_libelf_cvt_GNUHASH64_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t srcsz, int byteswap) { uint32_t *s32; size_t sz, hdrsz; @@ -921,8 +923,8 @@ _libelf_cvt_GNUHASH64_tof(char *dst, size_t dsz, char *src, size_t srcsz, * 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) +_libelf_cvt_NOTE_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) { uint32_t namesz, descsz, type; Elf_Note *en; @@ -962,8 +964,8 @@ _libelf_cvt_NOTE_tom(char *dst, size_t dsz, char *src, size_t count, dst += sizeof(Elf_Note); count -= hdrsz; - ROUNDUP2(namesz, 4); - ROUNDUP2(descsz, 4); + ROUNDUP2(namesz, 4U); + ROUNDUP2(descsz, 4U); sz = namesz + descsz; @@ -983,8 +985,8 @@ _libelf_cvt_NOTE_tom(char *dst, size_t dsz, char *src, size_t count, } static int -_libelf_cvt_NOTE_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) +_libelf_cvt_NOTE_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) { uint32_t namesz, descsz, type; Elf_Note *en; @@ -1015,8 +1017,8 @@ _libelf_cvt_NOTE_tof(char *dst, size_t dsz, char *src, size_t count, src += sizeof(Elf_Note); - ROUNDUP2(namesz, 4); - ROUNDUP2(descsz, 4); + ROUNDUP2(namesz, 4U); + ROUNDUP2(descsz, 4U); sz = namesz + descsz; @@ -1034,14 +1036,14 @@ _libelf_cvt_NOTE_tof(char *dst, size_t dsz, char *src, size_t count, } 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); + int (*tof32)(unsigned char *dst, size_t dsz, unsigned char *src, + size_t cnt, int byteswap); + int (*tom32)(unsigned char *dst, size_t dsz, unsigned char *src, + size_t cnt, int byteswap); + int (*tof64)(unsigned char *dst, size_t dsz, unsigned char *src, + size_t cnt, int byteswap); + int (*tom64)(unsigned char *dst, size_t dsz, unsigned char *src, + size_t cnt, int byteswap); }; @@ -1070,7 +1072,8 @@ CONVERTER_NAMES(ELF_TYPE_LIST) }; int (*_libelf_get_translator(Elf_Type t, int direction, int elfclass)) - (char *_dst, size_t dsz, char *_src, size_t _cnt, int _byteswap) + (unsigned char *_dst, size_t dsz, unsigned char *_src, size_t _cnt, + int _byteswap) { assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); assert(direction == ELF_TOFILE || direction == ELF_TOMEMORY); diff --git a/libelf/libelf_data.c b/libelf/libelf_data.c index 809002f71e78..f078c36ab755 100644 --- a/libelf/libelf_data.c +++ b/libelf/libelf_data.c @@ -30,11 +30,14 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: libelf_data.c 2225 2011-11-26 18:55:54Z jkoshy $"); +ELFTC_VCSID("$Id: libelf_data.c 3080 2014-07-28 08:46:17Z jkoshy $"); int _libelf_xlate_shtype(uint32_t sht) { + /* + * Look for known section types. + */ switch (sht) { case SHT_DYNAMIC: return (ELF_T_DYN); @@ -83,6 +86,18 @@ _libelf_xlate_shtype(uint32_t sht) case SHT_SUNW_versym: /* == SHT_GNU_versym */ return (ELF_T_HALF); default: + /* + * Values in the range [SHT_LOOS..SHT_HIUSER] (i.e., + * OS, processor and user-defined section types) are + * legal, but since we do not know anything more about + * their semantics, we return a type of ELF_T_BYTE. + */ + if (sht >= SHT_LOOS && sht <= SHT_HIUSER) + return (ELF_T_BYTE); + + /* + * Other values are unsupported. + */ return (-1); } } diff --git a/libelf/libelf_ehdr.c b/libelf/libelf_ehdr.c index 363a0a834b9f..d59f61f2ba1e 100644 --- a/libelf/libelf_ehdr.c +++ b/libelf/libelf_ehdr.c @@ -33,7 +33,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: libelf_ehdr.c 2225 2011-11-26 18:55:54Z jkoshy $"); +ELFTC_VCSID("$Id: libelf_ehdr.c 3009 2014-03-23 01:49:59Z jkoshy $"); /* * Retrieve counts for sections, phdrs and the section string table index @@ -45,7 +45,8 @@ _libelf_load_extended(Elf *e, int ec, uint64_t shoff, uint16_t phnum, { Elf_Scn *scn; size_t fsz; - int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); + int (*xlator)(unsigned char *_d, size_t _dsz, unsigned char *_s, + size_t _c, int _swap); uint32_t shtype; assert(STAILQ_EMPTY(&e->e_u.e_elf.e_scn)); @@ -62,8 +63,8 @@ _libelf_load_extended(Elf *e, int ec, uint64_t shoff, uint16_t phnum, return (0); xlator = _libelf_get_translator(ELF_T_SHDR, ELF_TOMEMORY, ec); - (*xlator)((char *) &scn->s_shdr, sizeof(scn->s_shdr), - e->e_rawfile + shoff, (size_t) 1, + (*xlator)((unsigned char *) &scn->s_shdr, sizeof(scn->s_shdr), + (unsigned char *) e->e_rawfile + shoff, (size_t) 1, e->e_byteorder != LIBELF_PRIVATE(byteorder)); #define GET_SHDR_MEMBER(M) ((ec == ELFCLASS32) ? scn->s_shdr.s_shdr32.M : \ @@ -74,7 +75,7 @@ _libelf_load_extended(Elf *e, int ec, uint64_t shoff, uint16_t phnum, return (0); } - e->e_u.e_elf.e_nscn = GET_SHDR_MEMBER(sh_size); + e->e_u.e_elf.e_nscn = (size_t) GET_SHDR_MEMBER(sh_size); e->e_u.e_elf.e_nphdr = (phnum != PN_XNUM) ? phnum : GET_SHDR_MEMBER(sh_info); e->e_u.e_elf.e_strndx = (strndx != SHN_XINDEX) ? strndx : @@ -92,7 +93,7 @@ _libelf_load_extended(Elf *e, int ec, uint64_t shoff, uint16_t phnum, eh->e_ident[EI_MAG3] = ELFMAG3; \ eh->e_ident[EI_CLASS] = ELFCLASS##SZ; \ eh->e_ident[EI_DATA] = ELFDATANONE; \ - eh->e_ident[EI_VERSION] = LIBELF_PRIVATE(version); \ + eh->e_ident[EI_VERSION] = LIBELF_PRIVATE(version) & 0xFFU; \ eh->e_machine = EM_NONE; \ eh->e_type = ELF_K_NONE; \ eh->e_version = LIBELF_PRIVATE(version); \ @@ -105,7 +106,8 @@ _libelf_ehdr(Elf *e, int ec, int allocate) size_t fsz, msz; uint16_t phnum, shnum, strndx; uint64_t shoff; - int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); + int (*xlator)(unsigned char *_d, size_t _dsz, unsigned char *_s, + size_t _c, int _swap); assert(ec == ELFCLASS32 || ec == ELFCLASS64); @@ -167,7 +169,7 @@ _libelf_ehdr(Elf *e, int ec, int allocate) return (ehdr); xlator = _libelf_get_translator(ELF_T_EHDR, ELF_TOMEMORY, ec); - (*xlator)(ehdr, msz, e->e_rawfile, (size_t) 1, + (*xlator)((unsigned char*) ehdr, msz, e->e_rawfile, (size_t) 1, e->e_byteorder != LIBELF_PRIVATE(byteorder)); /* diff --git a/libelf/libelf_extended.c b/libelf/libelf_extended.c index 5343696548d4..f1a77d17efba 100644 --- a/libelf/libelf_extended.c +++ b/libelf/libelf_extended.c @@ -31,7 +31,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: libelf_extended.c 2225 2011-11-26 18:55:54Z jkoshy $"); +ELFTC_VCSID("$Id: libelf_extended.c 3005 2014-03-22 07:43:25Z jkoshy $"); /* * Retrieve section #0, allocating a new section if needed. @@ -69,9 +69,9 @@ _libelf_setshnum(Elf *e, void *eh, int ec, size_t shnum) } if (ec == ELFCLASS32) - ((Elf32_Ehdr *) eh)->e_shnum = shnum; + ((Elf32_Ehdr *) eh)->e_shnum = shnum & 0xFFFFU; else - ((Elf64_Ehdr *) eh)->e_shnum = shnum; + ((Elf64_Ehdr *) eh)->e_shnum = shnum & 0xFFFFU; return (1); @@ -99,9 +99,9 @@ _libelf_setshstrndx(Elf *e, void *eh, int ec, size_t shstrndx) } if (ec == ELFCLASS32) - ((Elf32_Ehdr *) eh)->e_shstrndx = shstrndx; + ((Elf32_Ehdr *) eh)->e_shstrndx = shstrndx & 0xFFFFU; else - ((Elf64_Ehdr *) eh)->e_shstrndx = shstrndx; + ((Elf64_Ehdr *) eh)->e_shstrndx = shstrndx & 0xFFFFU; return (1); } @@ -128,9 +128,9 @@ _libelf_setphnum(Elf *e, void *eh, int ec, size_t phnum) } if (ec == ELFCLASS32) - ((Elf32_Ehdr *) eh)->e_phnum = phnum; + ((Elf32_Ehdr *) eh)->e_phnum = phnum & 0xFFFFU; else - ((Elf64_Ehdr *) eh)->e_phnum = phnum; + ((Elf64_Ehdr *) eh)->e_phnum = phnum & 0xFFFFU; return (1); } diff --git a/libelf/libelf_memory.c b/libelf/libelf_memory.c index 892e909b079c..cb8e8f20438a 100644 --- a/libelf/libelf_memory.c +++ b/libelf/libelf_memory.c @@ -31,7 +31,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: libelf_memory.c 2368 2011-12-29 06:34:28Z jkoshy $"); +ELFTC_VCSID("$Id: libelf_memory.c 3013 2014-03-23 06:16:59Z jkoshy $"); /* * Create an ELF descriptor for a memory image, optionally reporting @@ -39,7 +39,7 @@ ELFTC_VCSID("$Id: libelf_memory.c 2368 2011-12-29 06:34:28Z jkoshy $"); */ Elf * -_libelf_memory(char *image, size_t sz, int reporterror) +_libelf_memory(unsigned char *image, size_t sz, int reporterror) { Elf *e; int e_class; @@ -89,7 +89,7 @@ _libelf_memory(char *image, size_t sz, int reporterror) e->e_version = e_version; } } else if (sz >= SARMAG && - strncmp(image, ARMAG, (size_t) SARMAG) == 0) + strncmp((const char *) image, ARMAG, (size_t) SARMAG) == 0) return (_libelf_ar_open(e, reporterror)); return (e); diff --git a/libelf/libelf_open.c b/libelf/libelf_open.c index 6d93c73a0312..7ec33952dfe1 100644 --- a/libelf/libelf_open.c +++ b/libelf/libelf_open.c @@ -39,7 +39,7 @@ #include <sys/mman.h> #endif -ELFTC_VCSID("$Id: libelf_open.c 2932 2013-03-30 01:26:04Z jkoshy $"); +ELFTC_VCSID("$Id: libelf_open.c 3007 2014-03-22 08:10:14Z jkoshy $"); #define _LIBELF_INITSIZE (64*1024) @@ -73,11 +73,11 @@ _libelf_read_special_file(int fd, size_t *fsz) } do { - readsz = bufsz - datasz; + assert(bufsz - datasz > 0); t = buf + datasz; - if ((readsz = read(fd, t, readsz)) <= 0) + if ((readsz = read(fd, t, bufsz - datasz)) <= 0) break; - datasz += readsz; + datasz += (size_t) readsz; } while (datasz < bufsz); } while (readsz > 0); diff --git a/libelf/libelf_phdr.c b/libelf/libelf_phdr.c index f2eb697fbc04..f44c3cd7e44e 100644 --- a/libelf/libelf_phdr.c +++ b/libelf/libelf_phdr.c @@ -33,7 +33,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: libelf_phdr.c 2931 2013-03-23 11:41:07Z jkoshy $"); +ELFTC_VCSID("$Id: libelf_phdr.c 3009 2014-03-23 01:49:59Z jkoshy $"); void * _libelf_getphdr(Elf *e, int ec) @@ -44,7 +44,8 @@ _libelf_getphdr(Elf *e, int ec) Elf32_Ehdr *eh32; Elf64_Ehdr *eh64; void *ehdr, *phdr; - int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); + int (*xlator)(unsigned char *_d, size_t _dsz, unsigned char *_s, + size_t _c, int _swap); assert(ec == ELFCLASS32 || ec == ELFCLASS64); diff --git a/libelf/libelf_xlate.c b/libelf/libelf_xlate.c index eda6df8c2260..4cc6a452e4dd 100644 --- a/libelf/libelf_xlate.c +++ b/libelf/libelf_xlate.c @@ -31,7 +31,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: libelf_xlate.c 2225 2011-11-26 18:55:54Z jkoshy $"); +ELFTC_VCSID("$Id: libelf_xlate.c 3007 2014-03-22 08:10:14Z jkoshy $"); /* * Translate to/from the file representation of ELF objects. @@ -99,10 +99,10 @@ _libelf_xlate(Elf_Data *dst, const Elf_Data *src, unsigned int encoding, * buffer. */ if (direction == ELF_TOMEMORY) { - cnt = src->d_size / fsz; + cnt = (size_t) src->d_size / fsz; dsz = cnt * msz; } else { - cnt = src->d_size / msz; + cnt = (size_t) src->d_size / msz; dsz = cnt * fsz; } @@ -112,9 +112,9 @@ _libelf_xlate(Elf_Data *dst, const Elf_Data *src, unsigned int encoding, } sb = (uintptr_t) src->d_buf; - se = sb + src->d_size; + se = sb + (size_t) src->d_size; db = (uintptr_t) dst->d_buf; - de = db + dst->d_size; + de = db + (size_t) dst->d_size; /* * Check for overlapping buffers. Note that db == sb is |
