[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