base: support dynamic loading of Linux ELF objects in SE mode
[gem5.git] / SConstruct
index 9ad589661efc2d4f68a24f7d50b51eefdcd1f05a..d791033e79e93e976919bb3a2c39b1ab84941349 100755 (executable)
@@ -194,6 +194,8 @@ AddLocalOption('--without-tcmalloc', dest='without_tcmalloc',
                help='Disable linking against tcmalloc')
 AddLocalOption('--with-ubsan', dest='with_ubsan', action='store_true',
                help='Build with Undefined Behavior Sanitizer if available')
+AddLocalOption('--with-asan', dest='with_asan', action='store_true',
+               help='Build with Address Sanitizer if available')
 
 termcap = get_termcap(GetOption('use_colors'))
 
@@ -209,10 +211,12 @@ use_vars = set([ 'AS', 'AR', 'CC', 'CXX', 'HOME', 'LD_LIBRARY_PATH',
                  'PYTHONPATH', 'RANLIB', 'SWIG', 'TERM' ])
 
 use_prefixes = [
-    "M5",           # M5 configuration (e.g., path to kernels)
-    "DISTCC_",      # distcc (distributed compiler wrapper) configuration
-    "CCACHE_",      # ccache (caching compiler wrapper) configuration
-    "CCC_",         # clang static analyzer configuration
+    "ASAN_",           # address sanitizer symbolizer path and settings
+    "CCACHE_",         # ccache (caching compiler wrapper) configuration
+    "CCC_",            # clang static analyzer configuration
+    "DISTCC_",         # distcc (distributed compiler wrapper) configuration
+    "INCLUDE_SERVER_", # distcc pump server settings
+    "M5",              # M5 configuration (e.g., path to kernels)
     ]
 
 use_env = {}
@@ -553,14 +557,12 @@ if main['GCC'] or main['CLANG']:
     # As gcc and clang share many flags, do the common parts here
     main.Append(CCFLAGS=['-pipe'])
     main.Append(CCFLAGS=['-fno-strict-aliasing'])
-    # Enable -Wall and then disable the few warnings that we
-    # consistently violate
-    main.Append(CCFLAGS=['-Wall', '-Wno-sign-compare', '-Wundef'])
+    # Enable -Wall and -Wextra and then disable the few warnings that
+    # we consistently violate
+    main.Append(CCFLAGS=['-Wall', '-Wundef', '-Wextra',
+                         '-Wno-sign-compare', '-Wno-unused-parameter'])
     # We always compile using C++11
     main.Append(CXXFLAGS=['-std=c++11'])
-    # Add selected sanity checks from -Wextra
-    main.Append(CXXFLAGS=['-Wmissing-field-initializers',
-                          '-Woverloaded-virtual'])
 else:
     print termcap.Yellow + termcap.Bold + 'Error' + termcap.Normal,
     print "Don't know what compiler options to use for your compiler."
@@ -655,14 +657,11 @@ elif main['CLANG']:
         print 'Error: Unable to determine clang version.'
         Exit(1)
 
-    # clang has a few additional warnings that we disable,
-    # tautological comparisons are allowed due to unsigned integers
-    # being compared to constants that happen to be 0, and extraneous
+    # clang has a few additional warnings that we disable, extraneous
     # parantheses are allowed due to Ruby's printing of the AST,
     # finally self assignments are allowed as the generated CPU code
     # is relying on this
-    main.Append(CCFLAGS=['-Wno-tautological-compare',
-                         '-Wno-parentheses',
+    main.Append(CCFLAGS=['-Wno-parentheses',
                          '-Wno-self-assign',
                          # Some versions of libstdc++ (4.8?) seem to
                          # use struct hash and class hash
@@ -819,32 +818,6 @@ scanners.append(CPPScanner("SwigScan", [ ".i" ], "CPPPATH", swig_inc_re))
 # replace the scanners list that has what we want
 main['SCANNERS'] = scanners
 
-# Add a custom Check function to the Configure context so that we can
-# figure out if the compiler adds leading underscores to global
-# variables.  This is needed for the autogenerated asm files that we
-# use for embedding the python code.
-def CheckLeading(context):
-    context.Message("Checking for leading underscore in global variables...")
-    # 1) Define a global variable called x from asm so the C compiler
-    #    won't change the symbol at all.
-    # 2) Declare that variable.
-    # 3) Use the variable
-    #
-    # If the compiler prepends an underscore, this will successfully
-    # link because the external symbol 'x' will be called '_x' which
-    # was defined by the asm statement.  If the compiler does not
-    # prepend an underscore, this will not successfully link because
-    # '_x' will have been defined by assembly, while the C portion of
-    # the code will be trying to use 'x'
-    ret = context.TryLink('''
-        asm(".globl _x; _x: .byte 0");
-        extern int x;
-        int main() { return x; }
-        ''', extension=".c")
-    context.env.Append(LEADING_UNDERSCORE=ret)
-    context.Result(ret)
-    return ret
-
 # Add a custom Check function to test for structure members.
 def CheckMember(context, include, decl, member, include_quotes="<>"):
     context.Message("Checking for member %s in %s..." %
@@ -871,14 +844,9 @@ conf = Configure(main,
                  conf_dir = joinpath(build_root, '.scons_config'),
                  log_file = joinpath(build_root, 'scons_config.log'),
                  custom_tests = {
-        'CheckLeading' : CheckLeading,
         'CheckMember' : CheckMember,
         })
 
-# Check for leading underscores.  Don't really need to worry either
-# way so don't need to check the return code.
-conf.CheckLeading()
-
 # Check if we should compile a 64 bit binary on Mac OS X/Darwin
 try:
     import platform
@@ -1013,6 +981,21 @@ if not GetOption('without_tcmalloc'):
               "installing tcmalloc (libgoogle-perftools-dev package "\
               "on Ubuntu or RedHat)." + termcap.Normal
 
+
+# Detect back trace implementations. The last implementation in the
+# list will be used by default.
+backtrace_impls = [ "none" ]
+
+if conf.CheckLibWithHeader(None, 'execinfo.h', 'C',
+                           'backtrace_symbols_fd((void*)0, 0, 0);'):
+    backtrace_impls.append("glibc")
+
+if backtrace_impls[-1] == "none":
+    default_backtrace_impl = "none"
+    print termcap.Yellow + termcap.Bold + \
+        "No suitable back trace implementation found." + \
+        termcap.Normal
+
 if not have_posix_clock:
     print "Can't find library for POSIX clocks."
 
@@ -1085,7 +1068,9 @@ main = conf.Finish()
 
 # Define the universe of supported ISAs
 all_isa_list = [ ]
+all_gpu_isa_list = [ ]
 Export('all_isa_list')
+Export('all_gpu_isa_list')
 
 class CpuModel(object):
     '''The CpuModel class encapsulates everything the ISA parser needs to
@@ -1141,9 +1126,11 @@ for bdir in [ base_dir ] + extras_dir_list:
             SConscript(joinpath(root, 'SConsopts'))
 
 all_isa_list.sort()
+all_gpu_isa_list.sort()
 
 sticky_vars.AddVariables(
     EnumVariable('TARGET_ISA', 'Target ISA', 'alpha', all_isa_list),
+    EnumVariable('TARGET_GPU_ISA', 'Target GPU ISA', 'hsail', all_gpu_isa_list),
     ListVariable('CPU_MODELS', 'CPU models',
                  sorted(n for n,m in CpuModel.dict.iteritems() if m.default),
                  sorted(CpuModel.dict.keys())),
@@ -1159,14 +1146,17 @@ sticky_vars.AddVariables(
     BoolVariable('USE_FENV', 'Use <fenv.h> IEEE mode control', have_fenv),
     BoolVariable('CP_ANNOTATE', 'Enable critical path annotation capability', False),
     BoolVariable('USE_KVM', 'Enable hardware virtualized (KVM) CPU models', have_kvm),
+    BoolVariable('BUILD_GPU', 'Build the compute-GPU model', False),
     EnumVariable('PROTOCOL', 'Coherence protocol for Ruby', 'None',
                   all_protocols),
+    EnumVariable('BACKTRACE_IMPL', 'Post-mortem dump implementation',
+                 backtrace_impls[-1], backtrace_impls)
     )
 
 # These variables get exported to #defines in config/*.hh (see src/SConscript).
-export_vars += ['USE_FENV', 'SS_COMPATIBLE_FP', 'TARGET_ISA', 'CP_ANNOTATE',
-                'USE_POSIX_CLOCK', 'USE_KVM', 'PROTOCOL', 'HAVE_PROTOBUF',
-                'HAVE_PERF_ATTR_EXCLUDE_HOST']
+export_vars += ['USE_FENV', 'SS_COMPATIBLE_FP', 'TARGET_ISA', 'TARGET_GPU_ISA',
+                'CP_ANNOTATE', 'USE_POSIX_CLOCK', 'USE_KVM', 'PROTOCOL',
+                'HAVE_PROTOBUF', 'HAVE_PERF_ATTR_EXCLUDE_HOST']
 
 ###################################################
 #
@@ -1213,9 +1203,9 @@ main.Append(BUILDERS = { 'ConfigFile' : config_builder })
 main.SConscript('ext/libelf/SConscript',
                 variant_dir = joinpath(build_root, 'libelf'))
 
-# gzstream build is shared across all configs in the build root.
-main.SConscript('ext/gzstream/SConscript',
-                variant_dir = joinpath(build_root, 'gzstream'))
+# iostream3 build is shared across all configs in the build root.
+main.SConscript('ext/iostream3/SConscript',
+                variant_dir = joinpath(build_root, 'iostream3'))
 
 # libfdt build is shared across all configs in the build root.
 main.SConscript('ext/libfdt/SConscript',
@@ -1233,6 +1223,10 @@ main.SConscript('ext/dramsim2/SConscript',
 main.SConscript('ext/drampower/SConscript',
                 variant_dir = joinpath(build_root, 'drampower'))
 
+# nomali build is shared across all configs in the build root.
+main.SConscript('ext/nomali/SConscript',
+                variant_dir = joinpath(build_root, 'nomali'))
+
 ###################################################
 #
 # This function is used to set up a directory with switching headers
@@ -1240,6 +1234,7 @@ main.SConscript('ext/drampower/SConscript',
 ###################################################
 
 main['ALL_ISA_LIST'] = all_isa_list
+main['ALL_GPU_ISA_LIST'] = all_gpu_isa_list
 all_isa_deps = {}
 def make_switching_dir(dname, switch_headers, env):
     # Generate the header.  target[0] is the full path of the output
@@ -1272,6 +1267,35 @@ def make_switching_dir(dname, switch_headers, env):
 
 Export('make_switching_dir')
 
+def make_gpu_switching_dir(dname, switch_headers, env):
+    # Generate the header.  target[0] is the full path of the output
+    # header to generate.  'source' is a dummy variable, since we get the
+    # list of ISAs from env['ALL_ISA_LIST'].
+    def gen_switch_hdr(target, source, env):
+        fname = str(target[0])
+
+        isa = env['TARGET_GPU_ISA'].lower()
+
+        try:
+            f = open(fname, 'w')
+            print >>f, '#include "%s/%s/%s"' % (dname, isa, basename(fname))
+            f.close()
+        except IOError:
+            print "Failed to create %s" % fname
+            raise
+
+    # Build SCons Action object. 'varlist' specifies env vars that this
+    # action depends on; when env['ALL_ISA_LIST'] changes these actions
+    # should get re-executed.
+    switch_hdr_action = MakeAction(gen_switch_hdr,
+                          Transform("GENERATE"), varlist=['ALL_ISA_GPU_LIST'])
+
+    # Instantiate actions for each header
+    for hdr in switch_headers:
+        env.Command(hdr, [], switch_hdr_action)
+
+Export('make_gpu_switching_dir')
+
 # all-isas -> all-deps -> all-environs -> all_targets
 main.Alias('#all-isas', [])
 main.Alias('#all-deps', '#all-isas')