Prefaced by the top comments ...
The assembler .symver
shows some promise. A web search on it shows:
- http://web.mit.edu/rhel-doc/3/rhel-as-en-3/symver.html
- https://man7.org/conf/lca2006/shared_libraries/slide19a.html
- Linking against older symbol version in a .so file
From this, I've created a symver.s
file that has stubs that seems to work on my system [which has the same versioned symbols issue].
However, I'd have a look at those linked pages (e.g.) symver
is also an attribute, so it may be possible to do this with inline asm from a .c
file.
I've created a crude test program:
// xdrtest.c -- print address of xdr_wrapstring
#include <stdio.h>
void xdr_wrapstring(void);
int
main(void)
{
void *ptr = xdr_wrapstring;
printf("%p\n",ptr);
return 0;
}
Here is an better test program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <rpc/types.h>
#include <rpc/xdr.h>
#define ALEN 1000
#define sysfault(_fmt...) \
do { \
fprintf(stderr,_fmt); \
exit(1); \
} while (0)
XDR xdrs;
void
sendstring(const char *str)
{
static char buf[ALEN];
char *bp;
strcpy(buf,str);
bp = buf;
if (! xdr_wrapstring(&xdrs,&bp))
sysfault("sendstring: xdr_wrapstring fail -- str='%s' buf='%s'\n",
str,buf);
}
void
recvstring(const char *str)
{
static char buf[ALEN];
char *bp;
bp = buf;
if (! xdr_wrapstring(&xdrs,&bp))
sysfault("recvstring: xdr_wrapstring fail -- str='%s' buf='%s'\n",
str,buf);
fprintf(stderr,"buf=%p bp=%p str='%s' bp='%s'\n",buf,bp,str,bp);
if (strcmp(bp,str) != 0)
sysfault("recvstring: MISMATCH\n");
}
void
writer(void)
{
xdrstdio_create(&xdrs, stdout, XDR_ENCODE);
sendstring("hello");
sendstring("world");
sendstring("goodbye");
sendstring("galaxy");
}
void
reader(void)
{
xdrstdio_create(&xdrs, stdin, XDR_DECODE);
recvstring("hello");
recvstring("world");
recvstring("goodbye");
recvstring("galaxy");
}
int
main(int argc,char **argv)
{
int opt_dir = -1;
--argc;
++argv;
for (; argc > 0; --argc, ++argv) {
char *cp = *argv;
if (*cp != '-')
break;
cp += 2;
switch (cp[-1]) {
case 'r':
opt_dir = 0;
break;
case 'w':
opt_dir = 1;
break;
}
}
switch (opt_dir) {
case 0:
reader();
break;
case 1:
writer();
break;
default:
sysfault("main: -r/-w not specified\n");
break;
}
return 0;
}
Here is the "magic" xdrver.s
file:
.globl xdrstdio_create
.symver foo, xdrstdio_create@GLIBC_2.2.5
xdrstdio_create:
jmp foo
.globl xdr_wrapstring
.symver bar, xdr_wrapstring@GLIBC_2.2.5
xdr_wrapstring:
jmp bar
Compile with (e.g.):
cc -o xdrtest xdrtest.c xdrver.s
Or, of course, we can create xdrver.o
and link with whatever program we want.
Anyway, to test the program:
./xdrtest -w | ./xdrtest -r
And, the output is:
buf=0x4044a0 bp=0x4044a0 str='hello' bp='hello'
buf=0x4044a0 bp=0x4044a0 str='world' bp='world'
buf=0x4044a0 bp=0x4044a0 str='goodbye' bp='goodbye'
buf=0x4044a0 bp=0x4044a0 str='galaxy' bp='galaxy'