Skip to content

Commit a00bbd9

Browse files
committed
Add support for dlvsym(3)
1 parent 37ac832 commit a00bbd9

File tree

7 files changed

+107
-4
lines changed

7 files changed

+107
-4
lines changed

libtest/GNUmakefile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ JFLAGS = -fno-omit-frame-pointer -fno-strict-aliasing
4747
OFLAGS = -O2 $(JFLAGS)
4848
WFLAGS = -W -Werror -Wall -Wno-unused -Wno-unused-parameter -Wno-parentheses
4949
PICFLAGS = -fPIC
50-
SOFLAGS = -shared -Wl,-O1
50+
SOFLAGS = -shared -Wl,-O1 -Wl,--version-script,$(SRC_DIR)/libtest.map
5151
LDFLAGS += $(SOFLAGS)
5252

5353
IFLAGS = -I"$(BUILD_DIR)"
@@ -127,17 +127,17 @@ ifeq ($(OS), solaris)
127127
CC = gcc
128128
CFLAGS += -std=c99
129129
LD = /usr/ccs/bin/ld
130-
SOFLAGS = -shared -static-libgcc
130+
SOFLAGS = -shared -static-libgcc -Wl,--version-script,$(SRC_DIR)/libtest.map
131131
endif
132132

133133
ifeq ($(OS), aix)
134134
LIBEXT = a
135-
SOFLAGS = -shared -static-libgcc
135+
SOFLAGS = -shared -static-libgcc -Wl,--version-script,$(SRC_DIR)/libtest.map
136136
PICFLAGS += -pthread
137137
endif
138138

139139
ifneq ($(findstring bsd, $(OS)),)
140-
SOFLAGS = -shared -static-libgcc
140+
SOFLAGS = -shared -static-libgcc -Wl,--version-script,$(SRC_DIR)/libtest.map
141141
CFLAGS += -pthread
142142
LDFLAGS += -pthread
143143
endif

libtest/VersionedSymbols.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
int
2+
old_answer(void)
3+
{
4+
return 41;
5+
}
6+
7+
int
8+
new_answer(void)
9+
{
10+
return 42;
11+
}
12+
13+
__asm__(".symver old_answer,answer@VERS_1.0");
14+
__asm__(".symver new_answer,answer@@VERS_1.1");

libtest/libtest.map

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
VERS_1.0 {};
2+
VERS_1.1 {};

src/main/java/com/kenai/jffi/Foreign.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,16 @@ static boolean isMemoryProtectionEnabled() {
290290
*/
291291
static native long dlsym(long handle, String name);
292292

293+
/**
294+
* Locates the memory address of the specified version of a dynamic library symbol.
295+
*
296+
* @param handle A dynamic library handle obtained from {@link #dlopen}
297+
* @param name The name of the symbol.
298+
* @param version The version of the symbol.
299+
* @return The address where the symbol in loaded in memory.
300+
*/
301+
static native long dlvsym(long handle, String name, String version);
302+
293303
/**
294304
* Gets the last error raised by {@link #dlopen} or {@link #dlsym}
295305
*

src/main/java/com/kenai/jffi/Library.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,23 @@ public final long getSymbolAddress(String name) {
182182
}
183183
}
184184

185+
/**
186+
* Gets the address of a symbol within the <tt>Library</tt>.
187+
*
188+
* @param name The name of the symbol to locate.
189+
* @param version The version of the symbol to locate.
190+
* @return The address of the symbol within the current address space.
191+
*/
192+
public final long getSymbolAddressWithVersion(String name, String version) {
193+
try {
194+
return foreign.dlvsym(handle, name, version);
195+
196+
} catch (UnsatisfiedLinkError ex) {
197+
lastError.set(foreign.dlerror());
198+
return 0;
199+
}
200+
}
201+
185202
/**
186203
* Gets the current error string from dlopen/LoadLibrary.
187204
*

src/test/java/com/kenai/jffi/UnitHelper.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,13 @@ public static Address findSymbol(String name) {
112112
}
113113
return new Address(address);
114114
}
115+
public static Address findSymbolWithVersion(String name, String version) {
116+
final long address = LibraryHolder.libtest.getSymbolAddressWithVersion(name, version);
117+
if (address == 0L) {
118+
throw new UnsatisfiedLinkError("Could not locate symbol '" + name + "' at version '" + version + "'");
119+
}
120+
return new Address(address);
121+
}
115122
private static final class NativeInvocationHandler implements InvocationHandler {
116123
private final ConcurrentMap<Method, MethodInvoker> invokers
117124
= new ConcurrentHashMap<Method, MethodInvoker>();
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.kenai.jffi;
2+
3+
import com.kenai.jffi.UnitHelper.Address;
4+
import org.junit.After;
5+
import org.junit.AfterClass;
6+
import org.junit.Before;
7+
import org.junit.BeforeClass;
8+
import org.junit.Test;
9+
import static org.junit.Assert.*;
10+
11+
public class VersionTest {
12+
public VersionTest() {
13+
}
14+
15+
@BeforeClass
16+
public static void setUpClass() throws Exception {
17+
}
18+
19+
@AfterClass
20+
public static void tearDownClass() throws Exception {
21+
}
22+
23+
@Before
24+
public void setUp() {
25+
}
26+
27+
@After
28+
public void tearDown() {
29+
}
30+
31+
@Test public void old_answer() {
32+
Address sym = UnitHelper.findSymbolWithVersion("answer", "VERS_1.0");
33+
34+
int res = 0;
35+
// FIXME: Store answer()'s return value into res
36+
37+
assertEquals(41, res);
38+
}
39+
40+
@Test public void new_answer() {
41+
Address sym = UnitHelper.findSymbolWithVersion("answer", "VERS_1.1");
42+
43+
int res = 0;
44+
// FIXME: Store answer()'s return value into res
45+
46+
assertEquals(42, res);
47+
}
48+
49+
@Test(expected = UnsatisfiedLinkError.class)
50+
public void future_answer() {
51+
UnitHelper.findSymbolWithVersion("answer", "VERS_1.2");
52+
}
53+
}

0 commit comments

Comments
 (0)