summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2013-04-29 23:55:52 +0200
committerAndy Wingo <wingo@pobox.com>2013-04-29 23:55:59 +0200
commit76068c2a97f745c55312b9471aad9a28283e3d15 (patch)
tree92f17ed61e5fe16a3ea55677c86f157178743950
parentc34484dde68b5977e8c335e14c54394533b19e14 (diff)
downloadguile-76068c2a97f745c55312b9471aad9a28283e3d15.tar.gz
replace mapped-elf-images with find-mapped-elf-image
* libguile/objcodes.c (scm_find_mapped_elf_image): Replace mapped-elf-images with find-mapped-elf-image, which takes a pointer as an argument.
-rw-r--r--libguile/objcodes.c97
1 files changed, 87 insertions, 10 deletions
diff --git a/libguile/objcodes.c b/libguile/objcodes.c
index 45518877b..7946091a9 100644
--- a/libguile/objcodes.c
+++ b/libguile/objcodes.c
@@ -638,28 +638,105 @@ scm_c_make_objcode_slice (SCM parent, const scm_t_uint8 *ptr)
}
#undef FUNC_NAME
-static SCM mapped_elf_images = SCM_EOL;
+struct mapped_elf_image
+{
+ char *start;
+ char *end;
+};
+
+static struct mapped_elf_image *mapped_elf_images = NULL;
+static size_t mapped_elf_images_count = 0;
+static size_t mapped_elf_images_allocated = 0;
+
+static size_t
+find_mapped_elf_insertion_index (char *ptr)
+{
+ /* "mapped_elf_images_count" must never be dereferenced. */
+ size_t start = 0, end = mapped_elf_images_count;
+
+ while (start < end)
+ {
+ size_t n = start + (end - start) / 2;
+
+ if (ptr < mapped_elf_images[n].end)
+ end = n;
+ else
+ start = n + 1;
+ }
+
+ return start;
+}
static void
register_elf (char *data, size_t len)
{
- SCM bv = scm_c_take_gc_bytevector ((signed char *) data, len, SCM_BOOL_F);
-
scm_i_pthread_mutex_lock (&scm_i_misc_mutex);
- mapped_elf_images = scm_cons (bv, mapped_elf_images);
+ {
+ /* My kingdom for a generic growable sorted vector library. */
+ if (mapped_elf_images_count == mapped_elf_images_allocated)
+ {
+ struct mapped_elf_image *prev;
+ size_t n;
+
+ if (mapped_elf_images_allocated)
+ mapped_elf_images_allocated *= 2;
+ else
+ mapped_elf_images_allocated = 16;
+
+ prev = mapped_elf_images;
+ mapped_elf_images =
+ scm_gc_malloc_pointerless (sizeof (*mapped_elf_images)
+ * mapped_elf_images_allocated,
+ "mapped elf images");
+
+ for (n = 0; n < mapped_elf_images_count; n++)
+ {
+ mapped_elf_images[n].start = prev[n].start;
+ mapped_elf_images[n].end = prev[n].end;
+ }
+ }
+
+ {
+ size_t end;
+ size_t n = find_mapped_elf_insertion_index (data);
+
+ for (end = mapped_elf_images_count; n < end; end--)
+ {
+ mapped_elf_images[end].start = mapped_elf_images[end - 1].start;
+ mapped_elf_images[end].end = mapped_elf_images[end - 1].end;
+ }
+ mapped_elf_images_count++;
+
+ mapped_elf_images[n].start = data;
+ mapped_elf_images[n].end = data + len;
+ }
+ }
scm_i_pthread_mutex_unlock (&scm_i_misc_mutex);
}
static SCM
-scm_mapped_elf_images (void)
+scm_find_mapped_elf_image (SCM ip)
{
- SCM ret;
+ char *ptr = (char *) scm_to_unsigned_integer (ip, 0, SCM_T_UINTPTR_MAX);
+ SCM result;
scm_i_pthread_mutex_lock (&scm_i_misc_mutex);
- ret = mapped_elf_images;
+ {
+ size_t n = find_mapped_elf_insertion_index ((char *) ptr);
+ if (n < mapped_elf_images_count
+ && mapped_elf_images[n].start <= ptr
+ && ptr < mapped_elf_images[n].end)
+ {
+ signed char *data = (signed char *) mapped_elf_images[n].start;
+ size_t len = mapped_elf_images[n].end - mapped_elf_images[n].start;
+ result = scm_c_take_gc_bytevector (data, len, SCM_BOOL_F);
+ }
+ else
+ result = SCM_BOOL_F;
+ }
scm_i_pthread_mutex_unlock (&scm_i_misc_mutex);
- return ret;
+ return result;
}
@@ -800,8 +877,8 @@ scm_init_objcodes (void)
#include "libguile/objcodes.x"
#endif
- scm_c_define_gsubr ("mapped-elf-images", 0, 0, 0,
- (scm_t_subr) scm_mapped_elf_images);
+ scm_c_define_gsubr ("find-mapped-elf-image", 1, 0, 0,
+ (scm_t_subr) scm_find_mapped_elf_image);
scm_c_define ("word-size", scm_from_size_t (sizeof(SCM)));
scm_c_define ("byte-order", scm_from_uint16 (SCM_BYTE_ORDER));