blob: 61908416d319f600389cf527e473711d7e38b51a [file] [log] [blame]
/* **********************************************************
* Copyright (c) 2012-2022 Google, Inc. All rights reserved.
* Copyright (c) 2003-2009 VMware, 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.
*/
/* Copyright (c) 2003-2007 Determina Corp. */
/*
* options.h
*
* options struct and prototypes from options.c
* for use with core and gui/nm
*/
#ifndef _OPTIONS_H_
#define _OPTIONS_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "options_struct.h"
/* For default integer values we use an enum, while for default string values we
* use the default_options struct instance that is already being used
* for option parsing, and a second one for internal options when !INTERNAL
*/
extern const options_t default_options;
#ifndef EXPOSE_INTERNAL_OPTIONS
/* only needs to contain string options, but no compile-time way to
* do that without having OPTION_COMMAND_INTERNAL_STRING()!
*/
extern const internal_options_t default_internal_options;
#endif
#define IS_OPTION_INTERNAL(name) (OPTION_IS_INTERNAL_##name)
#define IS_OPTION_STRING(name) (OPTION_IS_STRING_##name)
/* FIXME : figure out a way to handle types here so that we don't have to cast
* strings to ints to avoid compiler warnings */
#define DEFAULT_OPTION_VALUE(name) \
(IS_OPTION_STRING(name) ? (int)default_options.name : OPTION_DEFAULT_VALUE_##name)
#ifdef EXPOSE_INTERNAL_OPTIONS
# define DEFAULT_INTERNAL_OPTION_VALUE DEFAULT_OPTION_VALUE
#else
# define DEFAULT_INTERNAL_OPTION_VALUE(name) \
(IS_OPTION_STRING(name) ? default_internal_options.name \
: OPTION_DEFAULT_VALUE_##name)
#endif
/* for non-internal builds we don't support setting the default value
* since they are all constants
*/
#define SET_DEFAULT_VALUE(name) (dynamo_options.name = DEFAULT_OPTION_VALUE(name))
/* checks for incompatible option values */
/* max==0 means no max and 0 is an ok value */
/* if option is incompatible, will try to touch up the option
* by assigning min to make it valid returns true if changed the
* option value
*/
bool
check_param_bounds(ptr_uint_t *val, ptr_uint_t min, ptr_uint_t max, const char *name);
int
options_init(void);
/* Only frees a lock: does not destroy any options info other exit routines
* might need (due to orderings during exit). See options_detach for resetting
* options back to defaults for static re-attach.
*/
void
options_exit(void);
/* Resets options to default values for the purpose of a full cleanup
* during static detach. It is called after nearly all other cleanup has
* occurred.
*/
void
options_detach(void);
int
synchronize_dynamic_options(void);
#ifdef WINDOWS
const options_t *
get_process_options(HANDLE process_handle);
#endif
/*
* if minimal then the options string only contains values different than
* the defaults, otherwise it explicitly lists all options being used
*/
void
get_dynamo_options_string(options_t *options, char *opstr, int len, bool minimal);
/* Fills opstr with a minimal string of only
* persistent-cache-affecting options whose effect is >= pcache_effect
* and that are different from the defaults.
*/
void
get_pcache_dynamo_options_string(options_t *options, char *opstr, int len,
op_pcache_t pcache_effect);
bool
has_pcache_dynamo_options(options_t *options, op_pcache_t pcache_effect);
char *
d_r_parse_word(const char *str, const char **strpos, char *wordbuf, uint wordbuflen);
void
options_enable_code_api_dependences(options_t *options);
/****************************************************************************/
#ifdef NOT_DYNAMORIO_CORE
void
set_dynamo_options_defaults(options_t *options);
int
set_dynamo_options(options_t *options, const char *optstr);
#else /* !NOT_DYNAMORIO_CORE */
# include "utils.h"
/* are any fragments (potentially) shared? */
# define SHARED_FRAGMENTS_ENABLED() \
(DYNAMO_OPTION(shared_bbs) || DYNAMO_OPTION(shared_traces))
/* PR 244737: for x64 we use a "unified" scheme were thread-shared and
* thread-private code always uses TLS for scratch space, eliminating
* reachability issues. We require -private_ib_in_tls for x64 as well
* as for SHARED_FRAGMENTS_ENABLED and use that option to also
* cover non-ib scratch space.
*/
# define SCRATCH_ALWAYS_TLS() (DYNAMO_OPTION(private_ib_in_tls))
/* are any traces (potentially) private? */
/* FIXME Fix this if we permit private & shared traces to co-exist */
# define PRIVATE_TRACES_ENABLED() \
(!DYNAMO_OPTION(disable_traces) && !DYNAMO_OPTION(shared_traces))
/* are shared BBs ibl targets? */
# define SHARED_BB_IB_TARGETS() \
(DYNAMO_OPTION(shared_bbs) && DYNAMO_OPTION(bb_ibl_targets))
/* What this answers is
* "Are only shared BBs being created and are they valid IB targets?"
* It's used when a client wants to know if shared BBs are the only
* possible IB targets. So, for example, this is false whenever trace
* building is active, even if traces are not being added to the
* lookup tables.
*/
# define SHARED_BB_ONLY_IB_TARGETS() \
(SHARED_BB_IB_TARGETS() && DYNAMO_OPTION(disable_traces))
/* are any shared fragments ibl targets? */
# define SHARED_IB_TARGETS() (DYNAMO_OPTION(shared_traces) || SHARED_BB_IB_TARGETS())
/* are any IBT tables (potentially) shared? */
# define SHARED_IBT_TABLES_ENABLED() \
(DYNAMO_OPTION(shared_bb_ibt_tables) || DYNAMO_OPTION(shared_trace_ibt_tables))
# define TRACEDUMP_ENABLED() \
(!DYNAMO_OPTION(disable_traces) && \
(INTERNAL_OPTION(tracedump_text) || INTERNAL_OPTION(tracedump_binary) || \
INTERNAL_OPTION(tracedump_origins)))
# define RUNNING_WITHOUT_CODE_CACHE() \
(IF_HOTP(DYNAMO_OPTION(hotp_only) ||) DYNAMO_OPTION(thin_client))
# ifndef NOT_DYNAMORIO_CORE_PROPER
# define CLIENT_OR_STANDALONE() (standalone_library || CLIENTS_EXIST())
# else
# define CLIENT_OR_STANDALONE() false
# endif
extern char d_r_option_string[];
extern read_write_lock_t options_lock;
/* check for empty is considered safe w/o the read lock
* this takes the field name only, and not {DYNAMO,INTERNAL}_OPTION macro,
* since those macros will ASSERT_OWN_READWRITE_LOCK(<is_stringtype>, &options_lock)
*/
# define IS_STRING_OPTION_EMPTY(op) ((dynamo_options.op)[0] == '\0')
/* single character check for ALL is considered safe w/o the read lock
* similarly to IS_STRING_OPTION_EMPTY see above
*/
# define IS_LISTSTRING_OPTION_FORALL(op) ((dynamo_options.op)[0] == '*')
# ifdef EXPOSE_INTERNAL_OPTIONS
# define IS_INTERNAL_STRING_OPTION_EMPTY(op) IS_STRING_OPTION_EMPTY(op)
# else
# define IS_INTERNAL_STRING_OPTION_EMPTY(op) \
((default_internal_options.op)[0] == '\0')
# endif
# ifdef STATIC_LIBRARY
/* For our static model, we enable -code_api and assume that client code could
* be run at any time, even if there's no dr_init.
*/
# define CLIENTS_EXIST() true
# else
# define CLIENTS_EXIST() (!IS_INTERNAL_STRING_OPTION_EMPTY(client_lib))
# endif
/* 0=ret => 1, 1=call* => 2, 2=jmp* => 4 */
# define COARSE_FILL_IBL_MASK(branch_type) (1 << (branch_type))
/* full access to string requires read lock */
static inline void
string_option_read_lock()
{
d_r_read_lock(&options_lock);
}
static inline void
string_option_read_unlock()
{
d_r_read_unlock(&options_lock);
}
typedef enum {
LIST_NO_MATCH = 0, /* ensure can use as bool */
LIST_ON_DEFAULT = 1,
LIST_ON_APPEND = 2,
} list_default_or_append_t;
/* compare short_name, usually module name, against a list option of the combined
* default option (that could be overridden) and append list that is usually used
*/
list_default_or_append_t
check_list_default_and_append(liststring_t default_list, liststring_t append_list,
const char *short_name);
void
options_make_writable(void);
void
options_restore_readonly(void);
#endif /* !NOT_DYNAMORIO_CORE */
#ifdef __cplusplus
}
#endif
#endif /* _OPTIONS_H_ */