Build omnitrace-rt library (#355)

* Build omnitrace-rt library

- Explicitly build dyninstAPI_RT as omnitrace-rt so that the SONAME in the ELF is omnitrace-rt instead of dyninstAPI_RT
- Create symbolic link lib/omnitrace/libdyninstAPI_RT.so which points to lib/libomnitrace-rt.so
- Simplify build tree location of libomnitrace-rt.so since it is ../lib from the bin directory even in the build tree
- Update dyninst submodule with minor tweaks to dyninstAPI_RT/CMakeLists.txt

* Update source/lib/omnitrace-rt/cmake/platform.cmake

* Use ftpmirror.gnu.org instead of ftp.gnu.org

- in timemory and dyninst submodules
- minor .clang-tidy tweak

[ROCm/rocprofiler-systems commit: 0cf017251e]
이 커밋은 다음에 포함됨:
Jonathan R. Madsen
2024-06-27 16:51:43 -05:00
커밋한 사람 GitHub
부모 65f46fde8c
커밋 8ad58c5d28
57개의 변경된 파일7652개의 추가작업 그리고 81개의 파일을 삭제
+1
파일 보기
@@ -23,6 +23,7 @@ performance-*,\
readability-*,\
-readability-function-size,\
-readability-identifier-naming,\
-readability-identifier-length,\
-readability-implicit-bool-cast,\
-readability-inconsistent-declaration-parameter-name,\
-readability-named-parameter,\
+1 -40
파일 보기
@@ -291,6 +291,7 @@ if(OMNITRACE_BUILD_DYNINST)
set(DYNINST_OPTION_PREFIX ON)
set(DYNINST_BUILD_DOCS OFF)
set(DYNINST_BUILD_RTLIB OFF)
set(DYNINST_QUIET_CONFIG
ON
CACHE BOOL "Suppress dyninst cmake messages")
@@ -344,7 +345,6 @@ if(OMNITRACE_BUILD_DYNINST)
dynDwarf
dynElf
dyninstAPI
dyninstAPI_RT
instructionAPI
parseAPI
patchAPI
@@ -360,9 +360,6 @@ if(OMNITRACE_BUILD_DYNINST)
endif()
endforeach()
omnitrace_install_tpl(dyninstAPI_RT omnitrace-rt
"${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}" core)
# for packaging
install(
DIRECTORY ${DYNINST_TPL_STAGING_PREFIX}/lib/
@@ -373,35 +370,11 @@ if(OMNITRACE_BUILD_DYNINST)
target_link_libraries(omnitrace-dyninst INTERFACE Dyninst::Dyninst)
set(OMNITRACE_DYNINST_API_RT
${PROJECT_BINARY_DIR}/external/dyninst/dyninstAPI_RT/libdyninstAPI_RT${CMAKE_SHARED_LIBRARY_SUFFIX}
)
if(OMNITRACE_DYNINST_API_RT)
omnitrace_target_compile_definitions(
omnitrace-dyninst
INTERFACE
DYNINST_API_RT="${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}:$<TARGET_FILE_DIR:Dyninst::dyninstAPI_RT>:${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/$<TARGET_FILE_NAME:Dyninst::dyninstAPI_RT>:$<TARGET_FILE:Dyninst::dyninstAPI_RT>"
)
endif()
else()
find_package(Dyninst ${omnitrace_FIND_QUIETLY} REQUIRED
COMPONENTS dyninstAPI parseAPI instructionAPI symtabAPI)
if(TARGET Dyninst::Dyninst) # updated Dyninst CMake system was found
# useful for defining the location of the runtime API
find_library(
OMNITRACE_DYNINST_API_RT dyninstAPI_RT
HINTS ${Dyninst_ROOT_DIR} ${Dyninst_DIR}
PATHS ${Dyninst_ROOT_DIR} ${Dyninst_DIR}
PATH_SUFFIXES lib NO_CACHE)
if(OMNITRACE_DYNINST_API_RT)
omnitrace_target_compile_definitions(
omnitrace-dyninst INTERFACE DYNINST_API_RT="${OMNITRACE_DYNINST_API_RT}")
endif()
target_link_libraries(omnitrace-dyninst INTERFACE Dyninst::Dyninst)
else() # updated Dyninst CMake system was not found
set(_BOOST_COMPONENTS atomic system thread date_time)
@@ -424,13 +397,6 @@ else()
PATH_SUFFIXES include)
endif()
# useful for defining the location of the runtime API
find_library(
OMNITRACE_DYNINST_API_RT dyninstAPI_RT
HINTS ${Dyninst_ROOT_DIR} ${Dyninst_DIR}
PATHS ${Dyninst_ROOT_DIR} ${Dyninst_DIR}
PATH_SUFFIXES lib)
# try to find TBB
find_package(TBB QUIET)
@@ -447,11 +413,6 @@ else()
PATH_SUFFIXES include)
endif()
if(OMNITRACE_DYNINST_API_RT)
omnitrace_target_compile_definitions(
omnitrace-dyninst INTERFACE DYNINST_API_RT="${OMNITRACE_DYNINST_API_RT}")
endif()
target_link_libraries(omnitrace-dyninst INTERFACE ${DYNINST_LIBRARIES}
${Boost_LIBRARIES})
foreach(
서브모듈 projects/rocprofiler-systems/external/dyninst 업데이트됨: d3ab0a71e9...dedad14f55
서브모듈 projects/rocprofiler-systems/external/timemory 업데이트됨: 227559ad27...86d2d12a8b
+2
파일 보기
@@ -45,6 +45,8 @@ if(OMNITRACE_BUILD_DYNINST)
target_compile_definitions(omnitrace-instrument PRIVATE OMNITRACE_BUILD_DYNINST=1)
endif()
add_target_flag_if_avail(omnitrace-instrument "-Wno-deprecated-declarations")
omnitrace_strip_target(omnitrace-instrument)
if(CMAKE_BUILD_TYPE MATCHES "^(DEBUG|Debug)")
@@ -22,6 +22,7 @@
#include "omnitrace-instrument.hpp"
#include "common/defines.h"
#include "common/join.hpp"
#include "dl/dl.hpp"
#include "fwd.hpp"
#include "internal_libs.hpp"
@@ -187,18 +188,26 @@ strset_t print_formats = { "txt", "json
std::string modfunc_dump_dir = {};
auto regex_opts = std::regex_constants::egrep | std::regex_constants::optimize;
strvec_t lib_search_paths =
tim::delimit(JOIN(':', tim::get_env<std::string>("DYNINSTAPI_RT_LIB"),
tim::get_env<std::string>("DYNINST_REWRITER_PATHS"),
tim::get_env<std::string>("LD_LIBRARY_PATH")),
":");
std::string
get_internal_libpath()
{
auto _exe = std::string_view{ ::realpath("/proc/self/exe", nullptr) };
auto _pos = _exe.find_last_of('/');
auto _dir = std::string{ "./" };
if(_pos != std::string_view::npos) _dir = _exe.substr(0, _pos);
return omnitrace::common::join("/", _dir, "..", "lib");
}
strvec_t lib_search_paths = tim::delimit(
JOIN(':', get_internal_libpath(), tim::get_env<std::string>("DYNINSTAPI_RT_LIB"),
tim::get_env<std::string>("DYNINST_REWRITER_PATHS"),
tim::get_env<std::string>("LD_LIBRARY_PATH")),
":");
strvec_t bin_search_paths = tim::delimit(tim::get_env<std::string>("PATH"), ":");
#if defined(DYNINST_API_RT)
auto _dyn_api_rt_paths = tim::delimit(DYNINST_API_RT, ":");
#else
auto _dyn_api_rt_paths = std::vector<std::string>{};
#endif
auto _dyn_api_rt_paths = tim::delimit(
JOIN(":", get_internal_libpath(), JOIN("/", get_internal_libpath(), "omnitrace")),
":");
std::string
get_absolute_filepath(std::string _name, const strvec_t& _paths);
+1 -11
파일 보기
@@ -16,16 +16,6 @@ function(OMNITRACE_ADD_BIN_TEST)
if(NOT TEST_WORKING_DIRECTORY)
set(TEST_WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
endif()
if(NOT OMNITRACE_DYNINST_API_RT_DIR AND OMNITRACE_DYNINST_API_RT)
get_filename_component(OMNITRACE_DYNINST_API_RT_DIR "${OMNITRACE_DYNINST_API_RT}"
DIRECTORY)
endif()
if(OMNITRACE_BUILD_DYNINST)
set(OMNITRACE_DYNINST_API_RT_DIR
"${PROJECT_BINARY_DIR}/external/dyninst/dyninstAPI_RT:${PROJECT_BINARY_DIR}/external/dyninst/dyninstAPI"
)
endif()
if(NOT TEST_ENVIRONMENT)
set(TEST_ENVIRONMENT
@@ -33,7 +23,7 @@ function(OMNITRACE_ADD_BIN_TEST)
"OMNITRACE_PROFILE=ON"
"OMNITRACE_USE_SAMPLING=ON"
"OMNITRACE_TIME_OUTPUT=OFF"
"LD_LIBRARY_PATH=${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}:${OMNITRACE_DYNINST_API_RT_DIR}:$ENV{LD_LIBRARY_PATH}"
"LD_LIBRARY_PATH=${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}:$ENV{LD_LIBRARY_PATH}"
)
endif()
+1
파일 보기
@@ -77,4 +77,5 @@ add_subdirectory(binary)
add_subdirectory(omnitrace)
add_subdirectory(omnitrace-dl)
add_subdirectory(omnitrace-rt)
add_subdirectory(omnitrace-user)
+138
파일 보기
@@ -0,0 +1,138 @@
#
# C extensions are required
#
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_EXTENSIONS ON)
set(CMAKE_C_STANDARD_REQUIRED ON)
# ------------------------------------------------------------------------------#
# target sources
# ------------------------------------------------------------------------------#
include(cmake/platform.cmake)
set(SRC_LIST src/RTcommon.c src/RTmemEmulator.c)
if(PLATFORM MATCHES freebsd)
list(
APPEND
SRC_LIST
src/RTposix.c
src/RTfreebsd.c
src/RTheap.c
src/RTheap-freebsd.c
src/RTthread.c
src/RTspace.S
src/RTsignal.c)
elseif(PLATFORM MATCHES linux)
list(
APPEND
SRC_LIST
src/RTposix.c
src/RTlinux.c
src/RTheap.c
src/RTheap-linux.c
src/RTthread.c
src/RTspace.S
src/RTsignal.c)
list(APPEND RT_STATIC_ONLY_SRC_LIST src/RTstatic_ctors_dtors_begin.c
src/RTstatic_ctors_dtors_end.c)
elseif(PLATFORM MATCHES nt OR PLATFORM MATCHES windows)
list(APPEND SRC_LIST src/RTheap.c src/RTheap-win.c src/RTwinnt.c src/RTthread.c
src/RTthread-x86.c)
endif()
set(SRC_LIST_i386 src/RTthread-x86.c src/RTtlsgetaddr-x86.S)
set(RT_STATIC_ONLY_SRC_LIST_i386 src/RTstatic_ctors_dtors-x86.c)
set(SRC_LIST_x86_64 src/RTthread-x86-64.c src/RTtlsgetaddr-x86.S)
set(RT_STATIC_ONLY_SRC_LIST_x86_64 src/RTstatic_ctors_dtors-x86.c)
set(SRC_LIST_ppc32 src/RTthread-powerpc.c src/RTthread-powerpc-asm.S)
set(RT_STATIC_ONLY_SRC_LIST_ppc32 src/RTstatic_ctors_dtors-ppc32.c)
set(SRC_LIST_ppc64 src/RTthread-powerpc.c src/RTthread-powerpc-asm.S)
set(RT_STATIC_ONLY_SRC_LIST_ppc64 src/RTstatic_ctors_dtors-ppc64.c)
set(SRC_LIST_aarch64 src/RTthread-aarch64.c
# src/RTthread-aarch64-asm.S
)
set(RT_STATIC_ONLY_SRC_LIST_aarch64 src/RTstatic_ctors_dtors-aarch64.c)
# We use gcc to compile the various assembly files, but cmake doesn't default to knowing
# that gcc can handle .S.
enable_language(ASM)
file(GLOB SRC_ASSEMBLY "src/*.S")
if(NEED_NATIVE_ASSEMBER)
set_source_files_properties(${SRC_ASSEMBLY} PROPERTIES LANGUAGE ASM)
else()
set_source_files_properties(${SRC_ASSEMBLY} PROPERTIES LANGUAGE C)
endif()
# The arch-specific files other than RTthread-x86 are Unix-only.
if(UNIX)
if(PLATFORM MATCHES amd64 OR PLATFORM MATCHES x86_64)
set(SRC_LIST_mabi ${SRC_LIST} ${SRC_LIST_i386})
set(RT_STATIC_ONLY_SRC_LIST_mabi ${RT_STATIC_ONLY_SRC_LIST}
${RT_STATIC_ONLY_SRC_LIST_i386})
list(APPEND SRC_LIST ${SRC_LIST_x86_64})
list(APPEND RT_STATIC_ONLY_SRC_LIST ${RT_STATIC_ONLY_SRC_LIST_x86_64})
elseif(PLATFORM MATCHES ppc64)
set(SRC_LIST_mabi ${SRC_LIST} ${SRC_LIST_ppc32})
set(RT_STATIC_ONLY_SRC_LIST_mabi ${RT_STATIC_ONLY_SRC_LIST}
${RT_STATIC_ONLY_SRC_LIST_ppc32})
list(APPEND SRC_LIST ${SRC_LIST_ppc64})
list(APPEND RT_STATIC_ONLY_SRC_LIST ${RT_STATIC_ONLY_SRC_LIST_ppc64})
elseif(PLATFORM MATCHES i386)
list(APPEND SRC_LIST ${SRC_LIST_i386})
list(APPEND RT_STATIC_ONLY_SRC_LIST ${RT_STATIC_ONLY_SRC_LIST_i386})
elseif(PLATFORM MATCHES ppc32)
list(APPEND SRC_LIST ${SRC_LIST_ppc32})
list(APPEND RT_STATIC_ONLY_SRC_LIST ${RT_STATIC_ONLY_SRC_LIST_ppc32})
elseif(PLATFORM MATCHES aarch64)
list(APPEND SRC_LIST ${SRC_LIST_aarch64})
list(APPEND RT_STATIC_ONLY_SRC_LIST ${RT_STATIC_ONLY_SRC_LIST_aarch64})
endif()
endif()
add_library(omnitrace-rt-library SHARED)
add_library(omnitrace::omnitrace-rt-library ALIAS omnitrace-rt-library)
target_sources(omnitrace-rt-library PRIVATE ${SRC_LIST})
target_include_directories(
omnitrace-rt-library PRIVATE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/h>)
target_compile_definitions(omnitrace-rt-library PRIVATE ${UNIFIED_DEFINES})
target_link_libraries(
omnitrace-rt-library
PUBLIC $<BUILD_INTERFACE:${dl_LIBRARY}>
PRIVATE omnitrace::omnitrace-threading)
add_target_cxx_flag_if_avail(omnitrace-rt-library "-g3")
set_target_properties(
omnitrace-rt-library
PROPERTIES OUTPUT_NAME omnitrace-rt
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
BUILD_RPATH "\$ORIGIN"
INSTALL_RPATH "\$ORIGIN")
omnitrace_strip_target(omnitrace-rt-library)
install(TARGETS omnitrace-rt-library DESTINATION ${CMAKE_INSTALL_LIBDIR})
if(NOT EXISTS ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME})
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME})
endif()
add_custom_target(
omnitrace-rt-library-dyninstAPI_RT-symlink ALL
${CMAKE_COMMAND} -E create_symlink ../$<TARGET_FILE_NAME:omnitrace-rt-library>
${CMAKE_SHARED_LIBRARY_PREFIX}dyninstAPI_RT${CMAKE_SHARED_LIBRARY_SUFFIX}
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}
DEPENDS omnitrace-rt-library
COMMENT
"Creating ${CMAKE_SHARED_LIBRARY_PREFIX}dyninstAPI_RT${CMAKE_SHARED_LIBRARY_SUFFIX} to omnitrace-rt..."
)
install(
FILES
${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}/${CMAKE_SHARED_LIBRARY_PREFIX}dyninstAPI_RT${CMAKE_SHARED_LIBRARY_SUFFIX}
DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME})
+74
파일 보기
@@ -0,0 +1,74 @@
#!/bin/bash
P=$1
# i386/Linux, x86-64/Linux, ppc/Linux, ppc64/Linux
if [ ${P/linux/} != ${P} ]; then
if [ ${P/i686/} != ${P} ]; then
PLATFORM=i386-unknown-linux2.4
fi
if [ ${P/i586/} != ${P} ]; then
PLATFORM=i386-unknown-linux2.4
fi
if [ ${P/i486/} != ${P} ]; then
PLATFORM=i386-unknown-linux2.4
fi
if [ ${P/i386/} != ${P} ]; then
PLATFORM=i386-unknown-linux2.4
fi
if [ ${P/x86_64/} != ${P} ]; then
PLATFORM=x86_64-unknown-linux2.4
fi
if [ ${P/ppc64/} != ${P} ]; then
PLATFORM=ppc64_linux
fi
if [ ${P/powerpc64/} != ${P} ]; then
PLATFORM=ppc64_linux
fi
if [ ${P/powerpc-/} != ${P} ]; then
PLATFORM=ppc32_linux
fi
if [ ${P/ppc-/} != ${P} ]; then
PLATFORM=ppc32_linux
fi
if [ ${P/aarch64-/} != ${P} ]; then
PLATFORM=aarch64-unknown-linux
fi
# Freebsd
elif [ ${P/freebsd/} != ${P} ]; then
if [ ${P/i686/} != ${P} ]; then
PLATFORM=i386-unknown-freebsd7.2
fi
if [ ${P/i586/} != ${P} ]; then
PLATFORM=i386-unknown-freebsd7.2
fi
if [ ${P/i486/} != ${P} ]; then
PLATFORM=i386-unknown-freebsd7.2
fi
if [ ${P/i386/} != ${P} ]; then
PLATFORM=i386-unknown-freebsd7.2
fi
if [ ${P/x86_64/} != ${P} ]; then
PLATFORM=amd64-unknown-freebsd7.2
fi
# VxWorks
elif [ ${P/vxworks/} != ${P} ]; then
if [ ${P/i686/} != ${P} ]; then
PLATFORM=i386-unknown-vxworks6.x
fi
if [ ${P/i586/} != ${P} ]; then
PLATFORM=i386-unknown-vxworks6.x
fi
if [ ${P/i486/} != ${P} ]; then
PLATFORM=i386-unknown-vxworks6.x
fi
if [ ${P/i386/} != ${P} ]; then
PLATFORM=i386-unknown-vxworks6.x
fi
if [ ${P/powerpc-/} != ${P} ]; then
PLATFORM=ppc32-unknown-vxworks6.x
fi
fi
echo $PLATFORM
+132
파일 보기
@@ -0,0 +1,132 @@
#
#
#
set(PLATFORM $ENV{PLATFORM})
set(VALID_PLATFORMS
amd64-unknown-freebsd7.2 i386-unknown-freebsd7.2 i386-unknown-linux2.4 ppc32_linux
ppc64_linux x86_64-unknown-linux2.4 aarch64-unknown-linux)
if(NOT PLATFORM)
set(INVALID_PLATFORM true)
else()
list(FIND VALID_PLATFORMS ${PLATFORM} PLATFORM_FOUND)
if(PLATFORM_FOUND EQUAL -1)
set(INVALID_PLATFORM true)
endif()
endif()
execute_process(
COMMAND ${CMAKE_CURRENT_LIST_DIR}/sysname
OUTPUT_VARIABLE SYSNAME_OUT
OUTPUT_STRIP_TRAILING_WHITESPACE)
string(REPLACE "\n" "" SYSPLATFORM ${SYSNAME_OUT})
if(INVALID_PLATFORM)
# Try to set it automatically
execute_process(
COMMAND ${CMAKE_CURRENT_LIST_DIR}/dynsysname ${SYSNAME_OUT}
OUTPUT_VARIABLE DYNSYSNAME_OUT
OUTPUT_STRIP_TRAILING_WHITESPACE)
string(REPLACE "\n" "" PLATFORM ${DYNSYSNAME_OUT})
omnitrace_message(STATUS
"-- Attempting to automatically identify platform: ${PLATFORM}")
endif()
list(FIND VALID_PLATFORMS ${PLATFORM} PLATFORM_FOUND)
if(PLATFORM_FOUND EQUAL -1)
omnitrace_message(
FATAL_ERROR
"Error: unknown platform ${PLATFORM}; please set the PLATFORM environment variable to one of the following options: ${VALID_PLATFORMS}"
)
endif()
if(PLATFORM MATCHES i386)
set(ARCH_DEFINES arch_x86)
list(APPEND CAP_DEFINES cap_fixpoint_gen cap_noaddr_gen cap_stripped_binaries
cap_tramp_liveness cap_virtual_registers cap_stack_mods)
elseif(PLATFORM MATCHES x86_64 OR PLATFORM MATCHES amd64)
set(ARCH_DEFINES arch_x86_64 arch_64bit)
list(
APPEND
CAP_DEFINES
cap_32_64
cap_fixpoint_gen
cap_noaddr_gen
cap_registers
cap_stripped_binaries
cap_tramp_liveness
cap_stack_mods)
elseif(PLATFORM MATCHES ppc32)
set(ARCH_DEFINES arch_power)
list(APPEND CAP_DEFINES cap_registers)
elseif(PLATFORM MATCHES ppc64)
set(ARCH_DEFINES arch_power arch_64bit)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m64")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m64")
list(APPEND CAP_DEFINES cap_32_64 cap_registers cap_toc_64)
if(SYSPLATFORM MATCHES ppc64le)
list(APPEND CAP_DEFINES arch_ppc_little_endian)
endif()
elseif(PLATFORM MATCHES aarch64)
# set(ARCH_DEFINES aarch_64 arch_64bit)
set(ARCH_DEFINES arch_aarch64 arch_64bit)
list(APPEND CAP_DEFINES cap_32_64 cap_registers)
endif()
if(PLATFORM MATCHES linux)
set(OS_DEFINES os_linux)
list(APPEND CAP_DEFINES cap_async_events cap_binary_rewriter cap_dwarf
cap_mutatee_traps cap_ptrace)
set(BUG_DEFINES bug_syscall_changepc_rewind bug_force_terminate_failure)
elseif(PLATFORM MATCHES cnl)
set(OS_DEFINES os_linux os_cnl)
list(APPEND CAP_DEFINES cap_async_events cap_binary_rewriter cap_dwarf
cap_mutatee_traps cap_ptrace)
set(BUG_DEFINES bug_syscall_changepc_rewind)
elseif(PLATFORM MATCHES freebsd)
set(OS_DEFINES os_freebsd)
list(APPEND CAP_DEFINES cap_binary_rewriter cap_dwarf cap_mutatee_traps)
set(BUG_DEFINES
bug_freebsd_missing_sigstop bug_freebsd_mt_suspend bug_freebsd_change_pc
bug_phdrs_first_page bug_syscall_changepc_rewind)
elseif(PLATFORM STREQUAL i386-unknown-nt4.0)
set(OS_DEFINES os_windows)
list(APPEND CAP_DEFINES cap_mem_emulation cap_mutatee_traps)
endif()
if(PLATFORM STREQUAL i386-unknown-linux2.4)
set(OLD_DEFINES i386_unknown_linux2_0)
elseif(PLATFORM STREQUAL x86_64-unknown-linux2.4)
set(OLD_DEFINES x86_64_unknown_linux2_4)
elseif(PLATFORM STREQUAL ppc32_linux)
set(OLD_DEFINES ppc32_linux)
set(BUG_DEFINES ${BUG_DEFINES} bug_registers_after_exit)
elseif(PLATFORM STREQUAL ppc64_linux)
set(OLD_DEFINES ppc64_linux)
set(BUG_DEFINES ${BUG_DEFINES} bug_registers_after_exit)
elseif(PLATFORM STREQUAL x86_64_cnl)
set(OLD_DEFINES x86_64_cnl x86_64_unknown_linux2_4)
elseif(PLATFORM STREQUAL i386-unknown-freebsd7.2)
set(OLD_DEFINES i386_unknown_freebsd7_0)
elseif(PLATFORM STREQUAL amd64-unknown-freebsd7.2)
set(OLD_DEFINES amd64_unknown_freebsd7_0)
elseif(PLATFORM STREQUAL i386-unknown-nt4.0)
set(OLD_DEFINES i386_unknown_nt4_0)
elseif(PLATFORM STREQUAL aarch64-unknown-linux)
set(OLD_DEFINES aarch64_unknown_linux)
else(PLATFORM STREQUAL i386-unknown-linux2.4)
dyninst_message(FATAL_ERROR "Unknown platform: ${PLATFORM}")
endif()
if(Thread_DB_FOUND)
dyninst_message(STATUS "-- Enabling ThreadDB support")
list(APPEND CAP_DEFINES cap_thread_db)
endif()
set(UNIFIED_DEFINES ${CAP_DEFINES} ${BUG_DEFINES} ${ARCH_DEFINES} ${OS_DEFINES}
${OLD_DEFINES})
list(REMOVE_DUPLICATES UNIFIED_DEFINES)
+681
파일 보기
@@ -0,0 +1,681 @@
#!/bin/bash
# $Id: sysname,v 1.6 2005/08/09 16:13:16 gquinn Exp $
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Written by Per Bothner <bothner@cygnus.com>.
# The master version of this file is at the FSF in /home/gd/gnu/lib.
#
# This script attempts to guess a canonical system name similar to
# config.sub. If it succeeds, it prints the system name on stdout, and
# exits with 0. Otherwise, it exits with 1.
#
# The plan is that this can be called by configure scripts if you
# don't specify an explicit system type (host/target name).
#
# Only a few systems have been added to this list; please add others
# (but try to keep the structure clean).
#
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 8/24/94.)
if (test -f /.attbin/uname) >/dev/null 2>&1; then
PATH=$PATH:/.attbin
export PATH
fi
UNAME_MACHINE=$( (uname -m) 2>/dev/null) || UNAME_MACHINE=unknown
UNAME_RELEASE=$( (uname -r) 2>/dev/null) || UNAME_RELEASE=unknown
UNAME_SYSTEM=$( (uname -s) 2>/dev/null) || UNAME_SYSTEM=unknown
UNAME_VERSION=$( (uname -v) 2>/dev/null) || UNAME_VERSION=unknown
trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
# Note: order is significant - the case branches are not exclusive.
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
alpha:OSF1:V*:*)
# After 1.2, OSF1 uses "V1.3" for uname -r.
echo alpha-dec-osf$(echo ${UNAME_RELEASE} | sed -e 's/^V//')
exit 0
;;
alpha:OSF1:*:*)
# 1.2 uses "1.2" for uname -r.
echo alpha-dec-osf${UNAME_RELEASE}
exit 0
;;
21064:Windows_NT:50:3)
echo alpha-dec-winnt3.5
exit 0
;;
amiga:NetBSD:*:*)
echo m68k-cbm-netbsd${UNAME_RELEASE}
exit 0
;;
arm:RISC*:1.[012]*:* | arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit 0
;;
Pyramid*:OSx*:*:*)
if test "$( (/bin/universe) 2>/dev/null)" = att; then
echo pyramid-pyramid-sysv3
else
echo pyramid-pyramid-bsd
fi
exit 0
;;
sun4*:SunOS:5.*:*)
echo sparc-sun-solaris2$(echo ${UNAME_RELEASE} | sed -e 's/[^.]*//')
exit 0
;;
i86pc:SunOS:5.*:*)
echo i386-unknown-solaris2$(echo ${UNAME_RELEASE} | sed -e 's/[^.]*//')
exit 0
;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
# SunOS6. Hard to guess exactly what SunOS6 will be like, but
# it's likely to be more like Solaris than SunOS4.
echo sparc-sun-solaris3$(echo ${UNAME_RELEASE} | sed -e 's/[^.]*//')
exit 0
;;
sun4*:SunOS:*:*)
case "$(/usr/bin/arch -k)" in
Series* | S4*)
UNAME_RELEASE=$(uname -v)
;;
esac
# Japanese Language versions have a version number like `4.1.3-JL'.
echo sparc-sun-sunos$(echo ${UNAME_RELEASE} | sed -e 's/-/_/')
exit 0
;;
sun3*:SunOS:*:*)
echo m68k-sun-sunos${UNAME_RELEASE}
exit 0
;;
atari*:NetBSD:*:*)
echo m68k-atari-netbsd${UNAME_RELEASE}
exit 0
;;
sun3*:NetBSD:*:*)
echo m68k-sun-netbsd${UNAME_RELEASE}
exit 0
;;
mac68k:NetBSD:*:*)
echo m68k-apple-netbsd${UNAME_RELEASE}
exit 0
;;
RISC*:ULTRIX:*:*)
echo mips-dec-ultrix${UNAME_RELEASE}
exit 0
;;
VAX*:ULTRIX*:*:*)
echo vax-dec-ultrix${UNAME_RELEASE}
exit 0
;;
mips:*:4*:UMIPS)
echo mips-mips-riscos4sysv
exit 0
;;
mips:*:5*:RISCos)
echo mips-mips-riscos${UNAME_RELEASE}
exit 0
;;
m88k:CX/UX:7*:*)
echo m88k-harris-cxux7
exit 0
;;
m88k:*:4*:R4*)
echo m88k-motorola-sysv4
exit 0
;;
m88k:*:3*:R3*)
echo m88k-motorola-sysv3
exit 0
;;
AViiON:dgux:*:*)
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
-o ${TARGET_BINARY_INTERFACE}x = x ]; then
echo m88k-dg-dgux${UNAME_RELEASE}
else
echo m88k-dg-dguxbcs${UNAME_RELEASE}
fi
exit 0
;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
exit 0
;;
M88*:*:R3*:*)
# Delta 88k system running SVR3
echo m88k-motorola-sysv3
exit 0
;;
XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
echo m88k-tektronix-sysv3
exit 0
;;
Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
echo m68k-tektronix-bsd
exit 0
;;
*:IRIX*:*:*)
echo mips-sgi-irix$(echo ${UNAME_RELEASE} | sed -e 's/-/_/g')
exit 0
;;
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
exit 0
;; # Note that: echo "'`uname -s`'" gives 'AIX '
i[34]86:AIX:*:*)
echo i386-ibm-aix
exit 0
;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
sed 's/^ //' <<EOF >dummy.c
#include <sys/systemcfg.h>
main()
{
if (!__power_pc())
exit(1);
puts("powerpc-ibm-aix3.2.5");
exit(0);
}
EOF
${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
rm -f dummy.c dummy
echo rs6000-ibm-aix3.2.5
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
echo rs6000-ibm-aix3.2.4
else
echo rs6000-ibm-aix3.2
fi
exit 0
;;
*:AIX:*:4)
if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
IBM_ARCH=powerpc
fi
if [ -x /usr/bin/oslevel ]; then
IBM_REV=$(/usr/bin/oslevel)
else
IBM_REV=4.${UNAME_RELEASE}
fi
echo ${IBM_ARCH}-ibm-aix${IBM_REV}
exit 0
;;
*:AIX:*:5)
if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
IBM_ARCH=powerpc
fi
if [ -x /usr/bin/oslevel ]; then
IBM_REV=$(/usr/bin/oslevel)
else
IBM_REV=5.${UNAME_RELEASE}
fi
echo ${IBM_ARCH}-ibm-aix${IBM_REV}
exit 0
;;
*:AIX:*:*)
echo rs6000-ibm-aix
exit 0
;;
ibmrt:4.4BSD:* | romp-ibm:BSD:*)
echo romp-ibm-bsd4.4
exit 0
;;
ibmrt:*BSD:* | romp-ibm:BSD:*) # covers RT/PC NetBSD and
echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
exit 0
;; # report: romp-ibm BSD 4.3
*:BOSX:*:*)
echo rs6000-bull-bosx
exit 0
;;
DPX/2?00:B.O.S.:*:*)
echo m68k-bull-sysv3
exit 0
;;
9000/[34]??:4.3bsd:1.*:*)
echo m68k-hp-bsd
exit 0
;;
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
echo m68k-hp-bsd4.4
exit 0
;;
9000/[3478]??:HP-UX:*:*)
case "${UNAME_MACHINE}" in
9000/31?) HP_ARCH=m68000 ;;
9000/[34]??) HP_ARCH=m68k ;;
9000/7?? | 9000/8?[79]) HP_ARCH=hppa1.1 ;;
9000/8??) HP_ARCH=hppa1.0 ;;
esac
HPUX_REV=$(echo ${UNAME_RELEASE} | sed -e 's/[^.]*.[0B]*//')
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
exit 0
;;
3050*:HI-UX:*:*)
sed 's/^ //' <<EOF >dummy.c
#include <unistd.h>
int
main ()
{
long cpu = sysconf (_SC_CPU_VERSION);
/* The order matters, because CPU_IS_HP_MC68K erroneously returns
true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
results, however. */
if (CPU_IS_PA_RISC (cpu))
{
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
default: puts ("hppa-hitachi-hiuxwe2"); break;
}
}
else if (CPU_IS_HP_MC68K (cpu))
puts ("m68k-hitachi-hiuxwe2");
else puts ("unknown-hitachi-hiuxwe2");
exit (0);
}
EOF
${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
rm -f dummy.c dummy
echo unknown-hitachi-hiuxwe2
exit 0
;;
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*)
echo hppa1.1-hp-bsd
exit 0
;;
9000/8??:4.3bsd:*:*)
echo hppa1.0-hp-bsd
exit 0
;;
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*)
echo hppa1.1-hp-osf
exit 0
;;
hp8??:OSF1:*:*)
echo hppa1.0-hp-osf
exit 0
;;
parisc*:Lites*:*:*)
echo hppa1.1-hp-lites
exit 0
;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
exit 0
;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc; then
echo c32-convex-bsd
else
echo c2-convex-bsd
fi
exit 0
;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
echo c34-convex-bsd
exit 0
;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
echo c38-convex-bsd
exit 0
;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
exit 0
;;
CRAY*X-MP:*:*:*)
echo xmp-cray-unicos
exit 0
;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE}
exit 0
;;
CRAY*C90:*:*:*)
echo c90-cray-unicos${UNAME_RELEASE}
exit 0
;;
CRAY-2:*:*:*)
echo cray2-cray-unicos
exit 0
;;
hp3[0-9][05]:NetBSD:*:*)
echo m68k-hp-netbsd${UNAME_RELEASE}
exit 0
;;
i[34]86:BSD/386:*:* | *:BSD/OS:*:*)
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit 0
;;
i[3456]86:CYGWIN_NT*:*:*)
echo i386-unknown-nt4.0
exit 0
;;
*:FreeBSD:*:*)
echo ${UNAME_MACHINE}-unknown-freebsd$(echo ${UNAME_RELEASE} | sed -e 's/[-(].*//')
exit 0
;;
*:NetBSD:*:*)
echo ${UNAME_MACHINE}-unknown-netbsd$(echo ${UNAME_RELEASE} | sed -e 's/[-_].*/\./')
exit 0
;;
*:GNU:*:*)
echo $(echo ${UNAME_MACHINE} | sed -e 's,/.*$,,')-unknown-gnu$(echo ${UNAME_RELEASE} | sed -e 's,/.*$,,')
exit 0
;;
*:Linux:*:*)
# The BFD linker knows what the default object file format is, so
# first see if it will tell us.
ld_help_string=$(ld --help 2>&1)
if echo $ld_help_string | grep >/dev/null 2>&1 "supported emulations: elf_i[345]86"; then
echo "${UNAME_MACHINE}-unknown-linux"
exit 0
elif echo $ld_help_string | grep >/dev/null 2>&1 "supported emulations: i[345]86linux"; then
echo "${UNAME_MACHINE}-unknown-linuxaout"
exit 0
elif echo $ld_help_string | grep >/dev/null 2>&1 "supported emulations: i[345]86coff"; then
echo "${UNAME_MACHINE}-unknown-linuxcoff"
exit 0
elif echo $ld_help_string | grep >/dev/null 2>&1 "supported emulations: elf64_ia64"; then
echo "${UNAME_MACHINE}-unknown-linux"
exit 0
elif echo $ld_help_string | grep >/dev/null 2>&1 "supported emulations: elf_x86_64"; then
echo "${UNAME_MACHINE}-unknown-linux"
exit 0
elif test "${UNAME_MACHINE}" = "alpha"; then
echo alpha-unknown-linux
exit 0
else
# Either a pre-BFD a.out linker (linuxoldld) or one that does not give us
# useful --help. Gcc wants to distinguish between linuxoldld and linuxaout.
test ! -d /usr/lib/ldscripts/. &&
echo "${UNAME_MACHINE}-unknown-linuxoldld" && exit 0
# Determine whether the default compiler is a.out or elf
cat >dummy.c <<EOF
main(argc, argv)
int argc;
char *argv[];
{
#ifdef __ELF__
printf ("%s-unknown-linux\n", argv[1]);
#else
printf ("%s-unknown-linuxaout\n", argv[1]);
#endif
return 0;
}
EOF
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
rm -f dummy.c dummy
fi
;;
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
# are messed up and put the nodename in both sysname and nodename.
i[34]86:DYNIX/ptx:4*:*)
echo i386-sequent-sysv4
exit 0
;;
i[34]86:*:4.*:* | i[34]86:SYSTEM_V:4.*:*)
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
else
echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}
fi
exit 0
;;
i[34]86:*:3.2:*)
if test -f /usr/options/cb.name; then
UNAME_REL=$(sed -n 's/.*Version //p' </usr/options/cb.name)
echo ${UNAME_MACHINE}-unknown-isc$UNAME_REL
elif /bin/uname -X 2>/dev/null >/dev/null; then
UNAME_REL=$( (/bin/uname -X | egrep Release | sed -e 's/.*= //'))
(/bin/uname -X | egrep i80486 >/dev/null) && UNAME_MACHINE=i486
echo ${UNAME_MACHINE}-unknown-sco$UNAME_REL
else
echo ${UNAME_MACHINE}-unknown-sysv32
fi
exit 0
;;
Intel:Mach:3*:*)
echo i386-unknown-mach3
exit 0
;;
paragon:*:*:*)
echo i860-intel-osf1
exit 0
;;
i860:*:4.*:*) # i860-SVR4
if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1; then
echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
else # Add other i860-SVR4 vendors below as they are discovered.
echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
fi
exit 0
;;
mini*:CTIX:SYS*5:*)
# "miniframe"
echo m68010-convergent-sysv
exit 0
;;
M680[234]0:*:R3V[567]*:*)
test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0
;;
3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0)
uname -p 2>/dev/null | grep 86 >/dev/null &&
echo i486-ncr-sysv4.3 && exit 0
;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
uname -p 2>/dev/null | grep 86 >/dev/null &&
echo i486-ncr-sysv4 && exit 0
;;
m680[234]0:LynxOS:2.[23]*:*)
echo m68k-lynx-lynxos${UNAME_RELEASE}
exit 0
;;
mc68030:UNIX_System_V:4.*:*)
echo m68k-atari-sysv4
exit 0
;;
i[34]86:LynxOS:2.[23]*:*)
echo i386-lynx-lynxos${UNAME_RELEASE}
exit 0
;;
TSUNAMI:LynxOS:2.[23]*:*)
echo sparc-lynx-lynxos${UNAME_RELEASE}
exit 0
;;
rs6000:LynxOS:2.[23]*:*)
echo rs6000-lynx-lynxos${UNAME_RELEASE}
exit 0
;;
RM*:SINIX-*:*:*)
echo mips-sni-sysv4
exit 0
;;
*:SINIX-*:*:*)
if uname -p 2>/dev/null >/dev/null; then
UNAME_MACHINE=$( (uname -p) 2>/dev/null)
echo ${UNAME_MACHINE}-sni-sysv4
else
echo ns32k-sni-sysv
fi
exit 0
;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
cat >dummy.c <<EOF
#ifdef _SEQUENT_
# include <sys/types.h>
# include <sys/utsname.h>
#endif
main ()
{
#if defined (sony)
#if defined (MIPSEB)
/* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
I don't know.... */
printf ("mips-sony-bsd\n"); exit (0);
#else
#include <sys/param.h>
printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
"4"
#else
""
#endif
); exit (0);
#endif
#endif
#if defined (__arm) && defined (__acorn) && defined (__unix)
printf ("arm-acorn-riscix"); exit (0);
#endif
#if defined (hp300) && !defined (hpux)
printf ("m68k-hp-bsd\n"); exit (0);
#endif
#if defined (NeXT)
#if !defined (__ARCHITECTURE__)
#define __ARCHITECTURE__ "m68k"
#endif
int version;
version=$( (hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null);
printf ("%s-next-nextstep%s\n", __ARCHITECTURE__, version==2 ? "2" : "3");
exit (0);
#endif
#if defined (MULTIMAX) || defined (n16)
#if defined (UMAXV)
printf ("ns32k-encore-sysv\n"); exit (0);
#else
#if defined (CMU)
printf ("ns32k-encore-mach\n"); exit (0);
#else
printf ("ns32k-encore-bsd\n"); exit (0);
#endif
#endif
#endif
#if defined (__386BSD__)
printf ("i386-unknown-bsd\n"); exit (0);
#endif
#if defined (sequent)
#if defined (i386)
printf ("i386-sequent-dynix\n"); exit (0);
#endif
#if defined (ns32000)
printf ("ns32k-sequent-dynix\n"); exit (0);
#endif
#endif
#if defined (_SEQUENT_)
struct utsname un;
uname(&un);
if (strncmp(un.version, "V2", 2) == 0) {
printf ("i386-sequent-ptx2\n"); exit (0);
}
if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
printf ("i386-sequent-ptx1\n"); exit (0);
}
printf ("i386-sequent-ptx\n"); exit (0);
#endif
#if defined (vax)
#if !defined (ultrix)
printf ("vax-dec-bsd\n"); exit (0);
#else
printf ("vax-dec-ultrix\n"); exit (0);
#endif
#endif
#if defined (alliant) && defined (i860)
printf ("i860-alliant-bsd\n"); exit (0);
#endif
exit (1);
}
EOF
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0
rm -f dummy.c dummy
# Apollos put the system type in the environment.
test -d /usr/apollo && {
echo ${ISP}-apollo-${SYSTYPE}
exit 0
}
# Convex versions that predate uname can use getsysinfo(1)
if [ -x /usr/convex/getsysinfo ]; then
case $(getsysinfo -f cpu_type) in
c1*)
echo c1-convex-bsd
exit 0
;;
c2*)
if getsysinfo -f scalar_acc; then
echo c32-convex-bsd
else
echo c2-convex-bsd
fi
exit 0
;;
c34*)
echo c34-convex-bsd
exit 0
;;
c38*)
echo c38-convex-bsd
exit 0
;;
c4*)
echo c4-convex-bsd
exit 0
;;
esac
fi
#echo '(Unable to guess system type)' 1>&2
exit 1
+197
파일 보기
@@ -0,0 +1,197 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/************************************************************************
* $Id: Types.h,v 1.38 2008/08/29 21:45:10 legendre Exp $
* Types.h: commonly used types (used by runtime libs and other modules)
************************************************************************/
#if !defined(_Types_h_)
# define _Types_h_
/* Sets up 64 and 32 bit
types:
int64_t uint64_t int32_t uint32_t
constant macros:
I64_C(x) UI64_C(x)
limits:
I64_MAX I64_MIN UI64_MAX
I32_MAX I32_MIN UI32_MAX
note: needs to be included before anything that includes inttypes.h
(eg. stdio on some systems)
*/
/* Set up the 32 AND 64 BIT TYPES ===================================== */
/*
--- inttypes.h ---
int32_t uint32_t int64_t uint64_t 32B lmts 64Blmts 64BlitMacros#
Linux yes yes yes yes yes yes yes
FreeBSD yes yes yes yes yes yes yes
WindowsNT nonexistant
# we rename all of the 64 bit literal macros to our shortened name
*/
# if defined(os_windows)
typedef signed __int64 int64_t;
typedef signed __int32 int32_t;
typedef signed __int16 int16_t;
typedef signed __int8 int8_t;
typedef unsigned __int64 uint64_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int8 uint8_t;
# elif defined(os_linux)
# if !defined(__STDC_CONSTANT_MACROS)
# define __STDC_CONSTANT_MACROS
# endif
# if !defined(__STDC_LIMIT_MACROS)
# define __STDC_LIMIT_MACROS
# endif
# include <stdint.h>
# if defined(arch_x86_64) || defined(arch_64bit)
# define TYPE64BIT
# endif
typedef long double double128_t;
# elif defined(os_freebsd)
# if !defined(__STDC_CONSTANT_MACROS)
# define __STDC_CONSTANT_MACROS
# endif
# if !defined(__STDC_LIMIT_MACROS)
# define __STDC_LIMIT_MACROS
# endif
# include <stdint.h>
typedef long double double128_t;
/* FreeBSD doesn't define this */
typedef int64_t off64_t;
# else
# error Unknown architecture
# endif
/* Set up the 64 BIT LITERAL MACROS =================================== */
# if defined(os_windows)
/* nt ----------------------------- */
# define I64_C(x) (x##i64)
# define UI64_C(x) (x##ui64)
# else /* linux, freebsd ----------------- */
# define I64_C(x) INT64_C(x)
# define UI64_C(x) UINT64_C(x)
# endif
/* Set up the 32 and 64 BIT LIMITS for those not already set up ======= */
# if defined(os_windows)
/* nt ----------------------------- */
# include <limits.h>
# define I64_MAX _I64_MAX
# define UI64_MAX _UI64_MAX
# define I64_MIN _I64_MIN
# define I32_MAX _I32_MAX
# define I32_MIN _I32_MIN
# define UI32_MAX _UI32_MAX
# else /* linux, freebsd ----------------- */
# define I64_MAX INT64_MAX
# define UI64_MAX UINT64_MAX
# define I64_MIN INT64_MIN
# define I32_MAX INT32_MAX
# define I32_MIN INT32_MIN
# define UI32_MAX UINT32_MAX
# endif
/*
typedef int64_t time64;
*/
# if defined(__cplusplus)
# include "h/dyntypes.h"
using namespace Dyninst;
static const Address ADDR_NULL = (Address)(0);
# else
# define ADDR_NULL (0)
typedef unsigned long Address;
# endif
/* Note the inherent assumption that the size of a "long" integer matches
that of an address (void*) on every supported Paradyn/Dyninst system!
(This can be checked with Address_chk().)
*/
typedef unsigned int Word;
typedef long long int RegValue; /* register content 64-bit */
/* This needs to be an int since it is sometimes used to pass offsets
to the code generator (i.e. if-statement) - jkh 5/24/99 */
typedef unsigned int Register; /* a register number, e.g., [0..31] */
static const Register Null_Register = (Register)(-1); /* '255' */
/* Easily noticeable name... */
static const Register REG_NULL = (Register)(-1);
// Virtual Memory Map -- shared between platforms
# define PREMS_PRIVATE (1 << 4)
# define PREMS_SHARED (1 << 3)
# define PREMS_READ (1 << 2)
# define PREMS_WRITE (1 << 1)
# define PREMS_EXEC (1 << 0)
# define MAPENTRIES_PATH_SIZE 512
# define MAPENTRIES_PATH_SIZE_STR "512"
typedef struct maps_entries
{
Address start;
Address end;
unsigned prems;
Address offset;
int dev_major;
int dev_minor;
unsigned long inode;
char path[MAPENTRIES_PATH_SIZE];
} map_entries;
# ifdef __cplusplus
# include "h/util.h"
COMMON_EXPORT void
Address_chk();
COMMON_EXPORT char*
Address_str(Address addr);
// NB: this is probably inappropriate for 64-bit addresses!
inline unsigned
hash_address(const Address& addr)
{
return (unsigned) ((addr >> 2) & 0xffffffff);
}
# endif /* __cplusplus */
#endif /* !defined(_Types_h_) */
+171
파일 보기
@@ -0,0 +1,171 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef COMPILER_ANNOTATIONS_H
#define COMPILER_ANNOTATIONS_H
/***********************************************************************
*
* DYNINST_FALLTHROUGH
*
* Eliminates "this statement may fall through" warnings when used as the last
* statment of a switch case that falls through to the next case. The macro
* is used as shown in indicate that case 2 should fall through to case 1.
*
* switch (x) {
* case 2:
* foo();
* DYNINST_FALLTHROUGH;
* case 1:
* foo();
* break;
* default:
* error();
* break;
* }
*/
#if defined(__cpluscplus) && defined(__has_cpp_attribute)
# if __has_cpp_attribute(fallthrough)
# define DYNINST_FALLTHROUGH [[fallthrough]]
# elif __has_cpp_attribute(gcc::fallthrough)
# define DYNINST_FALLTHROUGH [[gcc::fallthrough]]
# elif __has_cpp_attribute(clang::fallthrough)
# define DYNINST_FALLTHROUGH [[clang::fallthrough]]
# endif
#elif !defined(__cpluscplus) && defined(__has_c_attribute)
# if __has_c_attribute(fallthrough)
# define DYNINST_FALLTHROUGH [[fallthrough]]
# elif __STDC_VERSION__ > 201710
// scoped attribute names are only valid in C starting with 2x
# if __has_c_attribute(gcc::fallthrough)
# define DYNINST_FALLTHROUGH [[gcc::fallthrough]]
# elif __has_c_attribute(clang::fallthrough)
# define DYNINST_FALLTHROUGH [[clang::fallthrough]]
# endif
# endif
#elif defined(__has_attribute)
# if __has_attribute(fallthrough)
# define DYNINST_FALLTHROUGH __attribute__((fallthrough))
# elif __cplusplus || __STDC_VERSION__ > 201710
// scoped attribute names are only valid in C++ or C starting with 2x
# if __has_attribute(gcc::fallthrough)
# define DYNINST_FALLTHROUGH __attribute__((gcc::fallthrough))
# elif __has_attribute(clang::fallthrough)
# define DYNINST_FALLTHROUGH __attribute__((clang::fallthrough))
# endif
# endif
#endif
#if !defined(DYNINST_FALLTHROUGH)
# define DYNINST_FALLTHROUGH \
do \
{ \
} while(0)
#endif
/***********************************************************************
*
* DYNINST_PRINTF_ANNOTATION(fmtIndex, argIndex)
* DYNINST_SCANF_ANNOTATION(fmtIndex, argIndex)
* DYNINST_FORMAT_ANNOTATION(fmtType, fmtIndex, argIndex)
*
* Annotates a function as taking a printf for scanf format string and vararg
* list of values allowing the compiler to validate the format string and the
* supplied arguments. fmtIndex is the 1-based index of the format string, and
* argIndex is the 1-based index that begins the variable argument list used by
* printf or scanf.
*
* The annotation should be placed after the declaration of the function. For
* example:
*
* myprintf(int level, char *fmt, ...) DYNINST_PRINTF_ANNOTATION(2, 3);
*/
#if defined(__has_attribute)
# if __has_attribute(format)
# define DYNINST_FORMAT_ANNOTATION(fmtType, fmtIndex, argIndex) \
__attribute__((format(fmtType, fmtIndex, argIndex)))
# endif
#endif
#if !defined(DYNINST_FORMAT_ANNOTATION)
# define DYNINST_FORMAT_ANNOTATION(fmtType, fmtIndex, argIndex)
#endif
#define DYNINST_PRINTF_ANNOTATION(fmtIndex, argIndex) \
DYNINST_FORMAT_ANNOTATION(printf, fmtIndex, argIndex)
#define DYNINST_SCANF_ANNOTATION(fmtIndex, argIndex) \
DYNINST_FORMAT_ANNOTATION(scanf, fmtIndex, argIndex)
/***********************************************************************
*
* DYNINST_MALLOC_ANNOTATION
* DYNINST_MALLOC_DEALLOC_ANNOTATION(freeFunction)
* DYNINST_MALLOC_DEALLOC_POS_ANNOTATION(freeFunction, pos)
*
* Annotates a function as returning a unique pointer to suitable memory
* to hold an object. The second form names the matching deallocator, and
* the third form indicates the position of the pointer in the argument list.
*
* The annotation should be placed after the declaration of the function. For
* example:
*
* Obj* myalloc(int x) DYNINST_MALLOC_ANNOTATION;
* void mydealloc2(Obj* o);
* Obj* myalloc2(int x) DYNINST_MALLOC_DEALLOC_ANNOTATION(mydealloc2);
* void mydealloc3(int y, Obj* o);
* Obj* myalloc3(int x) DYNINST_MALLOC_DEALLOC_POS_ANNOTATION(mydealloc3, 2);
*/
#if defined(__has_attribute)
# if __has_attribute(malloc)
# define DYNINST_MALLOC_ANNOTATION __attribute__((malloc))
# if __GNUC__ >= 11
// malloc attribute with 1 and 2 params is gcc 11 and later only
# define DYNINST_MALLOC_DEALLOC_ANNOTATION(f) \
__attribute__((malloc, malloc(f)))
# define DYNINST_MALLOC_DEALLOC_POS_ANNOTATION(f, p) \
__attribute__((malloc, malloc(f, p)))
# endif
# endif
#endif
#if !defined(DYNINST_MALLOC_ANNOTATION)
# define DYNINST_MALLOC_ANNOTATION
#endif
#if !defined(DYNINST_MALLOC_DEALLOC_ANNOTATION)
# define DYNINST_MALLOC_DEALLOC_ANNOTATION(f) DYNINST_MALLOC_ANNOTATION
#endif
#if !defined(DYNINST_MALLOC_DEALLOC_POS_ANNOTATION)
# define DYNINST_MALLOC_DEALLOC_POS_ANNOTATION(f, p) DYNINST_MALLOC_ANNOTATION
#endif
#endif /* COMPILER_ANNOTATIONS_H */
+284
파일 보기
@@ -0,0 +1,284 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* $Id: dyninstAPI_RT.h,v 1.45 2008/04/15 16:43:43 roundy Exp $
* This file contains the standard instrumentation functions that are provided
* by the run-time instrumentation layer.
*/
#ifndef _DYNINSTAPI_RT_H
#define _DYNINSTAPI_RT_H
/*
* Define the size of the per process data area.
*
* This should be a power of two to reduce paging and caching shifts.
* Note that larger sizes may result in requiring longjumps within
* mini-trampolines to reach within this area.
*/
#if !defined(target_smallmem)
# define SYN_INST_BUF_SIZE (1024 * 1024 * 4)
#else
# define SYN_INST_BUF_SIZE (1024 * 1024 * 1)
#endif
#define DYNINST_BREAKPOINT_SIGNUM (SIGRTMIN + 4)
#include <stdint.h>
#include <stdio.h>
#include "h/Types.h"
#include "dyninstRTExport.h"
/* If we must make up a boolean type, we should make it unique */
typedef unsigned char RT_Boolean;
static const RT_Boolean RT_TRUE = 1;
static const RT_Boolean RT_FALSE = 0;
DLLEXPORT extern char gLoadLibraryErrorString[];
extern void* gBRKptr;
struct DYNINST_bootstrapStruct
{
int event; /* "event" values:
0 --> nothing
1 --> end of DYNINSTinit (normal)
2 --> end of DYNINSTinit (forked process)
3 --> start of DYNINSTexec (before exec)
*/
int pid;
int ppid; /* parent of forked process */
};
typedef enum
{
DSE_undefined,
DSE_forkEntry,
DSE_forkExit,
DSE_execEntry,
DSE_execExit,
DSE_exitEntry,
DSE_loadLibrary,
DSE_lwpExit,
DSE_snippetBreakpoint,
DSE_stopThread,
DSE_userMessage,
DSE_dynFuncCall
} DYNINST_synch_event_t;
extern int DYNINSTdebugPrintRT; /* control run-time lib debug/trace prints */
#if !defined(RTprintf)
# define RTprintf \
if(DYNINSTdebugPrintRT) printf
#endif
#define TARGET_CACHE_WIDTH 128
#define TARGET_CACHE_WAYS 2
#define THREAD_AWAITING_DELETION -2
#define ERROR_STRING_LENGTH 256
typedef enum
{
rtBPatch_nullEvent,
rtBPatch_newConnectionEvent,
rtBPatch_internalShutDownEvent,
rtBPatch_threadCreateEvent,
rtBPatch_threadDestroyEvent,
rtBPatch_dynamicCallEvent,
rtBPatch_userEvent
} rtBPatch_asyncEventType;
const char* asyncEventType2str(rtBPatch_asyncEventType);
typedef struct
{
unsigned int pid;
rtBPatch_asyncEventType type;
unsigned int event_fd;
unsigned int size;
} rtBPatch_asyncEventRecord;
typedef struct
{
void* call_site_addr;
void* call_target;
} BPatch_dynamicCallRecord;
typedef struct
{
int ppid; /*Parent process's pid*/
dyntid_t tid; /*Thread library ID for thread*/
int lwp; /*OS id for thread*/
int index; /*The dyninst index for this thread*/
void* stack_addr; /*The top of this thread's stack*/
void* start_pc; /*The pc of this threads initial function*/
} BPatch_newThreadEventRecord;
#if defined(arch_x86_64) /* cannot use MUTATEE_32 here b/c libdyninstAPI.so compiles \
this */
/*these are the 32 bit structures for use with 32 bit mutatees on AMD64*/
typedef struct
{
unsigned int call_site_addr;
unsigned int call_target;
} BPatch_dynamicCallRecord32;
typedef struct
{
int ppid; /*Parent process's pid*/
unsigned int tid; /*Thread library ID for thread*/
int lwp; /*OS id for thread*/
int index; /*The dyninst index for this thread*/
unsigned int stack_addr; /*The top of this thread's stack*/
unsigned int start_pc; /*The pc of this threads initial function*/
} BPatch_newThreadEventRecord32;
#endif
typedef struct
{
int index; /*Index of the dead thread*/
} BPatch_deleteThreadEventRecord;
/* Let's define some constants for, well, everything.... */
/* These should be different to avoid unexpected collisions */
#if !defined(DYNINST_SINGLETHREADED)
# define DYNINST_SINGLETHREADED -128
#endif
#define DYNINST_TRACEPIPE_ERRVAL -1
#define DYNINST_PRINTF_ERRVAL -2
#define DYNINST_NOT_IN_HASHTABLE ((unsigned) -1)
DLLEXPORT extern int DYNINST_break_point_event;
typedef struct
{
void* source;
void* target;
} trapMapping_t;
#define TRAP_HEADER_SIG 0x759191D6
#define DT_DYNINST 0x6D191957
#if defined(_MSC_VER)
# pragma warning(disable : 4200)
#endif
#if defined(__GNUC__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wpedantic"
// Disable warning about flexible array members in C++
// FIXME: Flexible array member, traps[], in structure below
#endif
struct trap_mapping_header
{
uint32_t signature;
uint32_t num_entries;
int32_t pos;
uint32_t padding;
uint64_t low_entry;
uint64_t high_entry;
trapMapping_t
traps[]; // Don't change this to a pointer, despite any compiler warnings
};
#if defined(__GNUC__)
# pragma GCC diagnostic pop
#endif
#define MAX_MEMORY_MAPPER_ELEMENTS 1024
typedef struct
{
long start;
long size;
} MemoryMapperCopyElement;
typedef struct
{
unsigned long lo;
unsigned long hi;
long shift;
MemoryMapperCopyElement* copyList;
} MemoryMapperElement;
struct MemoryMapper
{
int guard1;
int guard2;
int size;
int padding;
MemoryMapperElement elements[MAX_MEMORY_MAPPER_ELEMENTS];
};
/* 32/64 bit versions for the mutator */
typedef struct
{
uint32_t lo;
uint32_t hi;
uint32_t shift;
void* copyList;
} MemoryMapperElement32;
typedef struct
{
uint64_t lo;
uint64_t hi;
uint64_t shift;
void* copyList;
} MemoryMapperElement64;
struct MemoryMapper32
{
int guard1;
int guard2;
int size;
int padding;
MemoryMapperElement32 elements[MAX_MEMORY_MAPPER_ELEMENTS];
};
struct MemoryMapper64
{
int guard1;
int guard2;
int size;
int padding;
MemoryMapperElement64 elements[MAX_MEMORY_MAPPER_ELEMENTS];
};
DLLEXPORT extern struct MemoryMapper RTmemoryMapper;
extern int RTuntranslatedEntryCounter;
#include "dyninstRTExport.h"
#endif /* _DYNINSTAPI_RT_H */
+142
파일 보기
@@ -0,0 +1,142 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _DYNINST_RT_EXPORT_H_
#define _DYNINST_RT_EXPORT_H_
#ifndef ASSEMBLER
/* This file contains function prototypes that may be useful for
dyninst users to directly have access to from their own runtime
libraries.
*/
# if !defined(DLLEXPORT)
# if defined(_MSC_VER)
/* If we're on Windows, we need to explicetely export these functions: */
# define DLLEXPORT __declspec(dllexport)
# else
# define DLLEXPORT __attribute__((visibility("default")))
# endif
# endif
/*
DYNINSTuserMessage(void *msg, unsigned int msg_size) may be used
in conjunction with the dyninstAPI method
BPatch_process::registerUserMessageCallback(), to implement a generic
user-defined, asynchronous communications protocol from the mutatee
(via this runtime library) to the mutator.
Calls to DYNINSTuserMessage() will result in <msg> (of <msg_size> bytes)
being sent to the mutator, and then passed to the callback function
provided by the API user via registerUserMessageCallback().
Returns zero on success, nonzero on failure.
*/
DLLEXPORT int
DYNINSTuserMessage(void* msg, unsigned int msg_size);
/* Returns the number of threads DYNINST currently knows about. (Which
may differ at certain times from the number of threads actually present.) */
DLLEXPORT int
DYNINSTthreadCount();
/**
* These function implement a locking mechanism that can be used by
* a user's runtime library.
*
* Be sure to always check for DYNINST_LIVE_LOCK and DYNINST_DEAD_LOCK.
* When instrumenting multithread or signal-based application as these error
* conditions can trigger even on simple synchronization mechanisms.
**/
/* The contents of this structure are subject to change between
dyninst versions. Don't rely on it. */
typedef void* dyntid_t;
# define DYNINST_INITIAL_LOCK_PID ((void*) -129)
typedef struct
{
volatile int mutex;
dyntid_t tid;
} dyninst_lock_t;
/* Return values for 'dyninst_lock' */
# define DYNINST_LIVE_LOCK -1
# define DYNINST_DEAD_LOCK -2
/* Declare a lock already initialized */
# define DECLARE_DYNINST_LOCK(lck) dyninst_lock_t lck = { 0, DYNINST_INITIAL_LOCK_PID }
DLLEXPORT void
dyninst_init_lock(dyninst_lock_t* lock);
DLLEXPORT void
dyninst_free_lock(dyninst_lock_t* lock);
DLLEXPORT int
dyninst_lock(dyninst_lock_t* lock);
DLLEXPORT void
dyninst_unlock(dyninst_lock_t* lock);
/**
* Internal functions that we export to ensure they show up.
**/
DLLEXPORT void
DYNINSTsafeBreakPoint();
DLLEXPORT void
DYNINSTinit();
DLLEXPORT void
DYNINST_snippetBreakpoint();
DLLEXPORT void
DYNINST_stopThread(void*, void*, void*, void*);
DLLEXPORT void
DYNINST_stopInterProc(void*, void*, void*, void*, void*, void*);
DLLEXPORT void
RThandleShadow(void*, void*, void*, void*, void*);
DLLEXPORT unsigned long
RTtranslateMemory(unsigned long, unsigned long, unsigned long);
DLLEXPORT unsigned long
RTtranslateMemoryShift(unsigned long, unsigned long, unsigned long);
DLLEXPORT void*
DYNINSTos_malloc(size_t, void*, void*);
DLLEXPORT int
DYNINSTloadLibrary(char*);
/**
* And variables
**/
DLLEXPORT extern dyntid_t (*DYNINST_pthread_self)(void);
DLLEXPORT extern unsigned int DYNINSTobsCostLow;
DLLEXPORT extern int libdyninstAPI_RT_init_localCause;
DLLEXPORT extern int libdyninstAPI_RT_init_localPid;
DLLEXPORT extern int libdyninstAPI_RT_init_maxthreads;
DLLEXPORT extern int libdyninstAPI_RT_init_debug_flag;
DLLEXPORT extern struct DYNINST_bootstrapStruct DYNINST_bootstrap_info;
#endif
#endif
+122
파일 보기
@@ -0,0 +1,122 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if !defined(DYNTYPES_H)
# define DYNTYPES_H
# if defined(_MSC_VER)
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h>
# include <winsock2.h>
# endif
# ifndef FILE__
# if defined(_MSC_VER)
# define FILE__ \
(strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
# else
# define FILE__ \
(strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
# endif
# endif
# if defined(_POWER) && !defined(__GNUC__)
# define XLC
# endif
# include <unordered_map>
# include <unordered_set>
// NB: std::hash has overloads for [un]scoped enums
template <typename Key, typename Value, typename Hash = std::hash<Key>,
typename Comp = std::equal_to<Key>,
typename Alloc = std::allocator<std::pair<const Key, Value>>>
using dyn_hash_map = std::unordered_map<Key, Value, Hash, Comp, Alloc>;
template <typename Key, typename Hash = std::hash<Key>,
typename Comp = std::equal_to<Key>, typename Alloc = std::allocator<Key>>
using dyn_hash_set = std::unordered_set<Key, Hash, Comp, Alloc>;
// We require C++11 thread_local support
# define dyn_tls thread_local
namespace Dyninst
{
# if defined(_WIN64)
typedef uintptr_t Address;
typedef uintptr_t Offset;
# else
typedef unsigned long Address;
typedef unsigned long Offset;
# endif
# if defined(_MSC_VER)
typedef int PID;
typedef HANDLE PROC_HANDLE;
typedef HANDLE LWP;
typedef HANDLE THR_ID;
typedef DWORD psaddr_t; // for breakpoints; match the debug struct
# define NULL_PID -1
# define NULL_LWP INVALID_HANDLE_VALUE
# define NULL_THR_ID INVALID_HANDLE_VALUE
# define DYNINST_SINGLETHREADED INVALID_HANDLE_VALUE
# else
typedef int PID;
typedef int PROC_HANDLE;
typedef int LWP;
typedef long THR_ID;
# define NULL_PID -1
# define NULL_LWP -1
# define NULL_THR_ID -1
# ifndef INVALID_HANDLE_VALUE
# define INVALID_HANDLE_VALUE -1
# endif
# endif
int
ThrIDToTid(Dyninst::THR_ID id);
} // namespace Dyninst
namespace Dyninst
{
typedef enum
{
OSNone,
Linux,
FreeBSD,
Windows
} OSType;
}
#endif
+243
파일 보기
@@ -0,0 +1,243 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if !defined(SYMTAB_EXPORT)
# if defined(_MSC_VER)
# if defined SYMTAB_LIB
# define SYMTAB_EXPORT __declspec(dllexport)
# else
# define SYMTAB_EXPORT __declspec(dllimport)
# endif
# else
# define SYMTAB_EXPORT __attribute__((visibility("default")))
# endif
#endif
#if !defined(SYMLITE_EXPORT)
# if defined(_MSC_VER)
# if defined SYMLITE_LIB
# define SYMLITE_EXPORT __declspec(dllexport)
# else
# define SYMLITE_EXPORT __declspec(dllimport)
# endif
# else
# define SYMLITE_EXPORT __attribute__((visibility("default")))
# endif
#endif
#if !defined(DYNELF_EXPORT)
# if defined(_MSC_VER)
# if defined DYNELF_LIB
# define DYNELF_EXPORT __declspec(dllexport)
# else
# define DYNELF_EXPORT __declspec(dllimport)
# endif
# else
# define DYNELF_EXPORT __attribute__((visibility("default")))
# endif
#endif
#if !defined(DYNDWARF_EXPORT)
# if defined(_MSC_VER)
# if defined DYNDWARF_LIB
# define DYNDWARF_EXPORT __declspec(dllexport)
# else
# define DYNDWARF_EXPORT __declspec(dllimport)
# endif
# else
# define DYNDWARF_EXPORT __attribute__((visibility("default")))
# endif
#endif
#if !defined(COMMON_EXPORT)
# if defined(_MSC_VER)
# if defined(COMMON_LIB)
# define COMMON_EXPORT __declspec(dllexport)
# else
# define COMMON_EXPORT __declspec(dllimport)
# endif
# else
# define COMMON_EXPORT __attribute__((visibility("default")))
# endif
#endif
#if !defined(COMMON_TEMPLATE_EXPORT)
# if defined(_MSC_VER)
# if defined(COMMON_LIB) || defined(INSTRUCTION_LIB) || defined(SYMTAB_LIB) || \
defined(BPATCH_LIBRARY)
# define COMMON_TEMPLATE_EXPORT __declspec(dllexport)
# else
# define COMMON_TEMPLATE_EXPORT __declspec(dllimport)
# endif
# else
# define COMMON_TEMPLATE_EXPORT __attribute__((visibility("default")))
# endif
#endif
#if !defined(INSTRUCTION_EXPORT)
# if defined(_MSC_VER)
# if defined(INSTRUCTION_LIB)
# define INSTRUCTION_EXPORT __declspec(dllexport)
# else
# define INSTRUCTION_EXPORT __declspec(dllimport)
# endif
# else
# define INSTRUCTION_EXPORT __attribute__((visibility("default")))
# endif
#endif
#if !defined(PARSER_EXPORT)
# if defined(_MSC_VER)
# if defined(PARSER_LIB)
# define PARSER_EXPORT __declspec(dllexport)
# else
# define PARSER_EXPORT __declspec(dllimport)
# endif
# else
# define PARSER_EXPORT __attribute__((visibility("default")))
# endif
#endif
#if !defined(PATCHAPI_EXPORT)
# if defined(_MSC_VER)
# if defined(PATCHAPI_LIB)
# define PATCHAPI_EXPORT __declspec(dllexport)
# else
# define PATCHAPI_EXPORT __declspec(dllimport)
# endif
# else
# define PATCHAPI_EXPORT __attribute__((visibility("default")))
# endif
#endif
#if !defined(DATAFLOW_EXPORT)
# if defined(_MSC_VER)
# if defined(DATAFLOW_LIB)
# define DATAFLOW_EXPORT __declspec(dllexport)
# else
# define DATAFLOW_EXPORT __declspec(dllimport)
# endif
# else
# define DATAFLOW_EXPORT __attribute__((visibility("default")))
# endif
#endif
#if !defined(PC_EXPORT)
# if defined(_MSC_VER)
# if defined(PROCCONTROL_EXPORTS)
# define PC_EXPORT __declspec(dllexport)
# else
# define PC_EXPORT __declspec(dllimport)
# endif
# else
# define PC_EXPORT __attribute__((visibility("default")))
# endif
#endif
#if !defined(SW_EXPORT)
# if defined(_MSC_VER)
# if defined(STACKWALKER_EXPORTS)
# define SW_EXPORT __declspec(dllexport)
# else
# define SW_EXPORT __declspec(dllimport)
# endif
# else
# define SW_EXPORT __attribute__((visibility("default")))
# endif
#endif
#if !defined(INJECTOR_EXPORT)
# if defined(_MSC_VER)
# if defined(INJECTOR_EXPORTS)
# define INJECTOR_EXPORT __declspec(dllexport)
# else
# define INJECTOR_EXPORT __declspec(dllimport)
# endif
# else
# define INJECTOR_EXPORT __attribute__((visibility("default")))
# endif
#endif
#if !defined(SYMEVAL_EXPORT)
# if defined(_MSC_VER)
# if defined(SYMEVAL_LIB)
# define SYMEVAL_EXPORT __declspec(dllexport)
# else
# define SYMEVAL_EXPORT __declspec(dllimport)
# endif
# else
# define SYMEVAL_EXPORT __attribute__((visibility("default")))
# endif
#endif
#ifndef __UTIL_H__
# define __UTIL_H__
# include "dyntypes.h"
# include <string>
# if defined(_MSC_VER)
# pragma warning(disable : 4251 4275 4396 4996)
# endif
namespace Dyninst
{
COMMON_EXPORT unsigned
addrHashCommon(const Address& addr);
COMMON_EXPORT unsigned
ptrHash(const void* addr);
COMMON_EXPORT unsigned
ptrHash(void* addr);
COMMON_EXPORT unsigned
addrHash(const Address& addr);
COMMON_EXPORT unsigned
addrHash4(const Address& addr);
COMMON_EXPORT unsigned
addrHash16(const Address& addr);
COMMON_EXPORT unsigned
stringhash(const std::string& s);
COMMON_EXPORT std::string
itos(int);
COMMON_EXPORT std::string
utos(unsigned);
# define WILDCARD_CHAR '?'
# define MULTIPLE_WILDCARD_CHAR '*'
COMMON_EXPORT bool
wildcardEquiv(const std::string& us, const std::string& them, bool checkCase = false);
const char*
platform_string();
} // namespace Dyninst
#endif
@@ -0,0 +1,16 @@
curRPC
DYNINSTversion
DYNINSTobsCostLow
DYNINSTglobalData
DYNINSTinit
DYNINSTos_init
pcAtLastIRPC
DYNINSTos_malloc
DYNINSTos_free
DYNINSTheap_useMalloc
DYNINSTheap_mmapFdOpen
DYNINSTheap_mmapFdClose
DYNINSTgetMemoryMap
DYNINSTstaticHeap_16M_textHeap_1
DYNINSTstaticHeap_16M_anyHeap_1
DYNINSTstaticHeap_32K_lowmemHeap_1
+814
파일 보기
@@ -0,0 +1,814 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* $Id: RTcommon.c,v 1.78 2008/04/15 16:43:44 roundy Exp $ */
#include "RTcommon.h"
#include "RTthread.h"
#include "h/dyninstAPI_RT.h"
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
unsigned int DYNINSTobsCostLow;
DLLEXPORT unsigned int DYNINSThasInitialized = 0;
struct DYNINST_bootstrapStruct DYNINST_bootstrap_info;
char gLoadLibraryErrorString[ERROR_STRING_LENGTH];
int DYNINSTdebugRTlib = 0;
DLLEXPORT int DYNINSTstaticMode = 1;
/**
* Allocate the Dyninst heaps
*
* The IA-64 requires that instruction be 16-byte aligned, so we have to
* align the heaps if we want to use them for inferior RPCs.
**/
#define HEAP_TYPE double
#define ALIGN_ATTRIB
#if defined(os_linux) || defined(os_freebsd)
# define HEAP_LOCAL extern
#else
# define HEAP_LOCAL DLLEXPORT
#endif
HEAP_LOCAL HEAP_TYPE
DYNINSTglobalData[SYN_INST_BUF_SIZE / sizeof(HEAP_TYPE)] ALIGN_ATTRIB;
#if !defined(target_smallmem)
HEAP_LOCAL HEAP_TYPE
DYNINSTstaticHeap_512K_lowmemHeap_1[512 * 1024 / sizeof(HEAP_TYPE)] ALIGN_ATTRIB;
HEAP_LOCAL HEAP_TYPE
DYNINSTstaticHeap_16M_anyHeap_1[16 * 1024 * 1024 / sizeof(HEAP_TYPE)] ALIGN_ATTRIB;
/* These are necessary due to silly C-style 'extern'/linking conventions. */
const unsigned long sizeOfLowMemHeap1 = sizeof(DYNINSTstaticHeap_512K_lowmemHeap_1);
const unsigned long sizeOfAnyHeap1 = sizeof(DYNINSTstaticHeap_16M_anyHeap_1);
#else
HEAP_LOCAL HEAP_TYPE
DYNINSTstaticHeap_8K_lowmemHeap_1[8 * 1024 / sizeof(HEAP_TYPE)] ALIGN_ATTRIB;
HEAP_LOCAL HEAP_TYPE
DYNINSTstaticHeap_32K_anyHeap_1[32 * 1024 / sizeof(HEAP_TYPE)] ALIGN_ATTRIB;
/* These are necessary due to silly C-style 'extern'/linking conventions. */
const unsigned long sizeOfLowMemHeap1 = sizeof(DYNINSTstaticHeap_8K_lowmemHeap_1);
const unsigned long sizeOfAnyHeap1 = sizeof(DYNINSTstaticHeap_32K_anyHeap_1);
#endif
/**
* One some platforms we can tell when a fork or exec is occurring through
* system-provided events. On others we do it ourselves. Enumerated type
* defined in header file
**/
DLLEXPORT DYNINST_synch_event_t DYNINST_synch_event_id = DSE_undefined;
DLLEXPORT void* DYNINST_synch_event_arg1;
/* Code to read args 2,3 would have to be moved from dyninstAPI's*/
/* process::handleStopThread to signalgenerator::decodeRTSignal in*/
/* order for other signals to make use of them, as currently only the*/
/* stopThread event needs makes use of them. */
DLLEXPORT void* DYNINST_synch_event_arg2 = NULL; /* not read in dyninst's decodeRTSignal*/
DLLEXPORT void* DYNINST_synch_event_arg3 = NULL; /* not read in dyninst's decodeRTSignal*/
DLLEXPORT int DYNINST_break_point_event = 0;
/**
* These variables are used to pass arguments into DYNINSTinit
* when it is called as an _init function
**/
int libdyninstAPI_RT_init_localCause = -1;
int libdyninstAPI_RT_init_localPid = -1;
int libdyninstAPI_RT_init_maxthreads = -1;
int libdyninstAPI_RT_init_debug_flag = 0;
int DYNINST_mutatorPid;
int DYNINSTdebugPrintRT = 0;
int isMutatedExec = 0;
// stopThread cache variables
char cacheLRUflags[TARGET_CACHE_WIDTH];
DLLEXPORT void* DYNINST_target_cache[TARGET_CACHE_WIDTH][TARGET_CACHE_WAYS];
FILE* stOut;
int fakeTickCount;
#ifdef _MSC_VER
# define TLS_VAR __declspec(thread)
#else
// Note, the initial-exec model gives us static TLS which can be accessed
// directly, unlike dynamic TLS that calls __tls_get_addr(). Such calls risk
// recursing back to us if they're also instrumented, ad infinitum. Static TLS
// must be used very sparingly though, because it is a limited resource.
// *** This case is very special -- do not use IE in general libraries! ***
# if defined(DYNINST_RT_STATIC_LIB)
# define TLS_VAR __thread __attribute__((tls_model("local-exec")))
# else
# define TLS_VAR __thread __attribute__((tls_model("initial-exec")))
# endif
#endif
// It's tempting to make this a char, but glibc < 2.17 hits a bug:
// https://sourceware.org/bugzilla/show_bug.cgi?id=14898
static TLS_VAR short DYNINST_tls_tramp_guard = 1;
DLLEXPORT int
DYNINST_lock_tramp_guard()
{
if(!DYNINST_tls_tramp_guard) return 0;
DYNINST_tls_tramp_guard = 0;
return 1;
}
DLLEXPORT void
DYNINST_unlock_tramp_guard()
{
DYNINST_tls_tramp_guard = 1;
}
DECLARE_DYNINST_LOCK(DYNINST_trace_lock);
/**
* Init the FPU. We've seen bugs with Linux (e.g., Redhat 6.2 stock kernel on
* PIIIs) where processes started by Paradyn started with FPU uninitialized.
* DYNINSTdummydouble is global so the compiler won't optimize away FP code
* in initFPU
**/
double DYNINSTdummydouble = 4321.71;
static void
initFPU()
{
double x = 17.1234;
DYNINSTdummydouble *= x;
}
/**
* This function is called in both static and dynamic rewriting, on
* all platforms that support binary rewriting, but before DYNINSTinit
**/
void
DYNINSTBaseInit()
{
#if defined(cap_mutatee_traps)
DYNINSTinitializeTrapHandler();
#endif
DYNINST_unlock_tramp_guard();
DYNINSThasInitialized = 1;
RTuntranslatedEntryCounter = 0;
}
/**
* The Dyninst API arranges for this function to be called at the entry to
* main() via libdyninstAPI_RT_init (defined in RTposix.c and RTwinnt.c).
* libdyninstAPI_RT_init is called by one of the following methods:
* GCC: link with gcc -shared, and use __attribute__((constructor));
* Linux: ld with -init libdyninstAPI_RT_init
* gcc with -Wl,-init -Wl,...
* Windows: called from DllMain, which exists in lieu of libdyninstAPI_RT_init
*
* This is only called in the Dynamic instrumentation case. Static
* libraries don't call this.
**/
void
DYNINSTinit()
{
rtdebug_printf("%s[%d]: DYNINSTinit: welcome to DYNINSTinit()\n", __FILE__,
__LINE__);
initFPU();
mark_heaps_exec();
tc_lock_init(&DYNINST_trace_lock);
DYNINSThasInitialized = 1;
rtdebug_printf("%s[%d]: welcome to DYNINSTinit\n", __FILE__, __LINE__);
/* sanity check */
assert(sizeof(int64_t) == 8);
assert(sizeof(int32_t) == 4);
/* defensive stuff */
memset(DYNINST_target_cache, 0,
sizeof(void*) * TARGET_CACHE_WIDTH * TARGET_CACHE_WAYS);
memset(cacheLRUflags, 1, sizeof(char) * TARGET_CACHE_WIDTH);
// stOut = fopen("rtdump.txt","w");
rtdebug_printf("%s[%d]: leaving DYNINSTinit\n", __FILE__, __LINE__);
fakeTickCount = 0;
/* Memory emulation */
}
/**
* Does what it's called. Used by the paradyn daemon as a default in certain
* cases (MT in particular)
**/
int
DYNINSTreturnZero()
{
return 0;
}
/* Used to by dyninst breakpoint snippet */
void
DYNINST_snippetBreakpoint()
{
tc_lock_lock(&DYNINST_trace_lock);
/* Set the state so the mutator knows what's up */
DYNINST_synch_event_id = DSE_snippetBreakpoint;
DYNINST_synch_event_arg1 = NULL;
/* Stop ourselves */
DYNINSTbreakPoint();
/* Once the stop completes, clean up */
DYNINST_synch_event_id = DSE_undefined;
tc_lock_unlock(&DYNINST_trace_lock);
}
/* Used to instrument (and report) the entry of fork */
DLLEXPORT void
DYNINST_instForkEntry()
{
tc_lock_lock(&DYNINST_trace_lock);
/* Set the state so the mutator knows what's up */
DYNINST_synch_event_id = DSE_forkEntry;
DYNINST_synch_event_arg1 = NULL;
/* Stop ourselves */
DYNINSTbreakPoint();
/* Once the stop completes, clean up */
DYNINST_synch_event_id = DSE_undefined;
DYNINST_synch_event_arg1 = NULL;
tc_lock_unlock(&DYNINST_trace_lock);
}
/* Used to instrument (and report) the exit of fork */
/* We use the safe breakpoint on the child side of fork
as we may not be attached at that point. The parent
side uses the normal version. */
DLLEXPORT void
DYNINST_instForkExit(void* arg1)
{
//#warning "This function is not implemented for AARCH64 yet!"
#if !defined(arch_aarch64)
tc_lock_lock(&DYNINST_trace_lock);
/* Set the state so the mutator knows what's up */
DYNINST_synch_event_id = DSE_forkExit;
DYNINST_synch_event_arg1 = arg1;
/* Stop ourselves */
if((long int) arg1 == 0)
{
/* Child... */
DYNINSTsafeBreakPoint();
}
else
{
DYNINSTbreakPoint();
}
/* Once the stop completes, clean up */
DYNINST_synch_event_id = DSE_undefined;
DYNINST_synch_event_arg1 = NULL;
tc_lock_unlock(&DYNINST_trace_lock);
#else
// Silence compiler warnings
(void) arg1;
assert(0);
#endif
}
/* Used to instrument (and report) the entry of exec */
DLLEXPORT void
DYNINST_instExecEntry(void* arg1)
{
//#warning "This function is not implemented for AARCH64 yet!"
#if !defined(arch_aarch64)
tc_lock_lock(&DYNINST_trace_lock);
/* Set the state so the mutator knows what's up */
DYNINST_synch_event_id = DSE_execEntry;
DYNINST_synch_event_arg1 = arg1;
/* Stop ourselves */
DYNINSTbreakPoint();
/* Once the stop completes, clean up */
DYNINST_synch_event_id = DSE_undefined;
DYNINST_synch_event_arg1 = NULL;
tc_lock_unlock(&DYNINST_trace_lock);
#endif
// Silence compiler warnings
(void) arg1;
}
/* Used to instrument (and report) the exit of exec */
DLLEXPORT void
DYNINST_instExecExit(void* arg1)
{
tc_lock_lock(&DYNINST_trace_lock);
/* Set the state so the mutator knows what's up */
DYNINST_synch_event_id = DSE_execExit;
DYNINST_synch_event_arg1 = arg1;
/* Stop ourselves */
DYNINSTbreakPoint();
/* Once the stop completes, clean up */
DYNINST_synch_event_id = DSE_undefined;
DYNINST_synch_event_arg1 = NULL;
tc_lock_unlock(&DYNINST_trace_lock);
}
/* Used to instrument (and report) the entry of exit */
DLLEXPORT void
DYNINST_instExitEntry(void* arg1)
{
tc_lock_lock(&DYNINST_trace_lock);
/* Set the state so the mutator knows what's up */
DYNINST_synch_event_id = DSE_exitEntry;
DYNINST_synch_event_arg1 = arg1;
/* Stop ourselves */
DYNINSTbreakPoint();
/* Once the stop completes, clean up */
DYNINST_synch_event_id = DSE_undefined;
DYNINST_synch_event_arg1 = NULL;
tc_lock_unlock(&DYNINST_trace_lock);
}
/* Used to instrument (and report) the entry of exit */
DLLEXPORT void
DYNINST_instLoadLibrary(void* arg1)
{
tc_lock_lock(&DYNINST_trace_lock);
/* Set the state so the mutator knows what's up */
DYNINST_synch_event_id = DSE_loadLibrary;
DYNINST_synch_event_arg1 = arg1;
/* Stop ourselves */
DYNINSTbreakPoint();
/* Once the stop completes, clean up */
DYNINST_synch_event_id = DSE_undefined;
DYNINST_synch_event_arg1 = NULL;
tc_lock_unlock(&DYNINST_trace_lock);
}
/* Used to instrument (and report) the entry of exit */
DLLEXPORT void
DYNINST_instLwpExit(void)
{
tc_lock_lock(&DYNINST_trace_lock);
/* Set the state so the mutator knows what's up */
DYNINST_synch_event_id = DSE_lwpExit;
DYNINST_synch_event_arg1 = NULL;
/* Stop ourselves */
DYNINSTbreakPoint();
/* Once the stop completes, clean up */
DYNINST_synch_event_id = DSE_undefined;
DYNINST_synch_event_arg1 = NULL;
tc_lock_unlock(&DYNINST_trace_lock);
}
// implementation of an N=2 way associative cache to keep access time low
// width = 32
// the cache contains valid addresses
// add to the cache when an instrumented instruction misses in the cache
// update flags for the cache when an instrumented instruction hits in the cache
// instrumentation will take the form of a call to cache check
RT_Boolean
cacheLookup(void* calculation)
{
int index = ((unsigned long) calculation) % TARGET_CACHE_WIDTH;
if(DYNINST_target_cache[index][0] == calculation)
{
cacheLRUflags[index] = 0;
return RT_TRUE;
}
else if(DYNINST_target_cache[index][1] == calculation)
{
cacheLRUflags[index] = 1;
return RT_TRUE;
}
else
{ // miss
if(cacheLRUflags[index] == 0)
{
DYNINST_target_cache[index][1] = calculation;
cacheLRUflags[index] = 1;
}
else
{
DYNINST_target_cache[index][0] = calculation;
cacheLRUflags[index] = 0;
}
return RT_FALSE;
}
}
/**
* Receives two snippets as arguments and stops the mutatee
* while the mutator reads the arguments, saved to
* DYNINST_synch_event... global variables.
*
* if flag useCache==1, does a cache lookup and stops only
* if there is a cache miss
*
* The flags are:
* bit 0: useCache
* bit 1: true if interpAsTarget
* bit 2: true if interpAsReturnAddr
**/
//#define STACKDUMP
void
DYNINST_stopThread(void* pointAddr, void* callBackID, void* flags, void* calculation)
{
static int reentrant = 0;
RT_Boolean isInCache = RT_FALSE;
if(reentrant == 1)
{
return;
}
reentrant = 1;
tc_lock_lock(&DYNINST_trace_lock);
rtdebug_printf("RT_st: pt[%lx] flags[%lx] calc[%lx] ", (unsigned long) pointAddr,
(unsigned long) flags, (unsigned long) calculation);
#if 0 && defined STACKDUMP
//if (0 && ((unsigned long)calculation == 0x9746a3 ||
// (unsigned long)calculation == 0x77dd761b))
//{
fprintf(stOut,"RT_st: %lx(%lx)\n", (long)pointAddr,&calculation);
fprintf(stOut,"at instr w/ targ=%lx\n",(long)calculation);
for (bidx=0; bidx < 0x100; bidx+=4) {
fprintf(stOut,"0x%x: ", (int)stackBase+bidx);
fprintf(stOut,"%02hhx", stackBase[bidx]);
fprintf(stOut,"%02hhx", stackBase[bidx+1]);
fprintf(stOut,"%02hhx", stackBase[bidx+2]);
fprintf(stOut,"%02hhx", stackBase[bidx+3]);
fprintf(stOut,"\n");
}
//}
// fsg: read from 40a4aa, how did it become 40a380?
#endif
if((((long) flags) & 0x04))
{
rtdebug_printf("ret-addr stopThread yields %lx", (unsigned long) calculation);
// fprintf(stderr,"[$0x%lx]\n", (long)calculation);
}
if(0 != (((long) flags) & 0x03))
{
// do the lookup if the useCache bit is set, or if it represents
// the address of real code, so that we add the address to the cache
// even if we will stop the thread if there's a cache hit
isInCache = cacheLookup(calculation);
}
// if the cache flag bit is not set, or if we get a cache miss,
// stop the thread so that we can call back to the mutatee
if(0 == (((long) flags) & 0x01) || !isInCache)
{
/* Set vars for Dyninst to read */
DYNINST_synch_event_id = DSE_stopThread;
DYNINST_synch_event_arg1 = pointAddr;
DYNINST_synch_event_arg2 = callBackID;
DYNINST_synch_event_arg3 = calculation;
// encode interp as target or as return addr by making
// callback ID negative
if(0 != (((long) flags) & 0x06))
{
DYNINST_synch_event_arg2 = (void*) (-1 * (long) DYNINST_synch_event_arg2);
}
rtdebug_printf("stopping! isInCache=%d\n", isInCache);
/* Stop ourselves */
DYNINSTbreakPoint();
/* Once the stop completes, clean up */
DYNINST_synch_event_id = DSE_undefined;
DYNINST_synch_event_arg1 = NULL;
DYNINST_synch_event_arg2 = NULL;
DYNINST_synch_event_arg3 = NULL;
}
fflush(stOut);
tc_lock_unlock(&DYNINST_trace_lock);
reentrant = 0;
return;
}
// zeroes out the useCache flag if the call is interprocedural
void
DYNINST_stopInterProc(void* pointAddr, void* callBackID, void* flags, void* calculation,
void* objStart, void* objEnd)
{
#if defined STACKDUMP
fprintf(stOut, "RT_sip: calc=%lx objStart=%lx objEnd=%lx\n", calculation, objStart,
objEnd);
fflush(stOut);
#endif
if(calculation < objStart || calculation >= objEnd)
{
flags = (void*) ((long) (((int) ((long) flags)) & 0xfffffffe));
}
DYNINST_stopThread(pointAddr, callBackID, flags, calculation);
}
// boundsArray is a sequence of (blockStart,blockEnd) pairs
DLLEXPORT RT_Boolean
DYNINST_boundsCheck(void** boundsArray_, void* arrayLen_, void* writeTarget_)
{
RT_Boolean callStopThread = RT_FALSE;
const unsigned long writeTarget = (unsigned long) writeTarget_;
const long arrayLen = (long) arrayLen_;
unsigned long* boundsArray = (unsigned long*) boundsArray_;
// set idx to halfway into the array, ensuring we use a blockStart address
int idx = (int) arrayLen / 4 * 2;
int lowIdx = 0;
int highIdx = (int) arrayLen;
// fprintf(stderr,"D_bc@%p: boundsArray=%p target=%lx idx=%d arrayLen=%d [%d]\n",
// (void*)DYNINST_boundsCheck, boundsArray_, writeTarget_, idx, arrayLen, __LINE__);
// rtdebug_printf("D_bc@%p: boundsArray=%p target=%lx idx=%d arrayLen=%d [%d]\n",
// (void*)DYNINST_boundsCheck, boundsArray_, writeTarget_, idx, arrayLen, __LINE__);
if((unsigned long) boundsArray < 0x10000000)
{
printf("D_bc: boundsArray_ = %lx, returning false\n",
(unsigned long) boundsArray);
return RT_FALSE;
}
while(lowIdx < highIdx)
{
if(idx > arrayLen || idx < 0)
rtdebug_printf("ERROR: out of bounds idx=%d, arrayLen = %ld [%d]\n", idx,
arrayLen, __LINE__);
rtdebug_printf("D_bc: low=%d high=%d arr[%d]=%lx [%d]\n", lowIdx, highIdx, idx,
boundsArray[idx], __LINE__);
if(writeTarget < boundsArray[idx])
{
rtdebug_printf("D_bc: [%d]\n", __LINE__);
highIdx = idx;
idx = (highIdx - lowIdx) / 4 * 2 + lowIdx;
}
else if(boundsArray[idx + 1] <= writeTarget)
{
rtdebug_printf("D_bc: [%d]\n", __LINE__);
lowIdx = idx + 2;
idx = (highIdx - lowIdx) / 4 * 2 + lowIdx;
}
else
{
rtdebug_printf("D_bc: callST=true [%d]\n", __LINE__);
callStopThread = RT_TRUE;
break;
}
}
rtdebug_printf("D_bc: boundsArray=%p ret=%d [%d]\n", (void*) boundsArray,
callStopThread, __LINE__);
return callStopThread;
}
/**
* Used to report addresses of functions called at dynamic call sites
**/
DLLEXPORT int
DYNINSTasyncDynFuncCall(void* call_target, void* call_addr)
{
if(DYNINSTstaticMode) return 0;
tc_lock_lock(&DYNINST_trace_lock);
/* Set the state so the mutator knows what's up */
DYNINST_synch_event_id = DSE_dynFuncCall;
DYNINST_synch_event_arg1 = call_target;
DYNINST_synch_event_arg2 = call_addr;
/* Stop ourselves */
DYNINSTbreakPoint();
/* Once the stop completes, clean up */
DYNINST_synch_event_id = DSE_undefined;
DYNINST_synch_event_arg1 = NULL;
DYNINST_synch_event_arg2 = NULL;
tc_lock_unlock(&DYNINST_trace_lock);
return 0;
}
int
DYNINSTuserMessage(void* msg, unsigned int msg_size)
{
unsigned long msg_size_long = (unsigned long) msg_size;
if(DYNINSTstaticMode)
{
return 0;
}
tc_lock_lock(&DYNINST_trace_lock);
/* Set the state so the mutator knows what's up */
DYNINST_synch_event_id = DSE_userMessage;
DYNINST_synch_event_arg1 = msg;
DYNINST_synch_event_arg2 = (void*) msg_size_long;
/* Stop ourselves */
DYNINSTbreakPoint();
/* Once the stop completes, clean up */
DYNINST_synch_event_id = DSE_undefined;
DYNINST_synch_event_arg1 = NULL;
DYNINST_synch_event_arg2 = NULL;
tc_lock_unlock(&DYNINST_trace_lock);
return 0;
}
int
tc_lock_init(tc_lock_t* t)
{
t->mutex = 0;
t->tid = (dyntid_t) DYNINST_INITIAL_LOCK_PID;
return 0;
}
int
tc_lock_unlock(tc_lock_t* t)
{
t->tid = (dyntid_t) DYNINST_INITIAL_LOCK_PID;
t->mutex = 0;
return 0;
}
int
tc_lock_destroy(tc_lock_t* t)
{
t->tid = (dyntid_t) DYNINST_INITIAL_LOCK_PID;
t->mutex = 0;
return 0;
}
void
dyninst_init_lock(dyninst_lock_t* lock)
{
lock->tid = (dyntid_t) DYNINST_INITIAL_LOCK_PID;
lock->mutex = 0;
}
void
dyninst_free_lock(dyninst_lock_t* lock)
{
(void) lock; /* unused parameter */
}
int
dyninst_lock(dyninst_lock_t* lock)
{
return tc_lock_lock(lock);
}
void
dyninst_unlock(dyninst_lock_t* lock)
{
tc_lock_unlock(lock);
}
int
rtdebug_printf(const char* format, ...)
{
int ret;
va_list va;
if(!DYNINSTdebugRTlib) return 0;
if(NULL == format) return DYNINST_PRINTF_ERRVAL;
fprintf(stderr, "[RTLIB]");
va_start(va, format);
ret = vfprintf(stderr, format, va);
va_end(va);
return ret;
}
// clang-format off
#ifndef CASE_RETURN_STR
# define CASE_RETURN_STR(x) \
case x: return #x
#endif
// clang-format on
const char*
asyncEventType2str(rtBPatch_asyncEventType t)
{
switch(t)
{
CASE_RETURN_STR(rtBPatch_nullEvent);
CASE_RETURN_STR(rtBPatch_newConnectionEvent);
CASE_RETURN_STR(rtBPatch_internalShutDownEvent);
CASE_RETURN_STR(rtBPatch_threadCreateEvent);
CASE_RETURN_STR(rtBPatch_threadDestroyEvent);
CASE_RETURN_STR(rtBPatch_dynamicCallEvent);
CASE_RETURN_STR(rtBPatch_userEvent);
default: return "bad_async_event_type";
}
}
DLLEXPORT volatile unsigned long dyninstTrapTableUsed;
DLLEXPORT volatile unsigned long dyninstTrapTableVersion;
DLLEXPORT volatile trapMapping_t* dyninstTrapTable;
DLLEXPORT volatile unsigned long dyninstTrapTableIsSorted;
void*
dyninstTrapTranslate(void* source, volatile unsigned long* table_used,
volatile unsigned long* table_version,
volatile trapMapping_t** trap_table,
volatile unsigned long* is_sorted)
{
volatile unsigned local_version;
unsigned i;
void* target;
do
{
local_version = *table_version;
target = NULL;
if(*is_sorted)
{
unsigned min = 0;
unsigned mid = 0;
unsigned max = *table_used;
unsigned prev = max + 1;
for(;;)
{
mid = (min + max) / 2;
if(mid == prev)
{
fprintf(stderr,
"ERROR: dyninstTrapTranslate couldn't find "
"entry for %p: min=%x mid=%x max=%x prev=%x\n",
source, min, mid, max, prev);
break;
}
prev = mid;
if((*trap_table)[mid].source < source)
min = mid;
else if((*trap_table)[mid].source > source)
max = mid;
else
{
target = (*trap_table)[mid].target;
break;
}
}
}
else
{ /*!dyninstTrapTableIsSorted*/
for(i = 0; i < *table_used; i++)
{
if((*trap_table)[i].source == source)
{
target = (*trap_table)[i].target;
break;
}
}
}
} while(local_version != *table_version);
return target;
}
DLLEXPORT void
DYNINSTtrapFunction()
{
__asm__ __volatile__("nop\n" :::);
}
+84
파일 보기
@@ -0,0 +1,84 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _RTCOMMON_H_
#define _RTCOMMON_H_
#include "RTthread.h"
#include "h/compiler_annotations.h"
#include "h/dyninstAPI_RT.h"
#include <stdarg.h>
void
DYNINSTtrapFunction();
void
DYNINSTbreakPoint();
/* Use a signal that is safe if we're not attached. */
void
DYNINSTsafeBreakPoint();
void
DYNINSTinit();
int
DYNINSTreturnZero();
int
DYNINSTwriteEvent(void* ev, size_t sz);
int
DYNINSTasyncConnect(int pid);
int
DYNINSTinitializeTrapHandler();
void*
dyninstTrapTranslate(void* source, volatile unsigned long* table_used,
volatile unsigned long* table_version,
volatile trapMapping_t** trap_table,
volatile unsigned long* is_sorted);
extern int DYNINST_mutatorPid;
extern int libdyninstAPI_RT_init_localCause;
extern int libdyninstAPI_RT_init_localPid;
extern int libdyninstAPI_RT_init_maxthreads;
extern int libdyninstAPI_RT_init_debug_flag;
extern int DYNINSTdebugPrintRT;
extern tc_lock_t DYNINST_trace_lock;
extern void*
map_region(void* addr, int len, int fd);
extern int
unmap_region(void* addr, int len);
extern void
mark_heaps_exec(void);
extern int DYNINSTdebugRTlib;
DLLEXPORT extern int DYNINSTstaticMode;
int
rtdebug_printf(const char* format, ...) DYNINST_PRINTF_ANNOTATION(1, 2);
#endif
+729
파일 보기
@@ -0,0 +1,729 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/************************************************************************
* $Id: RTlinux.c,v 1.54 2008/04/11 23:30:44 legendre Exp $
* RTlinux.c: mutatee-side library function specific to Linux
************************************************************************/
#include "h/dyninstAPI_RT.h"
#include "src/RTcommon.h"
#include "src/RTthread.h"
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <dlfcn.h>
#include <errno.h>
#include <link.h>
#include <signal.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <sys/types.h>
/* FreeBSD libc has stubs so a static version shouldn't need libpthreads */
#include <pthread.h>
extern double DYNINSTstaticHeap_512K_lowmemHeap_1[];
extern double DYNINSTstaticHeap_16M_anyHeap_1[];
extern unsigned long sizeOfLowMemHeap1;
extern unsigned long sizeOfAnyHeap1;
static struct trap_mapping_header*
getStaticTrapMap(unsigned long addr);
/** RT lib initialization **/
void
mark_heaps_exec()
{
RTprintf("*** Initializing dyninstAPI runtime.\n");
/* Grab the page size, to align the heap pointer. */
long int pageSize = sysconf(_SC_PAGESIZE);
if(pageSize == 0 || pageSize == -1)
{
fprintf(stderr, "*** Failed to obtain page size, guessing 16K.\n");
perror("mark_heaps_exec");
pageSize = 1024 * 16;
} /* end pageSize initialization */
/* Align the heap pointer. */
unsigned long int alignedHeapPointer =
(unsigned long int) DYNINSTstaticHeap_16M_anyHeap_1;
alignedHeapPointer = (alignedHeapPointer) & ~(pageSize - 1);
unsigned long int adjustedSize = (unsigned long int) DYNINSTstaticHeap_16M_anyHeap_1 -
alignedHeapPointer + sizeOfAnyHeap1;
/* Make the heap's page executable. */
int result = mprotect((void*) alignedHeapPointer, (size_t) adjustedSize,
PROT_READ | PROT_WRITE | PROT_EXEC);
if(result != 0)
{
fprintf(stderr,
"%s[%d]: Couldn't make DYNINSTstaticHeap_16M_anyHeap_1 executable!\n",
__FILE__, __LINE__);
perror("mark_heaps_exec");
}
RTprintf("*** Marked memory from 0x%lx to 0x%lx executable.\n", alignedHeapPointer,
alignedHeapPointer + adjustedSize);
/* Mark _both_ heaps executable. */
alignedHeapPointer = (unsigned long int) DYNINSTstaticHeap_512K_lowmemHeap_1;
alignedHeapPointer = (alignedHeapPointer) & ~(pageSize - 1);
adjustedSize = (unsigned long int) DYNINSTstaticHeap_512K_lowmemHeap_1 -
alignedHeapPointer + sizeOfLowMemHeap1;
/* Make the heap's page executable. */
result = mprotect((void*) alignedHeapPointer, (size_t) adjustedSize,
PROT_READ | PROT_WRITE | PROT_EXEC);
if(result != 0)
{
fprintf(stderr,
"%s[%d]: Couldn't make DYNINSTstaticHeap_512K_lowmemHeap_1 executable!\n",
__FILE__, __LINE__);
perror("mark_heaps_exec");
}
RTprintf("*** Marked memory from 0x%lx to 0x%lx executable.\n", alignedHeapPointer,
alignedHeapPointer + adjustedSize);
} /* end mark_heaps_exec() */
#if defined(cap_binary_rewriter) && !defined(DYNINST_RT_STATIC_LIB)
/* For a static binary, all global constructors are combined in an undefined
* order. Also, DYNINSTBaseInit must be run after all global constructors have
* been run. Since the order of global constructors is undefined, DYNINSTBaseInit
* cannot be run as a constructor in static binaries. Instead, it is run from a
* special constructor handler that processes all the global constructors in
* the binary. Leaving this code in would create a global constructor for the
* function runDYNINSTBaseInit(). See DYNINSTglobal_ctors_handler.
*/
extern void
DYNINSTBaseInit();
void
runDYNINSTBaseInit() __attribute__((constructor));
void
runDYNINSTBaseInit()
{
DYNINSTBaseInit();
}
#endif
/** Dynamic instrumentation support **/
static int
tkill(pid_t pid, long lwp, int sig)
{
static int has_tkill = 1;
int result = 0;
if(has_tkill)
{
result = syscall(SYS_thr_kill2, pid, lwp, sig);
if(0 != result && ENOSYS == errno)
{
has_tkill = 0;
}
}
if(!has_tkill)
{
result = kill(pid, sig);
}
return (result == 0);
}
void
DYNINSTbreakPoint()
{
if(DYNINSTstaticMode) return;
DYNINST_break_point_event = 1;
while(DYNINST_break_point_event)
{
tkill(getpid(), dyn_lwp_self(), DYNINST_BREAKPOINT_SIGNUM);
}
/* Mutator resets to 0 */
}
static int failed_breakpoint = 0;
void
uncaught_breakpoint(int sig)
{
failed_breakpoint = 1;
}
void
DYNINSTsafeBreakPoint()
{
if(DYNINSTstaticMode) return;
DYNINST_break_point_event = 1;
while(DYNINST_break_point_event)
{
tkill(getpid(), dyn_lwp_self(), SIGSTOP);
}
/* Mutator resets to 0 */
#if 0
if( DYNINSTstaticMode ) return;
DYNINST_break_point_event = 2;
sigset_t emptyset;
sigemptyset(&emptyset);
// There is a bug with attaching to a stopped process on FreeBSD This
// achieves the same result as long as Dyninst attaches to the process when
// it is in sigsuspend
while( DYNINST_break_point_event ) {
sigsuspend(&emptyset);
}
#endif
}
#if !defined(DYNINST_RT_STATIC_LIB)
static int
get_dlopen_error()
{
const char* err_str;
err_str = dlerror();
if(err_str)
{
strncpy(gLoadLibraryErrorString, err_str, (size_t) ERROR_STRING_LENGTH);
return 1;
}
sprintf(gLoadLibraryErrorString, "unknown error withe dlopen");
return 0;
}
int
DYNINSTloadLibrary(char* libname)
{
void* res;
gLoadLibraryErrorString[0] = '\0';
res = dlopen(libname, RTLD_NOW | RTLD_GLOBAL);
if(res) return 1;
get_dlopen_error();
return 0;
}
#endif
/** threading support **/
int
dyn_lwp_self()
{
static int gettid_not_valid = 0;
int result;
if(gettid_not_valid) return getpid();
long lwp_id;
result = syscall(SYS_thr_self, &lwp_id);
if(result && errno == ENOSYS)
{
gettid_not_valid = 1;
return getpid();
}
return lwp_id;
}
int
dyn_pid_self()
{
return getpid();
}
dyntid_t (*DYNINST_pthread_self)(void);
dyntid_t
dyn_pthread_self()
{
dyntid_t me;
if(DYNINSTstaticMode)
{
return (dyntid_t) pthread_self();
}
if(!DYNINST_pthread_self)
{
return (dyntid_t) DYNINST_SINGLETHREADED;
}
me = (*DYNINST_pthread_self)();
return (dyntid_t) me;
}
int
DYNINST_am_initial_thread(dyntid_t tid)
{
/*
* LWPs and PIDs are in different namespaces on FreeBSD.
*
* I don't really know a good way to determine this without
* doing an expensive sysctl.
*
* Luckily, this function isn't used anymore
*/
assert(!"This function is unimplemented on FreeBSD");
return 0;
}
/** trap based instrumentation **/
#if defined(cap_mutatee_traps)
# include <ucontext.h>
# if defined(arch_x86) || defined(MUTATEE_32)
# define UC_PC(x) x->uc_mcontext.mc_eip
# elif defined(arch_x86_64)
# define UC_PC(x) x->uc_mcontext.mc_rip
# endif // UC_PC
extern unsigned long dyninstTrapTableUsed;
extern unsigned long dyninstTrapTableVersion;
extern trapMapping_t* dyninstTrapTable;
extern unsigned long dyninstTrapTableIsSorted;
/**
* This comment is now obsolete, left for historic purposes
*
* Called by the SIGTRAP handler, dyninstTrapHandler. This function is
* closly intwined with dyninstTrapHandler, don't modify one without
* understanding the other.
*
* This function sets up the calling context that was passed to the
* SIGTRAP handler so that control will be redirected to our instrumentation
* when we do the setcontext call.
*
* There are a couple things that make this more difficult than it should be:
* 1. The OS provided calling context is similar to the GLIBC calling context,
* but not compatible. We'll create a new GLIBC compatible context and
* copy the possibly stomped registers from the OS context into it. The
* incompatiblities seem to deal with FP and other special purpose registers.
* 2. setcontext doesn't restore the flags register. Thus dyninstTrapHandler
* will save the flags register first thing and pass us its value in the
* flags parameter. We'll then push the instrumentation entry and flags
* onto the context's stack. Instead of transfering control straight to the
* instrumentation, we'll actually go back to dyninstTrapHandler, which will
* do a popf/ret to restore flags and go to instrumentation. The 'retPoint'
* parameter is the address in dyninstTrapHandler the popf/ret can be found.
**/
void
dyninstTrapHandler(int sig, siginfo_t* sg, ucontext_t* context)
{
void* orig_ip;
void* trap_to;
orig_ip = UC_PC(context);
assert(orig_ip);
// Find the new IP we're going to and substitute. Leave everything else untouched
if(DYNINSTstaticMode)
{
unsigned long zero = 0;
unsigned long one = 1;
struct trap_mapping_header* hdr = getStaticTrapMap((unsigned long) orig_ip);
if(!hdr) return;
assert(hdr);
trapMapping_t* mapping = &(hdr->traps[0]);
trap_to = dyninstTrapTranslate(orig_ip, (unsigned long*) &hdr->num_entries, &zero,
(volatile trapMapping_t**) &mapping, &one);
}
else
{
trap_to = dyninstTrapTranslate(
orig_ip, &dyninstTrapTableUsed, &dyninstTrapTableVersion,
(volatile trapMapping_t**) &dyninstTrapTable, &dyninstTrapTableIsSorted);
}
UC_PC(context) = (long) trap_to;
}
# if defined(cap_binary_rewriter)
# define NUM_LIBRARIES 512 // Important, max number of rewritten libraries
# define WORD_SIZE (8 * sizeof(unsigned))
# define NUM_LIBRARIES_BITMASK_SIZE (1 + NUM_LIBRARIES / WORD_SIZE)
struct trap_mapping_header* all_headers[NUM_LIBRARIES];
static unsigned all_headers_current[NUM_LIBRARIES_BITMASK_SIZE];
static unsigned all_headers_last[NUM_LIBRARIES_BITMASK_SIZE];
# if !defined(arch_x86_64) || defined(MUTATEE_32)
typedef Elf32_Dyn ElfX_Dyn;
typedef Elf32_Ehdr ElfX_Ehdr;
# else
typedef Elf64_Dyn ElfX_Dyn;
typedef Elf64_Ehdr ElfX_Ehdr;
# endif
static int
parse_libs();
static int
parse_link_map(struct link_map* l);
static void
clear_unloaded_libs();
static void
set_bit(unsigned* bit_mask, int bit, char value);
static void
clear_bitmask(unsigned* bit_mask);
static unsigned
get_next_free_bitmask(unsigned* bit_mask, int last_pos);
static unsigned
get_next_set_bitmask(unsigned* bit_mask, int last_pos);
static tc_lock_t trap_mapping_lock;
static struct trap_mapping_header*
getStaticTrapMap(unsigned long addr)
{
struct trap_mapping_header* header;
int i;
tc_lock_lock(&trap_mapping_lock);
parse_libs();
i = -1;
for(;;)
{
i = get_next_set_bitmask(all_headers_current, i);
assert(i >= 0 && i <= NUM_LIBRARIES);
if(i == NUM_LIBRARIES)
{
header = NULL;
goto done;
}
header = all_headers[i];
if(addr >= header->low_entry && addr <= header->high_entry)
{
goto done;
}
}
done:
tc_lock_unlock(&trap_mapping_lock);
return header;
}
static struct link_map*
getLinkMap()
{
struct link_map* map = NULL;
# if !defined(DYNINST_RT_STATIC_LIB)
if(dlinfo(RTLD_SELF, RTLD_DI_LINKMAP, &map))
{
return NULL;
}
// Rewind the current link map pointer to find the
// start of the list
struct link_map* last_map;
while(map != NULL)
{
last_map = map;
map = map->l_prev;
}
map = last_map;
# endif
return map;
}
static int
parse_libs()
{
struct link_map* l_current;
l_current = getLinkMap();
if(!l_current) return -1;
clear_bitmask(all_headers_current);
while(l_current)
{
parse_link_map(l_current);
l_current = l_current->l_next;
}
clear_unloaded_libs();
return 0;
}
// parse_link_map return values
# define PARSED 0
# define NOT_REWRITTEN 1
# define ALREADY_PARSED 2
# define ERROR_INTERNAL -1
# define ERROR_FULL -2
static int
parse_link_map(struct link_map* l)
{
ElfX_Dyn* dynamic_ptr;
struct trap_mapping_header* header;
unsigned int i, new_pos;
dynamic_ptr = (ElfX_Dyn*) l->l_ld;
if(!dynamic_ptr) return -1;
assert(sizeof(dynamic_ptr->d_un.d_ptr) == sizeof(void*));
for(; dynamic_ptr->d_tag != DT_NULL && dynamic_ptr->d_tag != DT_DYNINST;
dynamic_ptr++)
;
if(dynamic_ptr->d_tag == DT_NULL)
{
return NOT_REWRITTEN;
}
header = (struct trap_mapping_header*) (dynamic_ptr->d_un.d_val + l->l_addr);
caddr_t libAddr = l->l_addr;
// Executables have an implicit zero load address but the library load address
// may be non-zero
if(((ElfX_Ehdr*) libAddr)->e_type == ET_EXEC)
{
libAddr = 0;
}
else if(((ElfX_Ehdr*) libAddr)->e_type == ET_DYN)
{
// Account for library_adjust mechanism which is used for shared libraries
// on FreeBSD
libAddr += getpagesize();
}
header = (struct trap_mapping_header*) (dynamic_ptr->d_un.d_val + libAddr);
if(header->signature != TRAP_HEADER_SIG) return ERROR_INTERNAL;
if(header->pos != -1)
{
set_bit(all_headers_current, header->pos, 1);
assert(all_headers[header->pos] == header);
return ALREADY_PARSED;
}
for(i = 0; i < header->num_entries; i++)
{
header->traps[i].source =
(void*) (((unsigned long) header->traps[i].source) + libAddr);
header->traps[i].target =
(void*) (((unsigned long) header->traps[i].target) + libAddr);
if(!header->low_entry ||
header->low_entry > (unsigned long) header->traps[i].source)
header->low_entry = (unsigned long) header->traps[i].source;
if(!header->high_entry ||
header->high_entry < (unsigned long) header->traps[i].source)
header->high_entry = (unsigned long) header->traps[i].source;
}
new_pos = get_next_free_bitmask(all_headers_last, -1);
assert(new_pos >= 0 && new_pos < NUM_LIBRARIES);
if(new_pos == NUM_LIBRARIES) return ERROR_FULL;
header->pos = new_pos;
all_headers[new_pos] = header;
set_bit(all_headers_current, new_pos, 1);
set_bit(all_headers_last, new_pos, 1);
return PARSED;
}
static void
clear_unloaded_libs()
{
unsigned i;
for(i = 0; i < NUM_LIBRARIES_BITMASK_SIZE; i++)
{
all_headers_last[i] = all_headers_current[i];
}
}
static void
set_bit(unsigned* bit_mask, int bit, char value)
{
assert(bit < NUM_LIBRARIES);
unsigned* word = bit_mask + bit / WORD_SIZE;
unsigned shift = bit % WORD_SIZE;
if(value)
{
*word |= (1 << shift);
}
else
{
*word &= ~(1 << shift);
}
}
static void
clear_bitmask(unsigned* bit_mask)
{
unsigned i;
for(i = 0; i < NUM_LIBRARIES_BITMASK_SIZE; i++)
{
bit_mask[i] = 0;
}
}
static unsigned
get_next_free_bitmask(unsigned* bit_mask, int last_pos)
{
unsigned i, j;
j = last_pos + 1;
i = j / WORD_SIZE;
for(; j < NUM_LIBRARIES; i++)
{
if(bit_mask[i] == (unsigned) -1)
{
j += WORD_SIZE;
continue;
}
for(;;)
{
if(!((1 << (j % WORD_SIZE) & bit_mask[i])))
{
return j;
}
j++;
if(j % WORD_SIZE == 0)
{
break;
}
}
}
return NUM_LIBRARIES;
}
static unsigned
get_next_set_bitmask(unsigned* bit_mask, int last_pos)
{
unsigned i, j;
j = last_pos + 1;
i = j / WORD_SIZE;
for(; j < NUM_LIBRARIES; i++)
{
if(bit_mask[i] == (unsigned) 0)
{
j += WORD_SIZE;
continue;
}
for(;;)
{
if((1 << (j % WORD_SIZE) & bit_mask[i]))
{
return j;
}
j++;
if(j % WORD_SIZE == 0)
{
break;
}
}
}
return NUM_LIBRARIES;
}
# endif
#endif /* cap_mutatee_traps */
/*
* Note: this program is for historical purposes only, we use libthread_db
* now to get thread information.
*
* A program to determine the offsets of certain thread structures on FreeBSD
*
* This program should be compiled with the headers from the libthr library from
* /usr/src. This can be installed using sysinstall. The following arguments
* should be added to the compile once these headers are installed.
*
* -I/usr/src/lib/libthr/arch/amd64/include -I/usr/src/lib/libthr/thread
*
* Change amd64 to what ever is appropriate.
#include <pthread.h>
#include <stdio.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
#include "thr_private.h"
pthread_attr_t attr;
void *foo(void *f) {
unsigned long stack_addr;
void *(*start_func)(void *);
unsigned long tid;
// Get all the values
syscall(SYS_thr_self, &tid);
start_func = foo;
asm("mov %%rbp,%0" : "=r" (stack_addr));
pthread_t threadSelf = pthread_self();
printf("TID: %u == %u\n", tid, threadSelf->tid);
printf("STACK: 0x%lx == 0x%lx\n", stack_addr, threadSelf->attr.stackaddr_attr +
threadSelf->attr.stacksize_attr); printf("START: 0x%lx == 0x%lx\n", (unsigned
long)start_func, (unsigned long)threadSelf->start_routine);
unsigned char *ptr = (unsigned char *)threadSelf;
unsigned long tidVal = *((unsigned long *)(ptr + offsetof(struct pthread, tid)));
unsigned long stackAddrVal = *((unsigned long *)(ptr + offsetof(struct pthread, attr)
+ offsetof(struct pthread_attr, stackaddr_attr))); unsigned long stackSizeVal =
*((unsigned long *)(ptr + offsetof(struct pthread, attr) + offsetof(struct pthread_attr,
stacksize_attr))); unsigned long startFuncVal = *((unsigned long *)(ptr + offsetof(struct
pthread, start_routine)));
printf("TID = %u, offset = %u\n", tidVal, offsetof(struct pthread, tid));
printf("STACK = 0x%lx, offset = %u\n", stackAddrVal, offsetof(struct pthread, attr) +
offsetof(struct pthread_attr, stackaddr_attr)); printf("SIZE = 0x%lx, offset = %u\n",
stackSizeVal, offsetof(struct pthread, attr) + offsetof(struct pthread_attr,
stacksize_attr)); printf("START = 0x%lx, offset = %u\n", startFuncVal, offsetof(struct
pthread, start_routine));
return NULL;
}
int main(int argc, char *argv[]) {
pthread_t t;
void *result;
pthread_attr_init(&attr);
pthread_create(&t, &attr, foo, NULL);
pthread_join(t, &result);
return 0;
}
*/
+85
파일 보기
@@ -0,0 +1,85 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* RTheap-freebsd.c: FreeBSD-specific heap components */
#include "RTheap.h"
#include <assert.h>
#include <fcntl.h> /* open() */
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* str* */
#include <sys/mman.h> /* mmap() */
#include <sys/stat.h> /* open() */
#include <sys/types.h>
#include <sys/uio.h> /* read() */
#include <unistd.h> /* sbrk(), read(), mmap */
#if defined(MUTATEE64)
int DYNINSTheap_align = 4; /* heaps are word-aligned */
Address DYNINSTheap_loAddr = 0x4096;
Address DYNINSTheap_hiAddr = ~0x0;
#else
int DYNINSTheap_align = 4; /* heaps are word-aligned */
Address DYNINSTheap_loAddr = 0x50000000;
Address DYNINSTheap_hiAddr = 0xb0000000;
#endif
int DYNINSTheap_mmapFlags = MAP_FIXED | MAP_PRIVATE;
RT_Boolean
DYNINSTheap_useMalloc(void* lo, void* hi)
{
/* We do not save footprint space by allocating in
the user's heap on this platform, so we stay out of it. */
return RT_FALSE;
}
int
DYNINSTheap_mmapFdOpen(void)
{
int fd = open("/dev/zero", O_RDWR);
return fd;
}
void
DYNINSTheap_mmapFdClose(int fd)
{
close(fd);
}
int
DYNINSTgetMemoryMap(unsigned* nump, dyninstmm_t** mapp)
{
assert(!"Unimplemented on FreeBSD for the time being");
return -1;
}
+132
파일 보기
@@ -0,0 +1,132 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* $Id: RTheap-linux.c,v 1.9 2008/01/31 18:01:54 legendre Exp $ */
/* RTheap-linux.c: Linux-specific heap components */
#include "RTheap.h"
#include <assert.h>
#include <fcntl.h> /* open() */
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* str* */
#include <sys/mman.h> /* mmap() */
#include <sys/stat.h> /* open() */
#include <sys/types.h>
#include <sys/uio.h> /* read() */
#include <unistd.h> /* sbrk(), read(), mmap */
#if 1 // defined(MUTATEE64)
int DYNINSTheap_align = 4; /* heaps are word-aligned */
Address DYNINSTheap_loAddr = 0x10000; /* Bump to 64k to make SELinux happier */
Address DYNINSTheap_hiAddr = ~(Address) 0x0;
#elif defined(arch_power)
int DYNINSTheap_align = 4; /* heaps are word-aligned */
Address DYNINSTheap_loAddr =
~(Address) 0; // should be defined by getpagesize() when used.
Address DYNINSTheap_hiAddr = ~(Address) 0;
#else
int DYNINSTheap_align = 4; /* heaps are word-aligned */
Address DYNINSTheap_loAddr = 0x50000000;
Address DYNINSTheap_hiAddr = 0xb0000000;
#endif
int DYNINSTheap_mmapFlags = MAP_ANONYMOUS | MAP_PRIVATE;
RT_Boolean
DYNINSTheap_useMalloc(void* lo, void* hi)
{
/* We do not save footprint space by allocating in
the user's heap on this platform, so we stay out of it. */
(void) lo; /* unused parameter */
(void) hi; /* unused parameter */
return RT_FALSE;
}
int
DYNINSTheap_mmapFdOpen(void)
{
int fd = open("/dev/zero", O_RDWR);
return fd;
}
void
DYNINSTheap_mmapFdClose(int fd)
{
close(fd);
}
int
DYNINSTgetMemoryMap(unsigned* nump, dyninstmm_t** mapp)
{
FILE* procmaps;
Address saddr = 0, eaddr = 0;
int num_matches;
procmaps = fopen("/proc/self/maps", "r");
dyninstmm_t* maps = *mapp;
if(procmaps == NULL) return -1;
*nump = 0;
while(((num_matches = fscanf(procmaps, "%lx-%lx", &saddr, &eaddr)) != EOF) &&
(*nump < 1024))
{
if(num_matches == 2)
{
maps[*nump].pr_vaddr = saddr;
maps[*nump].pr_size = eaddr - saddr;
(*nump)++;
// skip to next line
int ch;
while((ch = fgetc(procmaps)) != '\n' && ch != EOF)
{
if(ch == EOF) break;
}
}
else
{
break;
}
}
fclose(procmaps);
return *nump < 1024;
/*
Here are two lines from 'cat /proc/self/maps' on Linux 2.2. Each
describes a segment of the address space. We parse out the first
two addresses for the start address and length of the segment. We
throw away the rest.
|SADDR-| |EADDR-|
0804a000-0804c000 rw-p 00001000 08:09 12089 /bin/cat
0804c000-0804f000 rwxp 00000000 00:00 0
*/
}
+153
파일 보기
@@ -0,0 +1,153 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "src/RTcommon.h"
#include "src/RTheap.h"
#include <stdlib.h>
#include <windows.h>
int DYNINSTheap_align = 16;
Address DYNINSTheap_loAddr = 0x400000; // 4MB mark
Address DYNINSTheap_hiAddr = 0x7FFFFFFF; // 2GB mark
int
getpagesize()
{
SYSTEM_INFO info;
static int page_size = 0;
if(page_size) return page_size;
GetSystemInfo(&info);
page_size = info.dwPageSize;
return page_size;
}
void*
map_region(void* addr, int len, int fd)
{
void* result;
DWORD lastError;
char* lpMessage = NULL;
result = VirtualAlloc(addr, len, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if(!result)
{
lastError = GetLastError();
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, lastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)(lpMessage), 0, NULL);
fprintf(stderr, "VirtualAlloc failed in RTlib: %s\n", lpMessage);
LocalFree((LPVOID) lpMessage);
}
else
{
fprintf(stderr, "VirtualAlloc succeeded, %p to %p mapped for RTlib heap\n", addr,
(char*) (addr) + len);
}
return result;
}
int
unmap_region(void* addr, int len)
{
BOOL result;
result = VirtualFree(addr, 0, MEM_RELEASE);
return (int) result;
}
int
DYNINSTheap_mmapFdOpen(void)
{
return 0;
}
void
DYNINSTheap_mmapFdClose(int fd)
{}
RT_Boolean
DYNINSTheap_useMalloc(void* lo, void* hi)
{
return RT_FALSE;
}
int
DYNINSTgetMemoryMap(unsigned* nump, dyninstmm_t** mapp)
{
dyninstmm_t* map = NULL;
void* temp;
Address cur, base;
MEMORY_BASIC_INFORMATION mem;
unsigned count = 0, size = 0;
static unsigned alloc_size = 256;
map = (dyninstmm_t*) malloc(alloc_size * sizeof(dyninstmm_t));
memset(map, 0, alloc_size * sizeof(dyninstmm_t));
cur = DYNINSTheap_loAddr;
for(; cur < DYNINSTheap_hiAddr; cur += size)
{
VirtualQuery((void*) cur, &mem, sizeof(MEMORY_BASIC_INFORMATION));
base = (Address) mem.BaseAddress;
size = mem.RegionSize;
if(!size) goto done_err;
if(mem.State & MEM_FREE) continue;
if(count && (base <= map[count - 1].pr_vaddr + map[count - 1].pr_size))
{
// We have two continuous regions, just merge them into one
map[count - 1].pr_size = base + size - map[count - 1].pr_vaddr;
continue;
}
if(count >= alloc_size)
{
// Grow the allocation buffer, if we need to
alloc_size *= 2;
temp = realloc(map, alloc_size * sizeof(dyninstmm_t));
if(!temp) goto done_err;
map = (dyninstmm_t*) temp;
}
map[count].pr_vaddr = base;
map[count].pr_size = size;
count++;
}
*nump = count;
*mapp = map;
return 0;
done_err:
free(map);
*nump = 0;
*mapp = NULL;
return -1;
}
+223
파일 보기
@@ -0,0 +1,223 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* $Id: RTheap.c,v 1.25 2006/05/03 00:31:25 jodom Exp $ */
/* RTheap.c: platform-generic heap management */
#include <stdio.h>
#include <stdlib.h>
#if !defined(os_windows) /* ccw 15 may 2000 : 29 mar 2001 */
/* win does not have these header files. it appears the only
one that is used assert.h anyway.
*/
# include <errno.h>
# include <fcntl.h> /* open() */
# include <sys/stat.h> /* open() */
# include <sys/types.h>
# include <unistd.h>
#else
extern int
getpagesize();
#endif
#include <assert.h>
#include "src/RTcommon.h"
#include "src/RTheap.h"
typedef enum
{
HEAP_TYPE_UNKNOWN = 0x0,
HEAP_TYPE_MMAP = 0x1,
HEAP_TYPE_MALLOC = 0x2
} heapType_t;
typedef struct heap_t
{
void* ret_addr; /* address returned to mutator */
void* addr; /* actual heap address */
size_t len; /* actual heap length */
heapType_t type; /* heap allocation type */
} heap_t;
typedef struct heapList_t
{
heap_t heap;
struct heapList_t* prev;
struct heapList_t* next;
} heapList_t;
/* local variables */
static heapList_t* Heaps = NULL;
static int psize = -1;
static Address
heap_alignUp(Address addr, int align)
{
if(addr % align == 0) return addr;
return ((addr / align) + 1) * align;
}
static Address
trymmap(size_t len, Address beg, Address end, size_t inc, int fd)
{
Address addr;
void* result;
/*We have a possibly large region (beg to end) and a hopefully smaller */
/* allocation size (len). We try to map at every page in the region*/
/* until we get one that succeeds.*/
for(addr = beg; addr + len <= end; addr += inc)
{
result = map_region((void*) addr, len, fd);
if(result)
{
/* Success doesn't necessarily mean it actually mapped at the hinted
* address. Return if it's in range, else unmap and try again. */
if((Address) result >= beg && (Address) result + len <= end)
return (Address) result;
unmap_region(result, len);
}
}
return (Address) NULL;
}
void*
DYNINSTos_malloc(size_t nbytes, void* lo_addr, void* hi_addr)
{
char* heap;
size_t size = nbytes;
heapList_t* node = NULL;
/* initialize page size */
if(psize == -1) psize = getpagesize();
/* buffer size must be aligned */
if(size % DYNINSTheap_align != 0)
{
return ((void*) -1);
}
/* use malloc() if appropriate */
if(DYNINSTheap_useMalloc(lo_addr, hi_addr))
{
char* ret_heap;
int size_heap = size + DYNINSTheap_align + sizeof(heapList_t);
heap = malloc(size_heap);
if(heap == NULL)
{
#ifdef DEBUG
fprintf(stderr, "Failed to MALLOC\n");
#endif
return NULL;
}
ret_heap = (char*) heap_alignUp((Address) heap, DYNINSTheap_align);
/* malloc buffer must meet range constraints */
if(ret_heap < (char*) lo_addr || ret_heap + size - 1 > (char*) hi_addr)
{
free(heap);
#ifdef DEBUG
fprintf(stderr, "MALLOC'd area fails range constraints\n");
#endif
return NULL;
}
/* define new heap */
node = (heapList_t*) (ret_heap + size);
node->heap.ret_addr = (void*) ret_heap;
node->heap.addr = heap;
node->heap.len = size_heap;
node->heap.type = HEAP_TYPE_MALLOC;
}
else
{ /* use mmap() for allocation */
Address lo = heap_alignUp((Address) lo_addr, psize);
Address hi = (Address) hi_addr;
heap = (char*) trymmap(size + sizeof(struct heapList_t), lo, hi, psize, -1);
if(!heap) return NULL;
node = (heapList_t*) (heap + size);
/* define new heap */
node->heap.addr = heap;
node->heap.ret_addr = heap;
node->heap.len = size + sizeof(struct heapList_t);
node->heap.type = HEAP_TYPE_MMAP;
}
/* insert new heap into heap list */
node->prev = NULL;
node->next = Heaps;
if(Heaps) Heaps->prev = node;
Heaps = node;
#ifdef DEBUG
fprintf(stderr, "new heap at %lx, size %lx\n", node->heap.ret_addr, node->heap.len);
#endif
return node->heap.ret_addr;
}
int
DYNINSTos_free(void* buf)
{
int ret = 0;
heapList_t* t;
/*
fprintf(stderr, "*** DYNINSTos_free(0x%08x)\n", buf);
*/
for(t = Heaps; t != NULL; t = t->next)
{
/* lookup heap by (returned) address */
heap_t* heap = &t->heap;
if(heap->ret_addr != buf) continue;
/* remove heap from list */
if(t->next) t->next->prev = t->prev;
if(t->prev) t->prev->next = t->next;
if(Heaps == t) Heaps = t->next;
/* deallocate heap */
switch(heap->type)
{
case HEAP_TYPE_MMAP:
if(!unmap_region(heap->addr, heap->len))
{
perror("DYNINSTos_free(munmap)");
ret = -1;
}
break;
case HEAP_TYPE_MALLOC: free(heap->addr); break;
default:
fprintf(stderr, "DYNINSTos_free(): unknown inferior heap type\n");
ret = -1;
break;
}
break;
}
return ret;
}
+83
파일 보기
@@ -0,0 +1,83 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* $Id: RTheap.h,v 1.10 2007/01/18 07:53:56 jaw Exp $ */
#ifndef _RT_HEAP_H
#define _RT_HEAP_H
#include "h/dyninstAPI_RT.h" /* RT_Boolean, Address */
#if defined(os_linux) || defined(os_freebsd)
/* LINUX */
typedef struct
{
Address pr_vaddr;
unsigned long pr_size;
} dyninstmm_t;
#elif defined(os_windows)
typedef struct
{
Address pr_vaddr;
unsigned long pr_size;
} dyninstmm_t;
#else
# error Dynamic heaps are not implemented on this platform
#endif
/*
* platform-specific variables
*/
extern int DYNINSTheap_align;
extern Address DYNINSTheap_loAddr;
extern Address DYNINSTheap_hiAddr;
extern int DYNINSTheap_mmapFlags;
/*
* platform-specific functions
*/
RT_Boolean
DYNINSTheap_useMalloc(void* lo, void* hi);
int
DYNINSTheap_mmapFdOpen();
void
DYNINSTheap_mmapFdClose(int fd);
int
DYNINSTheap_getMemoryMap(unsigned*, dyninstmm_t** mmap);
int
DYNINSTgetMemoryMap(unsigned* nump, dyninstmm_t** mapp);
#endif /* _RT_HEAP_H */
+829
파일 보기
@@ -0,0 +1,829 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/************************************************************************
* $Id: RTlinux.c,v 1.54 2008/04/11 23:30:44 legendre Exp $
* RTlinux.c: mutatee-side library function specific to Linux
************************************************************************/
#include "h/dyninstAPI_RT.h"
#include "src/RTcommon.h"
#include "src/RTthread.h"
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#if !defined(DYNINST_RT_STATIC_LIB)
# include <dlfcn.h>
#endif
#include <errno.h>
#include <gnu/libc-version.h>
#include <link.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <sys/types.h>
#if defined(DYNINST_RT_STATIC_LIB)
/*
* The weak symbol here removes the dependence of the static version of this
* library on pthread_self. If pthread_self is available, then it will be
* linked. Otherwise, the linker will ignore it.
*/
# pragma weak pthread_self
extern pthread_t
pthread_self(void);
#else
# include <pthread.h>
#endif
extern double DYNINSTstaticHeap_512K_lowmemHeap_1[];
extern double DYNINSTstaticHeap_16M_anyHeap_1[];
extern unsigned long sizeOfLowMemHeap1;
extern unsigned long sizeOfAnyHeap1;
static struct trap_mapping_header*
getStaticTrapMap(unsigned long addr);
#if defined(arch_power) && defined(arch_64bit) && defined(os_linux)
unsigned long DYNINSTlinkSave;
unsigned long DYNINSTtocSave;
#endif
/************************************************************************
* void DYNINSTbreakPoint(void)
*
* stop oneself.
************************************************************************/
#ifndef SYS_tkill
# define SYS_tkill 238
#endif
int
t_kill(int pid, int sig)
{
static int has_tkill = 1;
long int result = 0;
if(has_tkill)
{
result = syscall(SYS_tkill, pid, sig);
if(result == -1 && errno == ENOSYS)
{
has_tkill = 0;
}
}
if(!has_tkill)
{
result = kill(pid, sig);
}
return (result == 0);
}
void
DYNINSTbreakPoint()
{
if(DYNINSTstaticMode) return;
// Call into a funtion that contains a
// trap instruction.
DYNINSTtrapFunction();
}
static int failed_breakpoint = 0;
void
uncaught_breakpoint(int sig)
{
(void) sig; /* unused parameter */
failed_breakpoint = 1;
}
void
DYNINSTsafeBreakPoint()
{
if(DYNINSTstaticMode) return;
DYNINST_break_point_event = 2; /* Not the same as above */
// while (DYNINST_break_point_event)
kill(dyn_lwp_self(), SIGSTOP);
}
void
mark_heaps_exec()
{
/* Grab the page size, to align the heap pointer. */
long int pageSize = sysconf(_SC_PAGESIZE);
if(pageSize == 0 || pageSize == -1)
{
fprintf(stderr, "*** Failed to obtain page size, guessing 16K.\n");
perror("mark_heaps_exec");
pageSize = 1024 * 16;
} /* end pageSize initialization */
/* Align the heap pointer. */
unsigned long int alignedHeapPointer =
(unsigned long int) DYNINSTstaticHeap_16M_anyHeap_1;
alignedHeapPointer = (alignedHeapPointer) & ~(pageSize - 1);
unsigned long int adjustedSize = (unsigned long int) DYNINSTstaticHeap_16M_anyHeap_1 -
alignedHeapPointer + sizeOfAnyHeap1;
/* Make the heap's page executable. */
int result = mprotect((void*) alignedHeapPointer, (size_t) adjustedSize,
PROT_READ | PROT_WRITE | PROT_EXEC);
if(result != 0)
{
fprintf(stderr,
"%s[%d]: Couldn't make DYNINSTstaticHeap_16M_anyHeap_1 executable!\n",
__FILE__, __LINE__);
perror("mark_heaps_exec");
}
RTprintf("*** Marked memory from 0x%lx to 0x%lx executable.\n", alignedHeapPointer,
alignedHeapPointer + adjustedSize);
/* Mark _both_ heaps executable. */
alignedHeapPointer = (unsigned long int) DYNINSTstaticHeap_512K_lowmemHeap_1;
alignedHeapPointer = (alignedHeapPointer) & ~(pageSize - 1);
adjustedSize = (unsigned long int) DYNINSTstaticHeap_512K_lowmemHeap_1 -
alignedHeapPointer + sizeOfLowMemHeap1;
/* Make the heap's page executable. */
result = mprotect((void*) alignedHeapPointer, (size_t) adjustedSize,
PROT_READ | PROT_WRITE | PROT_EXEC);
if(result != 0)
{
fprintf(stderr,
"%s[%d]: Couldn't make DYNINSTstaticHeap_512K_lowmemHeap_1 executable!\n",
__FILE__, __LINE__);
perror("mark_heaps_exec");
}
RTprintf("*** Marked memory from 0x%lx to 0x%lx executable.\n", alignedHeapPointer,
alignedHeapPointer + adjustedSize);
} /* end mark_heaps_exec() */
/************************************************************************
* void DYNINSTos_init(void)
*
* OS initialization function
************************************************************************/
int DYNINST_sysEntry;
#if !defined(DYNINST_RT_STATIC_LIB)
/*
* For now, removing dependence of static version of this library
* on libdl.
*/
typedef struct dlopen_args
{
const char* libname;
int mode;
void* result;
void* caller;
} dlopen_args_t;
void* (*DYNINST_do_dlopen)(dlopen_args_t*) = NULL;
static int
get_dlopen_error()
{
char* err_str;
err_str = dlerror();
if(err_str)
{
strncpy(gLoadLibraryErrorString, err_str, (size_t) ERROR_STRING_LENGTH);
return 1;
}
else
{
sprintf(gLoadLibraryErrorString, "unknown error with dlopen");
return 0;
}
return 0;
}
int
DYNINSTloadLibrary(char* libname)
{
void* res;
gLoadLibraryErrorString[0] = '\0';
res = dlopen(libname, RTLD_LAZY | RTLD_GLOBAL);
if(res)
{
return 1;
}
get_dlopen_error();
# if defined(arch_x86)
/* dlopen on recent glibcs has a "security check" so that
only registered modules can call it. Unfortunately, progs
that don't include libdl break this check, so that we
can only call _dl_open (the dlopen worker function) from
within glibc. We do this by calling do_dlopen
We fool this check by calling an addr written by the
mutator */
if(strstr(gLoadLibraryErrorString, "invalid caller") != NULL &&
DYNINST_do_dlopen != NULL)
{
dlopen_args_t args;
args.libname = libname;
args.mode = RTLD_NOW | RTLD_GLOBAL;
args.result = 0;
args.caller = (void*) DYNINST_do_dlopen;
// There's a do_dlopen function in glibc. However, it's _not_
// exported; thus, getting the address is a bit of a pain.
(*DYNINST_do_dlopen)(&args);
// Duplicate the above
if(args.result != NULL)
{
return 1;
}
else
get_dlopen_error();
}
# endif
return 0;
}
#endif
// Define this value so that we can compile on a system that doesn't have
// gettid and still run on one that does.
#if !defined(SYS_gettid)
# if defined(arch_x86)
# define SYS_gettid 224
# elif defined(arch_x86_64)
# define SYS_gettid 186
# endif
#endif
int
dyn_lwp_self()
{
static int gettid_not_valid = 0;
int result;
if(gettid_not_valid) return getpid();
result = syscall((long int) SYS_gettid);
if(result == -1 && errno == ENOSYS)
{
gettid_not_valid = 1;
return getpid();
}
return result;
}
int
dyn_pid_self()
{
return getpid();
}
dyntid_t (*DYNINST_pthread_self)(void);
dyntid_t
dyn_pthread_self()
{
dyntid_t me;
if(DYNINSTstaticMode)
{
#if defined(DYNINST_RT_STATIC_LIB)
/* This special case is necessary because the static
* version of libc doesn't define a version of pthread_self
* unlike the shared version of the library.
*/
if(!pthread_self)
{
return (dyntid_t) DYNINST_SINGLETHREADED;
}
#endif
return (dyntid_t) pthread_self();
}
if(!DYNINST_pthread_self)
{
return (dyntid_t) DYNINST_SINGLETHREADED;
}
me = (*DYNINST_pthread_self)();
return (dyntid_t) me;
}
/*
We reserve index 0 for the initial thread. This value varies by
platform but is always constant for that platform. Wrap that
platform-ness here.
*/
int
DYNINST_am_initial_thread(dyntid_t tid)
{
(void) tid; /* unused parameter */
if(dyn_lwp_self() == getpid())
{
return 1;
}
return 0;
} /* end DYNINST_am_initial_thread() */
#if defined(cap_mutatee_traps)
# include <ucontext.h>
// Register numbers experimentally verified
# if defined(arch_x86)
# define UC_PC(x) x->uc_mcontext.gregs[14]
# elif defined(arch_x86_64)
# if defined(MUTATEE_32)
# define UC_PC(x) x->uc_mcontext.gregs[14]
# else // 64-bit
# define UC_PC(x) x->uc_mcontext.gregs[16]
# endif // amd-64
# elif defined(arch_power)
# if defined(arch_64bit)
# define UC_PC(x) x->uc_mcontext.regs->nip
# else // 32-bit
# define UC_PC(x) x->uc_mcontext.uc_regs->gregs[32]
# endif // power
# elif defined(arch_aarch64)
//#warning "UC_PC: in aarch64, pc is not directly accessable."
// aarch64 pc is not one of 31 GPRs, but an independent reg
# define UC_PC(x) x->uc_mcontext.pc
# endif // UC_PC
extern volatile unsigned long dyninstTrapTableUsed;
extern volatile unsigned long dyninstTrapTableVersion;
extern volatile trapMapping_t* dyninstTrapTable;
extern volatile unsigned long dyninstTrapTableIsSorted;
/**
* This comment is now obsolete, left for historic purposes
*
* Called by the SIGTRAP handler, dyninstTrapHandler. This function is
* closly intwined with dyninstTrapHandler, don't modify one without
* understanding the other.
*
* This function sets up the calling context that was passed to the
* SIGTRAP handler so that control will be redirected to our instrumentation
* when we do the setcontext call.
*
* There are a couple things that make this more difficult than it should be:
* 1. The OS provided calling context is similar to the GLIBC calling context,
* but not compatible. We'll create a new GLIBC compatible context and
* copy the possibly stomped registers from the OS context into it. The
* incompatiblities seem to deal with FP and other special purpose registers.
* 2. setcontext doesn't restore the flags register. Thus dyninstTrapHandler
* will save the flags register first thing and pass us its value in the
* flags parameter. We'll then push the instrumentation entry and flags
* onto the context's stack. Instead of transfering control straight to the
* instrumentation, we'll actually go back to dyninstTrapHandler, which will
* do a popf/ret to restore flags and go to instrumentation. The 'retPoint'
* parameter is the address in dyninstTrapHandler the popf/ret can be found.
**/
void
dyninstTrapHandler(int sig, siginfo_t* sg, ucontext_t* context)
{
void* orig_ip;
void* trap_to;
(void) sig; /* unused parameter */
(void) sg; /* unused parameter */
orig_ip = (void*) UC_PC(context);
assert(orig_ip);
// Find the new IP we're going to and substitute. Leave everything else untouched.
if(DYNINSTstaticMode)
{
unsigned long zero = 0;
unsigned long one = 1;
struct trap_mapping_header* hdr = getStaticTrapMap((unsigned long) orig_ip);
assert(hdr);
volatile trapMapping_t* mapping = &(hdr->traps[0]);
trap_to = dyninstTrapTranslate(orig_ip, (unsigned long*) &hdr->num_entries, &zero,
&mapping, &one);
}
else
{
trap_to =
dyninstTrapTranslate(orig_ip, &dyninstTrapTableUsed, &dyninstTrapTableVersion,
&dyninstTrapTable, &dyninstTrapTableIsSorted);
}
UC_PC(context) = (long) trap_to;
}
# if defined(cap_binary_rewriter)
extern struct r_debug _r_debug;
// Remove because of an issue with glibc-2.35+ switching to namespaces.
// Previously there was a dynamic relocation against _r_debug in the loader which
// picked up the interposed definition, but glibc now uses a direct internal hidden
// symbol reference and thus no longer updates the interposed object.
//
// DLLEXPORT struct r_debug _r_debug __attribute__((weak));
/* Verify that the r_debug variable is visible */
void
r_debugCheck()
{
# define LIBC_VERSION_BUFFER_LENGTH 1024
char _version_s[LIBC_VERSION_BUFFER_LENGTH];
snprintf(_version_s, LIBC_VERSION_BUFFER_LENGTH, "%s", gnu_get_libc_version());
unsigned long _version[2];
unsigned long idx = 0;
char* token = strtok(_version_s, ".");
while(token != NULL && idx < 2)
{
_version[idx++] = atol(token);
token = strtok(NULL, ".");
}
if(_version[0] < 2 || (_version[0] == 2 && _version[1] < 35))
{
assert(_r_debug.r_map);
}
# undef LIBC_VERSION_BUFFER_LENGTH
}
# define NUM_LIBRARIES 512 // Important, max number of rewritten libraries
# define WORD_SIZE (8 * sizeof(unsigned))
# define NUM_LIBRARIES_BITMASK_SIZE (1 + NUM_LIBRARIES / WORD_SIZE)
struct trap_mapping_header* all_headers[NUM_LIBRARIES];
# if !defined(arch_x86_64) || defined(MUTATEE_32)
typedef Elf32_Dyn ElfX_Dyn;
# else
typedef Elf64_Dyn ElfX_Dyn;
# endif
struct trap_mapping_header*
getStaticTrapMap(unsigned long addr);
# if !defined(arch_aarch64)
static unsigned all_headers_current[NUM_LIBRARIES_BITMASK_SIZE];
static unsigned all_headers_last[NUM_LIBRARIES_BITMASK_SIZE];
static int
parse_libs();
static int
parse_link_map(struct link_map* l);
static void
clear_unloaded_libs();
static void
set_bit(unsigned* bit_mask, int bit, char value);
// static char get_bit(unsigned *bit_mask, int bit);
static void
clear_bitmask(unsigned* bit_mask);
static unsigned
get_next_free_bitmask(unsigned* bit_mask, int last_pos);
static unsigned
get_next_set_bitmask(unsigned* bit_mask, int last_pos);
static tc_lock_t trap_mapping_lock;
# endif
static struct trap_mapping_header*
getStaticTrapMap(unsigned long addr)
{
# if !defined(arch_aarch64)
struct trap_mapping_header* header;
int i;
tc_lock_lock(&trap_mapping_lock);
parse_libs();
i = -1;
for(;;)
{
i = get_next_set_bitmask(all_headers_current, i);
assert(i >= 0 && i <= NUM_LIBRARIES);
if(i == NUM_LIBRARIES)
{
header = NULL;
rtdebug_printf("%s[%d]: getStaticTrapMap: returning NULL\n", __FILE__,
__LINE__);
goto done;
}
header = all_headers[i];
if(addr >= header->low_entry && addr <= header->high_entry)
{
goto done;
}
}
done:
tc_lock_unlock(&trap_mapping_lock);
return header;
# else
// Silence compiler warnings
(void) addr;
assert(0);
return NULL;
# endif
}
# if !defined(arch_aarch64)
static int
parse_libs()
{
struct link_map* l_current;
l_current = _r_debug.r_map;
if(!l_current)
{
rtdebug_printf("%s[%d]: parse_libs: _r_debug.r_map was not set\n", __FILE__,
__LINE__);
return -1;
}
clear_bitmask(all_headers_current);
while(l_current)
{
parse_link_map(l_current);
l_current = l_current->l_next;
}
clear_unloaded_libs();
return 0;
}
// parse_link_map return values
# define PARSED 0
# define NOT_REWRITTEN 1
# define ALREADY_PARSED 2
# define ERROR_INTERNAL -1
# define ERROR_FULL -2
static int
parse_link_map(struct link_map* l)
{
ElfX_Dyn* dynamic_ptr;
struct trap_mapping_header* header;
unsigned int i, new_pos;
dynamic_ptr = (ElfX_Dyn*) l->l_ld;
if(!dynamic_ptr) return -1;
assert(sizeof(dynamic_ptr->d_un.d_ptr) == sizeof(void*));
for(; dynamic_ptr->d_tag != DT_NULL && dynamic_ptr->d_tag != DT_DYNINST;
dynamic_ptr++)
;
if(dynamic_ptr->d_tag == DT_NULL)
{
return NOT_REWRITTEN;
}
header = (struct trap_mapping_header*) (dynamic_ptr->d_un.d_val + l->l_addr);
if(header->signature != TRAP_HEADER_SIG) return ERROR_INTERNAL;
if(header->pos != -1)
{
set_bit(all_headers_current, header->pos, 1);
assert(all_headers[header->pos] == header);
return ALREADY_PARSED;
}
for(i = 0; i < header->num_entries; i++)
{
header->traps[i].source =
(void*) (((unsigned long) header->traps[i].source) + l->l_addr);
header->traps[i].target =
(void*) (((unsigned long) header->traps[i].target) + l->l_addr);
if(!header->low_entry ||
header->low_entry > (unsigned long) header->traps[i].source)
header->low_entry = (unsigned long) header->traps[i].source;
if(!header->high_entry ||
header->high_entry < (unsigned long) header->traps[i].source)
header->high_entry = (unsigned long) header->traps[i].source;
}
new_pos = get_next_free_bitmask(all_headers_last, -1);
assert(new_pos < NUM_LIBRARIES);
if(new_pos == NUM_LIBRARIES) return ERROR_FULL;
header->pos = new_pos;
all_headers[new_pos] = header;
set_bit(all_headers_current, new_pos, 1);
set_bit(all_headers_last, new_pos, 1);
return PARSED;
}
static void
clear_unloaded_libs()
{
unsigned i;
for(i = 0; i < NUM_LIBRARIES_BITMASK_SIZE; i++)
{
all_headers_last[i] = all_headers_current[i];
}
}
static void
set_bit(unsigned* bit_mask, int bit, char value)
{
assert(bit < NUM_LIBRARIES);
unsigned* word = bit_mask + bit / WORD_SIZE;
unsigned shift = bit % WORD_SIZE;
if(value)
{
*word |= (1 << shift);
}
else
{
*word &= ~(1 << shift);
}
}
// Wasn't actually needed
/*
static char get_bit(unsigned *bit_mask, int bit) {
assert(bit < NUM_LIBRARIES);
unsigned *word = bit_mask + bit / WORD_SIZE;
unsigned shift = bit % WORD_SIZE;
return (*word & (1 << shift)) ? 1 : 0;
}
*/
static void
clear_bitmask(unsigned* bit_mask)
{
unsigned i;
for(i = 0; i < NUM_LIBRARIES_BITMASK_SIZE; i++)
{
bit_mask[i] = 0;
}
}
static unsigned
get_next_free_bitmask(unsigned* bit_mask, int last_pos)
{
unsigned i, j;
j = last_pos + 1;
i = j / WORD_SIZE;
for(; j < NUM_LIBRARIES; i++)
{
if(bit_mask[i] == (unsigned) -1)
{
j += WORD_SIZE;
continue;
}
for(;;)
{
if(!((1 << (j % WORD_SIZE) & bit_mask[i])))
{
return j;
}
j++;
if(j % WORD_SIZE == 0)
{
break;
}
}
}
return NUM_LIBRARIES;
}
static unsigned
get_next_set_bitmask(unsigned* bit_mask, int last_pos)
{
unsigned i, j;
j = last_pos + 1;
i = j / WORD_SIZE;
for(; j < NUM_LIBRARIES; i++)
{
if(bit_mask[i] == (unsigned) 0)
{
j += WORD_SIZE;
continue;
}
for(;;)
{
if((1 << (j % WORD_SIZE) & bit_mask[i]))
{
return j;
}
j++;
if(j % WORD_SIZE == 0)
{
break;
}
}
}
return NUM_LIBRARIES;
}
# endif
# endif
#endif /* cap_mutatee_traps */
#if defined(cap_binary_rewriter) && !defined(DYNINST_RT_STATIC_LIB)
/* For a static binary, all global constructors are combined in an undefined
* order. Also, DYNINSTBaseInit must be run after all global constructors have
* been run. Since the order of global constructors is undefined, DYNINSTBaseInit
* cannot be run as a constructor in static binaries. Instead, it is run from a
* special constructor handler that processes all the global constructors in
* the binary. Leaving this code in would create a global constructor for the
* function runDYNINSTBaseInit(). See DYNINSTglobal_ctors_handler.
*/
extern void
r_debugCheck();
extern void
DYNINSTBaseInit();
void
runDYNINSTBaseInit() __attribute__((constructor));
void
runDYNINSTBaseInit()
{
r_debugCheck();
DYNINSTBaseInit();
}
#endif
/*
//Small program for finding the correct values to fill in pos_in_pthreadt
// above
#include <pthread.h>
#include <stdio.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
#define gettid() syscall(SYS_gettid)
pthread_attr_t attr;
void *foo(void *f) {
pid_t pid, tid;
unsigned stack_addr;
unsigned best_stack = 0xffffffff;
int best_stack_pos = 0;
void *start_func;
int *p;
int i = 0;
pid = getpid();
tid = gettid();
start_func = foo;
//x86 only.
asm("movl %%ebp,%0" : "=r" (stack_addr));
p = (int *) pthread_self();
while (i < 1000)
{
if (*p == (unsigned) pid)
printf("pid @ %d\n", i);
if (*p == (unsigned) tid)
printf("lwp @ %d\n", i);
if (*p > stack_addr && *p < best_stack)
{
best_stack = *p;
best_stack_pos = i;
}
if (*p == (unsigned) start_func)
printf("func @ %d\n", i);
i += sizeof(int);
p++;
}
printf("stack @ %d\n", best_stack_pos);
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t t;
void *result;
pthread_attr_init(&attr);
pthread_create(&t, &attr, foo, NULL);
pthread_join(t, &result);
return 0;
}
*/
+205
파일 보기
@@ -0,0 +1,205 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "h/dyninstAPI_RT.h"
#include "src/RTcommon.h"
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#if defined(__GNUC__)
# include <unistd.h>
# define FAST_CALL __attribute__((fastcall))
#elif defined(os_windows)
# define FAST_CALL __fastcall
#endif
/* Code to assist in remapping memory operations that were affected
* by our instrumentation */
extern void
DYNINST_stopThread(void*, void*, void*, void*);
#if _MSC_VER
struct MemoryMapper RTmemoryMapper = { 0, 0, 0, 0 };
#else
struct MemoryMapper RTmemoryMapper = { 0, 0, 0, 0, { { 0 } } };
#endif
extern FILE* stOut;
//#define DEBUG_MEM_EM
unsigned long
RTtranslateMemory(unsigned long input, unsigned long origAddr, unsigned long currAddr)
{
/* Standard nonblocking synchronization construct */
int index;
int min;
int max;
volatile int guard2;
(void) origAddr; /* unused parameter */
(void) currAddr; /* unused parameter */
do
{
guard2 = RTmemoryMapper.guard2;
min = 0;
max = (RTmemoryMapper.size - 1);
do
{
index = min + ((max - min) / 2);
if(input >= RTmemoryMapper.elements[index].lo)
{
/* Either correct or too low */
if(input < RTmemoryMapper.elements[index].hi)
{
break;
}
else
{
min = index + 1;
}
}
else
{
/* Too high */
max = index - 1;
}
} while(min <= max);
} while(guard2 != RTmemoryMapper.guard1);
if(min <= max)
{
if(RTmemoryMapper.elements[index].shift == -1)
{
return 0;
}
else
{
return input + RTmemoryMapper.elements[index].shift;
}
}
else
{
return input;
}
return 0;
}
unsigned long
RTtranslateMemoryShift(unsigned long input, unsigned long origAddr,
unsigned long currAddr)
{
/* Standard nonblocking synchronization construct */
int index;
int min;
int max;
volatile int guard2;
(void) origAddr; /* unused parameter */
(void) currAddr; /* unused parameter */
do
{
guard2 = RTmemoryMapper.guard2;
min = 0;
max = (RTmemoryMapper.size - 1);
do
{
index = min + ((max - min) / 2);
if(input >= RTmemoryMapper.elements[index].lo)
{
/* Either correct or too low */
if(input < RTmemoryMapper.elements[index].hi)
{
break;
}
else
{
min = index + 1;
}
}
else
{
/* Too high */
max = index - 1;
}
} while(min <= max);
} while(guard2 != RTmemoryMapper.guard1);
if(min <= max)
{
if(RTmemoryMapper.elements[index].shift == -1)
{
fflush(stOut);
return -1 * input;
}
else
{
return RTmemoryMapper.elements[index].shift;
}
}
else
{
return 0;
}
return 0;
}
int RTuntranslatedEntryCounter;
extern void
DYNINST_stopThread(void* pointAddr, void* callBackID, void* flags, void* calculation);
void
RThandleShadow(void* direction, void* pointAddr, void* callbackID, void* flags,
void* calculation)
{
(void) calculation; /* unused parameter */
if((int) ((long) direction) == 1)
{
if(RTuntranslatedEntryCounter == 0)
{
// Entering a system call...
DYNINST_stopThread(pointAddr, callbackID, flags, (void*) 1);
}
RTuntranslatedEntryCounter++;
}
else
{
if(RTuntranslatedEntryCounter > 0)
{
RTuntranslatedEntryCounter--;
}
if(RTuntranslatedEntryCounter == 0)
{
DYNINST_stopThread(pointAddr, callbackID, flags, (void*) 0);
}
}
}
+308
파일 보기
@@ -0,0 +1,308 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/************************************************************************
* $Id: RTposix.c,v 1.37 2008/04/11 23:30:45 legendre Exp $
* RTposix.c: runtime instrumentation functions for generic posix.
************************************************************************/
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <memory.h>
#include <pwd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>
#include "h/dyninstAPI_RT.h"
#include "src/RTcommon.h"
#include "src/RTheap.h"
#define SOCKLEN_T socklen_t
#if !(defined(arch_power) && defined(os_linux))
void
RTmutatedBinary_init()
{
return;
}
#endif
#if defined(__GNUC) || defined(__GNUC__)
# if defined(DYNINST_RT_STATIC_LIB)
/*
* In the static version of the library, constructors cannot be
* used to run code at initialization. See DYNINSTglobal_ctors_handler.
*/
void
libdyninstAPI_RT_init(void);
# else
void
libdyninstAPI_RT_init(void) __attribute__((constructor));
# endif
#endif
#if defined(cap_async_events)
struct passwd* passwd_info = NULL;
#endif
void
libdyninstAPI_RT_init()
{
static int initCalledOnce = 0;
rtdebug_printf("%s[%d]: DYNINSTinit: welcome to libdyninstAPI_RT_init()\n",
__FILE__, __LINE__);
if(initCalledOnce) return;
initCalledOnce++;
DYNINSTinit();
rtdebug_printf("%s[%d]: did DYNINSTinit\n", __FILE__, __LINE__);
}
/************************************************************************
* void DYNINSTasyncConnect(int pid)
*
* Connect to mutator's async handler thread. <pid> is pid of mutator
************************************************************************/
static int async_socket = -1;
static int needToDisconnect = 0;
static char socket_path[255];
int
DYNINSTasyncConnect(int pid)
{
if(DYNINSTstaticMode) return 0;
#if defined(cap_async_events)
int sock_fd;
struct sockaddr_un sadr;
int res;
int mutatee_pid;
uid_t euid;
rtdebug_printf("%s[%d]: DYNINSTasyncConnnect: entry\n", __FILE__, __LINE__);
rtdebug_printf("%s[%d]: DYNINSTinit: before geteuid\n", __FILE__, __LINE__);
euid = geteuid();
passwd_info = getpwuid(euid);
assert(passwd_info);
if(async_socket != -1)
{
fprintf(stderr, "%s[%d]: - DYNINSTasyncConnect already initialized\n", __FILE__,
__LINE__);
rtdebug_printf("%s[%d]: DYNINSTasyncConnnect: already connected\n", __FILE__,
__LINE__);
return 0;
}
rtdebug_printf("%s[%d]: DYNINSTasyncConnnect: before socket 2\n", __FILE__,
__LINE__);
mutatee_pid = getpid();
snprintf(socket_path, (size_t) 255, "%s/dyninstAsync.%s.%d.%d", P_tmpdir,
passwd_info->pw_name, pid, mutatee_pid);
rtdebug_printf("%s[%d]: DYNINSTasyncConnnect: before socket: %s\n", __FILE__,
__LINE__, socket_path);
errno = 0;
sock_fd = socket(PF_UNIX, SOCK_STREAM, 0);
if(sock_fd < 0)
{
fprintf(stderr, "%s[%d]: DYNINSTasyncConnect() socket(%s): %s\n", __FILE__,
__LINE__, socket_path, strerror(errno));
abort();
}
rtdebug_printf("%s[%d]: DYNINSTasyncConnnect: after socket\n", __FILE__, __LINE__);
sadr.sun_family = PF_UNIX;
strcpy(sadr.sun_path, socket_path);
rtdebug_printf("%s[%d]: DYNINSTasyncConnnect: before connect\n", __FILE__,
__LINE__);
res = 0;
errno = 0;
res = connect(sock_fd, (struct sockaddr*) &sadr, sizeof(sadr));
if(res < 0)
{
perror("DYNINSTasyncConnect() connect()");
}
rtdebug_printf(
"%s[%d]: DYNINSTasyncConnnect: after connect to %s, res = %d, -- %s\n",
__FILE__, __LINE__, socket_path, res, strerror(errno));
/* maybe need to do fcntl to set nonblocking writes on this fd */
if(async_socket == -1)
{
rtdebug_printf("%s[%d]: WARN: async socket has not been reset!!\n", __FILE__,
__LINE__);
}
async_socket = sock_fd;
needToDisconnect = 1;
/* atexit(exit_func); */
rtdebug_printf("%s[%d]: leaving DYNINSTasyncConnect\n", __FILE__, __LINE__);
return 1;
#else
fprintf(stderr, "%s[%d]: called DYNINSTasyncConect when async_events disabled\n",
__FILE__, __LINE__);
return 0;
#endif
}
int
DYNINSTasyncDisconnect()
{
if(DYNINSTstaticMode) return 0;
rtdebug_printf("%s[%d]: welcome to DYNINSTasyncDisconnect\n", __FILE__, __LINE__);
if(needToDisconnect)
{
close(async_socket);
needToDisconnect = 0;
}
async_socket = -1;
return 0;
}
int
DYNINSTwriteEvent(void* ev, size_t sz)
{
ssize_t res;
if(DYNINSTstaticMode) return 0;
rtdebug_printf("%s[%d]: welcome to DYNINSTwriteEvent: %zu bytes\n", __FILE__,
__LINE__, sz);
if(-1 == async_socket)
{
rtdebug_printf("%s[%d]: failed to DYNINSTwriteEvent, no socket\n", __FILE__,
__LINE__);
return -1;
}
try_again:
res = write(async_socket, ev, sz);
if(-1 == res)
{
if(errno == EINTR || errno == EAGAIN)
goto try_again;
else
{
perror("write");
return -1;
}
}
if((size_t) res != sz)
{
/* maybe we need logic to handle partial writes? */
fprintf(stderr, "%s[%d]: partial ? write error, %zd bytes, should be %zu\n",
__FILE__, __LINE__, res, sz);
return -1;
}
return 0;
}
// Important note: addr will be zero in two cases here
// One is the case where we're doing a constrained low mmap, in which case MAP_32BIT
// is precisely correct. The other is the case where our
// constrained map attempts have failed, and we're doing a scan for first available
// mappable page. In that case, MAP_32BIT does no harm.
void*
map_region(void* addr, int len, int fd)
{
void* result;
int flags = DYNINSTheap_mmapFlags;
#if defined(arch_x86_64)
if(addr == 0) flags |= MAP_32BIT;
#endif
result = mmap(addr, len, PROT_READ | PROT_WRITE | PROT_EXEC, flags, fd, 0);
if(result == MAP_FAILED) return NULL;
return result;
}
int
unmap_region(void* addr, int len)
{
int result;
result = munmap(addr, len);
if(result == -1) return 0;
return 1;
}
#if defined(cap_mutatee_traps)
extern void
dyninstTrapHandler(int sig, siginfo_t* info, void* context);
int
DYNINSTinitializeTrapHandler()
{
int result;
struct sigaction new_handler;
int signo = SIGTRAP;
// If environment variable DYNINST_SIGNAL_TRAMPOLINE_SIGILL is set,
// we use SIGILL as the signal for signal trampoline.
// The mutatee has to be generated with DYNINST_SIGNAL_TRAMPOLINE_SIGILL set
// so that the mutator will generates illegal instructions as trampolines.
if(getenv("DYNINST_SIGNAL_TRAMPOLINE_SIGILL"))
{
signo = SIGILL;
}
new_handler.sa_sigaction = dyninstTrapHandler;
// new_handler.sa_restorer = NULL; obsolete
sigemptyset(&new_handler.sa_mask);
new_handler.sa_flags = SA_SIGINFO | SA_NODEFER;
result = sigaction(signo, &new_handler, NULL);
return (result == 0) ? 1 /*Success*/ : 0 /*Fail*/;
}
#endif
+64
파일 보기
@@ -0,0 +1,64 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
DYNINSTsigill:
DYNINSTsigill executes an illegal instruction, causing SIGILL to be
sent to the calling process. It is only needed for
detach-on-the-fly, where detached mutatees stop to wait for the
mutator or paradynd to reattach by sending themselves SIGILL.
A detached mutatee that stops itself with SIGSTOP will not be
noticed by the mutator or paradynd. It must send SIGILL to be
noticed.
There are two ways to send SIGILL to yourself: call kill() or
execute an illegal instruction.
We chose to use illegal instructions. The SIGILL handler has a
simpler implementation if SIGILL is caused by an illegal
instruction. We do not use kill() to send SIGILL.
The test suite calls this function through the dynamic loader to
avoid duplication of code in the test suite and additional makefile
complexity.
3000 bytes of source code for 3 bytes of object code.
*/
.text
.globl DYNINSTsigill
DYNINSTsigill:
ud2
ret
.section .note.GNU-stack,"",@progbits
+30
파일 보기
@@ -0,0 +1,30 @@
.globl dyninstTrapHandler2
.type dyninstTrapHandler2, @function
dyninstTrapHandler2:
pushf
pushl %ebp
movl %esp, %ebp
call __i686.get_pc_thunk.bx
addl $_GLOBAL_OFFSET_TABLE_, %ebx
call .Lnext_insn
.Lnext_insn:
addl $.Lret_point-.Lnext_insn,(%esp)
pushl 0x4(%ebp)
pushl 0x14(%ebp)
call dyninstSetupContext@PLT
movl $0x0, 0x0
.Lret_point:
popf
ret
#if defined(DYNINST_RT_STATIC_LIB)
__i686.get_pc_thunk.bx:
mov (%esp), %ebx
ret
__i686.get_pc_thunk.cx:
mov (%esp), %ecx
ret
#endif
.section .note.GNU-stack,"",@progbits
+21
파일 보기
@@ -0,0 +1,21 @@
.globl dyninstTrapHandler2
.type dyninstTrapHandler2, @function
dyninstTrapHandler2:
pushfq
pushq %rbp
mov %rsp, %rbp
mov %rdx, %rdi
leaq 0(%rip), %rdx
.Lnext_insn:
addq $.Lret_point - .Lnext_insn, %rdx
mov 0x8(%rbp), %rsi
call dyninstSetupContext@PLT
movl $0x0, 0x0
.Lret_point:
pop %rax
pop %r10
pop %r11
popfq
retq
.section .note.GNU-stack,"",@progbits
+66
파일 보기
@@ -0,0 +1,66 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/************************************************************************
* RTsignal.c: C-language signal handling code
************************************************************************/
#include <signal.h>
#include <stdio.h>
#include "h/dyninstAPI_RT.h"
typedef void (*dynsighandler_t)(int);
DLLEXPORT int
dyn_sigaction(int signum, const struct sigaction* act, struct sigaction* oldact)
{
if(signum != SIGTRAP)
{
return sigaction(signum, act, oldact);
}
else
{
return 0;
}
}
DLLEXPORT dynsighandler_t
dyn_signal(int signum, dynsighandler_t handler)
{
if(signum != SIGTRAP)
{
return signal(signum, handler);
}
else
{
return SIG_DFL;
}
}
+18
파일 보기
@@ -0,0 +1,18 @@
.file "RTspace.s"
.globl DYNINSTstaticHeap_8K_lowmemHeap_1
.type DYNINSTstaticHeap_8K_lowmemHeap_1, @object
.size DYNINSTstaticHeap_8K_lowmemHeap_1, 8192
.globl DYNINSTstaticHeap_32K_anyHeap_1
.type DYNINSTstaticHeap_32K_anyHeap_1, @object
.size DYNINSTstaticHeap_32K_anyHeap_1, 32768
.section .dyninst_heap,"awx",@nobits
.align 16
DYNINSTstaticHeap_8K_lowmemHeap_1:
.skip 8192
DYNINSTstaticHeap_32K_anyHeap_1:
.skip 32768
.section .note.GNU-stack,"",@progbits
+18
파일 보기
@@ -0,0 +1,18 @@
.file "RTspace.s"
.globl DYNINSTstaticHeap_512K_lowmemHeap_1
.type DYNINSTstaticHeap_512K_lowmemHeap_1, @object
.size DYNINSTstaticHeap_512K_lowmemHeap_1, 524288
.globl DYNINSTstaticHeap_16M_anyHeap_1
.type DYNINSTstaticHeap_16M_anyHeap_1, @object
.size DYNINSTstaticHeap_16M_anyHeap_1, 16777216
.section .dyninst_heap,"aw",@nobits
.align 16
DYNINSTstaticHeap_512K_lowmemHeap_1:
.skip 524288
DYNINSTstaticHeap_16M_anyHeap_1:
.skip 16777216
.section .note.GNU-stack,"",@progbits
@@ -0,0 +1,82 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
//#warning "This file is not implemented yet!"
#if defined(DYNINST_RT_STATIC_LIB)
# include <assert.h>
void (*DYNINSTctors_addr)(void);
void (*DYNINSTdtors_addr)(void);
//#if defined(MUTATEE64)
// static const unsigned long long CTOR_LIST_TERM = 0x0000000000000000ULL;
// static const unsigned long long CTOR_LIST_START = 0xffffffffffffffffULL;
// static const unsigned long long DTOR_LIST_TERM = 0x0000000000000000ULL;
// static const unsigned long long DTOR_LIST_START = 0xffffffffffffffffULL;
//#else
/*
static const unsigned CTOR_LIST_TERM = 0x00000000;
static const unsigned CTOR_LIST_START = 0xffffffff;
static const unsigned DTOR_LIST_TERM = 0x00000000;
static const unsigned DTOR_LIST_START = 0xffffffff;
*/
//#endif
extern void
DYNINSTBaseInit();
/*
* When rewritting a static binary, .ctors and .dtors sections of
* instrumentation code needs to be combined with the existing .ctors
* and .dtors sections of the static binary.
*
* The following functions process the .ctors and .dtors sections
* that have been rewritten. The rewriter will relocate the
* address of DYNINSTctors_addr and DYNINSTdtors_addr to point to
* new .ctors and .dtors sections.
*/
void
DYNINSTglobal_ctors_handler()
{
//#warning "This function is not implemented yet!"
assert(0);
}
void
DYNINSTglobal_dtors_handler()
{
//#warning "This function is not implemented yet!"
assert(0);
}
#endif
@@ -0,0 +1,102 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if defined(DYNINST_RT_STATIC_LIB)
void (*DYNINSTctors_addr)(void);
void (*DYNINSTdtors_addr)(void);
# if defined(MUTATEE64)
static const unsigned long long CTOR_LIST_TERM = 0x0000000000000000ULL;
static const unsigned long long CTOR_LIST_START = 0xffffffffffffffffULL;
static const unsigned long long DTOR_LIST_TERM = 0x0000000000000000ULL;
static const unsigned long long DTOR_LIST_START = 0xffffffffffffffffULL;
# else
static const unsigned CTOR_LIST_TERM = 0x00000000;
static const unsigned CTOR_LIST_START = 0xffffffff;
static const unsigned DTOR_LIST_TERM = 0x00000000;
static const unsigned DTOR_LIST_START = 0xffffffff;
# endif
extern void
DYNINSTBaseInit();
/*
* When rewritting a static binary, .ctors and .dtors sections of
* instrumentation code needs to be combined with the existing .ctors
* and .dtors sections of the static binary.
*
* The following functions process the .ctors and .dtors sections
* that have been rewritten. The rewriter will relocate the
* address of DYNINSTctors_addr and DYNINSTdtors_addr to point to
* new .ctors and .dtors sections.
*/
void
DYNINSTglobal_ctors_handler()
{
void (**ctors_array)(void) = &DYNINSTctors_addr;
// Find end of function pointer list
void (**tmp_ptr)(void) = ctors_array;
unsigned size = 0;
while(*tmp_ptr != ((void (*)(void)) CTOR_LIST_TERM))
{
size++;
tmp_ptr++;
}
// Constructors are called in the reverse order that they are listed
tmp_ptr = &ctors_array[size - 1]; // skip list end
while(*tmp_ptr != ((void (*)(void)) CTOR_LIST_START))
{
(*tmp_ptr)();
tmp_ptr--;
}
// This ensures that instrumentation cannot execute until all global
// constructors have run
DYNINSTBaseInit();
}
void
DYNINSTglobal_dtors_handler()
{
void (**dtors_array)(void) = &DYNINSTdtors_addr;
// Destructors are called in the forward order that they are listed
void (**tmp_ptr)(void) = &dtors_array[1]; // skip list start
while(*tmp_ptr != ((void (*)(void)) DTOR_LIST_TERM))
{
(*tmp_ptr)();
tmp_ptr++;
}
}
#endif
@@ -0,0 +1,72 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if defined(DYNINST_RT_STATIC_LIB)
# include <stdint.h>
extern void (*DYNINSTctors_begin)(void);
extern void (*DYNINSTdtors_begin)(void);
extern void (*DYNINSTctors_end)(void);
extern void (*DYNINSTdtors_end)(void);
extern void
DYNINSTBaseInit();
void
DYNINSTglobal_ctors_handler()
{
void (**ctor)(void) = &DYNINSTctors_begin;
while(ctor != (&DYNINSTctors_end))
{
if(*ctor && ((intptr_t) *ctor != -1)) (*ctor)();
ctor++;
}
// This ensures that instrumentation cannot execute until all global
// constructors have run
DYNINSTBaseInit();
}
void
DYNINSTglobal_dtors_handler()
{
void (**dtor)(void) = &DYNINSTdtors_begin;
// Destructors are called in the forward order that they are listed
while(dtor != (&DYNINSTdtors_end))
{
if(*dtor && ((intptr_t) *dtor != -1)) (*dtor)();
dtor++;
}
}
#endif
@@ -0,0 +1,129 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if defined(DYNINST_RT_STATIC_LIB)
# include <stdint.h>
void* DYNINSTirel_start;
void* DYNINSTirel_end;
extern void (*DYNINSTctors_begin)(void);
extern void (*DYNINSTdtors_begin)(void);
extern void (*DYNINSTctors_end)(void);
extern void (*DYNINSTdtors_end)(void);
extern void
DYNINSTBaseInit();
typedef struct
{
long* offset;
long info;
long (*ptr)(void);
} rela_t;
typedef struct
{
long* offset;
long info;
} rel_t;
/*
* When rewritting a static binary, .ctors and .dtors sections of
* instrumentation code needs to be combined with the existing .ctors
* and .dtors sections of the static binary.
*
* The following functions process the .ctors and .dtors sections
* that have been rewritten. The rewriter will relocate the
* address of DYNINSTctors_addr and DYNINSTdtors_addr to point to
* new .ctors and .dtors sections.
*/
void
DYNINSTglobal_ctors_handler()
{
void (**ctor)(void) = &DYNINSTctors_begin;
while(ctor != (&DYNINSTctors_end))
{
if(*ctor && ((intptr_t) *ctor != -1)) (*ctor)();
ctor++;
}
// This ensures that instrumentation cannot execute until all global
// constructors have run
DYNINSTBaseInit();
}
void
DYNINSTglobal_dtors_handler()
{
void (**dtor)(void) = &DYNINSTdtors_begin;
// Destructors are called in the forward order that they are listed
while(dtor != (&DYNINSTdtors_end))
{
if(*dtor && ((intptr_t) *dtor != -1)) (*dtor)();
dtor++;
}
}
void
DYNINSTglobal_irel_handler()
{
if(sizeof(long) == 8)
{
rela_t* rel = 0;
for(rel = (rela_t*) (&DYNINSTirel_start); rel != (rela_t*) (&DYNINSTirel_end);
++rel)
{
long result = 0;
if(rel->info != 0x25) continue;
result = (rel->ptr());
*(rel->offset) = result;
}
}
else
{
rel_t* rel = 0;
for(rel = (rel_t*) (&DYNINSTirel_start); rel != (rel_t*) (&DYNINSTirel_end);
++rel)
{
typedef long (*funcptr)(void);
long (*ptr)(void) = 0;
long result = 0;
if(rel->info != 0x2a) continue;
ptr = (funcptr)(*rel->offset);
result = ptr();
*(rel->offset) = result;
}
}
}
#endif
@@ -0,0 +1,4 @@
#if defined(DYNINST_RT_STATIC_LIB)
void (*DYNINSTctors_begin)(void) __attribute__((section(".init_array")));
void (*DYNINSTdtors_begin)(void) __attribute__((section(".fini_array")));
#endif
@@ -0,0 +1,4 @@
#if defined(DYNINST_RT_STATIC_LIB)
void (*DYNINSTctors_end)(void) __attribute__((section(".init_array")));
void (*DYNINSTdtors_end)(void) __attribute__((section(".fini_array")));
#endif
+41
파일 보기
@@ -0,0 +1,41 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "src/RTthread.h"
#include <stdbool.h>
int
tc_lock_lock(tc_lock_t* t)
{
dyntid_t me = dyn_pthread_self();
volatile bool* l = (volatile bool*) (&(t->mutex));
while(__atomic_test_and_set(l, __ATOMIC_ACQUIRE))
if(t->tid == me) return DYNINST_DEAD_LOCK;
return 0;
}
@@ -0,0 +1,9 @@
#include "RTconst.h"
#include "../../dyninstAPI/src/inst-power.h"
.machine "push"
#ifndef __clang__
.machine "ppc"
#endif
.machine "pop"
.section .note.GNU-stack,"",@progbits
@@ -0,0 +1,77 @@
.file "RTthread-powerpc-asm.S"
.machine "push"
#if defined(arch_ppc_little_endian)
.abiversion 2
#endif
#ifndef __clang__
# if defined(arch_64bit)
.machine "ppc64"
# else
.machine "ppc"
# endif
#endif
.section ".text"
.align 2
# /* ------------------------------------------- */
# /* int atomic_set(volatile int *int_ptr); */
# /* */
# /* The only possible values at the given */
# /* memory location are 0 and 1. Attempt to */
# /* atomically update the value from 0 to 1. */
# /* Return 1 if such an atomic update occurred; */
# /* return 0 otherwise. */
# /* ------------------------------------------- */
#if defined(arch_ppc_little_endian)
.section ".toc", "aw"
.section ".text"
.align 2
.p2align 4,,15
.globl atomic_set
.type atomic_set, @function
atomic_set:
#elif defined(arch_64bit)
.globl atomic_set
.section ".opd", "aw"
.align 3
atomic_set:
.quad .atomic_set, .TOC.@tocbase, 0
.size atomic_set, 24
.previous
.globl .atomic_set
.type .atomic_set, @function
.atomic_set:
#else
.globl atomic_set
.type atomic_set, @function
atomic_set:
#endif
addi 4,0,1 # r4 = 1
# Attempt atomic memory swap
lwarx 5,0,3 # r5 = *int_ptr (load reserve indexed)
stwcx. 4,0,3 # *int_ptr = 1 (store conditional indexed)
bne- atomic_set_return_0 # if atomic swap failed, return 0
cmpw 5,4 # if original value was already 1,
beq- atomic_set_return_0 # return 0 because no value update occurred
addi 3,0,1 # function return value = r3 = 1
blr # branch via link register (function return)
atomic_set_return_0:
addi 3,0,0 # function return value = r3 = 0
blr # branch via link register (function return)
#if defined(arch_ppc_little_endian)
.size atomic_set, . - atomic_set
#elif defined(arch_64bit)
.size .atomic_set, . - .atomic_set
#else
.size atomic_set, . - atomic_set
#endif
.machine "pop"
.section .note.GNU-stack,"",@progbits
+63
파일 보기
@@ -0,0 +1,63 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "src/RTthread.h"
/**
* atomic_set will do the following atomically:
* if (*val == 0) {
* *val = 1;
* return 1;
* }
* return 0;
*
**/
extern int
atomic_set(volatile int* int_ptr);
int
tc_lock_lock(tc_lock_t* tc)
{
dyntid_t me;
me = dyn_pthread_self();
if(me == tc->tid) return DYNINST_DEAD_LOCK;
while(1)
{
if(tc->mutex == 0 && atomic_set(&tc->mutex))
{
tc->tid = me;
break;
}
}
return 0;
}
+54
파일 보기
@@ -0,0 +1,54 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "src/RTthread.h"
static int
atomic_set(volatile int* val)
{
int result = 1;
__asm__ __volatile__("xchgl %0, %1\n" : "+r"(result), "+m"(*val)::"memory");
return !result;
}
int
tc_lock_lock(tc_lock_t* tc)
{
dyntid_t me;
me = dyn_pthread_self();
if(me == tc->tid) return DYNINST_DEAD_LOCK;
while(!atomic_set(&tc->mutex))
;
tc->tid = me;
return 0;
}
+89
파일 보기
@@ -0,0 +1,89 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "src/RTthread.h"
#include <assert.h>
/**
* atomic_set will do the following atomically:
* if (*val == 0) {
* *val = 1;
* return 1;
* }
* return 0;
*
* We need two versions since windows uses a different assembly syntax
* (AT&T syntax on Linux and Intel on Windows)
**/
#if defined(os_windows)
int
atomic_set(volatile int* val)
{
int result;
# ifdef _WIN64
result = _InterlockedCompareExchange(val, 1, 0);
return !result;
# else
__asm
{
mov eax, 0 ;
mov ebx, 1 ;
mov ecx, val ;
lock cmpxchg [ecx],ebx ;
setz al ;
mov result, eax ;
}
# endif
return result;
}
#else
static int
atomic_set(volatile int* val)
{
int result = 1;
__asm__ __volatile__("xchgl %0, %1\n" : "+r"(result), "+m"(*val)::"memory");
return !result;
}
#endif
int
tc_lock_lock(tc_lock_t* tc)
{
dyntid_t me;
me = dyn_pthread_self();
if(me == tc->tid) return DYNINST_DEAD_LOCK;
while(!atomic_set(&tc->mutex))
;
tc->tid = me;
return 0;
}
+51
파일 보기
@@ -0,0 +1,51 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "RTcommon.h"
#include "RTthread.h"
#include "h/dyninstAPI_RT.h"
#include "h/dyninstRTExport.h"
int DYNINST_multithread_capable;
extern unsigned int DYNINSThasInitialized;
static void (*rt_newthr_cb)(int) = NULL;
void
setNewthrCB(void (*cb)(int))
{
rt_newthr_cb = cb;
}
#define IDX_NONE -1
+62
파일 보기
@@ -0,0 +1,62 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _RTTHREAD_H_
#define _RTTHREAD_H_
#include "h/dyninstAPI_RT.h"
#include "h/dyninstRTExport.h"
DLLEXPORT dyntid_t
dyn_pthread_self(); /*Thread library identifier*/
int
dyn_lwp_self(); /*LWP used by the kernel identifier*/
int
dyn_pid_self(); /*PID identifier representing the containing process*/
extern int DYNINST_multithread_capable;
typedef dyninst_lock_t tc_lock_t;
#define DECLARE_TC_LOCK(l) tc_lock_t l = { 0, (dyntid_t) -1 }
int
tc_lock_init(tc_lock_t*);
int
tc_lock_lock(tc_lock_t*);
int
tc_lock_unlock(tc_lock_t*);
int
tc_lock_destroy(tc_lock_t*);
int
DYNINST_am_initial_thread(dyntid_t tid);
#endif
+54
파일 보기
@@ -0,0 +1,54 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* This function is used to help support TLS when rewriting static binaries.
* It is originally provided by the dynamic linker (which is unavailable to
* static binaries). One TLS model is to call the function with a module
* index in order to retrieve a TLS variable (see general dynamic). This model
* is unnecessarily general for static binaries but does exist in some non-PIC
* relocatable files. The GNU ld approach is to perform code transformations to
* relax the TLS model. In order to keep the rewriter for static binaries
* simple, the approach of emulating a call to ___tls_get_addr was used instead
* of implementing these link-time code transformations.
*/
#if defined(DYNINST_RT_STATIC_LIB)
.text
.globl ___tls_get_addr
___tls_get_addr:
mov (%eax), %eax /* Gets the TLS offset of the variable */
add %gs:0, %eax /* Gets the absolute address of the variable */
ret
#endif
.section .note.GNU-stack,"",@progbits
@@ -0,0 +1,58 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* This function is used to help support TLS when rewriting static binaries.
* It is originally provided by the dynamic linker (which is unavailable to
* static binaries). One TLS model is to call the function with a module
* index in order to retrieve a TLS variable (see general dynamic). This model
* is unnecessarily general for static binaries but does exist in some non-PIC
* relocatable files. The GNU ld approach is to perform code transformations to
* relax the TLS model. In order to keep the rewriter for static binaries
* simple, the approach of emulating a call to ___tls_get_addr was used instead
* of implementing these link-time code transformations.
*/
#if defined(DYNINST_RT_STATIC_LIB)
.text
.globl ___tls_get_addr
.globl __tls_get_addr
__tls_get_addr:
___tls_get_addr:
mov (%rdi), %rax /* Get the TLS offset of the variable */
add %fs:0, %rax /* Get the absolute address of the variable */
ret
#endif
.section .note.GNU-stack,"",@progbits
+565
파일 보기
@@ -0,0 +1,565 @@
/*
* See the dyninst/COPYRIGHT file for copyright information.
*
* We provide the Paradyn Tools (below described as "Paradyn")
* on an AS IS basis, and do not warrant its validity or performance.
* We reserve the right to update, modify, or discontinue this
* software at any time. We shall have no obligation to supply such
* updates or modifications or any other form of support to you.
*
* By your use of Paradyn, you understand and agree that we (or any
* other person or entity with proprietary rights in Paradyn) are
* under no obligation to provide either maintenance services,
* update services, notices of latent defects, or correction of
* defects for Paradyn.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/************************************************************************
* $Id: RTwinnt.c,v 1.22 2006/06/09 03:50:49 jodom Exp $
* RTwinnt.c: runtime instrumentation functions for Windows NT
************************************************************************/
#include "RTcommon.h"
#include "h/dyninstAPI_RT.h"
#include <Dbghelp.h>
#include <Psapi.h>
#include <WS2tcpip.h>
#include <WinSock2.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <io.h>
#include <limits.h>
#include <mmsystem.h>
#include <process.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <windows.h>
extern unsigned long dyninstTrapTableUsed;
extern unsigned long dyninstTrapTableVersion;
extern trapMapping_t* dyninstTrapTable;
extern unsigned long dyninstTrapTableIsSorted;
extern void
DYNINSTBaseInit();
extern double DYNINSTstaticHeap_512K_lowmemHeap_1[];
extern double DYNINSTstaticHeap_16M_anyHeap_1[];
extern unsigned long sizeOfLowMemHeap1;
extern unsigned long sizeOfAnyHeap1;
/************************************************************************
* void DYNINSTbreakPoint(void)
*
* stop oneself.
************************************************************************/
void
DYNINSTbreakPoint(void)
{
/* TODO: how do we stop all threads? */
DYNINST_break_point_event = 1;
DebugBreak();
DYNINST_break_point_event = 0;
}
void
DYNINSTsafeBreakPoint()
{
DYNINSTbreakPoint();
}
static dyntid_t initial_thread_tid;
/* this function is automatically called when windows loads this dll
if we are launching a mutatee to instrument, dyninst will place
the correct values in libdyninstAPI_RT_DLL_localPid and
libdyninstAPI_RT_DLL_localCause and they will be passed to
DYNINSTinit to correctly initialize the dll. this keeps us
from having to instrument two steps from the mutator (load and then
the execution of DYNINSTinit()
*/
BOOL WINAPI
DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
static int DllMainCalledOnce = 0;
// fprintf(stderr,"RTLIB: In DllMain staticmode=%d %s[%d]\n", DYNINSTstaticMode,
// __FILE__,__LINE__);
if(DllMainCalledOnce) return 1;
DllMainCalledOnce++;
DYNINSTinit();
#if defined(cap_mutatee_traps)
if(DYNINSTstaticMode)
{
DYNINSTinitializeTrapHandler();
}
#endif
return 1;
}
char gLoadLibraryErrorString[ERROR_STRING_LENGTH];
int
DYNINSTloadLibrary(char* libname)
{
HMODULE res;
gLoadLibraryErrorString[0] = '\0';
res = LoadLibrary(libname);
if(res == NULL)
{
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), gLoadLibraryErrorString,
ERROR_STRING_LENGTH, NULL);
return 0;
}
return 1;
}
/************************************************************************
* void DYNINSTasyncConnect()
*
* Connect to mutator's async handler thread. <pid> is pid of mutator
************************************************************************/
// CRITICAL_SECTION comms_mutex;
int async_socket = -1;
int connect_port = 0;
int
DYNINSTasyncConnect(int mutatorpid)
{
int sock_fd;
struct sockaddr_in sadr;
struct in_addr* inadr;
struct addrinfo* result = NULL;
WORD wsversion = MAKEWORD(2, 0);
WSADATA wsadata;
rtBPatch_asyncEventRecord ev;
if(async_socket != -1)
{
/*fprintf(stderr, "%s[%d]: already connected\n", __FILE__, __LINE__);*/
return 0;
}
RTprintf("%s[%d]: inside DYNINSTasyncConnect\n", __FILE__, __LINE__);
if(0 == connect_port)
{
fprintf(stderr, "%s[%d]: DYNINSTasyncConnect, no port\n", __FILE__, __LINE__);
}
WSAStartup(wsversion, &wsadata);
RTprintf("%s[%d]: DYNINSTasyncConnect before gethostbyname\n", __FILE__, __LINE__);
getaddrinfo("localhost", NULL, NULL, &result);
inadr = (struct in_addr*) result->ai_addr;
RTprintf("%s[%d]: inside DYNINSTasyncConnect before memset\n", __FILE__, __LINE__);
memset((void*) &sadr, 0, sizeof(sadr));
sadr.sin_family = PF_INET;
sadr.sin_port = htons((u_short) connect_port);
sadr.sin_addr = *inadr;
RTprintf("%s[%d]: DYNINSTasyncConnect before socket\n", __FILE__, __LINE__);
sock_fd = socket(PF_INET, SOCK_STREAM, 0);
if(sock_fd == INVALID_SOCKET)
{
fprintf(stderr, "DYNINST: socket failed: %d\n", WSAGetLastError());
}
RTprintf("%s[%d]: DYNINSTasyncConnect before connect\n", __FILE__, __LINE__);
if(connect(sock_fd, (struct sockaddr*) &sadr, sizeof(sadr)) == SOCKET_ERROR)
{
fprintf(stderr, "DYNINSTasyncConnect: connect failed: %d\n", WSAGetLastError());
}
/* maybe need to do fcntl to set nonblocking writes on this fd */
async_socket = sock_fd;
RTprintf("%s[%d]: DYNINSTasyncConnect before write\n", __FILE__, __LINE__);
/* after connecting, we need to send along our pid */
ev.type = rtBPatch_newConnectionEvent;
ev.pid = _getpid();
if(!DYNINSTwriteEvent((void*) &ev, sizeof(rtBPatch_asyncEventRecord)))
{
fprintf(stderr, "%s[%d]: DYNINSTwriteEventFailed\n", __FILE__, __LINE__);
}
/* initialize comms mutex */
// InitializeCriticalSection(&comms_mutex);
// fprintf(stderr, "%s[%d]: DYNINSTasyncConnect appears to have succeeded\n",
// __FILE__, __LINE__);
RTprintf("%s[%d]: leaving DYNINSTasyncConnect\n", __FILE__, __LINE__);
freeaddrinfo(result);
return 1; /*true*/
}
int
DYNINSTasyncDisconnect()
{
WSACleanup();
return _close(async_socket);
}
void
printSysError(unsigned errNo)
{
char buf[1000];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, errNo,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 1000, NULL);
fprintf(stderr, "*** System error [%d]: %s\n", errNo, buf);
fflush(stderr);
}
int
DYNINSTwriteEvent(void* ev, size_t sz)
{
DYNINSTasyncConnect(DYNINST_mutatorPid);
if(send((SOCKET) async_socket, ev, sz, 0) != sz)
{
printSysError(WSAGetLastError());
printf("DYNINSTwriteTrace: send error %d, %d %d\n", WSAGetLastError(), sz,
async_socket);
if(async_socket == -1) return 1;
return 0;
}
return 1;
}
int
dyn_pid_self()
{
return _getpid();
}
int
dyn_lwp_self()
{
#ifdef _WIN64
return GetCurrentThreadId();
#else
/* return GetCurrentThreadId(); */
/* getCurrentThreadId() is conflicting with SD-Dyninst instrumentation.
* So I'm doing the massively unportable thing here and hard-coding the assembly
* FOR GREAT JUSTICE!
*/
/* This will do stack frame setup, but that seems harmless in this context... */
__asm {
mov EAX,FS:[0x18]
mov EAX,DS:[EAX+0x24]
}
#endif
}
dyntid_t
dyn_pthread_self()
{
return (dyntid_t) dyn_lwp_self();
}
int
DYNINSTthreadInfo(BPatch_newThreadEventRecord* ev)
{
return 1;
}
/*
We reserve index 0 for the initial thread. This value varies by
platform but is always constant for that platform. Wrap that
platform-ness here.
*/
int
DYNINST_am_initial_thread(dyntid_t tid)
{
return (tid == initial_thread_tid);
}
// Check that the address is backed by a file,
// get the binary's load address,
// get the PE header, assuming there is one,
// see if the last section has been tagged with "DYNINST_REWRITE"
// get trap-table header from last binary section's end - label - size
// sets allocBase to the binary's load address
static struct trap_mapping_header*
getStaticTrapMap(unsigned long addr, unsigned long* allocBase)
{
struct trap_mapping_header* header = NULL;
char fileName[ERROR_STRING_LENGTH];
DWORD actualNameLen = 0;
MEMORY_BASIC_INFORMATION memInfo;
int numSections = 0;
PIMAGE_NT_HEADERS peHdr = NULL;
IMAGE_SECTION_HEADER curSecn;
int sidx = 0;
char* str = NULL;
// check that the address is backed by a file
actualNameLen = GetMappedFileName(GetCurrentProcess(), (LPVOID) addr, fileName,
ERROR_STRING_LENGTH);
if(!actualNameLen)
{
fileName[0] = '\0';
goto done; // no file mapped at trap address
}
fileName[ERROR_STRING_LENGTH - 1] = '\0';
// get the binary's load address, size
if(!VirtualQuery((LPCVOID) addr, &memInfo, sizeof(memInfo)) ||
MEM_COMMIT != memInfo.State)
{
fprintf(stderr, "ERROR IN RTLIB: getStaticTrapMap %s[%d]\n", __FILE__, __LINE__);
goto done; // shouldn't be possible given previous query, but hey
}
*allocBase = (unsigned long) memInfo.AllocationBase;
rtdebug_printf("RTLIB: getStaticTrapMap addr=%lx meminfo.BaseAddress=%lx "
"meminfo.AllocationBase = %lx, memInfo.RegionSize = %lx, "
"%s[%d]\n",
addr, memInfo.BaseAddress, memInfo.AllocationBase, memInfo.RegionSize,
__FILE__, __LINE__);
// get the PE header, assuming there is one
peHdr = ImageNtHeader(memInfo.AllocationBase);
if(!peHdr)
{
fprintf(stderr, "ERROR IN RTLIB: getStaticTrapMap %s[%d]\n", __FILE__, __LINE__);
goto done; // no pe header
}
// see if the last section has been tagged with "DYNINST_REWRITE"
numSections = peHdr->FileHeader.NumberOfSections;
curSecn = *(PIMAGE_SECTION_HEADER)(((unsigned char*) peHdr) + sizeof(DWORD) +
sizeof(IMAGE_FILE_HEADER) +
peHdr->FileHeader.SizeOfOptionalHeader +
sizeof(IMAGE_SECTION_HEADER) * (numSections - 1));
// fprintf(stderr, "RTLIB: PE section header address = %lx\n", curSecn);
// fprintf(stderr, "curSecn.chars = %lx %s[%d]\n",curSecn.Characteristics,
// __FILE__,__LINE__);
if((sizeof(void*) + 16) > curSecn.SizeOfRawData)
{
fprintf(stderr, "ERROR IN RTLIB: getStaticTrapMap %s[%d]\n", __FILE__, __LINE__);
goto done; // last section is uninitialized, doesn't have trap table
}
// fprintf(stderr, "RTLIB %s[%d]\n", __FILE__,__LINE__);
// fprintf(stderr, "RTLIB mi.ab =%lx cs.va =%lx cs.srd=%lx %s[%d]\n",
// memInfo.AllocationBase, curSecn.VirtualAddress, curSecn.SizeOfRawData,
// __FILE__,__LINE__);
str = (char*) ((long) memInfo.AllocationBase + curSecn.VirtualAddress +
curSecn.SizeOfRawData - 16);
if(0 != strncmp("DYNINST_REWRITE", str, 15))
{
fprintf(stderr,
"ERROR IN RTLIB: getStaticTrapMap found bad string [%s] at %p (%s[%d])\n",
str, str, __FILE__, __LINE__);
goto done; // doesn't have DYNINST_REWRITE label
}
// get trap-table header
header = (struct trap_mapping_header*) ((unsigned long) memInfo.AllocationBase +
*((unsigned long*) (str - sizeof(void*))));
done:
if(header)
{
rtdebug_printf("RTLIB: found trap map header at %lx: [%lx %lx]\n",
(unsigned long) header, header->low_entry, header->high_entry);
}
else
{
rtdebug_printf("ERROR: didn't find trap table\n");
}
return header;
}
// Find the target IP and substitute. Leave everything else untouched.
LONG
dyn_trapHandler(PEXCEPTION_POINTERS e)
{
void* trap_to = 0;
void* trap_addr = (void*) ((unsigned char*) e->ExceptionRecord->ExceptionAddress);
unsigned long zero = 0;
unsigned long one = 1;
unsigned long loadAddr = 0;
struct trap_mapping_header* hdr = NULL;
trapMapping_t* mapping = NULL;
rtdebug_printf("RTLIB: In dyn_trapHandler for exception type 0x%lx at 0x%lx\n",
e->ExceptionRecord->ExceptionCode, trap_addr);
assert(DYNINSTstaticMode && "detach on the fly not implemented on Windows");
if(EXCEPTION_BREAKPOINT != e->ExceptionRecord->ExceptionCode)
{
fprintf(stderr,
"RTLIB: dyn_trapHandler exiting early, exception "
"type = 0x%lx triggered at %p is not breakpoint %s[%d]\n",
e->ExceptionRecord->ExceptionCode, trap_addr, __FILE__, __LINE__);
return EXCEPTION_CONTINUE_SEARCH;
}
hdr = getStaticTrapMap((unsigned long) trap_addr, &loadAddr);
assert(hdr);
mapping = &(hdr->traps[0]);
rtdebug_printf("RTLIB: calling dyninstTrapTranslate(\n\t0x%lx, \n\t"
"0x%lx, \n\t0x%lx, \n\t0x%lx, \n\t0x%lx)\n",
(unsigned long) trap_addr - loadAddr + 1, hdr->num_entries, zero,
mapping, one);
trap_to = dyninstTrapTranslate((void*) ((unsigned long) trap_addr - loadAddr + 1),
(unsigned long*) &hdr->num_entries, &zero,
(volatile trapMapping_t**) &mapping, &one);
#ifdef _WIN64
rtdebug_printf("RTLIB: changing Rip from trap at 0x%lx to 0x%lx\n",
e->ContextRecord->Rip, (long) trap_to + loadAddr);
e->ContextRecord->Rip = (long) trap_to + loadAddr;
#else
rtdebug_printf("RTLIB: changing Eip from trap at 0x%lx to 0x%lx\n",
e->ContextRecord->Eip, (long) trap_to + loadAddr);
e->ContextRecord->Eip = (long) trap_to + loadAddr;
#endif
return EXCEPTION_CONTINUE_EXECUTION;
}
PVOID fake_AVEH_handle;
/* registers the trap handler by calling AddVectoredExceptionHandler
*/
int
DYNINSTinitializeTrapHandler()
{
fake_AVEH_handle = AddVectoredExceptionHandler(
RT_TRUE, (PVECTORED_EXCEPTION_HANDLER) dyn_trapHandler);
rtdebug_printf("RTLIB: added vectored trap handler\n");
return fake_AVEH_handle != 0;
}
PVOID
dyn_AddVectoredExceptionHandler(ULONG isFirst, PVECTORED_EXCEPTION_HANDLER handler)
{
PVOID handlerHandle;
if(isFirst)
{
RemoveVectoredExceptionHandler(fake_AVEH_handle);
handlerHandle = AddVectoredExceptionHandler(isFirst, handler);
fake_AVEH_handle = AddVectoredExceptionHandler(
isFirst, (PVECTORED_EXCEPTION_HANDLER) dyn_trapHandler);
}
else
{
handlerHandle = AddVectoredExceptionHandler(isFirst, handler);
}
return handlerHandle;
}
extern int fakeTickCount;
extern FILE* stOut;
DWORD __stdcall DYNINST_FakeTickCount()
{
DWORD tmp = 0x12345678;
if(0 == fakeTickCount)
{
fakeTickCount = tmp;
}
else
{
fakeTickCount = fakeTickCount + 2;
// fakeTickCount = fakeTickCount + (tmp - fakeTickCount)/1000 + 1;
}
fprintf(stOut, "0x%lx = DYNINST_FakeTickCount()\n", fakeTickCount);
return (DWORD) fakeTickCount;
}
BOOL __stdcall DYNINST_FakeBlockInput(BOOL blockit)
{
BOOL ret = RT_TRUE;
fprintf(stOut, "0x%lx = DYNINST_FakeBlockInput(%d)\n", ret, blockit);
return ret;
}
DWORD __stdcall DYNINST_FakeSuspendThread(HANDLE hThread)
{
DWORD suspendCnt = 0;
fprintf(stOut, "%d = DYNINST_FakeSuspendThread(%p)\n", suspendCnt, hThread);
return suspendCnt;
}
BOOL __stdcall DYNINST_FakeCheckRemoteDebuggerPresent(HANDLE hProcess,
PBOOL bpDebuggerPresent)
{
BOOL ret = RT_FALSE;
fprintf(stOut, "%d = DYNINST_FakeCheckRemoteDebuggerPresent(%p,%p)\n", ret, hProcess,
bpDebuggerPresent);
(*bpDebuggerPresent) = ret;
return ret;
}
VOID __stdcall DYNINST_FakeGetSystemTime(LPSYSTEMTIME lpSystemTime)
{
lpSystemTime->wYear = 2009;
lpSystemTime->wMonth = 5;
lpSystemTime->wDayOfWeek = 0;
lpSystemTime->wDay = 3;
lpSystemTime->wHour = 10;
lpSystemTime->wMinute = 1;
lpSystemTime->wSecond = 33;
lpSystemTime->wMilliseconds = 855;
fprintf(stOut, "called DYNINST_FakeGetSystemTime()\n");
fflush(stOut);
}
void
mark_heaps_exec()
{
int OK;
DWORD old_permissions;
OK = VirtualProtect(DYNINSTstaticHeap_16M_anyHeap_1, sizeOfAnyHeap1,
PAGE_EXECUTE_READWRITE, &old_permissions);
if(!OK)
{
fprintf(stderr, "ERROR: 16M/any heap not usable in RTlib: %d\n", GetLastError());
}
OK = VirtualProtect(DYNINSTstaticHeap_512K_lowmemHeap_1, sizeOfLowMemHeap1,
PAGE_EXECUTE_READWRITE, &old_permissions);
if(!OK)
{
fprintf(stderr, "ERROR: 512k/lowmem heap not usable in RTlib: %d\n",
GetLastError());
}
}
+23
파일 보기
@@ -0,0 +1,23 @@
.toc
.csect .text[PR]
.globl DYNINSTstaticHeap_1048576_textHeap_libSpace
.globl .DYNINSTstaticHeap_1048576_textHeap_libSpace
.csect DYNINSTstaticHeap_1048576_textHeap_libSpace[DS]
DYNINSTstaticHeap_1048576_textHeap_libSpace:
.long .DYNINSTstaticHeap_1048576_textHeap_libSpace, TOC[tc0], 0
.csect .text[PR]
.DYNINSTstaticHeap_1048576_textHeap_libSpace:
blr
.space 1048576
LT..DYNINSTstaticHeap_1048576_textHeap_libSpace:
.long 0
.byte 0,0,32,96,128,1,0,1
.long LT..DYNINSTstaticHeap_1048576_textHeap_libSpace-.DYNINSTstaticHeap_1048576_textHeap_libSpace
.short 43
.byte "DYNINSTstaticHeap_1048576_textHeap_libSpace"
.byte 31
_section_.text:
.csect .data[RW],3
.long _section_.text
.section .note.GNU-stack,"",@progbits
+23
파일 보기
@@ -0,0 +1,23 @@
.toc
.csect .text[PR]
.globl DYNINSTstaticHeap_1048576_textHeap_libSpace
.globl .DYNINSTstaticHeap_1048576_textHeap_libSpace
.csect DYNINSTstaticHeap_1048576_textHeap_libSpace[DS]
DYNINSTstaticHeap_1048576_textHeap_libSpace:
.llong .DYNINSTstaticHeap_1048576_textHeap_libSpace, TOC[tc0], 0
.csect .text[PR]
.DYNINSTstaticHeap_1048576_textHeap_libSpace:
blr
.space 1048576
LT..DYNINSTstaticHeap_1048576_textHeap_libSpace:
.llong 0
.byte 0,0,32,96,128,1,0,1
.llong LT..DYNINSTstaticHeap_1048576_textHeap_libSpace-.DYNINSTstaticHeap_1048576_textHeap_libSpace
.short 43
.byte "DYNINSTstaticHeap_1048576_textHeap_libSpace"
.byte 31
_section_.text:
.csect .data[RW],3
.llong _section_.text
.section .note.GNU-stack,"",@progbits
-5
파일 보기
@@ -18,11 +18,6 @@ add_subdirectory(library)
target_link_libraries(omnitrace-object-library
PRIVATE omnitrace::omnitrace-interface-library)
if(OMNITRACE_DYNINST_API_RT)
get_filename_component(OMNITRACE_DYNINST_API_RT_DIR "${OMNITRACE_DYNINST_API_RT}"
DIRECTORY)
endif()
# ------------------------------------------------------------------------------#
#
# omnitrace static library
+1 -13
파일 보기
@@ -17,11 +17,6 @@ endif()
omnitrace_message(STATUS "OS release: ${_OS_RELEASE}")
if(NOT OMNITRACE_DYNINST_API_RT_DIR AND OMNITRACE_DYNINST_API_RT)
get_filename_component(OMNITRACE_DYNINST_API_RT_DIR "${OMNITRACE_DYNINST_API_RT}"
DIRECTORY)
endif()
include(ProcessorCount)
if(NOT DEFINED NUM_PROCS_REAL)
processorcount(NUM_PROCS_REAL)
@@ -46,15 +41,8 @@ if(MAX_CAUSAL_ITERATIONS GREATER 100)
set(MAX_CAUSAL_ITERATIONS 100)
endif()
if(OMNITRACE_BUILD_DYNINST)
set(OMNITRACE_DYNINST_API_RT_DIR
"${PROJECT_BINARY_DIR}/external/dyninst/dyninstAPI_RT:${PROJECT_BINARY_DIR}/external/dyninst/dyninstAPI"
)
endif()
set(_test_library_path
"LD_LIBRARY_PATH=${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}:${OMNITRACE_DYNINST_API_RT_DIR}:$ENV{LD_LIBRARY_PATH}"
)
"LD_LIBRARY_PATH=${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}:$ENV{LD_LIBRARY_PATH}")
set(_test_openmp_env "OMP_PROC_BIND=spread" "OMP_PLACES=threads" "OMP_NUM_THREADS=2")
set(_base_environment