Merge remote-tracking branch 'svnrepo/master'

This commit is contained in:
Martin Hoffmann
2013-02-17 18:25:09 +01:00
4304 changed files with 1094189 additions and 0 deletions

35
.gitignore vendored Normal file
View File

@ -0,0 +1,35 @@
*.o
*.a
*.d
*.acc
*.pb.h
*.pb.cc
*.gcda
*.pyc
*~
Makefile
build
build-*
simulators/bochs/autom4te.cache/
simulators/bochs/bochs
simulators/bochs/build/linux/bochs-dlx
simulators/bochs/build/macosx/Info.plist
simulators/bochs/build/win32/nsis/bochs.nsi
simulators/bochs/bxcommit
simulators/bochs/bximage
simulators/bochs/bxversion.h
simulators/bochs/bxversion.rc
simulators/bochs/config.h
simulators/bochs/config.log
simulators/bochs/config.status
simulators/bochs/libtool
simulators/bochs/ltdlconf.h
simulators/bochs/src
simulators/bochs/tmp
simulators/bochs/install
!simulators/bochs/plex86/kernel/freebsd/Makefile
simulators/gem5/.hg
simulators/gem5/m5out/

79
CMakeLists.txt Normal file
View File

@ -0,0 +1,79 @@
# cmake 2.6 might suffice, but we don't test it (even Debian stable has 2.8.2)
cmake_minimum_required(VERSION 2.8.2)
if("${CMAKE_VERSION}" VERSION_GREATER 2.8.3)
# system cmake modules take precedence over those in CMAKE_MODULE_PATH
# (makes cmake 2.8.4 and newer)
cmake_policy(SET CMP0017 NEW)
endif("${CMAKE_VERSION}" VERSION_GREATER 2.8.3)
PROJECT(Fail*)
set(PROJECT_VERSION "0.0.1" CACHE STRING "Fail* version number")
#### Put all resulting library files in <your_build_dir>/lib ####
SET(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib)
#### Put all resulting executables in <your_build_dir>/bin ####
SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
# At the moment this is the campaign controller executable.
## (The autoconf'd Bochs instance is placed in the auto-configured path,
## as we still just call Bochs' Makefile's make install)
#### Setup search path for custom cmake scipts ####
SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
#### Compiler configuration, see cmake/compilerconfig.cmake
include(compilerconfig)
#### Backend selection ####
OPTION( BUILD_BOCHS "Build Bochs Variant?" ON)
OPTION( BUILD_GEM5 "Build gem5 Variant?" OFF)
OPTION( BUILD_OVP "Build OVP Variant?" OFF)
OPTION( BUILD_QEMU "Build QEMU Variant?" OFF)
OPTION( BUILD_T32 "Build Lauterbach Trace32 Variant?" OFF)
OPTION( BUILD_X86 "Build for x86 guests?" ON)
OPTION( BUILD_ARM "Build for ARM guests?" OFF)
# FIXME: only add simulators/ to include_directories, and include, e.g.,
# bochs/bochs.h in Fail*. -> avoids naming conflicts (e.g., /usr/include/elf.h
# vs. qemu/elf.h)
if(BUILD_BOCHS)
## add necessary additional header search paths.
#add_definitions(-I${CMAKE_SOURCE_DIR}/simulators/bochs/instrument/stubs/ -I${CMAKE_SOURCE_DIR}/simulators/bochs)
include_directories(simulators/bochs/instrument/stubs simulators/bochs)
elseif(BUILD_GEM5)
include_directories(simulators/gem5/src simulators/gem5/build/ARM)
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG -DTRACING_ON")
elseif(BUILD_OVP)
add_subdirectory(simulators/ovp)
elseif(BUILD_QEMU)
include_directories(simulators)
elseif(BUILD_T32)
include_directories(debuggers/t32/include src/core)
add_subdirectory(debuggers/t32)
endif(BUILD_BOCHS)
## Additional compiler and linker flags ##
set(CMAKE_C_FLAGS "-g -Wall")
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "-Wl,-gc-sections")
## Tell the linker where to find the Fail* libraries
link_directories("${LIBRARY_OUTPUT_PATH}")
# Add "simulators"-directory to the include path. This allows
# us to use simulator-specific headers in a comfortable way.
include_directories(${CMAKE_BINARY_DIR}/src/core)
# FIXME: this should be in src/core/CMakeLists.txt but actually doesn't work
## Add CMakeLists from subdirectories:
add_subdirectory(src)
#### Backend-related build system stuff
include(bochs)
include(gem5)
include(ovp)
include(qemu)
include(t32)

5
README Normal file
View File

@ -0,0 +1,5 @@
This is an import of the old danceos svn repository
The failstar development started with rev 2108
Imported from external gitsvn checkout.
http://www.kernel.org/pub/software/scm/git/docs/howto/using-merge-subtree.html

View File

@ -0,0 +1,138 @@
# CMAKE_PARSE_ARGUMENTS(<prefix> <options> <one_value_keywords> <multi_value_keywords> args...)
#
# CMAKE_PARSE_ARGUMENTS() is intended to be used in macros or functions for
# parsing the arguments given to that macro or function.
# It processes the arguments and defines a set of variables which hold the
# values of the respective options.
#
# The <options> argument contains all options for the respective macro,
# i.e. keywords which can be used when calling the macro without any value
# following, like e.g. the OPTIONAL keyword of the install() command.
#
# The <one_value_keywords> argument contains all keywords for this macro
# which are followed by one value, like e.g. DESTINATION keyword of the
# install() command.
#
# The <multi_value_keywords> argument contains all keywords for this macro
# which can be followed by more than one value, like e.g. the TARGETS or
# FILES keywords of the install() command.
#
# When done, CMAKE_PARSE_ARGUMENTS() will have defined for each of the
# keywords listed in <options>, <one_value_keywords> and
# <multi_value_keywords> a variable composed of the given <prefix>
# followed by "_" and the name of the respective keyword.
# These variables will then hold the respective value from the argument list.
# For the <options> keywords this will be TRUE or FALSE.
#
# All remaining arguments are collected in a variable
# <prefix>_UNPARSED_ARGUMENTS, this can be checked afterwards to see whether
# your macro was called with unrecognized parameters.
#
# As an example here a my_install() macro, which takes similar arguments as the
# real install() command:
#
# function(MY_INSTALL)
# set(options OPTIONAL FAST)
# set(oneValueArgs DESTINATION RENAME)
# set(multiValueArgs TARGETS CONFIGURATIONS)
# cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
# ...
#
# Assume my_install() has been called like this:
# my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub)
#
# After the cmake_parse_arguments() call the macro will have set the following
# variables:
# MY_INSTALL_OPTIONAL = TRUE
# MY_INSTALL_FAST = FALSE (this option was not used when calling my_install()
# MY_INSTALL_DESTINATION = "bin"
# MY_INSTALL_RENAME = "" (was not used)
# MY_INSTALL_TARGETS = "foo;bar"
# MY_INSTALL_CONFIGURATIONS = "" (was not used)
# MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL"
#
# You can the continue and process these variables.
#
# Keywords terminate lists of values, e.g. if directly after a one_value_keyword
# another recognized keyword follows, this is interpreted as the beginning of
# the new option.
# E.g. my_install(TARGETS foo DESTINATION OPTIONAL) would result in
# MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION would
# be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor.
#=============================================================================
# Copyright 2010 Alexander Neundorf <neundorf@kde.org>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
if(__CMAKE_PARSE_ARGUMENTS_INCLUDED)
return()
endif()
set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE)
function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames)
# first set all result variables to empty/FALSE
foreach(arg_name ${_singleArgNames} ${_multiArgNames})
set(${prefix}_${arg_name})
endforeach(arg_name)
foreach(option ${_optionNames})
set(${prefix}_${option} FALSE)
endforeach(option)
set(${prefix}_UNPARSED_ARGUMENTS)
set(insideValues FALSE)
set(currentArgName)
# now iterate over all arguments and fill the result variables
foreach(currentArg ${ARGN})
list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword
list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword
list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword
if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1)
if(insideValues)
if("${insideValues}" STREQUAL "SINGLE")
set(${prefix}_${currentArgName} ${currentArg})
set(insideValues FALSE)
elseif("${insideValues}" STREQUAL "MULTI")
list(APPEND ${prefix}_${currentArgName} ${currentArg})
endif()
else(insideValues)
list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg})
endif(insideValues)
else()
if(NOT ${optionIndex} EQUAL -1)
set(${prefix}_${currentArg} TRUE)
set(insideValues FALSE)
elseif(NOT ${singleArgIndex} EQUAL -1)
set(currentArgName ${currentArg})
set(${prefix}_${currentArgName})
set(insideValues "SINGLE")
elseif(NOT ${multiArgIndex} EQUAL -1)
set(currentArgName ${currentArg})
set(${prefix}_${currentArgName})
set(insideValues "MULTI")
endif()
endif()
endforeach(currentArg)
# propagate the result variables to the caller:
foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames})
set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE)
endforeach(arg_name)
set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE)
endfunction(CMAKE_PARSE_ARGUMENTS _options _singleArgs _multiArgs)

597
cmake/FindGTK2.cmake Normal file
View File

@ -0,0 +1,597 @@
# - FindGTK2.cmake
# This module can find the GTK2 widget libraries and several of its other
# optional components like gtkmm, glade, and glademm.
#
# NOTE: If you intend to use version checking, CMake 2.6.2 or later is
# required.
#
# Specify one or more of the following components
# as you call this find module. See example below.
#
# gtk
# gtkmm
# glade
# glademm
#
# The following variables will be defined for your use
#
# GTK2_FOUND - Were all of your specified components found?
# GTK2_INCLUDE_DIRS - All include directories
# GTK2_LIBRARIES - All libraries
#
# GTK2_VERSION - The version of GTK2 found (x.y.z)
# GTK2_MAJOR_VERSION - The major version of GTK2
# GTK2_MINOR_VERSION - The minor version of GTK2
# GTK2_PATCH_VERSION - The patch version of GTK2
#
# Optional variables you can define prior to calling this module:
#
# GTK2_DEBUG - Enables verbose debugging of the module
# GTK2_SKIP_MARK_AS_ADVANCED - Disable marking cache variables as advanced
# GTK2_ADDITIONAL_SUFFIXES - Allows defining additional directories to
# search for include files
#
#=================
# Example Usage:
#
# Call find_package() once, here are some examples to pick from:
#
# Require GTK 2.6 or later
# find_package(GTK2 2.6 REQUIRED gtk)
#
# Require GTK 2.10 or later and Glade
# find_package(GTK2 2.10 REQUIRED gtk glade)
#
# Search for GTK/GTKMM 2.8 or later
# find_package(GTK2 2.8 COMPONENTS gtk gtkmm)
#
# if(GTK2_FOUND)
# include_directories(${GTK2_INCLUDE_DIRS})
# add_executable(mygui mygui.cc)
# target_link_libraries(mygui ${GTK2_LIBRARIES})
# endif()
#
#=============================================================================
# Copyright 2009 Kitware, Inc.
# Copyright 2008-2009 Philip Lowman <philip@yhbt.com>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
# Version 1.3 (11/9/2010) (CMake 2.8.4)
# * 11429: Add support for detecting GTK2 built with Visual Studio 10.
# Thanks to Vincent Levesque for the patch.
# Version 1.2 (8/30/2010) (CMake 2.8.3)
# * Merge patch for detecting gdk-pixbuf library (split off
# from core GTK in 2.21). Thanks to Vincent Untz for the patch
# and Ricardo Cruz for the heads up.
# Version 1.1 (8/19/2010) (CMake 2.8.3)
# * Add support for detecting GTK2 under macports (thanks to Gary Kramlich)
# Version 1.0 (8/12/2010) (CMake 2.8.3)
# * Add support for detecting new pangommconfig.h header file
# (Thanks to Sune Vuorela & the Debian Project for the patch)
# * Add support for detecting fontconfig.h header
# * Call find_package(Freetype) since it's required
# * Add support for allowing users to add additional library directories
# via the GTK2_ADDITIONAL_SUFFIXES variable (kind of a future-kludge in
# case the GTK developers change versions on any of the directories in the
# future).
# Version 0.8 (1/4/2010)
# * Get module working under MacOSX fink by adding /sw/include, /sw/lib
# to PATHS and the gobject library
# Version 0.7 (3/22/09)
# * Checked into CMake CVS
# * Added versioning support
# * Module now defaults to searching for GTK if COMPONENTS not specified.
# * Added HKCU prior to HKLM registry key and GTKMM specific environment
# variable as per mailing list discussion.
# * Added lib64 to include search path and a few other search paths where GTK
# may be installed on Unix systems.
# * Switched to lowercase CMake commands
# * Prefaced internal variables with _GTK2 to prevent collision
# * Changed internal macros to functions
# * Enhanced documentation
# Version 0.6 (1/8/08)
# Added GTK2_SKIP_MARK_AS_ADVANCED option
# Version 0.5 (12/19/08)
# Second release to cmake mailing list
#=============================================================
# _GTK2_GET_VERSION
# Internal function to parse the version number in gtkversion.h
# _OUT_major = Major version number
# _OUT_minor = Minor version number
# _OUT_micro = Micro version number
# _gtkversion_hdr = Header file to parse
#=============================================================
function(_GTK2_GET_VERSION _OUT_major _OUT_minor _OUT_micro _gtkversion_hdr)
file(READ ${_gtkversion_hdr} _contents)
if(_contents)
string(REGEX REPLACE ".*#define GTK_MAJOR_VERSION[ \t]+\\(([0-9]+)\\).*" "\\1" ${_OUT_major} "${_contents}")
string(REGEX REPLACE ".*#define GTK_MINOR_VERSION[ \t]+\\(([0-9]+)\\).*" "\\1" ${_OUT_minor} "${_contents}")
string(REGEX REPLACE ".*#define GTK_MICRO_VERSION[ \t]+\\(([0-9]+)\\).*" "\\1" ${_OUT_micro} "${_contents}")
if(NOT ${_OUT_major} MATCHES "[0-9]+")
message(FATAL_ERROR "Version parsing failed for GTK2_MAJOR_VERSION!")
endif()
if(NOT ${_OUT_minor} MATCHES "[0-9]+")
message(FATAL_ERROR "Version parsing failed for GTK2_MINOR_VERSION!")
endif()
if(NOT ${_OUT_micro} MATCHES "[0-9]+")
message(FATAL_ERROR "Version parsing failed for GTK2_MICRO_VERSION!")
endif()
set(${_OUT_major} ${${_OUT_major}} PARENT_SCOPE)
set(${_OUT_minor} ${${_OUT_minor}} PARENT_SCOPE)
set(${_OUT_micro} ${${_OUT_micro}} PARENT_SCOPE)
else()
message(FATAL_ERROR "Include file ${_gtkversion_hdr} does not exist")
endif()
endfunction()
#=============================================================
# _GTK2_FIND_INCLUDE_DIR
# Internal function to find the GTK include directories
# _var = variable to set
# _hdr = header file to look for
#=============================================================
function(_GTK2_FIND_INCLUDE_DIR _var _hdr)
if(GTK2_DEBUG)
message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
"_GTK2_FIND_INCLUDE_DIR( ${_var} ${_hdr} )")
endif()
set(_relatives
# If these ever change, things will break.
${GTK2_ADDITIONAL_SUFFIXES}
glibmm-2.4
glib-2.0
atk-1.0
atkmm-1.6
cairo
cairomm-1.0
gdk-pixbuf-2.0
gdkmm-2.4
giomm-2.4
gtk-2.0
gtkmm-2.4
libglade-2.0
libglademm-2.4
pango-1.0
pangomm-1.4
sigc++-2.0
)
set(_suffixes)
foreach(_d ${_relatives})
list(APPEND _suffixes ${_d})
list(APPEND _suffixes ${_d}/include) # for /usr/lib/gtk-2.0/include
endforeach()
if(GTK2_DEBUG)
message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
"include suffixes = ${_suffixes}")
endif()
find_path(${_var} ${_hdr}
PATHS
/usr/local/lib64
/usr/local/lib
/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}
/usr/lib64
/usr/lib
/opt/gnome/include
/opt/gnome/lib
/opt/openwin/include
/usr/openwin/lib
/sw/include
/sw/lib
/opt/local/include
/opt/local/lib
$ENV{GTKMM_BASEPATH}/include
$ENV{GTKMM_BASEPATH}/lib
[HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/include
[HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/lib
[HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/include
[HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/lib
PATH_SUFFIXES
${_suffixes}
)
if(${_var})
set(GTK2_INCLUDE_DIRS ${GTK2_INCLUDE_DIRS} ${${_var}} PARENT_SCOPE)
if(NOT GTK2_SKIP_MARK_AS_ADVANCED)
mark_as_advanced(${_var})
endif()
endif()
endfunction(_GTK2_FIND_INCLUDE_DIR)
#=============================================================
# _GTK2_FIND_LIBRARY
# Internal function to find libraries packaged with GTK2
# _var = library variable to create
#=============================================================
function(_GTK2_FIND_LIBRARY _var _lib _expand_vc _append_version)
if(GTK2_DEBUG)
message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
"_GTK2_FIND_LIBRARY( ${_var} ${_lib} ${_expand_vc} ${_append_version} )")
endif()
# Not GTK versions per se but the versions encoded into Windows
# import libraries (GtkMM 2.14.1 has a gtkmm-vc80-2_4.lib for example)
# Also the MSVC libraries use _ for . (this is handled below)
set(_versions 2.20 2.18 2.16 2.14 2.12
2.10 2.8 2.6 2.4 2.2 2.0
1.20 1.18 1.16 1.14 1.12
1.10 1.8 1.6 1.4 1.2 1.0)
set(_library)
set(_library_d)
set(_library ${_lib})
if(_expand_vc AND MSVC)
# Add vc80/vc90/vc100 midfixes
if(MSVC80)
set(_library ${_library}-vc80)
elseif(MSVC90)
set(_library ${_library}-vc90)
elseif(MSVC10)
set(_library ${_library}-vc100)
endif()
set(_library_d ${_library}-d)
endif()
if(GTK2_DEBUG)
message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
"After midfix addition = ${_library} and ${_library_d}")
endif()
set(_lib_list)
set(_libd_list)
if(_append_version)
foreach(_ver ${_versions})
list(APPEND _lib_list "${_library}-${_ver}")
list(APPEND _libd_list "${_library_d}-${_ver}")
endforeach()
else()
set(_lib_list ${_library})
set(_libd_list ${_library_d})
endif()
if(GTK2_DEBUG)
message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
"library list = ${_lib_list} and library debug list = ${_libd_list}")
endif()
# For some silly reason the MSVC libraries use _ instead of .
# in the version fields
if(_expand_vc AND MSVC)
set(_no_dots_lib_list)
set(_no_dots_libd_list)
foreach(_l ${_lib_list})
string(REPLACE "." "_" _no_dots_library ${_l})
list(APPEND _no_dots_lib_list ${_no_dots_library})
endforeach()
# And for debug
set(_no_dots_libsd_list)
foreach(_l ${_libd_list})
string(REPLACE "." "_" _no_dots_libraryd ${_l})
list(APPEND _no_dots_libd_list ${_no_dots_libraryd})
endforeach()
# Copy list back to original names
set(_lib_list ${_no_dots_lib_list})
set(_libd_list ${_no_dots_libd_list})
endif()
if(GTK2_DEBUG)
message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
"While searching for ${_var}, our proposed library list is ${_lib_list}")
endif()
find_library(${_var}
NAMES ${_lib_list}
PATHS
/opt/gnome/lib
/opt/gnome/lib64
/usr/openwin/lib
/usr/openwin/lib64
/sw/lib
$ENV{GTKMM_BASEPATH}/lib
[HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/lib
[HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/lib
)
if(_expand_vc AND MSVC)
if(GTK2_DEBUG)
message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
"While searching for ${_var}_DEBUG our proposed library list is ${_libd_list}")
endif()
find_library(${_var}_DEBUG
NAMES ${_libd_list}
PATHS
$ENV{GTKMM_BASEPATH}/lib
[HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/lib
[HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/lib
)
if(${_var} AND ${_var}_DEBUG)
if(NOT GTK2_SKIP_MARK_AS_ADVANCED)
mark_as_advanced(${_var}_DEBUG)
endif()
set(GTK2_LIBRARIES ${GTK2_LIBRARIES} optimized ${${_var}} debug ${${_var}_DEBUG})
set(GTK2_LIBRARIES ${GTK2_LIBRARIES} PARENT_SCOPE)
endif()
else()
if(NOT GTK2_SKIP_MARK_AS_ADVANCED)
mark_as_advanced(${_var})
endif()
set(GTK2_LIBRARIES ${GTK2_LIBRARIES} ${${_var}})
set(GTK2_LIBRARIES ${GTK2_LIBRARIES} PARENT_SCOPE)
# Set debug to release
set(${_var}_DEBUG ${${_var}})
set(${_var}_DEBUG ${${_var}} PARENT_SCOPE)
endif()
endfunction(_GTK2_FIND_LIBRARY)
#=============================================================
#
# main()
#
set(GTK2_FOUND)
set(GTK2_INCLUDE_DIRS)
set(GTK2_LIBRARIES)
if(NOT GTK2_FIND_COMPONENTS)
# Assume they only want GTK
set(GTK2_FIND_COMPONENTS gtk)
endif()
#
# If specified, enforce version number
#
if(GTK2_FIND_VERSION)
cmake_minimum_required(VERSION 2.6.2)
set(GTK2_FAILED_VERSION_CHECK true)
if(GTK2_DEBUG)
message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
"Searching for version ${GTK2_FIND_VERSION}")
endif()
_GTK2_FIND_INCLUDE_DIR(GTK2_GTK_INCLUDE_DIR gtk/gtk.h)
if(GTK2_GTK_INCLUDE_DIR)
_GTK2_GET_VERSION(GTK2_MAJOR_VERSION
GTK2_MINOR_VERSION
GTK2_PATCH_VERSION
${GTK2_GTK_INCLUDE_DIR}/gtk/gtkversion.h)
set(GTK2_VERSION
${GTK2_MAJOR_VERSION}.${GTK2_MINOR_VERSION}.${GTK2_PATCH_VERSION})
if(GTK2_FIND_VERSION_EXACT)
if(GTK2_VERSION VERSION_EQUAL GTK2_FIND_VERSION)
set(GTK2_FAILED_VERSION_CHECK false)
endif()
else()
if(GTK2_VERSION VERSION_EQUAL GTK2_FIND_VERSION OR
GTK2_VERSION VERSION_GREATER GTK2_FIND_VERSION)
set(GTK2_FAILED_VERSION_CHECK false)
endif()
endif()
else()
# If we can't find the GTK include dir, we can't do version checking
if(GTK2_FIND_REQUIRED AND NOT GTK2_FIND_QUIETLY)
message(FATAL_ERROR "Could not find GTK2 include directory")
endif()
return()
endif()
if(GTK2_FAILED_VERSION_CHECK)
if(GTK2_FIND_REQUIRED AND NOT GTK2_FIND_QUIETLY)
if(GTK2_FIND_VERSION_EXACT)
message(FATAL_ERROR "GTK2 version check failed. Version ${GTK2_VERSION} was found, version ${GTK2_FIND_VERSION} is needed exactly.")
else()
message(FATAL_ERROR "GTK2 version check failed. Version ${GTK2_VERSION} was found, at least version ${GTK2_FIND_VERSION} is required")
endif()
endif()
# If the version check fails, exit out of the module here
return()
endif()
endif()
#
# Find all components
#
find_package(Freetype)
list(APPEND GTK2_INCLUDE_DIRS ${FREETYPE_INCLUDE_DIRS})
list(APPEND GTK2_LIBRARIES ${FREETYPE_LIBRARIES})
foreach(_GTK2_component ${GTK2_FIND_COMPONENTS})
if(_GTK2_component STREQUAL "gtk")
_GTK2_FIND_INCLUDE_DIR(GTK2_GLIB_INCLUDE_DIR glib.h)
_GTK2_FIND_INCLUDE_DIR(GTK2_GLIBCONFIG_INCLUDE_DIR glibconfig.h)
_GTK2_FIND_LIBRARY (GTK2_GLIB_LIBRARY glib false true)
_GTK2_FIND_INCLUDE_DIR(GTK2_GOBJECT_INCLUDE_DIR gobject/gobject.h)
_GTK2_FIND_LIBRARY (GTK2_GOBJECT_LIBRARY gobject false true)
_GTK2_FIND_INCLUDE_DIR(GTK2_GDK_PIXBUF_INCLUDE_DIR gdk-pixbuf/gdk-pixbuf.h)
_GTK2_FIND_LIBRARY (GTK2_GDK_PIXBUF_LIBRARY gdk_pixbuf false true)
_GTK2_FIND_INCLUDE_DIR(GTK2_GDK_INCLUDE_DIR gdk/gdk.h)
_GTK2_FIND_INCLUDE_DIR(GTK2_GDKCONFIG_INCLUDE_DIR gdkconfig.h)
_GTK2_FIND_INCLUDE_DIR(GTK2_GTK_INCLUDE_DIR gtk/gtk.h)
if(UNIX)
_GTK2_FIND_LIBRARY (GTK2_GDK_LIBRARY gdk-x11 false true)
_GTK2_FIND_LIBRARY (GTK2_GTK_LIBRARY gtk-x11 false true)
else()
_GTK2_FIND_LIBRARY (GTK2_GDK_LIBRARY gdk-win32 false true)
_GTK2_FIND_LIBRARY (GTK2_GTK_LIBRARY gtk-win32 false true)
endif()
_GTK2_FIND_INCLUDE_DIR(GTK2_CAIRO_INCLUDE_DIR cairo.h)
_GTK2_FIND_LIBRARY (GTK2_CAIRO_LIBRARY cairo false false)
_GTK2_FIND_INCLUDE_DIR(GTK2_FONTCONFIG_INCLUDE_DIR fontconfig/fontconfig.h)
_GTK2_FIND_INCLUDE_DIR(GTK2_PANGO_INCLUDE_DIR pango/pango.h)
_GTK2_FIND_LIBRARY (GTK2_PANGO_LIBRARY pango false true)
_GTK2_FIND_INCLUDE_DIR(GTK2_GIO_INCLUDE_DIR gio.h)
_GTK2_FIND_INCLUDE_DIR(GTK2_GIOCONFIG_INCLUDE_DIR gioconfig.h)
_GTK2_FIND_LIBRARY (GTK2_GIO_LIBRARY gio true true)
_GTK2_FIND_INCLUDE_DIR(GTK2_ATK_INCLUDE_DIR atk/atk.h)
_GTK2_FIND_LIBRARY (GTK2_ATK_LIBRARY atk false true)
elseif(_GTK2_component STREQUAL "gtkmm")
_GTK2_FIND_INCLUDE_DIR(GTK2_GLIBMM_INCLUDE_DIR glibmm.h)
_GTK2_FIND_INCLUDE_DIR(GTK2_GLIBMMCONFIG_INCLUDE_DIR glibmmconfig.h)
_GTK2_FIND_LIBRARY (GTK2_GLIBMM_LIBRARY glibmm true true)
_GTK2_FIND_INCLUDE_DIR(GTK2_GDKMM_INCLUDE_DIR gdkmm.h)
_GTK2_FIND_INCLUDE_DIR(GTK2_GDKMMCONFIG_INCLUDE_DIR gdkmmconfig.h)
_GTK2_FIND_LIBRARY (GTK2_GDKMM_LIBRARY gdkmm true true)
_GTK2_FIND_INCLUDE_DIR(GTK2_GTKMM_INCLUDE_DIR gtkmm.h)
_GTK2_FIND_INCLUDE_DIR(GTK2_GTKMMCONFIG_INCLUDE_DIR gtkmmconfig.h)
_GTK2_FIND_LIBRARY (GTK2_GTKMM_LIBRARY gtkmm true true)
_GTK2_FIND_INCLUDE_DIR(GTK2_CAIROMM_INCLUDE_DIR cairomm/cairomm.h)
_GTK2_FIND_LIBRARY (GTK2_CAIROMM_LIBRARY cairomm true true)
_GTK2_FIND_INCLUDE_DIR(GTK2_PANGOMM_INCLUDE_DIR pangomm.h)
_GTK2_FIND_INCLUDE_DIR(GTK2_PANGOMMCONFIG_INCLUDE_DIR pangommconfig.h)
_GTK2_FIND_LIBRARY (GTK2_PANGOMM_LIBRARY pangomm true true)
_GTK2_FIND_INCLUDE_DIR(GTK2_SIGC++_INCLUDE_DIR sigc++/sigc++.h)
_GTK2_FIND_INCLUDE_DIR(GTK2_SIGC++CONFIG_INCLUDE_DIR sigc++config.h)
_GTK2_FIND_LIBRARY (GTK2_SIGC++_LIBRARY sigc true true)
_GTK2_FIND_INCLUDE_DIR(GTK2_GIOMM_INCLUDE_DIR giomm.h)
_GTK2_FIND_INCLUDE_DIR(GTK2_GIOMMCONFIG_INCLUDE_DIR giommconfig.h)
_GTK2_FIND_LIBRARY (GTK2_GIOMM_LIBRARY giomm true true)
_GTK2_FIND_INCLUDE_DIR(GTK2_ATKMM_INCLUDE_DIR atkmm.h)
_GTK2_FIND_LIBRARY (GTK2_ATKMM_LIBRARY atkmm true true)
elseif(_GTK2_component STREQUAL "glade")
_GTK2_FIND_INCLUDE_DIR(GTK2_GLADE_INCLUDE_DIR glade/glade.h)
_GTK2_FIND_LIBRARY (GTK2_GLADE_LIBRARY glade false true)
elseif(_GTK2_component STREQUAL "glademm")
_GTK2_FIND_INCLUDE_DIR(GTK2_GLADEMM_INCLUDE_DIR libglademm.h)
_GTK2_FIND_INCLUDE_DIR(GTK2_GLADEMMCONFIG_INCLUDE_DIR libglademmconfig.h)
_GTK2_FIND_LIBRARY (GTK2_GLADEMM_LIBRARY glademm true true)
else()
message(FATAL_ERROR "Unknown GTK2 component ${_component}")
endif()
endforeach()
#
# Solve for the GTK2 version if we haven't already
#
if(NOT GTK2_FIND_VERSION AND GTK2_GTK_INCLUDE_DIR)
_GTK2_GET_VERSION(GTK2_MAJOR_VERSION
GTK2_MINOR_VERSION
GTK2_PATCH_VERSION
${GTK2_GTK_INCLUDE_DIR}/gtk/gtkversion.h)
set(GTK2_VERSION ${GTK2_MAJOR_VERSION}.${GTK2_MINOR_VERSION}.${GTK2_PATCH_VERSION})
endif()
#
# Try to enforce components
#
set(_GTK2_did_we_find_everything true) # This gets set to GTK2_FOUND
# CMAKE_CURRENT_LIST_DIR was introduced with cmake 2.8.3
#include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
include(cmake/FindPackageHandleStandardArgs.cmake)
foreach(_GTK2_component ${GTK2_FIND_COMPONENTS})
string(TOUPPER ${_GTK2_component} _COMPONENT_UPPER)
if(_GTK2_component STREQUAL "gtk")
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "Some or all of the gtk libraries were not found."
GTK2_GTK_LIBRARY
GTK2_GTK_INCLUDE_DIR
GTK2_GLIB_INCLUDE_DIR
GTK2_GLIBCONFIG_INCLUDE_DIR
GTK2_GLIB_LIBRARY
GTK2_GDK_INCLUDE_DIR
GTK2_GDKCONFIG_INCLUDE_DIR
GTK2_GDK_LIBRARY
)
elseif(_GTK2_component STREQUAL "gtkmm")
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "Some or all of the gtkmm libraries were not found."
GTK2_GTKMM_LIBRARY
GTK2_GTKMM_INCLUDE_DIR
GTK2_GTKMMCONFIG_INCLUDE_DIR
GTK2_GLIBMM_INCLUDE_DIR
GTK2_GLIBMMCONFIG_INCLUDE_DIR
GTK2_GLIBMM_LIBRARY
GTK2_GDKMM_INCLUDE_DIR
GTK2_GDKMMCONFIG_INCLUDE_DIR
GTK2_GDKMM_LIBRARY
)
elseif(_GTK2_component STREQUAL "glade")
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "The glade library was not found."
GTK2_GLADE_LIBRARY
GTK2_GLADE_INCLUDE_DIR
)
elseif(_GTK2_component STREQUAL "glademm")
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "The glademm library was not found."
GTK2_GLADEMM_LIBRARY
GTK2_GLADEMM_INCLUDE_DIR
GTK2_GLADEMMCONFIG_INCLUDE_DIR
)
endif()
if(NOT GTK2_${_COMPONENT_UPPER}_FOUND)
set(_GTK2_did_we_find_everything false)
endif()
endforeach()
if(_GTK2_did_we_find_everything AND NOT GTK2_VERSION_CHECK_FAILED)
set(GTK2_FOUND true)
else()
# Unset our variables.
set(GTK2_FOUND false)
set(GTK2_VERSION)
set(GTK2_VERSION_MAJOR)
set(GTK2_VERSION_MINOR)
set(GTK2_VERSION_PATCH)
set(GTK2_INCLUDE_DIRS)
set(GTK2_LIBRARIES)
endif()
if(GTK2_INCLUDE_DIRS)
list(REMOVE_DUPLICATES GTK2_INCLUDE_DIRS)
endif()

62
cmake/FindLibDwarf.cmake Normal file
View File

@ -0,0 +1,62 @@
# - Try to find libdwarf
# Once done this will define
#
# LIBDWARF_FOUND - system has libdwarf
# LIBDWARF_INCLUDE_DIRS - the libdwarf include directory
# LIBDWARF_LIBRARIES - Link these to use libdwarf
# LIBDWARF_DEFINITIONS - Compiler switches required for using libdwarf
#
# Locate libelf library at first
if (NOT LIBELF_FOUND)
find_package (LibElf REQUIRED)
endif (NOT LIBELF_FOUND)
if (LIBDWARF_LIBRARIES AND LIBDWARF_INCLUDE_DIRS)
set (LibDwarf_FIND_QUIETLY TRUE)
endif (LIBDWARF_LIBRARIES AND LIBDWARF_INCLUDE_DIRS)
find_path (DWARF_INCLUDE_DIR
NAMES
dwarf.h
PATHS
/usr/include
/usr/local/include
/opt/local/include
/sw/include
ENV CPATH) # PATH and INCLUDE will also work
#find_path (LIBDW_INCLUDE_DIR
# NAMES
# elfutils/libdw.h
# PATHS
# /usr/include
# /usr/local/include
# /opt/local/include
# /sw/include
# ENV CPATH)
if (DWARF_INCLUDE_DIR) # AND LIBDW_INCLUDE_DIR)
set (LIBDWARF_INCLUDE_DIRS ${DWARF_INCLUDE_DIR} )
endif (DWARF_INCLUDE_DIR)
find_library (LIBDWARF_LIBRARIES
NAMES
dwarf
PATHS
/usr/lib
/usr/local/lib
/opt/local/lib
/sw/lib
ENV LIBRARY_PATH # PATH and LIB will also work
ENV LD_LIBRARY_PATH)
include (FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set LIBDWARF_FOUND to TRUE
# if all listed variables are TRUE
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibDwarf DEFAULT_MSG
LIBDWARF_LIBRARIES
LIBDWARF_INCLUDE_DIRS)
mark_as_advanced(LIBDW_INCLUDE_DIR DWARF_INCLUDE_DIR)
mark_as_advanced(LIBDWARF_INCLUDE_DIRS LIBDWARF_LIBRARIES)

55
cmake/FindLibElf.cmake Normal file
View File

@ -0,0 +1,55 @@
# - Try to find libelf
# Once done this will define
#
# LIBELF_FOUND - system has libelf
# LIBELF_INCLUDE_DIRS - the libelf include directory
# LIBELF_LIBRARIES - Link these to use libelf
# LIBELF_DEFINITIONS - Compiler switches required for using libelf
#
# Copyright (c) 2008 Bernhard Walle <bernhard.walle@gmx.de>
#
# Redistribution and use is allowed according to the terms of the New
# BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
if (LIBELF_LIBRARIES AND LIBELF_INCLUDE_DIRS)
set (LibElf_FIND_QUIETLY TRUE)
endif (LIBELF_LIBRARIES AND LIBELF_INCLUDE_DIRS)
find_path (LIBELF_INCLUDE_DIRS
NAMES
libelf.h
PATHS
/usr/include
/usr/include/libelf
/usr/local/include
/usr/local/include/libelf
/opt/local/include
/opt/local/include/libelf
/sw/include
/sw/include/libelf
ENV CPATH)
find_library (LIBELF_LIBRARIES
NAMES
elf
PATHS
/usr/lib
/usr/local/lib
/opt/local/lib
/sw/lib
ENV LIBRARY_PATH
ENV LD_LIBRARY_PATH)
include (FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set LIBELF_FOUND to TRUE if all listed variables are TRUE
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibElf DEFAULT_MSG
LIBELF_LIBRARIES
LIBELF_INCLUDE_DIRS)
mark_as_advanced(LIBELF_INCLUDE_DIRS LIBELF_LIBRARIES)

22
cmake/FindLibPCL.cmake Normal file
View File

@ -0,0 +1,22 @@
# - Try to find PCL library (Portable Coroutine Library, libpcl1)
# Once done this will define
#
# LIBPCL_FOUND - system has libPCL
# LIBPCL_INCLUDE_DIRS - the libPCL include directory
# LIBPCL_LIBRARIES - Link these to use libPCL
# LIBPCL_DEFINITIONS - Compiler switches required for using libPCL
FIND_PATH(LIBPCL_INCLUDE_DIRS pcl.h)
FIND_LIBRARY(LIBPCL_LIBRARIES NAMES pcl
PATHS /usr/lib /usr/local/lib /opt/local/lib
ENV LIBRARY_PATH # PATH and LIB will also work
ENV LD_LIBRARY_PATH)
# handle the QUIETLY and REQUIRED arguments and set LIBPCL_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(libPCL DEFAULT_MSG LIBPCL_LIBRARIES LIBPCL_INCLUDE_DIRS)
MARK_AS_ADVANCED(LIBPCL_INCLUDE_DIRS LIBPCL_LIBRARIES)
unset(libPCL_DIR CACHE)

64
cmake/FindLibUUID.cmake Normal file
View File

@ -0,0 +1,64 @@
# - Try to find UUID (Universally Unique Identifier)
# Once done this will define
#
# UUID_FOUND - system has UUID
# UUID_INCLUDE_DIRS - the UUID include directory
# UUID_LIBRARIES - Link these to use UUID
# UUID_DEFINITIONS - Compiler switches required for using UUID
#
# Copyright (c) 2006 Andreas Schneider <mail@cynapses.org>
#
# Redistribution and use is allowed according to the terms of the New
# BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
if (UUID_LIBRARIES AND UUID_INCLUDE_DIRS)
# in cache already
set(UUID_FOUND TRUE)
else (UUID_LIBRARIES AND UUID_INCLUDE_DIRS)
find_path(UUID_INCLUDE_DIR
NAMES
uuid/uuid.h
PATHS
/usr/include
/usr/local/include
/opt/local/include
/sw/include
)
find_library(UUID_LIBRARY
NAMES
uuid
PATHS
/usr/lib
/usr/local/lib
/opt/local/lib
/sw/lib
)
set(UUID_INCLUDE_DIRS
${UUID_INCLUDE_DIR}
)
set(UUID_LIBRARIES
${UUID_LIBRARY}
)
if (UUID_INCLUDE_DIRS AND UUID_LIBRARIES)
set(UUID_FOUND TRUE)
endif (UUID_INCLUDE_DIRS AND UUID_LIBRARIES)
if (UUID_FOUND)
if (NOT UUID_FIND_QUIETLY)
message(STATUS "Found UUID (Universally Unique Identifier): ${UUID_LIBRARIES}")
endif (NOT UUID_FIND_QUIETLY)
else (UUID_FOUND)
if (UUID_FIND_REQUIRED)
message(FATAL_ERROR "Could not find UUID (Universally Unique Identifier)")
endif (UUID_FIND_REQUIRED)
endif (UUID_FOUND)
# show the UUID_INCLUDE_DIRS and UUID_LIBRARIES variables only in the advanced view
mark_as_advanced(UUID_INCLUDE_DIRS UUID_LIBRARIES)
endif (UUID_LIBRARIES AND UUID_INCLUDE_DIRS)

21
cmake/FindLibUdis86.cmake Normal file
View File

@ -0,0 +1,21 @@
# - Try to find udis86 library (udis86.sourceforge.net)
# Once done this will define
#
# LIBUDIS86_FOUND - system has libudis86
# LIBUDIS86_INCLUDE_DIRS - the libudis86 include directory
# LIBUDIS86_LIBRARIES - Link these to use libudis86
# LIBUDIS86_DEFINITIONS - Compiler switches required for using libudis86
FIND_PATH(LIBUDIS86_INCLUDE_DIRS udis86.h)
FIND_LIBRARY(LIBUDIS86_LIBRARIES NAMES udis86
PATHS /usr/lib /usr/local/lib /opt/local/lib
ENV LIBRARY_PATH # PATH and LIB will also work
ENV LD_LIBRARY_PATH)
# handle the QUIETLY and REQUIRED arguments and set LIBUDIS86_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(libudis86 DEFAULT_MSG LIBUDIS86_LIBRARIES LIBUDIS86_INCLUDE_DIRS)
MARK_AS_ADVANCED(LIBUDIS86_INCLUDE_DIR LIBUDIS86_INCLUDE_DIRS LIBUDIS86_LIBRARIES)

View File

@ -0,0 +1,296 @@
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(<name> ... )
#
# This function is intended to be used in FindXXX.cmake modules files.
# It handles the REQUIRED, QUIET and version-related arguments to FIND_PACKAGE().
# It also sets the <UPPERCASED_NAME>_FOUND variable.
# The package is considered found if all variables <var1>... listed contain
# valid results, e.g. valid filepaths.
#
# There are two modes of this function. The first argument in both modes is
# the name of the Find-module where it is called (in original casing).
#
# The first simple mode looks like this:
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(<name> (DEFAULT_MSG|"Custom failure message") <var1>...<varN> )
# If the variables <var1> to <varN> are all valid, then <UPPERCASED_NAME>_FOUND
# will be set to TRUE.
# If DEFAULT_MSG is given as second argument, then the function will generate
# itself useful success and error messages. You can also supply a custom error message
# for the failure case. This is not recommended.
#
# The second mode is more powerful and also supports version checking:
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(NAME [REQUIRED_VARS <var1>...<varN>]
# [VERSION_VAR <versionvar>]
# [HANDLE_COMPONENTS]
# [CONFIG_MODE]
# [FAIL_MESSAGE "Custom failure message"] )
#
# As above, if <var1> through <varN> are all valid, <UPPERCASED_NAME>_FOUND
# will be set to TRUE.
# After REQUIRED_VARS the variables which are required for this package are listed.
# Following VERSION_VAR the name of the variable can be specified which holds
# the version of the package which has been found. If this is done, this version
# will be checked against the (potentially) specified required version used
# in the find_package() call. The EXACT keyword is also handled. The default
# messages include information about the required version and the version
# which has been actually found, both if the version is ok or not.
# If the package supports components, use the HANDLE_COMPONENTS option to enable
# handling them. In this case, find_package_handle_standard_args() will report
# which components have been found and which are missing, and the <NAME>_FOUND
# variable will be set to FALSE if any of the required components (i.e. not the
# ones listed after OPTIONAL_COMPONENTS) are missing.
# Use the option CONFIG_MODE if your FindXXX.cmake module is a wrapper for
# a find_package(... NO_MODULE) call. In this case VERSION_VAR will be set
# to <NAME>_VERSION and the macro will automatically check whether the
# Config module was found.
# Via FAIL_MESSAGE a custom failure message can be specified, if this is not
# used, the default message will be displayed.
#
# Example for mode 1:
#
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 DEFAULT_MSG LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR)
#
# LibXml2 is considered to be found, if both LIBXML2_LIBRARY and
# LIBXML2_INCLUDE_DIR are valid. Then also LIBXML2_FOUND is set to TRUE.
# If it is not found and REQUIRED was used, it fails with FATAL_ERROR,
# independent whether QUIET was used or not.
# If it is found, success will be reported, including the content of <var1>.
# On repeated Cmake runs, the same message won't be printed again.
#
# Example for mode 2:
#
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(BISON REQUIRED_VARS BISON_EXECUTABLE
# VERSION_VAR BISON_VERSION)
# In this case, BISON is considered to be found if the variable(s) listed
# after REQUIRED_VAR are all valid, i.e. BISON_EXECUTABLE in this case.
# Also the version of BISON will be checked by using the version contained
# in BISON_VERSION.
# Since no FAIL_MESSAGE is given, the default messages will be printed.
#
# Another example for mode 2:
#
# FIND_PACKAGE(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4)
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(Automoc4 CONFIG_MODE)
# In this case, FindAutmoc4.cmake wraps a call to FIND_PACKAGE(Automoc4 NO_MODULE)
# and adds an additional search directory for automoc4.
# The following FIND_PACKAGE_HANDLE_STANDARD_ARGS() call produces a proper
# success/error message.
#=============================================================================
# Copyright 2007-2009 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
INCLUDE(FindPackageMessage)
INCLUDE(CMakeParseArguments)
# internal helper macro
MACRO(_FPHSA_FAILURE_MESSAGE _msg)
IF (${_NAME}_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "${_msg}")
ELSE (${_NAME}_FIND_REQUIRED)
IF (NOT ${_NAME}_FIND_QUIETLY)
MESSAGE(STATUS "${_msg}")
ENDIF (NOT ${_NAME}_FIND_QUIETLY)
ENDIF (${_NAME}_FIND_REQUIRED)
ENDMACRO(_FPHSA_FAILURE_MESSAGE _msg)
# internal helper macro to generate the failure message when used in CONFIG_MODE:
MACRO(_FPHSA_HANDLE_FAILURE_CONFIG_MODE)
# <name>_CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found:
IF(${_NAME}_CONFIG)
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing: ${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})")
ELSE(${_NAME}_CONFIG)
# If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version.
# List them all in the error message:
IF(${_NAME}_CONSIDERED_CONFIGS)
SET(configsText "")
LIST(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount)
MATH(EXPR configsCount "${configsCount} - 1")
FOREACH(currentConfigIndex RANGE ${configsCount})
LIST(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename)
LIST(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version)
SET(configsText "${configsText} ${filename} (version ${version})\n")
ENDFOREACH(currentConfigIndex)
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}")
ELSE(${_NAME}_CONSIDERED_CONFIGS)
# Simple case: No Config-file was found at all:
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}")
ENDIF(${_NAME}_CONSIDERED_CONFIGS)
ENDIF(${_NAME}_CONFIG)
ENDMACRO(_FPHSA_HANDLE_FAILURE_CONFIG_MODE)
FUNCTION(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
# set up the arguments for CMAKE_PARSE_ARGUMENTS and check whether we are in
# new extended or in the "old" mode:
SET(options CONFIG_MODE HANDLE_COMPONENTS)
SET(oneValueArgs FAIL_MESSAGE VERSION_VAR)
SET(multiValueArgs REQUIRED_VARS)
SET(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} )
LIST(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX)
IF(${INDEX} EQUAL -1)
SET(FPHSA_FAIL_MESSAGE ${_FIRST_ARG})
SET(FPHSA_REQUIRED_VARS ${ARGN})
SET(FPHSA_VERSION_VAR)
ELSE(${INDEX} EQUAL -1)
CMAKE_PARSE_ARGUMENTS(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN})
IF(FPHSA_UNPARSED_ARGUMENTS)
MESSAGE(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"")
ENDIF(FPHSA_UNPARSED_ARGUMENTS)
IF(NOT FPHSA_FAIL_MESSAGE)
SET(FPHSA_FAIL_MESSAGE "DEFAULT_MSG")
ENDIF(NOT FPHSA_FAIL_MESSAGE)
ENDIF(${INDEX} EQUAL -1)
# now that we collected all arguments, process them
IF("${FPHSA_FAIL_MESSAGE}" STREQUAL "DEFAULT_MSG")
SET(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}")
ENDIF("${FPHSA_FAIL_MESSAGE}" STREQUAL "DEFAULT_MSG")
# In config-mode, we rely on the variable <package>_CONFIG, which is set by find_package()
# when it successfully found the config-file, including version checking:
IF(FPHSA_CONFIG_MODE)
LIST(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG)
LIST(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS)
SET(FPHSA_VERSION_VAR ${_NAME}_VERSION)
ENDIF(FPHSA_CONFIG_MODE)
IF(NOT FPHSA_REQUIRED_VARS)
MESSAGE(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()")
ENDIF(NOT FPHSA_REQUIRED_VARS)
LIST(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR)
STRING(TOUPPER ${_NAME} _NAME_UPPER)
STRING(TOLOWER ${_NAME} _NAME_LOWER)
# collect all variables which were not found, so they can be printed, so the
# user knows better what went wrong (#6375)
SET(MISSING_VARS "")
SET(DETAILS "")
SET(${_NAME_UPPER}_FOUND TRUE)
# check if all passed variables are valid
FOREACH(_CURRENT_VAR ${FPHSA_REQUIRED_VARS})
IF(NOT ${_CURRENT_VAR})
SET(${_NAME_UPPER}_FOUND FALSE)
SET(MISSING_VARS "${MISSING_VARS} ${_CURRENT_VAR}")
ELSE(NOT ${_CURRENT_VAR})
SET(DETAILS "${DETAILS}[${${_CURRENT_VAR}}]")
ENDIF(NOT ${_CURRENT_VAR})
ENDFOREACH(_CURRENT_VAR)
# component handling
UNSET(FOUND_COMPONENTS_MSG)
UNSET(MISSING_COMPONENTS_MSG)
IF(FPHSA_HANDLE_COMPONENTS)
FOREACH(comp ${${_NAME}_FIND_COMPONENTS})
IF(${_NAME}_${comp}_FOUND)
IF(NOT DEFINED FOUND_COMPONENTS_MSG)
SET(FOUND_COMPONENTS_MSG "found components: ")
ENDIF()
SET(FOUND_COMPONENTS_MSG "${FOUND_COMPONENTS_MSG} ${comp}")
ELSE()
IF(NOT DEFINED MISSING_COMPONENTS_MSG)
SET(MISSING_COMPONENTS_MSG "missing components: ")
ENDIF()
SET(MISSING_COMPONENTS_MSG "${MISSING_COMPONENTS_MSG} ${comp}")
IF(${_NAME}_FIND_REQUIRED_${comp})
SET(${_NAME_UPPER}_FOUND FALSE)
SET(MISSING_VARS "${MISSING_VARS} ${comp}")
ENDIF()
ENDIF()
ENDFOREACH(comp)
SET(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}")
SET(DETAILS "${DETAILS}[c${COMPONENT_MSG}]")
ENDIF(FPHSA_HANDLE_COMPONENTS)
# version handling:
SET(VERSION_MSG "")
SET(VERSION_OK TRUE)
SET(VERSION ${${FPHSA_VERSION_VAR}} )
IF (${_NAME}_FIND_VERSION)
IF(VERSION)
IF(${_NAME}_FIND_VERSION_EXACT) # exact version required
IF (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}")
SET(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"")
SET(VERSION_OK FALSE)
ELSE (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}")
SET(VERSION_MSG "(found suitable exact version \"${VERSION}\")")
ENDIF (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}")
ELSE(${_NAME}_FIND_VERSION_EXACT) # minimum version specified:
IF ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}")
SET(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"")
SET(VERSION_OK FALSE)
ELSE ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}")
SET(VERSION_MSG "(found suitable version \"${VERSION}\", required is \"${${_NAME}_FIND_VERSION}\")")
ENDIF ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}")
ENDIF(${_NAME}_FIND_VERSION_EXACT)
ELSE(VERSION)
# if the package was not found, but a version was given, add that to the output:
IF(${_NAME}_FIND_VERSION_EXACT)
SET(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")")
ELSE(${_NAME}_FIND_VERSION_EXACT)
SET(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")")
ENDIF(${_NAME}_FIND_VERSION_EXACT)
ENDIF(VERSION)
ELSE (${_NAME}_FIND_VERSION)
IF(VERSION)
SET(VERSION_MSG "(found version \"${VERSION}\")")
ENDIF(VERSION)
ENDIF (${_NAME}_FIND_VERSION)
IF(VERSION_OK)
SET(DETAILS "${DETAILS}[v${VERSION}(${${_NAME}_FIND_VERSION})]")
ELSE(VERSION_OK)
SET(${_NAME_UPPER}_FOUND FALSE)
ENDIF(VERSION_OK)
# print the result:
IF (${_NAME_UPPER}_FOUND)
FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}")
ELSE (${_NAME_UPPER}_FOUND)
IF(FPHSA_CONFIG_MODE)
_FPHSA_HANDLE_FAILURE_CONFIG_MODE()
ELSE(FPHSA_CONFIG_MODE)
IF(NOT VERSION_OK)
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})")
ELSE(NOT VERSION_OK)
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing: ${MISSING_VARS}) ${VERSION_MSG}")
ENDIF(NOT VERSION_OK)
ENDIF(FPHSA_CONFIG_MODE)
ENDIF (${_NAME_UPPER}_FOUND)
SET(${_NAME_UPPER}_FOUND ${${_NAME_UPPER}_FOUND} PARENT_SCOPE)
ENDFUNCTION(FIND_PACKAGE_HANDLE_STANDARD_ARGS _FIRST_ARG)

36
cmake/FindVGA.cmake Normal file
View File

@ -0,0 +1,36 @@
# Find vga-related library information for Linux
# This module defines the following uncached variables:
# VGA_FOUND, if false, do not try to use VGA.
# VGA_INCLUDE_DIRS, where to find vga.h.
# VGA_LIBRARIES, the libraries to link against to use the vga library
# VGA_LIBRARY_DIRS, the directory where the vga library is found.
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
find_path(VGA_INCLUDE_DIR vga.h /usr/local/include /usr/include)
if(VGA_INCLUDE_DIR)
find_library(VGA_LIBRARY
NAMES vga
PATHS /usr/local/lib /usr/lib
)
if(VGA_LIBRARY)
set(VGA_LIBRARY_DIR "")
get_filename_component(VGA_LIBRARY_DIRS ${VGA_LIBRARY} PATH)
# Set uncached variables as per standard.
set(VGA_FOUND ON)
set(VGA_INCLUDE_DIRS ${VGA_INCLUDE_DIR})
set(VGA_LIBRARIES ${VGA_LIBRARY})
endif(VGA_LIBRARY)
endif(VGA_INCLUDE_DIR)
if(VGA_FOUND)
if(NOT VGA_FIND_QUIETLY)
message(STATUS "FindVGA: Found both vga.h and the vga library")
endif(NOT VGA_FIND_QUIETLY)
else(VGA_FOUND)
if(VGA_FIND_REQUIRED)
message(FATAL_ERROR "FindVGA: Could not find vga.h and/or the vga library")
endif(VGA_FIND_REQUIRED)
endif(VGA_FOUND)
endif(CMAKE_SYSTEM_NAME STREQUAL "Linux")

129
cmake/bochs.cmake Normal file
View File

@ -0,0 +1,129 @@
#### Add some custom targets for the autoconf-based Bochs
if(BUILD_BOCHS)
message(STATUS "[${PROJECT_NAME}] Building Bochs variant ...")
SET(VARIANT bochs)
# FIXME: some of these may be mandatory, depending on the actual Bochs config!
# -L/usr/lib -lSDL -lasound -latk-1.0 -lcairo -lfontconfig -lfreetype -lgdk_pixbuf-2.0 -lgdk-x11-2.0 -lgio-2.0 -lglib-2.0 -lgmodule-2.0 -lgobject-2.0 -lgthread-2.0 -lgtk-x11-2.0 -lICE -lm -lncurses -lpango-1.0 -lpangocairo-1.0 -lpangoft2-1.0 -lrt -lSM -lvga -lvgagl -lwx_baseu-2.8 -lwx_gtk2u_core-2.8 -lX11 -lXpm -lXrandr -pthread)
find_package(SDL) # -lSDL
if(SDL_FOUND)
set(bochs_library_dependencies ${bochs_library_dependencies} ${SDL_LIBRARY})
endif(SDL_FOUND)
unset(FindSDL_DIR CACHE)
unset(SDLMAIN_LIBRARY CACHE)
unset(SDL_INCLUDE_DIR CACHE)
unset(SDL_LIBRARY CACHE)
find_package(ALSA) # -lasoud
if(ALSA_FOUND)
set(bochs_library_dependencies ${bochs_library_dependencies} ${ALSA_LIBRARIES})
endif(ALSA_FOUND)
unset(FindALSA_DIR CACHE)
find_package(GTK2 COMPONENTS gtk) # -latk-1.0 -lcairo -lgdk_pixbuf-2.0 -lgdk-x11-2.0 -lglib-2.0 -lgobject-2.0 -lgtk-x11-2.0 -lpango
if(GTK2_FOUND)
set(bochs_library_dependencies ${bochs_library_dependencies} ${GTK2_ATK_LIBRARY} ${GTK2_CAIRO_LIBRARY} ${GTK2_GDK_PIXBUF_LIBRARY} ${GTK2_GDK_LIBRARY} ${GTK2_GLIB_LIBRARY} -lgmodule-2.0 ${GTK2_GOBJECT_LIBRARY} -lgthread-2.0 ${GTK2_GTK_LIBRARY} ${GTK2_PANGO_LIBRARY} -lpangocairo-1.0 -lpangoft2-1.0)
endif(GTK2_FOUND)
unset(FindGTK2_DIR CACHE)
unset(GTK2_GIOCONFIG_INCLUDE_DIR CACHE)
unset(GTK2_GIO_INCLUDE_DIR CACHE)
find_package(Freetype) # -lfreetype
if(FREETYPE_FOUND)
set(bochs_library_dependencies ${bochs_library_dependencies} ${FREETYPE_LIBRARIES})
endif(FREETYPE_FOUND)
unset(FindFreetype_DIR CACHE)
find_package(X11) # -lICE -lX11 -lXpm -lXrandr -lSM
if(X11_FOUND)
set(bochs_library_dependencies ${bochs_library_dependencies} ${X11_X11_LIB})
endif(X11_FOUND)
if(X11_ICE_FOUND)
set(bochs_library_dependencies ${bochs_library_dependencies} ${X11_ICE_LIB})
endif(X11_ICE_FOUND)
if(X11_Xpm_FOUND)
set(bochs_library_dependencies ${bochs_library_dependencies} ${X11_Xpm_LIB})
endif(X11_Xpm_FOUND)
if(X11_Xrandr_FOUND)
set(bochs_library_dependencies ${bochs_library_dependencies} ${X11_Xrandr_LIB})
endif(X11_Xrandr_FOUND)
if(X11_SM_FOUND)
set(bochs_library_dependencies ${bochs_library_dependencies} ${X11_SM_LIB})
endif(X11_SM_FOUND)
unset(FindX11_DIR CACHE)
find_package(Curses) # -lncurses
if(CURSES_FOUND)
set(bochs_library_dependencies ${bochs_library_dependencies} ${CURSES_LIBRARIES})
endif(CURSES_FOUND)
unset(CURSES_CURSES_H_PATH CACHE)
unset(CURSES_FORM_LIBRARY CACHE)
unset(CURSES_HAVE_CURSES_H CACHE)
unset(FindCurses_DIR CACHE)
find_package(wxWidgets) # -lwx_baseu-2.8? -lwx_gtk2u_core-2.8
if(wxWidgets_FOUND)
set(bochs_library_dependencies ${bochs_library_dependencies} ${wxWidgets_LIBRARIES})
link_directories(${wxWidgets_LIB_DIR})
endif(wxWidgets_FOUND)
unset(FindwxWidgets_DIR CACHE)
unset(wxWidgets_USE_DEBUG CACHE)
mark_as_advanced(wxWidgets_CONFIG_EXECUTABLE wxWidgets_wxrc_EXECUTABLE)
find_package(VGA)
if(VGA_FOUND)
set(bochs_library_dependencies ${bochs_library_dependencies} ${VGA_LIBRARIES})
endif()
# FIXME: some libraries still need to be located the "cmake way"
set(bochs_library_dependencies ${bochs_library_dependencies} -lfontconfig -lrt -lvgagl -pthread)
set(bochs_src_dir ${PROJECT_SOURCE_DIR}/simulators/bochs)
set(bochs_install_prefix ${bochs_src_dir}/install CACHE STRING "FailBochs installation path")
set(bochs_configure_params --enable-a20-pin --enable-x86-64 --enable-cpu-level=6 --enable-ne2000 --enable-acpi --enable-pci --enable-usb --enable-trace-cache --enable-fast-function-calls --enable-host-specific-asms --enable-disasm --enable-readline --enable-clgd54xx --enable-fpu --enable-vmx=2 --enable-monitor-mwait --enable-cdrom --enable-sb16=linux --enable-gdb-stub CACHE STRING "Bochs default configure parameters")
## Bochs CXX args for calling make
set(bochs_build_CXX CXX=ag++\ -p\ ${PROJECT_SOURCE_DIR}\ -I${PROJECT_SOURCE_DIR}/src/core\ -I${CMAKE_BINARY_DIR}/src/core\ ${CMAKE_AGPP_FLAGS}\ --Xcompiler)
## Bochs libtool command.
set(bochs_build_LIBTOOL LIBTOOL=/bin/sh\ ./libtool\ --tag=CXX)
# Use cmake's external project feature to build fail library
include(ExternalProject)
ExternalProject_Add(
libfailbochs_external
SOURCE_DIR ${bochs_src_dir}
CONFIGURE_COMMAND ${bochs_src_dir}/configure ${bochs_configure_params} --prefix=${bochs_install_prefix}
PREFIX ${bochs_src_dir}
BUILD_COMMAND $(MAKE) -C ${bochs_src_dir} ${bochs_build_CXX} ${bochs_build_LIBTOOL} libfailbochs.a
## Put install command here, to prevent cmake calling make install
INSTALL_COMMAND ${CMAKE_COMMAND} -E echo "[${PROJECT_NAME}] Built libfailbochs.a"
BUILD_IN_SOURCE 1
)
# tell cmake that the external project generated a library so we can add dependencies here instead of later
add_library(libfailbochs STATIC IMPORTED)
set_property(TARGET libfailbochs PROPERTY IMPORTED_LOCATION ${bochs_src_dir}/libfailbochs.a )
add_dependencies(libfailbochs libfailbochs_external)
# make sure aspects don't fail to match in entry.cc
include_directories(${PROJECT_SOURCE_DIR}/src/core ${CMAKE_BINARY_DIR}/src/core)
# an executable needs at least one source file, so we hand over an empty .cc file to make cmake happy.
add_executable(fail-client ${bochs_src_dir}/fail_empty_source_file_for_build.cc)
target_link_libraries(fail-client libfailbochs fail ${bochs_library_dependencies})
install(TARGETS fail-client RUNTIME DESTINATION bin)
# Get stamp directory to touch files for forcing rebuilds.
ExternalProject_Get_Property(libfailbochs_external stamp_dir)
# a few Bochs-specific passthrough targets:
add_custom_target(bochsclean
COMMAND +make -C ${bochs_src_dir} clean
# touch stamp file to force rebuild, without calling configure again.
COMMAND ${CMAKE_COMMAND} -E touch_nocreate ${stamp_dir}/libfailbochs_external-configure
COMMENT "[${PROJECT_NAME}] Cleaning all up (clean in bochs)"
)
add_custom_target(bochsallclean
COMMAND +make -C ${bochs_src_dir} all-clean
# touch stamp file to force rebuild, without calling configure again.
COMMAND ${CMAKE_COMMAND} -E touch_nocreate ${stamp_dir}/libfailbochs_external-configure
COMMENT "[${PROJECT_NAME}] Cleaning all up (all-clean in bochs)"
)
endif(BUILD_BOCHS)

View File

@ -0,0 +1,30 @@
##### Verbose make ####
option( VERBOSE_MAKE "Verbose Makefile output" OFF) # defaults to OFF
set(CMAKE_VERBOSE_MAKEFILE ${VERBOSE_MAKE})
##### Compilers #####
SET( COMPILER "ag++" CACHE STRING "Use clang/gcc/ag++") # Defaults to ag++
if(${COMPILER} STREQUAL "clang")
set(CMAKE_C_COMPILER "clang")
set(CMAKE_CXX_COMPILER "clang++")
elseif(${COMPILER} STREQUAL "gcc")
set(CMAKE_C_COMPILER "gcc")
set(CMAKE_CXX_COMPILER "g++")
elseif(${COMPILER} STREQUAL "ag++")
set(CMAKE_C_COMPILER "ag++")
set(CMAKE_CXX_COMPILER "ag++")
set(CMAKE_AGPP_FLAGS "--real-instances" CACHE STRING "Additional ag++ flags, e.g. --real-instances --keep_woven")
## Here we add the build dir holding the generated header files (protobuf)
add_definitions("-p ${CMAKE_SOURCE_DIR}" ${CMAKE_AGPP_FLAGS} --Xcompiler)
else(${COMPILER} STREQUAL "clang")
message(FATAL_ERROR "COMPILER must be exactly one of clang/gcc/ag++. If unsure, use 'ag++'.")
endif(${COMPILER} STREQUAL "clang")
add_definitions(-D_FILE_OFFSET_BITS=64)
message(STATUS "[${PROJECT_NAME}] Compiler: ${CMAKE_C_COMPILER}/${CMAKE_CXX_COMPILER}" )

19
cmake/config_failbochs.sh.in Executable file
View File

@ -0,0 +1,19 @@
#!/bin/bash
SOURCE_DIR=@CMAKE_SOURCE_DIR@
BINARY_DIR=@CMAKE_BINARY_DIR@
PREFIX_DIR=@BOCHS_PREFIX_DIR@
if [ ! -d "$SOURCE_DIR" ]; then
echo Source directory does not exists! $SOURCE_DIR
exit 2
fi
if [ ! -d "$PREFIX_DIR" ]; then
echo Prefix directory does not exists! $BINARY_DIR
exit 2
fi
./configure CXX="ag++ -p $SOURCE_DIR -I$SOURCE_DIR/src -I"$BINARY_DIR"/src --real-instances --Xcompiler" LIBTOOL="/bin/sh ./libtool --tag=CXX" --prefix=$PREFIX_DIR --enable-{a20-pin,x86-64,cpu-level=6,ne2000,acpi,pci,usb,repeat-speedups,trace-cache,fast-function-calls,host-specific-asms,disasm,all-optimizations,readline,clgd54xx,fpu,vmx=2,monitor-mwait,cdrom,sb16=linux,gdb-stub} --with-all-libs

7
cmake/gem5.cmake Normal file
View File

@ -0,0 +1,7 @@
#### gem5-specific stuff
if(BUILD_GEM5)
message(STATUS "[${PROJECT_NAME}] Building gem5 variant ...")
SET(VARIANT gem5)
#set(gem5_src_dir ${PROJECT_SOURCE_DIR}/simulators/gem5)
endif(BUILD_GEM5)

59
cmake/mergelib.sh Executable file
View File

@ -0,0 +1,59 @@
#!/bin/bash
#
# Merge a list of static libraries (.a) and standalone objects (.o) into a
# common static library, and avoid .o naming conflicts.
#
set -e
shopt -s nullglob # expand "*.o" to "" instead of "*.o" if no .o file exists
[ -z "$1" ] && echo "usage: $0 output.a input1.a input2.a input3.o ..." >&2 && exit 1
OUT=$1
shift
TMPDIR=$(mktemp -d)
COUNT=1
# collect files in tmpdir, assign unique names
for f in "$@"
do
if echo "$f"|egrep -vq '\.[ao]'
then
echo "$0: can only merge .a/.o files, ignoring '$f'" >&2
continue
fi
cp $f $TMPDIR/$(printf %03d $COUNT)$(basename $f)
COUNT=$(($COUNT+1))
done
# create empty output lib
rm -f "$OUT"
ar rc "$OUT"
for lib in $TMPDIR/*.a
do
echo "[FAIL*] Unpacking/merging: $(basename $lib) " >&2
EXTRACTDIR=$TMPDIR/"$(basename $lib).dir"
( # subshell to preserve cwd
mkdir "$EXTRACTDIR"
cd "$EXTRACTDIR"
# unpack .o files to cwd
ar x "$lib"
# make sure the .o file names are unique
for f in *.o
do
mv "$f" $(basename "$lib")_"$f"
done
)
# move into merged library
ar r "$OUT" "$EXTRACTDIR"/*.o
rm -rf "$EXTRACTDIR"
done
ar r "$OUT" $TMPDIR/*.o
rm -rf "$TMPDIR" &
ranlib "$OUT"

5
cmake/ovp.cmake Normal file
View File

@ -0,0 +1,5 @@
#### OVP-specific stuff
if(BUILD_OVP)
message(STATUS "[${PROJECT_NAME}] Building OVP variant ...")
SET(VARIANT ovp)
endif(BUILD_OVP)

62
cmake/qemu.cmake Normal file
View File

@ -0,0 +1,62 @@
#### Add some custom targets for qemu-system-x86_64
if(BUILD_QEMU)
message(STATUS "[${PROJECT_NAME}] Building QEMU variant ...")
SET(VARIANT qemu)
# ./configure --prefix=$(echo ~/localroot/usr) --enable-sdl --disable-vnc --disable-curses --disable-curl --enable-system --target-list=x86_64-softmmu
# LIBS = -lrt -pthread -lgthread-2.0 -lglib-2.0 -lutil -luuid -lSDL -lX11 -lm -lz
# -L/usr/lib -lSDL -lasound -latk-1.0 -lcairo -lfontconfig -lfreetype -lgdk_pixbuf-2.0 -lgdk-x11-2.0 -lgio-2.0 -lglib-2.0 -lgmodule-2.0 -lgobject-2.0 -lgthread-2.0 -lgtk-x11-2.0 -lICE -lm -lncurses -lpango-1.0 -lpangocairo-1.0 -lpangoft2-1.0 -lrt -lSM -lvga -lvgagl -lwx_baseu-2.8 -lwx_gtk2u_core-2.8 -lX11 -lXpm -lXrandr -pthread)
find_package(SDL) # -lSDL
if(SDL_FOUND)
set(qemu_library_dependencies ${qemu_library_dependencies} ${SDL_LIBRARY})
endif(SDL_FOUND)
unset(FindSDL_DIR CACHE)
unset(SDLMAIN_LIBRARY CACHE)
unset(SDL_INCLUDE_DIR CACHE)
unset(SDL_LIBRARY CACHE)
find_package(GTK2 COMPONENTS gtk)
if(GTK2_FOUND)
set(qemu_library_dependencies ${qemu_library_dependencies} ${GTK2_GLIB_LIBRARY} -lgthread-2.0)
endif(GTK2_FOUND)
unset(FindGTK2_DIR CACHE)
unset(GTK2_GIOCONFIG_INCLUDE_DIR CACHE)
unset(GTK2_GIO_INCLUDE_DIR CACHE)
find_package(X11) # -lX11
if(X11_FOUND)
set(qemu_library_dependencies ${qemu_library_dependencies} ${X11_X11_LIB})
endif(X11_FOUND)
find_package(ZLIB) # -lz
if(ZLIB_FOUND)
set(qemu_library_dependencies ${qemu_library_dependencies} ${ZLIB_LIBRARIES})
endif(ZLIB_FOUND)
find_package(LibUUID) # -luuid
if(UUID_FOUND)
set(qemu_library_dependencies ${qemu_library_dependencies} ${UUID_LIBRARIES})
endif(UUID_FOUND)
# FIXME: some libraries still need to be located the "cmake way"
set(qemu_library_dependencies ${qemu_library_dependencies} -lrt -pthread -lutil -lm)
set(qemu_src_dir ${PROJECT_SOURCE_DIR}/simulators/qemu)
set(qemu_lib "${qemu_src_dir}/x86_64-softmmu/qemu-system-x86_64.a")
add_custom_command(OUTPUT "${qemu_lib}"
COMMAND +make -C ${qemu_src_dir} CFLAGS=\"-I${PROJECT_SOURCE_DIR}/src/core -I${CMAKE_BINARY_DIR}/src/core\"
COMMENT "[${PROJECT_NAME}] Building qemu-system-x86_64.a"
)
# make sure aspects don't fail to match in entry.cc
include_directories(${PROJECT_SOURCE_DIR}/src/core ${CMAKE_BINARY_DIR}/src/core)
add_executable(fail-client "${qemu_lib}")
target_link_libraries(fail-client -Wl,-whole-archive "${qemu_lib}" -Wl,-no-whole-archive fail ${qemu_library_dependencies})
install(TARGETS fail-client RUNTIME DESTINATION bin)
# a few QEMU-specific passthrough targets:
add_custom_target(qemuclean
COMMAND +make -C ${qemu_src_dir} clean
COMMENT "[${PROJECT_NAME}] Cleaning all up (clean in qemu)"
)
endif(BUILD_QEMU)

10
cmake/t32.cmake Normal file
View File

@ -0,0 +1,10 @@
#### Add some custom targets for T32
if(BUILD_T32)
message(STATUS "[${PROJECT_NAME}] Building T32 variant ...")
SET(VARIANT t32)
# make sure aspects don't fail to match in entry.cc
include_directories(${PROJECT_SOURCE_DIR}/src/core ${CMAKE_BINARY_DIR}/src/core)
endif(BUILD_T32)

1
debuggers/gdb/README Normal file
View File

@ -0,0 +1 @@
TODO: a nice GDB backend.

View File

@ -0,0 +1,8 @@
include_directories(include)
include_directories(${CMAKE_BINARY_DIR}/src/core)
add_subdirectory(api)
add_subdirectory(src)

View File

@ -0,0 +1 @@
add_library(t32api hlinknet.cc hremote.cc)

View File

@ -0,0 +1,882 @@
/****************************************************************
* *
* Copyright notice: *
* *
* Lauterbach Datentechnik GmbH *
* Alle Rechte vorbehalten - All rights reserved *
* *
*****************************************************************
Module: hlinknet.c
Function: Low level communication protocol for talking to TRACE32.
Is used by CAPI routined implemented in hremote.c.
Link both files with your application.
***************************************************************/
#include "t32.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef MS_WINDOWS
# include <winsock2.h>
# include <windows.h>
# include <fcntl.h>
typedef int socklen_t;
#endif
#ifdef DEC_VMS
# include <file.h>
# include <time.h>
# include <errno.h>
# include <socket.h>
# include <inet.h>
# include <netdb.h>
# include <in.h>
# define DONT_USE_ASYNC
#endif
#ifdef __linux__
# include <fcntl.h>
# include <unistd.h>
# include <sys/time.h>
# include <errno.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <netdb.h>
# include <sys/select.h>
#endif
#ifdef UNIX_V
# include <fcntl.h>
# include <unistd.h>
# include <sys/time.h>
# include <errno.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <netdb.h>
# ifdef HP_UX
typedef int socklen_t;
# else
# include <sys/select.h>
# endif
#endif
#ifdef OS_9
# include <fcntl.h>
# include <sys/time.h>
# include <errno.h>
# include <inet/socket.h>
# include <inet/in.h>
# include <inet/netdb.h>
#endif
#define PCKLEN_MAX 1472 /* maximum size of UDP-packet */
#define BUFLEN_MIN 6000
#ifndef MS_WINDOWS
# ifndef UNIX_V
extern struct hostent * gethostbyaddr();
# endif
#endif
#ifdef DEC_VMS
# define fd_set int
# define FD_ZERO(fdset) (*fdset = 0)
# define FD_SET(fd,fdset) (*fdset |= (1<<(fd)))
# define FD_ISSET(fd,fdset) (*fdset & (1<<(fd)))
#endif
#if defined(DEC_VMS) || defined(MS_WINDOWS) || defined(OS_9) || defined(LINUX)
# define RECEIVEADDR (&ReceiveSocketAddress)
static struct sockaddr ReceiveSocketAddress;
#else
# define RECEIVEADDR 0
#endif
struct LineStruct {
char NodeName[80]; /* node name of host running T32 SW */
int CommSocket; /* socket for communication */
unsigned short HostPort; /* Host side port */
unsigned short ReceivePort; /* Receiver Port */
unsigned short TransmitPort; /* Transmitter Port in T32 */
int PacketSize; /* Max. size of UDP-packet data */
int PollTimeSec;
int ReceiveToggleBit;
unsigned char MessageId;
int LineUp;
unsigned short ReceiveSeq, TransmitSeq; /* block-ids */
unsigned short LastReceiveSeq, LastTransmitSeq;
unsigned char* LastTransmitBuffer;
int LastTransmitSize;
struct sockaddr_in SocketAddress;
};
#ifdef MS_WINDOWS
extern void T32_InstallAsyncSelect(HWND hwnd, int msg);
extern void T32_UnInstallAsyncSelect(HWND hwnd);
#endif
extern void LINE_SetReceiveToggleBit(int value);
extern int LINE_GetReceiveToggleBit(void);
extern int LINE_GetNextMessageId(void);
extern int LINE_GetMessageId(void);
extern int LINE_GetLineParamsSize (void);
extern void LINE_SetDefaultLineParams (LineStruct* params);
extern LineStruct* LINE_GetLine0Params (void);
extern void LINE_SetLine (LineStruct* params);
extern int LINE_LineConfig(char * in);
extern void LINE_LineExit(void);
extern int LINE_LineInit(char * message);
extern int LINE_LineTransmit(unsigned char * in, int size);
extern int LINE_LineDriverGetSocket(void);
extern int LINE_LineReceive(unsigned char * out);
extern int LINE_ReceiveNotifyMessage(unsigned char* package);
extern int LINE_LineSync(void);
static int Connection(unsigned char *ipaddrused);
static struct timeval LongTime = { 0, 500000 };
static const LineStruct LineDefaultParams = {
"localhost", -1, 0, 0, 20000, 1024, 5, -1, 0, 0};
static LineStruct Line0Params = {
"localhost", -1, 0, 0, 20000, 1024, 5, -1, 0, 0};
static LineStruct* pLineParams = &Line0Params;
static int str2dec (char* in)
{
int x = 0;
while (*in) {
x *= 10;
if (*in < '0' || *in > '9')
return -1;
x += *in - '0';
in++;
}
return x;
}
void LINE_SetReceiveToggleBit(int value)
{
pLineParams->ReceiveToggleBit = value;
}
int LINE_GetReceiveToggleBit(void)
{
return pLineParams->ReceiveToggleBit;
}
int LINE_GetNextMessageId(void)
{
return ++pLineParams->MessageId;
}
int LINE_GetMessageId(void)
{
return pLineParams->MessageId;
}
int LINE_GetLineParamsSize (void)
{
return sizeof (LineStruct);
}
void LINE_SetDefaultLineParams (LineStruct* params)
{
*params = LineDefaultParams;
return;
}
LineStruct* LINE_GetLine0Params (void)
{
return &Line0Params;
}
void LINE_SetLine (LineStruct* params)
{
pLineParams = params;
}
int LINE_LineConfig(char * in)
{
int x;
LineStruct* line = pLineParams;
if (!strncmp((char *) in, "NODE=", 5)) {
strcpy(line->NodeName, in+5);
return 1;
}
if (!strncmp((char *) in, "PORT=", 5)) {
x = str2dec (in+5);
if (x == -1)
return -1;
line->TransmitPort = x;
return 1;
}
if (!strncmp((char *) in, "HOSTPORT=", 9)) {
x = str2dec (in+9);
if (x == -1)
return -1;
line->HostPort = x;
return 1;
}
if (!strncmp((char *) in, "PACKLEN=", 8)) {
x = str2dec (in+8);
if (x == -1)
return -1;
line->PacketSize = x;
return 1;
}
if (!strncmp((char *) in, "TIMEOUT=", 8)) {
x = str2dec (in+8);
if (x == -1)
return -1;
line->PollTimeSec = x;
return 1;
}
return -1;
}
static void WinsockErrorMessage(char * out)
{
#ifdef MS_WINDOWS
int err;
err = WSAGetLastError();
switch (err) {
case WSAHOST_NOT_FOUND:
strcat(out, " (HOST_NOT_FOUND)");
break;
case WSATRY_AGAIN:
strcat(out, " (TRY_AGAIN)");
break;
case WSANO_RECOVERY:
strcat(out, " (NO_RECOVERY)");
break;
case WSANO_DATA:
strcat(out, " (NO_DATA)");
break;
case WSAEINTR:
strcat(out, " (INTR)");
break;
case WSANOTINITIALISED:
strcat(out, " (NOTINITIALISED)");
break;
case WSAENETDOWN:
strcat(out, " (NETDOWN)");
break;
case WSAEAFNOSUPPORT:
strcat(out, " (WSAEAFNOSUPPORT)");
break;
case WSAEINPROGRESS:
strcat(out, " (INPROGRESS)");
break;
case WSAEMFILE:
strcat(out, " (WSAEMFILE)");
break;
case WSAENOBUFS:
strcat(out, " (WSAENOBUFS)");
break;
case WSAEPROTONOSUPPORT:
strcat(out, " (WSAEPROTONOSUPPORT)");
break;
case WSAEPROTOTYPE:
strcat(out, " (WSAEPROTOTYPE)");
break;
case WSAESOCKTNOSUPPORT:
strcat(out, " (WSAESOCKTNOSUPPORT)");
break;
}
#endif
}
static long GetInetAddress(char * name, char * message)
{
struct hostent *hp;
int i1, i2, i3, i4;
char ownname[256];
if (name == NULL) {
gethostname(ownname, sizeof(ownname));
name = ownname;
}
i1 = i2 = i3 = i4 = 0;
if (sscanf(name, "%d.%d.%d.%d", &i1, &i2, &i3, &i4) == 4) {
if (i1 || i2 || i3 || i4) {
return (i1 << 24) | (i2 << 16) | (i3 << 8) | (i4);
}
}
hp = gethostbyname(name);
if (!hp) {
strcpy(message, "node name (");
strcat(message, name);
strcat(message, ") unknown");
WinsockErrorMessage(message);
return -1l;
}
return ntohl(*(long *) (hp->h_addr));
}
void LINE_LineExit(void)
{
int i;
LineStruct* line = pLineParams;
static const unsigned char discon[] = {4, 0, 0, 0, 0, 0, 0, 0, 'T', 'R', 'A', 'C', 'E', '3', '2', 0};
if (!line->LineUp)
return;
if (line->CommSocket != -1) {
for (i = 0; i < 5; i++)
sendto(line->CommSocket, (char *) discon, 16, 0,
(struct sockaddr *) &(line->SocketAddress), sizeof(line->SocketAddress));
#ifdef MS_WINDOWS
closesocket(line->CommSocket);
#endif
#if defined(DEC_VMS) || defined(UNIX_V) || defined(OS_9)
close(line->CommSocket);
#endif
}
#ifdef MS_WINDOWS
WSACleanup();
#endif
line->CommSocket = -1;
line->LineUp = 0;
}
int LINE_LineInit(char * message)
{
int i, j;
socklen_t length;
int val;
unsigned char ipaddrused[4];
long remote_ip;
int buflen;
LineStruct* line = pLineParams;
if (line->LineUp)
return 0;
if (line->CommSocket == -1) {
#ifdef MS_WINDOWS
WSADATA wsaData;
if (WSAStartup(0x0101, &wsaData)) {
strcpy(message, "TCP/IP not ready, check configuration");
return -1;
}
#endif
}
if ((remote_ip = GetInetAddress(line->NodeName, message)) == -1l)
return -1;
if (line->CommSocket == -1) {
line->SocketAddress.sin_family = AF_INET;
line->SocketAddress.sin_addr.s_addr = INADDR_ANY;
line->SocketAddress.sin_port = line->HostPort; /* Port can be determined by
* host */
if ((line->CommSocket = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
strcpy(message, "cannot create socket");
WinsockErrorMessage(message);
goto done;
}
if ((i = bind(line->CommSocket, (struct sockaddr *) & line->SocketAddress, sizeof(line->SocketAddress))) == -1) {
strcpy(message, "cannot bind socket");
WinsockErrorMessage(message);
goto done;
}
length = sizeof(line->SocketAddress);
if (getsockname(line->CommSocket, (struct sockaddr *) & line->SocketAddress, &length) == -1) {
strcpy(message, "cannot identify port");
WinsockErrorMessage(message);
goto done;
}
line->ReceivePort = ntohs(line->SocketAddress.sin_port);
line->SocketAddress.sin_family = AF_INET;
line->SocketAddress.sin_addr.s_addr = INADDR_ANY;
line->SocketAddress.sin_port = htons(line->TransmitPort);
}
line->SocketAddress.sin_addr.s_addr = htonl(remote_ip);
buflen = 18000;
#if !defined(OS_9)
val = 0;
length = sizeof(val);
getsockopt(line->CommSocket, SOL_SOCKET, SO_RCVBUF, (char *) &val, &length);
if (val > 0 && val < line->PacketSize)
line->PacketSize = val;
if (val < buflen) {
val = buflen;
length = sizeof(val);
if (setsockopt(line->CommSocket, SOL_SOCKET, SO_RCVBUF, (char *) &val, length) == -1) {
strcpy(message, "cannot alloc buffer for rcvsocket");
goto done;
}
val = 0;
length = sizeof(val);
getsockopt(line->CommSocket, SOL_SOCKET, SO_RCVBUF, (char *) &val, &length);
if (val < buflen) {
strcpy(message, "cannot alloc buffer for rcvsocket");
goto done;
}
}
val = 0;
length = sizeof(val);
getsockopt(line->CommSocket, SOL_SOCKET, SO_SNDBUF, (char *) &val, &length);
if (val < buflen) {
val = buflen;
length = sizeof(val);
if (setsockopt(line->CommSocket, SOL_SOCKET, SO_SNDBUF, (char *) &val, length) == -1) {
strcpy(message, "cannot alloc buffer for sndsocket");
goto done;
}
val = 0;
length = sizeof(val);
getsockopt(line->CommSocket, SOL_SOCKET, SO_SNDBUF, (char *) &val, &length);
if (val < buflen) {
strcpy(message, "cannot alloc buffer for sndsocket");
goto done;
}
}
#endif
for (i = 0; i < 10; i++) {
j = Connection(ipaddrused);
if (j == 0)
continue;
if (j == 1) {
line->LineUp = 1;
return 1;
}
strcpy(message, "TRACE32 access refused");
goto done;
}
strcpy(message, "TRACE32 not responding");
done:
LINE_LineExit(); /* Close connection if no success */
return -1;
}
#ifdef MS_WINDOWS
void T32_InstallAsyncSelect(HWND hwnd, int msg)
{
#ifndef DONT_USE_ASYNC
WSAAsyncSelect(pLineParams->CommSocket, hwnd, msg, FD_READ);
#endif
}
void T32_UnInstallAsyncSelect(HWND hwnd)
{
#ifndef DONT_USE_ASYNC
WSAAsyncSelect(pLineParams->CommSocket, hwnd, 0, 0);
#endif
}
#endif
/**
Sends a message to T32. Handles segmentation of _message_ into (one
or multiple) _packages_.
@param in pointer to outgoing message (already includes 5 byte message header)
@param size size of message
@note the message must be allocated such that there is space in
front of the message for adding the packet header
*/
int LINE_LineTransmit(unsigned char * in, int size)
{
int packetSize;
unsigned int tmpl;
LineStruct* line = pLineParams;
line->LastTransmitBuffer = in;
line->LastTransmitSize = size;
line->LastTransmitSeq = line->TransmitSeq;
in -= 4; /* space for packet header */
do {
packetSize = (size > line->PacketSize - 4) ? line->PacketSize - 4 : size;
/* When sending multiple packets, the packet header is written inside the
message's payload. Original contents needs to be saved/restored */
SETLONGVAR(tmpl, in[0]); /* save */
in[0] = 0x11; /* transmit data package */
in[1] = (size > packetSize) ? 1 : 0; /* more packets follow */
SETWORDVAR(in[2], line->TransmitSeq); /* packet sequence ID */
if (sendto(line->CommSocket,
(char *) in,
packetSize + 4, 0,
(struct sockaddr *) & line->SocketAddress, sizeof(line->SocketAddress)
) != packetSize + 4) {
SETLONGVAR(in[0], tmpl); /* restore buffer */
return 0;
}
SETLONGVAR(in[0], tmpl); /* restore buffer */
line->TransmitSeq++;
in += packetSize;
size -= packetSize;
}
while (size > 0); /* more packets required? */
return line->LastTransmitSize;
}
/** Receives a package from the socket, with timeout handling.
@return number of received bytes or error number (<0)
*/
static int ReceiveWithTimeout(struct timeval *tim, unsigned char *dest, int size)
{
int i;
fd_set readfds;
socklen_t length;
struct timeval timeout;
LineStruct* line = pLineParams;
timeout = *tim;
#ifdef POLL_NET
DWORD endpoll;
static struct timeval tival = {0};
if (tim->tv_usec || tim->tv_sec)
endpoll = GetCurrentTime() + tim->tv_usec / 1000 + tim->tv_sec * 1000;
else
endpoll = 0;
retry:
#endif
FD_ZERO(&readfds);
FD_SET( (unsigned int)line->CommSocket, &readfds);
#ifdef POLL_NET
i = select(FD_SETSIZE, &readfds, (fd_set *) NULL, (fd_set *) NULL, &tival);
if (i < 0)
return i;
if (i == 0) {
if (endpoll) {
if (GetCurrentTime() < endpoll) {
ScreenDispatcher(line->CommSocket);
goto retry;
}
}
return i;
}
#else
i = select(FD_SETSIZE, &readfds, (fd_set *) NULL, (fd_set *) NULL, &timeout);
#endif
if (i <= 0) {
return i;
}
length = sizeof(struct sockaddr);
return recvfrom(line->CommSocket, dest, size, 0, (struct sockaddr *) RECEIVEADDR, &length);
}
int LINE_LineDriverGetSocket(void)
{
return pLineParams->CommSocket;
}
/* Queue pending notifications */
T32_NotificationPackage *T32_NotificationHead = NULL, *T32_NotificationTail = NULL;
/** Receives messages from the socket. Assembles multiple packets into
a single message.
@param out output buffer for storing payload. Attention: there must
be some space _before_ the output buffer (4 bytes or more)
for temporary usage.
@return number of bytes of the message or error number (<0)
*/
int LINE_LineReceive(unsigned char * out)
{
int i, flag;
int count;
unsigned short tmpw;
unsigned int tmpl;
unsigned short s;
LineStruct* line = pLineParams;
register unsigned char *dest;
static unsigned char handshake[] = {7, 0, 0, 0, 0, 0, 0, 0, 'T', 'R', 'A', 'C', 'E', '3', '2', 0};
retry:
dest = out-4; /* adjust pointer so we place header BEFORE "out" and thus payload AT "out" */
count = 0;
s = line->ReceiveSeq;
do {
/* multiple packets are merged in-place: backup data that is
overwritten package aby header */
SETLONGVAR(tmpl, dest[0]);
do {
struct timeval PollTime = {0, 0};
PollTime.tv_sec = line->PollTimeSec;
if ((i = ReceiveWithTimeout(&PollTime, dest, line->PacketSize)) <= 0) {
if (i == -2)
goto retry;
return -1;
}
if (i <= 4) {
return -1;
}
/* Detect and enqeue async notification that slipped into a request/reply pair */
if (dest[0] == T32_API_NOTIFICATION)
{
T32_NotificationPackage *newPackage, *oldHead;
newPackage = reinterpret_cast<T32_NotificationPackage*>( malloc(sizeof(T32_NotificationPackage)) );
if (newPackage==NULL)
return -1;
memcpy(newPackage, dest, i); /* in theory i should always be the package size, at least for ethernet */
oldHead = T32_NotificationHead;
newPackage->prev = NULL;
newPackage->next = oldHead;
if (oldHead)
oldHead->prev = newPackage;
T32_NotificationHead = newPackage;
if (T32_NotificationTail==NULL) {
T32_NotificationTail=newPackage;
}
goto retry;
}
if (dest[0] != T32_API_RECEIVE) {
return -1;
}
SETWORDVAR(tmpw, dest[2]);
if (tmpw == line->LastReceiveSeq && line->LastTransmitSize) {
line->TransmitSeq = line->LastTransmitSeq;
LINE_LineTransmit(line->LastTransmitBuffer, line->LastTransmitSize);
}
}
while (tmpw != line->ReceiveSeq);
line->ReceiveSeq++;
flag = dest[1];
SETLONGVAR(dest[0], tmpl); /* restore payload overwritten by package header */
dest += i - 4;
count += i - 4;
if (count > LINE_MSIZE) {
return -1;
}
if (flag == 2) {
if (sendto(line->CommSocket, (char *) handshake, 16, 0,
(struct sockaddr *) &line->SocketAddress, sizeof(line->SocketAddress)) != 16) {
return -1;
}
}
}
while (flag);
line->LastReceiveSeq = s;
return count;
}
/** Receives notification messages. First checks for a queued
notification and if none is available polls the socket for new
notifications. For getting all pending notifications call the
function until it returns -1.
@param package output buffer of size T32_PCKLEN_MAX for the package
@return -1 no notification pending,
>=0 notificataion type T32_E_BREAK, T32_E_EDIT, T32_E_BREAKPOINTCONFIG
*/
int LINE_ReceiveNotifyMessage(unsigned char* package)
{
int len;
static struct timeval LongTime = {0, 0};
/* Check for asynchronous notifications */
if (T32_NotificationTail) {
T32_NotificationPackage *prev = T32_NotificationTail->prev;
if (prev)
prev->next = NULL;
memcpy(package, T32_NotificationTail->payload, T32_PCKLEN_MAX);
free(T32_NotificationTail);
T32_NotificationTail = prev;
if (prev==NULL) /* deleted last message */
T32_NotificationHead = NULL;
} else {
len = ReceiveWithTimeout(&LongTime, package, T32_PCKLEN_MAX);
if (len < 2)
return -1;
}
if (package[0] != T32_API_NOTIFICATION)
return -1;
return package[1]; /* type of notification: T32_E_BREAK, T32_E_EDIT, T32_E_BREAKPOINTCONFIG */
}
/** Sends sync packets */
int LINE_LineSync(void)
{
int i, j;
unsigned char packet[T32_PCKLEN_MAX];
static char magicPattern[] = "TRACE32";
LineStruct* line = pLineParams;
j = 0;
memset(packet, 0, sizeof(packet));
retry:
packet[0] = T32_API_SYNCREQUEST;
packet[1] = 0;
SETWORDVAR(packet[2], line->TransmitSeq);
SETWORDCONST(packet[4], 0);
SETWORDCONST(packet[6], 0);
strcpy((char *) (packet + 8), magicPattern);
if (sendto(line->CommSocket, (char *) packet, 16 /*size*/, 0,
(struct sockaddr *) & line->SocketAddress, sizeof(line->SocketAddress)) == -1) {
return -1;
}
while (1) { /* empty queue */
if (++j > 20) {
return -1;
}
if ((i = ReceiveWithTimeout(&LongTime, packet, T32_PCKLEN_MAX)) <= 0) {
return -1;
}
if (i != 16 || packet[0] != T32_API_SYNCACKN || strcmp((char *) packet + 8, magicPattern)) {
if (i == 16 && packet[0] == 5)
goto retry;
continue;
}
break;
}
SETWORDVAR(line->ReceiveSeq, packet[2]);
line->LastReceiveSeq = line->ReceiveSeq - 100;
packet[0] = T32_API_SYNCBACK;
packet[1] = 0;
SETWORDVAR(packet[2], line->TransmitSeq);
SETWORDCONST(packet[4], 0);
SETWORDCONST(packet[6], 0);
strcpy((char *) (packet + 8), magicPattern);
if (sendto(line->CommSocket, (char *) packet, 16, 0, (struct sockaddr *) & line->SocketAddress, sizeof(line->SocketAddress)) == -1) {
return -1;
}
return 1;
}
static int Connection(unsigned char *ipaddrused)
{
int i;
unsigned char buffer[T32_PCKLEN_MAX];
LineStruct* line = pLineParams;
static const char magicPattern[] = "TRACE32";
memset(buffer, 0, sizeof(buffer));
buffer[0] = 3; /* CONNECTREQUEST */
buffer[1] = 0;
line->TransmitSeq = 1;
SETWORDVAR(buffer[2], line->TransmitSeq);
SETWORDVAR(buffer[4], line->TransmitPort);
SETWORDVAR(buffer[6], line->ReceivePort);
strcpy((char *) (buffer + 8), magicPattern);
if (sendto(line->CommSocket, (char *) buffer, line->PacketSize, 0, (struct sockaddr *) & line->SocketAddress, sizeof(line->SocketAddress)) == -1) {
return 0;
}
if ((i = ReceiveWithTimeout(&LongTime, buffer, line->PacketSize)) <= 0) {
return 0;
}
if (strcmp((char *) (buffer + 8), magicPattern)) {
return 0;
}
SETWORDVAR(line->ReceiveSeq, buffer[2]);
if (buffer[0] == 0x53) { /* POSITIVE CONNECTACKN from Debug Unit ? */
ipaddrused[0] = 1;
ipaddrused[1] = 1;
ipaddrused[2] = 1;
ipaddrused[3] = 11;
return 2;
}
if (buffer[0] != 0x13) { /* POSITIVE CONNECTACKN ? */
if (buffer[0] == 0x23) {/* NEGATIVE ? */
ipaddrused[0] = buffer[4];
ipaddrused[1] = buffer[5];
ipaddrused[2] = buffer[6];
ipaddrused[3] = buffer[7];
return 2;
}
return 0;
}
line->PacketSize = i;
return 1;
}

2427
debuggers/t32/api/hremote.cc Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,21 @@
#ifndef __T32CONNECTOR_HPP__
#define __T32CONNECTOR_HPP__
namespace fail {
class T32Connector {
char* m_hostname;
unsigned m_port;
unsigned m_packetlength;
public:
T32Connector() { };
T32Connector(char* hostname, unsigned port, unsigned packlen);
~T32Connector();
};
} // end-of-namespace fail
#endif // __T32CONNECTOR_HPP__

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,53 @@
#ifndef __OPTIONSPARSER_EXT_HPP__
#define __OPTIONSPARSER_EXT_HPP__
struct Arg: public option::Arg
{
static void printError(const char* msg1, const option::Option& opt, const char* msg2)
{
fprintf(stderr, "%s", msg1);
fwrite(opt.name, opt.namelen, 1, stderr);
fprintf(stderr, "%s", msg2);
}
static option::ArgStatus Unknown(const option::Option& option, bool msg)
{
if (msg) printError("Unknown option '", option, "'\n");
return option::ARG_ILLEGAL;
}
static option::ArgStatus Required(const option::Option& option, bool msg)
{
if (option.arg != 0)
return option::ARG_OK;
if (msg) printError("Option '", option, "' requires an argument\n");
return option::ARG_ILLEGAL;
}
static option::ArgStatus NonEmpty(const option::Option& option, bool msg)
{
if (option.arg != 0 && option.arg[0] != 0)
return option::ARG_OK;
if (msg) printError("Option '", option, "' requires a non-empty argument\n");
return option::ARG_ILLEGAL;
}
static option::ArgStatus Numeric(const option::Option& option, bool msg)
{
char* endptr = 0;
if (option.arg != 0 && strtol(option.arg, &endptr, 10)){};
if (endptr != option.arg && *endptr == 0)
return option::ARG_OK;
if (msg) printError("Option '", option, "' requires a numeric argument\n");
return option::ARG_ILLEGAL;
}
};
#endif // __OPTIONSPARSER_EXT_HPP__

366
debuggers/t32/include/t32.h Normal file
View File

@ -0,0 +1,366 @@
#ifndef __T32_H__
#define __T32_H__
#include <config/VariantConfig.hpp>
#if defined WIN32 || defined WIN64
#ifndef MS_WINDOWS
#define MS_WINDOWS
#endif
#define LOW_HIGH
#endif
#ifdef DEC_VMS
#define LOW_HIGH_BYTE
#endif
#ifdef DEC_OSF1
#define UNIX_V
#define LOW_HIGH_BYTE
#endif
#ifdef HP_UX
#define UNIX_V
#define HIGH_LOW_BYTE
#endif
#ifdef IBM_AIX
#define UNIX_V
#define HIGH_LOW_BYTE
#endif
#ifdef __linux__
# ifndef LINUX
# define LINUX
# endif
# define UNIX_V
# define LOW_HIGH_BYTE
#endif
#ifdef T32HOST_LINUX_X64
# define UNIX_V
# define LOW_HIGH_BYTE
#endif
#ifdef LINUX_PPC
# ifndef LINUX
# define LINUX
# endif
# define UNIX_V
# define HIGH_LOW_BYTE
#endif
#ifdef T32HOST_MACOSX_X86
# define UNIX_V
# define LOW_HIGH_BYTE
#endif
#ifdef SUN_SOL
#define UNIX_V
#define HIGH_LOW_BYTE
#endif
typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned int dword;
#ifdef HIGH_LOW_BYTE
#define SETWORDCONST(A,B) ( ((unsigned char *)&(A))[0] = (B),((unsigned char *)&(A))[1] = (B)>>8 )
#define SETLONGCONST(A,B) ( ((unsigned char *)&(A))[0] = (B),((unsigned char *)&(A))[1] = (B)>>8,((unsigned char *)&(A))[2] = (B)>>16,((unsigned char *)&(A))[3] = (B)>>24 )
#define SETWORDVAR(A,B) ( ((unsigned char *)&(A))[0] = ((unsigned char *)&(B))[1],((unsigned char *)&(A))[1] = ((unsigned char *)&(B))[0] )
#define SETLONGVAR(A,B) ( ((unsigned char *)&(A))[0] = ((unsigned char *)&(B))[3],((unsigned char *)&(A))[1] = ((unsigned char *)&(B))[2],((unsigned char *)&(A))[2] = ((unsigned char *)&(B))[1],((unsigned char *)&(A))[3] = ((unsigned char *)&(B))[0] )
#endif
#ifdef HIGH_LOW
#define SETWORDCONST(A,B) ((*((unsigned short *)&(A))) = (unsigned short)((((B)>>8)&0xff)|(((B)<<8)&0xff00)))
#define SETLONGCONST(A,B) ((*((int *)&(A))) = (int)((((B)>>24)&0xffl)|(((B)>>8)&0xff00l)|(((B)<<8)&0xff0000l)|(((B)<<24)&0xff000000l)))
#define SETWORDVAR(A,B) ( ((unsigned char *)&(A))[0] = ((unsigned char *)&(B))[1],((unsigned char *)&(A))[1] = ((unsigned char *)&(B))[0] )
#define SETLONGVAR(A,B) ( ((unsigned char *)&(A))[0] = ((unsigned char *)&(B))[3],((unsigned char *)&(A))[1] = ((unsigned char *)&(B))[2],((unsigned char *)&(A))[2] = ((unsigned char *)&(B))[1],((unsigned char *)&(A))[3] = ((unsigned char *)&(B))[0] )
#endif
#ifdef LOW_HIGH
#define SETWORDCONST(A,B) ((*((unsigned short *)&(A))) = (unsigned short)(B))
#define SETLONGCONST(A,B) ((*((int *)&(A))) = (int)(B))
#define SETWORDVAR(A,B) ((*((unsigned short *)&(A))) = (*((unsigned short *)&(B))))
#define SETLONGVAR(A,B) ((*((int *)&(A))) = (*((int *)&(B))))
#endif
#ifdef LOW_HIGH_BYTE
#define SETWORDCONST(A,B) ( ((unsigned char *)&(A))[0] = (B),((unsigned char *)&(A))[1] = (B)>>8 )
#define SETLONGCONST(A,B) ( ((unsigned char *)&(A))[0] = (B),((unsigned char *)&(A))[1] = (B)>>8,((unsigned char *)&(A))[2] = (B)>>16,((unsigned char *)&(A))[3] = (B)>>24 )
#define SETWORDVAR(A,B) ( ((unsigned char *)&(A))[0] = ((unsigned char *)&(B))[0],((unsigned char *)&(A))[1] = ((unsigned char *)&(B))[1] )
#define SETLONGVAR(A,B) ( ((unsigned char *)&(A))[0] = ((unsigned char *)&(B))[0],((unsigned char *)&(A))[1] = ((unsigned char *)&(B))[1],((unsigned char *)&(A))[2] = ((unsigned char *)&(B))[2],((unsigned char *)&(A))[3] = ((unsigned char *)&(B))[3] )
#endif
#define LINE_MBLOCK 16384 /* large block mode */
#define LINE_MSIZE (LINE_MBLOCK+256)
#define T32_DEV_OS 0
#define T32_DEV_ICE 1
#define T32_DEV_ICD 1 /* similar to ICE but clearer for user */
/* Events that can be generated by T32 */
#define T32_MAX_EVENTS 3
#define T32_E_BREAK 0x0 /* change in runstate, probably only "break" */
#define T32_E_EDIT 0x1 /* user requested "edit source" in external editor */
#define T32_E_BREAKPOINTCONFIG 0x2 /* breakpoint configuration changed (breakpoint set/removed) */
/* Callbacks should have the following protoypes */
/************************* WARNING *****************************/
/*
* If you add more callback functions here, make sure you ONLY
* use 'int', 'unsigned int', 'integral-type *' or 'float-type *' as parameters.
*
* No 'long', no 'long long', no 'short', no 'char', no floats, no typedefs
* and no function pointers!
* This is because we absolutely need to avoid portability problems here.
*
* Explanation:
* The T32_NotificationCallback_t typedef'd below has an empty parameter list,
* which we can't change anymore to a va_list because of backwards compatibility.
* This means only the native types like 'int' and 'integral type *' can be used
* safely, otherwise we run into hard-to-debug problems with type-promotion and
* parameter-passing conventions on the varying platforms we support.
*/
extern void T32_callbackBreak(int generic);
extern void T32_callbackEditExtern(int generic, int lineNr, unsigned char *fileName);
extern void T32_callbackBreakpointConfig(int generic);
#define T32_API_RECEIVE 0x1
/* Missing: 0x5, */
#define T32_API_NOTIFICATION 0x6
#define T32_API_SYNCREQUEST 0x02
#define T32_API_SYNCACKN 0x12
#define T32_API_SYNCBACK 0x22
#define T32_PCKLEN_MAX 1472
typedef struct t32_notification {
char payload[T32_PCKLEN_MAX]; /* maximum packet size*/
struct t32_notification *next, *prev;
/* T32_NotificationPackage *next;
T32_NotificationPackage *prev; */
} T32_NotificationPackage;
extern T32_NotificationPackage *T32_NotificationHead, *T32_NotificationTail; /* Queue pending notifications */
#define T32_COM_RECEIVE_FAIL -1
#define T32_COM_TRANSMIT_FAIL -2
#define T32_COM_PARA_FAIL -3
#define T32_COM_SEQ_FAIL -4
#define T32_MAX_EVENT_FAIL -5
#define T32_MALLOC_FAIL -6
typedef void * T32_TAPACCESS_HANDLE;
#define T32_TAPACCESS_MAXBITS 0x3b00
#define T32_TAPACCESS_RELEASE ((T32_TAPACCESS_HANDLE)0)
#define T32_TAPACCESS_HOLD ((T32_TAPACCESS_HANDLE)1)
#define T32_TAPACCESS_TDO 0x00
#define T32_TAPACCESS_TDI 0x04
#define T32_TAPACCESS_TMS 0x08
#define T32_TAPACCESS_TCK 0x0c
#define T32_TAPACCESS_nTRST 0x10
#define T32_TAPACCESS_nRESET 0x14
#define T32_TAPACCESS_nRESET_LATCH 0x18
#define T32_TAPACCESS_VTREF 0x1c
#define T32_TAPACCESS_VTREF_LATCH 0x20
#define T32_TAPACCESS_nENOUT 0x24
#define T32_TAPACCESS_SET(x) (2|((x)&1))
#define T32_TAPACCESS_SET_LOW 2
#define T32_TAPACCESS_SET_HIGH 3
#define T32_TAPACCESS_SET_0 T32_TAPACCESS_SET_LOW
#define T32_TAPACCESS_SET_1 T32_TAPACCESS_SET_HIGH
#define T32_TAPACCESS_SHIFT 0x30
#define T32_TAPACCESS_SHIFTTMS 0x40
#define T32_TAPACCESS_SHIFTIR 0x50
#define T32_TAPACCESS_SHIFTDR 0x60
#define T32_TAPACCESS_SLEEP_MS 0x7c
#define T32_TAPACCESS_SLEEP_US 0x7d
#define T32_TAPACCESS_SLEEP_HALF_CLOCK 0x7e
#define T32_TAPACCESS_SLEEP T32_TAPACCESS_SLEEP_MS /*just for backwards compatibility*/
#define SHIFTRAW_OPTION_INTERNAL_TMS 0x0001 /*do not use the internal options*/
#define SHIFTRAW_OPTION_INTERNAL_TDI 0x0002
#define SHIFTRAW_OPTION_INTERNAL_TDO 0x0004
#define SHIFTRAW_OPTION_INTERNAL_ALL 0x0007
#define SHIFTRAW_OPTION_NONE 0x0000
#define SHIFTRAW_OPTION_LASTTMS_ONE 0x0008
#define SHIFTRAW_OPTION_TMS_ONE 0x0010
#define SHIFTRAW_OPTION_TMS_ZERO 0x0000
#define SHIFTRAW_OPTION_TDI_ONE 0x0040
#define SHIFTRAW_OPTION_TDI_ZERO 0x0000
#define SHIFTRAW_OPTION_TDI_LASTTDO 0x0020
#define T32_TAPACCESS_SPECIAL 0x80
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _NO_PROTO
extern int T32_Config( const char *, const char * );
extern int T32_Init(void);
extern int T32_Exit(void);
extern int T32_Nop(void);
extern int T32_NopFail(void);
extern int T32_Ping(void);
extern int T32_Stop(void);
extern int T32_GetPracticeState(int * );
extern int T32_Attach( int );
extern int T32_GetState( int * );
extern int T32_GetCpuInfo( char **, word *, word *, word * );
extern int T32_GetRam(dword *, dword *, word *);
extern int T32_ResetCPU(void);
extern int T32_WriteMemory( dword, int, byte * , int );
extern int T32_WriteMemoryPipe( dword, int, byte * , int );
extern int T32_WriteMemoryEx( dword, int, int, int, byte * , int );
extern int T32_ReadMemory( dword, int, byte *, int );
extern int T32_ReadMemoryEx( dword, int, int, int, byte * , int );
#define T32_MEMORY_ACCESS_DATA 0x0000
#define T32_MEMORY_ACCESS_PROGRAM 0x0001
#define T32_MEMORY_ACCESS_ARM_CP0 0x0002
#define T32_MEMORY_ACCESS_ARM_ICE 0x0003
#define T32_MEMORY_ACCESS_ARM_ETM 0x0004
#define T32_MEMORY_ACCESS_ARM_CP14 0x0005
#define T32_MEMORY_ACCESS_ARM_CP15 0x0006
#define T32_MEMORY_ACCESS_ARM_ARM 0x0007
#define T32_MEMORY_ACCESS_ARM_THUMB 0x0008
#define T32_MEMORY_ACCESS_ARM_PHYSICAL_ARM 0x0009
#define T32_MEMORY_ACCESS_ARM_PHYSICAL_THUMB 0x000a
#define T32_MEMORY_ACCESS_ARM_ETB 0x000b
#define T32_MEMORY_ACCESS_ARM_PHYSICAL_DATA 0x000c
#define T32_MEMORY_ACCESS_ARM_PHYSICAL_PROGRAM 0x000d
#define T32_MEMORY_ACCESS_ARM_DAP 0x000e
#define T32_MEMORY_ACCESS_ARM_USR 0x000f
#define T32_MEMORY_ATTR_WIDTHMASK 0x000f
#define T32_MEMORY_ATTR_DUALPORT 0x0400
#define T32_MEMORY_ATTR_NOINCREMENT 0x4000
extern int T32_WriteRegister( dword, dword, dword * );
extern int T32_ReadRegister( dword, dword, dword * );
extern int T32_ReadPP( dword * );
extern int T32_WriteBreakpoint( dword, int, int, int );
extern int T32_ReadBreakpoint( dword, int, word * , int );
extern int T32_Step(void);
extern int T32_StepMode(int);
extern int T32_SetMode(int);
extern int T32_Go(void);
extern int T32_Break(void);
extern int T32_Terminate(int retval);
extern int T32_Cmd( char * );
extern int T32_CmdWin( dword, char * );
extern int T32_EvalGet ( dword * );
extern int T32_GetMessage ( char *, word * );
extern int T32_GetTriggerMessage ( char* );
extern int T32_GetSymbol ( char *, dword *, dword * , dword * );
extern int T32_GetSource ( dword, char *, dword * );
extern int T32_GetSelectedSource( char *, dword * );
extern int T32_AnaStatusGet( byte *, long *, long *, long * );
extern int T32_AnaRecordGet( long , byte *, int );
extern int T32_GetTraceState(int tracetype, int * state, long * size, long * min, long * max);
extern int T32_ReadTrace(int tracetype, long record, int nrecords, unsigned long mask, byte * buffer);
typedef void (*T32_NotificationCallback_i_t)(int);
typedef void (*T32_NotificationCallback_iicp_t)(int, int, unsigned char *);
#ifndef SUPPRESS_FUNCTION_TYPE_WARNING
typedef void (*T32_NotificationCallback_t)();
extern int T32_NotifyStateEnable( int event, T32_NotificationCallback_t func);
#endif
extern int T32_CheckStateNotify( unsigned param1);
extern void T32_GetSocketHandle( int *t32soc );
extern T32_TAPACCESS_HANDLE T32_TAPAccessAlloc(void);
extern int T32_TAPAccessExecute(T32_TAPACCESS_HANDLE connection, T32_TAPACCESS_HANDLE connectionhold);
extern int T32_TAPAccessFree(T32_TAPACCESS_HANDLE connection);
extern int T32_TAPAccessSetInfo(int irpre, int irpost, int drpre, int drpost, int tristate, int tapstate, int tcklevel, int slave);
extern int T32_TAPAccessShiftIR(T32_TAPACCESS_HANDLE connection, int numberofbits, byte * poutbits, byte * pinbits);
extern int T32_TAPAccessShiftDR(T32_TAPACCESS_HANDLE connection, int numberofbits, byte * poutbits, byte * pinbits);
extern int T32_TAPAccessShiftRaw(T32_TAPACCESS_HANDLE connection, int numberofbits, byte * pTMSBits, byte * pTDIBits, byte * pTDOBits, int options);
extern int T32_TAPAccessDirect(T32_TAPACCESS_HANDLE connection, int nbytes, byte * poutbytes, byte * pinbytes);
extern int T32_TAPAccessRelease(void);
extern int T32_Fdx_Resolve(char * name);
extern int T32_Fdx_Open(char * name, char * mode);
extern int T32_Fdx_Close(int channel);
extern int T32_Fdx_ReceivePoll(int channel, void * data, int width, int maxsize);
extern int T32_Fdx_Receive(int channel, void * data, int width, int maxsize);
extern int T32_Fdx_SendPoll(int channel, void * data, int width, int size);
extern int T32_Fdx_Send(int channel, void * data, int width, int size);
/*
* New stream structure, to improve performance for PIPE mode.
*/
typedef struct
{
int blen;
unsigned char *ptr;
unsigned char *ptrend;
int channel;
unsigned char buffer[4096];
} T32_Fdx_Stream;
extern T32_Fdx_Stream *T32_Fdx_OpenStream(char *name, char *mode);
extern int T32_Fdx_CloseStream(T32_Fdx_Stream * pstream);
extern int T32_Fdx_ReceiveStreamNext(T32_Fdx_Stream * pstream, unsigned char *target, int width, int size);
#define T32_Fdx_ReceiveStream(__pstream,__target,__width,__len) ( \
(((__pstream)->ptr >= (__pstream)->ptrend) ? \
T32_Fdx_ReceiveStreamNext(__pstream,__target,__width,__len) : \
((__pstream)->blen = ((__pstream)->ptr[0]|((__pstream)->ptr[1]<<8)), memcpy((__target),(__pstream)->ptr+2,(__pstream)->blen), (__pstream)->ptr += 2+(__pstream)->blen, (__pstream)->blen)))
extern int T32_GetChannelSize(void);
extern void T32_GetChannelDefaults(void* line);
extern void T32_SetChannel(void* line);
extern void* T32_GetChannel0(void);
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,12 @@
set(SRCS
main.cc
T32Connector.cc
)
add_executable(fail-client ${SRCS})
target_link_libraries(fail-client -Wl,-whole-archive t32api -Wl,-no-whole-archive fail )
install(TARGETS fail-client RUNTIME DESTINATION bin)
add_executable(t32cli t32cli.cc)
target_link_libraries(t32cli t32api)

View File

@ -0,0 +1,17 @@
#include "T32Connector.hpp"
#include <iostream>
namespace fail {
T32Connector::T32Connector(char *hostname, unsigned port, unsigned packlen) : m_hostname(hostname), m_port(port), m_packetlength(packlen) {
}
T32Connector::~T32Connector() {
// Close Connection to T32 on object deletion. Also works, on simulator.terminate -> global object.
std::cout << "[T32] Closing connection." << std::endl;
}
}

133
debuggers/t32/src/main.cc Normal file
View File

@ -0,0 +1,133 @@
/**
* FailT32 -- Fault Injection on the Lauterbach Trace32 System
*
* 1. Invoke t32 executable with appropriate Lauterbach Skript
* - Script has to load binary
* - and let system run until entry point
* -> Then we have a readily configured system
*
* @author Martin Hoffmann <hoffmann@cs.fau.de>
* @date 15.02.2013
*/
#include <t32.h>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "config/VariantConfig.hpp"
#include "sal/SALInst.hpp"
#include "optionparser.h"
#include "optionparser_ext.hpp"
#include "T32Connector.hpp"
using namespace std;
/* Default T32 error handler */
void err(int ernum){
if(err != 0){
cerr << "Error: " << err << endl;
//exit(-1);
}
}
static fail::T32Connector t32;
//!< Program options
enum optionIndex { UNKNOWN, HELP, RUN, T32HOST, PORT, PACKLEN };
const option::Descriptor usage[] =
{
{UNKNOWN, 0,"" , "" ,Arg::None, "USAGE: fail-client [options]\n\n"
"Options:" },
{HELP, 0,"" , "help",Arg::None, " --help \tPrint usage and exit." },
{RUN, 0,"r", "run",Arg::Required, " --run, -r \tLauterbach script to startup system." },
{T32HOST, 0,"t", "trace32-host",Arg::Required, " --trace32-host, -t <hostname> \tHostname/IP Address of the Trace32 instance. (default: localhost)" },
{PORT, 0,"p", "port",Arg::Required, " --port <NUM>, -p <NUM> \tTCP Port. (default: 20010)" },
{PACKLEN, 0,"l", "packet-length",Arg::Required, " --packet-length, -l <NUM> \tPacket length. (default: 1024)" },
{0,0,0,0,0,0}
};
/* Here we go... */
int main(int argc, char** argv){
// Evaluate arguments
argc-=(argc>0); argv+=(argc>0); // skip program name argv[0] if present
option::Stats stats(usage, argc, argv);
option::Option options[stats.options_max], buffer[stats.buffer_max];
option::Parser parse(usage, argc, argv, options, buffer);
if (parse.error()){
cerr << "Error parsing arguments." << endl;
return 1;
}
if ( options[HELP] ) // || argc == 0 || options[RUN].count() == 0) // to enforce -s
{
int columns = getenv("COLUMNS")? atoi(getenv("COLUMNS")) : 80;
option::printUsage(fwrite, stdout, usage, columns);
return 0;
}
if(options[RUN].count()){
cout << "Script: " << options[RUN].first()->arg << endl;
}
char hostname[] = "localhost";
if(options[T32HOST].count()){
cout << "T32 Hostname: " << options[T32HOST].first()->arg << endl;
}
char port[] = "20010";
if(options[PORT].count()){
cout << "T32 Port: " << options[PORT].first()->arg << endl;
}
char packlen[] = "1024";
if(options[PACKLEN].count()){
cout << "T32 Packet Length: " << options[PACKLEN].first()->arg << endl;
}
// Setup connection to Lauterbach
cout << "Lauterbach remote connection" << endl;
int error;
cout << "[T32] Connecting to " << hostname << ":" << port << " Packlen: " << packlen << endl;
T32_Config("NODE=", hostname);
T32_Config("PACKLEN=", packlen);
T32_Config("PORT=", port);
cout << "[T32] Init." << endl;
err(T32_Init());
cout << "[T32] Attach." << endl;
err(T32_Attach(T32_DEV_ICD));
// Let the SimulatorController do the dirty work.
fail::simulator.startup();
// Here, we come back after any experiment called a resume
// Start execution of the SUT.
// The experiments/traces hopefully set some Breakpoints, we can react on.
// We may also provide a timeout, if a TimerListener was set wanted.
/*
while(1) {
// Start execution (with next timeout, in any)
// Wait for debugger to stop.
// Evaluate state.
// Call appropriate callback of the SimulatorController.
}
*/
cout << "[T32 Backend] After startup" << endl;
return 0;
}

View File

@ -0,0 +1,63 @@
#include <t32.h>
#include <iostream>
#include <string.h>
#include <stdlib.h>
using namespace std;
void err(int ernum){
if(err != 0){
cerr << "Error: " << err << endl;
//exit(-1);
}
}
int eval_command(){
string cmd;
char errmsg[128];
cout << "%> ";
getline(cin, cmd);
if(cmd.compare("bye") == 0) return -1;
int err = T32_Cmd((char*)cmd.c_str());
if(err != 0){
cerr << "Could not execute command: " << err << endl;
word errnum;
T32_GetMessage(errmsg, &errnum);
cerr << errmsg << "Type: " << errnum << endl;
}
return 0;
}
int main(void){
cout << "Lauterbach remote connection" << endl;
cout << "Enter bye to exit." << endl;
int error;
char hostname[] = "localhost";
char packlen[] = "1024";
char port[] = "20010";
cout << "[T32] Connecting to " << hostname << ":" << port << " Packlen: " << packlen << endl;
T32_Config("NODE=", hostname);
T32_Config("PACKLEN=", packlen);
T32_Config("PORT=", port);
cout << "[T32] Init." << endl;
err(T32_Init());
cout << "[T32] Attach." << endl;
err(T32_Attach(T32_DEV_ICD));
while(eval_command() != -1);
cout << "[T32] Exit." << endl;
err(T32_Exit());
cout << "Bye." << endl;
return 0;
}

View File

@ -0,0 +1,29 @@
#ifndef __FIRETIMER_AH__
#define __FIRETIMER_AH__
#include <iostream>
// FIXME: This seems deprecated...?!
aspect fireTimer {
advice "bx_pc_system_c" : slice class {
public:
// TODO: Log-level?
void fireTimer(Bit32u timerNum){
if(timerNum <= numTimers){
if(!timer[timerNum].active){
std::cout << "[FAIL] WARNING: The selected timer is actually NOT active!" << std::endl;
}
currCountdownPeriod = Bit64u(1);
timer[timerNum].timeToFire = Bit64u(currCountdownPeriod) + ticksTotal;
std::cout << "[FAIL] Timer " << timerNum <<" will fire now!" << std::endl;
}else{
std::cout << "[FAIL] There are actually only " << numTimers <<" allocated!" << std::endl;
}
}
};
};
#endif // __FIRETIMER_AH__

View File

@ -0,0 +1,35 @@
#ifndef __JUMP_TO_PREVIOUS_CTX_AH__
#define __JUMP_TO_PREVIOUS_CTX_AH__
#include "config/FailConfig.hpp"
// FIXME: What's the purpose of this file/code? Deprecated?
#if 0
// #if defined(CONFIG_SR_RESTORE) || defined(CONFIG_SR_REBOOT)
#include "bochs.h"
#include "../SALInst.hpp"
aspect jumpToPreviousCtx
{
pointcut end_reset_handler() = "void bx_gui_c::reset_handler(...)";
//|| "int bxmain()";
advice execution (end_reset_handler()) : after ()
{
if (fail::restore_bochs_request || fail::reboot_bochs_request )
{
fail::restore_bochs_request = false;
fail::reboot_bochs_request = false;
fail::simulator.toPreviousCtx();
}
}
};
#endif // CONFIG_SR_RESTORE || CONFIG_SR_REBOOT
#endif // __JUMP_TO_PREVIOUS_CTX_AH__

View File

@ -0,0 +1,102 @@
#ifndef __MEM_ACCESS_BIT_FLIP_AH__
#define __MEM_ACCESS_BIT_FLIP_AH__
#include "config/FailConfig.hpp"
#ifdef CONFIG_FI_MEM_ACCESS_BITFLIP
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "bochs.h"
#include "../../controller/EventList.hpp"
#include "../../controller/Event.hpp"
// FIXME: This is deprecated stuff. Delete this file.
using namespace std;
// FIXME this code doesn't make any sense for the read_virtual_% functions
// (the fault would need to be injected into their *return* value)
aspect MemAccessBitFlip
{
pointcut injection_methods()
= "% ...::bx_cpu_c::read_virtual_%(...)" || // -> access32/64.cc
/*
"% ...::bx_cpu_c::read_RMW_virtual_%(...)" || // -> access32.cc
"% ...::bx_cpu_c::system_read_%(...)" || // -> access.cc
"% ...::bx_cpu_c::v2h_read_byte(...)" || // -> access.cc
*/
"% ...::bx_cpu_c::write_virtual_%(...)"; // -> access32/64.cc
/*
"% ...::bx_cpu_c::write_RMW_virtual_%(...)" || // -> access32.cc
"% ...::bx_cpu_c::write_new_stack_%(...)" || // -> access32/64.cc
"% ...::bx_cpu_c::system_write_%(...)" || // -> access.cc
"% ...::bx_cpu_c::v2h_write_byte(...)"; // -> access.cc
*/
//
// Injects a bitflip each time the guest system requests to write/read
// data to/from RAM at the (hardcoded) addresses defined above:
//
// Event source: "memory write/read access"
//
advice execution (injection_methods()) : before ()
{
for(size_t i = 0; i < fi::evbuf.getEventCount(); i++) // check for active events
{
fi::SimpleBitFlip* pEv = dynamic_cast<fi::SimpleBitFlip*>(fi::evbuf.getEvent(i)); // FIXME: Performance verbessern
if(pEv && *(tjp->arg<1>())/*typed!*/ == pEv->getAddress())
{
cout << " " << tjp->signature() << endl;
// Get a pointer to the data that should be written to RAM
// *before* it is actually written:
Bit32u* pData = (Bit32u*)(tjp->arg(JoinPoint::ARGS-1));
// Flip bit at position pEv->getBitPos():
char* ptr = (char*)pData; // For simplification we're just looking at the
// first byte of the data
ptr[0] = (ptr[0]) ^ (pEv->getMask() << pEv->getBitPos());
cout << " >>> Bit flipped at index " << pEv->getBitPos()
<< " at address 0x" << hex << (*(tjp->arg<1>())) << "!" << endl;
fi::evbuf.fireEvent(pEv);
// Continue... (maybe more events to process)
}
}
}
/*
//
// Shows the mapping of a virtual address (within eCos) to a *host* address:
//
if(g_fEnableInjection) // event fired?
{
g_fEnableInjection = false;
const unsigned SEGMENT_SELECTOR_IDX = 2; // always the code segment (seg-base-addr should be zero)
const bx_address logicalAddr = MEM_ADDR_TO_INJECT; // offset within the segment ("local eCos address")
// Get the linear address:
Bit32u linearAddr = pThis->get_laddr32(SEGMENT_SELECTOR_IDX/ *seg* /, logicalAddr/ *offset* /);
// Map the linear address to the physical address:
bx_phy_address physicalAddr;
bx_bool fValid = pThis->dbg_xlate_linear2phy(linearAddr, (bx_phy_address*)&physicalAddr);
// Determine the *host* address of the physical address:
Bit8u* hostAddr = BX_MEM(0)->getHostMemAddr(pThis, physicalAddr, BX_READ);
// Now, hostAddr contains the "final" address where we are allowed to inject errors:
*(unsigned*)hostAddr = BAD_VALUE; // inject error
if(!fValid)
printf("[Error]: Could not map logical address to host address.\n");
else
printf("[Info]: Error injected at logical addr %p (host addr %p).\n", logicalAddr, hostAddr);
}
*/
};
#endif // CONFIG_FI_MEM_ACCESS_BITFLIP
#endif // __MEM_ACCESS_BIT_FLIP_AH__

View File

@ -0,0 +1,36 @@
#include <iostream>
#include "DataRetrievalExperiment.hpp"
#include "../SAL/SALInst.hpp"
#include "../controller/Event.hpp"
#include "ExperimentDataExample/FaultCoverageExperiment.pb.h"
using namespace std;
using namespace fail;
#define MEMTEST86_BREAKPOINT 0x4EDC
bool DataRetrievalExperiment::run()
{
cout << "[getExperimentDataExperiment] Experiment start." << endl;
// Breakpoint address for Memtest86:
BPSingleEvent mainbp(MEMTEST86_BREAKPOINT);
simulator.addEventAndWait(&mainbp);
cout << "[getExperimentDataExperiment] Breakpoint reached." << endl;
FaultCoverageExperimentData* test = NULL;
cout << "[getExperimentDataExperiment] Getting ExperimentData (FaultCoverageExperiment)..." << endl;
test = simulator.getExperimentData<FaultCoverageExperimentData>();
cout << "[getExperimentDataExperiment] Content of ExperimentData (FaultCoverageExperiment):" << endl;
if (test->has_data_name())
cout << "Name: "<< test->data_name() << endl;
// m_instrptr1 augeben
cout << "m_instrptr1: " << hex << test->m_instrptr1() << endl;
// m_instrptr2 augeben
cout << "m_instrptr2: " << hex << test->m_instrptr2() << endl;
simulator.clearEvents(this);
return true; // experiment successful
}

View File

@ -0,0 +1,14 @@
#ifndef __DATA_RETRIEVAL_EXPERIMENT_HPP__
#define __DATA_RETRIEVAL_EXPERIMENT_HPP__
#include "../controller/ExperimentFlow.hpp"
class DataRetrievalExperiment : public fail::ExperimentFlow
{
public:
DataRetrievalExperiment() { }
bool run();
};
#endif // __DATA_RETRIEVAL_EXPERIMENT_HPP__

View File

@ -0,0 +1,19 @@
## Setup desired protobuf descriptions HERE ##
set(MY_PROTOS
FaultCoverageExperiment.proto
)
set(SRCS
example.cc
)
#### PROTOBUFS ####
find_package(Protobuf REQUIRED)
include_directories(${PROTOBUF_INCLUDE_DIRS})
include_directories(${CMAKE_CURRNET_BINARY_DIR})
PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ${MY_PROTOS} )
## Build library
add_library(fcexperimentmessage ${PROTO_SRCS} ${SRCS} )

View File

@ -0,0 +1,7 @@
message FaultCoverageExperimentData{
optional string data_name = 1;
required int64 m_InstrPtr1 = 2;
required int64 m_InstrPtr2 = 3;
}

View File

@ -0,0 +1,3 @@
#!/bin/bash
cd $(dirname $0)
g++ ../../controller/JobServer.cc ../../controller/ExperimentDataQueue.cc example.cc FaultCoverageExperiment.pb.cc -o ./ExperimentData_example -l protobuf -pthread

View File

@ -0,0 +1,63 @@
#include <iostream>
#include <fstream>
#include "controller/ExperimentData.hpp"
#include "controller/ExperimentDataQueue.hpp"
#include "jobserver/JobServer.hpp"
#include "FaultCoverageExperiment.pb.h"
using namespace std;
int main(int argc, char* argv[])
{
// FIXME: Translation missing.
ExperimentDataQueue exDaQu;
ExperimentData* readFromQueue;
// Daten in Struktur schreiben und in Datei speichern
ofstream fileWrite;
fileWrite.open("test.txt");
FaultCoverageExperimentData faultCovExWrite;
// Namen setzen
faultCovExWrite.set_data_name("Testfall 42");
// Instruktionpointer 1
faultCovExWrite.set_m_instrptr1(0x4711);
// Instruktionpointer 2
faultCovExWrite.set_m_instrptr2(0x1122);
// In ExperimentData verpacken
ExperimentData exDaWrite(&faultCovExWrite);
// In Queue einbinden
exDaQu.addData(&exDaWrite);
// Aus Queue holen
if (exDaQu.size() != 0)
readFromQueue = exDaQu.getData();
// Serialisierung ueber Wrapper-Methode in ExperimentData
readFromQueue->serialize(&fileWrite);
// cout << "Ausgabe: " << out << endl;
fileWrite.close();
//---------------------------------------------------------------
// Daten aus Datei lesen und in Struktur schreiben
ifstream fileRead;
fileRead.open("test.txt");
FaultCoverageExperimentData faultCovExRead;
ExperimentData exDaRead(&faultCovExRead);
exDaRead.unserialize( &fileRead);
// Wenn Name, dann ausgeben
if(faultCovExRead.has_data_name()){
cout << "Name: "<< faultCovExRead.data_name() << endl;
}
// m_instrptr1 augeben
cout << "m_instrptr1: " << faultCovExRead.m_instrptr1() << endl;
// m_instrptr2 augeben
cout << "m_instrptr2: " << faultCovExRead.m_instrptr2() << endl;
fileRead.close();
return 0;
}

View File

@ -0,0 +1,76 @@
#ifndef __JUMP_AND_RUN_EXPERIMENT_HPP__
#define __JUMP_AND_RUN_EXPERIMENT_HPP__
#include <iostream>
#include "../controller/ExperimentFlow.hpp"
#include "../SAL/SALInst.hpp"
#include "../SAL/bochs/BochsRegister.hpp"
#include "config/FailConfig.hpp"
// Check if aspect dependencies are satisfied:
#if !defined(CONFIG_EVENT_CPULOOP) || !defined(CONFIG_EVENT_JUMP)
#error Breakpoint- and jump-events needed! Enable aspects first (see FailConfig.hpp)!
#endif
using namespace std;
using namespace fail;
class JumpAndRunExperiment : public fail::ExperimentFlow {
public:
bool run()
{
/************************************
* Description of experiment flow. *
************************************/
// Wait for function entry adresss:
cout << "[JumpAndRunExperiment] Setting up experiment. Allowing to "
<< "start now." << endl;
BPEvent mainFuncEntry(0x3c1f);
simulator.addEvent(&mainFuncEntry);
if (&mainFuncEntry != simulator.waitAny()) {
cerr << "[JumpAndRunExperiment] Now, we are completely lost! "
<< "It's time to cry! :-(" << endl;
simulator.clearEvents(this);
return false;
}
else
cout << "[JumpAndRunExperiment] Entry of main function reached! "
<< " Let's see who's jumping around here..." << endl;
const unsigned COUNTER = 20000;
unsigned i = 0;
BxFlagsReg* pFlags = dynamic_cast<BxFlagsReg*>(simulator.
getRegisterManager().getSetOfType(RT_ST).snatch());
assert(pFlags != NULL && "FATAL ERROR: NULL ptr not expected!");
JumpEvent ev;
// Catch the next "counter" jumps:
while (++i <= COUNTER) {
ev.setWatchInstructionPointer(ANY_INSTR);
simulator.addEvent(&ev);
if (simulator.waitAny() != &ev) {
cerr << "[JumpAndRunExperiment] Damn! Something went "
<< "terribly wrong! Who added that event?! :-(" << endl;
simulator.clearEvents(this);
return false;
}
else
cout << "[JumpAndRunExperiment] Jump detected. Instruction: "
<< "0x" hex << ev.getTriggerInstructionPointer()
<< " -- FLAGS [CF, ZF, OF, PF, SF] = ["
<< pFlags->getCarryFlag() << ", "
<< pFlags->getZeroFlag() << ", "
<< pFlags->getOverflowFlag() << ", "
<< pFlags->getParityFlag() << ", "
<< pFlags->getSignFlag() << "]." << endl;
}
cout << "[JumpAndRunExperiment] " << dec << counter
<< " jump(s) detected -- enough for today...exiting! :-)"
<< endl;
simulator.clearEvents(this);
return true;
}
};
#endif // __JUMP_AND_RUN_EXPERIMENT_HPP__

View File

@ -0,0 +1,71 @@
#ifndef __MEM_WRITE_EXPERIMENT_HPP__
#define __MEM_WRITE_EXPERIMENT_HPP__
#include <iostream>
#include "../controller/ExperimentFlow.hpp"
#include "../SAL/SALInst.hpp"
#include "config/FailConfig.hpp"
// Check aspect dependencies:
#if !defined(CONFIG_EVENT_CPULOOP) || !defined(CONFIG_EVENT_MEMACCESS) || !defined(CONFIG_SR_SAVE) || !defined(CONFIG_FI_MEM_ACCESS_BITFLIP)
#error Event dependecies not satisfied! Enabled needed aspects in FailConfig.hpp!
#endif
using namespace std;
using namespace fail;
class MemWriteExperiment : public fail::ExperimentFlow {
public:
bool run() // Example experiment (defines "what we wanna do")
{
/************************************
* Description of experiment flow. *
************************************/
// 1. Add some events (set up the experiment):
cout << "[MemWriteExperiment] Setting up experiment. Allowing to"
<< " start now." << endl;
MemWriteEvent mem1(0x000904F0), mem2(0x02ff0916), mem3(0x0050C8E8);
BPEvent breakpt(0x4ae6);
simulator.addEvent(&mem1);
simulator.addEvent(&mem2);
simulator.addEvent(&mem3);
simulator.addEvent(&breakpt);
// 2. Wait for event condition "(id1 && id2) || id3" to become true:
cout << "[MemWriteExperiment] Waiting for condition (1) (\"(id1 &&"
<< " id2) || id3\") to become true..." << endl;
bool f1 = false, f2 = false, f3 = false, f4 = false;
while (!(f1 || f2 || f3 || f4)) {
BPEvent* pev = simulator.waitAny();
cout << "[MemWriteExperiment] Received event id=" << id
<< "." << endl;
if(pev == &mem4)
f4 = true;
if(pev == &mem3)
f3 = true;
if(pev == &mem2)
f2 = true;
if(pev == &mem1)
f1 = true;
}
cout << "[MemWriteExperiment] Condition (1) satisfied! Ready to "
<< "add next event..." << endl;
// 3. Add a new event now:
cout << "[MemWriteExperiment] Adding new Event..."; cout.flush();
simulator.clearEvents(); // remove residual events in the buffer
// (we're just interested in the new event)
simulator.save("./bochs_save_point");
cout << "done!" << endl;
// 4. Continue simulation (waitAny) and inject bitflip:
// ...
simulator.clearEvents(this);
return true;
}
};
#endif // __MEM_WRITE_EXPERIMENT_HPP__

View File

@ -0,0 +1,60 @@
#ifndef __MY_EXPERIMENT_HPP__
#define __MY_EXPERIMENT_HPP__
#include <iostream>
#include "../controller/ExperimentFlow.hpp"
#include "../SAL/SALInst.hpp"
using namespace std;
using namespace fail;
class MyExperiment : public fail::ExperimentFlow {
public:
bool run() // Example experiment (defines "what we wanna do")
{
/************************************
* Description of experiment flow. *
************************************/
// 1. Add some events (set up the experiment):
cout << "[MyExperiment] Setting up experiment. Allowing to start"
<< " now." << endl;
BPEvent ev1(0x8048A00), ev2(0x8048F01), ev3(0x3c1f);
simulator.addEvent(&ev1);
simulator.addEvent(&ev2);
simulator.addEvent(&ev3);
// 2. Wait for event condition "(id1 && id2) || id3" to become true:
BPEvent* pev;
cout << "[MyExperiment] Waiting for condition (1) (\"(id1 && id2)"
<< " || id3\") to become true..." << endl;
bool f1 = false, f2 = false, f3 = false;
while (!((f1 && f2) || f3)) {
pev = simulator.waitAny();
cout << "[MyExperiment] Received event id=" << pev->getId()
<< "." << endl;
if(pev == &ev3)
f3 = true;
if(pev == &ev2)
f2 = true;
if(pev == &ev1)
f1 = true;
}
cout << "[MyExperiment] Condition (1) satisfied! Ready..." << endl;
// Remove residual (for all active experiments!)
// events in the buffer:
simulator.clearEvents();
BPEvent foobar(ANY_ADDR);
foobar.setCounter(400);
cout << "[MyExperiment] Adding breakpoint-event, firing after the"
<< " next 400 instructions..."; cout.flush();
simulator.addEventAndWait(&foobar);
cout << "cought! Exiting now." << endl;
simulator.clearEvents(this);
return true;
}
};
#endif // __MY_EXPERIMENT_HPP__

View File

@ -0,0 +1,60 @@
#ifndef __SINGLE_STEPPING_EXPERIMENT_HPP__
#define __SINGLE_STEPPING_EXPERIMENT_HPP__
#include <iostream>
#include "../controller/ExperimentFlow.hpp"
#include "../SAL/SALInst.hpp"
#include "config/FailConfig.hpp"
#include "../SAL/bochs/BochsRegister.hpp"
// Check if aspect dependency is satisfied:
#ifndef CONFIG_EVENT_CPULOOP
#error Breakpoint-events needed! Enable aspect first (see FailConfig.hpp)!
#endif
using namespace std;
using namespace fail;
#define FUNCTION_ENTRY_ADDRESS 0x3c1f
class SingleSteppingExperiment : public fail::ExperimentFlow {
public:
bool run()
{
/************************************
* Description of experiment flow. *
************************************/
// Wait for function entry adresss:
cout << "[SingleSteppingExperiment] Setting up experiment. Allowing"
<< " to start now." << endl;
BPEvent mainFuncEntry(FUNCTION_ENTRY_ADDRESS);
simulator.addEvent(&mainFuncEntry);
if (&mainFuncEntry != simulator.waitAny()) {
cerr << "[SingleSteppingExperiment] Now, we are completely lost!"
<< " It's time to cry! :-(" << endl;
simulator.clearEvents(this);
return false;
}
cout << "[SingleSteppingExperiment] Entry of main function reached!"
<< " Beginning single-stepping..." << endl;
char action;
while (true) {
BPEvent bp(ANY_ADDR);
simulator.addEvent(&bp);
simulator.waitAny();
cout << "0x" << hex
<< simulator.getRegisterManager().getInstructionPointer()
<< endl;
cout << "Continue (y/n)? ";
cin >> action; cin.sync(); cin.clear();
if (action != 'y')
break;
}
simulator.clearEvents(this);
return true;
}
};
#endif // __SINGLE_STEPPING_EXPERIMENT_HPP__

View File

@ -0,0 +1,16 @@
#ifndef __INSTANTIATE_EXPERIMENT_AH__
#define __INSTANTIATE_EXPERIMENT_AH__
// copy this file to a .ah file and instantiate the experiment(s) you need
#include "hscsimple.hpp"
#include "../SAL/SALInst.hpp"
aspect hscsimple {
hscsimpleExperiment experiment;
advice execution ("void fail::SimulatorController::initExperiments()") : after () {
fail::simulator.addFlow(&experiment);
}
};
#endif // __INSTANTIATE_EXPERIMENT_AH__

View File

@ -0,0 +1,34 @@
## Setup desired protobuf descriptions HERE ##
#set(MY_PROTOS
# TestData.proto
#)
set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake)
#find_package (LibElf REQUIRED)
#find_package (LibDwarf REQUIRED)
#### PROTOBUFS ####
#find_package(Protobuf REQUIRED)
#include_directories(${PROTOBUF_INCLUDE_DIRS})
include_directories(${CMAKE_BINARY_DIR})
include_directories(${CMAKE_CURERNT_BINARY_DIR})
#PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ${MY_PROTOS} )
## Build library
#add_library(testmessages ${PROTO_SRCS})
## Add some tests
#add_executable(testclient client.cc )
#add_executable(testclient testjc.cc )
#add_executable(testserver server.cc)
#target_link_libraries(testclient fail ${PROTOBUF_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} anexperimentmessage protomessages)
#target_link_libraries(testserver fail ${PROTOBUF_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} anexperimentmessage protomessages)
#add_executable(dwarf dwarf.cc)
#target_link_libraries(dwarf ${LIBDWARF_LIBRARIES} ${LIBELF_LIBRARIES} )
#include_directories(${CMAKE_BINARY_DIR}/core/experiments/MHTestCampaign)
#add_executable(mhcampaign mhcampaign.cc)
#target_link_libraries(mhcampaign mhtestcampaign fail ${PROTOBUF_LIBRARY} ${Boost_THREAD_LIBRARY})

View File

@ -0,0 +1,6 @@
message TestData {
optional string foo = 1;
optional int64 input = 2;
optional int64 output = 3;
}

View File

@ -0,0 +1,110 @@
#include <iostream>
#include "jobserver/messagedefs/FailControlMessage.pb.h"
#include "jobserver/SocketComm.hpp"
#include "experiments/AnExperiment/AnExperiment.pb.h"
#include <stdio.h>
using namespace std;
void error(const char *s)
{
perror(s);
exit(0);
}
template <typename Message>
Message *get_job(int sockfd)
{
Message *msg = new Message;
FailControlMessage ctrlmsg;
ctrlmsg.set_command(FailControlMessage_Command_NEED_WORK);
ctrlmsg.set_build_id(42);
cout << "Sending need work msg: " << ctrlmsg.build_id() << ", Command: " << ctrlmsg.command() << endl;
fail::SocketComm::send_msg(sockfd, ctrlmsg);
cout << "sent ctrl message." << endl;
fail::SocketComm::rcv_msg(sockfd, ctrlmsg);
cout << "Received ctrl message: " << ctrlmsg.command() << endl;
switch(ctrlmsg.command()){
case FailControlMessage_Command_DIE: return 0;
case FailControlMessage_Command_WORK_FOLLOWS:
fail::SocketComm::rcv_msg(sockfd, *msg);
return msg;
default:
cerr << "wtf?" << endl;
}
return 0;
}
template <typename Message>
void return_result(int sockfd, Message *msg)
{
FailControlMessage ctrlmsg;
ctrlmsg.set_command(FailControlMessage_Command_RESULT_FOLLOWS);
ctrlmsg.set_build_id(42);
cout << "Sending Result msg: " << ctrlmsg.build_id() << ", Command: " << ctrlmsg.command() << endl;
fail::SocketComm::send_msg(sockfd, ctrlmsg);
fail::SocketComm::send_msg(sockfd, *msg);
delete msg;
}
int main(int argc, char **argv){
int portno;
struct hostent *server;
cout << "JobClient" << endl;
if (argc < 3) {
cerr << "usage: " << argv[0] << " hostname port" << endl;
return 1;
}
portno = atoi(argv[2]);
server = gethostbyname(argv[1]);
if (server == NULL) {
cerr << "cannot resolve host " << argv[1] << endl;
return 1;
}
int i = 1;
while (1) {
int sockfd;
struct sockaddr_in serv_addr;
cout << ">>>>>>>>>Durchgang " << i++ << endl;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
error("socket()");
}
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
memcpy(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd, (sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
error("connect()");
}
MHTestData *msg = get_job<MHTestData>(sockfd);
if(!msg){
break;
close(sockfd);
}
cout << "[Minion] received job input: " << msg->input() << endl;
cout << "[Minion] Calculating " << msg->input() << "^2 = " << msg->input() * msg->input() << endl;
msg->set_output(msg->input() * msg->input());
sleep(1);
cout << "[Minion] returning result: " << msg->output() << endl;
return_result<MHTestData>(sockfd, msg);
close(sockfd);
}
cout << "ByeBye" << endl;
return 0;
}

View File

@ -0,0 +1,163 @@
/* Code sample: Using libdwarf for getting the address of a function
** from DWARF in an ELF executable.
** Not much error-handling or resource-freeing is done here...
**
** Eli Bendersky (http://eli.thegreenplace.net)
** This code is in the public domain.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <dwarf.h>
#include <libdwarf.h>
void die(char* fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
exit(EXIT_FAILURE);
}
/* List a function if it's in the given DIE.
*/
void list_func_in_die(Dwarf_Debug dgb, Dwarf_Die the_die)
{
char* die_name = 0;
const char* tag_name = 0;
Dwarf_Error err;
Dwarf_Half tag;
Dwarf_Attribute* attrs;
Dwarf_Addr lowpc, highpc;
Dwarf_Signed attrcount, i;
int rc = dwarf_diename(the_die, &die_name, &err);
if (rc == DW_DLV_ERROR)
die("Error in dwarf_diename\n");
else if (rc == DW_DLV_NO_ENTRY)
return;
if (dwarf_tag(the_die, &tag, &err) != DW_DLV_OK)
die("Error in dwarf_tag\n");
/* Only interested in subprogram DIEs here */
if (tag != DW_TAG_subprogram)
return;
if (dwarf_get_TAG_name(tag, &tag_name) != DW_DLV_OK)
die("Error in dwarf_get_TAG_name\n");
printf("DW_TAG_subprogram: '%s'\n", die_name);
/* Grab the DIEs attributes for display */
if (dwarf_attrlist(the_die, &attrs, &attrcount, &err) != DW_DLV_OK)
die("Error in dwarf_attlist\n");
for (i = 0; i < attrcount; ++i) {
Dwarf_Half attrcode;
if (dwarf_whatattr(attrs[i], &attrcode, &err) != DW_DLV_OK)
die("Error in dwarf_whatattr\n");
/* We only take some of the attributes for display here.
** More can be picked with appropriate tag constants.
*/
if (attrcode == DW_AT_low_pc)
dwarf_formaddr(attrs[i], &lowpc, 0);
else if (attrcode == DW_AT_high_pc)
dwarf_formaddr(attrs[i], &highpc, 0);
}
printf("low pc : 0x%08llx\n", lowpc);
printf("high pc : 0x%08llx\n", highpc);
}
/* List all the functions from the file represented by the given descriptor.
*/
void list_funcs_in_file(Dwarf_Debug dbg)
{
Dwarf_Unsigned cu_header_length, abbrev_offset, next_cu_header;
Dwarf_Half version_stamp, address_size;
Dwarf_Error err;
Dwarf_Die no_die = 0, cu_die, child_die;
/* Find compilation unit header */
while (dwarf_next_cu_header(
dbg,
&cu_header_length,
&version_stamp,
&abbrev_offset,
&address_size,
&next_cu_header,
&err) != DW_DLV_ERROR) {
/* Expect the CU to have a single sibling - a DIE */
if (dwarf_siblingof(dbg, no_die, &cu_die, &err) == DW_DLV_ERROR)
die("Error getting sibling of CU\n");
/* Expect the CU DIE to have children */
if (dwarf_child(cu_die, &child_die, &err) == DW_DLV_ERROR)
die("Error getting child of CU DIE\n");
/* Now go over all children DIEs */
while (1) {
int rc;
list_func_in_die(dbg, child_die);
rc = dwarf_siblingof(dbg, child_die, &child_die, &err);
if (rc == DW_DLV_ERROR)
die("Error getting sibling of DIE\n");
else if (rc == DW_DLV_NO_ENTRY)
break; /* done */
}
}
}
int main(int argc, char** argv)
{
Dwarf_Debug dbg = 0;
Dwarf_Error err;
const char* progname;
int fd = -1;
if (argc < 2) {
fprintf(stderr, "Expected a program name as argument\n");
return 1;
}
progname = argv[1];
if ((fd = open(progname, O_RDONLY)) < 0) {
perror("open");
return 1;
}
if (dwarf_init(fd, DW_DLC_READ, 0, 0, &dbg, &err) != DW_DLV_OK) {
fprintf(stderr, "Failed DWARF initialization\n");
return 1;
}
list_funcs_in_file(dbg);
if (dwarf_finish(dbg, &err) != DW_DLV_OK) {
fprintf(stderr, "Failed DWARF finalization\n");
return 1;
}
close(fd);
return 0;
}

BIN
deprecated/old-tests/main.elf Executable file

Binary file not shown.

View File

@ -0,0 +1,62 @@
#include "jobserver/JobServer.hpp"
#include <iostream>
#include "experiments/AnExperiment.hpp"
#include <boost/thread.hpp>
fail::JobServer js;
using namespace std;
static const int nums = 30;
void exec_js(){
js.waitForConnections();
cout << "That's it.." << endl;
}
int main(int argc, char**argv){
cout << "Testing Jobserver" << endl;
boost::thread th(exec_js);
AnExperimentData* datas[nums];
for(int i = 1; i <= nums; i++){
datas[i] = new AnExperimentData;
datas[i]->setInput(i);
js.addExperiment(datas[i]);
usleep(100 * 1000); // 100 ms
}
js.setNoMoreExperiments();
// test results.
int f;
int res = 0;
int res2 = 0;
AnExperimentData * exp;
for(int i = 1; i <= nums; i++){
exp = static_cast<AnExperimentData*>( js.m_doneJobs.Dequeue() );
f = exp->getOutput();
// cout << ">>>>>>>>>>>>>>> Output: " << i << "^2 = " << f << endl;
res += f;
res2 += (i*i);
delete exp;
}
if (res == res2) {
cout << "TEST SUCCESSFUL FINISHED! " << "[" << res << "==" << res2 << "]" << endl;
}else{
cout << "TEST FAILED!" << " [" << res << "!=" << res2 << "]" << endl;
}
cout << "thats all, waiting for server thread. " << endl;
js.done();
th.join();
return 0;
}

View File

@ -0,0 +1,42 @@
#include <iostream>
#include "jobserver/JobClient.hpp"
#include "experiments/AnExperiment.hpp"
using namespace std;
using namespace fail;
int main(int argc, char** argv){
int portno;
JobClient* jc;
cout << "JobClient" << endl;
if(argc == 1){
jc = new JobClient();
}else if(argc == 3){
portno = atoi(argv[2]);
jc = new JobClient(argv[1], portno);
}else{
cerr << "usage: " << argv[0] << " hostname port" << endl;
return 1;
}
AnExperimentData exp;
while(1){
if(jc->getExperimentData(exp)){
/// Do some work.
cout << "Got data: " << exp.getInput() << endl;
int result = exp.getInput() * exp.getInput();
usleep(500 * 1000); // 500 ms
/// Send back.
exp.setOutput(result);
jc->sendResult(exp);
}else{
cout << "No (more) data for me :(" << endl;
break;
}
}
delete jc;
}

View File

@ -0,0 +1,24 @@
#include "ExperimentDataQueue.hpp"
#include <assert.h>
// FIXME: This is deprecated stuff. Remove it.
namespace fi
{
void ExperimentDataQueue::addData(ExperimentData* exp)
{
assert(exp != 0);
m_queue.push_front(exp);
}
ExperimentData* ExperimentDataQueue::getData()
{
ExperimentData* ret = m_queue.back();
m_queue.pop_back();
return ret;
}
}

View File

@ -0,0 +1,55 @@
/**
* \brief A queue for experiment data.
*
*
* \author Martin Hoffmann, Richard Hellwig
*
*/
// FIXME: This is deprecated stuff. Remove it.
#ifndef __EXPERIMENT_DATA_QUEUE_H__
#define __EXPERIMENT_DATA_QUEUE_H__
#include <deque>
#include "ExperimentData.hpp"
namespace fi{
/**
* \class ExperimentDataQueue
* Class which manage ExperimentData in a queue.
*/
class ExperimentDataQueue
{
protected:
std::deque<ExperimentData*> m_queue;
public:
ExperimentDataQueue() {}
~ExperimentDataQueue() {}
/**
* Adds ExperimentData to the queue.
* @param exp ExperimentData that is to be added to the queue.
*/
void addData(ExperimentData* exp);
/**
* Returns an item from the queue
* @return the next element of the queue
*/
ExperimentData* getData();
/**
* Returns the number of elements in the queue
* @return the size of teh queue
*/
size_t size() const { return m_queue.size(); };
};
};
#endif //__EXPERIMENT_DATA_QUEUE_H__

View File

@ -0,0 +1,16 @@
// Author: Adrian Böckenkamp
// Date: 15.06.2011
// FIXME: This is deprecated stuff. Delete it.
#include "Signal.hpp"
namespace fi
{
std::auto_ptr<Signal> Signal::m_This;
Mutex Signal::m_InstanceMutex;
} // end-of-namespace: fi

View File

@ -0,0 +1,135 @@
#ifndef __SIGNAL_HPP__
#define __SIGNAL_HPP__
// FIXME: This is deprecated stuff. Delete it.
#include <cassert>
#include <memory>
#include <iostream>
#ifndef __puma
#include <boost/thread.hpp>
#include <boost/interprocess/sync/named_semaphore.hpp>
#include <boost/thread/condition.hpp>
#include <boost/thread/mutex.hpp>
#endif
namespace fi
{
#ifndef __puma
typedef boost::mutex Mutex; // lock/unlock
typedef boost::mutex::scoped_lock ScopeLock; // use RAII with lock/unlock mechanism
typedef boost::condition_variable ConditionVariable; // wait/notify_one
#else
typedef int Mutex;
typedef int ScopeLock;
typedef int ConditionVariable;
#endif
// Simulate a "private" semaphore using boost-mechanisms:
class Semaphore
{
private:
Mutex m_Mutex;
ConditionVariable m_CondVar;
unsigned long m_Value;
public:
// Create a semaphore object based on a mutex and a condition variable
// and initialize it to value "init".
Semaphore(unsigned long init = 0) : m_Value(init) { }
void post()
{
ScopeLock lock(m_Mutex);
++m_Value; // increase semaphore value:
#ifndef __puma
m_CondVar.notify_one(); // wake up other thread, currently waiting on condition var.
#endif
}
void wait()
{
ScopeLock lock(m_Mutex);
#ifndef __puma
while(!m_Value) // "wait-if-zero"
m_CondVar.wait(lock);
#endif
--m_Value; // decrease semaphore value
}
};
class Signal
{
private:
static Mutex m_InstanceMutex; // used to sync calls to getInst()
static std::auto_ptr<Signal> m_This; // the one and only instance
Semaphore m_semBochs;
Semaphore m_semContr;
Semaphore m_semSimCtrl;
bool m_Locked; // prevent misuse of thread-sync
// Singleton class (forbid creation, copying and assignment):
Signal()
: m_semBochs(0), m_semContr(0),
m_semSimCtrl(0), m_Locked(false) { }
Signal(Signal const& s)
: m_semBochs(), m_semContr(),
m_semSimCtrl(), m_Locked(false) { } // never called.
Signal& operator=(Signal const&) { return *this; } // dito.
~Signal() { }
friend class std::auto_ptr<Signal>;
public:
static Signal& getInst()
{
ScopeLock lock(m_InstanceMutex); // lock/unlock handled by RAII principle
if(!m_This.get())
m_This.reset(new Signal());
return (*m_This);
}
// Called from Experiment-Controller class ("beyond Bochs"):
void lockExperiment()
{
assert(!m_Locked &&
"[Signal::lockExperiment]: lockExperiment called twice without calling unlockExperiment() in between.");
m_Locked = true;
m_semContr.wait(); // suspend experiment process
}
// Called from Experiment-Controller class ("beyond Bochs"):
void unlockExperiment()
{
assert(m_Locked &&
"[Signal::unlockExperiment]: unlockExperiment called twice without calling lockExperiment() in between.");
m_Locked = false;
m_semBochs.post(); // resume experiment (continue bochs simulation)
}
// Called from Advice-Code ("within Bochs") to trigger event occurrence:
void signalEvent()
{
m_semContr.post(); // Signal event (to Experiment-Controller)
m_semBochs.wait(); // Wait upon handling to finish
}
// Called from Experiment-Controller to allow simulation start:
void startSimulation()
{
m_semSimCtrl.post();
}
// Called from Bochs, directly after thread creation for Experiment-Controller:
// (This ensures that Bochs waits until the experiment has been set up in the
// Experiment-Controller.)
void waitForStartup()
{
m_semSimCtrl.wait();
}
};
} // end-of-namespace: fi
#endif /* __SIGNAL_HPP__ */

View File

@ -0,0 +1,25 @@
#include "SynchronizedExperimentDataQueue.hpp"
// FIXME: This file is not used. Delete it either.
namespace fi {
void SynchronizedExperimentDataQueue::addData(ExperimentData* exp){
//
m_sema_full.wait();
ExperimentDataQueue::addData(exp);
m_sema_empty.post();
//
}
ExperimentData* SynchronizedExperimentDataQueue::getData(){
//
m_sema_empty.wait();
return ExperimentDataQueue::getData();
m_sema_full.post();
//
}
};

View File

@ -0,0 +1,57 @@
/**
* \brief A queue for experiment data.
*
*
* \author Martin Hoffmann, Richard Hellwig
*
*/
// FIXME: This file is not used. Delete it.
#ifndef __SYNC_EXPERIMENT_DATA_QUEUE_H__
#define __SYNC_EXPERIMENT_DATA_QUEUE_H__
#include "ExperimentDataQueue.hpp"
#include "Signal.hpp"
namespace fi{
/**
* \class SynchronizedExperimentDataQueue
* Class which manage ExperimentData in a queue.
* Thread safe using semphores.
*/
class SynchronizedExperimentDataQueue : public ExperimentDataQueue
{
private:
/// There are maxSize elements in at a time
/// Or do we allow a really possibly huge queue?
Semaphore m_sema_full;
Semaphore m_sema_empty;
public:
SynchronizedExperimentDataQueue(int maxSize = 1024) : m_sema_full(maxSize), m_sema_empty(0) {}
~SynchronizedExperimentDataQueue() {}
/**
* Adds ExperimentData to the queue.
* @param exp ExperimentData that is to be added to the queue.
*/
void addData(ExperimentData* exp);
/**
* Returns an item from the queue
* @return the next element of the queue
*/
ExperimentData* getData();
/**
* Returns the number of elements in the queue
* @return the size of the queue
*/
size_t size() const { return m_queue.size(); };
};
};
#endif //__EXPERIMENT_DATA_QUEUE_H__

1
doc/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
!Makefile

4
doc/Makefile Normal file
View File

@ -0,0 +1,4 @@
all: class-diagram.png collaboration.png communication-sequence-normal.png
%.png: %.dia
dia -e $@ $<
-optipng $@ -out tmp$@ && mv tmp$@ $@

21203
doc/class-diagram.dia Normal file

File diff suppressed because it is too large Load Diff

BIN
doc/class-diagram.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 879 KiB

87
doc/coding-style.txt Normal file
View File

@ -0,0 +1,87 @@
Coding Style for Fail*
======================
You may violate/break any of the following rules if you have a good reason to
do so, e.g., if readability is notably enhanced.
For Python code, try to stick to <http://www.python.org/dev/peps/pep-0008>.
Especially use 4 spaces per indentation level, and don't mix tabs and spaces
for indentation.
The following style rules apply to C/C++/AspectC++ code:
- Language (comments, SVN commit messages, "temporary" stuff): English
(without exception)
- Naming conventions:
* Source files: .cc (Source), .hpp (Header), .ah (Aspect Header), MixedCase
* Namespaces: lowercase
* Classes, (global) functions: MixedCase, starting with uppercase letter
* Public members: MixedCase, starting with lowercase letter
* Private & protected members: starting with "m_"
* Global Variables: starting with "g_"
* Preprocessor macros: uppercase
- Include guard for MyFooBar.hpp: __MY_FOO_BAR_HPP__
* Constant variables: uppercase
* (no convention for local variables)
* typedefs: lowercase, underscores (good_name_t)
* abbreviations (even in identifiers): uppercase
- Comments:
* Doxygen comments:
- In detail for all public members (parameters, return value, side
effects, ...)
- (At least) Briefly for private/protected members
- At the top of each (aspect) header file: @brief
- For each complex data type (and its elements)
* Explain *nontrivial* program logic not only by describing the "what's
happening here", but also the "why are we doing it this way".
* Use "normal" C/C++ comments within functions (//, /**/).
* No author names, creation dates, change logs etc. in source files.
That's why we're using a VCS.
- Formatting:
* Indentation: 1 tab (tabstop at 4 spaces)
- may be relaxed / mixed with spaces for better readability of
multi-line statements, e.g.:
<TAB>cout << "The counter value is: "
<TAB> << value;
<TAB>if (first_looong_condition &&
<TAB> second_looong_condition) {
<TAB><TAB>...
* Preprocessor directives start in column 1.
* Max. line length: 100 characters.
* "public"/"private"/"protected" has the same identation as its surrounding
"class Foo" statement (we'd waste one indentation level for every class
definition otherwise):
class Foo {
public:
<TAB>void doSomething();
};
Similarly (and for the same reason) for namespaces and switch/case
statements:
switch (foo) {
case 1:
<TAB>...
}
* Compound statements (blocks): <Space>+'{' in the same line as its
governing control structure (if, while, for, switch, try) or
namespace/class definition:
if (something) {
<TAB>...
}
* Method/Function definitions are an exception to this ('{' in a new line):
Definition: | Declaration:
void myFunction(int i) | void myFunction(int i);
{ |
<TAB>... |
} |
* Control structure tokens ("if", "try", for, ...) are followed by a
single space for better disambiguation from function definitions:
if (...) {
<TAB>...
} else if (...) {
<TAB>...
} else {
<TAB>...
}

BIN
doc/collaboration.dia Normal file

Binary file not shown.

BIN
doc/collaboration.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

52
doc/fail-structure.txt Normal file
View File

@ -0,0 +1,52 @@
=========================================================================================
Directory structure:
=========================================================================================
The folders are nested as follow:
**********************************************************************
fail: Fail* parent directory, containing all source & configuration files (${FAIL_DIR})
|-cmake: CMake-related configuration files (e.g. compiler-flags, dependencies, ...)
|-doc: Fail*-Framework documentation (e.g., diagrams, howtos, ...)
|-deprecated: temporal and old (source) files, which will probably be deleted
|-scripts: python/shell scripts for Fail*-compilation and experiment distribution
|-simulators: parent directory of simulators supported by Fail* (may still be WIP)
|-bochs: source files of the (modified) Bochs x86 simulator backend
|-ovp: source files of the Open Virtual Platform simulator backend
|-src: C/C++/AspectC++ source files related to Fail*, experiments and plugins
|-core: core source files forming the Fail* framework
|-util: utility classes and miscellaneous helper functions
|-config: CMake configuration files, defining the Fail* components and variant
|-sal: source file forming the Simulator Abstraction Layer (backend-interface)
|-bochs: backend source files to the Bochs simulator
|-ovp: backend source files to the Open Virtual Platform simulator
|-cpn: campaign- (and therefore server-)related source files
|-efw: experiment-framework- (and therefore client-)related source files
|-comm: communication related source files (these files are used by cpn and efw)
|-msg: Google protobuf message definitions used for communication purposes
|-experiments: experiment code files (within a new dir) need to be located here
|-plugins: plugin code files (within a new dir) need to be located here
|-[build]: recommended location of your build-tree, generated files will be placed here
Some additional useful notes:
**********************************************************************
- The source files have been documented using Doxygen comments. The Doxygen
documentation can be generated by typing "make doc" in your build-tree. The
resulting HTML and LaTeX files will be located in "${BUILD_DIR}/src/core/doc/".
- CMake supports an "in-source" build-tree. We recommend you not to use this
"feature", because it leads to a cluttered directory structure (mixing original
source files and generated code/config files). (Since it is still possible, however,
the "build" directory is optional.)
- CMake invokes the compiler with the following include directories:
* ${FAIL_DIR}/src/core
* ${BUILD_DIR}/src/core
When compiling the Bochs variant the following directory is added, too:
* ${FAIL_DIR}/simulators/bochs
These definitions simplify and shorten the include paths.
=========================================================================================
Namespace structure:
=========================================================================================
All classes, functions, constants, etc. are encapsulated in the namespace "fail".
Experiments and plugins (see corresponding directories above) are located in the
global scope (not in the "fail"-namespace).

244
doc/how-to-build.txt Normal file
View File

@ -0,0 +1,244 @@
=========================================================================================
Additional libraries/packages/tools needed for Fail*:
=========================================================================================
Required for Fail*:
**********************************************************************
- libprotobuf-dev
- libpcl1-dev
- libboost-thread-dev
- protobuf-compiler
- cmake
- cmake-curses-gui
- binutils-dev
- AspectC++ (ag++, ac++): AspectC++ 1.1 or newer is known to work and can be
obtained from http://www.aspectc.org; nightlies can be downloaded from
http://akut.aspectc.org
Required for the Bochs simulator backend:
**********************************************************************
- libpthread
- Probably more, depending on, e.g., the GUI you configure (X11 ->
libsvga1-dev, libxrandr-dev)
Required for the gem5 simulator backend:
**********************************************************************
- SCons
- SWIG
- zlib
- m4
- python-dev
- optional: libgoogle-perftools-dev
For distribution/parallelization:
**********************************************************************
- rsync
- tmux
32-bit FailBochs on x86_64 Linux machines:
**********************************************************************
- Create a "bochslibs" directory and fill it with all necessary libraries from
your build machine:
$ mkdir bochslibs
$ cp -v $(ldd fail-client|awk '{print $3}'|egrep -v '\(|lib(pthread|selinux|c.so.)|^$') bochslibs/
- Copy this directory to ~/bochslibs on all machines lacking these libraries
(this may also be the case for i386 machines you cannot install library
packages on yourself). client.sh will add ~/bochslibs to LD_LIBRARY_PATH if
it exists.
=========================================================================================
Compiling, building and modifying: Simulators and Fail*
=========================================================================================
Building Fail*:
**********************************************************************
For the first time:
------------------------------------------------------------
1. Enter the "fail/" directory (${FAIL_DIR}, see also "fail-structure.txt"):
$ cd fail/
2. (Optional) Cleanup previous CMake remnants:
$ find -name CMakeCache.txt | xargs rm
3. Create out of source build directory (${BUILD_DIR}, see also "fail-structure.txt"):
$ mkdir build
Note that currently this build directory must be located somewhere below
the fail/ directory, as generated .ah files in there will not be included
in the compile process otherwise.
4. Enter out-of-source build directory. All generated files end up there.
$ cd build
5. Generate CMake environment.
$ cmake ..
6. Setup build configuration by opening the CMake configuration tool
$ ccmake .
Select "BUILD_BOCHS" or "BUILD_GEM5". Select an experiment to enable by
naming its "experiments/" subdirectory under "EXPERIMENTS_ACTIVATED".
Configure Fail* features you need for this experiment by enabling
"CONFIG_*" options. Press 'c', 'g' to regenerate the build system.
(Alternatively use
$ cmake-gui .
for a Qt GUI.) To enable a Debug build, choose "Debug" as the build type,
otherwise choose "Release".
If building FailBochs, optionally set up the bochs configure flags
for your need.
After changes to Fail* code:
------------------------------------------------------------
Compile (in ${BUILD_DIR}, optionally "add -jN" for parallel building):
$ make
CMake will build all Fail* libraries and link them with the simulator backend
library to a binary called "fail-client". You may use the shell script
$ ${FAIL_DIR}/scripts/rebuild-bochs.sh [-]
to speed up repetitive tasks regarding Fail/Bochs builds. This script contains
a concise documentation on itself.
Add new Fail* sources to build chain:
------------------------------------------------------------
To add new source files to the build, see CMakeLists.txt in the subdirectory of the
corresponding component in "${FAIL_DIR}/src/core/", and probably consultate the
CMake docs: http://cmake.org/cmake/help/documentation.html
Add new experiment/plugin/campaign:
------------------------------------------------------------
Look at "${FAIL_DIR}/src/experiments/coolchecksum/" as a template. After creating a
new subdirectory in "experiments/", activate it in the CMake configuration step (see
above).
Generating the Doxygen documentation for Fail*:
**********************************************************************
To generate the Doxygen documentation, type:
$ make doc
The documentation files (HTML and LaTeX) are located in "${BUILD_DIR}/src/core/doc/".
To open the HTML documentation, type:
$ firefox src/core/doc/html/index.html
(You may want to replace "firefox" with your favourite browser.) The LaTeX docs need
to be compiled previously:
$ cd src/core/doc/latex; make
FailBochs: Bochs configuration features
**********************************************************************
The autotools-based bochs is configured within the Fail* build run.
The configuration flags can be set within the ccmake configuration (ccmake ${FAIL_DIR}/build)
- Sufficient:
--enable-cpu-level=6;--enable-ne2000;--enable-trace-cache;--enable-gdb-stub --disable-docbook
- More simulator features (FailBochs default configuration):
--enable-a20-pin;--enable-x86-64;--enable-cpu-level=6;--enable-ne2000;--enable-acpi;--enable-pci;--enable-usb;--enable-trace-cache;--enable-fast-function-calls;--enable-host-specific-asms;--enable-disasm;--enable-readline;--enable-clgd54xx;--enable-fpu;--enable-vmx=2;--enable-monitor-mwait;--enable-cdrom;--enable-sb16=linux;--enable-gdb-stub --disable-docbook --with-all-libs
Instead of --with-all-libs, you could use --with-nogui for "headless" experiments,
additionally removing lots of library dependencies (thus reducing startup overhead).
--with-x11 enables only the "x" (X11), --with-wx only the "wx" (wxWidgets) GUI.
Note that "wx" does not play well together with Fail*'s "restore" feature (FailBochs
will fall back to "x" if available, or die trying.)
Once you know everything works as it should, you may want to add the
following flags before running larger campaigns:
--disable-logging --disable-assert-checks
Make sure --enable-repeat-speedups (--enable-all-optimizations implicitly
enables this) is not enabled; you will otherwise encounter funny effects
when tracing REP-prefixed instructions.
FIXME: Remove more redundant flags/libraries
After changes to Bochs code:
------------------------------------------------------------
- Just re-run "make" in ${BUILD_DIR}, or call "scripts/rebuild-bochs.sh -".
The latter automatically runs "make install" after rebuilding fail-client
(and probably the experiment's campaign server).
- Cleaning up (forcing a complete rebuild of libfailbochs.a next time):
$ make bochsallclean
This is especially necessary if you changed a Bochs-affecting aspect header
(.ah), as the build system does not know about Bochs sources depending on
certain aspects.
Debug build:
------------------------------------------------------------
Configure Bochs to use debugging-related compiler flags (expects to be in ${BUILD_DIR}):
$ cd ../simulator/bochs
$ CFLAGS="-g -O0" CXXFLAGS="-g -O0" ./configure --prefix=... ... (see above)
You might additionally want to configure the rest of Fail* into debug mode by
setting CMAKE_BUILD_TYPE to "Debug" (ccmake, see above).
Profiling-based optimization build:
------------------------------------------------------------
FIXME: ag++ needs to be run with --keep_woven
Configure Bochs to use compiler flags to enable profiling:
$ cd ../simulator/bochs
$ CFLAGS="-fprofile-generate" CXXFLAGS="-fprofile-generate" LDFLAGS="-fprofile-generate" ./configure --prefix=... ... (see above)
Build Bochs normally, and run it. Configure Bochs to use compiler flags to enable
optimizations based on profiling results:
$ CFLAGS="-fprofile-use -Wcoverage-mismatch" CXXFLAGS="-fprofile-use -Wcoverage-mismatch" LDFLAGS="-fprofile-use" ./configure --prefix=... ... (see above)
Benchmarking:
------------------------------------------------------------
Simple instructions/second measurement:
- Configure Bochs with --enable-show-ips (see above)
- Modify the bochsrc: print_timestamps: enabled=1
Comparison IPS numbers are shown in the default "bochsrc". Headless bochsrc configuration,
all aspects disabled, guest system executes endless loop, host CPU Xeon X5470 (3.33GHz):
IPS: 66124283 average = 66964789
Building OVP for ARM Cortex-M3:
**********************************************************************
For the first time:
------------------------------------------------------------
1. Get a license from http://www.ovpworld.org/
2. Download the following files:
- Downloads -> Main OVP Download including OVPsim Simulator
- Downloads -> ARM -> ARM OVP Cortex-M Profile Model
-> Self contained ARM Cortex-M examples
-> ARM GNU GCC and GDB tools
3. Install OVP by running the self-extracting archives.
4. Get Sourcery CodeBench Lite Edition from
http://www.mentor.com/embedded-software/codesourcery
(ARM processors -> EABI release)
5. Install the self-extracting archive, or use the installation in
/fs/proj/compiler/codesourcery-arm-eabi (DO, ios/kos)
TODO: Source setup.sh, setupImperas ...
TODO: Fix Hard-coded paths
Building gem5:
**********************************************************************
Fail* configuration:
------------------------------------------------------------
- BUILD_GEM5 ON
- BUILD_ARM ON
- all configuration options specific for other simulators OFF
- Release or Debug choice must match gem5 in the following
For the first time:
------------------------------------------------------------
1. Change to the gem5 simulator directory (expects to be in ${FAIL_DIR}):
$ cd simulators/gem5
2. Build gem5 using the commands below until it fails finding the fail-libs
3. Build fail
4. Select an experiment (see below)
5. Build gem5 again. THe fail-libs should be found now.
Optimized build:
------------------------------------------------------------
$ cd ../simulator/gem5
$ scons EXTRAS=../../src/core/sal/gem5 build/ARM/gem5.fast
(add -jN for a parallel build)
Debug build:
------------------------------------------------------------
$ cd ../simulator/gem5
$ scons EXTRAS=../../src/core/sal/gem5 build/ARM/gem5.debug
(add -jN for a parallel build)
Selecting an experiment:
------------------------------------------------------------
1. Edit ../src/core/sal/gem5/SConscript
In line starting with (gStaticLibs = ...) change -lfail-arch-test to
-lfail-EXPERIMENTNAME

187
doc/how-to-use.txt Normal file
View File

@ -0,0 +1,187 @@
=========================================================================================
Steps to run a boot image in Fail* using the Bochs simulator backend:
=========================================================================================
Follow the Bochs documentation, and start your own "bochsrc" configuration file
based on the "${PREFIX}/share/doc/bochs/bochsrc-sample.txt" template (or
"/usr/share/doc/bochs/examples/bochsrc.gz" on Debian systems with Bochs installed).
1. Add your floppy/cdrom/hdd image in the floppya/ata0-master/ata0-slave
sections; configure the boot: section appropriately.
2. Comment out com1 and parport1.
3. The following Bochs configuration settings (managed in the "bochsrc" file) might
be helpful, depending on your needs:
- For "headless" experiments:
config_interface: textconfig
display_library: nogui
- For an X11 GUI:
config_interface: textconfig
display_library: x
- For a wxWidgets GUI (does not play well with Fail*'s "restore" feature):
config_interface: wx
display_library: wx
- Reduce the guest system's RAM to a minimum to reduce Fail*'s memory footprint
and save/restore overhead, e.g.:
memory: guest=16, host=16
- If you want to redirect FailBochs's output to a file using the shell's
redirection operator '>', make sure "/dev/stdout" is not used as a target
file for logging. (The Debian "bochsrc" template unfortunately does this
in two places. It suffices to comment out these entries.)
- To make Fail* terminate if something unexpected happens in a larger
campaign, be sure it doesn't "ask" in these cases, e.g.:
panic: action=fatal
error: action=fatal
info: action=ignore
debug: action=ignore
pass: action=ignore
- If you need a quick-and-dirty way to pass data from the guest system to the
outside world, and you don't want to write an experiment utilizing
GuestEvents, you can use the "port e9 hack" that prints all outbs to port
0xe9 to the console:
port_e9_hack: enabled=1
- Determinism: (Fail)Bochs is deterministic regarding timer interrupts,
i.e., two experiment runs after calling simulator.restore() will count
the same number of instructions between two interrupts. Though, you
need to be careful when running (Fail)Bochs with a GUI enabled: Typing
fail-client -q<return>
on the command line may lead to the GUI window receiving a "return key
released" event, resulting in a keyboard interrupt for the guest system.
This can be avoided by starting Bochs with "sleep 1; fail-client -q", by
suppressing keyboard input (CONFIG_DISABLE_KEYB_INTERRUPTS setting in
the CMake configuration), or disabling the GUI (see "headless
experiments" above).
=========================================================================================
Example experiments and code snippets
=========================================================================================
Experiment "hsc-simple":
**********************************************************************
A simple standalone experiment (without a separate campaign). To compile this
experiment, the following steps are required:
1. Add "hsc-simple" to ccmake's EXPERIMENTS_ACTIVATED.
2. Enable CONFIG_EVENT_BREAKPOINTS, CONFIG_SR_RESTORE and CONFIG_SR_SAVE.
3. Build Fail* and Bochs, see "how-to-build.txt" for details.
4. Enter experiment_targets/hscsimple/, bunzip2 -k *.bz2
5. Start the Bochs simulator by typing
$ fail-client -q
After successfully booting the eCos/hello world example, the console shows
"[HSC] breakpoint reached, saving", and a hello.state/ subdirectory appears.
You probably need to adjust the bochsrc's paths to romimage/vgaromimage.
These by default point to the locations installed by the Debian packages
"bochsbios" and "vgabios"; for example, you alternatively may use the
BIOSes supplied in "${FAIL_DIR}/simulators/bochs/bios/".
6. Compile the experiment's second step: edit
fail/src/experiments/hsc-simple/experiment.cc, and change the first "#if 1"
into "#if 0". Make an incremental build, e.g., by running
"${FAIL_DIR}/scripts/rebuild-bochs.sh -" from your ${BUILD_DIR}.
7. Back to ../experiment_targets/hscsimple/ (assuming, your are in ${FAIL_DIR}),
again run
$ fail-client -q
After restoring the state, the hello world program's calculation should
yield a different result.
Experiment "coolchecksum":
**********************************************************************
An example for separate campaign/experiment implementations. To compile this
experiment, the following steps are required:
1. Run step #1 (and if you're curious how COOL_ECC_NUMINSTR in
experimentInfo.hpp was figured out, then step #2) of the experiment
(analogous to what needed to be done in case of the "hsc-simple" experiment,
see above). The experiment's target guest system can be found under
../experiment_targets/coolchecksum/.
(If you want to enable COOL_FAULTSPACE_PRUNING, step #2 is mandatory because
it generates the instruction/memory access trace needed for pruning.)
2. Build the campaign server (if it wasn't already built automatically):
$ make coolchecksum-server
3. Run the campaign server: bin/coolchecksum-server
4. In another terminal, run step #3 of the experiment ("fail-client -q").
Step #3 of the experiment currently runs 2000 experiment iterations and then
terminates, because Bochs has some memory leak issues. You need to re-run
fail-client for the next 2k experiments.
The experiments can be significantly sped up by
a) parallelization (run more FailBochs clients and
b) a headless (and more optimized) Fail* configuration (see above).
Experiment "MHTestCampaign":
**********************************************************************
An example for separate campaign/experiment implementations.
1. Execute campaign (job server): ${BUILD_DIR}/bin/MHTestCampaign-server
2. Run the FailBochs instance, in properly defined environment:
$ fail-client -q
=========================================================================================
Parallelization
=========================================================================================
Fail* is designed to allow parallelization of experiment execution allowing to reduce
the time needed to execute the experiments on a (larger) set of experiment data (aka
input parameters for the experiment execution, e.g. instruction pointer, registers, bit
numbers, ...). We call such "experiment data" the parameter sets. The so called "campaign"
is responsible for managing the parameter sets (i.e., the data to be used by the experiment
flows), inquired by the clients. As a consequence, the campaign is running on the server-
side and the experiment flows are running on the (distributed) clients.
First of all, the Fail* instances (and other required files, e.g. saved state) are
distributed to the clients. In the second step the campaign(-server) is started, preparing
its parameter sets in order to be able to answer the requests from the clients. (Once
there are available parameter sets, the clients can request them.) In the final step,
the distributed Fail* clients have to be started. As soon as this setup is finished,
the clients request new parameter sets, execute their experiment code and return their
results to the server (aka campaign) in an iterative way, until all paremeter sets have
been processed successfully. If all (new) parameter sets have been distributed, the
campaign starts to re-send unfinished parameter sets to requesting clients in order to
speed up the overall campaign execution. Additionally, this ensures that all parameter
sets will produce a corresponding result set. (If, for example, a client terminates
abnormally, no result is sent back. This scenario is dealt with by this mechanism, too.)
Shell scripts supporting experiment distribution:
**********************************************************************
These can be found in ${FAIL_DIR}/scripts/ (for now have a look at the script files
themselves, they contain some documentation):
- fail-env.sh: Environment variables for distribution/parallelization host
lists etc.; don't modify in-place but edit your own copy!
- distribute-experiment.sh: Distribute necessary FailBochs ingredients to
experiment hosts.
- runcampaign.sh: Locally run a campaign server, and a large amount of
clients on the experiment hosts.
- multiple-clients.sh: Is run on an experiment host by runcampaign.sh,
starts several instances of client.sh in a tmux session.
- client.sh: (Repeatedly) Runs a single fail-client instance.
Some useful things to note:
**********************************************************************
- Using the distribute-experiment.sh script causes the local fail-client binary to
be copied to the hosts. If the binary is not present in the current directory
the default fail-client binary (-> $ which fail-client) will be used. If you
have modified some of your experiment code (i.e., your fail-client binary will
change), don't forget to delete the local fail-client binary in order to
distribute the *new* binary.
- The runcampaign.sh script prints some status information about the clients
recently started. In addition, there will be a few error messages concerning
ssh, tmux and so on. They can be ignored for now.
- The runcampaign.sh script starts the coolchecksum-server. Note that the server
instance will terminate immediately (without notice), if there is still an
existing coolcampaign.csv file.
- In order to make the performance gains (mentioned above) take effect, a "workload
balancing" between the server and the clients is mandatory. This means that
the communication overhead (client <-> server) and the time needed to execute
the experiment code on the client-side should be in due proportion. More
specifically, for each experiment there will be exactly 2 TCP connections
(send parameter set to client, send result to server) established. Therefore
you should ensure that the jobs you distribute take enough time not to
overflow the server with requests. You may need to bundle parameters for
more than one experiment if a single experiment only takes a few hundred
milliseconds. (See existing experiments for examples.)
=========================================================================================
Steps to run an experiment with gem5:
=========================================================================================
1. Create a directory which will be used as gem5 system directory (which
will contain the guest system and boot image). Further called $SYSTEM.
2. Create two directories $SYSTEM/binaries and $SYSTEM/disks.
3. Put guestsystem kernel to $SYSTEM/binaries and boot image to $SYSTEM/disks
4. Run gem5 with:
$ M5_PATH=$SYSTEM build/ARM/gem5.debug configs/example/fs.py --bare-metal --kernel kernelname

BIN
doc/t32_remote_api.pdf Normal file

Binary file not shown.

3
doc/todo-gem5.txt Normal file
View File

@ -0,0 +1,3 @@
- Dokumentation korrigieren und überarbeiten
- build-Prozess vereinfachen
- funktionsfähiges restore implementieren

238
doc/todo.txt Normal file
View File

@ -0,0 +1,238 @@
==========================================================================================
Verrückte Ideen
==========================================================================================
- aufeinander aufbauende Events (Backend-spezifisch <- generisch, oder mehrere
Einzelevents gebündelt in ein einzelnes abstraktes ["Crash", HLT mit
abgeschalteten Interrupts])
* lösbar als Callback-"Experimente", die selbst Events auslösen?
* Synthese komplexerer Events
- Backend-Schnittstelle (z.B. direkte Anbindung an Simulator vs.
GDB-Schnittstelle zu Simulator vs. Anbindung an reale HW) von
Backend-Architektur (welche Register gibt es, wie breit ist der
Datenbus, welche Traps können ausgelöst werden, etc.) trennen
==========================================================================================
FailBochs-Bausteine TODO
==========================================================================================
Wer gerade an was arbeitet, steht in Klammern hinter dem TODO.
Bochs:
- Bug: Nach save() ist momentan hinterher der Instruction-Pointer eins weiter,
womit nicht unbedingt zu rechnen ist. (rh)
-> Workaround? save() ruft implizit restore() ...
- bei BX_PANIC nicht einfach weitermachen, sondern dem Experiment
signalisieren, dass der Simulator gepanict hat?
Abstraktionen:
- Endianness?
- Merkmalmodell von Implementierungsdetails trennen (hsc)
-> automatische Konfigurierung anhand Experimentauswahl
-> Annotierung von Experimentcode, automatisches Nachladen von Aspekten
- (Allgemeine) Testfälle / Regression-Tests
-> Modifikationen an FAIL* sind damit leichter zu verifizieren
- Abstraktionen für Funktionsparameter und -rückgabewerte
- API zum Übersetzen von Adressen (virtuell [-> linear] -> physikalisch)
-> ggf. nur noch physikalische (oder virtuelle?) Adressen für diverse
Listener?
- SingleBitflipFaultspacePruning kapseln (hsc)
Events/Listener:
- Umstrukturierung des Event-Managements, damit es performanter wird. Dazu
werden Aspekte für die Performanz-Verbesserung pro zeitkritischem Typ
eingewoben. Dabei soll auf eine "search"-Methode zurückgegriffen werden, mit
der in den typspezifischen Containern gesucht werden kann. [...]
- Listener-Callback-Funktionalität einführen: von spezifischem Listener
ableiten, trigger() überschreiben
- Listener alternativ beliebig lange aktiv lassen (statt sie jedes mal neu
registrieren zu müssen, wenn einer gefeuert hat)
- Bug? Wenn z.B. das Tracing-Plugin aktiv ist, ist nicht klar, ob ein
bestimmtes Ereignis zuerst diesem, oder dem laufenden Experiment zugestellt
wird; je nach Reihenfolge sieht der rausgeschriebene Trace anders aus
-> explizites "stell mal alle übrigen Events zu, bevor es mit mir weitergeht"
im SimulatorController?
Parallelisierung:
- Momentan landen initial *alle* Parametersätze im Speicher. Sobald das viel
mehr werden, wird das eventuell eng.
-> BoundedSynchronizedQueue basteln, Kampagne blockiert dann, wenn die voll ist
-> eingehende Resultate nicht in der Kampagne "verarbeiten" (rausschreiben)
-- sonst bekommen wir dasselbe Problem mit der Queue der Resultate;
stattdessen z.B. die Idee der ExperimentDataStorage weiterverfolgen,
Ergebnisse werden asynchron zur Kampagne weggeschrieben
(oder: Zweiteilung der Kampagne vornehmen, "Verarbeitung" in eigenem
Thread)
- coolcampaign fährt momentan ziemlich Achterbahn bei RAM-Benutzung
-> Grund analysieren, ggf. beheben (Ressourcenverwaltung? Threadpool?)
- warum skalieren die Experimente/s nicht (ganz) linear mit der Anzahl der
Cores auf einer Maschine? Jobserver-Problem, oder lokal Contention auf dem
Client (Kernel, Disk-IO)?
-> mal Experimente ohne Kommunikation laufenlassen, Durchsatz messen
-> mal mit mehreren Maschinen durchmessen
- JobServer Statistiken ausgeben lassen, dafür keine Meldung mehr bei jedem Auftrag
* Anzahl Hosts
* Anzahl Clients (momentan ununterscheidbar ...)
* Aufträge pro Sekunde
* ETA bis Kampagne komplett
- Client/Server-TCP-Verbindungen aufrechterhalten
- die Möglichkeit schaffen, im Server mehr Informationen über einen Job
vorzuhalten (und zu loggen), als man an den Client kommuniziert
-> bei Fault-Space-Pruning hat man im Server Äquivalenzklassen, aus denen
man nur einen einzelnen Parametersatz auswählt und dem Client zum
Ausprobieren gibt; die Informationen über die Äquivalenzklasse müss(t)en
nicht über die Leitung, werden aber am Schluss zur Auswertung gebraucht
- Build-ID in control message tatsächlich generieren und verwenden!
- einfacher, aber nicht in allen Fällen wirksam: Server generiert zur
Laufzeit "Session-ID"; falls bei Client-/Server-Kommunikation diese nicht
mit der vorherigen übereinstimmt, terminiert der Client automatisch
* Problem 1: hilft nicht, wenn der Client gerade neu gestartet wurde
* Problem 2: wenn das viele Clients tun, landen sehr viele unbearbeitete
Jobs in der Aktiv-Queue auf dem Server
- mehrere Jobs auf einmal übertragen -> weniger Kommunikationsvorgänge (rh)
* adaptiv: clientseitig erst nur einen anfordern, Laufzeit messen, die
folgenden Male immer so viele anfordern, dass (geschätzt) z.B. mindestens
60s zwischen zwei Kommunikationsvorgängen liegen (mit oberem Limit für
Anzahl Jobs)
-> dann müsste man sich über die ganzen serverseitigen Engpässe gar keine
Gedanken machen
Implementierungsdetails:
- einheitliche Fehlerbehandlung
- einheitliches Logging (Loglevels?), Ausgaben (z.B. im Bochs-Controller,
siehe BochsController::save) vereinheitlichen, evtl. zusätzlich via
(Non-)Verbose-Mode(s)
-> "Ausgabesystem", "Logger"
- einfache, Linux-spezifische Wallclock-Zeitmessung ähnlich boost::timer v2 (rh)
* Start, Ende, einfache Stringkonvertierung/Ausgabe
Effizienz:
- getrennte Queues?
- Queue-Suche optimieren (Hashes, Sortierung, ...)?
- boolean/Counter für Events (um Durchlaufen der Queue zu verhindern)?
- Dynamic AspectC++ ausprobieren
- Löschliste in EventManager via Hashing implementieren (o.Ä.)?
Buildsystem:
- (mittelfristig) in cmake nur wirklich Build-spezifische Dinge konfigurieren
(verwendeter Compiler, Installationsverzeichnis, ...), den Rest in einem
brauchbaren Konfigurationswerkzeug mit Ausdrucksmöglichkeiten für
Merkmalmodelle, Abhängigkeiten, Mehrfachauswahl etc. (kconfig?)
* Bochs / OVP / Gem5 sind Alternativen, nicht beide anschaltbar
-> Cmake-Combo-Box (ggf. noch an anderen Stellen einsetzbar)
http://www.kitware.com/blog/home/post/82
- Hinzufügen eines neuen Experiments konkreter dokumentieren (how-to-build.txt?)
- "Aktivieren" von Aspekten muss anders implementiert werden:
* Momentan ist es nicht möglich, dass mehrere Build-Verzeichnisse (mit
Aspekten darin) nebeneinander existieren, da ag++ alle Unterverzeichnisse
von fail/ nach Aspektheadern durchsucht.
-> stattdessen (in Cmake) eine globale Liste von aktiven Aspektheadern
pflegen und diese per ag++-Flag "-a" aktivieren.
-> ggf. instantiate-foo-experiment.ah nicht mehr generieren (hässlicher, und
dann unnötiger Hack)
Dokumentation:
- Änderungen im Klassendiagramm nachziehen
Erledigt:
- alle Events mit Zähler versehen, so dass sie erst bei Erreichen der 0 feuern
* z.B. erst nach dem 5ten Mal Lesen von Adresse X auslösen
- Bereiche von Instruction-Pointern
- Wrapper für häufig auftretende Experimentmuster, z.B. einzelnes Event
anlegen und dann genau darauf warten
- Wildcards für beliebige Instruktions- bzw. Speicheradresse (ANY_ADDR, siehe Event.hpp),
inkl. Anpassung des ausgelösten Events
- Registerzugriff aus dem Experiment-Controller, RegisterBitflip vorbereitet
- Auslösen von Reboot (rh)
- Auslesen von Register- und Speicherzustand (Kontext Golden-Run-Vergleiche etc.)
- Coroutinen-Bibliothek (oder getcontext/setcontext) statt Threads+Synchronisation?
- Bitflips in Register
- nach Eintreten eines Events wird das Event- (oder FI-)Objekt mit
Detailinformationen befüllt
-> insbesondere bei "Wildcards" (ANY_TRAP) will man ja im
Experimentablauf wissen, was jetzt eigentlich passiert ist
- Event-Aspekt zur Kommunikation mit dem Gastsystem fertig stellen (siehe events/GuestSysCom.ah)
- Bochs-Spezifika von Bochs-unabhängigen Codeteilen trennen
-> Simulator-Abstraktionsschicht
-> Schnittstelle für Informationen über Plattformspezifika, z.B. Register + Bitbreiten
-> Bochs-spezifische Aspekte leiten nur noch Kontrollfluss um,
Implementierung von Ereignissen separat
- (sofern möglich) Ereignisse von FI trennen
- Scattering-Graphik, (Python-)Skript (ab)
- ohne GUI bzw. gesetztem $DISPLAY lauffähig? (rh)
- Save (rh):
- Zielverzeichnis anlegen, falls nicht existent
- Fehlermeldung, falls Zielverzeichnis nicht schreibbar
- FI-Jobs gibt's nicht mehr, überall rauswerfen (ab)
- Traps und Interrupts (alle, oder Match auf beliebige Teilmenge)
(Aspekte existieren bereits. Matchen auf beliebige Teilmenge der Traps ist noch nicht moeglich)
(rh)
- die schlimmsten Speicherlecks in Bochs eliminieren (rh)
- Event-IDs als Identifikationsmittel für Events auf den zweiten Platz verweisen
-> IDs gibt's weiterhin (getId()), aber z.B. waitAny() liefert einen Pointer (ab)
- Brauchen wir eigentlich IDs als Handles für Events, oder genügt es nicht
eigentlich, die Event-Objektadresse zu verwenden? (ab)
- Event-Match-Schleife von Event-Feuer-Schleife trennen (ab):
- erst alle Events, die aktuell matchen, sammeln (Code ggf. spezifisch für die Ereignisart)
- dann sequentiell feuern (Code zentral in SimulatorController)
-> keine Probleme mit nachträglich hinzukommenden Events
- dann leider immer noch Probleme mit nachträglich entfernten Events
-> siehe fail/experiments/coolchecksum/experiment.cc FIXME am Ende
-> Lösung: Löschliste
- ggf. zusammen mit Datenstruktur-Implementierungsdetails-TODO (s.u.) angehen
- FailConfig.hpp in cmake-config einbinden (genauso behandeln wie experiments.hpp!)
-> generierte Datei landet in Buildtree, wird nicht mehr eingecheckt
- variant_config.h in cmake-config einbinden (genauso behandeln wie experiments.hpp!)
-> generierte Datei landet in Buildtree, wird nicht mehr eingecheckt
- EXP*-options nur einmal in config/, nicht in drei verschiedenen Dateien
(config/CMakelists.txt, config/experiments.hpp.in,
experiments/CMakeLists.txt)
- zum Verpacken in ExperimentData-Nachrichten Register<->String-Konvertierung
vereinfachen (ab)
- Speicherzugriffe: bei Instruction Fetch? INC $Adresse? CALL? PUSH?
PUSHF? Interrupt? (ab)
- Timer (Bochs: basierend auf bx_pc_system.register_timer()) für "echte"
Timeouts (die auch dann greifen, wenn die CPU z.B. in einem CLI/HLT steht) (ab)
- Client-Timeouts untersuchen, Server-Implementierung tunen? Retries im Client? (ab)
- unbeantwortete Jobs am Ende einer Kampagne erneut vergeben (ab)
- Namespace Confusion: aufräumen (ab)
- Verzeichnisstruktur umstrukturieren und aufräumen (ab)
- Determinismus: Wie kann für Mikroexperimente sichergestellt werden, dass
externe Ereignisse (Timer, Eingang von Netzwerkpaketen, ...) reproduzierbar
zum selben Zeitpunkt eintreffen? (rh)
- Interrupts teilweise oder komplett sperren
- optional: Interrupts auslösen
- Traces: geeignet kapseln, in einer Sequenz von protobuf-Nachrichten statt
einer großen rausschreiben/laden (rh)
- einheitliches Namensschema für Backend-Beeinflussungen (Interrupt-Synthese,
Interrupt-Unterdrückung, Speicher schreiben, Register schreiben, ...) finden
-> "Fehlerinjektion" ist das ja nicht immer
- Aktuelle Events sind viel mehr "Listener", die auf eine ganze Klasse von
Ereignissen warten (semantische Ungenauigkeit)
-> benenne Events um ("Listener")
-> Erstelle neue Klassenhierarchie, die den "Informationsanteil" der "Events"
repräsentiert. Diese kapseln dann die Informationen in den Events und
werden zudem intern im Fail*-Framework verwendet (genauer: kommuniziert).
==========================================================================================
Theorie TODO
==========================================================================================
- Problem Fork von FI Tools -> Merging eklig.
-> Liste mit konkreten Beispielen
==========================================================================================
FailOVP-Bausteine TODO
==========================================================================================
Wer gerade an was arbeitet, steht in Klammern hinter dem TODO.
Abstraktionen:
- save/restore implementieren -> Speicher-, Register-, Timer-, ??- Zustaende
Sonstiges:
- Sections aus ELF Datei extrahieren, entsprechende Speicherbereiche (generisch) anlegen (rz)
- Symbole aus ELF extrahieren -> Adressen von globalen Objekten/Funktionen in Experimenten angeben (rz)
- Prozessormodell per cmake cleanen und neu bauen (mh)
- CiAO ELF in OVP ausfuehren
Erledigt:
-

14
doc/wishlist.txt Normal file
View File

@ -0,0 +1,14 @@
This file documents ideas/wishes especially from a Fail* *user* perspective.
- Recurring Fail* API usage patterns in experiment/campaign implementations
(that could be implemented in a reusable way, e.g. in a library that sits
between the Fail* API and the experiment)
* Fault-space pruning (FIXME elaborate)
* Preparation vs. final experiment steps -> cmake-driven, automatically
build 2 fail-client binaries? (FIXME elaborate)
* ...
- Campaign distribution: More foolproof host CPU load/local users/RAM usage
examination
- Merge Guest- and IOListeners

60
scripts/client.sh Executable file
View File

@ -0,0 +1,60 @@
#!/bin/bash
#
# client.sh
# Starts a single FailBochs client in an endless loop. Adds ./bochslibs to
# LD_LIBRARY_PATH if existent. Terminates if ./stop exists, or bochs
# terminates with exit status 1.
#
# Prerequisite: All necessary FailBochs ingredients (see multiple-clients.sh)
# in the current directory.
#
rm -f stop
LIBDIR=$PWD/bochslibs
if [ -d $LIBDIR ]
then
export LD_LIBRARY_PATH=$LIBDIR
fi
while [ ! -e stop ]
do
# fiws fairness (don't use this host while someone else is logged in)
# since these pool computers are used by students
# NOTE: this will only work if fail-client terminates from time to time
# TODO: only on Mo-Fr/20h-6h and Sa-So/24h ?
if [[ $(uname -n) == fiws[1-2][0-9][0-9] ]]; then
FIWS_FREE=0
while [ "$FIWS_FREE" -eq 0 ]; do
if [ -e stop ]; then
#repeated exit condition from above
exit 0
fi
FIWS_FREE=1
for user in $(users); do
if [[ "$user" != `whoami` ]]; then
# someone else uses this host, don't do any experiments
FIWS_FREE=0
fi
done
if [ "$FIWS_FREE" -eq 0 ]; then
sleep 300
fi
done
fi
# only start a client if at least 500 MiB is available
FREE_MEM=$(free -m | grep "buffers/cache:" | awk '{print $4}')
if [ $FREE_MEM -lt "500" ]; then
# waiting for free memory. sleep 1-60s and retry.
sleep $(($RANDOM / (32768 / 60) + 1))
else
#nice -n 19 ./bochs -q 2>&1 | tee log.$$.txt | fgrep Result
#nice -n 18 ./bochs -q 2>&1 | fgrep Result
nice -n 18 ./fail-client -q >/dev/null 2>&1
if [ $? -eq 1 ]
then
break
fi
fi
done
echo DONE

132
scripts/colorize.pl Executable file
View File

@ -0,0 +1,132 @@
#! /usr/bin/perl -w
#
# ripped from colorgcc Version: 1.3.2
# http://schlueters.de/colorgcc.1.3.2.txt
#
use Term::ANSIColor;
sub initDefaults
{
$nocolor{"dumb"} = "true";
$colors{"srcColor"} = color("cyan");
$colors{"introColor"} = color("blue");
$colors{"warningFileNameColor"} = color("yellow");
$colors{"warningNumberColor"} = color("yellow");
$colors{"warningMessageColor"} = color("yellow");
$colors{"errorFileNameColor"} = color("bold red");
$colors{"errorNumberColor"} = color("bold red");
$colors{"errorMessageColor"} = color("bold red");
}
sub loadPreferences
{
# Usage: loadPreferences("filename");
my($filename) = @_;
open(PREFS, "<$filename") || return;
while(<PREFS>)
{
next if (m/^\#.*/); # It's a comment.
next if (!m/(.*):\s*(.*)/); # It's not of the form "foo: bar".
$option = $1;
$value = $2;
if ($option eq "nocolor")
{
# The nocolor option lists terminal types, separated by
# spaces, not to do color on.
foreach $termtype (split(/\s+/, $value))
{
$nocolor{$termtype} = "true";
}
}
else
{
$colors{$option} = color($value);
}
}
close(PREFS);
}
sub srcscan
{
# Usage: srcscan($text, $normalColor)
# $text -- the text to colorize
# $normalColor -- The escape sequence to use for non-source text.
# Looks for text between ` and ', and colors it srcColor.
my($line, $normalColor) = @_;
my($srcon) = color("reset") . $colors{"srcColor"};
my($srcoff) = color("reset") . $normalColor;
$line = $normalColor . $line;
# This substitute replaces `foo' with `AfooB' where A is the escape
# sequence that turns on the the desired source color, and B is the
# escape sequence that returns to $normalColor.
$line =~ s/\`(.*?)\'/\`$srcon$1$srcoff\'/g;
print($line, color("reset"));
}
#
# Main program
#
# Set up default values for colors and compilers.
initDefaults();
# Read the configuration file, if there is one.
$configFile = $ENV{"HOME"} . "/.colorgccrc";
if (-f $configFile)
{
loadPreferences($configFile);
}
# Colorize the input
while(<>)
{
if (m/^(.*?):([0-9]+):(.*)$/) # filename:lineno:message
{
$field1 = $1 || "";
$field2 = $2 || "";
$field3 = $3 || "";
if ($field3 =~ m/\s+warning:.*/)
{
# Warning
print($colors{"warningFileNameColor"}, "$field1:", color("reset"));
print($colors{"warningNumberColor"}, "$field2:", color("reset"));
srcscan($field3, $colors{"warningMessageColor"});
}
else
{
# Error
print($colors{"errorFileNameColor"}, "$field1:", color("reset"));
print($colors{"errorNumberColor"}, "$field2:", color("reset"));
srcscan($field3, $colors{"errorMessageColor"});
}
print("\n");
}
elsif (m/^(.*?):(.+):$/) # filename:message:
{
# No line number, treat as an "introductory" line of text.
srcscan($_, $colors{"introColor"});
} elsif (m/No such file or directory/) {
print($colors{"errorFileNameColor"}, $_);
} else # Anything else.
{
# Doesn't seem to be a warning or an error. Print normally.
print(color("reset"), $_);
}
}

View File

@ -0,0 +1,46 @@
#!/bin/bash
#
# distribute-experiment.sh [path/to/experiment-target]
# Distribute necessary FailBochs ingredients for experiment target to
# FAIL_DISTRIBUTE_HOSTS. Defaults to an experiment target in the current
# directory.
#
# Prerequisites:
# - (possibly overridden) env variables from fail-env.sh
#
set -e
# determine absolute path of this script
SCRIPTDIR=$(readlink -f $(dirname $0))
# env variable defaults
source $SCRIPTDIR/fail-env.sh
if [ -n "$1" ]; then cd "$1"; fi
# possibly necessary files
[ ! -e bochsrc ] && echo 'Warning: no bochsrc found' >&2
[ ! -e BIOS-bochs-latest ] && echo 'Warning: no BIOS-bochs-latest found' >&2
[ ! -e vgabios.bin ] && echo 'Warning: no vgabios.bin found' >&2
# necessary files
[ ! -e client.sh ] && cp -v $SCRIPTDIR/client.sh .
[ ! -e multiple-clients.sh ] && cp -v $SCRIPTDIR/multiple-clients.sh .
# add fail-client binary if it doesn't exist
if [ -e fail-client ]
then
echo 'Info: Using local "fail-client" binary.' >&2
else
cp -v $(which fail-client) .
strip fail-client
fi
# sync everything to experiment hosts
for h in $FAIL_DISTRIBUTE_HOSTS
do
echo Distributing to $h ...
rsync -az --partial --delete-before --delete-excluded --exclude=core --exclude=trace.tc . $h:"$FAIL_EXPERIMENT_TARGETDIR" &
done
wait
echo "Done."

30
scripts/fail-env.sh Normal file
View File

@ -0,0 +1,30 @@
#!/bin/bash
#
# fail-env.sh
# default values for several Fail* environment variables
# If you want to set your own defaults, or need a script to source from, e.g.,
# your ~/.bashrc, please copy this file and do not edit it in-place.
#
# A whitespace-separated list of hosts to rsync the experiment data to. This
# is not necessarily the same list as FAIL_EXPERIMENT_HOSTS (see below), as
# many hosts may share their homes via NFS.
export FAIL_DISTRIBUTE_HOSTS=${FAIL_DISTRIBUTE_HOSTS:='ios kos virtuos plutonium bigbox.informatik.uni-erlangen.de ls12sp'}
# A whitespace-separated list of hosts to run experiments on. If the host name
# is followed by a ':' and a number, this specifies the number of clients to
# run on that host (defaults to #CPUs).
export FAIL_EXPERIMENT_HOSTS=${FAIL_EXPERIMENT_HOSTS:="bigbox.informatik.uni-erlangen.de plutonium:4 uran:4 virtuos ios:6 kos:6 bohrium:12 polonium:12 radon $(for hostnr in $(seq 100 254); do echo fiws$hostnr; done)"}
# A homedir-relative directory on the distribution hosts where all necessary
# Fail* ingredients reside (see multiple-clients.sh).
export FAIL_EXPERIMENT_TARGETDIR=${FAIL_EXPERIMENT_TARGETDIR:=.fail-experiment}
# Number of parallel build processes. If unset, #CPUs+1.
if [ -z "$FAIL_BUILD_PARALLEL" ]; then
if [ -e /proc/cpuinfo ]; then
export FAIL_BUILD_PARALLEL=$(($(egrep -c ^processor /proc/cpuinfo)+1))
else
export FAIL_BUILD_PARALLEL=2
fi
fi

33
scripts/killall-bochs.sh Executable file
View File

@ -0,0 +1,33 @@
#!/bin/bash
#
# killall-fail.sh
# Kills all remaining FailBochs instances on $FAIL_EXPERIMENT_HOSTS.
#
# Prerequisites:
# - (possibly overridden) env variables from fail-env.sh
#
# FIXME: unify with runcampaign.sh
set -e
# determine absolute path of this script
SCRIPTDIR=$(readlink -f $(dirname $0))
# env variable defaults
source $SCRIPTDIR/fail-env.sh
CMD="killall -q client.sh"
CONNECTION_ATTEMPTS=2
SSH="ssh -o BatchMode=yes -o ConnectTimeout=60 -o ConnectionAttempts=$CONNECTION_ATTEMPTS"
for h in $FAIL_EXPERIMENT_HOSTS
do
if [[ $h == *:* ]]
then
# split in host:nclients
NCLIENTS=${h#*:}
h=${h%:*}
else
NCLIENTS=
fi
$SSH $h "$CMD $NCLIENTS" &
done

64
scripts/multiple-clients.sh Executable file
View File

@ -0,0 +1,64 @@
#!/bin/bash
#
# multiple-clients.sh [num_clients]
# Starts multiple client.sh instances in a new tmux session. The number of
# clients defaults to #CPUs+1.
#
# Prerequisites:
# - client.sh and all necessary FailBochs ingredients (fail-client binary,
# bochsrc, BIOS/VGA-BIOS, boot image, possibly a saved state) in the current
# directory
# - tmux installed somewhere in $PATH
# - possibly missing dynamic libraries in ~/bochslibs (e.g., for running a
# i386 fail-client/bochs binary in an x86_64 environment)
#
set -e
umask 0077
LIBDIR=~/bochslibs
# cleanup earlier failures
# (FIXME: you probably don't want this on your local machine!)
killall -q client.sh || true
killall -q fail-client || true
sleep .5
killall -q -9 fail-client || true
# On many machines, ~ is mounted via NFS. To avoid the (severe) performance
# penalty, copy all experiment-related stuff to /tmp.
TMP=/tmp/fail.$(id -nu)
mkdir -p $TMP
rsync -a --delete-before * $TMP/
if [ -d $LIBDIR ]
then
rsync -a --delete-before $LIBDIR $TMP/
fi
cd $TMP
# tmux, please shut up.
TMUX='tmux -q'
COMMAND=./client.sh
SESSION=fail-client.$$
# Calculate number of clients from #processors.
PROCESSORS=$(fgrep processor /proc/cpuinfo|wc -l)
if [ -z "$1" ]
then
NWIN=$PROCESSORS
else
NWIN=$1
fi
# Run $NWIN clients in a new tmux session.
if [ $NWIN -ge 1 ]; then
$TMUX new-session -s $SESSION -d "$COMMAND"
fi
for i in $(seq 1 $(($NWIN-1)))
do
$TMUX new-session -t $SESSION -d \; split-window -h "$COMMAND"
$TMUX new-session -t $SESSION -d \; select-layout tiled
done
# Some diagnostics for the operator.
echo "$(uname -n) ($PROCESSORS CPUs @ $(fgrep MHz /proc/cpuinfo|head -n1|awk '{print $(NF)}') MHz): started $NWIN clients"
#$TMUX attach -t $SESSION

View File

@ -0,0 +1,19 @@
#!/bin/bash
#
# ab-fail-env.sh (Adrian Böckenkamp)
# default values for several Fail* environment variables
#
# A whitespace-separated list of hosts to rsync the experiment data to. This
# is not necessarily the same list as FAIL_EXPERIMENT_HOSTS (see below), as
# many hosts may share their homes via NFS.
export FAIL_DISTRIBUTE_HOSTS=${FAIL_DISTRIBUTE_HOSTS:='kos plutonium'}
# A whitespace-separated list of hosts to run experiments on. If the host name
# is followed by a ':' and a number, this specifies the number of clients to
# run on that host (defaults to #CPUs+1).
export FAIL_EXPERIMENT_HOSTS=${FAIL_EXPERIMENT_HOSTS:="plutonium uran kos:6 bohrium polonium radon $(for hostnr in $(seq 100 254); do echo fiws$hostnr; done)"}
# A homedir-relative directory on the distribution hosts where all necessary
# Fail* ingredients reside (see multiple-clients.sh).
export FAIL_EXPERIMENT_TARGETDIR=.fail-experiment

35
scripts/rebuild-bochs.sh Executable file
View File

@ -0,0 +1,35 @@
#!/bin/bash
#
# - needs to be called from within your build directory
# - "rebuild-bochs.sh": rebuild all of both Fail* and Bochs
# (e.g., possibly necessary if you don't understand what was changed by others)
# - "rebuild-bochs.sh fail": rebuild all of Fail* and link fail-client
# (e.g., possibly necessary if you changed Fail-affecting aspects or the
# build system)
# - "rebuild-bochs.sh bochs": rebuild all of Bochs and link fail-client
# (e.g., necessary if you changed Bochs-affecting aspects/code that must be
# inlined in Bochs)
# - "rebuild-bochs.sh -": rebuild only changed parts of Fail* and Bochs
# (e.g., sufficient if you only changed experiment code)
#
set -e
# determine absolute path of this script
SCRIPTDIR=$(readlink -f $(dirname $0))
# env variable defaults
source $SCRIPTDIR/fail-env.sh
if [ "$1" = fail -o -z "$1" ]
then
make clean
fi
if [ "$1" = bochs -o -z "$1" ]
then
make bochsallclean
fi
#export PATH=/fs/staff/hsc/bin/ccache:$PATH
nice make -j$FAIL_BUILD_PARALLEL 2>&1 | $(dirname $0)/colorize.pl 2>&1
nice make install
# no need to use Bochs' own installation mechanism
#nice make -j$FAIL_BUILD_PARALLEL bochsinstall

66
scripts/run-regression-test.sh Executable file
View File

@ -0,0 +1,66 @@
#!/bin/bash
declare testsuccess=true;
declare script_dir=$(dirname $0);
declare fail_dir=$script_dir/../;
declare build_dir=$PWD;
declare target_dir=$script_dir/../../experiment_targets/regression-test;
#find . -name *.ah -not -regex "./src/.*" ! -path $build_dir -exec rm {} \;
cd $build_dir
if [ -f bin/fail-client ]; then
echo -e '\033[37;44m Build-Environment already exists. Start to compile changes. \033[0m'
$script_dir/rebuild-bochs.sh -;
else
echo -e '\033[37;44m Start to generate Build-Environment. \033[0m'
rm * -rf;
cmake -DCONFIG_EVENT_BREAKPOINTS:BOOL=ON -DCONFIG_EVENT_BREAKPOINTS_RANGE:BOOL=ON \
-DCONFIG_EVENT_GUESTSYS:BOOL=ON -DCONFIG_EVENT_INTERRUPT:BOOL=ON \
-DCONFIG_EVENT_IOPORT:BOOL=ON -DCONFIG_EVENT_JUMP:BOOL=ON -DCONFIG_EVENT_MEMREAD:BOOL=ON \
-DCONFIG_EVENT_MEMWRITE:BOOL=ON -DCONFIG_EVENT_TRAP:BOOL=ON -DCONFIG_FAST_BREAKPOINTS:BOOL=OFF \
-DCONFIG_FAST_WATCHPOINTS:BOOL=OFF -DCONFIG_FIRE_INTERRUPTS:BOOL=ON -DCONFIG_SR_REBOOT:BOOL=ON \
-DCONFIG_SR_RESTORE:BOOL=ON -DCONFIG_SR_SAVE:BOOL=ON -DCONFIG_SUPPRESS_INTERRUPTS:BOOL=ON \
-DEXPERIMENTS_ACTIVATED:STRING=regression-test -DPLUGINS_ACTIVATED:STRING='serialoutput;tracing' ..;
echo -e '\033[37;44m Start to compile. \033[0m'
$script_dir/rebuild-bochs.sh;
fi
if [ -d $build_dir/../build ]; then
echo -e '\033[37;44m Restore old configuration in build. \033[0m'
cd $build_dir/../build/;
cmake ..;
fi
cd $target_dir;
$build_dir/bin/fail-client -q;
#diff tracing plugin
diff -q regression-trace.results golden_run/regression-trace.results
if [ ! $? -eq 0 ]
then
testsuccess=false;
fi
#diff Main results
diff -q regression-test.results golden_run/regression-test.results
if [ ! $? -eq 0 ]
then
echo -e '\033[37;44m Regression-Test FAILED.\033[0m'
if $testsuccess;
then
echo -e '\033[37;44m Tracing-Plugin Test SUCCESSFUL. \033[0m'
echo -e '\033[37;44m The output of regression-test differs from that of the golden-run.\033[0m'
else
echo -e '\033[37;44m Tracing-Plugin Test FAILED. Look at regression-trace.results for more information. \033[0m'
echo -e '\033[37;44m The output of regression-test and the trace differs from those of the golden-run.\033[0m'
fi
else
echo -e '\033[37;44m Regression-Test SUCCESSFUL. \033[0m'
if $testsuccess;
then
echo -e '\033[37;44m Tracing-Plugin Test SUCCESSFUL. \033[0m'
else
echo -e '\033[37;44m Tracing-Plugin Test FAILED. \033[0m'
echo -e '\033[37;44m The regression-test was successful, but the trace differs from that of the golden-run. \033[0m'
fi
fi

22
scripts/runcampaign.sh Executable file
View File

@ -0,0 +1,22 @@
#!/bin/bash
#
# runcampaign.sh <campaignserver-binary>
# Runs the campaign server, and launches clients on all $FAIL_EXPERIMENT_HOSTS.
#
# Prerequisites:
# - (possibly overridden) env variables from fail-env.sh
#
# runcampaign.sh <campaignserver-binary>
if [ ! -x "$1" ]; then echo "usage: $0 <campaignserver-binary>" >&2; exit 1; fi
CAMPAIGNSERVER_BINARY=$1
date
/usr/bin/time -po .time "$CAMPAIGNSERVER_BINARY" > $(basename "$CAMPAIGNSERVER_BINARY")_progress.txt 2>&1 &
sleep .1 # wait until server is likely to have a listening socket opened
$(dirname $0)/start-clients.sh
wait
echo "duration:"
cat .time

36
scripts/start-clients.sh Executable file
View File

@ -0,0 +1,36 @@
#!/bin/bash
#
# start-clients.sh
# Launches clients on all $FAIL_EXPERIMENT_HOSTS.
#
# Prerequisites:
# - (possibly overridden) env variables from fail-env.sh
#
set -e
# determine absolute path of this script
SCRIPTDIR=$(readlink -f $(dirname $0))
# env variable defaults
source $SCRIPTDIR/fail-env.sh
CMD="killall -q client.sh || true; cd $FAIL_EXPERIMENT_TARGETDIR; ./multiple-clients.sh"
CONNECTION_ATTEMPTS=2
SSH="ssh -o BatchMode=yes -o ConnectTimeout=60 -o ConnectionAttempts=$CONNECTION_ATTEMPTS"
for h in $FAIL_EXPERIMENT_HOSTS
do
if [[ $h == *:* ]]
then
# split in host:nclients
NCLIENTS=${h#*:}
h=${h%:*}
else
NCLIENTS=
fi
$SSH $h "$CMD $NCLIENTS" &
#disown
done
wait
echo 'done.'

989
simulators/bochs/.bochsrc Normal file
View File

@ -0,0 +1,989 @@
# You may now use double quotes around pathnames, in case
# your pathname includes spaces.
#=======================================================================
# CONFIG_INTERFACE
#
# The configuration interface is a series of menus or dialog boxes that
# allows you to change all the settings that control Bochs's behavior.
# Depending on the platform there are up to 3 choices of configuration
# interface: a text mode version called "textconfig" and two graphical versions
# called "win32config" and "wx". The text mode version uses stdin/stdout and
# is always compiled in, unless Bochs is compiled for wx only. The choice
# "win32config" is only available on win32 and it is the default there.
# The choice "wx" is only available when you use "--with-wx" on the configure
# command. If you do not write a config_interface line, Bochs will
# choose a default for you.
#
# NOTE: if you use the "wx" configuration interface, you must also use
# the "wx" display library.
#=======================================================================
#config_interface: textconfig
#config_interface: win32config
#config_interface: wx
#=======================================================================
# DISPLAY_LIBRARY
#
# The display library is the code that displays the Bochs VGA screen. Bochs
# has a selection of about 10 different display library implementations for
# different platforms. If you run configure with multiple --with-* options,
# the display_library command lets you choose which one you want to run with.
# If you do not write a display_library line, Bochs will choose a default for
# you.
#
# The choices are:
# x use X windows interface, cross platform
# win32 use native win32 libraries
# carbon use Carbon library (for MacOS X)
# beos use native BeOS libraries
# macintosh use MacOS pre-10
# amigaos use native AmigaOS libraries
# sdl use SDL library, cross platform
# svga use SVGALIB library for Linux, allows graphics without X11
# term text only, uses curses/ncurses library, cross platform
# rfb provides an interface to AT&T's VNC viewer, cross platform
# wx use wxWidgets library, cross platform
# nogui no display at all
#
# NOTE: if you use the "wx" configuration interface, you must also use
# the "wx" display library.
#
# Specific options:
# Some display libraries now support specific option to control their
# behaviour. See the examples below for currently supported options.
#=======================================================================
#display_library: amigaos
#display_library: beos
#display_library: carbon
#display_library: macintosh
#display_library: nogui
#display_library: rfb, options="timeout=60" # time to wait for client
#display_library: sdl, options="fullscreen" # startup in fullscreen mode
#display_library: term
#display_library: win32, options="gui_debug" # use Win32 debugger gui
#display_library: wx
#display_library: x, options="hideIPS" # disable IPS output in status bar
#display_library: x, options="gui_debug" # use GTK debugger gui
#=======================================================================
# ROMIMAGE:
# The ROM BIOS controls what the PC does when it first powers on.
# Normally, you can use a precompiled BIOS in the source or binary
# distribution called BIOS-bochs-latest. The ROM BIOS is usually loaded
# starting at address 0xf0000, and it is exactly 64k long. Another option
# is 128k BIOS which is loaded at address 0xe0000.
# You can also use the environment variable $BXSHARE to specify the
# location of the BIOS.
# The usage of external large BIOS images (up to 512k) at memory top is
# now supported, but we still recommend to use the BIOS distributed with
# Bochs. The start address optional, since it can be calculated from image size.
#=======================================================================
romimage: file=$BXSHARE/BIOS-bochs-latest
#romimage: file=bios/seabios-0.5.1.bin
#romimage: file=mybios.bin, address=0xfff80000 # 512k at memory top
#=======================================================================
# CPU:
# This defines cpu-related parameters inside Bochs:
#
# COUNT:
# Set the number of processors:cores per processor:threads per core
# when Bochs is compiled for SMP emulation.
# Bochs currently supports up to 8 threads running simultaniosly.
# If Bochs is compiled without SMP support, it won't accept values
# different from 1.
#
# QUANTUM:
# Maximum amount of instructions allowed to execute by processor before
# returning control to another cpu. This option exists only in Bochs
# binary compiled with SMP support.
#
# RESET_ON_TRIPLE_FAULT:
# Reset the CPU when triple fault occur (highly recommended) rather than
# PANIC. Remember that if you trying to continue after triple fault the
# simulation will be completely bogus !
#
# MSRS:
# Define path to user CPU Model Specific Registers (MSRs) specification.
# See example in msrs.def.
#
# IGNORE_BAD_MSRS:
# Ignore MSR references that Bochs does not understand; print a warning
# message instead of generating #GP exception. This option is enabled
# by default but will not be avaiable if configurable MSRs are enabled.
#
# IPS:
# Emulated Instructions Per Second. This is the number of IPS that bochs
# is capable of running on your machine. You can recompile Bochs with
# --enable-show-ips option enabled, to find your host's capability.
# Measured IPS value will then be logged into your log file or shown
# in the status bar (if supported by the gui).
#
# IPS is used to calibrate many time-dependent events within the bochs
# simulation. For example, changing IPS affects the frequency of VGA
# updates, the duration of time before a key starts to autorepeat, and
# the measurement of BogoMips and other benchmarks.
#
# Examples:
#
# Bochs Machine/Compiler Mips
# ____________________________________________________________________
# 2.3.7 3.2Ghz Intel Core 2 Q9770 with WinXP/g++ 3.4 50 to 55 Mips
# 2.3.7 2.6Ghz Intel Core 2 Duo with WinXP/g++ 3.4 38 to 43 Mips
# 2.2.6 2.6Ghz Intel Core 2 Duo with WinXP/g++ 3.4 21 to 25 Mips
# 2.2.6 2.1Ghz Athlon XP with Linux 2.6/g++ 3.4 12 to 15 Mips
# 2.0.1 1.6Ghz Intel P4 with Win2000/g++ 3.3 5 to 7 Mips
#=======================================================================
cpu: count=1, ips=50000000, reset_on_triple_fault=1, ignore_bad_msrs=1, msrs="msrs.def"
#=======================================================================
# CPUID:
#
# This defines features and functionality supported by Bochs emulated CPU:
#
# MMX:
# Select MMX instruction set support.
# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 5.
#
# SEP:
# Select SYSENTER/SYSEXIT instruction set support.
# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
#
# SSE:
# Select SSE instruction set support.
# Any of NONE/SSE/SSE2/SSE3/SSSE3/SSE4_1/SSE4_2 could be selected.
# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
#
# XAPIC:
# Select XAPIC extensions support.
# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
#
# AES:
# Select AES instruction set support.
# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
#
# MOVBE:
# Select MOVBE Intel(R) Atom instruction support.
# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
#
# XSAVE:
# Select XSAVE extensions support.
# This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
#
# 1G_PAGES:
# Enable 1G page size support in long mode.
# This option exists only if Bochs compiled with x86-64 support.
#
# PCID:
# Enable Process-Context Identifiers (PCID) support in long mode.
# This option exists only if Bochs compiled with x86-64 support.
#
# FSGSBASE:
# Enable GS/GS BASE access instructions support in long mode.
# This option exists only if Bochs compiled with x86-64 support.
#
# MWAIT:
# Select MONITOR/MWAIT instructions support.
# This option exists only if Bochs compiled with --enable-monitor-mwait.
#
# MWAIT_IS_NOP:
# When this option is enabled MWAIT will not put the CPU into a sleep state.
# This option exists only if Bochs compiled with --enable-monitor-mwait.
#
# VENDOR_STRING:
# Set the CPUID vendor string returned by CPUID(0x0). This should be a
# twelve-character ASCII string.
#
# BRAND_STRING:
# Set the CPUID vendor string returned by CPUID(0x80000002 .. 0x80000004).
# This should be at most a forty-eight-character ASCII string.
#
# STEPPING:
# Set stepping information returned by CPUID. Default stepping value is 3.
#
# CPUID_LIMIT_WINNT:
# Determine whether to limit maximum CPUID function to 3. This mode is
# required to workaround WinNT installation and boot issues.
#=======================================================================
cpuid: mmx=1, sep=1, sse=sse4_2, xapic=1, aes=1, movbe=1, xsave=1
cpuid: stepping=5
cpuid: cpuid_limit_winnt=0
#=======================================================================
# MEMORY
# Set the amount of physical memory you want to emulate.
#
# GUEST:
# Set amount of guest physical memory to emulate. The default is 32MB,
# the maximum amount limited only by physical address space limitations.
#
# HOST:
# Set amount of host memory you want to allocate for guest RAM emulation.
# It is possible to allocate less memory than you want to emulate in guest
# system. This will fake guest to see the non-existing memory. Once guest
# system touches new memory block it will be dynamically taken from the
# memory pool. You will be warned (by FATAL PANIC) in case guest already
# used all allocated host memory and wants more.
#
#=======================================================================
memory: guest=512, host=256
#=======================================================================
# OPTROMIMAGE[1-4]:
# You may now load up to 4 optional ROM images. Be sure to use a
# read-only area, typically between C8000 and EFFFF. These optional
# ROM images should not overwrite the rombios (located at
# F0000-FFFFF) and the videobios (located at C0000-C7FFF).
# Those ROM images will be initialized by the bios if they contain
# the right signature (0x55AA) and a valid checksum.
# It can also be a convenient way to upload some arbitrary code/data
# in the simulation, that can be retrieved by the boot loader
#=======================================================================
#optromimage1: file=optionalrom.bin, address=0xd0000
#optromimage2: file=optionalrom.bin, address=0xd1000
#optromimage3: file=optionalrom.bin, address=0xd2000
#optromimage4: file=optionalrom.bin, address=0xd3000
#optramimage1: file=/path/file1.img, address=0x0010000
#optramimage2: file=/path/file2.img, address=0x0020000
#optramimage3: file=/path/file3.img, address=0x0030000
#optramimage4: file=/path/file4.img, address=0x0040000
#=======================================================================
# VGAROMIMAGE
# You now need to load a VGA ROM BIOS into C0000.
#=======================================================================
#vgaromimage: file=bios/VGABIOS-elpin-2.40
vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest
#vgaromimage: file=bios/VGABIOS-lgpl-latest-cirrus
#=======================================================================
# VGA:
# Here you can specify the display extension to be used. With the value
# 'none' you can use standard VGA with no extension. Other supported
# values are 'vbe' for Bochs VBE and 'cirrus' for Cirrus SVGA support.
#=======================================================================
#vga: extension=cirrus
vga: extension=vbe
#=======================================================================
# FLOPPYA:
# Point this to pathname of floppy image file or device
# This should be of a bootable floppy(image/device) if you're
# booting from 'a' (or 'floppy').
#
# You can set the initial status of the media to 'ejected' or 'inserted'.
# floppya: 2_88=path, status=ejected (2.88M 3.5" media)
# floppya: 1_44=path, status=inserted (1.44M 3.5" media)
# floppya: 1_2=path, status=ejected (1.2M 5.25" media)
# floppya: 720k=path, status=inserted (720K 3.5" media)
# floppya: 360k=path, status=inserted (360K 5.25" media)
# floppya: 320k=path, status=inserted (320K 5.25" media)
# floppya: 180k=path, status=inserted (180K 5.25" media)
# floppya: 160k=path, status=inserted (160K 5.25" media)
# floppya: image=path, status=inserted (guess media type from image size)
# floppya: 1_44=vvfat:path, status=inserted (use directory as VFAT media)
# floppya: type=1_44 (1.44M 3.5" floppy drive, no media)
#
# The path should be the name of a disk image file. On Unix, you can use a raw
# device name such as /dev/fd0 on Linux. On win32 platforms, use drive letters
# such as a: or b: as the path. The parameter 'image' works with image files
# only. In that case the size must match one of the supported types.
# The parameter 'type' can be used to enable the floppy drive without media
# and status specified. Usually the drive type is set up based on the media type.
# The optional parameter 'write_protected' can be used to control the media
# write protect switch. By default it is turned off.
#=======================================================================
floppya: 1_44=/dev/fd0, status=inserted
#floppya: image=../1.44, status=inserted
#floppya: 1_44=/dev/fd0H1440, status=inserted
#floppya: 1_2=../1_2, status=inserted
#floppya: 1_44=a:, status=inserted
#floppya: 1_44=a.img, status=inserted, write_protected=1
#floppya: 1_44=/dev/rfd0a, status=inserted
#=======================================================================
# FLOPPYB:
# See FLOPPYA above for syntax
#=======================================================================
#floppyb: 1_44=b:, status=inserted
#floppyb: 1_44=b.img, status=inserted
#=======================================================================
# ATA0, ATA1, ATA2, ATA3
# ATA controller for hard disks and cdroms
#
# ata[0-3]: enabled=[0|1], ioaddr1=addr, ioaddr2=addr, irq=number
#
# These options enables up to 4 ata channels. For each channel
# the two base io addresses and the irq must be specified.
#
# ata0 and ata1 are enabled by default with the values shown below
#
# Examples:
# ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
# ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15
# ata2: enabled=1, ioaddr1=0x1e8, ioaddr2=0x3e0, irq=11
# ata3: enabled=1, ioaddr1=0x168, ioaddr2=0x360, irq=9
#=======================================================================
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15
ata2: enabled=0, ioaddr1=0x1e8, ioaddr2=0x3e0, irq=11
ata3: enabled=0, ioaddr1=0x168, ioaddr2=0x360, irq=9
#=======================================================================
# ATA[0-3]-MASTER, ATA[0-3]-SLAVE
#
# This defines the type and characteristics of all attached ata devices:
# type= type of attached device [disk|cdrom]
# mode= only valid for disks [flat|concat|external|dll|sparse|vmware3]
# mode= only valid for disks [undoable|growing|volatile|vvfat]
# path= path of the image / directory
# cylinders= only valid for disks
# heads= only valid for disks
# spt= only valid for disks
# status= only valid for cdroms [inserted|ejected]
# biosdetect= type of biosdetection [none|auto], only for disks on ata0 [cmos]
# translation=type of translation of the bios, only for disks [none|lba|large|rechs|auto]
# model= string returned by identify device command
# journal= optional filename of the redolog for undoable, volatile and vvfat disks
#
# Point this at a hard disk image file, cdrom iso file, or physical cdrom
# device. To create a hard disk image, try running bximage. It will help you
# choose the size and then suggest a line that works with it.
#
# In UNIX it may be possible to use a raw device as a Bochs hard disk,
# but WE DON'T RECOMMEND IT. In Windows there is no easy way.
#
# In windows, the drive letter + colon notation should be used for cdroms.
# Depending on versions of windows and drivers, you may only be able to
# access the "first" cdrom in the system. On MacOSX, use path="drive"
# to access the physical drive.
#
# The path is mandatory for hard disks. Disk geometry autodetection works with
# images created by bximage if CHS is set to 0/0/0 (cylinders are calculated
# using heads=16 and spt=63). For other hard disk images and modes the
# cylinders, heads, and spt are mandatory. In all cases the disk size reported
# from the image must be exactly C*H*S*512.
#
# Default values are:
# mode=flat, biosdetect=auto, translation=auto, model="Generic 1234"
#
# The biosdetect option has currently no effect on the bios
#
# Examples:
# ata0-master: type=disk, mode=flat, path=10M.sample, cylinders=306, heads=4, spt=17
# ata0-slave: type=disk, mode=flat, path=20M.sample, cylinders=615, heads=4, spt=17
# ata1-master: type=disk, mode=flat, path=30M.sample, cylinders=615, heads=6, spt=17
# ata1-slave: type=disk, mode=flat, path=46M.sample, cylinders=940, heads=6, spt=17
# ata2-master: type=disk, mode=flat, path=62M.sample, cylinders=940, heads=8, spt=17
# ata2-slave: type=disk, mode=flat, path=112M.sample, cylinders=900, heads=15, spt=17
# ata3-master: type=disk, mode=flat, path=483M.sample, cylinders=1024, heads=15, spt=63
# ata3-slave: type=cdrom, path=iso.sample, status=inserted
#=======================================================================
ata0-master: type=disk, mode=flat, path="30M.sample"
#ata0-master: type=disk, mode=flat, path="30M.sample", cylinders=615, heads=6, spt=17
#ata0-master: type=disk, mode=flat, path="c.img", cylinders=0 # autodetect
#ata0-slave: type=disk, mode=vvfat, path=/bochs/images/vvfat, journal=vvfat.redolog
#ata0-slave: type=cdrom, path=D:, status=inserted
#ata0-slave: type=cdrom, path=/dev/cdrom, status=inserted
#ata0-slave: type=cdrom, path="drive", status=inserted
#ata0-slave: type=cdrom, path=/dev/rcd0d, status=inserted
#=======================================================================
# BOOT:
# This defines the boot sequence. Now you can specify up to 3 boot drives,
# which can be 'floppy', 'disk', 'cdrom' or 'network' (boot ROM).
# Legacy 'a' and 'c' are also supported.
# Examples:
# boot: floppy
# boot: cdrom, disk
# boot: network, disk
# boot: cdrom, floppy, disk
#=======================================================================
#boot: floppy
boot: disk
#=======================================================================
# CLOCK:
# This defines the parameters of the clock inside Bochs:
#
# SYNC:
# This defines the method how to synchronize the Bochs internal time
# with realtime. With the value 'none' the Bochs time relies on the IPS
# value and no host time synchronization is used. The 'slowdown' method
# sacrifices performance to preserve reproducibility while allowing host
# time correlation. The 'realtime' method sacrifices reproducibility to
# preserve performance and host-time correlation.
# It is possible to enable both synchronization methods.
#
# TIME0:
# Specifies the start (boot) time of the virtual machine. Use a time
# value as returned by the time(2) system call. If no time0 value is
# set or if time0 equal to 1 (special case) or if time0 equal 'local',
# the simulation will be started at the current local host time.
# If time0 equal to 2 (special case) or if time0 equal 'utc',
# the simulation will be started at the current utc time.
#
# Syntax:
# clock: sync=[none|slowdown|realtime|both], time0=[timeValue|local|utc]
#
# Example:
# clock: sync=none, time0=local # Now (localtime)
# clock: sync=slowdown, time0=315529200 # Tue Jan 1 00:00:00 1980
# clock: sync=none, time0=631148400 # Mon Jan 1 00:00:00 1990
# clock: sync=realtime, time0=938581955 # Wed Sep 29 07:12:35 1999
# clock: sync=realtime, time0=946681200 # Sat Jan 1 00:00:00 2000
# clock: sync=none, time0=1 # Now (localtime)
# clock: sync=none, time0=utc # Now (utc/gmt)
#
# Default value are sync=none, time0=local
#=======================================================================
#clock: sync=none, time0=local
#=======================================================================
# FLOPPY_BOOTSIG_CHECK: disabled=[0|1]
# Enables or disables the 0xaa55 signature check on boot floppies
# Defaults to disabled=0
# Examples:
# floppy_bootsig_check: disabled=0
# floppy_bootsig_check: disabled=1
#=======================================================================
floppy_bootsig_check: disabled=0
#=======================================================================
# LOG:
# Give the path of the log file you'd like Bochs debug and misc. verbiage
# to be written to. If you don't use this option or set the filename to
# '-' the output is written to the console. If you really don't want it,
# make it "/dev/null" (Unix) or "nul" (win32). :^(
#
# Examples:
# log: ./bochs.out
# log: /dev/tty
#=======================================================================
#log: /dev/null
log: bochsout.txt
#=======================================================================
# LOGPREFIX:
# This handles the format of the string prepended to each log line.
# You may use those special tokens :
# %t : 11 decimal digits timer tick
# %i : 8 hexadecimal digits of cpu current eip (ignored in SMP configuration)
# %e : 1 character event type ('i'nfo, 'd'ebug, 'p'anic, 'e'rror)
# %d : 5 characters string of the device, between brackets
#
# Default : %t%e%d
# Examples:
# logprefix: %t-%e-@%i-%d
# logprefix: %i%e%d
#=======================================================================
#logprefix: %t%e%d
#=======================================================================
# LOG CONTROLS
#
# Bochs now has four severity levels for event logging.
# panic: cannot proceed. If you choose to continue after a panic,
# don't be surprised if you get strange behavior or crashes.
# error: something went wrong, but it is probably safe to continue the
# simulation.
# info: interesting or useful messages.
# debug: messages useful only when debugging the code. This may
# spit out thousands per second.
#
# For events of each level, you can choose to crash, report, or ignore.
# TODO: allow choice based on the facility: e.g. crash on panics from
# everything except the cdrom, and only report those.
#
# If you are experiencing many panics, it can be helpful to change
# the panic action to report instead of fatal. However, be aware
# that anything executed after a panic is uncharted territory and can
# cause bochs to become unstable. The panic is a "graceful exit," so
# if you disable it you may get a spectacular disaster instead.
#=======================================================================
panic: action=ask
error: action=report
info: action=report
debug: action=ignore
#pass: action=fatal
#=======================================================================
# DEBUGGER_LOG:
# Give the path of the log file you'd like Bochs to log debugger output.
# If you really don't want it, make it /dev/null or '-'. :^(
#
# Examples:
# debugger_log: ./debugger.out
#=======================================================================
#debugger_log: /dev/null
#debugger_log: debugger.out
debugger_log: -
#=======================================================================
# COM1, COM2, COM3, COM4:
# This defines a serial port (UART type 16550A). In the 'term' you can specify
# a device to use as com1. This can be a real serial line, or a pty. To use
# a pty (under X/Unix), create two windows (xterms, usually). One of them will
# run bochs, and the other will act as com1. Find out the tty the com1
# window using the `tty' command, and use that as the `dev' parameter.
# Then do `sleep 1000000' in the com1 window to keep the shell from
# messing with things, and run bochs in the other window. Serial I/O to
# com1 (port 0x3f8) will all go to the other window.
# In socket* and pipe* (win32 only) modes Bochs becomes either socket/named pipe
# client or server. In client mode it connects to an already running server (if
# connection fails Bochs treats com port as not connected). In server mode it
# opens socket/named pipe and waits until a client application connects to it
# before starting simulation. This mode is useful for remote debugging (e.g.
# with gdb's "target remote host:port" command or windbg's command line option
# -k com:pipe,port=\\.\pipe\pipename). Note: 'socket' is a shorthand for
# 'socket-client' and 'pipe' for 'pipe-client'. Socket modes use simple TCP
# communication, pipe modes use duplex byte mode pipes.
# Other serial modes are 'null' (no input/output), 'file' (output to a file
# specified as the 'dev' parameter), 'raw' (use the real serial port - under
# construction for win32), 'mouse' (standard serial mouse - requires
# mouse option setting 'type=serial', 'type=serial_wheel' or 'type=serial_msys').
#
# Examples:
# com1: enabled=1, mode=null
# com1: enabled=1, mode=mouse
# com2: enabled=1, mode=file, dev=serial.out
# com3: enabled=1, mode=raw, dev=com1
# com3: enabled=1, mode=socket-client, dev=localhost:8888
# com3: enabled=1, mode=socket-server, dev=localhost:8888
# com4: enabled=1, mode=pipe-client, dev=\\.\pipe\mypipe
# com4: enabled=1, mode=pipe-server, dev=\\.\pipe\mypipe
#=======================================================================
#com1: enabled=1, mode=term, dev=/dev/ttyp9
#=======================================================================
# PARPORT1, PARPORT2:
# This defines a parallel (printer) port. When turned on and an output file is
# defined the emulated printer port sends characters printed by the guest OS
# into the output file. On some platforms a device filename can be used to
# send the data to the real parallel port (e.g. "/dev/lp0" on Linux, "lpt1" on
# win32 platforms).
#
# Examples:
# parport1: enabled=1, file="parport.out"
# parport2: enabled=1, file="/dev/lp0"
# parport1: enabled=0
#=======================================================================
parport1: enabled=1, file="parport.out"
#=======================================================================
# SB16:
# This defines the SB16 sound emulation. It can have several of the
# following properties.
# All properties are in the format sb16: property=value
# midi: The filename is where the midi data is sent. This can be a
# device or just a file if you want to record the midi data.
# midimode:
# 0=no data
# 1=output to device (system dependent. midi denotes the device driver)
# 2=SMF file output, including headers
# 3=output the midi data stream to the file (no midi headers and no
# delta times, just command and data bytes)
# wave: This is the device/file where wave output is stored
# wavemode:
# 0=no data
# 1=output to device (system dependent. wave denotes the device driver)
# 2=VOC file output, incl. headers
# 3=output the raw wave stream to the file
# log: The file to write the sb16 emulator messages to.
# loglevel:
# 0=no log
# 1=resource changes, midi program and bank changes
# 2=severe errors
# 3=all errors
# 4=all errors plus all port accesses
# 5=all errors and port accesses plus a lot of extra info
# dmatimer:
# microseconds per second for a DMA cycle. Make it smaller to fix
# non-continuous sound. 750000 is usually a good value. This needs a
# reasonably correct setting for the IPS parameter of the CPU option.
#
# Examples for output devices:
# sb16: midimode=1, midi="", wavemode=1, wave="" # win32
# sb16: midimode=1, midi=alsa:128:0, wavemode=1, wave=alsa # Linux with ALSA
#=======================================================================
#sb16: midimode=1, midi=/dev/midi00, wavemode=1, wave=/dev/dsp, loglevel=2, log=sb16.log, dmatimer=600000
#=======================================================================
# VGA_UPDATE_INTERVAL:
# Video memory is scanned for updates and screen updated every so many
# virtual seconds. The default is 50000, about 20Hz. Keep in mind that
# you must tweak the 'cpu: ips=N' directive to be as close to the number
# of emulated instructions-per-second your workstation can do, for this
# to be accurate.
#
# Examples:
# vga_update_interval: 250000
#=======================================================================
vga_update_interval: 300000
# using for Winstone '98 tests
#vga_update_interval: 100000
#=======================================================================
# KEYBOARD_SERIAL_DELAY:
# Approximate time in microseconds that it takes one character to
# be transfered from the keyboard to controller over the serial path.
# Examples:
# keyboard_serial_delay: 200
#=======================================================================
keyboard_serial_delay: 250
#=======================================================================
# KEYBOARD_PASTE_DELAY:
# Approximate time in microseconds between attempts to paste
# characters to the keyboard controller. This leaves time for the
# guest os to deal with the flow of characters. The ideal setting
# depends on how your operating system processes characters. The
# default of 100000 usec (.1 seconds) was chosen because it works
# consistently in Windows.
#
# If your OS is losing characters during a paste, increase the paste
# delay until it stops losing characters.
#
# Examples:
# keyboard_paste_delay: 100000
#=======================================================================
keyboard_paste_delay: 100000
#=======================================================================
# MOUSE:
# This defines parameters for the emulated mouse type, the initial status
# of the mouse capture and the runtime method to toggle it.
#
# TYPE:
# With the mouse type option you can select the type of mouse to emulate.
# The default value is 'ps2'. The other choices are 'imps2' (wheel mouse
# on PS/2), 'serial', 'serial_wheel' and 'serial_msys' (one com port requires
# setting 'mode=mouse'). To connect a mouse to an USB port, see the 'usb_uhci'
# or 'usb_ohci' option (requires PCI and USB support).
#
# ENABLED:
# The Bochs gui creates mouse "events" unless the 'enabled' option is
# set to 0. The hardware emulation itself is not disabled by this.
# Unless you have a particular reason for enabling the mouse by default,
# it is recommended that you leave it off. You can also toggle the mouse
# usage at runtime (RFB, SDL, Win32, wxWidgets and X11 - see below).
#
# TOGGLE:
# The default method to toggle the mouse capture at runtime is to press the
# CTRL key and the middle mouse button ('ctrl+mbutton'). This option allows
# to change the method to 'ctrl+f10' (like DOSBox), 'ctrl+alt' (like QEMU)
# or 'f12' (replaces win32 'legacyF12' option).
#
# Examples:
# mouse: enabled=1
# mouse: type=imps2, enabled=1
# mouse: type=serial, enabled=1
# mouse: enabled=0, toggle=ctrl+f10
#=======================================================================
mouse: enabled=0
#=======================================================================
# private_colormap: Request that the GUI create and use it's own
# non-shared colormap. This colormap will be used
# when in the bochs window. If not enabled, a
# shared colormap scheme may be used. Not implemented
# on all GUI's.
#
# Examples:
# private_colormap: enabled=1
# private_colormap: enabled=0
#=======================================================================
private_colormap: enabled=0
#=======================================================================
# fullscreen: ONLY IMPLEMENTED ON AMIGA
# Request that Bochs occupy the entire screen instead of a
# window.
#
# Examples:
# fullscreen: enabled=0
# fullscreen: enabled=1
#=======================================================================
#fullscreen: enabled=0
#screenmode: name="sample"
#=======================================================================
# ne2k: NE2000 compatible ethernet adapter
#
# Examples:
# ne2k: ioaddr=IOADDR, irq=IRQ, mac=MACADDR, ethmod=MODULE, ethdev=DEVICE, script=SCRIPT
#
# ioaddr, irq: You probably won't need to change ioaddr and irq, unless there
# are IRQ conflicts. These arguments are ignored when assign the ne2k to a
# PCI slot.
#
# mac: The MAC address MUST NOT match the address of any machine on the net.
# Also, the first byte must be an even number (bit 0 set means a multicast
# address), and you cannot use ff:ff:ff:ff:ff:ff because that's the broadcast
# address. For the ethertap module, you must use fe:fd:00:00:00:01. There may
# be other restrictions too. To be safe, just use the b0:c4... address.
#
# ethdev: The ethdev value is the name of the network interface on your host
# platform. On UNIX machines, you can get the name by running ifconfig. On
# Windows machines, you must run niclist to get the name of the ethdev.
# Niclist source code is in misc/niclist.c and it is included in Windows
# binary releases.
#
# script: The script value is optional, and is the name of a script that
# is executed after bochs initialize the network interface. You can use
# this script to configure this network interface, or enable masquerading.
# This is mainly useful for the tun/tap devices that only exist during
# Bochs execution. The network interface name is supplied to the script
# as first parameter
#
# If you don't want to make connections to any physical networks,
# you can use the following 'ethmod's to simulate a virtual network.
# null: All packets are discarded, but logged to a few files.
# arpback: ARP is simulated. Disabled by default.
# vde: Virtual Distributed Ethernet
# vnet: ARP, ICMP-echo(ping), DHCP and read/write TFTP are simulated.
# The virtual host uses 192.168.10.1.
# DHCP assigns 192.168.10.2 to the guest.
# TFTP uses the ethdev value for the root directory and doesn't
# overwrite files.
#
#=======================================================================
# ne2k: ioaddr=0x300, irq=9, mac=fe:fd:00:00:00:01, ethmod=fbsd, ethdev=en0 #macosx
# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:00, ethmod=fbsd, ethdev=xl0
# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:00, ethmod=linux, ethdev=eth0
# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:01, ethmod=win32, ethdev=MYCARD
# ne2k: ioaddr=0x300, irq=9, mac=fe:fd:00:00:00:01, ethmod=tap, ethdev=tap0
# ne2k: ioaddr=0x300, irq=9, mac=fe:fd:00:00:00:01, ethmod=tuntap, ethdev=/dev/net/tun0, script=./tunconfig
# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:01, ethmod=null, ethdev=eth0
# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:01, ethmod=vde, ethdev="/tmp/vde.ctl"
# ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:01, ethmod=vnet, ethdev="c:/temp"
#=======================================================================
# pnic: Bochs/Etherboot pseudo-NIC
#
# Example:
# pnic: enabled=1, mac=MACADDR, ethmod=MODULE, ethdev=DEVICE, script=SCRIPT
#
# The pseudo-NIC accepts the same syntax (for mac, ethmod, ethdev, script) and
# supports the same networking modules as the NE2000 adapter. In addition to
# this, it must be assigned to a PCI slot.
#=======================================================================
#pnic: enabled=1, mac=b0:c4:20:00:00:00, ethmod=vnet
#=======================================================================
# KEYBOARD_MAPPING:
# This enables a remap of a physical localized keyboard to a
# virtualized us keyboard, as the PC architecture expects.
# If enabled, the keymap file must be specified.
#
# Examples:
# keyboard_mapping: enabled=1, map=gui/keymaps/x11-pc-de.map
#=======================================================================
keyboard_mapping: enabled=0, map=
#=======================================================================
# KEYBOARD_TYPE:
# Type of keyboard return by a "identify keyboard" command to the
# keyboard controler. It must be one of "xt", "at" or "mf".
# Defaults to "mf". It should be ok for almost everybody. A known
# exception is french macs, that do have a "at"-like keyboard.
#
# Examples:
# keyboard_type: mf
#=======================================================================
#keyboard_type: mf
#=======================================================================
# USER_SHORTCUT:
# This defines the keyboard shortcut to be sent when you press the "user"
# button in the headerbar. The shortcut string is a combination of maximum
# 3 key names (listed below) separated with a '-' character.
# Valid key names:
# "alt", "bksl", "bksp", "ctrl", "del", "down", "end", "enter", "esc",
# "f1", ... "f12", "home", "ins", "left", "menu", "minus", "pgdwn", "pgup",
# "plus", "right", "shift", "space", "tab", "up", "win", "print" and "power".
#
# Example:
# user_shortcut: keys=ctrl-alt-del
#=======================================================================
#user_shortcut: keys=ctrl-alt-del
#=======================================================================
# I440FXSUPPORT:
# This option controls the presence of the i440FX PCI chipset. You can
# also specify the devices connected to PCI slots. Up to 5 slots are
# available now. These devices are currently supported: ne2k, pcivga,
# pcidev, pcipnic and usb_ohci. If Bochs is compiled with Cirrus SVGA
# support you'll have the additional choice 'cirrus'.
#
# Example:
# i440fxsupport: enabled=1, slot1=pcivga, slot2=ne2k
#=======================================================================
i440fxsupport: enabled=1
#=======================================================================
# USB_UHCI:
# This option controls the presence of the USB root hub which is a part
# of the i440FX PCI chipset. With the portX parameter you can connect devices
# to the hub (currently supported: 'mouse', 'tablet', 'keypad', 'disk', 'cdrom'
# 'hub' and 'printer').
#
# The optionsX parameter can be used to assign specific options to the device
# connected to the corresponding USB port. Currently this feature is only used
# to set the speed reported by device and by the 'disk' device to specify
# an alternative redolog file of some image modes.
#
# If you connect the mouse or tablet to one of the ports, Bochs forwards the
# mouse movement data to the USB device instead of the selected mouse type.
# When connecting the keypad to one of the ports, Bochs forwards the input of
# the numeric keypad to the USB device instead of the PS/2 keyboard.
#
# To connect a 'flat' mode image as an USB hardisk you can use the 'disk' device
# with the path to the image separated with a colon. To use other disk image modes
# similar to ATA disks the syntax 'disk:mode:filename' must be used (see below).
#
# To emulate an USB cdrom you can use the 'cdrom' device name and the path to
# an ISO image or raw device name also separated with a colon. An option to
# insert/eject media is available in the runtime configuration.
#
# The device name 'hub' connects an external hub with max. 8 ports (default: 4)
# to the root hub. To specify the number of ports you have to add the value
# separated with a colon. Connecting devices to the external hub ports is only
# available in the runtime configuration.
#
# The device 'printer' emulates the HP Deskjet 920C printer. The PCL data is
# sent to a file specified in bochsrc.txt. The current code appends the PCL
# code to the file if the file already existed. It would probably be nice to
# overwrite the file instead, asking user first.
#=======================================================================
#usb_uhci: enabled=1
#usb_uhci: enabled=1, port1=mouse, port2=disk:usbstick.img
#usb_uhci: enabled=1, port1=hub:7, port2=disk:growing:usbdisk.img
#usb_uhci: enabled=1, port2=disk:undoable:usbdisk.img, options1=journal:redo.log
#usb_uhci: enabled=1, port1=printer:printdata.bin, port2=cdrom:image.iso
#=======================================================================
# USB_OHCI:
# This option controls the presence of the USB OHCI host controller with a
# 2-port hub. The portX option accepts the same device types with the same
# syntax as the UHCI controller (see above). The OHCI HC must be assigned to
# a PCI slot.
#=======================================================================
#usb_ohci: enabled=1
#usb_ohci: enabled=1, port1=printer:usbprinter.bin
#=======================================================================
# CMOSIMAGE:
# This defines image file that can be loaded into the CMOS RAM at startup.
# The rtc_init parameter controls whether initialize the RTC with values stored
# in the image. By default the time0 argument given to the clock option is used.
# With 'rtc_init=image' the image is the source for the initial time.
#
# Example:
# cmosimage: file=cmos.img, rtc_init=image
#=======================================================================
#cmosimage: file=cmos.img, rtc_init=time0
#=======================================================================
# MAGIC_BREAK:
# This enables the "magic breakpoint" feature when using the debugger.
# The useless cpu instruction XCHG BX, BX causes Bochs to enter the
# debugger mode. This might be useful for software development.
#
# Example:
# magic_break: enabled=1
#=======================================================================
#magic_break: enabled=1
#=======================================================================
# PORT_E9_HACK:
# The 0xE9 port doesn't exists in normal ISA architecture. However, we
# define a convention here, to display on the console of the system running
# Bochs anything that is written to it. The idea is to provide debug output
# very early when writing BIOS or OS code for example, without having to
# bother with setting up a serial port or etc. Reading from port 0xE9 will
# will return 0xe9 to let you know if the feature is available.
# Leave this 0 unless you have a reason to use it.
#
# Example:
# port_e9_hack: enabled=1
#=======================================================================
#port_e9_hack: enabled=1
#=======================================================================
# DEBUG_SYMBOLS:
# This loads symbols from the specified file for use in Bochs' internal
# debugger. Symbols are loaded into global context. This is equivalent to
# issuing ldsym debugger command at start up.
#
# Example:
# debug_symbols: file="kernel.sym"
# debug_symbols: file="kernel.sym", offset=0x80000000
#=======================================================================
#debug_symbols: file="kernel.sym"
#=======================================================================
# other stuff
#=======================================================================
#load32bitOSImage: os=nullkernel, path=../kernel.img, iolog=../vga_io.log
#load32bitOSImage: os=linux, path=../linux.img, iolog=../vga_io.log, initrd=../initrd.img
#text_snapshot_check: enabled=1
#print_timestamps: enabled=1
#-------------------------
# PCI host device mapping
#-------------------------
#pcidev: vendor=0x1234, device=0x5678
#=======================================================================
# GDBSTUB:
# Enable GDB stub. See user documentation for details.
# Default value is enabled=0.
#=======================================================================
#gdbstub: enabled=0, port=1234, text_base=0, data_base=0, bss_base=0
#=======================================================================
# PLUGIN_CTRL:
# Controls the presence of optional plugins without a separate option.
# By default all existing plugins are enabled. These plugins are currently
# supported: 'acpi', 'biosdev', 'extfpuirq', 'gameport', 'iodebug',
# 'pci_ide', 'speaker' and 'unmapped'.
#=======================================================================
#plugin_ctrl: biosdev=0, speaker=0
#=======================================================================
# USER_PLUGIN:
# Load user-defined plugin. This option is available only if Bochs is
# compiled with plugin support. Maximum 8 different plugins are supported.
# See the example in the Bochs sources how to write a plugin device.
#=======================================================================
#user_plugin: name=testdev
#=======================================================================
# for Macintosh, use the style of pathnames in the following
# examples.
#
# vgaromimage: :bios:VGABIOS-elpin-2.40
# romimage: file=:bios:BIOS-bochs-latest, address=0xf0000
# floppya: 1_44=[fd:], status=inserted
#=======================================================================
#=======================================================================
# MEGS
# Set the number of Megabytes of physical memory you want to emulate.
# The default is 32MB, most OS's won't need more than that.
# The maximum amount of memory supported is 2048Mb.
# The 'MEGS' option is deprecated. Use 'MEMORY' option instead.
#=======================================================================
#megs: 256
#megs: 128
#megs: 64
#megs: 32
#megs: 16
#megs: 8

6
simulators/bochs/.conf.amigaos Executable file
View File

@ -0,0 +1,6 @@
#!/bin/sh
#
# These options should work on Amiga/MorphOS
#
./configure --with-amigaos --disable-shared ${CONFIGURE_ARGS}

21
simulators/bochs/.conf.beos Executable file
View File

@ -0,0 +1,21 @@
#!/bin/sh
#
# These options are suggested by Bernd Korz, who maintains the BeOS
# port. He says that SDL works better than the native BeOS gui.
#
CC=gcc
CXX=$CC
CFLAGS="-Wall -O9 -mpentium -fomit-frame-pointer -pipe"
CXXFLAGS=$CFLAGS
export CC
export CXX
export CFLAGS
export CXXFLAGS
./configure --with-sdl \
--enable-ne2000 \
--enable-all-optimizations \
--enable-pci

View File

@ -0,0 +1,36 @@
# This script tries to turn on nearly every configure option.
# It is useful for finding compile problems, but it may turn on
# more things than you actually want.
./configure \
--enable-smp \
--enable-x2apic \
--enable-x86-64 \
--enable-all-optimizations \
--enable-long-phy-address \
--enable-configurable-msrs \
--enable-debugger \
--enable-disasm \
--enable-debugger-gui \
--enable-fpu \
--enable-misaligned-sse \
--enable-alignment-check \
--enable-3dnow \
--enable-monitor-mwait \
--enable-vmx \
--enable-x86-debugger \
--enable-a20-pin \
--enable-instrumentation=instrument/example1 \
--enable-vbe \
--enable-ne2000 \
--enable-pci \
--enable-acpi \
--enable-clgd54xx \
--enable-usb \
--enable-usb-ohci \
--enable-cdrom \
--enable-sb16 \
--enable-iodebug \
--enable-gdb-stub \
--enable-show-ips \
--with-all-libs

64
simulators/bochs/.conf.linux Executable file
View File

@ -0,0 +1,64 @@
#!/bin/sh
#
# .conf.linux
#
#which_config=normal
which_config=plugins
CC="gcc"
CXX="c++"
CFLAGS="-Wall -O3 -fomit-frame-pointer -pipe" # for speed
#CFLAGS="-Wall -g -pipe" # for development
CXXFLAGS="$CFLAGS"
export CC
export CXX
export CFLAGS
export CXXFLAGS
case $which_config in
normal)
#######################################################################
# configuration 1 for release binary RPMs
# Include a few standard options, speed optimizations, X11 only.
#######################################################################
./configure --enable-sb16 \
--enable-ne2000 \
--enable-all-optimizations \
--enable-cpu-level=6 \
--enable-x86-64 \
--enable-pci \
--enable-acpi \
--enable-clgd54xx \
--enable-usb \
--enable-usb-ohci \
--enable-show-ips \
${CONFIGURE_ARGS}
;;
plugins)
#######################################################################
# configuration 2 for release binary RPMs
# Include plugins, every possible gui.
#######################################################################
./configure --enable-sb16 \
--enable-ne2000 \
--enable-all-optimizations \
--enable-cpu-level=6 \
--enable-x86-64 \
--enable-pci \
--enable-acpi \
--enable-clgd54xx \
--enable-usb \
--enable-usb-ohci \
--enable-plugins \
--enable-show-ips \
--with-all-libs \
${CONFIGURE_ARGS}
;;
esac

34
simulators/bochs/.conf.macos Executable file
View File

@ -0,0 +1,34 @@
#!/bin/sh
# This script will run configure for a Macintosh/CodeWarrior Pro
# environment. I actually run this on my Linux machine, but
# the generated files are for a Mac.
set echo
# These really just make ./configure happy on your Unix machine.
# They are not the options used on your Mac.
CC="gcc"
CFLAGS=""
CXX="$CC"
CXXFLAGS="$CFLAGS"
export CC
export CXX
export CFLAGS
export CXXFLAGS
./configure --target=ppc-macos \
--enable-sb16 \
--enable-all-optimizations \
--enable-cpu-level=6 \
--enable-x86-64 \
--enable-pci \
--enable-acpi \
--enable-clgd54xx \
--enable-usb \
--enable-plugins \
--with-macos \
${CONFIGURE_ARGS}
unset echo

View File

@ -0,0 +1,33 @@
#!/bin/sh
# this sets up the compile for MacOS X
#
# To support plugins on macosx, you must have "dlcompat" installed. You can
# get dlcompat by installing the fink package "dlcompat-devel". On the SF
# compile farm, dlcompat is in /sw/include and /sw/lib, so we have added
# those paths to the environment variables.
set echo
CFLAGS="-pipe -O3 -I/sw/include -fomit-frame-pointer -finline-functions -falign-loops=16 -falign-jumps=16 -falign-functions=16 -falign-labels=16 -falign-loops-max-skip=15 -falign-jumps-max-skip=15 -fprefetch-loop-arrays $CFLAGS"
CPATH="/sw/include"
CPPFLAGS=""
CXXFLAGS="$CFLAGS"
LDFLAGS="-L/sw/lib"
export CFLAGS
export CPATH
export CPPFLAGS
export CXXFLAGS
export LDFLAGS
./configure --enable-sb16 \
--enable-ne2000 \
--enable-all-optimizations \
--enable-cpu-level=6 \
--enable-x86-64 \
--enable-pci \
--enable-acpi \
--enable-clgd54xx \
--enable-usb \
--enable-plugins \
${CONFIGURE_ARGS}

18
simulators/bochs/.conf.nothing Executable file
View File

@ -0,0 +1,18 @@
#!/bin/sh
#
# These are the steps I typically use to configure and compile Bochs
# on a Win32 system with cygwin (v.20.1)
#
CC="gcc"
CXX="g++"
CFLAGS="-O3 -Wall -Wno-format"
CXXFLAGS="$CFLAGS"
export CC
export CXX
export CFLAGS
export CXXFLAGS
./configure --enable-cpu-level=3 \
--disable-fpu

31
simulators/bochs/.conf.sparc Executable file
View File

@ -0,0 +1,31 @@
#!/bin/sh
#
# These are the steps I typically use to configure and compile Bochs.
#
# superSPARC w/ Solaris 2.x
set echo
CC="gcc"
CXX="g++"
#CFLAGS="-Wall -O2 -mv8 -msupersparc -mno-epilogue"
CFLAGS="-Wall -O2 -mv8 -msupersparc"
#CFLAGS="-Wall -O2 -g"
CXXFLAGS="$CFLAGS"
export CC
export CXX
export CFLAGS
export CXXFLAGS
./configure --enable-ne2000 \
--enable-all-optimizations \
--enable-cpu-level=6 \
--enable-x86-64 \
--enable-pci \
--enable-acpi \
--enable-clgd54xx \
--enable-usb
unset echo

View File

@ -0,0 +1,28 @@
#!/bin/sh
#
# These are the steps I typically use to configure and compile Bochs
# on a Win32 system with cygwin (v.20.1)
#
CC="gcc"
CXX="g++"
CFLAGS="-O3 -Wall -Wno-format"
CXXFLAGS="$CFLAGS"
export CC
export CXX
export CFLAGS
export CXXFLAGS
./configure --enable-sb16 \
--enable-ne2000 \
--enable-all-optimizations \
--enable-cpu-level=6 \
--enable-x86-64 \
--enable-pci \
--enable-acpi \
--enable-clgd54xx \
--enable-usb \
--enable-usb-ohci \
--enable-show-ips \
--with-win32 --with-rfb --with-nogui

View File

@ -0,0 +1,29 @@
#!/bin/sh
set echo
./configure --target=pentium-windows \
--enable-sb16 \
--enable-ne2000 \
--enable-all-optimizations \
--enable-cpu-level=6 \
--enable-x86-64 \
--enable-pci \
--enable-acpi \
--enable-clgd54xx \
--enable-usb \
--enable-usb-ohci \
--enable-show-ips \
--disable-readline \
--without-x \
--with-win32 --with-rfb --with-nogui
unset echo
# Fix up all makefiles so that nmake can handle them.
for i in `find . -name Makefile`; do
echo Removing curly brackets in $i for NMAKE.
mv $i $i.tmp
sed -e 's/{/(/g' -e 's/}/)/g' < $i.tmp > $i
rm -f $i.tmp
done

3374
simulators/bochs/CHANGES Normal file

File diff suppressed because it is too large Load Diff

504
simulators/bochs/COPYING Normal file
View File

@ -0,0 +1,504 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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 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 St, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

Some files were not shown because too many files have changed in this diff Show More