summary refs log tree commit diff
diff options
context:
space:
mode:
authorRoland McGrath <roland@hack.frob.com>2015-02-25 16:05:33 -0800
committerRoland McGrath <roland@hack.frob.com>2015-02-25 16:05:33 -0800
commitbce6c2d3aabbe0c913453781dccf845f94b6c1ea (patch)
tree768a3182ef8369ae84ca070a059f456b0000ad03
parent102df60df81ffe7f4d017a70ba2778b1d5e3109a (diff)
downloadglibc-bce6c2d3aabbe0c913453781dccf845f94b6c1ea.tar.gz
glibc-bce6c2d3aabbe0c913453781dccf845f94b6c1ea.tar.xz
glibc-bce6c2d3aabbe0c913453781dccf845f94b6c1ea.zip
Use code_data_alloc and dyncode_create IRT interfaces in _dl_map_segments.
-rw-r--r--sysdeps/nacl/dl-map-segments.h69
-rw-r--r--sysdeps/nacl/nacl-interface-list.h5
2 files changed, 43 insertions, 31 deletions
diff --git a/sysdeps/nacl/dl-map-segments.h b/sysdeps/nacl/dl-map-segments.h
index 0dd0af9cd8..5ad47de472 100644
--- a/sysdeps/nacl/dl-map-segments.h
+++ b/sysdeps/nacl/dl-map-segments.h
@@ -21,6 +21,7 @@
 #include <errno.h>
 #include <stdbool.h>
 #include <unistd.h>
+#include <libc-internal.h>
 
 
 /* This is basically pread, but with iteration after short reads.  */
@@ -45,28 +46,6 @@ read_in_data (int fd, void *data, size_t len, off_t pos)
   return false;
 }
 
-static int
-dyncode_create (void *dst, const void *src, size_t len)
-{
-  /* XXX */
-  return ENOSYS;
-}
-
-/* XXX to be replaced by use of new IRT interface */
-static uintptr_t
-choose_location (uintptr_t hint, size_t total_length,
-                 const struct loadcmd loadcmds[], size_t nloadcmds)
-{
-  assert (loadcmds[0].prot & PROT_EXEC);
-  assert (loadcmds[0].allocend % 0x10000 == 0);
-
-  static uintptr_t next_start = 0x4000000;
-  uintptr_t start = next_start;
-  next_start += loadcmds[0].allocend - loadcmds[0].mapstart;
-
-  return start;
-}
-
 static const char *
 _dl_map_segments (struct link_map *l, int fd,
                   const ElfW(Ehdr) *header, int type,
@@ -87,8 +66,41 @@ _dl_map_segments (struct link_map *l, int fd,
                                   loadcmds[0].mapstart & GLRO(dl_use_load_bias))
            - MAP_BASE_ADDR (l));
 
-      ElfW(Addr) mapstart = choose_location (mappref, maplength,
-                                             loadcmds, nloadcmds);
+      uintptr_t mapstart;
+      if (__glibc_likely (loadcmds[0].prot & PROT_EXEC))
+        {
+          uintptr_t code_size = loadcmds[0].allocend - loadcmds[0].mapstart;
+          uintptr_t data_offset;
+          size_t data_size;
+
+          if (__glibc_likely (nloadcmds > 1))
+            {
+              data_offset = loadcmds[1].mapstart - loadcmds[0].mapstart;
+              data_size = ALIGN_UP (maplength - data_offset,
+                                    GLRO(dl_pagesize));
+            }
+          else
+            {
+              data_offset = 0;
+              data_size = 0;
+            }
+
+          int error = __nacl_irt_code_data_alloc.allocate_code_data
+            (mappref, code_size, data_offset, data_size, &mapstart);
+          if (__glibc_unlikely (error))
+            {
+              errno = error;
+              return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT;
+            }
+        }
+      else
+        {
+          void *mapped = __mmap ((void *) mappref, maplength,
+                                 PROT_NONE, MAP_ANON, -1, 0);
+          if (__glibc_unlikely (mapped == MAP_FAILED))
+            return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT;
+          mapstart = (uintptr_t) mapped;
+        }
 
       l->l_addr = mapstart - loadcmds[0].mapstart;
     }
@@ -137,9 +149,8 @@ _dl_map_segments (struct link_map *l, int fd,
                                      MAP_ANON|MAP_PRIVATE, -1, 0);
                 if (__glibc_unlikely (data == MAP_FAILED))
                   return DL_MAP_SEGMENTS_ERROR_MAP_ZERO_FILL;
-                int error
-                  = dyncode_create ((void *) (l->l_addr + c->mapstart),
-                                    data, len);
+                int error = __nacl_irt_dyncode.dyncode_create
+                  ((void *) (l->l_addr + c->mapstart), data, len);
                 __munmap (data, len);
                 if (__glibc_unlikely (error))
                   {
@@ -209,10 +220,6 @@ _dl_map_segments (struct link_map *l, int fd,
           }
 
         _dl_postprocess_loadcmd (l, header, c);
-
-        _dl_debug_printf ("XXX '%s' load[%u] at [%x,%x)\n",
-                          l->l_name, c - loadcmds,
-                          l->l_addr + c->mapstart, l->l_addr + c->allocend);
       }
 
   /* Notify ELF_PREFERRED_ADDRESS that we have to load this one
diff --git a/sysdeps/nacl/nacl-interface-list.h b/sysdeps/nacl/nacl-interface-list.h
index 2e6afd731c..a13bb20aac 100644
--- a/sysdeps/nacl/nacl-interface-list.h
+++ b/sysdeps/nacl/nacl-interface-list.h
@@ -14,7 +14,12 @@ NACL_MANDATORY_INTERFACE (rtld,
                           NACL_IRT_TLS_v0_1, nacl_irt_tls)
 NACL_MANDATORY_INTERFACE (libc,
                           NACL_IRT_RESOURCE_OPEN_v0_1, nacl_irt_resource_open)
+NACL_MANDATORY_INTERFACE (rtld,
+                          NACL_IRT_CODE_DATA_ALLOC_v0_1,
+                          nacl_irt_code_data_alloc)
 NACL_OPTIONAL_INTERFACE (libc,
                          NACL_IRT_CLOCK_v0_1, nacl_irt_clock)
 NACL_OPTIONAL_INTERFACE (rtld,
+                         NACL_IRT_DYNCODE_v0_1, nacl_irt_dyncode)
+NACL_OPTIONAL_INTERFACE (rtld,
                          NACL_IRT_DEV_GETPID_v0_1, nacl_irt_dev_getpid)