On Sun, Jan 08, 2012 at 01:05:27PM +0000, Miod Vallat wrote:
> > 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?
> 
> Wouldn't it be simpler, in library_mquery.c, to skip LDLIST_INSERT() for
> size == 0 elements?

You're absolutely right. Updated diff (mmap0_ld.so.diff.1) below.

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 16:49:52 -0000
@@ -157,15 +157,17 @@ _dl_tryload_shlib(const char *libname, i
                        off = (phdp->p_vaddr & align);
                        size = off + phdp->p_filesz;
 
-                       ld = _dl_malloc(sizeof(struct load_list));
-                       ld->start = NULL;
-                       ld->size = size;
-                       ld->moff = TRUNC_PG(phdp->p_vaddr);
-                       ld->foff = TRUNC_PG(phdp->p_offset);
-                       ld->prot = PFLAGS(phdp->p_flags);
-                       LDLIST_INSERT(ld);
+                       if (size != 0) {
+                               ld = _dl_malloc(sizeof(struct load_list));
+                               ld->start = NULL;
+                               ld->size = size;
+                               ld->moff = TRUNC_PG(phdp->p_vaddr);
+                               ld->foff = TRUNC_PG(phdp->p_offset);
+                               ld->prot = PFLAGS(phdp->p_flags);
+                               LDLIST_INSERT(ld);
+                       }
 
-                       if ((ld->prot & PROT_WRITE) == 0 ||
+                       if ((PFLAGS(phdp->p_flags) & PROT_WRITE) == 0 ||
                            ROUND_PG(size) == ROUND_PG(off + phdp->p_memsz))
                                break;
                        /* This phdr has a zfod section */

Reply via email to