| // NACL MOD TRACK "third_party/nacl-glibc/sysdeps/nacl/nacl_dyncode_map.c" |
| // NACL MOD BEGIN |
| // Copyright and #include lines. |
| // Copyright 2013 Google Inc. All Rights Reserved. |
| |
| #include <sys/mman.h> |
| |
| #include <irt_syscalls.h> |
| |
| // Add declarations of __mmap, __munmap, and __nacl_dyncode_create. |
| void *__mmap(void *addr, size_t length, int prot, int flags, |
| int fd, off_t offset); |
| int __munmap(void *addr, size_t length); |
| int __nacl_dyncode_create(void *dest, const void *src, size_t size); |
| // NACL MOD END |
| |
| /* Dynamically load code from a file. One day NaCl might provide a |
| syscall that provides this functionality without needing to make a |
| copy of the code. offset and size do not need to be page-aligned. */ |
| int nacl_dyncode_map (int fd, void *dest, size_t offset, size_t size) |
| { |
| size_t alignment_padding = offset & (getpagesize() - 1); |
| uint8_t *mapping; |
| if (alignment_padding == 0 && (size & (getpagesize() - 1)) == 0) { |
| /* First try mmap using PROT_EXEC directly. */ |
| mapping = __mmap(dest, size, PROT_READ | PROT_EXEC, |
| MAP_PRIVATE | MAP_FIXED, fd, offset); |
| if (mapping == dest) { |
| return 0; |
| } else if (mapping != MAP_FAILED) { |
| /* Mapped to an unexpected location. Unmap and fall back. */ |
| __munmap(mapping, size); |
| } |
| } |
| mapping = __mmap (NULL, size + alignment_padding, |
| PROT_READ, MAP_PRIVATE, fd, |
| offset - alignment_padding); |
| if (mapping == MAP_FAILED) |
| return -1; |
| // NACL MOD BEGIN |
| // |dest| is aligned for us, and debugging code. |
| int result = __nacl_dyncode_create((char *)dest + alignment_padding, |
| mapping + alignment_padding, size); |
| // We do not support valgrind for now. |
| // TODO(crbug.com/243244): Figure out if we can/should support this. |
| #if 0 |
| /* Tell Valgrind about this mapping. */ |
| __nacl_dyncode_map_for_valgrind(dest, size, offset, mapping); |
| #endif |
| |
| // NACL MOD END |
| int munmap_result = __munmap (mapping, size); |
| if (result != 0 || munmap_result != 0) |
| return -1; |
| return 0; |
| } |