diff options
author | Andy Wingo <wingo@pobox.com> | 2013-04-29 23:55:52 +0200 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2013-04-29 23:55:59 +0200 |
commit | 76068c2a97f745c55312b9471aad9a28283e3d15 (patch) | |
tree | 92f17ed61e5fe16a3ea55677c86f157178743950 | |
parent | c34484dde68b5977e8c335e14c54394533b19e14 (diff) | |
download | guile-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.c | 97 |
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)); |