/*## (c) SECURITY EXPLORATIONS    2018 poland                                #*/
/*##     http://www.security-explorations.com                                #*/

/* THIS SOFTWARE IS PROTECTED BY DOMESTIC AND INTERNATIONAL COPYRIGHT LAWS    */
/* UNAUTHORISED COPYING OF THIS SOFTWARE IN EITHER SOURCE OR BINARY FORM IS   */
/* EXPRESSLY FORBIDDEN. ANY USE, INCLUDING THE REPRODUCTION, MODIFICATION,    */
/* DISTRIBUTION, TRANSMISSION, RE-PUBLICATION, STORAGE OR DISPLAY OF ANY      */
/* PART OF THE SOFTWARE, FOR COMMERCIAL OR ANY OTHER PURPOSES REQUIRES A      */
/* VALID LICENSE FROM THE COPYRIGHT HOLDER.                                   */

/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS    */
/* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,*/
/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    */
/* SECURITY EXPLORATIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
/* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF  */
/* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE     */
/* SOFTWARE.                                                                  */

import java.lang.*;
import java.lang.reflect.*;

public class Dl {
 public static final String DLOPENFUNC  = "__libc_dlopen_mode";
 public static final String DLSYMFUNC   = "__libc_dlsym";
 public static final String DLCLOSEFUNC = "__libc_dlclose";


 public static final int RTLD_LAZY	   = 0x00001;
 public static final int RTLD_NOW	   = 0x00002;
 public static final int RTLD_BINDING_MASK = 0x00003;
 public static final int RTLD_NOLOAD	   = 0x00004;
 public static final int RTLD_DEEPBIND	   = 0x00008;
 public static final int RTLD_GLOBAL	   = 0x00100;
 public static final int RTLD_NODELETE	   = 0x01000;

 private static int dlopen;
 private static int dlsym;
 private static int dlclose;

 static {
  dlopen=NativeCode.getInstance().get_libc_sym_addr(DLOPENFUNC);
  dlsym=NativeCode.getInstance().get_libc_sym_addr(DLSYMFUNC);
  dlclose=NativeCode.getInstance().get_libc_sym_addr(DLCLOSEFUNC);
 }

 public static int open_flags(String libname,int flags) {
  int cname=Utils.java2cstring(libname);
  int res=NativeCode.getInstance().invoke(dlopen,cname,flags,0,0,0,0,0,0);
  NativeCode.getInstance().free(cname);

  return res;
 }

 public static int open(String libname) {
  return open_flags(libname,RTLD_NOW);
 }

 public static int getsym(int handle,String symname) {
  int cname=Utils.java2cstring(symname);
  int res=NativeCode.getInstance().invoke(dlsym,handle,cname,0,0,0,0,0,0);
  NativeCode.getInstance().free(cname);

  return res;
 }

 public static void close(int handle) {
  NativeCode.getInstance().invoke(dlclose,handle,0,0,0,0,0,0,0);
 }

}
