Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8194)

Unified Diff: chrome/plugin/plugin_main_linux.cc

Issue 517031: linux: work around LAHF bug in Flash (Closed)
Patch Set: comment Created 10 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/plugin/plugin_main.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/plugin/plugin_main_linux.cc
diff --git a/chrome/plugin/plugin_main_linux.cc b/chrome/plugin/plugin_main_linux.cc
new file mode 100644
index 0000000000000000000000000000000000000000..9e1efda33420f4092781e955427004b2c6f58d5d
--- /dev/null
+++ b/chrome/plugin/plugin_main_linux.cc
@@ -0,0 +1,50 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#define _POSIX_SOURCE
+#include <signal.h>
+#include <string.h>
+
+#include "build/build_config.h"
+
+// This whole file is only useful on 64-bit architectures.
+#if defined(ARCH_CPU_64_BITS)
+
+namespace {
+
+// Signal handler for SIGILL; see WorkaroundFlashLAHF().
+void SignalHandler(int signal, siginfo_t* info, void* void_context) {
+ const char kLAHFInstruction = 0x9f;
+ if (signal != SIGILL ||
+ *reinterpret_cast<char*>(info->si_addr) != kLAHFInstruction) {
+ raise(signal);
agl 2010/01/04 23:02:43 This may overflow the stack.
+ return; // raise() should have killed us, but just in case...
+ }
+
+ ucontext_t* context = static_cast<ucontext_t*>(void_context);
+ greg_t* regs = context->uc_mcontext.gregs;
+ // LAHF moves the low byte of the EFLAGS register to AH. Emulate that.
+ reinterpret_cast<char*>(&regs[REG_RAX])[1] =
+ reinterpret_cast<char*>(&regs[REG_EFL])[0];
+ // And advance the instruction pointer past the (one-byte) instruction.
+ ++regs[REG_RIP];
+}
+
+} // namespace
+
+// 64-bit Flash sometimes uses the LAHF instruction which isn't
+// available on some CPUs. We can work around it by catching SIGILL
+// (illegal instruction), checking if the signal was caused by this
+// particular circumstance, emulating the instruction, and resuming.
+// This function registers the signal handler.
+void WorkaroundFlashLAHF() {
+ struct sigaction action;
+ memset(&action, 0, sizeof(action));
+ action.sa_flags = SA_SIGINFO;
+ action.sa_sigaction = &SignalHandler;
+
+ sigaction(SIGILL, &action, NULL);
+}
+
+#endif // defined(ARCH_CPU_64_BITS)
« no previous file with comments | « chrome/plugin/plugin_main.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698