Imported Genode release 11.11

This commit is contained in:
Genode Labs
2011-12-22 16:19:25 +01:00
committed by Christian Helmuth
parent 6bcc9aef0e
commit da4e1feaa5
2462 changed files with 320115 additions and 3 deletions

50
tool/README Normal file
View File

@@ -0,0 +1,50 @@
This directory contains tools for managing and using the source code
of Genode.
:'create_builddir'
The 'create_builddir' tool provides a convenient way to create build
directories for different platforms. Its usage information is printed when
starting the tool without arguments.
:'builddir/':
This directory contains a Makefile template and configuration snippets used
by the 'create_builddir' tool.
:'tool_chain':
This tool downloads, builds, and installs the tool chain needed to build the
Genode OS Framework. For getting usage information, start the tool without
arguments.
:'create_iso':
This simple tool helps to build bootable ISO images from your build of
Genode. For getting usage information, start the tool without arguments.
:'beautify':
Beautify is a coding-style checking tool that analyzes source code for its
adherence to Genode's coding style as described in 'doc/coding_style.txt'.
Whenever possible, the tool tries to fix the issues and outputs a corrected
file. Some corrections, however, require human interaction. In this case,
the tool stops the analysis with an error.
:'parse_cxx':
This tool is a C++ parser used as front-end for Beautify.
:'fix_include_ifndef':
This tool helps with assigning consistent include guards to header files.
:'boot':
This directory contains boot-loader files needed to create boot images.
:'autopilot':
Autopilot is a tool for the automatic execution of run scripts among multiple
base platforms.

360
tool/autopilot Executable file
View File

@@ -0,0 +1,360 @@
#!/usr/bin/tclsh
#
# \brief Automated exection of test cases
# \author Norman Feske
# \date 2011-07-2
#
# The autopilot utility automates the process of executing multiple run
# scripts on different platforms. For each executed run script, the exit
# value is checked and the result gets logged to a file.
#
##
# Execute 'func' for each command line argument of type 'tag'
#
proc foreach_cmdline_arg { tag func } {
global argv
set re "(\\s|^)-$tag\\s*(\[^\\s\]+)"
set args $argv
while {[regexp -- $re $args dummy dummy $tag]} {
eval $func
regsub -- $re $args "" args
}
}
##
# Determine base directory of genode source tree based on the known location of
# the 'autopilot' tool within the tree
#
proc genode_dir { } {
global argv0;
return [file dirname [file dirname $argv0]]
}
proc default_test_dir { } { global env; return "/tmp/autopilot.$env(USER)" }
proc default_log_file { } { return "autopilot.log" }
##
# Present usage information
#
proc help { } {
set help_text {
Automatically execute test cases on different platforms
usage: autopilot -p <platform> ... [-r <run-script> ...]
[-d <test-dir>] [-j <make-jobs>]
[--help] [--cleanup] [--force]
[--stdout] [--skip-clean-rules]
[--enable-ccache]
--force replace test directory if it already exists
--cleanup remove test directory at exit
--stdout print test output instead of writing log files
--skip-clean-rules skip cleanall tests, keep build-directory content
--enable-ccache use ccache instead of plain gcc
}
append help_text "\ndefault test directory is [default_test_dir]\n"
regsub -all {\n\t\t} $help_text "\n" help_text
puts $help_text
}
##
# Return true if command-line switch was specified
#
proc get_cmd_switch { arg_name } {
global argv
return [expr [lsearch $argv $arg_name] >= 0]
}
##
# Remove test directory
#
proc wipe_test_dir { } {
global test_dir
exec rm -rf $test_dir
}
##
# Remove build artifacts if commanded via the '--cleanup' argument
#
proc cleanup { } {
if {[get_cmd_switch --cleanup]} {
puts "cleaning up $test_dir"
wipe_test_dir
}
}
##
# Abort execution with a message and an error code
#
proc fail { message error_code } {
cleanup
puts stderr "Error: $message"
exit $error_code
}
##
# Return build directory used for the specified platform
#
proc build_dir { platform } {
global test_dir
return [file join $test_dir $platform]
}
##
# Return name of log file for test of 'run_script' on 'platform'
#
proc log_file { platform run_script } {
global test_dir
return [file join $test_dir $platform.$run_script.log]
}
##
# Return file descriptor for writing the log output of test case
#
proc log_fd { platform run_script } {
# if '--stdout' was specified, don't write log output to files
if {[get_cmd_switch --stdout]} { return stdout }
# create file descriptor of log file on demand
global _log_fds
if {![info exists _log_fds($platform,$run_script)]} {
set new_fd [open [log_file $platform $run_script] "WRONLY CREAT TRUNC"]
set _log_fds($platform,$run_script) $new_fd
}
return $_log_fds($platform,$run_script)
}
##
# Close file descriptor used for log output of test case
#
proc close_log_fd { platform run_script } {
global _log_fds
if {[info exists _log_fds($platform,$run_script)]} {
close $_log_fds($platform,$run_script)
unset _log_fds($platform,$run_script)
}
}
##
# Execute single run script for specified platform
#
# \return true if run script succeeded
#
proc execute_run_script { platform run_script } {
set return_value true
set fd [log_fd $platform $run_script]
if {[catch {
exec make -C [build_dir $platform] [file join run $run_script] >@ $fd
}]} {
set return_value false
}
close_log_fd $platform $run_script
return $return_value
}
##
# Clean build directory
#
# \return list of unexpected files remaining after 'make cleanall'
#
proc clean_build_dir { platform } {
set fd [log_fd $platform cleanall]
# make returns the exit code 2 on error
if {[catch {
exec make -C [build_dir $platform] cleanall >@ $fd
}] == 2} {
close_log_fd $platform cleanall
return [list "clean rule terminated abnormally"]
}
close_log_fd $platform cleanall
set remainings [split [exec sh -c "cd [build_dir $platform]; find . -mindepth 1"] "\n"]
set unexpected { }
foreach r $remainings {
if {$r == "./etc"} continue
if {$r == "./Makefile"} continue
if {[regexp {\.\/etc\/.*} $r dummy]} continue
lappend unexpected "unexpected: $r"
}
return $unexpected
}
proc build_failed_because_of_missing_run_script { platform run_script } {
# we cannot inspect any logfile when --stdout was used
if {[get_cmd_switch --stdout]} { return 0 }
# grep log output for the respective error message of the build system
if {[catch {
exec grep "^Error: No run script for" [log_file $platform $run_script]
}]} { return 0 }
return 1
}
#
# Collect command-line arguments
#
set platforms { }
foreach_cmdline_arg p { global platforms; lappend platforms $p }
set run_scripts { }
foreach_cmdline_arg r { global run_scripts; lappend run_scripts $r }
set test_dir [default_test_dir]
foreach_cmdline_arg d { global test_dir; set test_dir $d }
set make_jobs 2
foreach_cmdline_arg j { global make_jobs; set make_jobs $j }
# present help if explicitly requested
if {[get_cmd_switch --help]} { help; exit 0 }
# present help if arguments do not suffice
if {![llength $platforms]} {
puts stderr "Error: invalid arguments"
help
exit -1
}
# print information about the parameters
puts "genode dir : [genode_dir]"
puts "platforms : $platforms"
puts "run scripts : $run_scripts"
puts "test dir : $test_dir"
puts "make -j : $make_jobs"
#
# We first create all build directory for all platforms to back out early if
# any error occurs during the creation of build directories due to wrong
# command-line arguments.
#
if {[file exists $test_dir] && ![get_cmd_switch --force]} {
puts stderr "Error: test directory $test_dir already exists"
exit -3
}
if {[get_cmd_switch --force]} { wipe_test_dir }
# create build directories
foreach platform $platforms {
if {[catch {
exec [genode_dir]/tool/create_builddir $platform BUILD_DIR=[build_dir $platform]
}]} {
fail "create_builddir for platform $platform failed" -1
}
set build_conf [file join [build_dir $platform] etc build.conf]
if {![file exists $build_conf]} {
fail "build dir for $platform lacks 'etc/build.conf' file" -2
}
# enable all repositories
exec sed -i "/^#REPOSITORIES/s/^#//" $build_conf
# enable parallel build
exec echo "MAKE += -j$make_jobs" >> $build_conf
# optionally enable ccache
if {[get_cmd_switch --enable-ccache]} {
set tools_conf [file join [build_dir $platform] etc tools.conf]
exec echo "CUSTOM_CC = ccache \$(CROSS_DEV_PREFIX)gcc" >> $tools_conf
exec echo "CUSTOM_CXX = ccache \$(CROSS_DEV_PREFIX)g++" >> $tools_conf
}
}
#
# Revisit each platform's build directory and execute all test cases
#
##
# Print label identifying the specified test case to stderr
#
proc print_step_label { platform step } {
puts -nonewline stderr "[format {%-20s} $platform:] [format {%-20s} $step] "
}
# default exit value used if all tests went successfully
set exit_value 0
# execute run scripts
foreach platform $platforms {
puts stderr "\n--- platform $platform ---"
foreach run_script $run_scripts {
print_step_label $platform $run_script
if {[execute_run_script $platform $run_script]} {
puts stderr "-> OK"
} else {
if {[build_failed_because_of_missing_run_script $platform $run_script]} {
puts stderr "-> UNAVAILABLE"
} else {
puts stderr "-> ERROR"
set exit_value -1
}
}
}
if {[get_cmd_switch --skip-clean-rules]} continue
# execute and validate cleanall rule
print_step_label $platform cleanall
set pollution [clean_build_dir $platform]
if {[llength $pollution] == 0} {
puts stderr "-> OK"
} else {
puts stderr "-> ERROR"
set exit_value -1
foreach p $pollution { puts stderr " $p" }
}
}
proc concluding_message { } {
global exit_value
if {$exit_value == 0} { return "everything ok" }
return "errors occurred"
}
puts stderr "--- done ([concluding_message]) ---"
cleanup
exit $exit_value

1770
tool/beautify Executable file

File diff suppressed because it is too large Load Diff

BIN
tool/boot/chain.c32 Normal file

Binary file not shown.

BIN
tool/boot/isolinux.bin Normal file

Binary file not shown.

5
tool/boot/isolinux.cfg Normal file
View File

@@ -0,0 +1,5 @@
DEFAULT grub
LABEL grub
KERNEL chain.c32
APPEND grub=/boot/grub/stage2_eltorito

BIN
tool/boot/stage2_eltorito Normal file

Binary file not shown.

280
tool/builddir/build.mk Normal file
View File

@@ -0,0 +1,280 @@
#
# \brief Front end to the Genode build system
# \author Norman Feske
# \date 2011-08-04
#
#
# The operation of the build system can be tuned using the following variables,
# which can be specified at the command line or supplied via the
# 'etc/build.conf' file.
#
# BASE_DIR - this directory points to Genode's 'base' repository
# REPOSITORIES - list of directories incorporared into the build process
# VERBOSE - variable that controls the verboseness of the build process
#
# By default, compiler messages are not displayed. If you are
# interested in these messages set this variable to nothing.
# ('VERBOSE=')
#
# VERBOSE_MK - variable that controls the verboseness of make invocations
# VERBOSE_DIR - variable that controls the verboseness of changing directories
#
# Using this variable, you can enable the make messages printed
# when changing directories. To enable the messages, set the
# variable to nothing.
#
# LIB_CACHE_DIR - location of the library build cache
#
# This variable defines the place for the library build cache.
# Normally, the libcache is located at 'var/libcache' and
# there is no need to change it.
#
##
## Define global configuration variables
##
-include etc/build.conf
PWD := $(shell pwd)
BUILD_BASE_DIR := $(PWD)
INSTALL_DIR := $(PWD)/bin
export BASE_DIR ?= ../base
export REPOSITORIES ?= $(BASE_DIR:%base=%base-linux) $(BASE_DIR)
export VERBOSE ?= @
export VERBOSE_DIR ?= --no-print-directory
export VERBOSE_MK ?= @
export LIB_CACHE_DIR ?= $(BUILD_BASE_DIR)/var/libcache
export LIB_PROGRESS_LOG ?= $(BUILD_BASE_DIR)/progress.log
export LIB_DEP_FILE ?= var/libdeps
export ECHO ?= echo -e
#
# Convert user-defined directories to absolute directories
#
# The 'echo' shell command expands '~' characters to the home directory,
# 'realpath' converts relative path names to absolute.
#
REPOSITORIES := $(realpath $(shell echo $(REPOSITORIES)))
BASE_DIR := $(realpath $(shell echo $(BASE_DIR)))
#
# Configure shell program before executing any shell commands. On Ubuntu the
# standard shell is dash, which breaks colored output via its built-in echo
# command.
#
export SHELL := $(shell which bash)
select_from_repositories = $(firstword $(foreach REP,$(REPOSITORIES),$(wildcard $(REP)/$(1))))
include $(BASE_DIR)/mk/global.mk
#
# Some compilers do not support the compiler arguments that we use with 'gcc'
# and, consequently, spit errors. Hence, we have to check if the compiler
# arguments are supported and drop them in the other case. We cache the result
# of the check in the CC_OPT_CHECKCC variable. The caching improves the build
# performance by 5 to 10 percent.
#
checkcc = $(shell if $(CUSTOM_CC) $(1) -o /dev/null -xc - <<< 'int main(void){return 0;}' &> /dev/null; then echo "$(1)" ; fi ;)
CC_OPT_CHECKCC = $(call checkcc, -static)
CC_OPT_CHECKCC += $(call checkcc, -fno-stack-protector)
export CC_OPT_CHECKCC
export LIBGCC_INC_DIR = $(shell dirname `$(CUSTOM_CXX_LIB) -print-libgcc-file-name`)/include
#
# Find out about the target directories to build
#
DST_DIRS = $(filter-out all clean bin cleanall again run/%,$(MAKECMDGOALS))
ifeq ($(MAKECMDGOALS),)
DST_DIRS = .
endif
#
# Default rule: build all directories specified as make arguments
#
all $(DST_DIRS): gen_deps_and_build_targets
@true
#
# Helper to find targets in repositories
# The sed command is there to replace /./ by /. This happens when DST_DIRS = .
#
find_src_target_mk = $(GNU_FIND) $$i/src/$(@:.visit=) -name target.mk 2>/dev/null | sed "s/\/\.\//\//g"
find_all_src_target_mk = for i in $(REPOSITORIES); do $(find_src_target_mk); done
-include $(call select_from_repositories,etc/specs.conf)
-include $(BUILD_BASE_DIR)/etc/specs.conf
export SPEC_FILES := $(foreach SPEC,$(SPECS),$(call select_from_repositories,mk/spec-$(SPEC).mk))
include $(SPEC_FILES)
export SPECS
##
## First stage: generate library dependencies
##
#
# Reset library-build log and library-dependency file
#
# The 'progress' file contains the names of the already processed libraries
# of the current build process. Before considering to process any library,
# the build system checks if the library is already present in the 'progress'
# file and, if yes, skips it.
#
.PHONY: init_progress_log
init_progress_log:
@echo "#" > $(LIB_PROGRESS_LOG)
@echo "# Library build progress log - generated by dep_prg.mk and dep_lib.mk" >> $(LIB_PROGRESS_LOG)
@echo "#" >> $(LIB_PROGRESS_LOG)
.PHONY: init_libdep_file
init_libdep_file:
@echo "#" > $(LIB_DEP_FILE)
@echo "# Library dependencies for build '$(DST_DIRS)'" >> $(LIB_DEP_FILE)
@echo "#" >> $(LIB_DEP_FILE)
@echo "" >> $(LIB_DEP_FILE)
@echo "export SPEC_FILES := \\" >> $(LIB_DEP_FILE)
@for i in $(SPEC_FILES); do \
echo " $$i \\" >> $(LIB_DEP_FILE); done
@echo "" >> $(LIB_DEP_FILE)
@echo "LIB_CACHE_DIR = $(LIB_CACHE_DIR)" >> $(LIB_DEP_FILE)
@echo "BASE_DIR = $(realpath $(BASE_DIR))" >> $(LIB_DEP_FILE)
@echo "VERBOSE ?= $(VERBOSE)" >> $(LIB_DEP_FILE)
@echo "VERBOSE_MK ?= $(VERBOSE_MK)" >> $(LIB_DEP_FILE)
@echo "VERBOSE_DIR ?= $(VERBOSE_DIR)" >> $(LIB_DEP_FILE)
@echo "INSTALL_DIR ?= $(INSTALL_DIR)" >> $(LIB_DEP_FILE)
@echo "SHELL ?= $(SHELL)" >> $(LIB_DEP_FILE)
@echo "MKDIR ?= mkdir" >> $(LIB_DEP_FILE)
@echo "" >> $(LIB_DEP_FILE)
@echo "all:" >> $(LIB_DEP_FILE)
@echo " @true # prevent nothing-to-be-done message" >> $(LIB_DEP_FILE)
@echo "" >> $(LIB_DEP_FILE)
#
# We check if any target.mk files exist in the specified src directory. If
# there exist any target.mk files, we revisit each repository and create
# corresponding rules in the library-dependency file.
#
# This stage is executed serially.
#
$(dir $(LIB_DEP_FILE)):
@mkdir -p $@
VISIT_DST_DIRS = $(addsuffix .visit,$(DST_DIRS))
.PHONY: $(VISIT_DST_DIRS)
.NOTPARALLEL: $(VISIT_DST_DIRS)
$(VISIT_DST_DIRS): $(dir $(LIB_DEP_FILE)) init_libdep_file init_progress_log
@echo "checking library dependencies for $(@:.visit=)..."
@test "`$(find_all_src_target_mk)`" != "" ||\
(echo Error: non-existing target $(@:.visit=); false)
$(VERBOSE_MK)set -e; for i in $(REPOSITORIES); do \
for j in `$(find_src_target_mk)`; do \
$(MAKE) $(VERBOSE_DIR) -f $(BASE_DIR)/mk/dep_prg.mk \
REP_DIR=$$i TARGET_MK=$$j \
BUILD_BASE_DIR=$(BUILD_BASE_DIR) \
SHELL=$(SHELL) \
DARK_COL="$(DARK_COL)" DEFAULT_COL="$(DEFAULT_COL)"; done; done
.PHONY: $(LIB_DEP_FILE)
$(LIB_DEP_FILE): $(VISIT_DST_DIRS)
##
## Second stage: build targets based on the result of the first stage
##
$(INSTALL_DIR):
$(VERBOSE)mkdir -p $@
.PHONY: gen_deps_and_build_targets
gen_deps_and_build_targets: $(INSTALL_DIR) $(LIB_DEP_FILE)
@$(VERBOSE_MK)$(MAKE) $(VERBOSE_DIR) -f $(LIB_DEP_FILE) all
.PHONY: again
again: $(INSTALL_DIR)
@$(VERBOSE_MK)$(MAKE) $(VERBOSE_DIR) -f $(LIB_DEP_FILE) all
##
## Rules for running automated test cases
##
RUN_OPT ?=
RUN_ENV := $(call select_from_repositories,run/env)
ifeq ($(RUN_ENV),)
run: run_no_env
endif
run_no_env:
@echo "Error: There exists no execution environment this platform"
@false
# helper for run/% rule
RUN_SCRIPT = $(call select_from_repositories,run/$*.run)
#
# Read tools configuration to obtain the cross-compiler prefix passed
# to the run script.
#
-include $(call select_from_repositories,etc/tools.conf)
run/%: $(call select_from_repositories,run/%.run) $(RUN_ENV)
$(VERBOSE)test -f "$(RUN_SCRIPT)" || (echo "Error: No run script for $*"; exit -1)
$(VERBOSE)$(GENODE_DIR)/tool/run --genode-dir $(GENODE_DIR) \
--name $* \
--specs "$(SPECS)" \
--repositories "$(REPOSITORIES)" \
--cross-dev-prefix "$(CROSS_DEV_PREFIX)" \
--qemu-args "$(QEMU_OPT)" \
--include $(RUN_ENV) $(RUN_OPT) \
--include $(RUN_SCRIPT)
##
## Clean rules
##
#
# For cleaning, visit each directory for that a corresponding target.mk
# file exists in the source tree. For each such directory, we call
# the single_target rule.
#
clean_targets:
$(VERBOSE_MK)for d in `$(GNU_FIND) -mindepth 1 -type d | $(TAC) | sed "s/^..//"`; do \
for r in $(REPOSITORIES); do \
test -f $$r/src/$$d/target.mk && \
$(MAKE) $(VERBOSE_DIR) clean \
-C $$d \
-f $(BASE_DIR)/mk/prg.mk \
BUILD_BASE_DIR=$(BUILD_BASE_DIR) \
PRG_REL_DIR=$$d \
SHELL=$(SHELL) \
REP_DIR=$$r || \
true; \
done; \
done
clean_libcache:
$(VERBOSE)rm -rf var/libcache
clean_run:
$(VERBOSE)rm -rf var/run
clean_gen_files:
$(VERBOSE)rm -f $(LIB_PROGRESS_LOG)
$(VERBOSE)rm -f $(LIB_DEP_FILE)
clean_install_dir:
$(VERBOSE)(test -d $(INSTALL_DIR) && find $(INSTALL_DIR) -type l -not -readable -delete) || true
clean_empty_dirs: clean_targets clean_libcache clean_run clean_gen_files clean_install_dir
$(VERBOSE)$(GNU_FIND) . -depth -type d -empty -delete
clean cleanall: clean_empty_dirs

2
tool/builddir/etc/README Normal file
View File

@@ -0,0 +1,2 @@
This directory contains templates for configuring build directories
for different platforms. They are used by the 'create_builddir' tool.

View File

@@ -0,0 +1 @@
REPOSITORIES = $(GENODE_DIR)/base-codezero

View File

@@ -0,0 +1,12 @@
#
# Drivers ported from the Linux kernel
#
# Not supported on the ARM architecture.
#
#REPOSITORIES += $(GENODE_DIR)/linux_drivers
#
# Drivers ported from iPXE
#
#REPOSITORIES += $(GENODE_DIR)/dde_ipxe

View File

@@ -0,0 +1 @@
REPOSITORIES = $(GENODE_DIR)/base-fiasco

View File

@@ -0,0 +1 @@
REPOSITORIES = $(GENODE_DIR)/base-foc

View File

@@ -0,0 +1 @@
REPOSITORIES = $(GENODE_DIR)/base-foc

View File

@@ -0,0 +1 @@
REPOSITORIES = $(GENODE_DIR)/base-foc

View File

@@ -0,0 +1 @@
REPOSITORIES = $(GENODE_DIR)/base-foc

View File

@@ -0,0 +1,42 @@
##
## Repositories needed for the default demo scenario
##
REPOSITORIES += $(GENODE_DIR)/base
REPOSITORIES += $(GENODE_DIR)/os
REPOSITORIES += $(GENODE_DIR)/demo
##
## Optional repositories
##
#
# Ports of popular open-source libraries and the C library
#
# Make sure to execute 'make prepare' in 'libports' prior building.
#
#REPOSITORIES += $(GENODE_DIR)/libports
#
# Qt4 tool kit
#
# The 'qt4' repository depends on 'libc' and 'libports'
# Make sure to execute 'make prepare' in 'qt4' prior building.
#
#REPOSITORIES += $(GENODE_DIR)/qt4
#
# Ports of popular 3rd-party applications
#
# The 'ports' repository depends on 'libc', 'libports', and 'qt4'.
# Make sure to execute 'make prepare' in 'ports' prior building.
#
#REPOSITORIES += $(GENODE_DIR)/ports
#
# High-level Genode-specific services and applications
#
# The 'gems' repository depends on 'libc', 'libports', and 'qt4'.
#
#REPOSITORIES += $(GENODE_DIR)/gems

View File

@@ -0,0 +1 @@
REPOSITORIES = $(GENODE_DIR)/base-linux

View File

@@ -0,0 +1,2 @@
REPOSITORIES = $(GENODE_DIR)/base-mb
RUN_OPT += --qemu qemu-mb_s3a_starter_kit

View File

@@ -0,0 +1,2 @@
REPOSITORIES = $(GENODE_DIR)/base-mb
RUN_OPT += --qemu qemu-mb_s3a_starter_kit

View File

@@ -0,0 +1,6 @@
REPOSITORIES = $(GENODE_DIR)/base-nova
#
# The current NOVA kernel build is optimized for Intel Core Duo.
#
QEMU_OPT += -cpu coreduo

View File

@@ -0,0 +1 @@
REPOSITORIES = $(GENODE_DIR)/base-okl4

View File

@@ -0,0 +1 @@
REPOSITORIES = $(GENODE_DIR)/base-pistachio

View File

@@ -0,0 +1,5 @@
#
# Software ported specifically for Fiasco.OC, i.e., L4Linux
#
#REPOSITORIES += $(GENODE_DIR)/ports-foc

View File

@@ -0,0 +1,5 @@
#
# Software ported specifically for OKL4, i.e., OKLinux
#
#REPOSITORIES += $(GENODE_DIR)/ports-okl4

View File

@@ -0,0 +1,10 @@
#
# Prevent Qemu from using KVM
#
# Qemu version that come with major Linux distributions (i.e., Ubuntu) enable
# KVM by default. To use Qemu without KVM, Qemu must be started with the
# '-no-kvm' argument. However, if your Qemu version does not support this
# argument, comment-out this line.
#
QEMU_OPT += -no-kvm

145
tool/create_builddir Executable file
View File

@@ -0,0 +1,145 @@
#!/usr/bin/make -f
#
# \brief Prepare Genode build directory
# \author Christian Helmuth, Norman Feske
# \date 2008-08-14
#
MAKEOVERRIDES =
PLATFORM = $(MAKECMDGOALS)
usage:
@echo
@echo "Tool for preparing Genode build directories"
@echo
@echo "usage:"
@echo
@echo " create_builddir <platform> BUILD_DIR=<build-dir>"
@echo
@echo " <platform> can be 'linux_x86', 'fiasco_x86', 'pistachio_x86',"
@echo " 'okl4_x86', 'nova_x86', 'codezero_vpb926',"
@echo " 'mb_s3a_starter_kit', foc_x86_32', 'foc_x86_64',"
@echo " ''foc_pbxa9', or 'foc_vea9x4'"
@echo " 'or 'foc_pbxa9'"
@echo " "
@echo " <build-dir> is the location of the build directory to create"
@echo
#
# Determine Genode base directory based on the known location of the
# 'create_builddir' tool within the Genode source tree
#
GENODE_DIR ?= $(realpath $(dir $(MAKEFILE_LIST))/..)
ifeq ($(BUILD_DIR),)
$(PLATFORM):: usage
@echo "Error: BUILD_DIR not defined." ; false
endif
#
# Convert GENODE_DIR to an absolute directory because the user
# may have specified a '~'-relative location or a pwd-relative
# location.
#
GENODE_ABS_DIR := $(realpath $(shell echo $(GENODE_DIR)))
#
# Generic build-directory preparation rules
#
BUILD_CONF = $(GENODE_ABS_DIR)/tool/builddir/etc/build.conf
BUILD_CONF_PLATFORM = $(BUILD_CONF).$(PLATFORM)
$(BUILD_DIR)/etc:
@mkdir -p $@
$(BUILD_DIR)/etc/build.conf::
@echo "GENODE_DIR = $(GENODE_ABS_DIR)" > $@
@echo 'BASE_DIR = $$(GENODE_DIR)/base' >> $@
#
# Supply -no-kvm argument to Qemu for kernels that are incompatible with KVM
#
ifeq ($(filter-out foc_x86_32 foc_x86_64 okl4_x86 nova_x86 pistachio_x86,$(PLATFORM)),)
$(BUILD_DIR)/etc/build.conf::
@cat $(BUILD_CONF).qemu_no_kvm >> $@
endif
#
# Add 'base-<platform>' and generic repositories
#
$(BUILD_DIR)/etc/build.conf:: $(BUILD_CONF_PLATFORM)
@echo >> $@
@echo "##" >> $@
@echo "## Kernel-specific base repository" >> $@
@echo "##" >> $@
@echo >> $@
@cat $< >> $@
@cat $(BUILD_CONF).generic >> $@
#
# Add 'ports-okl4' repository to OKL4 build directory
#
ifeq ($(PLATFORM),okl4_x86)
$(BUILD_DIR)/etc/build.conf::
@cat $(BUILD_CONF).ports-okl4 >> $@
endif
$(BUILD_DIR)/Makefile:
@ln -sf $(GENODE_ABS_DIR)/tool/builddir/build.mk $@
#
# Add 'ports-foc' repository to Fiasco.OC build directory
#
ifeq ($(filter-out foc_x86_32 foc_pbxa9,$(PLATFORM)),)
$(BUILD_DIR)/etc/build.conf::
@cat $(BUILD_CONF).ports-foc >> $@
endif
#
# Add x86 drivers repositories to x86 build directories
#
ifeq ($(filter-out foc_x86_32 okl4_x86 nova_x86 pistachio_x86 fiasco_x86,$(PLATFORM)),)
$(BUILD_DIR)/etc/build.conf::
@cat $(BUILD_CONF).drivers_x86 >> $@
endif
#
# Generic platform dependencies
#
$(PLATFORM):: $(BUILD_DIR)/etc
$(PLATFORM):: $(BUILD_DIR)/etc/build.conf
$(PLATFORM):: $(BUILD_DIR)/Makefile
#
# Platform-specific dependencies
#
codezero_vpb926::
@echo "SPECS += codezero_platform_vpb926" > $(BUILD_DIR)/etc/specs.conf
foc_x86_32::
@echo "SPECS = genode foc_x86_32" > $(BUILD_DIR)/etc/specs.conf
foc_x86_64::
@echo "SPECS = genode foc_x86_64" > $(BUILD_DIR)/etc/specs.conf
foc_pbxa9::
@echo "SPECS = genode foc_pbxa9" > $(BUILD_DIR)/etc/specs.conf
foc_vea9x4::
@echo "SPECS = genode foc_vea9x4" > $(BUILD_DIR)/etc/specs.conf
codezero_vpb926::
@echo "CODEZERO_DIR = $(GENODE_DIR)/base-codezero/contrib" > $(BUILD_DIR)/etc/codezero.conf
mb_s3a_starter_kit::
@echo "SPECS = genode mb_s3a_starter_kit" > $(BUILD_DIR)/etc/specs.conf
mb_ml507::
@echo "SPECS = genode mb_ml507" > $(BUILD_DIR)/etc/specs.conf
$(PLATFORM)::
@echo "successfully created build directory at $(BUILD_DIR)"
.PHONY: $(PLATFORM)

70
tool/create_iso Executable file
View File

@@ -0,0 +1,70 @@
#!/usr/bin/make -f
#
# \brief ISO image creation tool
# \author Christian Helmuth
# \date 2009-02-05
ISO ?= genode
ISODIR = $(abspath $(ISO))
ISOIMG = $(abspath $(ISO).iso)
default help:
@echo "--- available commands ---"
@echo "iso - create ISO image of directory \"$(ISO)\""
@echo "tiny.iso - create tiny ISO image of directory \"$(ISO)\""
@echo "compress - create bzip2 compressed ISO image"
@echo "clean - cleanup everything"
@echo
@echo "--- configuration options ---"
@echo "ISO=<name> Overwrites basename of cd image file."
@echo
@echo "Please, place your binaries and config files in appropriate subdirectories in"
@echo " $(ISODIR)"
@echo "and adapt"
@echo " $(ISODIR)/boot/grub/menu.lst"
@echo "to your configuration's needs. A sample directory tree can be found in"
@echo "tool/boot/genode."
#
# Function to generate bootable ISO images
#
# parameter 1 filename of ISO image
# parameter 2 path of directory containing file tree for the ISO image
#
gen_iso_image = genisoimage -f -l -R -hide-rr-moved -jcharset utf8 \
-no-emul-boot -boot-load-size 4 -boot-info-table \
-b boot/isolinux/isolinux.bin \
-o $(1) $(2)
$(ISOIMG) iso:
@$(call gen_iso_image, $(ISOIMG) $(ISODIR))
@which isohybrid > /dev/null && isohybrid $(ISOIMG)
STRIP_FILES = $(wildcard genode/*) $(wildcard pistachio/*)
#
# Compact all files in a directory using strip and gzip
#
# parameter 1 directory containing the files to strip and gzip
#
compact_files = for f in `find $(1) -type f`; do \
strip $$f -o strip.tmp; \
gzip -c strip.tmp > $$f; \
done; rm -f strip.tmp
tiny.iso:
@rm -rf $(@:.iso=.dir)
@cp -Lrp $(ISODIR) $(@:.iso=.dir)
@$(call compact_files, $(@:.iso=.dir)/fiasco)
@$(call compact_files, $(@:.iso=.dir)/pistachio)
@$(call compact_files, $(@:.iso=.dir)/genode)
@$(call gen_iso_image, $@ $(@:.iso=.dir))
@rm -rf $(@:.iso=.dir)
compress: $(ISOIMG)
@bzip2 -f -c $< > $).bz2
clean:
@rm -rf tiny.dir tiny.iso $(ISOIMG)
.PHONY: $(ISOIMG) tiny.iso clean

119
tool/fix_include_ifndef Executable file
View File

@@ -0,0 +1,119 @@
#!/usr/bin/tclsh
# read include file
set include_pathname [lindex $argv 0]
if {[catch {
set source [exec cat $include_pathname]
}]} {
puts stderr ""
puts stderr "Assign correct ifndef-define name to header file."
puts stderr "The name is derived from the location of the"
puts stderr "header file relative to directory from which"
puts stderr "this program is executed."
puts stderr ""
puts stderr "\n usage: fix_include_ifndef <include_file>\n"
exit 0
}
puts stderr "Fixing ifndef header for $include_pathname"
# convert pathname to ifndef string
regsub {^./} $include_pathname "" ifndef_name
set ifndef_name [string toupper $ifndef_name]
regsub -all {/} $ifndef_name {__} ifndef_name
regsub -all {\.} $ifndef_name {_} ifndef_name
regsub -all {\-} $ifndef_name {_} ifndef_name
set ifndef_name "_$ifndef_name\_"
set lines [split $source "\n"]
set state comment_header_begin
set i 0
set output ""
proc out {txtline} {
global output
append output "$txtline\n"
}
foreach line $lines {
incr i
if {$state == "comment_header_begin"} {
if {[regexp {^/*} $line]} {
set state comment_header
out $line
continue
} else {
puts stderr "Error (line $i): missing comment header"
exit -1;
}
}
if {$state == "comment_header"} {
if {[regexp {^ \*/} $line]} {
set state empty_line_after_comment_header
out $line
continue;
}
if {[regexp {^ \*[^/]*} $line]} {
out $line
continue
}
puts "Error (line $i): non-complient comment header"
exit -1;
}
if {$state == "empty_line_after_comment_header"} {
if {![regexp {^$} $line]} {
puts "Error (line $i): no empty line after comment header"
exit -1;
}
set state ifndef
out $line
continue
}
if {$state == "ifndef"} {
if {![regexp {^#ifndef} $line]} {
puts "Error (line $i): expected \"#ifndef\""
exit -1;
}
regsub {^.*$} $line "#ifndef $ifndef_name" line
out $line
set state define
continue
}
if {$state == "define"} {
if {![regexp {^#define} $line]} {
puts "Error (line $i): expected \"#define\""
exit -1;
}
regsub {^.*$} $line "#define $ifndef_name" line
out $line
set state source_main
continue
}
out $line
}
# remove empty lines at the end of the header file
while {[regexp "\n$" $output]} {
regsub "\n$" $output "" output
}
if {![regexp "\n#endif\[^\n\]*\$" $output]} {
puts stderr "Error: last line is no \"#endif\""
exit -1
}
regsub "\n#endif\[^\n\]*\$" $output "\n#endif /* $ifndef_name */" output
# write result back to include file
set fh [open $include_pathname "w"]
puts $fh $output
close $fh

641
tool/libgcc_libc_stub.h Normal file
View File

@@ -0,0 +1,641 @@
/*
* \brief Stub for compiling GCC support libraries without libc
* \author Norman Feske
* \date 2011-08-31
*
* The target components of GCC tool chains (i.e. libsupc++, libgcc_eh, and
* libstdc++) depend on the presence of libc includes. For this reason, a C
* library for the target platform is normally regarded as a prerequisite for
* building a complete tool chain. However, for low-level operating-system
* code, this prerequisite is not satisfied.
*
* There are two traditional solutions to this problem. The first is to leave
* out those target components from the tool chain and live without full C++
* support (using '-fno-rtti' and '-fno-exceptions'). Because Genode relies on
* such C++ features however, this is no option. The other traditional solution
* is to use a tool chain compiled for a different target platform such as
* Linux. However, this approach calls for subtle problems because the target
* components are compiled against glibc and make certain presumptions about
* the underlying OS environment. E.g., the 'libstdc++' library of a Linux tool
* chain contains references to glibc's 'stderr' symbol, which does not exist
* on Genode's libc derived from FreeBSD. More critical assumptions are related
* to the mechanism used for thread-local storage.
*
* This header file overcomes these problems by providing all function
* prototypes and type declarations that are mandatory for compiling GCC's
* target components. Using this libc stub, all GCC target components can be
* built without the need for additional libc support. Of course, for actually
* using these target components, the target OS has to provide the
* implementation of a small subset of functions declared herein. On Genode,
* this subset is provided by the 'cxx' library.
*
* The code of the target components expects usual C header file names such as
* 'stdio.h'. It does not include 'libgcc_libc_stub.h'. By creating symlinks
* for all those file names pointing to this file, we ensure that this file is
* always included on the first occurrence of the inclusion of any libc header
* file. The set of symlinks pointing to this libc stub are created
* automatically by the 'tool_chain' script.
*/
/*
* Copyright (C) 2011 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _LIBC_STUB_H_
#define _LIBC_STUB_H_
/* used for vararg, comes with GCC */
#include <stdarg.h>
#ifdef __cplusplus
extern "C" {
#endif
/*****************
** sys/types.h **
*****************/
typedef __SIZE_TYPE__ size_t;
#ifndef ssize_t
#define ssize_t long /* xxx 64bit */
#endif
typedef unsigned long off_t; /* XXX 64bit */
#define pid_t int
typedef unsigned short mode_t; /* XXX 64bit */
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif /* __cplusplus */
#endif /* defined NULL */
typedef long clock_t; /* XXX not on 64bit */
#ifdef _LP64
typedef signed char __int8_t;
typedef signed short __int16_t;
typedef signed int __int32_t;
typedef signed long __int64_t;
typedef unsigned char __uint8_t;
typedef unsigned short __uint16_t;
typedef unsigned int __uint32_t;
typedef unsigned long __uint64_t;
#else /* _LP64 */
typedef signed char __int8_t;
typedef signed short __int16_t;
typedef signed long __int32_t;
typedef unsigned char __uint8_t;
typedef unsigned short __uint16_t;
typedef unsigned long __uint32_t;
#ifndef __STRICT_ANSI__
typedef signed long long __int64_t;
typedef unsigned long long __uint64_t;
#endif /* __STRICT_ANSI__ */
#endif /* _LP64 */
typedef __int64_t intmax_t;
typedef __int32_t int_fast8_t;
typedef __int32_t int_fast16_t;
typedef __int32_t int_fast32_t;
typedef __int64_t int_fast64_t;
typedef __int8_t int_least8_t;
typedef __int16_t int_least16_t;
typedef __int32_t int_least32_t;
typedef __int64_t int_least64_t;
typedef __uint64_t uintmax_t;
#ifdef _LP64
typedef __int64_t time_t;
typedef __int64_t intptr_t;
typedef __uint64_t uintptr_t;
#else
typedef __int32_t time_t;
typedef __int32_t intptr_t;
typedef __uint32_t uintptr_t;
#endif
typedef __uint32_t uint_fast8_t;
typedef __uint32_t uint_fast16_t;
typedef __uint32_t uint_fast32_t;
typedef __uint64_t uint_fast64_t;
typedef __uint8_t uint_least8_t;
typedef __uint16_t uint_least16_t;
typedef __uint32_t uint_least32_t;
typedef __uint64_t uint_least64_t;
struct timeval {
time_t tv_sec;
long tv_usec; /* XXX 64bit */
};
/****************
** sys/stat.h **
****************/
struct stat
{
unsigned long st_dev;
unsigned long st_ino;
unsigned short st_mode;
};
#define S_ISREG(m) (((m) & 0170000) == 0100000)
/************
** time.h **
************/
struct tm {
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
long tm_gmtoff;
char *tm_zone;
};
clock_t clock(void);
double difftime(time_t time1, time_t time0);
struct tm *localtime(const time_t *timep);
char *asctime(const struct tm *tm);
time_t mktime(struct tm *tm);
char *ctime(const time_t *timep);
struct tm *gmtime(const time_t *timep);
time_t time(time_t *t);
size_t strftime(char *s, size_t max, const char *format,
const struct tm *tm);
/**************
** string.h **
**************/
int memcmp(const void *s1, const void *s2, size_t n);
size_t strlen(const char *s);
void *memcpy(void *dest, const void *src, size_t n);
char *strchr(const char *s, int c);
char *strcpy(char *dest, const char *src);
char *strncpy(char *dest, const char *src, size_t n);
void *memchr(const void *s, int c, size_t n);
int strcmp(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t n);
void *memset(void *s, int c, size_t n);
size_t strcspn(const char *s, const char *reject);
char *strstr(const char *haystack, const char *needle);
size_t strspn(const char *s, const char *accept);
char *strpbrk(const char *s, const char *accept);
char *strcat(char *dest, const char *src);
char *strncat(char *dest, const char *src, size_t n);
/* for compiling 'libsupc++/del_opvnt.cc' */
void *memmove(void *dest, const void *src, size_t n);
int strcoll(const char *s1, const char *s2);
char *strerror(int errnum);
char *strtok(char *str, const char *delim);
size_t strxfrm(char *dest, const char *src, size_t n);
char *strrchr(const char *s, int c);
/***************
** strings.h **
***************/
void bcopy(const void *src, void *dest, size_t n);
void bzero(void *s, size_t n);
/**************
** stdlib.h **
**************/
void free(void *ptr);
void *realloc(void *ptr, size_t size);
void *malloc(size_t size);
void *calloc(size_t nmemb, size_t size);
void abort(void);
void exit(int);
int atoi(const char *nptr);
void *alloca(size_t size);
/* for compiling 'libsupc++/del_op.cc' */
typedef struct { int quot; int rem; } div_t;
typedef struct { long quot; long rem; } ldiv_t;
int abs(int j);
long int labs(long int j);
double atof(const char *nptr);
long atol(const char *nptr);
div_t div(int numerator, int denominator);
ldiv_t ldiv(long numerator, long denominator);
void qsort(void *base, size_t nmemb, size_t size,
int(*compar)(const void *, const void *));
int rand(void);
void srand(unsigned int seed);
int system(const char *command);
#ifdef _ANSIDECL_H
/* special case provided specifically for compiling libiberty's 'strtod.c' */
double strtod(char *nptr, char **endptr);
#else
double strtod(const char *nptr, char **endptr);
#endif
long int strtol(const char *nptr, char **endptr, int base);
unsigned long int strtoul(const char *nptr, char **endptr, int base);
char *getenv(const char *name);
int atexit(void (*function)(void));
void *bsearch(const void *key, const void *base,
size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
/*************
** stdio.h **
*************/
typedef struct __sFILE { int dummy; } FILE;
extern FILE *__stderrp;
extern FILE *__stdinp;
extern FILE *__stdoutp;
#define stderr __stderrp
#define stdin __stdinp
#define stdout __stdoutp
/* must not be enum values */
#define EOF (-1)
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
enum { _IONBF = 2 };
enum { BUFSIZ = 1024 };
FILE *fopen(const char *path, const char *mode);
int fclose(FILE *fp);
int fprintf(FILE *stream, const char *format, ...);
int fputs(const char *s, FILE *stream);
int sscanf(const char *str, const char *format, ...);
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
int ferror(FILE *stream);
int sprintf(char *str, const char *format, ...);
FILE *fdopen(int fd, const char *mode);
int fileno(FILE *);
/* for compiling 'libsupc++/vterminate.cc' */
typedef off_t fpos_t;
void clearerr(FILE *stream);
int feof(FILE *stream);
int ferror(FILE *stream);
int fflush(FILE *stream);
char *fgets(char *s, int size, FILE *stream);
int fgetc(FILE *stream);
int fgetpos(FILE *stream, fpos_t *pos);
int fsetpos(FILE *stream, fpos_t *pos);
long ftell(FILE *stream);
int fseek(FILE *stream, long offset, int whence);
void rewind(FILE *stream);
int fputc(int c, FILE *stream);
int putchar(int c);
int puts(const char *s);
int putc(int c, FILE *stream);
int rename(const char *oldpath, const char *newpath);
int remove(const char *pathname);
int vprintf(const char *format, va_list ap);
int vfprintf(FILE *stream, const char *format, va_list ap);
int vsprintf(char *str, const char *format, va_list ap);
FILE *freopen(const char *path, const char *mode, FILE *stream);
int fscanf(FILE *stream, const char *format, ...);
int scanf(const char *format, ...);
int getc(FILE *stream);
int getchar(void);
char *gets(char *s);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
void perror(const char *s);
int printf(const char *format, ...);
void setbuf(FILE *stream, char *buf);
int setvbuf(FILE *stream, char *buf, int mode, size_t size);
FILE *tmpfile(void);
char *tmpnam(char *s);
int ungetc(int c, FILE *stream);
/**************
** unistd.h **
**************/
int close(int fd);
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
pid_t fork(void);
int unlink(const char *pathname);
void _exit(int status);
int link(const char *oldpath, const char *newpath);
pid_t getpid(void);
int pipe(int pipefd[2]);
int dup2(int oldfd, int newfd);
pid_t wait(int *status);
unsigned int sleep(unsigned int seconds);
off_t lseek(int fd, off_t offset, int whence);
/*************
** errno.h **
*************/
#define errno (* __error())
int *__error(void);
/**
* Error codes corresponding to those of FreeBSD
*/
enum {
EPERM = 1,
ENOENT = 2,
ESRCH = 3,
EINTR = 4,
EIO = 5,
ENXIO = 6,
E2BIG = 7,
ENOEXEC = 8,
EBADF = 9,
ECHILD = 10,
EXDEV = 18,
EDEADLK = 11,
ENOMEM = 12,
EACCES = 13,
EFAULT = 14,
EBUSY = 16,
EEXIST = 17,
ENODEV = 19,
ENOTDIR = 20,
EISDIR = 21,
EINVAL = 22,
ENFILE = 23,
EMFILE = 24,
ENOTTY = 25,
EFBIG = 27,
ENOSPC = 28,
ESPIPE = 29,
EROFS = 30,
EPIPE = 32,
EDOM = 33,
ERANGE = 34,
EAGAIN = 35,
EWOULDBLOCK = EAGAIN,
EINPROGRESS = 36,
EALREADY = 37,
ENOTSOCK = 38,
EDESTADDRREQ = 39,
EMLINK = 31,
EMSGSIZE = 40,
EPROTOTYPE = 41,
ENOPROTOOPT = 42,
EPROTONOSUPPORT = 43,
EOPNOTSUPP = 45,
EAFNOSUPPORT = 47,
EADDRINUSE = 48,
EADDRNOTAVAIL = 49,
ENETDOWN = 50,
ENETUNREACH = 51,
ENETRESET = 52,
ECONNABORTED = 53,
ECONNRESET = 54,
ENOBUFS = 55,
EISCONN = 56,
ENOTCONN = 57,
ETIMEDOUT = 60,
ECONNREFUSED = 61,
ELOOP = 62,
ENAMETOOLONG = 63,
EHOSTUNREACH = 65,
ENOTEMPTY = 66,
ENOLCK = 77,
ENOSYS = 78,
ENOMSG = 83,
EILSEQ = 86
};
/*************
** fcntl.h **
*************/
enum {
O_RDONLY = 0x0000,
O_WRONLY = 0x0001,
O_RDWR = 0x0002,
O_CREAT = 0x0200,
O_TRUNC = 0x0400,
O_EXCL = 0x0800
};
enum { F_SETFD = 2 };
enum { FD_CLOEXEC = 1 };
int open(const char *pathname, int flags, ...);
int fcntl(int fd, int cmd, ... /* arg */ );
/**************
** signal.h **
**************/
enum { SIGTERM = 15 };
int kill(pid_t pid, int sig);
/*************
** ctype.h **
*************/
int isalnum(int c);
int isalpha(int c);
int isascii(int c);
int isblank(int c);
int iscntrl(int c);
int isdigit(int c);
int isgraph(int c);
int islower(int c);
int isprint(int c);
int ispunct(int c);
int isspace(int c);
int isupper(int c);
int isxdigit(int c);
int toupper(int c);
int tolower(int c);
/**************
** locale.h **
**************/
struct lconv;
char *setlocale(int category, const char *locale);
struct lconv *localeconv(void);
enum {
LC_ALL = 0,
LC_COLLATE = 1,
LC_CTYPE = 2,
LC_MONETARY = 3,
LC_NUMERIC = 4,
LC_TIME = 5
};
/************
** math.h **
************/
double acos(double x);
double asin(double x);
double atan(double x);
double atan2(double y, double x);
double ceil(double x);
double cos(double x);
double cosh(double x);
double exp(double x);
double fabs(double x);
double floor(double x);
double fmod(double x, double y);
double frexp(double x, int *exp);
double ldexp(double x, int exp);
double log(double x);
double log10(double x);
double modf(double x, double *iptr);
double pow(double x, double y);
double sin(double x);
double sinh(double x);
double sqrt(double x);
double tan(double x);
double tanh(double x);
/**************
** assert.h **
**************/
#define assert(e) ((void)0)
/***********
** elf.h **
***********/
/*
* The following defines and types are solely needed to compile libgcc's
* 'unwind-dw2-fde-glibc.c' in libc mode. This is needed because Genode's
* dynamic linker relies on the the "new" exception mechanism, which is not
* compiled-in when compiling libgcc with the 'inhibit_libc' flag.
*
* The following types are loosely based on glibc's 'link.h' and 'elf.h'.
*/
typedef __uint32_t Elf64_Word;
typedef __uint64_t Elf64_Addr;
typedef __uint64_t Elf64_Xword;
typedef __uint64_t Elf64_Off;
typedef __uint16_t Elf64_Half;
typedef struct
{
Elf64_Word p_type;
Elf64_Word p_flags;
Elf64_Off p_offset;
Elf64_Addr p_vaddr;
Elf64_Addr p_paddr;
Elf64_Xword p_filesz;
Elf64_Xword p_memsz;
Elf64_Xword p_align;
} Elf64_Phdr;
typedef __uint32_t Elf32_Word;
typedef __uint32_t Elf32_Addr;
typedef __uint64_t Elf32_Xword;
typedef __uint32_t Elf32_Off;
typedef __uint16_t Elf32_Half;
typedef struct
{
Elf32_Word p_type;
Elf32_Off p_offset;
Elf32_Addr p_vaddr;
Elf32_Addr p_paddr;
Elf32_Word p_filesz;
Elf32_Word p_memsz;
Elf32_Word p_flags;
Elf32_Word p_align;
} Elf32_Phdr;
#define PT_LOAD 1
#define PT_DYNAMIC 2
#define PT_LOOS 0x60000000
/************
** link.h **
************/
/* definitions according to glibc */
#ifdef _LP64
#define ElfW(type) Elf64_##type
#else
#define ElfW(type) Elf32_##type
#endif /* _LP64 */
struct dl_phdr_info
{
ElfW(Addr) dlpi_addr;
const char *dlpi_name;
const ElfW(Phdr) *dlpi_phdr;
ElfW(Half) dlpi_phnum;
unsigned long long int dlpi_adds;
unsigned long long int dlpi_subs;
size_t dlpi_tls_modid;
void *dlpi_tls_data;
};
extern int dl_iterate_phdr(int (*__callback) (struct dl_phdr_info *,
size_t, void *), void *__data);
/****************
** features.h **
****************/
/* let check at the beginning of 'gcc/unwind-dw2-fde-glibc.c' pass */
#define __GLIBC__ 99
#ifdef __cplusplus
}
#endif
#endif /* _LIBC_STUB_H_ */

906
tool/parse_cxx Executable file
View File

@@ -0,0 +1,906 @@
#!/usr/bin/tclsh
#
# \brief Regular-expression-based C++ parser
# \author Norman Feske
# \date 2007-08-15
#
# check command line arguments
set config_out_xml [regsub -- "-format +xml" $argv "" argv]
set config_out_tokens [regsub -- "-format +tokens" $argv "" argv]
set config_out_source [regsub -- "-format +source" $argv "" argv]
set config_whitespace [regsub -- "-whitespace" $argv "" argv]
# read file
set input_pathname [lindex $argv 0]
if {[catch {
#
# Create root node of the syntax tree
#
set txt(0) [exec cat $input_pathname]
set typ(0) content
set num 1
}]} {
foreach line {
""
"Parse C++ file and output syntax tree."
""
" usage: parse_cxx \[-whitespace\] \[-format {xml|tokens|source}\] <source_file>"
""
"The supported output formats are:"
""
" xml - XML-based representation"
" tokens - List of tokens (parser-internal representation)"
" source - Source as generated from syntax tree (for debugging)"
""
"If the '-whitespace' argument is specified, whitespaces get translated to tokens."
""
} { puts stderr $line }
exit -1;
}
# do not stop parsing (this variable is only used for debugging)
set stop 0
#
# Detect occurence of magic characters that we
# use to mark substitutions in the syntax tree.
#
if {[regexp {[<5B><><EFBFBD>]} $txt(0) magic_char]} {
puts stderr "Error: Source code contains reserved character '$magic_char'."
puts stderr " The following characters are reserved: '<27>', '<27>', '<27>'"
exit -1;
}
#
# Replace all '&' characters from the original input
# because they cause trouble with the regexp command.
#
regsub -all {&} $txt(0) "<22>" txt(0)
##
# Extract expression from content
#
# All expressions that occur in the token types 'typelist'
# and that match the 'subexpr' criterion get replaced in
# their original token by a reference tag and form a new
# token of the type 'newtype'.
#
# The reference is coded as <20><token_type><token_id><3E>.
# Since the reference has the type coded in, we can
# match sub tokens of specific types via plain regular
# expressions.
##
proc extract {newtype subexpr typelist} {
global num txt typ stop
set old_num $num
if {$stop} { return }
for {set i 0} {$i < $old_num} {incr i} {
if {[lsearch $typelist $typ($i)] > -1} {
while {[regexp $subexpr $txt($i) mid]} {
# new sub text #
set typ($num) $newtype
set txt($num) $mid
# substitute expression by a reference #
regsub $subexpr $txt($i) "<22>$newtype$num<75>" txt($i)
incr num
}
}
}
}
##
# Extract operations
#
# \param op_name name of operator
# \param op_type type of operator, can be "binary", "pre", or "post"
# \param op_dir direction of application, can be "ltr" (left to
# right) or "trl" (right to left)
##
proc extract_op {newtype op_name op_type op_dir typelist} {
global num txt typ stop
set old_num $num
if {$stop} { return }
# Extracting operators is context-sensitive. In particular,
# unary operators must not be applied if they have an
# operand as neighbor. Hence, we construct a pattern with
# three subpatterns, one for the leading context, one for
# the new operand sub token, and one for the trailing context.
if {$op_dir == "ltr"} {
set lpattern ""
} else {
set lpattern ".*"
}
set repl_left {\1}
if {$op_type == "pre"} {
set pattern "(^|$lpattern\(?:\[^i\]er|\[^e\]r|\[^r\\d\]\)\\d+<2B>\\s*)(<28>$op_name\\d+<2B>\\s*<2A>identifier\\d+<2B>)" }
set repl_right {}
if {$op_type == "post"} {
set pattern "($lpattern)(<28>identifier\\d+<2B>\\s*<2A>$op_name\\d+<2B>\\s*)((<28>(\[^i\]|i\[^d\]|id\[^e\]))|;|\$)" }
set repl_right {\3}
if {$op_type == "binary"} {
set pattern "($lpattern)(<28>identifier\\d+<2B>\\s*<2A>$op_name\\d+<2B>\\s*<2A>identifier\\d+<2B>)"
set repl_right {}
}
for {set i 0} {$i < $old_num} {incr i} {
if {[lsearch $typelist $typ($i)] > -1} {
while {[regexp $pattern $txt($i) dummy lcontext match rcontext]} {
# new sub text #
set typ($num) $newtype
set txt($num) $match
set old_txt $txt($i)
# substitute expression by a reference #
regsub $pattern $txt($i) "$repl_left<66>$newtype$num<75>$repl_right" txt($i)
incr num
}
}
}
}
proc extract_operations { from } {
set operators { { doublecolon binary ltr }
{ parenblk post ltr # function call }
{ arrayindex post ltr }
{ deref binary ltr }
{ dot binary ltr }
{ incr post ltr }
{ decr post ltr }
{ not pre rtl }
{ tilde pre rtl }
{ incr pre rtl }
{ decr pre rtl }
{ minus pre rtl }
{ plus pre rtl }
{ star pre rtl # deref }
{ amper pre rtl # addrof }
{ keysizeof pre rtl }
{ parenblk pre rtl # cast }
{ star binary ltr }
{ div binary ltr }
{ mod binary ltr }
{ plus binary ltr }
{ minus binary ltr }
{ lshift binary ltr }
{ rshift binary ltr }
{ less binary ltr }
{ lessequal binary ltr }
{ greater binary ltr }
{ greaterequal binary ltr }
{ equal binary ltr }
{ notequal binary ltr }
{ amper binary ltr # bitand }
{ xor binary ltr }
{ bitor binary ltr }
{ and binary ltr }
{ or binary ltr }
{ cond binary ltr }
{ assign binary rtl }
{ assignopplus binary rtl }
{ assignopminus binary rtl }
{ assignopmult binary rtl }
{ assignopdiv binary rtl }
{ assignopmod binary rtl }
{ assignopbitand binary rtl }
{ assignopbitxor binary rtl }
{ assignopbitor binary rtl }
{ assignoplshift binary rtl }
{ assignoprshift binary rtl }
{ keythrow pre rtl }
{ comma binary ltr }
}
foreach op $operators {
set op_name [lindex $op 0]
set op_type [lindex $op 1]
set op_dir [lindex $op 2]
extract_op identifier $op_name $op_type $op_dir $from
}
}
proc extract_enum_operations { from } {
set operators { { doublecolon binary ltr }
{ parenblk post ltr # function call }
{ not pre rtl }
{ tilde pre rtl }
{ minus pre rtl }
{ plus pre rtl }
{ amper pre rtl # addrof }
{ keysizeof pre rtl }
{ star binary ltr }
{ div binary ltr }
{ mod binary ltr }
{ plus binary ltr }
{ minus binary ltr }
{ lshift binary ltr }
{ rshift binary ltr }
{ less binary ltr }
{ lessequal binary ltr }
{ greater binary ltr }
{ greaterequal binary ltr }
{ equal binary ltr }
{ notequal binary ltr }
{ amper binary ltr # bitand }
{ xor binary ltr }
{ bitor binary ltr }
{ and binary ltr }
{ or binary ltr }
{ cond binary ltr }
}
foreach op $operators {
set op_name [lindex $op 0]
set op_type [lindex $op 1]
set op_dir [lindex $op 2]
extract_op identifier $op_name $op_type $op_dir $from
}
}
##
# Refine types of sub tokens
#
# This function changes the type of sub tokens of the specified
# environment token to the specified replacement type. It is
# used to specialize token types depending on their environment.
# For example, for turning blocks within classes into specialized
# declaration blocks, for which other rules apply than for
# function-body blocks.
##
proc refine_sub_tokens {env_type sub_type repl_sub_type} {
global num txt typ stop
if {$stop} { return }
# iterate through token list in search of env-typed tokens
for {set i 0} {$i < $num} {incr i} {
if {$typ($i) == $env_type} {
set env $txt($i)
while {[regexp "<22>$sub_type\(\\d+)<29>" $env dummy sub_token_idx]} {
set typ($sub_token_idx) $repl_sub_type
regsub "<22>$sub_type\(\\d+)<29>" $env "<22>$repl_sub_type$sub_token_idx<64>" env
}
# update environment token
set txt($i) $env
}
}
}
#####################################################
## Rules for splitting the input into its elements ##
#####################################################
#
# Starting with only the root token (content0) of the syntax tree
# containing the whole source code as one string, we extract
# typed sub tokens to partition the string into parts of distinct
# meanings (token types). In the process of subsequently
# applying extraction rules to specific token types, a syntax
# tree is formed.
#
# extract line comments
extract lcomment {/\*[^\n]*?\*/} content
# extract multi-line comments
extract mlcomment {/\*.*?\*/} content
extract quotedchar {'(.|\\.)'} content
# extract strings
#
# Strings may contain quoted '"' characters.
#
extract string {\"([^\"]|\")*?\"} content
# extract C++-style comments
extract cxxcomment {\/\/[^\n]*} content
# extract preprocessor directives
#
# Preprocessor macros may span over multiple lines if a
# backslash is supplied at the end of each line.
#
extract preproc {#([^\n]|\\\n)*} content
extract preprefix {#} preproc
# extract keywords
foreach keyword {
private public protected unsigned extern
while for if else switch do return typedef
static_cast reinterpret_cast dynamic_cast
using namespace class struct union enum template
const inline static virtual friend explicit
volatile case default operator new throw
try catch continue sizeof asm
GENODE_RPC GENODE_RPC_THROW
GENODE_RPC_INTERFACE GENODE_RPC_INTERFACE_INHERIT
GENODE_TYPE_LIST
} {
set keytag $keyword
regsub -all {_} $keytag "" keytag
set keytag [string tolower $keytag]
extract "key$keytag" "\\m$keyword\\M" content
}
# extract extern "C"
extract "keyexternc" {<7B>keyextern\d+<2B>\s*<2A>string\d+<2B>} content
# fold parenthesis and blocks
extract parenblk {\([^()]*?\)} {content parenblk}
extract block {\{[^{}]*?\}} {content parenblk block}
extract openbrace "\{" block
extract closebrace "\}" block
extract openparen {\(} parenblk
extract closeparen {\)} parenblk
extract externcblk {<7B>keyexternc\d+<2B>\s*<2A>block\d+<2B>} content
# extract template argument blocks
extract tplargs {<[^<>{}]*>$} {content block parenblk}
extract tplargs {<[^<>{}]*>(?=[^>])} {content block parenblk}
# extract special characters
extract equal {==} {content block parenblk}
extract assignopplus {\+=} {content block parenblk}
extract assignopminus {\-=} {content block parenblk}
extract assignopmult {\*=} {content block parenblk}
extract assignopdiv {\/=} {content block parenblk}
extract assignopmod {%=} {content block parenblk}
extract assignopbitor {\|=} {content block parenblk}
extract assignopbitand {<7B>=} {content block parenblk}
extract assignopbitxor {\^=} {content block parenblk}
extract assignopneq {\!=} {content block parenblk}
extract assignoplshift {<<=} {content block parenblk}
extract assignoprshift {>>=} {content block parenblk}
extract incr {\+\+} {content block parenblk}
extract decr {\-\-} {content block parenblk}
extract doublecolon {::} {content block parenblk}
extract or {\|\|} {content block parenblk}
extract bitor {\|} {content block parenblk}
extract and {<7B><>} {content block parenblk}
extract amper {<7B>} {content block parenblk}
extract plus {\+} {content block parenblk}
extract div {\/} {content block parenblk}
extract star {\*} {content block parenblk}
extract notequal {\!=} {content block parenblk}
extract not {\!} {content block parenblk}
extract deref {\->} {content block parenblk}
extract dot {\.} {content block parenblk}
extract tilde {~} {content block parenblk}
extract lshift {<<} {content block parenblk}
extract rshift {>>} {content block parenblk}
extract greaterequal {>=} {content block parenblk}
extract lessequal {<=} {content block parenblk}
extract greater {>} {content block parenblk}
extract less {<} {content block parenblk}
extract minus {\-} {content block parenblk}
extract mod {%} {content block parenblk}
extract xor {\^} {content block parenblk}
extract question {\?} {content block parenblk}
extract comma {,} {content block parenblk}
extract assign {=} {content block parenblk}
extract attribute {__attribute__\s*<2A>parenblk\d+<2B>} {content block parenblk}
# extract identifiers
extract identifier {([\w_][\w\d_]*)+(?=[^<5E>]*(<28>|$))} {content parenblk block}
extract identifier {<7B>quotedchar\d+<2B>} {content parenblk block}
# merge template arguments with the predecessing identifier
extract identifier {<7B>identifier\d+<2B>\s*<2A>tplargs\d+<2B>} {content block parenblk}
# extract using namespace
extract using {<7B>keyusing\d+<2B>\s*<2A>keynamespace\d+<2B>\s*<2A>identifier\d+<2B>\s*;} {content block}
# extract casted identifiers and thereby potentially creating new valid assignments
extract identifier {<7B>key(static|dynamic|reinterpret)cast\d+<2B>\s*<2A>tplargs\d+<2B>\s*<2A>parenblk\d+<2B>} {block}
#
# XXX the C++ precedence rules are not fully implemented
#
# extract namespaced identifiers
extract identifier {<7B>identifier\d+<2B>\s*<2A>doublecolon\d+<2B>\s*<2A>identifier\d+<2B>} block
# extract identifiers in the root namespace
extract identifier {<7B>doublecolon\d+<2B>\s*<2A>identifier\d+<2B>} block
extract whilecond {<7B>keywhile\d+<2B>\s*<2A>parenblk\d+<2B>} block
extract forcond {<7B>keyfor\d+<2B>\s*<2A>parenblk\d+<2B>} block
extract ifcond {<7B>keyif\d+<2B>\s*<2A>parenblk\d+<2B>} block
extract switchcond {<7B>keyswitch\d+<2B>\s*<2A>parenblk\d+<2B>} block
extract catchcond {<7B>keycatch\d+<2B>\s*<2A>parenblk\d+<2B>} block
# extract forward declarations of structs and classes
extract classdecl {<7B>keyclass\d+<2B>\s*<2A>identifier\d+<2B>\s*;} {content block}
extract structdecl {<7B>keystruct\d+<2B>\s*<2A>identifier\d+<2B>\s*;} {content block}
# extract classes
extract class {(<28>mlcomment\d+<2B> *\n[ \t]*)?<3F>keyclass\d+<2B>\s*<2A>identifier\d+<2B>[^;]*;} {content block}
extract struct {(<28>mlcomment\d+<2B> *\n[ \t]*)?<3F>keystruct\d+<2B>\s*<2A>identifier\d+<2B>[^;]*;} {content block}
extract union {(<28>mlcomment\d+<2B> *\n[ \t]*)?<3F>keyunion\d+<2B>\s*<2A>identifier\d+<2B>[^;]*;} {content block}
extract enum {(<28>mlcomment\d+<2B> *\n[ \t]*)?<3F>keyenum\d+<2B>\s*[^;]*;} {content block}
extract inherit {:.*?(?=\s*<2A>block\d+<2B>)} {class struct union}
# partition block types into more expressive sub types
refine_sub_tokens class block classblock
refine_sub_tokens struct block classblock
refine_sub_tokens union block classblock
refine_sub_tokens enum block enumblock
extract_enum_operations enumblock
#enumvalue {<7B>identifier\d+<2B>[^,]*?(?=<3D>comma\d+<2B>)} enumblock
extract enumentry {<7B>identifier\d+<2B>\s*<2A>assign\d+<2B>\s*<2A>identifier\d+<2B>} enumblock
extract enumvalue {<7B>identifier\d+<2B>$} enumentry
extract enumentry {<7B>identifier\d+<2B>} enumblock
# extract template classes
extract tplclassdecl {(<28>mlcomment\d+<2B>[\t ]*\n[\t ]*)?<3F>keytemplate\d+<2B>\s*<2A>tplargs\d+<2B>\s*<2A>classdecl\d+<2B>} {content block classblock}
extract tplstructdecl {(<28>mlcomment\d+<2B>[\t ]*\n[\t ]*)?<3F>keytemplate\d+<2B>\s*<2A>tplargs\d+<2B>\s*<2A>structdecl\d+<2B>} {content block classblock}
extract tplclass {(<28>mlcomment\d+<2B>[\t ]*\n[\t ]*)?<3F>keytemplate\d+<2B>\s*<2A>tplargs\d+<2B>\s*<2A>class\d+<2B>} {content block classblock}
extract tplstruct {(<28>mlcomment\d+<2B>[\t ]*\n[\t ]*)?<3F>keytemplate\d+<2B>\s*<2A>tplargs\d+<2B>\s*<2A>struct\d+<2B>} {content block classblock}
refine_sub_tokens tplclassdecl classdecl class;
refine_sub_tokens tplstructdecl structdecl class;
extract arrayindex {\[[^\]]*\]} {content classblock block arrayindex}
# detect case labels within switch statements and protection labels
extract caselabel {<7B>keycase\d+<2B>[^:]+:} {block}
extract caselabel {<7B>keydefault\d+<2B>:} {block}
foreach keyword { private public protected } {
set label label
extract "$keyword$label" "<22>key$keyword\\d+<2B>:" {classblock} }
extract identifier {<7B>identifier\d+<2B>+\s*<2A>doublecolon\d+<2B>\s*<2A>identifier\d+<2B>} {content classblock}
# extract class initialize list
extract initializer {:\s*<2A>identifier\d+<2B>\s*<2A>parenblk\d+<2B>(\s*<2A>comma\d+<2B>\s*<2A>identifier\d+<2B>\s*<2A>parenblk\d+<2B>)*} {content classblock}
extract colon {:} {initializer inherit}
# extract asm blocks
extract asm {<7B>keyasm\d+<2B>\s*(<28>keyvolatile\d+<2B>)?\s*<2A>parenblk\d+<2B>} {content block}
# extract Genode-specific RPC declaration macros
set genode_macros { genoderpc genoderpcthrow genoderpcinterface genoderpcinterfaceinherit genodetypelist }
foreach key $genode_macros {
extract $key "<22>key$key\\d+<2B>\\s*<2A>parenblk\\d+<2B>\\s*" { classblock parenblk } }
foreach key $genode_macros {
refine_sub_tokens $key parenblk macroargblk }
# extract functions
extract operatorfunction {<7B>keyoperator\d+<2B>\s*<2A>[^<5E>]+\d+<2B>\s*<2A>parenblk\d+<2B>} {content classblock}
extract funcptr {<7B>parenblk\d+<2B>\s*<2A>parenblk\d+<2B>(\s*<2A>attribute\d+<2B>)?} {content classblock block identifier parenblk}
extract function {<7B>identifier\d+<2B>\s*<2A>parenblk\d+<2B>(\s*<2A>attribute\d+<2B>)?} {content classblock block initializer}
extract destfunction {(<28>identifier\d+<2B><>doublecolon\d+<2B>)?<3F>tilde\d+<2B><>identifier\d+<2B>\s*<2A>parenblk\d+<2B>} {content classblock}
extract identifier {(<28>identifier\d+<2B><>doublecolon\d+<2B>)?<3F>tilde\d+<2B><>identifier\d+<2B>} destfunction
extract identifier {<7B>identifier\d+<2B>\s*<2A>parenblk\d+<2B>} {parenblk block identifier initializer}
extract identifier {<7B>parenblk\d+<2B>} {parenblk block}
#extract_operations parenblk
# extract arrays
extract array {(<28>identifier\d+<2B>\s*)(<28>arrayindex\d+<2B>\s*)+} {content classblock block}
extract identifier {<7B>array\d+<2B>} {content classblock block}
# extract assignments
extract identifier {(?=(\s*|;))(<28>star\d+<2B>\s*)*<2A>identifier\d+<2B>\s*<2A>assign\w*\d+<2B>[^;]*} block
# extract throw statements
extract identifier {(?=(\s*|;))<29>keythrow\d+<2B>\s*[^;]*} block
# extract stream operators
#extract lhidentifier {(?=(\s*|;))[^;]*?<3F>(lshift|rshift)\d+<2B>[^;]*} block
# extract uses of the new operator
extract identifier {<7B>keynew\d+<2B>\s*(<28>parenblk\d+<2B>\s*)?<3F>function\d+<2B>} block
# extract return statements
extract return {<7B>keyreturn\d+<2B>[^;]*} {block}
# extract modifiers
extract modifier {(<28>key(extern|externc|const|static|inline|virtual|volatile)\d+<2B>\s*)+} {content classblock block}
# extract function declarations
extract funcdecl {(<28>mlcomment\d+<2B> *\n[ \t]*)?(<28>(modifier|keyunsigned)\d+<2B>\s*)*<2A>(identifier|keyunsigned)\d+<2B>(\s|(<28>amper\d+<2B>)|(<28>star\d+<2B>))*<2A>(operator)?function\d+<2B>\s*(<28>modifier\d+<2B>\s*)*(<28>assign\d+<2B>\s*<2A>identifier\d+<2B>)?\s*;} {content block classblock}
# extract function implementations
extract funcimpl {(<28>mlcomment\d+<2B> *\n[ \t]*)?(<28>(modifier|keyunsigned)\d+<2B>\s*)?<3F>(identifier|keyunsigned)\d+<2B>(\s|(<28>amper\d+<2B>)|(<28>star\d+<2B>))*<2A>(operator)?function\d+<2B>\s*(<28>modifier\d+<2B>\s*)?<3F>block\d+<2B>[;\t ]*} {content block classblock}
extract funcimpl {(<28>mlcomment\d+<2B> *\n[ \t]*)?<3F>operatorfunction\d+<2B>\s*(<28>modifier\d+<2B>\s*)?<3F>block\d+<2B>[;\t ]*} {content block classblock}
# extract function implementations
extract funcimpl {(<28>mlcomment\d+<2B> *\n[ \t]*)?(<28>(modifier|keyunsigned)\d+<2B>\s*)?<3F>(identifier|keyunsigned)\d+<2B>(\s|(<28>amper\d+<2B>)|(<28>star\d+<2B>))*<2A>(operator)?function\d+<2B>\s*(<28>modifier\d+<2B>\s*)?<3F>block\d+<2B>[;\t ]*} {content block classblock}
# extract template functions
extract tplfunc {(<28>mlcomment\d+<2B> *\n[ \t]*)?<3F>keytemplate\d+<2B>\s*<2A>tplargs\d+<2B>\s*<2A>funcimpl\d+<2B>} {content block classblock}
# extract template functions declarations
extract tplfuncdecl {(<28>mlcomment\d+<2B> *\n[ \t]*)?<3F>keytemplate\d+<2B>\s*<2A>tplargs\d+<2B>\s*<2A>funcdecl\d+<2B>} {content block classblock}
# extract destructor implementations
extract destimpl {(<28>mlcomment\d+<2B> *\n[ \t]*)?(<28>modifier\d+<2B>\s*)?<3F>tilde\d+<2B><>function\d+<2B>\s*<2A>block\d+<2B>[;\t ]*} {content classblock}
refine_sub_tokens destimpl destfunction function
# extract constructor implementations
extract constimpl {(<28>mlcomment\d+<2B> *\n[ \t]*)?(<28>(modifier|keyexplicit)\d+<2B>\s*)*<2A>function\d+<2B>\s*(<28>initializer\d+<2B>\s*)?\s*<2A>block\d+<2B>[;\t ]*} {content classblock}
# extract destructor declarations
extract destdecl {(<28>mlcomment\d+<2B> *\n[ \t]*)?(<28>modifier\d+<2B>\s*)?<3F>tilde\d+<2B><>function\d+<2B>\s*(<28>assign\d+<2B>\s+<2B>identifier\d+<2B>)?\s*;} {classblock}
# extract constructor declarations
extract constdecl {(<28>mlcomment\d+<2B> *\n[ \t]*)?(<28>keyexplicit\d+<2B>[ \t]*)?<3F>function\d+<2B>\s*(<28>assign\d+<2B>\s+<2B>identifier\d+<2B>)?\s*;} {classblock}
# extract friendship declarations
extract frienddecl {<7B>keyfriend\d+<2B>\s*<2A>classdecl\d+<2B>} {classblock}
# classify function signatures and their containing argument-parenthesis blocks
foreach env_type [list destdecl constdecl destimpl constimpl funcimpl funcdecl] {
refine_sub_tokens $env_type function funcsignature }
refine_sub_tokens funcsignature parenblk argparenblk
extract_operations parenblk
extract modifier {(<28>key(const|volatile)\d+<2B>\s*)+} {argparenblk}
# extract pure-virtual assignments
extract virtassign {<7B>assign\d+<2B>\s+<2B>identifier\d+<2B>} funcdecl
# extract return values
extract retval {(<28>keyunsigned\d+<2B>\s*)*(<28>(identifier|keyunsigned)\d+<2B>)(\s|(<28>amper\d+<2B>)|(<28>star\d+<2B>))*} {funcdecl funcimpl}
extract identifier {<7B>keyunsigned\d+<2B>\s*(<28>identifier\d+<2B>)?} {retval}
# extract single argument declarations within argument-parenthesis blocks
extract argdecl {(<28>(modifier|keyunsigned)\d+<2B>\s*)*(<28>(identifier|keyunsigned)\d+<2B>)(\s|(<28>amper\d+<2B>)|(<28>star\d+<2B>))*(<28>modifier\d+<2B>\s*)*<2A>identifier\d+<2B>} {argparenblk tplargs}
extract argname {<7B>identifier\d+<2B>$} {argdecl}
extract argtype {^(<28>(modifier|keyunsigned)\d+<2B>\s*)*(<28>(identifier|keyunsigned)\d+<2B>)(\s|(<28>amper\d+<2B>)|(<28>star\d+<2B>))*(<28>modifier\d+<2B>\s*)*} {argdecl}
# extract argument-declaration types
extract argdecltype {^<5E>(identifier|keyunsigned)\d+<2B>(\s|(<28>amper\d+<2B>)|(<28>star\d+<2B>))*} argdecl
# extract typedefs
extract typedef {(<28>mlcomment\d+<2B> *\n[ \t]*)?<3F>keytypedef\d+<2B>(\s*<2A>identifier\d+<2B>)+\s*;} {content classblock block}
extract typename {<7B>identifier\d+<2B>(?=;)} typedef
# extract function pointers
extract vardecl {(<28>(modifier|keyunsigned)\d+<2B>\s*)*(<28>(identifier|keyunsigned)\d+<2B>)((\s|(<28>amper\d+<2B>)|(<28>star\d+<2B>))*(<28>modifier\d+<2B>\s*)*(<28>funcptr\d+<2B>)\s*(:\s*<2A>identifier\d+<2B>)?\s*(<28>assign\d+<2B>[^;]*?)?\s*(<28>comma\d+<2B>)?\s*)+;} {content classblock block}
# extract variable declarations (type + any number of comma-separated variables + optional tailing comment)
extract vardecl {(<28>(modifier|keyunsigned)\d+<2B>\s*)*(<28>(identifier|keyunsigned)\d+<2B>)((\s|(<28>amper\d+<2B>)|(<28>star\d+<2B>))*(<28>modifier\d+<2B>\s*)*(<28>(identifier|array)\d+<2B>)\s*(:\s*<2A>identifier\d+<2B>)?\s*(<28>assign\d+<2B>[^;]*?)?\s*(<28>comma\d+<2B>)?\s*)+;} {content classblock block}
# extract commented variable declaration
extract commentedvardecl {<7B>vardecl\d+<2B>\s*<2A>m?lcomment\d+<2B>(\s*<2A>lcomment\d<>)*} {content classblock block}
# extract valid declaration sequences
set elem "(mlcomment|lcomment|vardecl|array|commentedvardecl|typedef|funcimpl|funcdecl|enum|class|struct|union|constimpl|constdecl|destimpl|destdecl|tplfunc|tplfuncdecl|tplstruct|tplstructdecl|tplclass|tplclassdecl|frienddecl|classdecl|structdecl)"
extract declseq "<22>$elem\\d+<2B>(\\s*<2A>$elem\\d+<2B>)*" {classblock}
# group protection scopes with corresponding declaration sequences
foreach keyword { private public protected } {
set label label
extract $keyword "<22>$keyword$label\\d+<2B>\\s*<2A>declseq\\d+<2B>" {classblock} }
# extract protection-scope labels
extract label {<7B>key(private|public|protected)\d+<2B>:} {private public protected}
# extract name spaces
extract namespace {<7B>keynamespace\d+<2B>\s*<2A>identifier\d+<2B>\s*<2A>block\d+<2B>} {content block}
refine_sub_tokens namespace block namespaceblock
#
# The remaining block tokens are code blocks. So we can
# apply code-specific rules to them.
#
extract identifier {<7B>function\d+<2B>} block
extract_operations {block identifier}
# extract statements from remaining code blocks
extract statement {<7B>asm\d+<2B>;} block
extract statement {<7B>identifier\d+<2B>;} block
extract statement {<7B>return\d+<2B>;} {block}
extract statement {<7B>keycontinue\d+<2B>\s*;} block
# extract try-catch statements
extract statement {<7B>keytry\d+<2B>\s*<2A>block\d+<2B>(\s*<2A>catchcond\d+<2B>\s*<2A>block\d+<2B>)+} {block}
# wrap blocks into statements
extract statement {<7B>block\d+<2B>} {block statement}
# empty statements (all normal semicolons should be encapsulated in statements now)
extract statement {;} {block}
# turn control structures into statements
set pattern_ifelse {(<28>ifcond\d+<2B>(\s|<7C>m?lcomment\d+<2B>)*<2A>statement\d+<2B>(\s|<7C>m?lcomment\d+<2B>)*<2A>keyelse\d+<2B>(\s|<7C>m?lcomment\d+<2B>)*<2A>statement\d+<2B>)}
set pattern_if {(<28>ifcond\d+<2B>(\s|<7C>m?lcomment\d+<2B>)*<2A>statement\d+<2B>(?!(\s|<7C>m?lcomment\d+<2B>)*<2A>keyelse))}
set pattern_for {(<28>(while|for|switch)cond\d+<2B>(\s|<7C>m?lcomment\d+<2B>)*<2A>statement\d+<2B>)}
extract statement "($pattern_ifelse|$pattern_if|$pattern_for)" {block statement}
# extract control-structure types
extract ifelse $pattern_ifelse {statement}
extract if $pattern_if {statement}
extract for {<7B>forcond\d+<2B>(\s|<7C>m?lcomment\d+<2B>)*(<28>statement\d+<2B>|;)} {statement}
extract while {<7B>whilecond\d+<2B>(\s|<7C>m?lcomment\d+<2B>)*(<28>statement\d+<2B>|;)} {statement}
extract switch {<7B>switchcond\d+<2B>(\s|<7C>m?lcomment\d+<2B>)*<2A>statement\d+<2B>} {statement}
# turn control-flow element into statements
foreach type { ifelse if while for switch try } {
extract statement "<22>$type\\d+<2B>" block }
# extract valid code sequences
set elem "(mlcomment|vardecl|statement|lcomment)"
extract codeseq "<22>$elem\\d+<2B>(\\s*<2A>$elem\\d+<2B>)*" {block}
#
# Extract line breaks, spaces, and tabs from all types
#
if {$config_whitespace} {
set all_types ""
for {set i 0} {$i < $num} {incr i} {
if {[lsearch $all_types $typ($i)] == -1} {
lappend all_types $typ($i) }}
extract line {\n} $all_types
extract align { +(?= )} $all_types
extract space { } $all_types
extract tab {\t} $all_types
}
###############################
## Back-end helper functions ##
###############################
##
# Return name of reference token with specified index
##
proc token_by_idx {idx} {
global typ;
return "$typ($idx)$idx"
}
##
# Return index of specified reference token
##
proc idx_of_token {token} {
regexp {[0-9]+} $token idx
return $idx
}
##
# Return type of specified reference token
##
proc type_of_token {token} {
regexp {[a-z]+} $token type
return $type
}
##
# Return marker for reference token
##
proc marker {token} {
return "<22>$token<65>"
}
##
# Return text referenced by token
##
proc token_text {token} {
global txt
return $txt([idx_of_token $token])
}
##
# Assign a line number to each reference token
#
# To be able to provide error messages including line numbers, we
# determine the line number for each reference token and store it
# as an attribute.
#
# The result of the function is stored in the global 'ln' array.
##
proc assign_line_numbers {{token content0}} {
global ln curr_ln config_whitespace
if {$token == "content0"} { set curr_ln 1 }
# assign current line number to current token
set ln([idx_of_token $token]) $curr_ln
# count occurrences of line breaks
if {[type_of_token $token] == "line"} { incr curr_ln }
if {!$config_whitespace && ($token == "\n")} { incr curr_ln }
# count lines for all sub-tokens
set tex [token_text $token]
while {$tex != ""} {
# count and eat raw line breaks (needed if 'whitespace' option is disabled)
if {[regexp {^\n} $tex dummy]} {
if {!$config_whitespace} { incr curr_ln }
regsub {\n} $tex "" tex
}
# ignore plain text
if {[regexp {^[^<5E>\n]+} $tex plain]} {
regsub {^[^<5E>\n]+} $tex "" tex }
# traverse into token
if {[regexp {^<5E>(.+?)<29>} $tex dummy token]} {
assign_line_numbers $token
regsub {<7B>(.+?)<29>} $tex "" tex
}
}
}
##
# Look up line number of specified reference token
##
proc line_number {token} {
global ln
return $ln([idx_of_token $token])
}
##
# Output tokens as valid Tcl List
#
# The result of this function can be used directly
# as input by another Tcl script.
##
proc dump_tokens { } {
global num typ txt
set tokens [list]
for {set i 0} {($i < $num)} {incr i} {
set token [token_by_idx $i]
set text $txt($i)
lappend tokens [list $token [line_number $token] $text]
}
puts $tokens
}
##########################
## Source-code back end ##
##########################
##
# Output syntax tree as source code
#
# This constructs the source code from the syntax tree. It is
# useful to check the result against the input to make sure that
# no information gets lost during the parsing procedure.
##
proc dump_source { } {
global num typ txt
set output $txt(0)
while {[regexp {<7B>(.+?)<29>} $output dummy token]} {
regsub $dummy $output [token_text $token] output
}
# revert character substitutions of '&'
regsub -all {<7B>} $output "\\\&" output
puts $output
}
##################
## XML back end ##
##################
proc dump_xml_subtree {token} {
global dump_xml_indent line
set type [type_of_token $token]
set tex [token_text $token]
set line [line_number $token]
# shorten frequent leaf nodes
if {$type == "line"} {
puts "$dump_xml_indent<linebreak line=\"$line\"/>"
} elseif {$type == "tab"} {
puts "$dump_xml_indent<tab line=\"$line\"/>"
} elseif {$type == "space"} {
puts "$dump_xml_indent<space line=\"$line\"/>"
} elseif {$type == "align"} {
puts "$dump_xml_indent<align line=\"$line\">$tex</align>"
} else {
puts "$dump_xml_indent<$type line=\"$line\">"
set dump_xml_indent " $dump_xml_indent"
while {$tex != ""} {
# consume plain text
if {[regexp {^[^<5E>]+} $tex plain]} {
# perform character substitutions for xml compliance
regsub -all {<7B>} $plain "\\\&amp;" plain
regsub -all {<} $plain "\\\&lt;" plain
regsub -all {>} $plain "\\\&gt;" plain
regsub -all "\"" $plain "\\\&quot;" plain
regsub -all "'" $plain "\\\&apos;" plain
puts "$dump_xml_indent<plain line=\"$line\">$plain</plain>"
regsub {^[^<5E>]+} $tex "" tex
}
# consume token
if {[regexp {<7B>(.+?)<29>} $tex dummy token]} {
dump_xml_subtree $token
regsub {<7B>(.+?)<29>} $tex "" tex
}
}
regsub " " $dump_xml_indent "" dump_xml_indent
puts "$dump_xml_indent</$type>"
}
}
##
# Output syntax tree as xml
##
proc dump_xml { } {
# reset indentation level
global dump_xml_indent
set dump_xml_indent ""
# output subtree beginning with the root node
dump_xml_subtree content0
}
##################
## Main program ##
##################
assign_line_numbers
if {$config_out_tokens} { dump_tokens }
if {$config_out_xml} { dump_xml }
if {$config_out_source} { dump_source }

484
tool/run Executable file
View File

@@ -0,0 +1,484 @@
#!/usr/bin/expect
#
# \brief Framework for running automated tests
# \author Norman Feske
# \date 2010-03-16
#
# Usage: run --name <run_name> --include <run_script> ...
#
# The '--name' argument is used for as name for the boot-image and
# temporary directories. The files includes via the '--include'
# argument provide platform-specific additions/refinements to the
# test framework as well as the actual test steps.
#
##
# Remove leading and trailing whitespace from string
#
proc strip_whitespace {string} {
regsub -all {^\s+} $string "" string
regsub -all {\s+$} $string "" string
return $string
}
##
# Check if the specified spec requirement is satisfied
#
proc assert_spec {spec} {
global specs
if {[lsearch $specs $spec] == -1} {
puts stderr "Test requires '$spec'"
exit 0
}
}
##
# Build genode targets specified as space-separated strings
#
# If the build process fails, this procedure will exit the program with
# the error code -4.
#
proc build {targets} {
if {[get_cmd_switch --skip-build]} return
regsub -all {\s\s+} $targets " " targets
puts "building targets: $targets"
set timeout 10000
set pid [eval "spawn make $targets"]
expect { eof { } }
if {[lindex [wait $pid] end] != 0} {
puts "Error: Genode build failed"
exit -4
}
puts "genode build completed"
}
##
# Create a fresh boot directory
#
proc create_boot_directory { } { }
##
# Append string to variable only if 'condition' is satisfied
#
proc append_if {condition var string} {
global $var
if {$condition} { append $var $string }
}
##
# Append element to list only if 'condition' is satisfied
#
proc lappend_if {condition var string} {
global $var
if {$condition} { lappend $var $string }
}
##
# Install content of specfied variable as init config file
#
proc install_config {config} {
set fh [open "[run_dir]/genode/config" "WRONLY CREAT TRUNC"]
puts $fh $config
close $fh
}
##
# Integrate specified binaries into boot image
#
# \param binaries space-separated list of file names located within the
# '<build-dir>/bin/' directory
#
# This function should be implemented by a platform-specific file
# included via the '--include' argument.
#
proc build_boot_image {binaries} { }
##
# Execute Genode
#
# \param wait_for_re regular expression that matches the test completion
# \param timeout_value timeout in seconds
# \global output contains the core output (modified)
#
# If the function is called without any argument, Genode is executed in
# interactive mode.
#
# If the test execution times out, this procedure will exit the program with
# the error code -2.
#
# This function must be implemented by the platform-specific test environment.
# If not implemented, the program exits with the error code -3.
#
proc run_genode_until {{wait_for_re forever} {timeout_value 0}} {
puts stderr "Error: 'run_genode_until' is not implemented for this platform"
exit -3
}
##
# Filter output based on the specified pattern
#
# Only those lines that match the pattern are preserved.
#
proc grep_output {pattern} {
global output
regsub -all {[\r\n]+} $output "\n" output
set output_list [split $output "\n"]
set filtered ""
foreach line $output_list {
if {[regexp $pattern $line]} {
append filtered "$line\n"
}
}
set output $filtered
}
##
# Unify known variations that appear in the test output
#
# \global output test output (modified)
#
proc unify_output {pattern replacement} {
global output
regsub -all $pattern $output $replacement output
}
##
# Compare output against expected output line by line
#
# \param good expected test output
# \global output test output
#
# This procedure will exit the program with the error code -1 if the
# comparison fails.
#
proc compare_output_to { good } {
global output
set output_list [split [strip_whitespace $output] "\n"]
set good_list [split [strip_whitespace $good] "\n"]
set i 0
set mismatch_cnt 0
foreach good_line $good_list {
set output_line [strip_whitespace [lindex $output_list $i]]
set good_line [strip_whitespace $good_line]
if {$output_line != $good_line} {
puts ""
puts stderr "Line $i of output is unexpected"
puts stderr " expected: '$good_line'"
puts stderr " got: '$output_line'"
incr mismatch_cnt
}
incr i
}
if {$mismatch_cnt > 0} {
puts "Error: Test failed, $mismatch_cnt unexpected lines of output"
exit -1
} else {
puts "Test succeeded"
}
}
##
# Return true if command-line switch was specified
#
proc get_cmd_switch { arg_name } {
global argv
return [expr [lsearch $argv $arg_name] >= 0]
}
##
# Return command-line argument value
#
# If a argument name is specified multiple times, a
# list of argument values is returned.
#
proc get_cmd_arg { arg_name default_value } {
global argv
# find argument name in argv list
set arg_idx_list [lsearch -all $argv $arg_name]
if {[llength $arg_idx_list] == 0} { return $default_value }
set result {}
foreach arg_idx $arg_idx_list {
set next_idx [expr $arg_idx + 1]
# stop if argv ends with the argument name
if {$next_idx >= [llength $argv]} continue
# return list element following the argument name
lappend result [lindex $argv $next_idx]
}
# if argument occurred only once, return its value
if {[llength $result] == 1} { return [lindex $result 0] }
# if argument occurred multiple times, contain list of arguments
return $result
}
#
# Read command-line arguments
#
set run_name [get_cmd_arg --name "noname"]
set genode_dir [get_cmd_arg --genode-dir ""]
set cross_dev_prefix [get_cmd_arg --cross-dev-prefix ""]
set specs [get_cmd_arg --specs ""]
set repositories [get_cmd_arg --repositories ""]
set qemu_args [get_cmd_arg --qemu-args ""]
#
# Enable run scripts to extend 'qemu_arg' via 'append' without bothering
# about the required whitespace in front of the custom arguments.
#
append qemu_args " "
# accessor functions for command-line arguments
proc run_name { } { global run_name; return $run_name }
proc run_dir { } { global run_name; return var/run/$run_name }
proc genode_dir { } { global genode_dir; return $genode_dir }
proc cross_dev_prefix { } { global cross_dev_prefix; return $cross_dev_prefix }
# set expect match-buffer size
match_max -d 20000
##
# Return true if spec value is set for the build
#
proc have_spec {spec} { global specs; return [expr [lsearch $specs $spec] != -1] }
##
# Return true if specified program is installed
#
proc have_installed {program} {
if {[catch { exec which $program }]} { return false; }
return true
}
##
# Return true if specified program is installed on the host platform
#
proc requires_installation_of {program} {
if {![have_installed $program]} {
puts "Run script aborted because $program is not installed"; exit
}
}
##
# Return first repository containing the given path
#
proc repository_contains {path} {
global repositories;
foreach i $repositories {
if {[file exists $i/$path]} { return $i }
}
}
##
## Utilities for performing steps that are the same on several platforms
##
##
# Read kernel location from build-directory configuration
#
# If config file does not exist or if there is no 'KERNEL' declaration in the
# config file, the function returns 'default_location'. If the config file
# points to a non-existing kernel image, the function aborts with the exit
# value -6.
#
proc kernel_location_from_config_file { config_file default_location } {
global _kernel
if {![info exists _kernel]} {
if {[file exists $config_file]} {
set _kernel [exec sed -n "/^KERNEL/s/^.*=\\s*//p" $config_file]
# check if the regular expression matched
if {$_kernel != ""} {
if {[file exists $_kernel]} {
return $_kernel
} else {
puts stderr "Error: kernel specified in '$config_file' does not exist"
exit -6
}
}
}
# try to fall back to version hosted with the Genode build directory
set _kernel $default_location
}
return $_kernel
}
##
# Install files needed to create a bootable ISO image
#
# The ISO boot concept uses isolinux to load GRUB, which in turn loads Genode.
# This way we can make use of isolinux' support for booting ISO images from a
# USB stick.
#
proc install_iso_bootloader_to_run_dir { } {
exec mkdir -p [run_dir]/boot/isolinux
exec cp [genode_dir]/tool/boot/chain.c32 [run_dir]/boot/isolinux
exec cp [genode_dir]/tool/boot/isolinux.bin [run_dir]/boot/isolinux
exec cp [genode_dir]/tool/boot/isolinux.cfg [run_dir]/boot/isolinux
exec mkdir -p [run_dir]/boot/grub
exec cp [genode_dir]/tool/boot/stage2_eltorito [run_dir]/boot/grub
}
##
# Copy the specified binaries from the 'bin/' directory to the run
# directory and try to strip executables.
#
proc copy_and_strip_genode_binaries_to_run_dir { binaries } {
foreach binary $binaries {
exec cp bin/$binary [run_dir]/genode
catch {
exec [cross_dev_prefix]strip [run_dir]/genode/$binary || true }
}
}
##
# Create ISO image with the content of the run directory
#
proc create_iso_image_from_run_dir { } {
puts "creating ISO image..."
exec rm -f "[run_dir].iso"
#
# The 'create_iso' tool returns a non-zero return code even if
# successful. So we ignore the return code here.
#
catch { exec [genode_dir]/tool/create_iso iso ISO=[run_dir] }
if {![file exists "[run_dir].iso"]} {
puts stderr "Error: ISO image creation failed"
exit -5
}
}
##
# Execute scenario using Qemu
#
proc spawn_qemu { wait_for_re timeout_value } {
global output
global qemu_args
global qemu
global spawn_id
set qemu "qemu"
# use special qemu versions for non x86_32 architectures
if {[have_spec x86_64]} { set qemu "qemu-system-x86_64" }
if {[have_spec arm]} { set qemu "qemu-system-arm" }
#
# Only the x86_64 variant of Qemu provides the emulation of hardware
# virtualization features used by NOVA. So let's always stick to this
# varient of Qemu when working with NOVA even when operating in 32bit.
#
if {[have_spec nova]} { set qemu "qemu-system-x86_64" }
#
# Redirect serial output to stdio, but only in graphics mode and no
# explicit configuration of serial interfaces is specified in the run
# script. The 'mon' prefix enables the access to the qemu console.
#
if {![regexp -- {-nographic} $qemu_args dummy] &&
![regexp -- {-serial} $qemu_args dummy]} {
append qemu_args " -serial mon:stdio " }
# tweak emulated platform for specific platforms
if {[have_spec platform_pbxa9]} { append qemu_args " -M realview-pbx-a9 -m 256 " }
if {[have_spec platform_vpb926]} { append qemu_args " -M versatilepb -m 128 " }
if {[have_spec platform_vea9x4]} { append qemu_args " -M vexpress-a9 -cpu cortex-a9 -m 256 " }
# on x86, we supply the boot image as ISO image
if {[have_spec x86]} { append qemu_args " -cdrom [run_dir].iso " }
# on ARM, we supply the boot image as kernel
if {[have_spec arm]} { append qemu_args " -kernel [run_dir]/image.elf " }
set timeout $timeout_value
set pid [eval "spawn $qemu $qemu_args"]
if {$wait_for_re == "forever"} { interact $pid }
expect {
-re $wait_for_re { }
timeout { puts stderr "Error: Test execution timed out"; exit -2 }
}
set output $expect_out(buffer)
}
##
# Determine terminal program
#
proc terminal { } {
global env
if {[info exists env(COLORTERM)]} {
return $env(COLORTERM)
}
return $env(TERM)
}
##
# Determine GDB executable installed at the host
#
proc gdb { } {
if {[have_installed "[cross_dev_prefix]gdb"]} {
return "[cross_dev_prefix]gdb" }
if {[have_installed gdb]} {
return "gdb" }
requires_installation_of gdb
}
##
## Execution of run scripts
##
#
# Read and execute files specified as '--include' arguments
#
foreach include_name [get_cmd_arg --include ""] {
puts "using run script $include_name"
source $include_name
}

579
tool/tool_chain Executable file
View File

@@ -0,0 +1,579 @@
#!/usr/bin/make -f
#
# \brief Tool-chain creation tool for the Genode OS Framework
# \author Norman Feske
# \date 2009-02-03
#
help:
$(ECHO)
$(ECHO) "Build tool chain for the Genode OS Framework"
$(ECHO)
$(ECHO) "The tool chain consists of GCC $(GCC_VERSION) and binutils $(BINUTILS_VERSION)"
$(ECHO) "and will be created at '$(LOCAL_INSTALL_LOCATION)'."
$(ECHO)
$(ECHO) "--- available commands ---"
$(ECHO) "x86 - create tool chain for x86"
$(ECHO) "arm - create tool chain for arm"
$(ECHO) "clean - clean everything except downloaded archives"
$(ECHO) "cleanall - clean everything including downloaded archives"
$(ECHO) "install - copy tool chain to '$(INSTALL_LOCATION)'"
$(ECHO)
#
# User interface
#
SUPPORTED_PLATFORMS := x86 microblaze arm
PLATFORM := $(firstword $(filter $(SUPPORTED_PLATFORMS),$(MAKECMDGOALS)))
$(SUPPORTED_PLATFORMS): install
#
# Enable parallel build for 2nd-level $(MAKE) by default
#
MAKE_OPT ?= -j4
#
# Determine Genode base directory based on the known location of the
# 'create_builddir' tool within the Genode source tree
#
GENODE_DIR ?= $(realpath $(dir $(MAKEFILE_LIST))/..)
#
# Download locations
#
DOWNLOAD_MIRROR ?= ftp://ftp.fu-berlin.de
GCC_DOWNLOAD_URL = $(DOWNLOAD_MIRROR)/gnu/gcc
BINUTILS_DOWNLOAD_URL = $(DOWNLOAD_MIRROR)/gnu/binutils
GDB_DOWNLOAD_URL = $(DOWNLOAD_MIRROR)/gnu/gdb
GMP_DOWNLOAD_URL = $(DOWNLOAD_MIRROR)/gnu/gmp
MPFR_DOWNLOAD_URL = $(DOWNLOAD_MIRROR)/gnu/mpfr
MPC_DOWNLOAD_URL ?= http://www.multiprecision.org/mpc/download
#
# Tool versions and install location
#
GCC_VERSION = 4.6.1
BINUTILS_VERSION = 2.21.1
GDB_VERSION = 7.3.1
GMP_VERSION = 5.0.2
MPFR_VERSION = 3.1.0
MPC_VERSION = 0.9
INSTALL_LOCATION = /usr/local/genode-gcc
DOWNLOAD_DIR = download
CONTRIB_DIR = contrib
BINUTILS_DOWNLOAD_TBZ2 = binutils-$(BINUTILS_VERSION).tar.bz2
# download file name differs from dir name found within the archive
ifeq ($(BINUTILS_VERSION),2.21.1)
BINUTILS_DOWNLOAD_TBZ2 = binutils-$(BINUTILS_VERSION)a.tar.bz2
endif
#
# Utilities
#
SHELL = bash
BRIGHT_COL = \033[01;33m
DEFAULT_COL = \033[0m
ECHO = @echo -e
VERBOSE = @
AUTOCONF_gcc_4.4.5 = autoconf2.59
AUTOCONF_gcc_4.6.1 = autoconf2.64
AUTOCONF = $(AUTOCONF_gcc_$(GCC_VERSION))
ifeq ($(AUTOCONF),)
$(error Unknown autoconf version for GCC $(GCC_VERSION).)
endif
ifeq ($(shell which $(AUTOCONF)),)
$(error Need to have $(AUTOCONF) installed.)
endif
ifeq ($(shell which autogen)),)
$(error Need to have autogen installed.)
endif
#
# Libc stub
#
LIBC_GEN_SYMLINKS = \
stdint.h memory.h string.h stdlib.h unistd.h errno.h wchar.h \
ctype.h strings.h wctype.h math.h stdio.h dlfcn.h inttypes.h \
malloc.h signal.h fcntl.h assert.h locale.h setjmp.h time.h \
link.h gnu-versions.h elf.h
LIBC_GEN_SYS_SYMLINKS = types.h stat.h sem.h
LIBC_DIR = $(shell pwd)/build/libc/include
LIBC_STUB_H = $(GENODE_DIR)/tool/libgcc_libc_stub.h
LIBC = $(addprefix $(LIBC_DIR)/,$(LIBC_GEN_SYMLINKS)) \
$(addprefix $(LIBC_DIR)/sys/,$(LIBC_GEN_SYS_SYMLINKS))
$(LIBC_DIR) $(LIBC_DIR)/sys:
$(VERBOSE)mkdir -p $@
$(addprefix $(LIBC_DIR)/,$(LIBC_GEN_SYMLINKS)): $(LIBC_DIR)
$(VERBOSE)ln -sf $(LIBC_STUB_H) $@
$(addprefix $(LIBC_DIR)/sys/,$(LIBC_GEN_SYS_SYMLINKS)): $(LIBC_DIR)/sys
$(VERBOSE)ln -sf $(LIBC_STUB_H) $@
#
# 'configure' parameters for binutils, gcc and gdb
#
LOCAL_INSTALL_LOCATION = $(shell pwd)/build/install
#
# Local install location for gmp, mpfr, and mpc libraries. These libraries are
# requried at build time of gcc. We install them locally before invoking the
# gcc build. Because the libs do not need to be included in the tool-chain
# package (they are statically linked against gcc), we install them to a
# different install location as gcc.
#
LOCAL_LIB_INSTALL_LOCATION = $(shell pwd)/build/lib-install
TARGET_NAME_x86 = x86_64-elf
TARGET_NAME_microblaze = microblaze-elf
TARGET_NAME_arm = arm-elf-eabi
ifneq ($(VERBOSE),)
CONFIG_QUIET = --quiet
MAKEFLAGS += --quiet
export MAKEFLAGS
endif
COMMON_CONFIG = $(CONFIG_QUIET) \
--prefix=$(LOCAL_INSTALL_LOCATION) \
--program-prefix=genode-$(PLATFORM)- \
--target=$(TARGET_NAME_$(PLATFORM)) \
--program-transform-name="s/$(TARGET_NAME_$(PLATFORM))/$(PLATFORM)/"
BINUTILS_CONFIG += $(COMMON_CONFIG) --disable-werror
#
# Prevent GNU assembler from treating '/' as the start of a comment. In
# 'gas/config/tc-i386.c', the policy of handling '/' is defined. For Linux, '/'
# is treated as division, which we expect. To apply this needed policy for our
# plain 'elf' version gas, we supply the definition of 'TE_LINUX' by hand.
# Fortunately, this define is not used outside of gas.
#
BINUTILS_CONFIG += CFLAGS=-DTE_LINUX
#
# Add platform-specific binutils configure arguments
#
BINUTILS_CONFIG += $(BINUTILS_CONFIG_$(PLATFORM))
#
# Dummy libc symbols to resolve unresolved references when linking
# 'libgcc_s.so'. Even though, this library is not used on Genode, we want the
# link command to succeed to complete the build process.
#
DUMMY_LIBC_SYMS = strlen free memcpy malloc memset abort dl_iterate_phdr
LD_PREFIX = -Wl,
LD_DEFSYM_DUMMY_LIBC = $(addprefix $(LD_PREFIX)--defsym=,$(addsuffix =0,$(DUMMY_LIBC_SYMS)))
GCC_CONFIG += $(COMMON_CONFIG) \
--with-gnu-as --with-gnu-ld --disable-tls --disable-threads \
--disable-libstdcxx-pch \
--enable-shared \
--with-gmp=$(LOCAL_LIB_INSTALL_LOCATION) \
--with-mpfr=$(LOCAL_LIB_INSTALL_LOCATION) \
--with-mpc=$(LOCAL_LIB_INSTALL_LOCATION) \
CPPFLAGS_FOR_TARGET=-I$(LIBC_DIR) \
CFLAGS_FOR_TARGET="-I$(LIBC_DIR) -nostdlib $(LD_DEFSYM_DUMMY_LIBC) -fPIC"
GCC_CONFIG += $(GCC_CONFIG_$(PLATFORM))
#
# Configure options passed to gcc
#
# The 't-linux' tmake file is needed to let the tool chain use 'unwind-dw2-fde-glibc',
# needed for the exception handling on Genode in the presence of shared libraries.
#
HOST_CONFIG_ARGS = $(CONFIG_QUIET) \
host_xm_include_list=$(LINK_SPEC_H_$(PLATFORM)) \
tmake_file='t-slibgcc-elf-ver t-slibgcc-nolc-override t-linux'
# passed to target components such as libgcc, libstdc++
TARGET_CONFIG_ARGS = $(CONFIG_QUIET) \
extra_parts='crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o'
# compile libsupc++ as position-independent code
TARGET_CONFIG_ARGS += LIBSUPCXX_PICFLAGS='-prefer-pic'
GCC_INSTALL_RULE = install-strip
ifeq ($(GCC_VERSION),4.4.5)
GCC_INSTALL_RULE = install
endif
#
# Default linker script
#
# Needed only to make target-configure happy.
#
LD_SCRIPT_microblaze = $(LOCAL_INSTALL_LOCATION)/$(TARGET_NAME_microblaze)/lib/xilinx.ld
$(LD_SCRIPT_$(PLATFORM)):
$(VERBOSE)mkdir -p $(dir $@)
$(VERBOSE)touch $@
#
# Link spec
#
# The 'LINK_SPEC' define comprises the rules of how the GCC frontend invokes
# the linker.
#
LINK_SPEC_H_x86 = $(shell pwd)/build/$(PLATFORM)/link_spec.h
$(LINK_SPEC_H_x86):
$(VERBOSE)echo "#define LINK_SPEC \"%{!m32:-m elf_x86_64} %{m32:-m elf_i386} %{shared:-shared} %{!static:--eh-frame-hdr}\"" > $@
$(LINK_SPEC_H_arm):
$(VERBOSE)echo "#define LINK_SPEC \"%(shared:-shared) %{!static:--eh-frame-hdr}\"" > $@
#
# Platform-specific multilib support
#
MAKE_OPT_x86 := MULTILIB_OPTIONS="m64/m32" MULTILIB_DIRNAMES="64 32"
MAKE_OPT += $(MAKE_OPT_$(PLATFORM))
#
# Build rules and dependencies between build steps
#
# We use the binaries 'objdump' and 'g++' as representatives for expressing
# dependencies. All other programs will be generated as side effect.
#
BINUTILS_BINARIES = build/$(PLATFORM)/binutils/binutils/objdump
BINUTILS_INSTALLED_BINARIES = $(LOCAL_INSTALL_LOCATION)/bin/genode-$(PLATFORM)-objdump
GCC_BINARIES = build/$(PLATFORM)/gcc/gcc/g++
GCC_INSTALLED_BINARIES = $(LOCAL_INSTALL_LOCATION)/bin/genode-$(PLATFORM)-g++
GDB_BINARIES = build/$(PLATFORM)/gdb/gdb/gdb
GDB_INSTALLED_BINARIES = $(LOCAL_INSTALL_LOCATION)/bin/genode-$(PLATFORM)-gdb
build_all: $(GCC_INSTALLED_BINARIES) $(GDB_INSTALLED_BINARIES)
$(DOWNLOAD_DIR):
$(VERBOSE)mkdir -p $@
$(DOWNLOAD_DIR)/$(BINUTILS_DOWNLOAD_TBZ2): $(DOWNLOAD_DIR)
$(ECHO) "$(BRIGHT_COL)downloading binutils...$(DEFAULT_COL)"
$(VERBOSE)wget -c -P $(DOWNLOAD_DIR) $(BINUTILS_DOWNLOAD_URL)/$(BINUTILS_DOWNLOAD_TBZ2) && touch $@
$(DOWNLOAD_DIR)/gcc-core-$(GCC_VERSION).tar.bz2: $(DOWNLOAD_DIR)
$(ECHO) "$(BRIGHT_COL)downloading gcc...$(DEFAULT_COL)"
$(VERBOSE)wget -c -P $(DOWNLOAD_DIR) $(GCC_DOWNLOAD_URL)/gcc-$(GCC_VERSION)/gcc-core-$(GCC_VERSION).tar.bz2 && touch $@
$(DOWNLOAD_DIR)/gcc-g++-$(GCC_VERSION).tar.bz2: $(DOWNLOAD_DIR)
$(ECHO) "$(BRIGHT_COL)downloading g++...$(DEFAULT_COL)"
$(VERBOSE)wget -c -P $(DOWNLOAD_DIR) $(GCC_DOWNLOAD_URL)/gcc-$(GCC_VERSION)/gcc-g++-$(GCC_VERSION).tar.bz2 && touch $@
$(DOWNLOAD_DIR)/gmp-$(GMP_VERSION).tar.bz2: $(DOWNLOAD_DIR)
$(ECHO) "$(BRIGHT_COL)downloading gmp...$(DEFAULT_COL)"
$(VERBOSE)wget -c -P $(DOWNLOAD_DIR) $(GMP_DOWNLOAD_URL)/gmp-$(GMP_VERSION).tar.bz2 && touch $@
$(DOWNLOAD_DIR)/mpfr-$(MPFR_VERSION).tar.bz2: $(DOWNLOAD_DIR)
$(ECHO) "$(BRIGHT_COL)downloading mpfr...$(DEFAULT_COL)"
$(VERBOSE)wget -c -P $(DOWNLOAD_DIR) $(MPFR_DOWNLOAD_URL)/mpfr-$(MPFR_VERSION).tar.bz2 && touch $@
$(DOWNLOAD_DIR)/mpc-$(MPC_VERSION).tar.gz: $(DOWNLOAD_DIR)
$(ECHO) "$(BRIGHT_COL)downloading mpc...$(DEFAULT_COL)"
$(VERBOSE)wget -c -P $(DOWNLOAD_DIR) $(MPC_DOWNLOAD_URL)/mpc-$(MPC_VERSION).tar.gz && touch $@
$(CONTRIB_DIR)/gmp-$(GMP_VERSION)/configure: $(DOWNLOAD_DIR)/gmp-$(GMP_VERSION).tar.bz2
$(ECHO) "$(BRIGHT_COL)unpacking gmp...$(DEFAULT_COL)"
$(VERBOSE)tar xfj $< -C $(CONTRIB_DIR)
$(CONTRIB_DIR)/mpfr-$(MPFR_VERSION)/configure: $(DOWNLOAD_DIR)/mpfr-$(MPFR_VERSION).tar.bz2
$(ECHO) "$(BRIGHT_COL)unpacking mpfr...$(DEFAULT_COL)"
$(VERBOSE)tar xfj $< -C $(CONTRIB_DIR)
$(CONTRIB_DIR)/mpc-$(MPC_VERSION)/configure: $(DOWNLOAD_DIR)/mpc-$(MPC_VERSION).tar.gz
$(ECHO) "$(BRIGHT_COL)unpacking mpc...$(DEFAULT_COL)"
$(VERBOSE)tar xfz $< -C $(CONTRIB_DIR)
$(CONTRIB_DIR)/gcc-$(GCC_VERSION)/configure: $(addprefix $(DOWNLOAD_DIR)/,gcc-core-$(GCC_VERSION).tar.bz2 gcc-g++-$(GCC_VERSION).tar.bz2)
$(ECHO) "$(BRIGHT_COL)unpacking gcc and g++...$(DEFAULT_COL)"
$(VERBOSE)mkdir -p $(CONTRIB_DIR)
$(VERBOSE)for i in $^ ; do tar xfj $$i -C $(CONTRIB_DIR) ;done
$(VERBOSE)touch $@
$(ECHO) "$(BRIGHT_COL)patching gcc build system...$(DEFAULT_COL)"
@#
@# Enable support for passing custom 'tmake_file' and 'extra_parts' to the
@# GCC configure process uncommenting the default initialization of the
@# respective variables. The 'extra_parts' variable is used to carry the
@# the information about which crtN files are to be created.
@#
@# The 't-386elf' file must the treated to prevent it from defining the
@# 'EXTRA_PARTS' variable. If defined, the 'libgcc' Makefile would prepare
@# it against our custom list of 'extra_parts' and consequently fail.
@#
$(VERBOSE)sed -i "/^tmake_file=$$/s/^/#/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/gcc/config.gcc
$(VERBOSE)sed -i "/^extra_parts=$$/s/^/#/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/gcc/config.gcc
$(VERBOSE)sed -i "/^extra_parts=$$/s/^/#/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/libgcc/config.host
$(VERBOSE)sed -i "/^EXTRA_PARTS=/s/^/#/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/gcc/config/i386/t-i386elf
$(VERBOSE)sed -i "/^EXTRA_MULTILIB_PARTS *=/s/^/#/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/gcc/config/arm/t-arm-elf
@#
@# Let 'config.gcc' expand our already populated 'tmake_file' variable rather
@# than making a hard assignment. This is needed for the ARM platform because
@# the target 'arm-elf-eabi' actually matches the pattern 'arm-*-*-eabi' in
@# the 'config.gcc' file.
@#
$(VERBOSE)sed -i "/tmake_file=\"arm/s/=\"/=\"\$${tmake_file} /" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/gcc/config.gcc
@#
@# Enable LINK_SPEC customization via configure arguments
@#
@# We add a hook for sneaking our custom LINK_SPEC definition into the GCC
@# configure process by uncommentig the 'host_xm_include_list'. This enables us
@# to supply a custom header file to be included into 'gcc/config.h' defining
@# the 'LINK_SPEC' macro. This macro expresses the policy of how the GCC
@# frontend invokes 'ld' on multiarch platforms. I.e., on x86, we need to pass
@# '-melf_i386' to 'ld' when building in '-m32' mode.
@#
$(VERBOSE)sed -i "/^host_xm_include_list=$$/s/^/#/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/gcc/configure.ac
@#
@# Make sure to disable the 'inhibit_libc' flag, which is evaluated when
@# compiling libgcc. When libc is inhibited, the 'unwind-dw2-fde-glibc.c'
@# is not using the "new" glibc exception handling mechanism. However,
@# Genode's dynamic linker relies on this mechanism.
@#
$(VERBOSE)sed -i "/inhibit_libc=true/s/true/false # was true/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/gcc/configure.ac
@#
@# Accept prepopulation of 'host_configargs' and 'target_configargs' as
@# configure argument (only needed for gcc-4.4.5, fixed with later versions)
@#
$(VERBOSE)sed -i "/host_configargs=.--cache-file/s/=./=\"\$$host_configargs /" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/configure.ac
$(VERBOSE)sed -i "/target_configargs=..baseargs/s/=.*/=\"\$$target_configargs \$${baseargs}\"/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/configure.ac
@#
@# Allow customization of CPPFLAGS_FOR_TARGET, not supported by the original
@# GCC config and build system.
@#
$(VERBOSE)sed -i "/^CXXFLAGS_FOR_TARGET =/s/^/CPPFLAGS_FOR_TARGET = @CPPFLAGS_FOR_TARGET@\n/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/Makefile.tpl
$(VERBOSE)sed -i "/AC_SUBST(CFLAGS_FOR_TARGET)/s/^/AC_SUBST(CPPFLAGS_FOR_TARGET)\n/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/configure.ac
@#
@# Fix the handling of CPP_FOR_TARGET. Without the fix, the configure script
@# of libgcc tries to use the normal 'cpp' for executing preprocessor tests,
@# which produces bogus results.
@#
$(VERBOSE)sed -i "/CC=.*XGCC.*export CC/s/^/ CPP=\"\$$(CPP_FOR_TARGET) \$$(XGCC_FLAGS_FOR_TARGET) \$$\$$TFLAGS\"; export CPP; \\\\\n/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/Makefile.tpl
$(VERBOSE)sed -i "/^CC_FOR_TARGET=/s/^/CPP_FOR_TARGET=\$$(STAGE_CC_WRAPPER) @CPP_FOR_TARGET@\n/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/Makefile.tpl
$(VERBOSE)sed -i "/CC=.*XGCC.*TFLAGS....$$/s/^/ 'CPP=\$$\$$(CPP_FOR_TARGET) \$$\$$(XGCC_FLAGS_FOR_TARGET) \$$\$$(TFLAGS)' \\\\\n/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/Makefile.tpl
$(VERBOSE)sed -i "/flag= CC_FOR_TARGET/s/^/flags_to_pass = { flag= CPP_FOR_TARGET ; };\n/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/Makefile.def
$(VERBOSE)sed -i "/^GCC_TARGET_TOOL.cc,/s/^/GCC_TARGET_TOOL(cpp, CPP_FOR_TARGET, CPP, \[gcc\/cpp -B\$$\$$r\/\$$(HOST_SUBDIR)\/gcc\/\])\n/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/configure.ac
@#
@# Ensure -fno-short-enums as default.
@#
$(VERBOSE)sed -i "s/return TARGET_AAPCS_BASED && arm_abi != ARM_ABI_AAPCS_LINUX/return false/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/gcc/config/arm/arm.c
@#
@# Remove sanity check for host/target combination in configure script of
@# libstdc++. An alternative fix would be the addition of a new host or
@# the use of an existing one. However, adding a new host would require
@# us to maintain a larger patch to the GCC build system, and using an
@# existing host comes with all the (possibly unwanted) policies associated
@# with the respective host platform. We want to stick with the bare-bone
@# compiler as much as possible.
@#
$(VERBOSE)sed -i "/No support for this host.target combination/d" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/libstdc++-v3/crossconfig.m4
$(VERBOSE)cd $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/libstdc++-v3; $(AUTOCONF)
@#
@# Allow passing of PICFLAGS to the configure script of libstdc++.
@# Without this change, libsupc++ would be compiled w/o PICFLAGS, resulting
@# in text relocations. Because for base tool chains, no 'dynamic_linker'
@# is defined (see 'libtool.m4'), 'dynamic_linker' is set to 'no', which
@# results in 'can_build_shared = no', which, in turn , results
@# in 'enable_shared = no', which, in turn, sets 'LIBSUPCXX_PICFLAGS' to
@# nothing rather then '-prefer-pic'.
@#
$(VERBOSE)sed -i "/LIBSUPCXX_PICFLAGS=$$/s/LIB/__LIB/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/libstdc++-v3/configure.ac
@#
@# Re-generate configure scripts
@#
$(VERBOSE)cd $(CONTRIB_DIR)/gcc-$(GCC_VERSION); autogen Makefile.def
$(VERBOSE)cd $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/libgcc; $(AUTOCONF)
$(VERBOSE)cd $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/libstdc++-v3; $(AUTOCONF)
$(VERBOSE)cd $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/gcc; $(AUTOCONF)
$(VERBOSE)cd $(CONTRIB_DIR)/gcc-$(GCC_VERSION); $(AUTOCONF)
@#
@# Fix a bug in gcc 4.6.1 that causes compile errors when building Qt4 for ARM
@# More detailed description at and solution from http://gcc.gnu.org/ml/gcc-patches/2010-11/msg02245.html
@#
ifeq ($(GCC_VERSION),4.6.1)
$(ECHO) "$(BRIGHT_COL)patching gcc...$(DEFAULT_COL)"
$(VERBOSE)sed -i "/|| (volatilep && flag_strict_volatile_bitfields > 0/s/)/ \&\& (bitpos % GET_MODE_ALIGNMENT (mode) != 0))/" $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/gcc/expr.c
endif
$(CONTRIB_DIR)/binutils-$(BINUTILS_VERSION)/configure: $(DOWNLOAD_DIR)/$(BINUTILS_DOWNLOAD_TBZ2)
$(ECHO) "$(BRIGHT_COL)unpacking binutils...$(DEFAULT_COL)"
$(VERBOSE)mkdir -p $(CONTRIB_DIR)
$(VERBOSE)tar xfj $^ -C $(CONTRIB_DIR) && touch $@
build/$(PLATFORM)/binutils/Makefile: $(CONTRIB_DIR)/binutils-$(BINUTILS_VERSION)/configure
$(ECHO) "$(BRIGHT_COL)configuring binutils...$(DEFAULT_COL)"
$(VERBOSE)mkdir -p $(dir $@)
$(VERBOSE)cd $(dir $@); ../../../$(CONTRIB_DIR)/binutils-$(BINUTILS_VERSION)/configure $(BINUTILS_CONFIG)
$(BINUTILS_BINARIES): build/$(PLATFORM)/binutils/Makefile
$(ECHO) "$(BRIGHT_COL)builing binutils...$(DEFAULT_COL)"
$(VERBOSE)$(MAKE) -C $(dir $<) $(MAKE_OPT)
$(BINUTILS_INSTALLED_BINARIES): $(BINUTILS_BINARIES)
$(ECHO) "$(BRIGHT_COL)installing binutils...$(DEFAULT_COL)"
$(VERBOSE)for i in binutils gas ld intl opcodes; do \
$(MAKE) -C build/$(PLATFORM)/binutils/$$i install-strip; done
$(VERBOSE)$(MAKE) -C build/$(PLATFORM)/binutils/libiberty install
COMMON_LIB_CONFIG = --prefix=$(LOCAL_LIB_INSTALL_LOCATION) \
--disable-shared --enable-static
GMP_CONFIG = $(COMMON_LIB_CONFIG)
MPFR_CONFIG = $(COMMON_LIB_CONFIG) --with-gmp=$(LOCAL_LIB_INSTALL_LOCATION)
MPC_CONFIG = $(COMMON_LIB_CONFIG) --with-gmp=$(LOCAL_LIB_INSTALL_LOCATION) \
--with-mpfr=$(LOCAL_LIB_INSTALL_LOCATION)
$(LOCAL_LIB_INSTALL_LOCATION)/lib/libgmp.a: build/gmp/Makefile
$(LOCAL_LIB_INSTALL_LOCATION)/lib/libmpfr.a: build/mpfr/Makefile
$(LOCAL_LIB_INSTALL_LOCATION)/lib/libmpc.a: build/mpc/Makefile
# rule to build libgmp, libmpfr, and libmpc
$(LOCAL_LIB_INSTALL_LOCATION)/lib/lib%.a:
$(ECHO) "$(BRIGHT_COL)building lib$*...$(DEFAULT_COL)"
$(VERBOSE)make -C build/$* all install
build/gmp/Makefile: $(CONTRIB_DIR)/gmp-$(GMP_VERSION)/configure
build/gmp/Makefile:
$(ECHO) "$(BRIGHT_COL)configuring libgmp...$(DEFAULT_COL)"
$(VERBOSE)mkdir -p $(dir $@)
$(VERBOSE)cd $(dir $@); \
../../$(CONTRIB_DIR)/gmp-$(GMP_VERSION)/configure $(GMP_CONFIG)
build/mpfr/Makefile: $(CONTRIB_DIR)/mpfr-$(MPFR_VERSION)/configure \
$(LOCAL_LIB_INSTALL_LOCATION)/lib/libgmp.a
build/mpfr/Makefile:
$(ECHO) "$(BRIGHT_COL)configuring libmpfr...$(DEFAULT_COL)"
$(VERBOSE)mkdir -p $(dir $@)
$(VERBOSE)cd $(dir $@); \
../../$(CONTRIB_DIR)/mpfr-$(MPFR_VERSION)/configure $(MPFR_CONFIG)
build/mpc/Makefile: $(CONTRIB_DIR)/mpc-$(MPC_VERSION)/configure \
$(LOCAL_LIB_INSTALL_LOCATION)/lib/libgmp.a \
$(LOCAL_LIB_INSTALL_LOCATION)/lib/libmpfr.a
build/mpc/Makefile:
$(ECHO) "$(BRIGHT_COL)configuring libmpc...$(DEFAULT_COL)"
$(VERBOSE)mkdir -p $(dir $@)
$(VERBOSE)cd $(dir $@); \
../../$(CONTRIB_DIR)/mpc-$(MPC_VERSION)/configure $(MPC_CONFIG)
build/$(PLATFORM)/gcc/Makefile: $(CONTRIB_DIR)/gcc-$(GCC_VERSION)/configure \
$(BINUTILS_INSTALLED_BINARIES) \
$(LOCAL_LIB_INSTALL_LOCATION)/lib/libgmp.a \
$(LOCAL_LIB_INSTALL_LOCATION)/lib/libmpfr.a \
$(LOCAL_LIB_INSTALL_LOCATION)/lib/libmpc.a
build/$(PLATFORM)/gcc/Makefile:
$(ECHO) "$(BRIGHT_COL)configuring gcc...$(DEFAULT_COL)"
$(VERBOSE)mkdir -p $(dir $@)
$(VERBOSE)cd $(dir $@); \
host_configargs="$(HOST_CONFIG_ARGS)" \
target_configargs="$(TARGET_CONFIG_ARGS)" \
../../../$(CONTRIB_DIR)/gcc-$(GCC_VERSION)/configure $(GCC_CONFIG)
$(GCC_BINARIES): build/$(PLATFORM)/gcc/Makefile \
$(LINK_SPEC_H_$(PLATFORM)) \
$(LD_SCRIPT_$(PLATFORM)) \
$(LIBC)
$(GCC_BINARIES): build/$(PLATFORM)/gcc/Makefile
$(ECHO) "$(BRIGHT_COL)builing gcc...$(DEFAULT_COL)"
$(VERBOSE)$(MAKE) -C $(dir $<) $(MAKE_OPT)
$(GCC_INSTALLED_BINARIES): $(GCC_BINARIES)
$(ECHO) "$(BRIGHT_COL)installing gcc...$(DEFAULT_COL)"
$(VERBOSE)$(MAKE) -C build/$(PLATFORM)/gcc $(GCC_INSTALL_RULE)
$(DOWNLOAD_DIR)/gdb-$(GDB_VERSION).tar.bz2: $(DOWNLOAD_DIR)
$(ECHO) "$(BRIGHT_COL)downloading gdb...$(DEFAULT_COL)"
$(VERBOSE)wget -c -P $(DOWNLOAD_DIR) $(GDB_DOWNLOAD_URL)/gdb-$(GDB_VERSION).tar.bz2 && touch $@
$(CONTRIB_DIR)/gdb-$(GDB_VERSION)/configure: $(DOWNLOAD_DIR)/gdb-$(GDB_VERSION).tar.bz2
$(ECHO) "$(BRIGHT_COL)unpacking gdb...$(DEFAULT_COL)"
$(VERBOSE)mkdir -p $(CONTRIB_DIR)
$(VERBOSE)tar xfj $^ -C $(CONTRIB_DIR) && touch $@
$(ECHO) "$(BRIGHT_COL)patching gdb...$(DEFAULT_COL)"
@#
@# Include 'solib.o' and 'solib-svr4.o' in arm*-*-* (non-OS) target configuration for shared library support
@#
$(VERBOSE)sed -i "s/gdb_target_obs=\"arm-tdep\.o\"$$/gdb_target_obs=\"arm-tdep.o solib.o solib-svr4.o\"/" $(CONTRIB_DIR)/gdb-$(GDB_VERSION)/gdb/configure.tgt
@#
@# Add an x86_64-*-* (non-OS) target with shared library support
@#
$(VERBOSE)sed -i "/^xtensa\*-\*-linux\*/ s/^/x86_64-*-*)\n\tgdb_target_obs=\"amd64-tdep.o i386-tdep.o i387-tdep.o solib.o solib-svr4.o\"\n\t;;\n/" $(CONTRIB_DIR)/gdb-$(GDB_VERSION)/gdb/configure.tgt
@#
@# Enable shared library support
@#
$(VERBOSE)sed -i "/^#include \"features\/i386\/amd64-avx\.c\"$$/ s/$$/\n\n#include \"solib-svr4\.h\"/" $(CONTRIB_DIR)/gdb-$(GDB_VERSION)/gdb/amd64-tdep.c
$(VERBOSE)sed -i "/AMD64 generally uses/ s/^/ set_solib_svr4_fetch_link_map_offsets(gdbarch, svr4_lp64_fetch_link_map_offsets);\n\n/" $(CONTRIB_DIR)/gdb-$(GDB_VERSION)/gdb/amd64-tdep.c
$(VERBOSE)sed -i "/^#include \"features\/arm-with-m\.c\"$$/ s/$$/\n\n#include \"solib-svr4\.h\"/" $(CONTRIB_DIR)/gdb-$(GDB_VERSION)/gdb/arm-tdep.c
$(VERBOSE)sed -i "/gdbarch = gdbarch_alloc (&info, tdep);/ s/$$/\n\n set_solib_svr4_fetch_link_map_offsets(gdbarch, svr4_ilp32_fetch_link_map_offsets);/" $(CONTRIB_DIR)/gdb-$(GDB_VERSION)/gdb/arm-tdep.c
$(VERBOSE)sed -i "/^#include \"features\/i386\/i386-mmx\.c\"$$/ s/$$/\n\n#include \"solib-svr4\.h\"/" $(CONTRIB_DIR)/gdb-$(GDB_VERSION)/gdb/i386-tdep.c
$(VERBOSE)sed -i "/gdbarch = gdbarch_alloc (&info, tdep);/ s/$$/\n\n set_solib_svr4_fetch_link_map_offsets(gdbarch, svr4_ilp32_fetch_link_map_offsets);/" $(CONTRIB_DIR)/gdb-$(GDB_VERSION)/gdb/i386-tdep.c
@#
@# Enable software single-stepping on ARM
@#
$(VERBOSE)sed -i "/gdbarch = gdbarch_alloc (&info, tdep);/ s/$$/\n\n set_gdbarch_software_single_step(gdbarch, arm_software_single_step);/" $(CONTRIB_DIR)/gdb-$(GDB_VERSION)/gdb/arm-tdep.c
build/$(PLATFORM)/gdb/Makefile: $(CONTRIB_DIR)/gdb-$(GDB_VERSION)/configure
$(ECHO) "$(BRIGHT_COL)configuring gdb...$(DEFAULT_COL)"
$(VERBOSE)mkdir -p $(dir $@)
$(VERBOSE)cd $(dir $@); \
../../../$(CONTRIB_DIR)/gdb-$(GDB_VERSION)/configure $(COMMON_CONFIG)
$(GDB_BINARIES): build/$(PLATFORM)/gdb/Makefile
$(ECHO) "$(BRIGHT_COL)builing gdb...$(DEFAULT_COL)"
$(VERBOSE)$(MAKE) -C $(dir $<) $(MAKE_OPT)
$(GDB_INSTALLED_BINARIES): $(GDB_BINARIES)
$(ECHO) "$(BRIGHT_COL)installing gdb...$(DEFAULT_COL)"
$(VERBOSE)$(MAKE) -C build/$(PLATFORM)/gdb install
#
# Clean rules
#
clean:
rm -rf $(addprefix $(CONTRIB_DIR)/,binutils-$(BINUTILS_VERSION) gcc-$(GCC_VERSION))
rm -rf build
cleanall: clean
rm -rf $(DOWNLOAD_DIR)/$(BINUTILS_DOWNLOAD_TBZ2)
rm -rf $(DOWNLOAD_DIR)/gcc-core-$(GCC_VERSION).tar.bz2
rm -rf $(DOWNLOAD_DIR)/gcc-g++-$(GCC_VERSION).tar.bz2
#
# Install rules
#
install: build_all
$(ECHO) "$(BRIGHT_COL)installing tool chain to '$(INSTALL_LOCATION)'...$(DEFAULT_COL)"
$(VERBOSE)sudo cp -a --remove-destination --no-target-directory $(LOCAL_INSTALL_LOCATION) $(INSTALL_LOCATION)