jaulib v1.3.0
Jau Support Library (C++, Java, ..)
DynamicLinkerImpl.java
Go to the documentation of this file.
1/**
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2021 Gothel Software e.K.
4 * Copyright (c) 2013 Gothel Software e.K.
5 * Copyright (c) 2013 JogAmp Community.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining
8 * a copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sublicense, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26package jau.sys.dl;
27
28import java.util.HashMap;
29
30import org.jau.sec.SecurityUtil;
31import org.jau.sys.dl.DynamicLinker;
32
33/* pp */ abstract class DynamicLinkerImpl implements DynamicLinker {
34
35 //
36 // Package private scope of class w/ protected native code access
37 // and sealed jogamp.common.* package definition
38 // ensuring no abuse via subclassing.
39 //
40
41 private final Object secSync = new Object();
42 private boolean allLinkPermissionGranted = false;
43
44 /**
45 * @throws SecurityException if user is not granted global access
46 */
47 @Override
48public final void claimAllLinkPermission() throws SecurityException {
49 synchronized( secSync ) {
50 allLinkPermissionGranted = true;
51 }
52 }
53
54 /**
55 * @throws SecurityException if user is not granted global access
56 */
57 @Override
58public final void releaseAllLinkPermission() throws SecurityException {
59 synchronized( secSync ) {
60 allLinkPermissionGranted = false;
61 }
62 }
63
64 private final void checkLinkPermission(final String pathname) throws SecurityException {
65 synchronized( secSync ) {
66 if( !allLinkPermissionGranted ) {
67 SecurityUtil.checkLinkPermission(pathname);
68 }
69 }
70 }
71 private final void checkLinkPermission(final long libraryHandle) throws SecurityException {
72 synchronized( secSync ) {
73 if( !allLinkPermissionGranted ) {
74 final LibRef libRef = getLibRef( libraryHandle );
75 if( null == libRef ) {
76 throw new IllegalArgumentException("Library handle 0x"+Long.toHexString(libraryHandle)+" unknown.");
77 }
78 SecurityUtil.checkLinkPermission(libRef.getName());
79 }
80 }
81 }
82
83 private final void checkAllLinkPermission() throws SecurityException {
84 synchronized( secSync ) {
85 if( !allLinkPermissionGranted ) {
86 SecurityUtil.checkAllLinkPermission();
87 }
88 }
89 }
90
91 @Override
92 public final long openLibraryGlobal(final String pathname, final boolean debug) throws SecurityException {
93 checkLinkPermission(pathname);
94 final long handle = openLibraryGlobalImpl(pathname);
95 if( 0 != handle ) {
96 final LibRef libRef = incrLibRefCount(handle, pathname);
97 if( DEBUG || debug ) {
98 System.err.println("DynamicLinkerImpl.openLibraryGlobal \""+pathname+"\": 0x"+Long.toHexString(handle)+" -> "+libRef+")");
99 }
100 } else if ( DEBUG || debug ) {
101 System.err.println("DynamicLinkerImpl.openLibraryGlobal \""+pathname+"\" failed, error: "+getLastError());
102 }
103 return handle;
104 }
105 protected abstract long openLibraryGlobalImpl(final String pathname) throws SecurityException;
106
107 @Override
108 public final long openLibraryLocal(final String pathname, final boolean debug) throws SecurityException {
109 checkLinkPermission(pathname);
110 final long handle = openLibraryLocalImpl(pathname);
111 if( 0 != handle ) {
112 final LibRef libRef = incrLibRefCount(handle, pathname);
113 if( DEBUG || debug ) {
114 System.err.println("DynamicLinkerImpl.openLibraryLocal \""+pathname+"\": 0x"+Long.toHexString(handle)+" -> "+libRef+")");
115 }
116 } else if ( DEBUG || debug ) {
117 System.err.println("DynamicLinkerImpl.openLibraryLocal \""+pathname+"\" failed, error: "+getLastError());
118 }
119 return handle;
120 }
121 protected abstract long openLibraryLocalImpl(final String pathname) throws SecurityException;
122
123 @Override
124 public final long lookupSymbolGlobal(final String symbolName) throws SecurityException {
125 checkAllLinkPermission();
126 final long addr = lookupSymbolGlobalImpl(symbolName);
127 if(DEBUG_LOOKUP) {
128 System.err.println("DynamicLinkerImpl.lookupSymbolGlobal("+symbolName+") -> 0x"+Long.toHexString(addr));
129 }
130 return addr;
131 }
132 protected abstract long lookupSymbolGlobalImpl(final String symbolName) throws SecurityException;
133
134 @Override
135 public final long lookupSymbol(final long libraryHandle, final String symbolName) throws SecurityException, IllegalArgumentException {
136 checkLinkPermission(libraryHandle);
137 final long addr = lookupSymbolLocalImpl(libraryHandle, symbolName);
138 if(DEBUG_LOOKUP) {
139 System.err.println("DynamicLinkerImpl.lookupSymbol(0x"+Long.toHexString(libraryHandle)+", "+symbolName+") -> 0x"+Long.toHexString(addr));
140 }
141 return addr;
142 }
143 protected abstract long lookupSymbolLocalImpl(final long libraryHandle, final String symbolName) throws SecurityException;
144
145 @Override
146 public final void closeLibrary(final long libraryHandle, final boolean debug) throws SecurityException, IllegalArgumentException {
147 final LibRef libRef = decrLibRefCount( libraryHandle );
148 if( null != libRef ) {
149 checkLinkPermission(libRef.getName());
150 } // else null libRef is OK for global lookup
151 if( DEBUG || debug ) {
152 System.err.println("DynamicLinkerImpl.closeLibrary(0x"+Long.toHexString(libraryHandle)+" -> "+libRef+")");
153 }
154 if( 0 != libraryHandle ) {
155 closeLibraryImpl(libraryHandle);
156 }
157 }
158 protected abstract void closeLibraryImpl(final long libraryHandle) throws SecurityException;
159
160 private static final HashMap<Long,Object> libHandle2Name = new HashMap<Long,Object>( 16 /* initialCapacity */ );
161
162 static final class LibRef {
163 LibRef(final String name) {
164 this.name = name;
165 this.refCount = 1;
166 }
167 final int incrRefCount() { return ++refCount; }
168 final int decrRefCount() { return --refCount; }
169 final int getRefCount() { return refCount; }
170
171 final String getName() { return name; }
172 @Override
173 public final String toString() { return "LibRef["+name+", refCount "+refCount+"]"; }
174
175 private final String name;
176 private int refCount;
177 }
178
179 private final LibRef getLibRef(final long handle) {
180 synchronized( libHandle2Name ) {
181 return (LibRef) libHandle2Name.get(handle);
182 }
183 }
184
185 private final LibRef incrLibRefCount(final long handle, final String libName) {
186 synchronized( libHandle2Name ) {
187 LibRef libRef = getLibRef(handle);
188 if( null == libRef ) {
189 libRef = new LibRef(libName);
190 libHandle2Name.put(handle, libRef);
191 } else {
192 libRef.incrRefCount();
193 }
194 if(DEBUG) {
195 System.err.println("DynamicLinkerImpl.incrLibRefCount 0x"+Long.toHexString(handle)+ " -> "+libRef+", libs loaded "+libHandle2Name.size());
196 }
197 return libRef;
198 }
199 }
200
201 private final LibRef decrLibRefCount(final long handle) {
202 synchronized( libHandle2Name ) {
203 final LibRef libRef = getLibRef(handle);
204 if( null != libRef ) {
205 if( 0 == libRef.decrRefCount() ) {
206 libHandle2Name.remove(handle);
207 }
208 }
209 if(DEBUG) {
210 System.err.println("DynamicLinkerImpl.decrLibRefCount 0x"+Long.toHexString(handle)+ " -> "+libRef+", libs loaded "+libHandle2Name.size());
211 }
212 return libRef;
213 }
214 }
215}
String getLastError()
Returns a string containing the last error.