Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/external/bsd/libelf/dist fall back to malloc+pread when stat...
details: https://anonhg.NetBSD.org/src/rev/0b8fff7d1d44
branches: trunk
changeset: 758281:0b8fff7d1d44
user: yamt <yamt%NetBSD.org@localhost>
date: Sun Oct 31 05:03:12 2010 +0000
description:
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.
diffstat:
external/bsd/libelf/dist/_libelf.h | 3 +-
external/bsd/libelf/dist/elf_begin.c | 79 ++++++++++++++++++++++++++++++++---
external/bsd/libelf/dist/elf_end.c | 4 +-
3 files changed, 76 insertions(+), 10 deletions(-)
diffs (148 lines):
diff -r 7c9df2c27b60 -r 0b8fff7d1d44 external/bsd/libelf/dist/_libelf.h
--- a/external/bsd/libelf/dist/_libelf.h Sun Oct 31 04:51:19 2010 +0000
+++ b/external/bsd/libelf/dist/_libelf.h Sun Oct 31 05:03:12 2010 +0000
@@ -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 */
diff -r 7c9df2c27b60 -r 0b8fff7d1d44 external/bsd/libelf/dist/elf_begin.c
--- a/external/bsd/libelf/dist/elf_begin.c Sun Oct 31 04:51:19 2010 +0000
+++ b/external/bsd/libelf/dist/elf_begin.c Sun Oct 31 05:03:12 2010 +0000
@@ -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);
+ 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, objsize)) == NULL) {
+ if (p != NULL) {
+ free(p);
+ } else {
+ (void) munmap(m, objsize);
+ }
return (NULL);
}
- if ((e = elf_memory(m, (size_t) sb.st_size)) == NULL) {
- (void) munmap(m, (size_t) sb.st_size);
- return (NULL);
+ if (p != NULL) {
+ e->e_flags |= LIBELF_F_MALLOC;
+ } else {
+ e->e_flags |= LIBELF_F_MMAP;
}
-
- e->e_flags |= LIBELF_F_MMAP;
e->e_fd = fd;
e->e_cmd = c;
diff -r 7c9df2c27b60 -r 0b8fff7d1d44 external/bsd/libelf/dist/elf_end.c
--- a/external/bsd/libelf/dist/elf_end.c Sun Oct 31 04:51:19 2010 +0000
+++ b/external/bsd/libelf/dist/elf_end.c Sun Oct 31 05:03:12 2010 +0000
@@ -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)
Home |
Main Index |
Thread Index |
Old Index