mirror of
https://github.com/libunwind/libunwind.git
synced 2026-01-12 00:04:03 +08:00
Add internal version of mmap that makes the SYS_mmap syscall
Libunwind assumes that `mmap` "goes straight through to a system call stub". But this might not be true as other runtimes (I'm looking at you UCX) wrap `mmap` and do AS-unsafe stuff again.
This commit is contained in:
committed by
Stephen M. Webb
parent
192863f344
commit
5010beb099
@@ -217,6 +217,26 @@ do { \
|
||||
|
||||
#define SOS_MEMORY_SIZE 16384 /* see src/mi/mempool.c */
|
||||
|
||||
/* Provide an internal syscall version of mmap to improve signal safety. */
|
||||
static ALWAYS_INLINE void *
|
||||
mi_mmap (void *addr, size_t len, int prot, int flags, int fd, off_t offset)
|
||||
{
|
||||
#ifdef SYS_mmap
|
||||
#ifdef __syscall // prefer over syscall on *BSD
|
||||
long int ret = __syscall (SYS_mmap, addr, len, prot, flags, fd, offset);
|
||||
#else
|
||||
long int ret = syscall (SYS_mmap, addr, len, prot, flags, fd, offset);
|
||||
#endif
|
||||
// @todo this is very likely Linux specific
|
||||
if ((unsigned long int)ret > -4096UL)
|
||||
return MAP_FAILED;
|
||||
else
|
||||
return (void *)ret;
|
||||
#else
|
||||
return mmap (addr, len, prot, flags, fd, offset);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Provide an internal syscall version of munmap to improve signal safety. */
|
||||
static ALWAYS_INLINE int
|
||||
mi_munmap (void *addr, size_t len)
|
||||
@@ -233,9 +253,8 @@ mi_munmap (void *addr, size_t len)
|
||||
#endif
|
||||
#define GET_MEMORY(mem, size) \
|
||||
do { \
|
||||
/* Hopefully, mmap() goes straight through to a system call stub... */ \
|
||||
mem = mmap (NULL, size, PROT_READ | PROT_WRITE, \
|
||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \
|
||||
mem = mi_mmap (NULL, size, PROT_READ | PROT_WRITE, \
|
||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \
|
||||
if (mem == MAP_FAILED) \
|
||||
mem = NULL; \
|
||||
} while (0)
|
||||
|
||||
@@ -43,10 +43,10 @@ CD_elf_map_image(struct UCD_info *ui, coredump_phdr_t *phdr)
|
||||
* these pages are allocated, but non-accessible.
|
||||
*/
|
||||
/* addr, length, prot, flags, fd, fd_offset */
|
||||
ei->image = mmap(NULL, phdr->p_memsz, PROT_READ, MAP_PRIVATE, ui->coredump_fd, phdr->p_offset);
|
||||
ei->image = mi_mmap(NULL, phdr->p_memsz, PROT_READ, MAP_PRIVATE, ui->coredump_fd, phdr->p_offset);
|
||||
if (ei->image == MAP_FAILED)
|
||||
{
|
||||
Debug(0, "error %d in mmap(): %s\n", errno, strerror(errno));
|
||||
Debug(0, "error in mmap()\n");
|
||||
ei->image = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -124,10 +124,10 @@ ucd_file_map (ucd_file_t *ucd_file)
|
||||
_ucd_file_open (ucd_file);
|
||||
}
|
||||
|
||||
ucd_file->image = mmap(NULL, ucd_file->size, PROT_READ, MAP_PRIVATE, ucd_file->fd, 0);
|
||||
ucd_file->image = mi_mmap(NULL, ucd_file->size, PROT_READ, MAP_PRIVATE, ucd_file->fd, 0);
|
||||
if (ucd_file->image == MAP_FAILED)
|
||||
{
|
||||
Debug(0, "error %d in mmap(%s): %s\n", errno, ucd_file->filename, strerror(errno));
|
||||
Debug(0, "error in mmap(%s)\n", ucd_file->filename);
|
||||
ucd_file->image = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -239,10 +239,9 @@ elf_w (extract_minidebuginfo) (struct elf_image *ei, struct elf_image *mdi)
|
||||
}
|
||||
|
||||
mdi->size = uncompressed_len;
|
||||
mdi->image = mmap (NULL, uncompressed_len, PROT_READ|PROT_WRITE,
|
||||
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
||||
GET_MEMORY (mdi->image, uncompressed_len);
|
||||
|
||||
if (mdi->image == MAP_FAILED)
|
||||
if (!mdi->image)
|
||||
return 0;
|
||||
|
||||
size_t in_pos = 0, out_pos = 0;
|
||||
|
||||
@@ -85,7 +85,7 @@ elf_map_image (struct elf_image *ei, const char *path)
|
||||
}
|
||||
|
||||
ei->size = stat.st_size;
|
||||
ei->image = mmap (NULL, ei->size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
ei->image = mi_mmap (NULL, ei->size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
close (fd);
|
||||
if (ei->image == MAP_FAILED)
|
||||
return -1;
|
||||
|
||||
@@ -37,7 +37,7 @@ get_mem(size_t sz)
|
||||
{
|
||||
void *res;
|
||||
|
||||
res = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
res = mi_mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
if (res == MAP_FAILED)
|
||||
return (NULL);
|
||||
return (res);
|
||||
|
||||
@@ -77,9 +77,8 @@ maps_init (struct map_iterator *mi, pid_t pid)
|
||||
{
|
||||
/* Try to allocate a page-sized buffer. */
|
||||
mi->buf_size = getpagesize ();
|
||||
cp = mmap (NULL, mi->buf_size, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
if (cp == MAP_FAILED)
|
||||
GET_MEMORY (cp, mi->buf_size);
|
||||
if (!cp)
|
||||
{
|
||||
close(mi->fd);
|
||||
mi->fd = -1;
|
||||
|
||||
Reference in New Issue
Block a user