[cairo] Entry points for nonexistent backends?
Tor Lillqvist
tml at iki.fi
Fri Aug 17 08:19:59 PDT 2007
lode leroy writes:
> In theory, you could replace linking to "somelib.lib" to access
> "somelib.dll"
> by code that implements dynamic linking to the dll.
Yeah, in fact I have a Perl script "lazify.pl" I once wrote to
automate this. Never got around to actually use it for anything,
though. Usage: lazify.pl foo.dll a.o b.o c.o... Outputs a C source
file for gcc (with some__asm__ stuff).
#!/usr/bin/perl -w
use strict;
use File::Basename;
my %fun_exports;
my %data_exports;
my %imports;
my $library = shift @ARGV;
my @objects = @ARGV;
sub lazify ($) {
my ($symbol) = @_;
print <<EOF
static void *p_$symbol = 0;
static void dummy_$symbol (void)
{
__asm__ (".globl _$symbol\\n"
"_$symbol:\\n");
if (!p_$symbol)
{
__asm__ ("subl \$8, %esp\\n");
if (!hmodule)
hmodule = LOAD_LIBRARY (library);
p_$symbol = GET_ADDRESS (hmodule, "$symbol");
__asm__ ("addl \$8, %esp\\n");
}
__asm__ ("jmp *%0\\n"
: "=m" (p_$symbol));
}
EOF
}
if ($^O eq 'MSWin32' || $^O eq 'msys' || $^O eq 'Cygwin') {
open (PEXPORTS, "pexports $library |") || die "Cannot open pipe from pexports";
<PEXPORTS>; <PEXPORTS>; # Skip LIBRARY and EXPORTS lines
while (<PEXPORTS>) {
chop;
s/\r$// if $^O eq 'msys' || $^O eq 'Cygwin';
if (m/ DATA$/) {
m/(.*) DATA/;
$data_exports{$1}++;
next;
}
$fun_exports{$_}++;
}
} else {
open (NM, "nm --dynamic -g $library | grep ' T ' |") || die "Cannot open pipe from nm | grep";
while (<NM>) {
chop;
s/\r$// if $^O eq 'msys' || $^O eq 'Cygwin';
m/ T (.*)/ || die "Wrong format output from nm: $_";
}
}
foreach my $object (@objects) {
open (NM, "nm -g $object | grep ' U ' |") || die "Cannot open pipe from nm";
while (<NM>) {
chop;
s/\r$// if $^O eq 'msys' || $^O eq 'Cygwin';
m/ U (.*)$/ || die "Wrong format output from nm: $_";;
my $symbol = $1;
$symbol =~ s/^_// if $^O eq 'MSWin32' || $^O eq 'msys' || $^O eq 'Cygwin';
die "$object imports DATA, cannot lazify" if defined $data_exports{$symbol};
$imports{$symbol}++ if defined $fun_exports{$symbol};
}
}
my $basename = basename ($library);
if ($^O eq 'MSWin32' || $^O eq 'msys' || $^O eq 'Cygwin') {
print <<EOF
#include <windows.h>
#define LOAD_LIBRARY(x) LoadLibrary (x)
#define GET_ADDRESS(h,s) GetProcAddress (h, s)
EOF
} else {
print <<EOF
#include <dlfcn.h>
typedef void * HMODULE;
#define LOAD_LIBRARY(x) dlopen (x, RTLD_LAZY)
#define GET_ADDRESS(h,s) dlsym (h, s)
EOF
}
print <<EOF
static HMODULE hmodule = 0;
static const char library[] = "$basename";
EOF
;
foreach my $fun (sort keys %imports) {
lazify ($fun);
}
More information about the cairo
mailing list