Check for unpaired .cfi_remember_state
[openssl.git] / crypto / perlasm / x86_64-xlate.pl
index 5e5d6cc0b10d1c5a0a73a0c34063438d16fd33f0..4a7ec7a6e9e832e6433a37f0182bf403833f2291 100755 (executable)
@@ -541,6 +541,7 @@ my %globals;
        );
 
     my ($cfa_reg, $cfa_rsp);
+    my @cfa_stack;
 
     # [us]leb128 format is variable-length integer representation base
     # 2^128, with most significant bit of each byte being 0 denoting
@@ -648,7 +649,13 @@ my %globals;
            # why it starts with -8. Recall that CFA is top of caller's
            # stack...
            /startproc/ && do { ($cfa_reg, $cfa_rsp) = ("%rsp", -8); last; };
-           /endproc/   && do { ($cfa_reg, $cfa_rsp) = ("%rsp",  0); last; };
+           /endproc/   && do { ($cfa_reg, $cfa_rsp) = ("%rsp",  0);
+                               # .cfi_remember_state directives that are not
+                               # matched with .cfi_restore_state are
+                               # unnecessary.
+                               die "unpaired .cfi_remember_state" if (@cfa_stack);
+                               last;
+                             };
            /def_cfa_register/
                        && do { $cfa_reg = $$line; last; };
            /def_cfa_offset/
@@ -688,6 +695,14 @@ my %globals;
                                                      cfa_expression($$line)));
                                last;
                              };
+           /remember_state/
+                       && do { push @cfa_stack, [$cfa_reg, $cfa_rsp];
+                               last;
+                             };
+           /restore_state/
+                       && do { ($cfa_reg, $cfa_rsp) = @{pop @cfa_stack};
+                               last;
+                             };
            }
 
            $self->{value} = ".cfi_$dir\t$$line" if ($dir);