From madore@clipper.ens.fr Sun Sep 17 21:41:08 2000
Article: 692 of ens.forum.informatique.internet
Path: eleves!not-for-mail
From: madore@clipper.ens.fr (GroTeXdieck)
Newsgroups: ens.forum.informatique.internet
Subject: Re: Mozilla vs Netscape 4.x
Date: 17 Sep 2000 19:41:08 GMT
Lines: 62
Sender: madore@clipper.ens.fr
Message-ID: <8q36ok$dhu$1@clipper.ens.fr>
References: <8pd2oi$dt5$1@clipper.ens.fr> <8pjb7m$q7s$2@clipper.ens.fr> <8pl3vd$jvo$1@clipper.ens.fr> <8pl5b5$kvm$7@clipper.ens.fr> <8pl9op$7g2$1@clipper.ens.fr>
NNTP-Posting-Host: clipper.ens.fr
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
X-Trace: clipper.ens.fr 969219668 13886 129.199.129.1 (17 Sep 2000 19:41:08 GMT)
X-Complaints-To: forum@clipper.ens.fr
NNTP-Posting-Date: 17 Sep 2000 19:41:08 GMT
X-Newsreader: Flrn (0.4.0 - 07/99)
X-Start-Date: 17 Sep 2000 19:33:30 GMT
Xref: eleves ens.forum.informatique.internet:692

Tout compte fait, ça marche.  Le programme ressemble à ceci :

--- cut here ---
#include <dlfcn.h>
#include <sys/types.h>
#include <sys/socket.h>

#ifndef REPEAT_COUNT
#define REPEAT_COUNT 8
#endif

#ifdef DLOPEN_LIBC
static void *libc;
#endif

static int (*real_sendto) (int socket, const void *buffer, size_t size,
			   int flags, const struct sockaddr *addr,
			   socklen_t length)
     = NULL;

int
sendto (int socket, const void *buffer, size_t size,
	int flags, const struct sockaddr *addr,
	socklen_t length)
{
  int retval;
  int cnt;

  for ( cnt=0 ; cnt<REPEAT_COUNT ; cnt++ )
    {
      retval = real_sendto (socket, buffer, size, flags, addr, length);
      if ( retval < 0 )
	return retval;
    }
  return retval;
}

void
_init (void)
{
#ifdef DLOPEN_LIBC
  libc = dlopen ("libc.so.6", RTLD_LAZY);
  real_sendto = dlsym (libc, "sendto");
#else
  real_sendto = dlsym (RTLD_NEXT, "sendto");
#endif
}
--- cut here ---

à compiler avec

gcc -c doublesend.c -O6 -Wall -fPIC -DPIC
ld -o doublesend.so doublesend.o -shared

et à utiliser en exportant

LD_PRELOAD=/root/doublesend.so:/lib/libdl.so.2

-- 
David, qui découvre ainsi que deux maux (les bibliothèques dynamiques
et le DNS) peuvent s'annuler.  Je devrais envisager une norme ISO du
mouton, pour faire bon poids.

From madore@clipper.ens.fr Thu Nov 30 14:32:33 2000
Article: 3598 of ens.forum.informatique
Path: eleves!not-for-mail
From: madore@clipper.ens.fr (GroTeXdieck)
Newsgroups: ens.forum.syst,ens.forum.informatique
Subject: ELF symbol versioning (was: Re: Configuration)
Followup-To: ens.forum.informatique
Date: Thu, 30 Nov 2000 13:32:33 +0000 (UTC)
Organization: Forum.
Lines: 145
Sender: madore@clipper.ens.fr
Message-ID: <905kth$e10$2@clipper.ens.fr>
References: <Pine.GSO.4.04.10011181434250.5149-100000@esquif.ens.fr> <903ocd$6f7$1@clipper.ens.fr> <903sha$ic0$1@clipper.ens.fr> <903u1k$lvu$1@clipper.ens.fr> <9054f6$1sn$1@clipper.ens.fr>
NNTP-Posting-Host: clipper.ens.fr
X-Trace: clipper.ens.fr 975591153 14368 129.199.129.1 (30 Nov 2000 13:32:33 GMT)
X-Complaints-To: forum@clipper.ens.fr
NNTP-Posting-Date: Thu, 30 Nov 2000 13:32:33 +0000 (UTC)
X-Newsreader: Flrn (0.4.0 - 07/99)
X-Start-Date: 30 Nov 2000 12:34:18 GMT
Xref: eleves ens.forum.syst:2935 ens.forum.informatique:3598

Thomas Pornin in litteris <9054f6$1sn$1@clipper.ens.fr> scripsit:
> Malgré de nombreuses dénégations des RMS-fans, les histoires de
> versionning des symboles ça sux gravissime.

Rappelons à toutes fins utiles que le versioning a été introduit dans
la version 2.1 de la GNU libc (et la version correspondante des
binutils) et qu'il n'était pas disponible dans la version 2.0.  Par
conséquent, toute argumentation sur l'incompatibilité entre les
versions 2.0 et 2.1 de la GNU libc ne relève *pas* du versioning.

D'autre part, pour ceux qui ne connaîtraient pas, rappelons brièvement
et par un exemple comment cela marche :

vega david /tmp $ cat > mydl.h
extern const char dlvers[];

int frobnicate (void);
vega david /tmp $ cat > mydl.c
#include <stdio.h>
#include "mydl.h"

const char dlvers_1_0[] = "1.0";

int
frobnicate (void)
{
  return 42;
}

__asm__ (".symver dlvers_1_0,dlvers@@MYDL_1.0");
vega david /tmp $ cat > mydl.script
MYDL_1.0 { global: frobnicate; dlvers; local: __*; };
vega david /tmp $ gcc -o libmydl-1.0.so mydl.c -O6 -Wall -fPIC -DPIC -shared -Wl,--version-script,mydl.script
vega david /tmp $ rm -f libmydl.so ; ln -s libmydl-1.0.so libmydl.so
vega david /tmp $ cat > testdl.c
#include <stdio.h>
#include "mydl.h"

int
main (void)
{
  printf ("Library version is %s\n", dlvers);
  printf ("Frobnicate returns %d\n", frobnicate ());
  return 0;
}
vega david /tmp $ gcc -o testdl testdl.c -O6 -Wall libmydl.so -Wl,-rpath,/tmp
vega david /tmp $ ./testdl
Library version is 1.0
Frobnicate returns 42
vega david /tmp $ cat > mydl.c
#include <stdio.h>
#include "mydl.h"

const char dlvers_1_0[] = "1.0";
const char dlvers_1_1[] = "1.1";

int
__broken_frobnicate (void)
{
  return 42;
}

int
frobnicate (void)
{
  return 1729;
}

__asm__ (".symver dlvers_1_0,dlvers@MYDL_1.0");
__asm__ (".symver dlvers_1_1,dlvers@@MYDL_1.1");
__asm__ (".symver __broken_frobnicate,frobnicate@MYDL_1.0");
vega david /tmp $ cat > mydl.script
MYDL_1.0 { global: dlvers; local: __*; };
MYDL_1.1 { global: frobnicate; } MYDL_1.0;
vega david /tmp $ gcc -o libmydl-1.1.so mydl.c -O6 -Wall -fPIC -DPIC -shared -Wl,--version-script,mydl.script
vega david /tmp $ rm -f libmydl.so ; ln -s libmydl-1.1.so libmydl.so
vega david /tmp $ ./testdl
Library version is 1.0
Frobnicate returns 42
vega david /tmp $ gcc -o testdl testdl.c -O6 -Wall libmydl.so -Wl,-rpath,/tmp
vega david /tmp $ ./testdl
Library version is 1.1
Frobnicate returns 1729
vega david /tmp $ rm -f libmydl.so ; ln -s libmydl-1.0.so libmydl.so
vega david /tmp $ ./testdl
./testdl: /tmp/libmydl.so: version `MYDL_1.1' not found (required by ./testdl)
vega david /tmp $ cat > mydl.h
extern const char dlvers[];

int frobnicate (int foo);
vega david /tmp $ cat > mydl.c
#include <stdio.h>
#include "mydl.h"

const char dlvers_1_0[] = "1.0";
const char dlvers_1_1[] = "1.1";
const char dlvers_2_0[] = "2.0";

int
__broken_frobnicate (void)
{
  return 42;
}

int
__old_prototype_frobnicate (void)
{
  return 1729;
}

int
frobnicate (int foo)
{
  return foo;
}

__asm__ (".symver dlvers_1_0,dlvers@MYDL_1.0");
__asm__ (".symver dlvers_1_1,dlvers@MYDL_1.1");
__asm__ (".symver dlvers_2_0,dlvers@@MYDL_2.0");
__asm__ (".symver __broken_frobnicate,frobnicate@MYDL_1.0");
__asm__ (".symver __old_prototype_frobnicate,frobnicate@MYDL_1.1");
vega david /tmp $ cat > mydl.script
MYDL_1.0 { global: dlvers; local: __*; };
MYDL_1.1 { } MYDL_1.0;
MYDL_2.0 { global: frobnicate; } MYDL_1.1;
vega david /tmp $ gcc -o libmydl-2.0.so mydl.c -O6 -Wall -fPIC -DPIC -shared -Wl,--version-script,mydl.script
vega david /tmp $ rm -f libmydl.so ; ln -s libmydl-2.0.so libmydl.so
vega david /tmp $ ./testdl
Library version is 1.1
Frobnicate returns 1729
vega david /tmp $ cat > testdl.c
#include <stdio.h>
#include "mydl.h"

int
main (void)
{
  printf ("Library version is %s\n", dlvers);
  printf ("Frobnicate (10) returns %d\n", frobnicate (10));
  return 0;
}
vega david /tmp $ gcc -o testdl testdl.c -O6 -Wall libmydl.so -Wl,-rpath,/tmp
vega david /tmp $ ./testdl
Library version is 2.0
Frobnicate (10) returns 10

