Module Name: src Committed By: yamt Date: Sun Oct 31 05:03:12 UTC 2010
Modified Files: src/external/bsd/libelf/dist: _libelf.h elf_begin.c elf_end.c Log Message: fall back to malloc+pread when stat+malloc doesn't seem to work. it allows libelf work on /dev/ksyms. XXX the name of the flag is a bit confusing and i think it's better to rename MALLOCED to DATA_MALLOCED or such. but i don't think it's worth increasing the diff against the upstream for it. To generate a diff of this commit: cvs rdiff -u -r1.5 -r1.6 src/external/bsd/libelf/dist/_libelf.h cvs rdiff -u -r1.6 -r1.7 src/external/bsd/libelf/dist/elf_begin.c cvs rdiff -u -r1.2 -r1.3 src/external/bsd/libelf/dist/elf_end.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/external/bsd/libelf/dist/_libelf.h diff -u src/external/bsd/libelf/dist/_libelf.h:1.5 src/external/bsd/libelf/dist/_libelf.h:1.6 --- src/external/bsd/libelf/dist/_libelf.h:1.5 Tue Mar 2 21:08:36 2010 +++ src/external/bsd/libelf/dist/_libelf.h Sun Oct 31 05:03:12 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: _libelf.h,v 1.5 2010/03/02 21:08:36 darran Exp $ */ +/* $NetBSD: _libelf.h,v 1.6 2010/10/31 05:03:12 yamt Exp $ */ /*- * Copyright (c) 2006 Joseph Koshy @@ -75,6 +75,7 @@ #define LIBELF_F_MALLOCED 0x010000 /* whether data was malloc'ed */ #define LIBELF_F_MMAP 0x020000 /* whether e_rawfile was mmap'ed */ #define LIBELF_F_SHDRS_LOADED 0x040000 /* whether all shdrs were read in */ +#define LIBELF_F_MALLOC 0x080000 /* whether e_rawfile was mmap'ed */ struct _Elf { int e_activations; /* activation count */ Index: src/external/bsd/libelf/dist/elf_begin.c diff -u src/external/bsd/libelf/dist/elf_begin.c:1.6 src/external/bsd/libelf/dist/elf_begin.c:1.7 --- src/external/bsd/libelf/dist/elf_begin.c:1.6 Mon Feb 22 10:59:08 2010 +++ src/external/bsd/libelf/dist/elf_begin.c Sun Oct 31 05:03:12 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: elf_begin.c,v 1.6 2010/02/22 10:59:08 darran Exp $ */ +/* $NetBSD: elf_begin.c,v 1.7 2010/10/31 05:03:12 yamt Exp $ */ /*- * Copyright (c) 2006 Joseph Koshy @@ -41,6 +41,9 @@ #include <err.h> #include <errno.h> #include <libelf.h> +#include <stdbool.h> +#include <stdlib.h> +#include <unistd.h> #include "_libelf.h" @@ -49,7 +52,9 @@ { Elf *e; void *m; + void *p; /* malloc'ed pointer */ struct stat sb; + size_t objsize; /* * 'Raw' files are always mapped with 'PROT_READ'. At @@ -63,18 +68,76 @@ } m = NULL; - if ((m = mmap(NULL, (size_t) sb.st_size, PROT_READ, MAP_PRIVATE, fd, + p = NULL; + if (sb.st_size == 0) { + /* + * Might be a special device like /dev/ksyms. Try read(2)ing. + */ + goto doread; + } + objsize = (size_t) sb.st_size; + if ((m = mmap(NULL, objsize, PROT_READ, MAP_PRIVATE, fd, (off_t) 0)) == MAP_FAILED) { - LIBELF_SET_ERROR(IO, errno); - return (NULL); + size_t bufsize; + + if (errno != EINVAL) { + LIBELF_SET_ERROR(IO, errno); + return (NULL); + } +doread: + /* + * Fall back to malloc+read. + */ + bufsize = 1024 * 1024; + while (/*CONSTCOND*/true) { + void *newp = realloc(p, bufsize); + ssize_t rsz; + + if (newp == NULL) { + free(p); + LIBELF_SET_ERROR(RESOURCE, 0); + return (NULL); + } + p = newp; + rsz = pread(fd, p, bufsize, 0); + if (rsz == -1) { + free(p); + LIBELF_SET_ERROR(IO, errno); + return (NULL); + } else if ((size_t) rsz > bufsize) { + free(p); + LIBELF_SET_ERROR(IO, EIO); /* XXX */ + return (NULL); + } else if ((size_t) rsz < bufsize) { + /* + * try to shrink the buffer. + */ + newp = realloc(p, (size_t) rsz); + if (newp != NULL) { + p = newp; + } + break; + } + bufsize *= 2; + } + m = p; + objsize = bufsize; } - if ((e = elf_memory(m, (size_t) sb.st_size)) == NULL) { - (void) munmap(m, (size_t) sb.st_size); + if ((e = elf_memory(m, objsize)) == NULL) { + if (p != NULL) { + free(p); + } else { + (void) munmap(m, objsize); + } return (NULL); } - e->e_flags |= LIBELF_F_MMAP; + if (p != NULL) { + e->e_flags |= LIBELF_F_MALLOC; + } else { + e->e_flags |= LIBELF_F_MMAP; + } e->e_fd = fd; e->e_cmd = c; Index: src/external/bsd/libelf/dist/elf_end.c diff -u src/external/bsd/libelf/dist/elf_end.c:1.2 src/external/bsd/libelf/dist/elf_end.c:1.3 --- src/external/bsd/libelf/dist/elf_end.c:1.2 Mon Feb 22 10:48:32 2010 +++ src/external/bsd/libelf/dist/elf_end.c Sun Oct 31 05:03:12 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: elf_end.c,v 1.2 2010/02/22 10:48:32 darran Exp $ */ +/* $NetBSD: elf_end.c,v 1.3 2010/10/31 05:03:12 yamt Exp $ */ /*- * Copyright (c) 2006 Joseph Koshy @@ -82,6 +82,8 @@ if (e->e_flags & LIBELF_F_MMAP) (void) munmap(e->e_rawfile, e->e_rawsize); + if (e->e_flags & LIBELF_F_MALLOC) + (void) free(e->e_rawfile); sv = e; if ((e = e->e_parent) != NULL)