/* **********************************************************
 * Copyright (c) 2021-2023 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 Google, 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 GOOGLE, 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.
 */

/* Illustrates using the drcallstack extension.
 *
 * The drcallstack extension only supports Linux in this release.
 * This sample wraps malloc and every time it's called it symbolizes and
 * prints the callstack.
 */

#include "dr_api.h"
#include "drmgr.h"
#include "drwrap.h"
#include "drcallstack.h"
#include "drsyms.h"
#include "droption.h"
#include <string>

namespace dynamorio {
namespace samples {
namespace {

using ::dynamorio::droption::DROPTION_SCOPE_CLIENT;
using ::dynamorio::droption::droption_t;

static droption_t<std::string> trace_function(
    DROPTION_SCOPE_CLIENT, "trace_function", "malloc", "Name of function to trace",
    "The name of the function to wrap and print callstacks on every call.");

static void
print_qualified_function_name(app_pc pc)
{
    module_data_t *mod = dr_lookup_module(pc);
    if (mod == NULL) {
        // If we end up in assembly code or generated code we'll likely never
        // get out again without stack scanning or frame pointer walking or
        // other strategies not yet part of drcallstack.
        dr_fprintf(STDERR, "  <unknown module> @%p\n", pc);
        return;
    }
    drsym_info_t sym_info;
#define MAX_FUNC_LEN 1024
    char name[MAX_FUNC_LEN];
    char file[MAXIMUM_PATH];
    sym_info.struct_size = sizeof(sym_info);
    sym_info.name = name;
    sym_info.name_size = MAX_FUNC_LEN;
    sym_info.file = file;
    sym_info.file_size = MAXIMUM_PATH;
    const char *func = "<unknown>";
    drsym_error_t sym_res =
        drsym_lookup_address(mod->full_path, pc - mod->start, &sym_info, DRSYM_DEMANGLE);
    if (sym_res == DRSYM_SUCCESS)
        func = sym_info.name;
    dr_fprintf(STDERR, "  %s!%s\n", dr_module_preferred_name(mod), func);
    dr_free_module_data(mod);
}

static void
wrap_pre(void *wrapcxt, DR_PARAM_OUT void **user_data)
{
    dr_fprintf(STDERR, "%s called from:\n", trace_function.get_value().c_str());
    // Get the context.  The pc field is set by drwrap to the wrapped function
    // entry point.
    dr_mcontext_t *mc = drwrap_get_mcontext(wrapcxt);
    // Walk the callstack.
    drcallstack_walk_t *walk;
    drcallstack_status_t res = drcallstack_init_walk(mc, &walk);
    DR_ASSERT(res == DRCALLSTACK_SUCCESS);
    drcallstack_frame_t frame = {
        sizeof(frame),
    };
    int count = 0;
    print_qualified_function_name(drwrap_get_func(wrapcxt));
    do {
        res = drcallstack_next_frame(walk, &frame);
        if (res != DRCALLSTACK_SUCCESS)
            break;
        print_qualified_function_name(frame.pc);
        ++count;
    } while (res == DRCALLSTACK_SUCCESS);
    // The return value DRCALLSTACK_NO_MORE_FRAMES indicates a complete callstack.
    // Anything else indicates some kind of unwind info error.
    // If this code were used inside a larger tool it would be up to that tool
    // whether to record or act on the callstack quality.
    res = drcallstack_cleanup_walk(walk);
    DR_ASSERT(res == DRCALLSTACK_SUCCESS);
}

static void
module_load_event(void *drcontext, const module_data_t *mod, bool loaded)
{
    size_t modoffs;
    drsym_error_t sym_res = drsym_lookup_symbol(
        mod->full_path, trace_function.get_value().c_str(), &modoffs, DRSYM_DEMANGLE);
    if (sym_res == DRSYM_SUCCESS) {
        app_pc towrap = mod->start + modoffs;
        bool ok = drwrap_wrap(towrap, wrap_pre, NULL);
        DR_ASSERT(ok);
        dr_fprintf(STDERR, "wrapping %s!%s\n", mod->full_path,
                   trace_function.get_value().c_str());
    }
}

static void
module_unload_event(void *drcontext, const module_data_t *mod)
{
    size_t modoffs;
    drsym_error_t sym_res = drsym_lookup_symbol(
        mod->full_path, trace_function.get_value().c_str(), &modoffs, DRSYM_DEMANGLE);
    if (sym_res == DRSYM_SUCCESS) {
        app_pc towrap = mod->start + modoffs;
        bool ok = drwrap_unwrap(towrap, wrap_pre, NULL);
        DR_ASSERT(ok);
    }
}

static void
event_exit()
{
    drmgr_register_module_unload_event(module_unload_event);
    drcallstack_exit();
    drwrap_exit();
    drsym_exit();
}

} // namespace
} // namespace samples
} // namespace dynamorio

DR_EXPORT void
dr_client_main(client_id_t id, int argc, const char *argv[])
{
    dr_set_client_name("DynamoRIO Sample Client 'callstack'",
                       "http://dynamorio.org/issues");
    // Parse our option.
    if (!dynamorio::droption::droption_parser_t::parse_argv(
            dynamorio::droption::DROPTION_SCOPE_CLIENT, argc, argv, NULL, NULL))
        DR_ASSERT(false);
    drcallstack_options_t ops = {
        sizeof(ops),
    };
    // Initialize the libraries we're using.
    if (!drwrap_init() || drcallstack_init(&ops) != DRCALLSTACK_SUCCESS ||
        drsym_init(0) != DRSYM_SUCCESS ||
        !drmgr_register_module_load_event(dynamorio::samples::module_load_event))
        DR_ASSERT(false);
    drmgr_register_exit_event(dynamorio::samples::event_exit);
    // Improve performance as we only need basic wrapping support.
    drwrap_set_global_flags(
        static_cast<drwrap_global_flags_t>(DRWRAP_NO_FRILLS | DRWRAP_FAST_CLEANCALLS));
}
