+#!/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 $_;
+ }
+}