From 00fab7f6cbb427e331c007ed07403be1add49b25 Mon Sep 17 00:00:00 2001 From: Gabriel Corona Date: Tue, 7 Oct 2014 11:26:45 +0200 Subject: [PATCH 1/1] [mc] Add stack-cleaning compiler wrappers This compiler wrappers clear each satck frame before using it in order to avoid issues with unitialized variables in SimGridMC state comparison. Compiling with those compiler is much slower. --- tools/stack-cleaner/README | 21 +++++++++ tools/stack-cleaner/as | 57 ++++++++++++++++++++++++ tools/stack-cleaner/c++ | 3 ++ tools/stack-cleaner/cc | 3 ++ tools/stack-cleaner/clean-stack-filter | 61 ++++++++++++++++++++++++++ 5 files changed, 145 insertions(+) create mode 100644 tools/stack-cleaner/README create mode 100755 tools/stack-cleaner/as create mode 100755 tools/stack-cleaner/c++ create mode 100755 tools/stack-cleaner/cc create mode 100755 tools/stack-cleaner/clean-stack-filter diff --git a/tools/stack-cleaner/README b/tools/stack-cleaner/README new file mode 100644 index 0000000000..0aa98f8f4a --- /dev/null +++ b/tools/stack-cleaner/README @@ -0,0 +1,21 @@ +Provides stack-cleaning compilers for x86_64: + + * as + * cc + * c++ + +Each of them modify the generated/given X86_64 assembly by prepending +stack-cleanup code to each function: + + movq $QSIZE, %r11 +.Lloop: + movq $0, OFFSET(%rsp,%r11,8) + subq $1, %r11 + jne .Lloop + +The modification of the assembly is done by the clean-stack-filter +program. + +If the underlying compiler is clang, it might be necessary to add the +-no-integrated-as flag in order to force the usage of an external +assembler. diff --git a/tools/stack-cleaner/as b/tools/stack-cleaner/as new file mode 100755 index 0000000000..dcdb491e48 --- /dev/null +++ b/tools/stack-cleaner/as @@ -0,0 +1,57 @@ +#!/usr/bin/ruby +# Wrapper around the real `as` which adds filtering capabilities. + +require "tempfile" +require "fileutils" + +def wrapped_as(argv) + + args=[] + input=nil + + i = 0 + while i input, 1 => tempfile) + status=$?.exitstatus + FileUtils.rm tempfile + exit status + end + args.push(tempfile.path) + + # Call the real assembler: + res = system("as", *args) + status = if res != nil + $?.exitstatus + else + 1 + end + FileUtils.rm tempfile + exit status + +end + +wrapped_as(ARGV) diff --git a/tools/stack-cleaner/c++ b/tools/stack-cleaner/c++ new file mode 100755 index 0000000000..516d36c28c --- /dev/null +++ b/tools/stack-cleaner/c++ @@ -0,0 +1,3 @@ +#!/bin/sh +path="$(dirname $0)" +exec "${FILTER_CXX:-c++}" -B "$path" "$@" diff --git a/tools/stack-cleaner/cc b/tools/stack-cleaner/cc new file mode 100755 index 0000000000..3cfd37887e --- /dev/null +++ b/tools/stack-cleaner/cc @@ -0,0 +1,3 @@ +#!/bin/sh +path="$(dirname $0)" +exec "${FILTER_CC:-cc}" -B "$path" "$@" diff --git a/tools/stack-cleaner/clean-stack-filter b/tools/stack-cleaner/clean-stack-filter new file mode 100755 index 0000000000..8c5c01ca1c --- /dev/null +++ b/tools/stack-cleaner/clean-stack-filter @@ -0,0 +1,61 @@ +#!/usr/bin/perl -w +# Transform assembly in order to clean each stack frame for X86_64. + +use strict; +$SIG{__WARN__} = sub { die @_ }; + + +# Whether we are still scanning the content of a function: +our $scanproc = 0; + +# Save lines of the function: +our $lines = ""; + +# Size of the stack for this function: +our $size = 0; + + +# Counter for assigning unique ids to labels: +our $id=0; + +sub emit_code { + my $qsize = $size / 8; + my $offset = - $size - 8; + + if($size != 0) { + print("\tmovabsq \$$qsize, %r11\n"); + print(".Lstack_cleaner_loop$id:\n"); + print("\tmovq \$0, $offset(%rsp,%r11,8)\n"); + print("\tsubq \$1, %r11\n"); + print("\tjne .Lstack_cleaner_loop$id\n"); + } + + print $lines; + + $id = $id + 1; + $size = 0; + $lines = ""; + $scanproc = 0; +} + +while (<>) { + if ($scanproc) { + $lines = $lines . $_; + if (m/^[ \t]*.cfi_endproc$/) { + emit_code(); + } elsif (m/^[ \t]*pushq/) { + $size += 8; + } elsif (m/^[ \t]*subq[\t *]\$([0-9]*),[ \t]*%rsp$/) { + my $val = $1; + $val = oct($val) if $val =~ /^0/; + $size += $val; + emit_code(); + } + } elsif (m/^[ \t]*.cfi_startproc$/) { + print $_; + + $scanproc = 1; + } else { + print $_; + } +} -- 2.20.1