set test "tls"
set stap_path $env(SYSTEMTAP_PATH)/stap

# exp_internal 1

set so_flags "additional_flags=-shared"
set so_flags "$so_flags additional_flags=-g"
set so_flags "$so_flags additional_flags=-fPIC"
set x_flags "additional_flags=-Wl,-rpath,[pwd]"
set x_flags "$x_flags additional_flags=-g"
set x_flags "$x_flags additional_flags=-fPIC"
set x_flags "$x_flags additional_flags=-lpthread"

# static tls variables setup

set so1_sopath "[pwd]/libtls1.so"
set res0 [target_compile $srcdir/$subdir/tls1_.c $so1_sopath \
	      executable $so_flags ]
set x1_flags "$x_flags additional_flags=-L[pwd] additional_flags=-ltls1"
set x1_exepath "[pwd]/tls1.x"
set res [target_compile $srcdir/$subdir/tls1.c $x1_exepath \
	     executable $x1_flags ]
if {$res0 != "" || $res != ""} {
    fail "$test compiling tls1"
    return
} else {
    pass "$test compiling tls1"
}

# extern tls variables setup

set so2_sopath "[pwd]/libtls2.so"
set so3_sopath "[pwd]/libtls3.so"
set so2_flags "$so_flags additional_flags=-DEXTERN_TLS"

set res0 [target_compile $srcdir/$subdir/tls1_.c $so2_sopath \
	      executable $so2_flags ]
set res1 [target_compile $srcdir/$subdir/tls2_.c $so3_sopath \
	      executable $so2_flags ]
set x2_flags "$x_flags additional_flags=-L[pwd] additional_flags=-ltls2"
set x2_flags "$x2_flags additional_flags=-ltls3"
set x2_flags "$x2_flags additional_flags=-DEXTERN_TLS"
set x2_exepath "[pwd]/tls2.x"
set res [target_compile $srcdir/$subdir/tls1.c $x2_exepath \
	 executable $x2_flags ]
if { $res0 != "" || $res != "" } {
    fail "$test compiling -shared"
    return
} else {
    pass "$test compiling -shared"
}

# errno setup

set errno_exepath "[pwd]/tlserrno.x"
set res [target_compile $srcdir/$subdir/tlserrno.c $errno_exepath \
	     executable $x_flags ]
if {$res != ""} {
    fail "$test compiling tlserrno"
    return
} else {
    pass "$test compiling tls1errno"
}
set libc_path [exec sh -c "ldd tlserrno.x | grep libc.so | awk '{print \$3}'"]

foreach runtime [get_runtime_list] {
    if {$runtime != ""} {
	set test_type "$test ($runtime)"
    } else {
	set runtime "kernel"
	set test_type $test
    }

    set ok 0
    spawn $stap_path --runtime=$runtime -g -c $x1_exepath $srcdir/$subdir/tls1.stp $so1_sopath IGNORE
    expect {
	-timeout 180
	-re {In Stap(()| increase_tls): (tls1=0x[23] tls2=0x[34]|tls=99)} { incr ok; exp_continue }
	eof { }
    }
    catch {close}; catch {wait}
    if {$ok == 3} {
	pass "$test_type local tls vars"
    } else {
	fail "$test_type local tls vars ($ok/3)"
    }

    # extern tls variables

    set ok 0
    spawn $stap_path --runtime=$runtime -g -c $x2_exepath $srcdir/$subdir/tls1.stp $so2_sopath $so3_sopath
    expect {
	-timeout 180
	-re {In Stap (worker|increase_tls): tls1=0x[23] tls2=0x[34]\r\n} { incr ok; exp_continue }
	eof { }
    }
    catch {close}; catch {wait}
    if {$ok == 4} {
	pass "$test_type ext tls vars"
    } else {
	fail "$test_type ext tls vars ($ok/4)"
    }

    # Check errno

    set ok 0
    spawn $stap_path --runtime=$runtime  -e "probe process(\"$libc_path\").function(\"*stat*\").return { printf(\"errno=%d %s\\n\", @var(\"errno@errno.c\"),errno_str(@var(\"errno@errno.c\"))) }" -c "/usr/bin/ls /file/does/not/exist"
    expect {
	-timeout 180
	-re {errno=2 (ENOENT)} { incr ok; exp_continue }
	eof { }
    }
    catch {close}; catch {wait}
    if {$ok >= 1} {
	pass "$test_type errno"
    } else {
	fail "$test_type errno ($ok/>=1)"
    }

    set ok 0
    spawn $stap_path --runtime=$runtime -e "probe process(\"$errno_exepath\").function(\"main\").return {println (\"In Stap errno=\",@errno) }" -c "$errno_exepath"

    expect {
	-timeout 180
	-re {In Stap errno=2} { incr ok; exp_continue }
	eof { }
    }
    catch {close}; catch {wait}
    if {$ok >= 1} {
	pass "$test_type @errno"
    } else {
	fail "$test_type @errno ($ok/>=1)"
    }
}
