So a while ago I decided to explore the feasibility of running adobe's flash browser plugin on Gentoo/PPC under Qemu usermode. I was surprised nspluginwrapper already supported PPC using Qemu. Using one or two Google links, I set out for adventure. I'm putting this post online to both inform others and remind myself exactly what I did.

This is a work in progress -- I have not yet been entirely successful. Also, the paths are not formatted nicely for simple copy/paste of commands. You have to know somewhat what you're doing and adapt things for your own system.

First, Qemu needed installing. The portage situation with qemu was baffling. I opted to avoid that entirely and simply download the source from qemu.org. However, version 14.0 ended up being broken in regard to usermode path prefixing, and i686 executables would try to load libs from /lib or /usr/lib instead of /usr/gnemul/qemu-i386/lib. There wasn't much feedback on what was going on with that; qemu would appear to halt until the process allocated too much memory and died. The latest git sources worked like a charm, though.

Next, I installed nspluginwrapper. The www-plugins/nspluginwrapper ebuilds are not ppc keyworded at all so again I pulled the source (version 1.3.0 in this case) and compiled it myself. Not really sure why it lacks at least a ~ppc keyword; someone should file a keyword request bug when it's not 3:43 in the morning. ;) edit: /usr/local/lib/nspluginwrapper/i386/linux/{libnoxshm.so,libxpcom.so,npviewer.bin} all need to be compiled for x86. I accomplished this by compiling nspluginwrapper on an x86 without installing it, then manually copying libnoxshm.so, libxpcom.so, and npviewer.bin from the build directory to the PPC.

Now to cobble together shared libraries required by libflashplayer.so from a handy x86 system:

Fire up Firefox and browse to about:plugins to verify everything went smoothly.

Now you you're all set to browse to your favorite flash site and watch it spin and crash, because at this point it starts linking to GTK libs using absolute paths or something. I dunno how that works, but it keeps trying to load GTK engine libs not referenced in the .so ELF headers. Copying an x86 branch of /usr/lib/gtk-2.0/ into /usr/gnemul/qemu-i386/ doesn't help either; it still loads the PPC libs. Something to do with GTK engine preferences maybe?

I believe an x86 chroot would work here, but the time and space needed to compile a non-native chroot discourages me. Perhaps a static version of these libs would work as well. Or maybe even tweaking USE flags on the x86 system. note: If a full chroot is to be used, the qemu-user executable needs to be statically compiled and placed within the chroot (see online guides for chrooting qemu-user with binfmt).

It's probably a good idea to not leave the plugin active in Firefox all the time. To remove:

The locale warning is due to the absolute bare-bones chroot I built the libraries in; I didn't bother to set up the locale. Not one of my greater worries at the moment. ;)

As can be seen in the above filesystem, I included libcurls as well, but the flash plugin still complains. The various straces I've run show no attempt to load that particular module either. No ideas on that error.

The rpc_method_invoke_possible warnings look interesting, but I don't know anything about those functions. Anyone else have any ideas?

Beyond that, I'm pouring over strace logs without much success. A bit of a needle-in-a-haystack situation. Spirits are low; heading to sleep. Tomorrow I'll try playing a locally stored swf file to remove Firefox from the debugging equation.

Ok... I left it running and when I came back I had a FlashBlock icon. Doh. :) However, Firefox does eventually begin responding again. nspluginwrapper restarts a couple times, but eventually exits and control is returned to Firefox. Loading a local swf file illustrates this more quickly than a complex site such as YouTube, though the results are (eventually) the same.

Running npplayer on the command line brings up a blank window, runs qemu for a bit, then exits:

EDIT: I should warn that this post is rife with uninformed speculation and (very) late-night ramblings. I refuse to be held responsible for any damages, brain or otherwise. :P

Yeah, I haven't done much with this recently, but I wanted to give a parting (for now) comment.

That flash results in a black window/box and no real graphics output left me feeling that libraries running under Qemu (i.e. libX11) are segregated from accessing graphics. Like... the flash plugin is actually drawing, but to a virtual surface I can't see while the real one remains blank. That doesn't make much sense, and there's evidence against it, but dropping the idea is proving difficult. It's probably not drawing at all, but failing when trying to initialize X things. This whole paragraph illustrates how little I understand about interaction between dynamically linked libraries. It's entirely possible the emulation is just too slow.

My ultimate wish is a set of libraries bridging the platform barrier. Meaning native libraries that can be linked to by libflashplayer.so. Sort of a translation layer at the dynamic linking stage. The libraries would need only to mangle data structures and endianness, then pass on the call to a native library. As discussed on the qemu-devel list (a few times actually), this is "complicated" and unlikely to happen, yet the wish remains. And after all, this is exactly what nsluginwrapper does (albeit with a trivial case). Some sort of framework (cataloguing library data structures, calls, dependencies...) to facilitate creating these bridging libraries would be invaluable to usermode emulation. Ah, to dream. :)

Another fun thought experiment is to consider network abstraction: run the flash code on native hardware but link the graphics over an X or RPC network connection. Some issues would be user interface latency and audio transport & synchronization (X does not handle audio at all, no?). Might be faster than emulation, though.

Something that may actually see progress is porting lightspark. Reports of a PPC porting effort exist, but are spotty and uninformative at best.

Maybe I'll come back to this in a few years and try it with a full emulated chroot that more closely mirrors my native environment. Or maybe I won't. :P