ocaml/runtime/caml/codefrag.h

81 lines
3.4 KiB
C

/**************************************************************************/
/* */
/* 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
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;
unsigned char digest[16];
enum digest_status digest_status;
};
/* 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 *);
#endif
#endif