forked from ocaml/ocaml
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcodefrag.h
96 lines (78 loc) · 4.04 KB
/
codefrag.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/**************************************************************************/
/* */
/* OCaml */
/* */
/* Xavier Leroy, projet Cambium, INRIA Paris */
/* */
/* Copyright 2020 Institut National de Recherche en Informatique et */
/* en Automatique. */
/* */
/* All rights reserved. This file is distributed under the terms of */
/* the GNU Lesser General Public License version 2.1, with the */
/* special exception on linking described in the file LICENSE. */
/* */
/**************************************************************************/
/* A table of all code fragments (main program and dynlinked modules) */
#ifndef CAML_CODEFRAG_H
#define CAML_CODEFRAG_H
#ifdef CAML_INTERNALS
#include "platform.h"
enum digest_status {
DIGEST_LATER, /* computed on demand */
DIGEST_NOW, /* computed by caml_register_code_fragment */
DIGEST_PROVIDED, /* passed by caller of caml_register_code_fragment */
DIGEST_IGNORE /* this code fragment is private and cannot be
identified by its digest */
};
struct code_fragment {
char *code_start;
char *code_end;
int fragnum;
enum digest_status digest_status;
unsigned char digest[16];
/* the digest is obtained by hashing
the bytes between [code_start] and [code_end]. */
caml_plat_mutex mutex;
/* [mutex] protects the fields [digest_status] and [digest],
which may be written to when computing a digest
on-demand (DIGEST_LATER) and thus require synchronization. */
};
/* Initialise codefrag. This must be done before any of the other
operations in codefrag. */
void caml_init_codefrag(void);
/* Register a code fragment for addresses [start] (included)
to [end] (excluded). This range of addresses is assumed
disjoint from all currently-registered code fragments.
[digest_kind] explains what digest is to be associated to the code
fragment. If [digest_kind == DIGEST_PROVIDED], the [opt_digest]
parameter points to the 16-byte digest of the code.
For all other values of [digest_kind], [opt_digest] is ignored
and should be [NULL].
The returned integer is the fragment number (fragnum) associated
with the new code fragment. */
extern int caml_register_code_fragment(char * start, char * end,
enum digest_status digest_kind,
unsigned char * opt_digest);
/* Un-register a code fragment. */
extern void caml_remove_code_fragment(struct code_fragment * cf);
/* Find the code fragment whose range of addresses contains [pc].
Returns NULL if none exists. */
extern struct code_fragment * caml_find_code_fragment_by_pc(char *pc);
/* Find the code fragment whose fragment number is [fragnum].
Returns NULL if none exists. */
extern struct code_fragment * caml_find_code_fragment_by_num(int fragnum);
/* Find the code fragment whose digest is equal to the given digest.
Returns NULL if none exists. */
extern struct code_fragment *
caml_find_code_fragment_by_digest(unsigned char digest[16]);
/* Return the digest of the given code fragment.
If the code fragment was registered in [DIGEST_LATER] mode
and if the digest was not computed yet, it is obtained by hashing
the bytes between [code_start] and [code_end].
Returns NULL if the code fragment was registered with [DIGEST_IGNORE]. */
extern unsigned char * caml_digest_of_code_fragment(struct code_fragment *);
/* Cleans up (and frees) removed code fragments. Must be called from a stop the
world pause by only a single thread. */
extern void caml_code_fragment_cleanup(void);
#endif
#endif