]> Savannah Git Hosting - gnulib.git/commitdiff
vma-prot: New module.
authorBruno Haible <bruno@clisp.org>
Thu, 29 Aug 2024 20:48:52 +0000 (22:48 +0200)
committerBruno Haible <bruno@clisp.org>
Thu, 29 Aug 2024 21:54:13 +0000 (23:54 +0200)
* lib/vma-prot.h: New file.
* lib/vma-prot.c: New file.
* modules/vma-prot: New file.

ChangeLog
lib/vma-prot.c [new file with mode: 0644]
lib/vma-prot.h [new file with mode: 0644]
modules/vma-prot [new file with mode: 0644]

index 922aba9e8bff9b89c39e19dedab8f2ba98601e43..709509e07a05cbe47a6371cc142dbcd9e96a9e9f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2024-08-29  Bruno Haible  <bruno@clisp.org>
+
+       vma-prot: New module.
+       * lib/vma-prot.h: New file.
+       * lib/vma-prot.c: New file.
+       * modules/vma-prot: New file.
+
 2024-08-29  Bruno Haible  <bruno@clisp.org>
 
        vma-iter: Relicense under GPLv2+.
diff --git a/lib/vma-prot.c b/lib/vma-prot.c
new file mode 100644 (file)
index 0000000..ebf9699
--- /dev/null
@@ -0,0 +1,86 @@
+/* Determine the protection of a virtual memory area.
+   Copyright (C) 2024 Free Software Foundation, Inc.
+
+   This file is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 2 of the License,
+   or (at your option) any later version.
+
+   This file is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2024.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include "vma-prot.h"
+
+#include <stdint.h>
+
+struct locals
+{
+  /* The common protections seen so far.  */
+  unsigned int prot_so_far;
+  /* The remaining address interval.
+     remaining_start <= remaining_end-1.  */
+  uintptr_t remaining_start;
+  uintptr_t remaining_end;
+};
+
+static int
+callback (void *data, uintptr_t start, uintptr_t end, unsigned int flags)
+{
+  struct locals *l = (struct locals *) data;
+
+  if (start > l->remaining_start)
+    {
+      /* The interval [remaining_start, min (remaining_end, start)) is
+         unmapped.  */
+      l->prot_so_far = 0;
+      return 1;
+    }
+  if (end - 1 < l->remaining_start)
+    /* The interval [start,end) lies before [remaining_start,remaining_end).  */
+    return 0;
+  /* Here  start <= remaining_start <= remaining_end-1
+     and            remaining_start <= end-1,
+     hence start <= remaining_start <= min (end-1, remaining_end-1).
+     So, the two intervals intersect.  */
+  l->prot_so_far &= flags;
+  if (l->prot_so_far == 0)
+    return 1;
+  if (l->remaining_end - 1 <= end - 1)
+    /* Done.  */
+    return 1;
+  /* Trim the remaining address interval.  */
+  l->remaining_start = end;
+  return 0;
+}
+
+int
+get_vma_prot (void *start, size_t size)
+{
+  uintptr_t start_address = (uintptr_t) start;
+
+  struct locals l;
+  l.prot_so_far = VMA_PROT_READ | VMA_PROT_WRITE | VMA_PROT_EXECUTE;
+  l.remaining_start = start_address;
+  l.remaining_end = start_address + size;
+
+  if (l.remaining_end < l.remaining_start)
+    /* Invalid arguments.  */
+    return -1;
+
+  if (l.remaining_end > l.remaining_start)
+    {
+      if (vma_iterate (callback, &l) < 0)
+        return -1;
+    }
+  return l.prot_so_far;
+}
diff --git a/lib/vma-prot.h b/lib/vma-prot.h
new file mode 100644 (file)
index 0000000..aa99048
--- /dev/null
@@ -0,0 +1,50 @@
+/* Determine the protection of a virtual memory area.
+   Copyright (C) 2024 Free Software Foundation, Inc.
+
+   This file is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 2 of the License,
+   or (at your option) any later version.
+
+   This file is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2024.  */
+
+#ifndef _VMA_PROT_H
+#define _VMA_PROT_H
+
+/* Get size_t.  */
+#include <stddef.h>
+
+/* Get VMA_PROT_READ, VMA_PROT_WRITE, VMA_PROT_EXECUTE.  */
+#include "vma-iter.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Returns the declared permissions available on the memory area that
+   starts at START and is SIZE bytes long, as a combination of the bit masks
+   VMA_PROT_READ, VMA_PROT_WRITE, VMA_PROT_EXECUTE.
+   Note: The effective permissions may be larger.  For example, some hardware
+   allows execute permission anywhere where read permission is present.
+   Returns -1 if it cannot be determined.
+
+   Note: This function is expensive.  If possible, an application should find
+   faster alternatives for memory areas that it has allocated itself, such as
+   through malloc(), mmap(), or shmat().  */
+extern int get_vma_prot (void *start, size_t size);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _VMA_PROT_H */
diff --git a/modules/vma-prot b/modules/vma-prot
new file mode 100644 (file)
index 0000000..5ff9277
--- /dev/null
@@ -0,0 +1,24 @@
+Description:
+Determine the protection of a virtual memory area.
+
+Files:
+lib/vma-prot.h
+lib/vma-prot.c
+
+Depends-on:
+stdint
+vma-iter
+
+configure.ac:
+
+Makefile.am:
+lib_SOURCES += vma-prot.c
+
+Include:
+"vma-prot.h"
+
+License:
+GPLv2+
+
+Maintainer:
+all