* Copyright (c) 2011-2020 Google, Inc. All rights reserved.
* Copyright (c) 2008-2010 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.
*/
#ifndef MODULE_H
#define MODULE_H
#define OS_IMAGE_READ (MEMPROT_READ)
#define OS_IMAGE_WRITE (MEMPROT_WRITE)
#define OS_IMAGE_EXECUTE (MEMPROT_EXEC)
* it we go ahead and store info on each segment whether contiguous or not.
*/
typedef struct _module_segment_t {
app_pc start;
app_pc end;
uint prot;
bool shared;
uint64 offset;
} module_segment_t;
typedef struct _os_module_data_t {
* the lowest p_vaddr value for a PT_LOAD segment. One then obtains the base
* address by truncating the memory load address to the nearest multiple of the
* maximum page size and subtracting the truncated lowest p_vaddr value.
* Thus, this is not the load address but the base address used in
* address references within the file.
*/
app_pc base_address;
* not a requirement for ELF. To allow a different alignment for each segment we will
* need to move this field in the module_segment_t struct.
*/
size_t alignment;
size_t checksum;
size_t timestamp;
#ifdef LINUX
* using elf types here to avoid having to export those.
*/
bool have_dynamic_info;
bool hash_is_gnu;
app_pc hashtab;
size_t num_buckets;
app_pc buckets;
size_t num_chain;
app_pc chain;
app_pc dynsym;
app_pc dynstr;
size_t dynstr_size;
size_t symentry_size;
bool has_runpath;
app_pc gnu_bitmask;
ptr_uint_t gnu_shift;
ptr_uint_t gnu_bitidx;
size_t gnu_symbias;
#else
byte *exports;
size_t exports_sz;
byte *symtab;
uint num_syms;
byte *strtab;
size_t strtab_sz;
bool in_shared_cache;
uint current_version;
uint compatibility_version;
byte uuid[16];
#endif
bool contiguous;
uint num_segments;
uint alloc_segments;
module_segment_t *segments;
} os_module_data_t;
app_pc
module_entry_point(app_pc base, ptr_int_t load_delta);
bool
module_is_header(app_pc base, size_t size );
bool
module_is_executable(app_pc base);
bool
module_is_partial_map(app_pc base, size_t size, uint memprot);
bool
module_walk_program_headers(app_pc base, size_t view_size, bool at_map, bool dyn_reloc,
app_pc *out_base,
app_pc *out_first_end,
app_pc *out_max_end, char **out_soname,
os_module_data_t *out_data);
uint
module_num_program_headers(app_pc base);
void
os_module_update_dynamic_info(app_pc base, size_t size, bool at_map);
bool
module_file_has_module_header(const char *filename);
bool
module_file_is_module64(file_t f, bool *is64 OUT, bool *also32 OUT);
* returned in "platform" and the 2nd one in "alt_platform".
*/
bool
module_get_platform(file_t f, dr_platform_t *platform, dr_platform_t *alt_platform);
void
module_add_segment_data(OUT os_module_data_t *out_data, uint num_segments ,
app_pc segment_start, size_t segment_size, uint segment_prot,
size_t alignment, bool shared, uint64 offset);
#if defined(MACOS) || defined(ANDROID)
typedef FILE stdfile_t;
# define STDFILE_FILENO _file
#elif defined(LINUX)
typedef struct _IO_FILE stdfile_t;
# ifdef __GLIBC__
# define STDFILE_FILENO _fileno
# endif
#endif
extern stdfile_t **privmod_stdout;
extern stdfile_t **privmod_stderr;
extern stdfile_t **privmod_stdin;
app_pc
get_private_library_address(app_pc modbase, const char *name);
bool
get_private_library_bounds(IN app_pc modbase, OUT byte **start, OUT byte **end);
#ifdef MACOS
byte *
module_dynamorio_lib_base(void);
bool
module_dyld_shared_region(app_pc *start OUT, app_pc *end OUT);
void
module_walk_dyld_list(app_pc dyld_base);
#endif
#endif