autodata.c 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. // Licensed under BSD-MIT: See LICENSE.
  2. #include "autodata.h"
  3. #include <stdint.h>
  4. #include <unistd.h>
  5. #include <string.h>
  6. #if HAVE_SECTION_START_STOP
  7. void *autodata_get_section(void *start, void *stop, size_t *nump)
  8. {
  9. *nump = (void **)(stop) - (void **)(start);
  10. return start;
  11. }
  12. void autodata_free(void *table)
  13. {
  14. }
  15. #else
  16. #include <ccan/ptr_valid/ptr_valid.h>
  17. void *autodata_make_table(const void *example, const char *name, size_t *nump)
  18. {
  19. const char *start, *end, *tag;
  20. struct ptr_valid_batch batch;
  21. const void *const magic = (void *)AUTODATA_MAGIC;
  22. void **table = NULL;
  23. char first_magic;
  24. if (!ptr_valid_batch_start(&batch))
  25. return NULL;
  26. /* Get range to search. */
  27. for (start = (char *)((intptr_t)example & ~(getpagesize() - 1));
  28. ptr_valid_batch(&batch, start-getpagesize(), 1, sizeof(void *),
  29. false);
  30. start -= getpagesize());
  31. for (end = (char *)((intptr_t)example & ~(getpagesize() - 1));
  32. ptr_valid_batch(&batch, end, 1, sizeof(void *), false);
  33. end += getpagesize());
  34. *nump = 0;
  35. first_magic = *(char *)&magic;
  36. for (tag = memchr(start, first_magic, end - start);
  37. tag;
  38. tag = memchr(tag+1, first_magic, end - (tag + 1))) {
  39. void *adata[4];
  40. /* We can read 4 void *'s here? */
  41. if (tag + sizeof(adata) > end)
  42. continue;
  43. memcpy(adata, tag, sizeof(adata));
  44. /* False match? */
  45. if (adata[0] != (void *)AUTODATA_MAGIC || adata[1] != tag)
  46. continue;
  47. /* OK, check name. */
  48. if (!ptr_valid_batch_string(&batch, adata[3])
  49. || strcmp(name, adata[3]) != 0)
  50. continue;
  51. if (!ptr_valid_batch_read(&batch, (char *)adata[2]))
  52. continue;
  53. table = realloc(table, sizeof(void *) * (*nump + 1));
  54. if (!table)
  55. break;
  56. table[*nump] = adata[2];
  57. (*nump)++;
  58. }
  59. ptr_valid_batch_end(&batch);
  60. return table;
  61. }
  62. void autodata_free(void *table)
  63. {
  64. free(table);
  65. }
  66. #endif