about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRoland McGrath <roland@hack.frob.com>2015-11-20 16:16:35 -0800
committerRoland McGrath <roland@hack.frob.com>2015-11-20 16:17:34 -0800
commitaf822b45a62940efbf5f691777fd2862c825e6d4 (patch)
tree14853d5ec4b5ed5eea7a5be401e3d6ee1ebfdd86
parenta7e6fd7d41c895940d059468984c61b172acf2b2 (diff)
downloadglibc-af822b45a62940efbf5f691777fd2862c825e6d4.tar.gz
glibc-af822b45a62940efbf5f691777fd2862c825e6d4.tar.xz
glibc-af822b45a62940efbf5f691777fd2862c825e6d4.zip
NaCl: Use allocate_code_data after dyncode_create
(cherry picked from commit f549f0bcba7196a2afc51657c536bbc131a7c544)
-rw-r--r--ChangeLog7
-rw-r--r--sysdeps/nacl/dl-map-segments.h28
2 files changed, 34 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index e24c08ec42..b1816c2257 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2015-11-20  Roland McGrath  <roland@hack.frob.com>
+
+	* sysdeps/nacl/dl-map-segments.h (_dl_map_segments): Use
+	__glibc_likely instead of __builtin_expect.  After falling back to
+	dyncode_create in a non-ET_DYN case, use the allocate_code_data
+	system interface to register the code pages as occupied.
+
 2015-11-14  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* config.make.in (have-glob-dat-reloc): New.
diff --git a/sysdeps/nacl/dl-map-segments.h b/sysdeps/nacl/dl-map-segments.h
index f305da304a..f2d5d84dcd 100644
--- a/sysdeps/nacl/dl-map-segments.h
+++ b/sysdeps/nacl/dl-map-segments.h
@@ -53,7 +53,7 @@ _dl_map_segments (struct link_map *l, int fd,
 		  const size_t maplength, bool has_holes,
 		  struct link_map *loader)
 {
-  if (__builtin_expect (type, ET_DYN) == ET_DYN)
+  if (__glibc_likely (type == ET_DYN))
     {
       /* This is a position-independent shared object.  Let the system
 	 choose where to place it.
@@ -165,6 +165,32 @@ _dl_map_segments (struct link_map *l, int fd,
 		    errno = error;
 		    return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT;
 		  }
+                if (__glibc_unlikely (type != ET_DYN))
+                  {
+                    /* A successful PROT_EXEC mmap would have implicitly
+                       updated the bookkeeping so that a future
+                       allocate_code_data call would know that this range
+                       of the address space is already occupied.  That
+                       doesn't happen implicitly with dyncode_create, so
+                       it's necessary to do an explicit call to update the
+                       bookkeeping.  */
+                    uintptr_t allocated_address;
+                    error = __nacl_irt_code_data_alloc.allocate_code_data
+                      (l->l_addr + c->mapstart, len, 0, 0, &allocated_address);
+                    if (__glibc_unlikely (error))
+                      {
+                        errno = error;
+                        return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT;
+                      }
+                    if (__glibc_unlikely
+                        (allocated_address != l->l_addr + c->mapstart))
+                      {
+                        /* This is not a very helpful error for this case,
+                           but there isn't really anything better to use.  */
+                        errno = ENOMEM;
+                        return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT;
+                      }
+                  }
 	      }
 	    else
 	      {