Hi,
Posix says that mmap(2)ing 0 bytes is bad and furthermore, our subsystem
is not written to support this (because there is no difference between
no allocation and a 0-byte allocation).
Strictly speaking, mmap(2) is to return EINVAL for 0 byte allocations
and I intend to get that into the kernel. But before that can happen,
ld.so must cease performing 0-byte mmaps. Hence the diff below.
This diff is called mmap0_ld.so.diff.0, has no api/abi change and treats
a 0-byte area mmap as a noop (i.e. skips the corresponding mmap call).
ok?
--
Ariane
Index: libexec/ld.so/library.c
===================================================================
RCS file: /cvs/src/libexec/ld.so/library.c,v
retrieving revision 1.63
diff -u -d -p -r1.63 library.c
--- libexec/ld.so/library.c 28 Nov 2011 20:59:03 -0000 1.63
+++ libexec/ld.so/library.c 8 Jan 2012 05:36:13 -0000
@@ -181,17 +181,20 @@ _dl_tryload_shlib(const char *libname, i
Elf_Addr size = off + phdp->p_filesz;
void *res;
- res = _dl_mmap(start, ROUND_PG(size),
- PFLAGS(phdp->p_flags),
- MAP_FIXED|MAP_PRIVATE, libfile,
- TRUNC_PG(phdp->p_offset));
+ if (size != 0) {
+ res = _dl_mmap(start, ROUND_PG(size),
+ PFLAGS(phdp->p_flags),
+ MAP_FIXED|MAP_PRIVATE, libfile,
+ TRUNC_PG(phdp->p_offset));
+ } else
+ res = NULL; /* silence gcc */
next_load = _dl_malloc(sizeof(struct load_list));
next_load->next = load_list;
load_list = next_load;
next_load->start = start;
next_load->size = size;
next_load->prot = PFLAGS(phdp->p_flags);
- if (_dl_mmap_error(res)) {
+ if (size != 0 && _dl_mmap_error(res)) {
_dl_printf("%s: rtld mmap failed mapping %s.\n",
_dl_progname, libname);
_dl_close(libfile);
Index: libexec/ld.so/library_mquery.c
===================================================================
RCS file: /cvs/src/libexec/ld.so/library_mquery.c,v
retrieving revision 1.39
diff -u -d -p -r1.39 library_mquery.c
--- libexec/ld.so/library_mquery.c 28 Nov 2011 20:59:03 -0000 1.39
+++ libexec/ld.so/library_mquery.c 8 Jan 2012 05:30:25 -0000
@@ -245,6 +245,9 @@ retry:
off_t foff;
void *res;
+ if (ld->size == 0)
+ continue;
+
if (ld->foff < 0) {
fd = -1;
foff = 0;