/* ******************************************************
 * Copyright (c) 2014 Google, Inc.  All rights reserved.
 * ******************************************************/

/*
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * * Neither the name of VMware, Inc. nor the names of its contributors may be
 *   used to endorse or promote products derived from this software without
 *   specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 */

#include "globals.h"
#include "hashtable.h"
#include "instr.h"
#include "instr_create.h"
#include "decode_fast.h"
#include "utils.h"
#include "annotations.h"

#ifdef ANNOTATIONS /* around whole file */

#if !(defined (WINDOWS) && defined (X64))
# include "../third_party/valgrind/valgrind.h"
# include "../third_party/valgrind/memcheck.h"
#endif

#ifdef UNIX
# include <string.h>
#endif

/* Macros for identifying an annotation head and extracting the pointer to its name.
 *
 * IS_ANNOTATION_LABEL_INSTR(instr):               Evaluates to true for any `instr` that
 *                                                 could be the instruction which encodes
 *                                                 the pointer to the annotation name.
 * IS_ANNOTATION_LABEL_REFERENCE(opnd):            Evaluates to true for any `opnd` that
 *                                                 could be the operand which encodes
 *                                                 the pointer to the annotation name.
 * GET_ANNOTATION_LABEL_REFERENCE(src, instr_pc):  Extracts the annotation name pointer.
 * IS_ANNOTATION_LABEL_GOT_OFFSET_INSTR(instr):    Evaluates to true for any `instr` that
 *                                                 could encode the offset of the label's
 *                                                 GOT entry within the GOT table.
 * IS_ANNOTATION_LABEL_GOT_OFFSET_REFERENCE(opnd): Evaluates to true for any `opnd` that
 *                                                 could encode the offset of the label's
 *                                                 GOT entry within the GOT table.
 */
#ifdef WINDOWS
# ifdef X64
#  define IS_ANNOTATION_LABEL_INSTR(instr) \
        (instr_is_mov(instr) || (instr_get_opcode(instr) == OP_prefetchw))
#  define IS_ANNOTATION_LABEL_REFERENCE(opnd) opnd_is_rel_addr(opnd)
#  define GET_ANNOTATION_LABEL_REFERENCE(src, instr_pc) opnd_get_addr(src)
# else
#  define IS_ANNOTATION_LABEL_INSTR(instr) instr_is_mov(instr)
#  define IS_ANNOTATION_LABEL_REFERENCE(opnd) opnd_is_base_disp(opnd)
#  define GET_ANNOTATION_LABEL_REFERENCE(src, instr_pc) ((app_pc) opnd_get_disp(src))
# endif
#else
# define IS_ANNOTATION_LABEL_INSTR(instr) instr_is_mov(instr)
# define IS_ANNOTATION_LABEL_REFERENCE(opnd) opnd_is_base_disp(opnd)
# ifdef X64
#  define ANNOTATION_LABEL_REFERENCE_OPERAND_OFFSET 4
# else
#  define ANNOTATION_LABEL_REFERENCE_OPERAND_OFFSET 0
# endif
# define GET_ANNOTATION_LABEL_REFERENCE(src, instr_pc) \
    ((app_pc) (opnd_get_disp(src) + (instr_pc) + \
               ANNOTATION_LABEL_REFERENCE_OPERAND_OFFSET))
# define IS_ANNOTATION_LABEL_GOT_OFFSET_INSTR(instr) \
    (instr_get_opcode(scratch) == OP_bsf || instr_get_opcode(scratch) == OP_bsr)
# define IS_ANNOTATION_LABEL_GOT_OFFSET_REFERENCE(opnd) opnd_is_base_disp(opnd)
#endif

/* Annotation label components. */
#define DYNAMORIO_ANNOTATION_LABEL "dynamorio-annotation"
#define DYNAMORIO_ANNOTATION_LABEL_LENGTH 20
#define ANNOTATION_STATEMENT_LABEL "statement"
#define ANNOTATION_STATEMENT_LABEL_LENGTH 9
#define ANNOTATION_EXPRESSION_LABEL "expression"
#define ANNOTATION_EXPRESSION_LABEL_LENGTH 10
#define ANNOTATION_VOID_LABEL "void"
#define ANNOTATION_VOID_LABEL_LENGTH 4
#define IS_ANNOTATION_STATEMENT_LABEL(annotation_name) \
    (strncmp((const char *) (annotation_name), ANNOTATION_STATEMENT_LABEL, \
             ANNOTATION_STATEMENT_LABEL_LENGTH) == 0)
#define IS_ANNOTATION_VOID(annotation_name) \
    (strncmp((const char *) (annotation_name), ANNOTATION_VOID_LABEL":", \
             ANNOTATION_VOID_LABEL_LENGTH) == 0)

/* Annotation detection factors exclusive to Windows x64. */
#if defined (WINDOWS) && defined (X64)
/* Instruction `int 2c` hints that the preceding cbr is probably an annotation head. */
# define WINDOWS_X64_ANNOTATION_HINT_BYTE 0xcd
# define X64_WINDOWS_ENCODED_ANNOTATION_HINT 0x2ccd
/* Instruction `int 3` acts as a boundary for compiler optimizations, to prevent the
 * the annotation from being transformed into something unrecognizable.
 */
# define WINDOWS_X64_OPTIMIZATION_FENCE 0xcc
# define IS_ANNOTATION_HEADER(scratch, pc) \
    (instr_is_cbr(scratch) && (*(ushort *) (pc) == X64_WINDOWS_ENCODED_ANNOTATION_HINT))
#endif

/* OPND_RETURN_VALUE: create the return value operand for `mov $return_value,%xax`. */
#ifdef X64
# define OPND_RETURN_VALUE(return_value) OPND_CREATE_INT64(return_value)
#else
# define OPND_RETURN_VALUE(return_value) OPND_CREATE_INT32(return_value)
#endif

/* FASTCALL_REGISTER_ARG_COUNT: Specifies the number of arguments passed in registers. */
#ifdef X64
# ifdef UNIX
#  define FASTCALL_REGISTER_ARG_COUNT 6
# else /* WINDOWS x64 */
#  define FASTCALL_REGISTER_ARG_COUNT 4
# endif
#else /* x86 (all) */
# define FASTCALL_REGISTER_ARG_COUNT 2
#endif

#define DYNAMORIO_ANNOTATE_RUNNING_ON_DYNAMORIO_NAME \
    "dynamorio_annotate_running_on_dynamorio"

#define DYNAMORIO_ANNOTATE_LOG_NAME \
    "dynamorio_annotate_log"

#define DYNAMORIO_ANNOTATE_LOG_ARG_COUNT 20

/* Facilitates timestamp substitution in `dynamorio_annotate_log()`. */
#define LOG_ANNOTATION_TIMESTAMP_TOKEN "${timestamp}"
#define LOG_ANNOTATION_TIMESTAMP_TOKEN_LENGTH 12

/* Constant factors of the Valgrind annotation, as defined in valgrind.h. */
enum {
    VG_ROL_COUNT = 4,
    VG_PATTERN_LENGTH = 5,
};

/* Immediate operands to the special rol instructions.
 * See __SPECIAL_INSTRUCTION_PREAMBLE in valgrind.h.
 */
#ifdef X64
static const int
expected_rol_immeds[VG_PATTERN_LENGTH] = {
    3,
    13,
    61,
    51
};
#else
static const int
expected_rol_immeds[VG_PATTERN_LENGTH] = {
    3,
    13,
    29,
    19
};
#endif

typedef enum _annotation_type_t {
    /* Indicates that the analyzed instruction turned out not to be an annotation head. */
    ANNOTATION_TYPE_NONE,
    /* To invoke an annotation as an expression, the target app calls the annotation as if
     * it were a normal function. The annotation instruction sequence follows the preamble
     * of each annotation function, and instrumentation replaces it with (1) a clean call
     * to each registered handler for that annotation, or (2) a return value substitution,
     * depending on the type of registration.
     */
    ANNOTATION_TYPE_EXPRESSION,
    /* To invoke an annotation as a statement, the target app calls a macro defined in
     * the annotation header (via dr_annotations_asm.h), which places the annotation
     * instruction sequence inline at the invocation site. The sequence includes a normal
     * call to the annotation function, so instrumentation simply involves removing the
     * surrounding components of the annotation to expose the call. The DR client's clean
     * calls will be invoked within the annotation function itself (see above).
     */
    ANNOTATION_TYPE_STATEMENT,
} annotation_type_t;

/* Specifies the exact byte position of the essential components of an annotation. */
typedef struct _annotation_layout_t {
    app_pc start_pc;
    annotation_type_t type;
    /* Indicates whether the annotation function in the target app is of void type. */
    bool is_void;
    /* Points to the annotation name in the target app's data section. */
    const char *name;
    /* Specifies the translation of the annotation instrumentation (e.g., clean call). */
    app_pc substitution_xl8;
    /* Specifies the byte at which app decoding should resume following the annotation. */
    app_pc resume_pc;
} annotation_layout_t;

static strhash_table_t *handlers;

/* locked under the `handlers` table lock */
static dr_annotation_handler_t *vg_handlers[DR_VG_ID__LAST];

#if !(defined (WINDOWS) && defined (X64))
/* Dispatching function for Valgrind annotations (required because id of the Valgrind
 * client request object cannot be determined statically).
 */
static dr_annotation_handler_t vg_router;
static dr_annotation_receiver_t vg_receiver; /* The sole receiver for `vg_router`. */
static opnd_t vg_router_arg; /* The sole argument for the clean call to `vg_router`. */
#endif

/* Required for passing the va_list in `dynamorio_annotate_log()` to the log function. */
extern ssize_t do_file_write(file_t f, const char *fmt, va_list ap);

/*********************************************************
 * INTERNAL ROUTINE DECLARATIONS
 */

#if !(defined (WINDOWS) && defined (X64))
/* Valgrind dispatcher, called by the instrumentation of the Valgrind annotations. */
static void
handle_vg_annotation(app_pc request_args);

/* Maps a Valgrind request id into a (sequential) `DR_VG_ID__*` constant. */
static dr_valgrind_request_id_t
lookup_valgrind_request(ptr_uint_t request);

static ptr_uint_t
valgrind_running_on_valgrind(dr_vg_client_request_t *request);
#endif

static bool
is_annotation_tag(dcontext_t *dcontext, IN OUT app_pc *start_pc, instr_t *scratch,
                  OUT const char **name);

static void
identify_annotation(dcontext_t *dcontext, IN OUT annotation_layout_t *layout,
                    instr_t *scratch);

/* Create argument operands for the instrumented clean call */
static void
create_arg_opnds(dr_annotation_handler_t *handler, uint num_args,
                 dr_annotation_calling_convention_t call_type);

#ifdef DEBUG
/* Implements `dynamorio_annotate_log()`, including substitution of the string literal
 * token "${timestamp}" with the current system time.
 */
static ssize_t
annotation_printf(const char *format, ...);
#endif

/* Invoked during hashtable entry removal */
static void
free_annotation_handler(void *p);

/*********************************************************
 * ANNOTATION INTEGRATION FUNCTIONS
 */

void
annotation_init()
{
    handlers = strhash_hash_create(GLOBAL_DCONTEXT, 8, 80, /* favor a small table */
                                   HASHTABLE_ENTRY_SHARED | HASHTABLE_SHARED |
                                   HASHTABLE_RELAX_CLUSTER_CHECKS | HASHTABLE_PERSISTENT,
                                   free_annotation_handler
                                   _IF_DEBUG("annotation handler hashtable"));

#if !(defined (WINDOWS) && defined (X64))
    vg_router.type = DR_ANNOTATION_HANDLER_CALL;
    /* The Valgrind client request object is passed in %xax. */
    vg_router.num_args = 1;
    vg_router_arg = opnd_create_reg(DR_REG_XAX);
    vg_router.args = &vg_router_arg;
    vg_router.symbol_name = NULL; /* No symbols in Valgrind annotations. */
    vg_router.receiver_list = &vg_receiver;
    vg_receiver.instrumentation.callback = (void *) (void (*)()) handle_vg_annotation;
    vg_receiver.save_fpstate = false;
    vg_receiver.next = NULL;
#endif

    dr_annotation_register_return(DYNAMORIO_ANNOTATE_RUNNING_ON_DYNAMORIO_NAME,
                                  (void *) (ptr_uint_t) true);
#ifdef DEBUG
    /* The logging annotation requires a debug build of DR. Arbitrarily allows up to
     * 20 arguments, since the clean call must have a fixed number of them.
     */
    dr_annotation_register_call(DYNAMORIO_ANNOTATE_LOG_NAME, (void *) annotation_printf,
                                false, DYNAMORIO_ANNOTATE_LOG_ARG_COUNT,
                                DR_ANNOTATION_CALL_TYPE_VARARG);
#endif

#if !(defined (WINDOWS) && defined (X64))
    /* DR pretends to be Valgrind. */
    dr_annotation_register_valgrind(DR_VG_ID__RUNNING_ON_VALGRIND,
                                    valgrind_running_on_valgrind);
#endif
}

void
annotation_exit()
{
    uint i;
    for (i = 0; i < DR_VG_ID__LAST; i++) {
        if (vg_handlers[i] != NULL)
            free_annotation_handler(vg_handlers[i]);
    }

    strhash_hash_destroy(GLOBAL_DCONTEXT, handlers);
}

bool
instrument_annotation(dcontext_t *dcontext, IN OUT app_pc *start_pc,
                      OUT instr_t **substitution _IF_WINDOWS_X64(IN bool hint_is_safe))
{
    annotation_layout_t layout = {0};
    /* This instr_t is used for analytical decoding throughout the detection functions.
     * It is passed on the stack and its contents are considered void on function entry.
     */
    instr_t scratch;
#if defined (WINDOWS) && defined (X64)
    app_pc hint_pc = *start_pc;
    bool hint = true;
    byte hint_byte;
#endif

#if defined (WINDOWS) && defined (X64)
    if (hint_is_safe) {
        hint_byte = *hint_pc;
    } else {
        if (!safe_read(hint_pc, 1, &hint_byte))
            return false;
    }
    if (hint_byte != WINDOWS_X64_ANNOTATION_HINT_BYTE)
        return false;
    /* The hint is the first byte of the 2-byte instruction `int 2c`. Skip both bytes. */
    layout.start_pc = hint_pc + INT_LENGTH;
    layout.substitution_xl8 = layout.start_pc;
#else
    layout.start_pc = *start_pc;
#endif

    instr_init(dcontext, &scratch);
    TRY_EXCEPT(dcontext, {
        identify_annotation(dcontext, &layout, &scratch);
    }, { /* EXCEPT */
        LOG(THREAD, LOG_ANNOTATIONS, 2, "Failed to instrument annotation at "PFX"\n",
            *start_pc);
        /* layout.type is already ANNOTATION_TYPE_NONE */
    });
    if (layout.type != ANNOTATION_TYPE_NONE) {
        LOG(GLOBAL, LOG_ANNOTATIONS, 2, "Decoded %s instance of %s\n",
           (layout.type == ANNOTATION_TYPE_EXPRESSION) ? "expression" : "statement",
           layout.name);
        /* Notify the caller where to resume decoding app instructions. */
        *start_pc = layout.resume_pc;

        if (layout.type == ANNOTATION_TYPE_EXPRESSION) {
            dr_annotation_handler_t *handler;

            TABLE_RWLOCK(handlers, write, lock);
            handler = strhash_hash_lookup(GLOBAL_DCONTEXT, handlers, layout.name);
            if (handler != NULL) {
                if (handler->type == DR_ANNOTATION_HANDLER_CALL) {
                    /* Substitute the annotation with a label pointing to the handler. */
                    instr_t *call = INSTR_CREATE_label(dcontext);
                    dr_instr_label_data_t *label_data = instr_get_label_data_area(call);
                    SET_ANNOTATION_HANDLER(label_data, handler);
                    SET_ANNOTATION_APP_PC(label_data, layout.resume_pc);
                    instr_set_note(call, (void *) DR_NOTE_ANNOTATION);
                    instr_set_meta(call);
                    *substitution = call;

                    handler->is_void = layout.is_void;
                    if (!handler->is_void) {
                        /* Append `mov $0x0,%eax` to the annotation substitution, so that
                         * clients and tools recognize that %xax will be written here.
                         * The placeholder is "ok to mangle" because it (partially)
                         * implements the app's annotation. The placeholder will be
                         * removed post-client during mangling.
                         */
                        instr_t *return_placeholder =
                            INSTR_XL8(INSTR_CREATE_mov_st(dcontext,
                                                          opnd_create_reg(REG_XAX),
                                                          OPND_CREATE_INT32(0)),
                                      layout.substitution_xl8);
                        instr_set_note(return_placeholder, (void *) DR_NOTE_ANNOTATION);
                        /* Append the placeholder manually, because the caller can call
                         * `instrlist_append()` with a "sublist" of instr_t.
                         */
                        instr_set_next(*substitution, return_placeholder);
                        instr_set_prev(return_placeholder, *substitution);
                    }
                } else {
                    /* Substitute the annotation with `mov $return_value,%eax` */
                    void *return_value =
                        handler->receiver_list->instrumentation.return_value;
                    *substitution =
                        INSTR_XL8(INSTR_CREATE_mov_imm(dcontext,
                                                       opnd_create_reg(REG_XAX),
                                                       OPND_RETURN_VALUE(return_value)),
                                  layout.substitution_xl8);
                }
            } /* else no handlers, so replace the annotation with nothing */
            TABLE_RWLOCK(handlers, write, unlock);
        }
        /* else (layout.type == ANNOTATION_TYPE_STATEMENT), in which case the only
         * instrumentation is to remove the jump-over-annotation such that the annotation
         * function gets called like a normal function. Instrumentation of clean calls and
         * return values will then occur within the annotation function (the case above).
         */
    }
    instr_free(dcontext, &scratch);
    return (layout.type != ANNOTATION_TYPE_NONE);
}

#if !(defined (WINDOWS) && defined (X64))
void
instrument_valgrind_annotation(dcontext_t *dcontext, instrlist_t *bb, instr_t *xchg_instr,
                               app_pc xchg_pc, uint bb_instr_count)
{
    int i;
    instr_t *return_placeholder;
    instr_t *instr, *next_instr;
    dr_instr_label_data_t *label_data;

    LOG(THREAD, LOG_ANNOTATIONS, 2, "Matched valgrind client request pattern at "PFX"\n",
        instr_get_app_pc(xchg_instr));

    /* We leave the argument gathering code as app instructions, because it writes to app
     * registers (xref i#1423). Now delete the `xchg` instruction, and the `rol`
     * instructions--unless a previous BB contains some of the `rol`, in which case they
     * must be executed to avoid messing up %xdi (the 4 `rol` compose to form a nop).
     */
    instr_destroy(dcontext, xchg_instr);
    if (bb_instr_count > VG_ROL_COUNT) {
        instr = instrlist_last(bb);
        for (i = 0; i < VG_ROL_COUNT; i++) {
            ASSERT(instr != NULL && instr_get_opcode(instr) == OP_rol);
            next_instr = instr_get_prev(instr);
            instrlist_remove(bb, instr);
            instr_destroy(dcontext, instr);
            instr = next_instr;
        }
    }

    /* Substitute the annotation tail with a label pointing to the Valgrind handler. */
    instr = INSTR_CREATE_label(dcontext);
    instr_set_note(instr, (void *) DR_NOTE_ANNOTATION);
    label_data = instr_get_label_data_area(instr);
    SET_ANNOTATION_HANDLER(label_data, &vg_router);
    SET_ANNOTATION_APP_PC(label_data, xchg_pc);
    instr_set_meta(instr);
    instrlist_append(bb, instr);

    /* Append `mov $0x0,%edx` so that clients and tools recognize that %xdx will be
     * written here. The placeholder is "ok to mangle" because it (partially) implements
     * the app's annotation. The placeholder will be removed post-client during mangling.
     */
    return_placeholder = INSTR_XL8(INSTR_CREATE_mov_st(dcontext, opnd_create_reg(REG_XDX),
                                                       OPND_CREATE_INT32(0)),
                                   xchg_pc);
    instr_set_note(return_placeholder, (void *) DR_NOTE_ANNOTATION);
    instrlist_append(bb, return_placeholder);
}
#endif

/*********************************************************
 * ANNOTATION API FUNCTIONS
 */

bool
dr_annotation_register_call(const char *annotation_name, void *callee, bool save_fpstate,
                            uint num_args, dr_annotation_calling_convention_t call_type)
{
    bool result = true;
    dr_annotation_handler_t *handler;
    dr_annotation_receiver_t *receiver;

    TABLE_RWLOCK(handlers, write, lock);

    handler = (dr_annotation_handler_t *) strhash_hash_lookup(GLOBAL_DCONTEXT, handlers,
                                                              annotation_name);
    if (handler == NULL) { /* make a new handler if never registered yet */
        handler = HEAP_TYPE_ALLOC(GLOBAL_DCONTEXT, dr_annotation_handler_t,
                                  ACCT_OTHER, UNPROTECTED);
        memset(handler, 0, sizeof(dr_annotation_handler_t));
        handler->type = DR_ANNOTATION_HANDLER_CALL;
        handler->symbol_name = dr_strdup(annotation_name HEAPACCT(ACCT_OTHER));
        handler->num_args = num_args;

        if (num_args == 0) {
            handler->args = NULL;
        } else {
            handler->args = HEAP_ARRAY_ALLOC(GLOBAL_DCONTEXT, opnd_t, num_args,
                                             ACCT_OTHER, UNPROTECTED);
            create_arg_opnds(handler, num_args, call_type);
        }

        strhash_hash_add(GLOBAL_DCONTEXT, handlers, handler->symbol_name, handler);
    }
    if (handler->type == DR_ANNOTATION_HANDLER_CALL || handler->receiver_list == NULL) {
        /* If the annotation previously had a return value registration, it can be changed
         * to clean call instrumentation, provided the return value was unregistered.
         */
        handler->type = DR_ANNOTATION_HANDLER_CALL;
        receiver = HEAP_TYPE_ALLOC(GLOBAL_DCONTEXT, dr_annotation_receiver_t,
                                   ACCT_OTHER, UNPROTECTED);
        receiver->instrumentation.callback = callee;
        receiver->save_fpstate = save_fpstate;
        receiver->next = handler->receiver_list; /* push the new receiver onto the list */
        handler->receiver_list = receiver;
    } else {
        result = false; /* A return value is registered, so no call can be added. */
    }

    TABLE_RWLOCK(handlers, write, unlock);
    return result;
}

bool
dr_annotation_register_valgrind(dr_valgrind_request_id_t request_id,
                                ptr_uint_t (*annotation_callback)
                                (dr_vg_client_request_t *request))
{
    dr_annotation_handler_t *handler;
    dr_annotation_receiver_t *receiver;
    if (request_id >= DR_VG_ID__LAST)
        return false;

    TABLE_RWLOCK(handlers, write, lock);
    handler = vg_handlers[request_id];
    if (handler == NULL) { /* make a new handler if never registered yet */
        handler = HEAP_TYPE_ALLOC(GLOBAL_DCONTEXT, dr_annotation_handler_t,
                                  ACCT_OTHER, UNPROTECTED);
        memset(handler, 0, sizeof(dr_annotation_handler_t));
        handler->type = DR_ANNOTATION_HANDLER_VALGRIND;

        vg_handlers[request_id] = handler;
    }

    receiver = HEAP_TYPE_ALLOC(GLOBAL_DCONTEXT, dr_annotation_receiver_t,
                               ACCT_OTHER, UNPROTECTED);
    receiver->instrumentation.vg_callback = annotation_callback;
    receiver->save_fpstate = false;
    receiver->next = handler->receiver_list; /* push the new receiver onto the list */
    handler->receiver_list = receiver;

    TABLE_RWLOCK(handlers, write, unlock);
    return true;
}

bool
dr_annotation_register_return(const char *annotation_name, void *return_value)
{
    bool result = true;
    dr_annotation_handler_t *handler;
    dr_annotation_receiver_t *receiver;

    TABLE_RWLOCK(handlers, write, lock);
    ASSERT_TABLE_SYNCHRONIZED(handlers, WRITE);
    handler = (dr_annotation_handler_t *) strhash_hash_lookup(GLOBAL_DCONTEXT, handlers,
                                                              annotation_name);
    if (handler == NULL) { /* make a new handler if never registered yet */
        handler = HEAP_TYPE_ALLOC(GLOBAL_DCONTEXT, dr_annotation_handler_t,
                                  ACCT_OTHER, UNPROTECTED);
        memset(handler, 0, sizeof(dr_annotation_handler_t));
        handler->type = DR_ANNOTATION_HANDLER_RETURN_VALUE;
        handler->symbol_name = dr_strdup(annotation_name HEAPACCT(ACCT_OTHER));
        strhash_hash_add(GLOBAL_DCONTEXT, handlers, handler->symbol_name, handler);
    }
    if (handler->receiver_list == NULL) {
        /* If the annotation previously had clean call registration, it can be changed to
         * return value instrumentation, provided the calls have been unregistered.
         */
        handler->type = DR_ANNOTATION_HANDLER_RETURN_VALUE;
        receiver = HEAP_TYPE_ALLOC(GLOBAL_DCONTEXT, dr_annotation_receiver_t,
                                   ACCT_OTHER, UNPROTECTED);
        receiver->instrumentation.return_value = return_value;
        receiver->save_fpstate = false;
        receiver->next = NULL; /* Return value can only have one implementation. */
        handler->receiver_list = receiver;
    } else {
        result = false; /* Calls are registered, preventing the new return value. */
    }
    TABLE_RWLOCK(handlers, write, unlock);
    return result;
}

bool
dr_annotation_unregister_call(const char *annotation_name, void *callee)
{
    bool found = false;
    dr_annotation_handler_t *handler;

    TABLE_RWLOCK(handlers, write, lock);
    handler = (dr_annotation_handler_t *) strhash_hash_lookup(GLOBAL_DCONTEXT, handlers,
                                                              annotation_name);
    if (handler != NULL && handler->receiver_list != NULL) {
        dr_annotation_receiver_t *receiver = handler->receiver_list;
        if (receiver->instrumentation.callback == callee) { /* case 1: remove the head */
            handler->receiver_list = receiver->next;
            HEAP_TYPE_FREE(GLOBAL_DCONTEXT, receiver, dr_annotation_receiver_t,
                           ACCT_OTHER, UNPROTECTED);
            found = true;
        } else { /* case 2: remove from within the list */
            while (receiver->next != NULL) {
                if (receiver->next->instrumentation.callback == callee) {
                    dr_annotation_receiver_t *removal = receiver->next;
                    receiver->next = removal->next;
                    HEAP_TYPE_FREE(GLOBAL_DCONTEXT, removal, dr_annotation_receiver_t,
                                   ACCT_OTHER, UNPROTECTED);
                    found = true;
                    break;
                }
                receiver = receiver->next;
            }
        } /* Leave the handler for the next registration (free it on exit) */
    }
    TABLE_RWLOCK(handlers, write, unlock);
    return found;
}

bool
dr_annotation_unregister_return(const char *annotation_name)
{
    bool found = false;
    dr_annotation_handler_t *handler;

    TABLE_RWLOCK(handlers, write, lock);
    handler = (dr_annotation_handler_t *) strhash_hash_lookup(GLOBAL_DCONTEXT, handlers,
                                                           annotation_name);
    if ((handler != NULL) && (handler->receiver_list != NULL)) {
        ASSERT(handler->receiver_list->next != NULL);
        HEAP_TYPE_FREE(GLOBAL_DCONTEXT, handler->receiver_list, dr_annotation_receiver_t,
                       ACCT_OTHER, UNPROTECTED);
        handler->receiver_list = NULL;
        found = true;
    } /* Leave the handler for the next registration (free it on exit) */
    TABLE_RWLOCK(handlers, write, unlock);
    return found;
}

bool
dr_annotation_unregister_valgrind(dr_valgrind_request_id_t request_id,
                                  ptr_uint_t (*annotation_callback)
                                  (dr_vg_client_request_t *request))
{
    bool found = false;
    dr_annotation_handler_t *handler;
    TABLE_RWLOCK(handlers, write, lock);
    handler = vg_handlers[request_id];
    if ((handler != NULL) && (handler->receiver_list != NULL)) {
        dr_annotation_receiver_t *receiver = handler->receiver_list;
        if (receiver->instrumentation.vg_callback == annotation_callback) {
            handler->receiver_list = receiver->next; /* case 1: remove the head */
            HEAP_TYPE_FREE(GLOBAL_DCONTEXT, receiver, dr_annotation_receiver_t,
                           ACCT_OTHER, UNPROTECTED);
            found = true;
        } else { /* case 2: remove from within the list */
            while (receiver->next != NULL) {
                if (receiver->next->instrumentation.vg_callback == annotation_callback) {
                    dr_annotation_receiver_t *removal = receiver->next;
                    receiver->next = removal->next;
                    HEAP_TYPE_FREE(GLOBAL_DCONTEXT, removal, dr_annotation_receiver_t,
                                   ACCT_OTHER, UNPROTECTED);
                    found = true;
                    break;
                }
                receiver = receiver->next;
            }
        } /* Leave the handler for the next registration (free it on exit) */
    }
    TABLE_RWLOCK(handlers, write, unlock);
    return found;
}

/*********************************************************
 * ANNOTATION IMPLEMENTATIONS
 */

#if !(defined (WINDOWS) && defined (X64))
static void
handle_vg_annotation(app_pc request_args)
{
    dcontext_t *dcontext = get_thread_private_dcontext();
    dr_valgrind_request_id_t request_id;
    dr_annotation_receiver_t *receiver;
    dr_vg_client_request_t request;
    ptr_uint_t result;

    if (!safe_read(request_args, sizeof(dr_vg_client_request_t), &request)) {
        LOG(THREAD, LOG_ANNOTATIONS, 2, "Failed to read Valgrind client request args at "
            PFX". Skipping the annotation.\n", request_args);
        return;
    }

    result = request.default_result;
    request_id = lookup_valgrind_request(request.request);
    if (request_id < DR_VG_ID__LAST) {
        TABLE_RWLOCK(handlers, read, lock);
        receiver = vg_handlers[request_id]->receiver_list;
        while (receiver != NULL) {
            result = receiver->instrumentation.vg_callback(&request);
            receiver = receiver->next;
        }
        TABLE_RWLOCK(handlers, read, unlock);
    } else {
        LOG(THREAD, LOG_ANNOTATIONS, 2,
            "Skipping unrecognized Valgrind client request id %d\n", request.request);
        return;
    }

    /* Put the result in %xdx where the target app expects to find it. */
# ifdef CLIENT_INTERFACE
    if (dcontext->client_data->mcontext_in_dcontext) {
        get_mcontext(dcontext)->xdx = result;
    } else
# endif
    {
        priv_mcontext_t *state = get_priv_mcontext_from_dstack(dcontext);
        state->xdx = result;
    }
}

static dr_valgrind_request_id_t
lookup_valgrind_request(ptr_uint_t request)
{
    switch (request) {
    case VG_USERREQ__RUNNING_ON_VALGRIND:
        return DR_VG_ID__RUNNING_ON_VALGRIND;
    case VG_USERREQ__MAKE_MEM_DEFINED_IF_ADDRESSABLE:
        return DR_VG_ID__MAKE_MEM_DEFINED_IF_ADDRESSABLE;
    case VG_USERREQ__DISCARD_TRANSLATIONS:
        return DR_VG_ID__DISCARD_TRANSLATIONS;
    }
    return DR_VG_ID__LAST;
}

static ptr_uint_t
valgrind_running_on_valgrind(dr_vg_client_request_t *request)
{
    return 1; /* Pretend to be Valgrind. */
}
#endif

/*********************************************************
 * INTERNAL ROUTINES
 */

/* If the app code at `*cur_pc` can be read as an encoded annotation label, then:
 *   (1) advance `*cur_pc` beyond the last label instruction,
 *   (2) point `**name` to the start of the label within the app image data section, and
 *   (3) return true.
 * If there is no annotation label at `*cur_pc`, or failure occurs while trying to read
 * it, then return false with undefined values for `*cur_pc` and `**name`.
 *
 * On Unix and Windows x86, the label has the form
 * "<annotation-label>:<return-type>:<annotation-name>, e.g.
 *
 *     "dynamorio-annotation:void:dynamorio_annotate_log"
 *     "dynamorio-annotation:const char *:some_custom_client_annotation"
 *
 * On Windows x64, the label has an additional token for the annotation type:
 * "<annotation-label>:<annotation-type>:<return-type>:<annotation-name>, e.g.
 *
 *     "dynamorio-annotation:statement:void:dynamorio_annotate_log"
 *     "dynamorio-annotation:expression:const char *:some_custom_client_annotation"
 *
 * The encoding of the pointer to the label varies by platform:
 *
 *   Unix expression annotation label (two instructions form <GOT-base> + <GOT-offset>):
 *
 *     mov $<GOT-base>,%xax
 *     bsr $<GOT-offset>,%xax
 *
 *   Windows x86 expression annotation label (direct pointer to the <label>):
 *
 *     mov $<label>,%eax
 *
 *   Windows x64 expression annotation label (same, in 2 variations):
 *
 *     mov $<label>,%rax      Or      prefetch $<label>
 *     prefetch %rax
 *
 *   Decoding the label pointer proceeds as follows:
 *
 *     (step 1) check `*cur_pc` for the opcode of the first label-encoding instruction
 *     (step 2) check the operand of that instruction for a label-encoding operand type
 *     Unix only--dereference the GOT entry:
 *         (step 3) check the next instruction for the label offset opcode (bsr or bsf)
 *         (step 4) check its operand for the offset-encoding operand type (base disp)
 *         (step 5) add the two operands and dereference as the label's GOT entry
 *     (step 6) attempt to read the decoded pointer and compare to "dynamorio-annotation"
 *              (note there is a special case for Windows x64, which is not inline asm)
 *     (step 7) if it matches, point `**name` to the character beyond the separator ':'
 *
 * See https://code.google.com/p/dynamorio/wiki/Annotations for complete examples.
 */
static inline bool
is_annotation_tag(dcontext_t *dcontext, IN OUT app_pc *cur_pc, instr_t *scratch,
                  OUT const char **name)
{
    app_pc start_pc = *cur_pc;

    instr_reset(dcontext, scratch);
    *cur_pc = decode(dcontext, *cur_pc, scratch);
    if (IS_ANNOTATION_LABEL_INSTR(scratch)) {                               /* step 1 */
        opnd_t src = instr_get_src(scratch, 0);
        if (IS_ANNOTATION_LABEL_REFERENCE(src)) {                           /* step 2 */
            char buf[DYNAMORIO_ANNOTATION_LABEL_LENGTH + 1/*nul*/];
            app_pc buf_ptr;
            app_pc opnd_ptr = GET_ANNOTATION_LABEL_REFERENCE(src, start_pc);
#ifdef UNIX
            app_pc got_ptr;
            instr_reset(dcontext, scratch);
            *cur_pc = decode(dcontext, *cur_pc, scratch);
            if (!IS_ANNOTATION_LABEL_GOT_OFFSET_INSTR(scratch))             /* step 3 */
                return false;
            src = instr_get_src(scratch, 0);
            if (!IS_ANNOTATION_LABEL_GOT_OFFSET_REFERENCE(src))             /* step 4 */
                return false;
            opnd_ptr += opnd_get_disp(src);                                 /* step 5 */
            if (!safe_read(opnd_ptr, sizeof(app_pc), &got_ptr))
                return false;
            opnd_ptr = got_ptr;
#endif
#if defined (WINDOWS) && defined (X64)
            /* In Windows x64, if the `prefetch` instruction was found at
             * `*cur_pc` with no intervening `mov` instruction, the label
             * pointer must be an immediate operand to that `prefetch`.
             */
            if (instr_get_opcode(scratch) == OP_prefetchw) {                /* step 6 */
                if (!safe_read(opnd_ptr, DYNAMORIO_ANNOTATION_LABEL_LENGTH, buf))
                    return false;
                buf[DYNAMORIO_ANNOTATION_LABEL_LENGTH] = '\0';
                if (strcmp(buf, DYNAMORIO_ANNOTATION_LABEL) == 0) {
                    *name = (const char *) (opnd_ptr +                      /* step 7 */
                                            DYNAMORIO_ANNOTATION_LABEL_LENGTH
                                            + 1); /* skip the separator ':' */
                    return true;
                }
            } /* else the label pointer is the usual `mov` operand: */
#endif
            if (!safe_read(opnd_ptr, sizeof(app_pc), &buf_ptr))             /* step 6 */
                return false;
            if (!safe_read(buf_ptr, DYNAMORIO_ANNOTATION_LABEL_LENGTH, buf))
                return false;
            buf[DYNAMORIO_ANNOTATION_LABEL_LENGTH] = '\0';
            if (strcmp(buf, DYNAMORIO_ANNOTATION_LABEL) != 0)
                return false;
            *name = (const char *) (buf_ptr +                               /* step 7 */
                                    DYNAMORIO_ANNOTATION_LABEL_LENGTH
                                    + 1); /* skip the separator ':' */
            return true;
        }
    }
    return false;
}

#if defined (WINDOWS) && defined (X64)
/* Identify the annotation at layout->start_pc, if any. On Windows x64, some flexibility
 * is required to recognize the annotation sequence because it is compiled instead of
 * explicitly inserted with inline asm (which is unavailable in MSVC for this platform).
 *   (step 1) check if the instruction at layout->start_pc encodes an annotation label.
 *   (step 2) decode arbitrary instructions up to a `prefetch`,
 *            following any direct branches decoded along the way.
 *   (step 3) skip the `int 3` following the `prefetch`.
 *   (step 4) set the resume pc, so execution resumes within the annotation body.
 *   (step 5) compare the next label token to determine the annotation type.
 *     Expression annotations only:
 *       (step 6) compare the return type to determine whether the annotation is void.
 *   (step 7) advance the label pointer to the name token
 *            (note that the Statement annotation concludes with a special case).
 */
static inline void
identify_annotation(dcontext_t *dcontext, IN OUT annotation_layout_t *layout,
                    instr_t *scratch)
{
    app_pc cur_pc = layout->start_pc, last_call = NULL;

    if (!is_annotation_tag(dcontext, &cur_pc, scratch, &layout->name))      /* step 1 */
        return;

    while (instr_get_opcode(scratch) != OP_prefetchw) {                     /* step 2 */
        if (instr_is_ubr(scratch))
            cur_pc = instr_get_branch_target_pc(scratch);
        instr_reset(dcontext, scratch);
        cur_pc = decode(dcontext, cur_pc, scratch);
    }

    ASSERT(*cur_pc == WINDOWS_X64_OPTIMIZATION_FENCE);                      /* step 3 */
    cur_pc++;
    layout->resume_pc = cur_pc;                                             /* step 4 */

    if (IS_ANNOTATION_STATEMENT_LABEL(layout->name)) {                      /* step 5 */
        layout->type = ANNOTATION_TYPE_STATEMENT;
        layout->name += (ANNOTATION_STATEMENT_LABEL_LENGTH + 1);
        layout->name = strchr(layout->name, ':') + 1;                       /* step 7 */
        /* If the target app contains an annotation whose argument is a function call that
         * gets inlined, and that function contains the same annotation, the compiler will
         * fuse the headers. See https://code.google.com/p/dynamorio/wiki/Annotations for
         * a sample of fused headers. This loop identifies and skips any fused headers.
         */
        while (true) {
            instr_reset(dcontext, scratch);
            cur_pc = decode(dcontext, cur_pc, scratch);
            if (IS_ANNOTATION_HEADER(scratch, cur_pc)) {
                cur_pc += INT_LENGTH;
                while (instr_get_opcode(scratch) != OP_prefetchw) {
                    if (instr_is_ubr(scratch))
                        cur_pc = instr_get_branch_target_pc(scratch);
                    instr_reset(dcontext, scratch);
                    cur_pc = decode(dcontext, cur_pc, scratch);
                }
                ASSERT(*cur_pc == WINDOWS_X64_OPTIMIZATION_FENCE);
                cur_pc++;
                layout->resume_pc = cur_pc;
            } else if (instr_is_cti(scratch))
                break;
        }
    } else {
        layout->type = ANNOTATION_TYPE_EXPRESSION;
        layout->name += (ANNOTATION_EXPRESSION_LABEL_LENGTH + 1);
        layout->is_void = IS_ANNOTATION_VOID(layout->name);                 /* step 6 */
        layout->name = strchr(layout->name, ':') + 1;                       /* step 7 */
    }
}
#else /* Windows x86 and all Unix  */
/* Identify the annotation at layout->start_pc, if any. In summary:
 *   (step 1) check if the instruction at layout->start_pc encodes an annotation label.
 *   (step 2) determine the annotation type based on instruction opcodes
 *     Expression annotations only:
 *       (step 3) compare the return type to determine whether the annotation is void.
 *   (step 4) adjust the substitution xl8 to the current pc.
 *   (step 5) decode past the jump over the annotation body.
 *   (step 6) set the resume pc to the current instruction, which is a jump over the
 *            native version of the annotation body (specified by the target app).
 *   (step 7) advance the label pointer to the name token.
 */
static inline void
identify_annotation(dcontext_t *dcontext, IN OUT annotation_layout_t *layout,
                    instr_t *scratch)
{
    app_pc cur_pc = layout->start_pc;
    if (is_annotation_tag(dcontext, &cur_pc, scratch, &layout->name)) {     /* step 1 */
# ifdef WINDOWS
        if (*(cur_pc++) == RAW_OPCODE_pop_eax) {                            /* step 2 */
# else
        if (instr_get_opcode(scratch) == OP_bsf) {                          /* step 2 */
# endif
            layout->type = ANNOTATION_TYPE_STATEMENT;
        } else {
            layout->type = ANNOTATION_TYPE_EXPRESSION;
            layout->is_void = IS_ANNOTATION_VOID(layout->name);             /* step 3 */
        }
        layout->substitution_xl8 = cur_pc;                                  /* step 4 */
        instr_reset(dcontext, scratch);
        cur_pc = decode_cti(dcontext, cur_pc, scratch);                     /* step 5 */
        ASSERT(instr_is_ubr(scratch));
        layout->resume_pc = cur_pc;                                         /* step 6 */
        layout->name = strchr(layout->name, ':') + 1;                       /* step 7 */
    }
}
#endif

#ifdef X64
# ifdef UNIX
static inline void /* UNIX x64 */
create_arg_opnds(dr_annotation_handler_t *handler, uint num_args,
                 dr_annotation_calling_convention_t call_type)
{
    uint i, arg_stack_location;
    ASSERT(call_type == DR_ANNOTATION_CALL_TYPE_FASTCALL); /* architecture constraint */
    switch (num_args) { /* Create up to six register args */
    default:
    case 6:
        handler->args[5] = opnd_create_reg(DR_REG_R9);
    case 5:
        handler->args[4] = opnd_create_reg(DR_REG_R8);
    case 4:
        handler->args[3] = opnd_create_reg(DR_REG_XCX);
    case 3:
        handler->args[2] = opnd_create_reg(DR_REG_XDX);
    case 2:
        handler->args[1] = opnd_create_reg(DR_REG_XSI);
    case 1:
        handler->args[0] = opnd_create_reg(DR_REG_XDI);
    }
    /* Create the remaining args on the stack */
    for (i = FASTCALL_REGISTER_ARG_COUNT; i < num_args; i++) {
        /* The clean call will appear at the top of the annotation function body, where
         * the stack arguments follow the return address and the caller's saved stack
         * pointer. Rewind `i` to 0 and add 2 to skip over these pointers.
         */
        arg_stack_location = sizeof(ptr_uint_t) * (i-FASTCALL_REGISTER_ARG_COUNT+2);
        /* Use the stack pointer because the base pointer is a general register in x64 */
        handler->args[i] = OPND_CREATE_MEMPTR(DR_REG_XSP, arg_stack_location);
    }
}
# else /* WINDOWS x64 */
static inline void
create_arg_opnds(dr_annotation_handler_t *handler, uint num_args,
                 dr_annotation_calling_convention_t call_type)
{
    uint i, arg_stack_location;
    ASSERT(call_type == DR_ANNOTATION_CALL_TYPE_FASTCALL); /* architecture constraint */
    switch (num_args) { /* Create up to four register args */
    default:
    case 4:
        handler->args[3] = opnd_create_reg(DR_REG_R9);
    case 3:
        handler->args[2] = opnd_create_reg(DR_REG_R8);
    case 2:
        handler->args[1] = opnd_create_reg(DR_REG_XDX);
    case 1:
        handler->args[0] = opnd_create_reg(DR_REG_XCX);
    }
    /* Create the remaining args on the stack */
    for (i = FASTCALL_REGISTER_ARG_COUNT; i < num_args; i++) {
        /* The clean call will appear at the top of the annotation function body, where
         * the stack arguments follow the return address and 32 bytes of empty space.
         * Since `i` is already starting at 4, just add one more to reach the args.
         */
        arg_stack_location = sizeof(ptr_uint_t) * (i+1);
        /* Use the stack pointer because the base pointer is a general register in x64 */
        handler->args[i] = OPND_CREATE_MEMPTR(DR_REG_XSP, arg_stack_location);
    }
}
# endif
#else /* x86 (all) */
static inline void
create_arg_opnds(dr_annotation_handler_t *handler, uint num_args,
                 dr_annotation_calling_convention_t call_type)
{
    uint i, arg_stack_location;
    if (call_type == DR_ANNOTATION_CALL_TYPE_FASTCALL) {
        switch (num_args) { /* Create 1 or 2 register args */
        default:
        case 2:
            handler->args[1] = opnd_create_reg(DR_REG_XDX);
        case 1:
            handler->args[0] = opnd_create_reg(DR_REG_XCX);
        }
        /* Create the remaining args on the stack */
        for (i = FASTCALL_REGISTER_ARG_COUNT; i < num_args; i++) {
            /* The clean call will appear at the top of the annotation function body,
             * where the stack args follow the return address and the caller's saved base
             * pointer. Since `i` already starts at 2, use it to skip those pointers.
             */
            arg_stack_location = sizeof(ptr_uint_t) * i;
            handler->args[i] = OPND_CREATE_MEMPTR(DR_REG_XBP, arg_stack_location);
        }
    } else { /* DR_ANNOTATION_CALL_TYPE_STDCALL: Create all args on the stack */
        for (i = 0; i < num_args; i++) {
            /* The clean call will appear at the top of the annotation function body,
             * where the stack args follow the return address and the caller's saved base
             * pointer. Since `i` starts at 0, add 2 to skip those pointers.
             */
            arg_stack_location = sizeof(ptr_uint_t) * (i+2);
            handler->args[i] = OPND_CREATE_MEMPTR(DR_REG_XBP, arg_stack_location);
        }
    }
}
#endif

#ifdef DEBUG
static ssize_t
annotation_printf(const char *format, ...)
{
    va_list ap;
    ssize_t count;
    const char *timestamp_token_start;
    char *timestamped_format = NULL;
    uint buffer_length = 0;

    if (stats == NULL || stats->loglevel == 0)
        return 0; /* No log is available for writing. */
    if ((stats->logmask & LOG_VIA_ANNOTATIONS) == 0)
        return 0; /* Filtered out by the user. */

    /* Substitute the first instance of the timestamp token with a timestamp string.
     * Additional timestamp tokens will be ignored, because it would be pointless.
     */
    timestamp_token_start = strstr(format, LOG_ANNOTATION_TIMESTAMP_TOKEN);
    if (timestamp_token_start != NULL) {
        char timestamp_buffer[PRINT_TIMESTAMP_MAX_LENGTH];
        buffer_length = (uint) (strlen(format) + PRINT_TIMESTAMP_MAX_LENGTH);
        if (print_timestamp_to_buffer(timestamp_buffer, PRINT_TIMESTAMP_MAX_LENGTH) > 0) {
            uint length_before_token =
                (uint)((ptr_uint_t) timestamp_token_start - (ptr_uint_t) format);
            /* print the timestamped format string into this heap buffer */
            timestamped_format = HEAP_ARRAY_ALLOC(GLOBAL_DCONTEXT, char, buffer_length,
                                                  ACCT_OTHER, UNPROTECTED);

            /* copy the original format string up to the timestamp token */
            our_snprintf(timestamped_format, length_before_token, "%s", format);
            /* copy the timestamp and the remainder of the original format string */
            our_snprintf(timestamped_format + length_before_token,
                         (buffer_length - length_before_token), "%s%s", timestamp_buffer,
                         timestamp_token_start + LOG_ANNOTATION_TIMESTAMP_TOKEN_LENGTH);
            /* use the timestamped format string */
            format = (const char *) timestamped_format;
        } else {
            LOG(GLOBAL, LOG_ANNOTATIONS, 2, "Failed to obtain a system timestamp for "
                "substitution in annotation log statements '%s'\n", format);
        }
    }

    va_start(ap, format);
    count = do_file_write(GLOBAL, format, ap);
    va_end(ap);
    if (timestamped_format != NULL) { /* free the timestamp heap buffer, if any */
        HEAP_ARRAY_FREE(GLOBAL_DCONTEXT, format, char, buffer_length,
                        ACCT_OTHER, UNPROTECTED);
    }
    return count;
}
#endif

static void
free_annotation_handler(void *p)
{
    dr_annotation_handler_t *handler = (dr_annotation_handler_t *) p;
    dr_annotation_receiver_t *next, *receiver = handler->receiver_list;
    while (receiver != NULL) {
        next = receiver->next;
        HEAP_TYPE_FREE(GLOBAL_DCONTEXT, receiver, dr_annotation_receiver_t,
                       ACCT_OTHER, UNPROTECTED);
        receiver = next;
    }
    if (handler->num_args > 0) {
        HEAP_ARRAY_FREE(GLOBAL_DCONTEXT, handler->args, opnd_t, handler->num_args,
                        ACCT_OTHER, UNPROTECTED);
    }
    if ((handler->type == DR_ANNOTATION_HANDLER_CALL) ||
        (handler->type == DR_ANNOTATION_HANDLER_RETURN_VALUE))
        dr_strfree(handler->symbol_name HEAPACCT(ACCT_OTHER));
    HEAP_TYPE_FREE(GLOBAL_DCONTEXT, p, dr_annotation_handler_t, ACCT_OTHER, UNPROTECTED);
}

#endif /* ANNOTATIONS */
