Recently Adobe released a long-anticipated x86_64 build of their ubiquitous Flash Player. After several months many distro-makers began to bundle this as standard, including, Debian in the Lenny release.
Unfortunately for some this plugin makes use of the “LAHF” instruction, an instruction that is not always present on otherwise capable x86_64 CPUs. What this means is that on these CPUs (including early AMD64s, Pentium 4s and others) the Flash Player plugin will cause Firefox or Iceweasel to exit suddenly with an “Illegal instruction” message (or no message at all, depending on how it was launched).
If you are the owner of one of the affected CPUs though, all is not lost. This issue was raised on the Gentoo bug tracker and a clever solution was developed by Maks Verver. The solution comes in the form of a wrapper plugin. This wrapper is compiled from a short section of C code which intercepts the SIGILL signal and emulates the behaviour of the missing LAHF instruction.
Here is the code in its entirety:
/* Simple work-around for running the 64-bit Adobe Flash plug-in version 10
on Athlon64 processors without support for the lahf instruction.
Compile with:
cc -fPIC -shared -nostdlib -lc -oflashplugin-lahf-fix.so flashplugin-lahf-fix.c
Then place the .so file in the plug-in directory (e.g. $HOME/.mozilla/plugins)
or use LD_PRELOAD to force Firefox to load the library.
- Maks Verver <maksverver@geocities.com> July 2009 */
#define _GNU_SOURCE
#include <stdlib.h>
#include <signal.h>
#include <ucontext.h>
static void sig_handler(int signal, siginfo_t *info, void *context) {
if (signal != SIGILL) return;
if (*(char*)info->si_addr != (char)0x9f) abort();
greg_t *regs = ((ucontext_t*)context)->uc_mcontext.gregs;
((char*)®s[REG_RAX])[1] = ((char*)®s[REG_EFL])[0];
regs[REG_RIP]++;
}
static struct sigaction old_sa, new_sa = {
.sa_flags = SA_SIGINFO,
.sa_sigaction = &sig_handler };
int _init() { sigaction(SIGILL, &new_sa, &old_sa); return 0; }
int _fini() { sigaction(SIGILL, &old_sa, &new_sa); return 0; }
In order to make use of this on Debian Lenny, copy and paste the code to a text file called flashplugin-lahf-fix.c and compile from the same directory like so:
cc -fPIC -shared -nostdlib -lc -oflashplugin-lahf-fix.so flashplugin-lahf-fix.c
If you find this doesn’t work, first install the package build-essential with aptitude. See the Debian documentation for more on how to do this.
Once the wrapper has been built you can either copy it to the system-wide plugins directory by executing this command as root:
cp flashplugin-lahf-fix.so /usr/lib/mozilla/plugins/
Or drop the file in to ~/.mozilla/plugins (creating the directory as necessary). Then restart Firefox / Iceweasel and ensure that Flash is running by visiting a site like YouTube and playing a video.