diff options
author | Roland McGrath <roland@hack.frob.com> | 2015-02-25 16:05:33 -0800 |
---|---|---|
committer | Roland McGrath <roland@hack.frob.com> | 2015-02-25 16:05:33 -0800 |
commit | bce6c2d3aabbe0c913453781dccf845f94b6c1ea (patch) | |
tree | 768a3182ef8369ae84ca070a059f456b0000ad03 | |
parent | 102df60df81ffe7f4d017a70ba2778b1d5e3109a (diff) | |
download | glibc-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.h | 69 | ||||
-rw-r--r-- | sysdeps/nacl/nacl-interface-list.h | 5 |
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) |