Merge "Optimization : Do not recurse into unexported Abi."
diff --git a/ndk/platforms/android-9/include/sys/cdefs.h b/ndk/platforms/android-9/include/sys/cdefs.h
index 9a8dfdd..eb9a654 100644
--- a/ndk/platforms/android-9/include/sys/cdefs.h
+++ b/ndk/platforms/android-9/include/sys/cdefs.h
@@ -86,6 +86,12 @@
 #define	__static_cast(x,y)	(x)y
 #endif
 
+#if defined(__cplusplus)
+#define __BIONIC_CAST(_k,_t,_v) (_k<_t>(_v))
+#else
+#define __BIONIC_CAST(_k,_t,_v) ((_t) (_v))
+#endif
+
 /*
  * The __CONCAT macro is used to concatenate parts of symbol names, e.g.
  * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo.
diff --git a/ndk/platforms/android-9/include/termios.h b/ndk/platforms/android-9/include/termios.h
index ad19089..fc991ab 100644
--- a/ndk/platforms/android-9/include/termios.h
+++ b/ndk/platforms/android-9/include/termios.h
@@ -108,6 +108,18 @@
     s->c_cflag |= CS8;
 }
 
+static __inline int cfsetspeed(struct termios* s, speed_t speed) {
+  // TODO: check 'speed' is valid.
+  s->c_cflag = (s->c_cflag & ~CBAUD) | (speed & CBAUD);
+  return 0;
+}
+
+static __inline int tcdrain(int fd) {
+  // A non-zero argument to TCSBRK means "don't send a break".
+  // The drain is a side-effect of the ioctl!
+  return ioctl(fd, TCSBRK, __BIONIC_CAST(static_cast, unsigned long, 1));
+}
+
 __END_DECLS
 
 #endif /* _TERMIOS_H_ */
diff --git a/vndk/tools/definition-tool/tests/compat.py b/vndk/tools/definition-tool/tests/compat.py
index 16197fd..f9d83e7 100644
--- a/vndk/tools/definition-tool/tests/compat.py
+++ b/vndk/tools/definition-tool/tests/compat.py
@@ -35,7 +35,7 @@
             return
         return os.makedirs(path)
 
-try:
+if sys.version_info >= (3, 0):
     from io import StringIO
-except ImportError:
+else:
     from StringIO import StringIO
diff --git a/vndk/tools/definition-tool/tests/expected/arm/libtest-rpath-multi.so.txt b/vndk/tools/definition-tool/tests/expected/arm/libtest-rpath-multi.so.txt
new file mode 100644
index 0000000..59db4c5
--- /dev/null
+++ b/vndk/tools/definition-tool/tests/expected/arm/libtest-rpath-multi.so.txt
@@ -0,0 +1,13 @@
+EI_CLASS	32
+EI_DATA		Little-Endian
+E_MACHINE	EM_ARM
+DT_RPATH	/system/lib
+DT_RPATH	/vendor/lib
+DT_NEEDED	libc.so
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/arm/libtest-rpath.so.txt b/vndk/tools/definition-tool/tests/expected/arm/libtest-rpath.so.txt
index bd73f72..1c19446 100644
--- a/vndk/tools/definition-tool/tests/expected/arm/libtest-rpath.so.txt
+++ b/vndk/tools/definition-tool/tests/expected/arm/libtest-rpath.so.txt
@@ -3,7 +3,10 @@
 E_MACHINE	EM_ARM
 DT_RPATH	$ORIGIN/../lib
 DT_NEEDED	libc.so
-SYMBOL		__bss_start
-SYMBOL		_edata
-SYMBOL		_end
-SYMBOL		test
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/arm/libtest-runpath-multi.so.txt b/vndk/tools/definition-tool/tests/expected/arm/libtest-runpath-multi.so.txt
new file mode 100644
index 0000000..0d42f82
--- /dev/null
+++ b/vndk/tools/definition-tool/tests/expected/arm/libtest-runpath-multi.so.txt
@@ -0,0 +1,13 @@
+EI_CLASS	32
+EI_DATA		Little-Endian
+E_MACHINE	EM_ARM
+DT_RUNPATH	/system/lib
+DT_RUNPATH	/vendor/lib
+DT_NEEDED	libc.so
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/arm/libtest-runpath.so.txt b/vndk/tools/definition-tool/tests/expected/arm/libtest-runpath.so.txt
index d60d172..ab70935 100644
--- a/vndk/tools/definition-tool/tests/expected/arm/libtest-runpath.so.txt
+++ b/vndk/tools/definition-tool/tests/expected/arm/libtest-runpath.so.txt
@@ -3,7 +3,10 @@
 E_MACHINE	EM_ARM
 DT_RUNPATH	$ORIGIN/../lib
 DT_NEEDED	libc.so
-SYMBOL		__bss_start
-SYMBOL		_edata
-SYMBOL		_end
-SYMBOL		test
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/arm/libtest.so.txt b/vndk/tools/definition-tool/tests/expected/arm/libtest.so.txt
index a0439943..54f89ae 100644
--- a/vndk/tools/definition-tool/tests/expected/arm/libtest.so.txt
+++ b/vndk/tools/definition-tool/tests/expected/arm/libtest.so.txt
@@ -2,7 +2,10 @@
 EI_DATA		Little-Endian
 E_MACHINE	EM_ARM
 DT_NEEDED	libc.so
-SYMBOL		__bss_start
-SYMBOL		_edata
-SYMBOL		_end
-SYMBOL		test
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/arm/main.out.txt b/vndk/tools/definition-tool/tests/expected/arm/main.out.txt
index 10f9d05..7f5dbac 100644
--- a/vndk/tools/definition-tool/tests/expected/arm/main.out.txt
+++ b/vndk/tools/definition-tool/tests/expected/arm/main.out.txt
@@ -4,6 +4,12 @@
 DT_NEEDED	libdl.so
 DT_NEEDED	libc.so
 DT_NEEDED	libstdc++.so
-SYMBOL		__bss_start
-SYMBOL		_edata
-SYMBOL		_end
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__libc_init
+IMP_SYMBOL	dlclose
+IMP_SYMBOL	dlopen
+IMP_SYMBOL	dlsym
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/arm64/libtest-rpath-multi.so.txt b/vndk/tools/definition-tool/tests/expected/arm64/libtest-rpath-multi.so.txt
new file mode 100644
index 0000000..2cece74
--- /dev/null
+++ b/vndk/tools/definition-tool/tests/expected/arm64/libtest-rpath-multi.so.txt
@@ -0,0 +1,17 @@
+EI_CLASS	64
+EI_DATA		Little-Endian
+E_MACHINE	EM_AARCH64
+DT_RPATH	/system/lib
+DT_RPATH	/vendor/lib
+DT_NEEDED	libc.so
+EXP_SYMBOL	__bss_end__
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	__bss_start__
+EXP_SYMBOL	__end__
+EXP_SYMBOL	_bss_end__
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/arm64/libtest-rpath.so.txt b/vndk/tools/definition-tool/tests/expected/arm64/libtest-rpath.so.txt
index 72ed3da..028080e 100644
--- a/vndk/tools/definition-tool/tests/expected/arm64/libtest-rpath.so.txt
+++ b/vndk/tools/definition-tool/tests/expected/arm64/libtest-rpath.so.txt
@@ -3,11 +3,14 @@
 E_MACHINE	EM_AARCH64
 DT_RPATH	$ORIGIN/../lib
 DT_NEEDED	libc.so
-SYMBOL		__bss_end__
-SYMBOL		__bss_start
-SYMBOL		__bss_start__
-SYMBOL		__end__
-SYMBOL		_bss_end__
-SYMBOL		_edata
-SYMBOL		_end
-SYMBOL		test
+EXP_SYMBOL	__bss_end__
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	__bss_start__
+EXP_SYMBOL	__end__
+EXP_SYMBOL	_bss_end__
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/arm64/libtest-runpath-multi.so.txt b/vndk/tools/definition-tool/tests/expected/arm64/libtest-runpath-multi.so.txt
new file mode 100644
index 0000000..2d97f6d
--- /dev/null
+++ b/vndk/tools/definition-tool/tests/expected/arm64/libtest-runpath-multi.so.txt
@@ -0,0 +1,17 @@
+EI_CLASS	64
+EI_DATA		Little-Endian
+E_MACHINE	EM_AARCH64
+DT_RUNPATH	/system/lib
+DT_RUNPATH	/vendor/lib
+DT_NEEDED	libc.so
+EXP_SYMBOL	__bss_end__
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	__bss_start__
+EXP_SYMBOL	__end__
+EXP_SYMBOL	_bss_end__
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/arm64/libtest-runpath.so.txt b/vndk/tools/definition-tool/tests/expected/arm64/libtest-runpath.so.txt
index 0754c32..eb88f22 100644
--- a/vndk/tools/definition-tool/tests/expected/arm64/libtest-runpath.so.txt
+++ b/vndk/tools/definition-tool/tests/expected/arm64/libtest-runpath.so.txt
@@ -3,11 +3,14 @@
 E_MACHINE	EM_AARCH64
 DT_RUNPATH	$ORIGIN/../lib
 DT_NEEDED	libc.so
-SYMBOL		__bss_end__
-SYMBOL		__bss_start
-SYMBOL		__bss_start__
-SYMBOL		__end__
-SYMBOL		_bss_end__
-SYMBOL		_edata
-SYMBOL		_end
-SYMBOL		test
+EXP_SYMBOL	__bss_end__
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	__bss_start__
+EXP_SYMBOL	__end__
+EXP_SYMBOL	_bss_end__
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/arm64/libtest.so.txt b/vndk/tools/definition-tool/tests/expected/arm64/libtest.so.txt
index 7f00e9f..4b2bac6 100644
--- a/vndk/tools/definition-tool/tests/expected/arm64/libtest.so.txt
+++ b/vndk/tools/definition-tool/tests/expected/arm64/libtest.so.txt
@@ -2,11 +2,14 @@
 EI_DATA		Little-Endian
 E_MACHINE	EM_AARCH64
 DT_NEEDED	libc.so
-SYMBOL		__bss_end__
-SYMBOL		__bss_start
-SYMBOL		__bss_start__
-SYMBOL		__end__
-SYMBOL		_bss_end__
-SYMBOL		_edata
-SYMBOL		_end
-SYMBOL		test
+EXP_SYMBOL	__bss_end__
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	__bss_start__
+EXP_SYMBOL	__end__
+EXP_SYMBOL	_bss_end__
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/arm64/main.out.txt b/vndk/tools/definition-tool/tests/expected/arm64/main.out.txt
index 57691c1..c1750e3 100644
--- a/vndk/tools/definition-tool/tests/expected/arm64/main.out.txt
+++ b/vndk/tools/definition-tool/tests/expected/arm64/main.out.txt
@@ -4,14 +4,20 @@
 DT_NEEDED	libdl.so
 DT_NEEDED	libc.so
 DT_NEEDED	libstdc++.so
-SYMBOL		__FINI_ARRAY__
-SYMBOL		__INIT_ARRAY__
-SYMBOL		__PREINIT_ARRAY__
-SYMBOL		__bss_end__
-SYMBOL		__bss_start
-SYMBOL		__bss_start__
-SYMBOL		__end__
-SYMBOL		_bss_end__
-SYMBOL		_edata
-SYMBOL		_end
-SYMBOL		main
+EXP_SYMBOL	__FINI_ARRAY__
+EXP_SYMBOL	__INIT_ARRAY__
+EXP_SYMBOL	__PREINIT_ARRAY__
+EXP_SYMBOL	__bss_end__
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	__bss_start__
+EXP_SYMBOL	__end__
+EXP_SYMBOL	_bss_end__
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	main
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__libc_init
+IMP_SYMBOL	dlclose
+IMP_SYMBOL	dlopen
+IMP_SYMBOL	dlsym
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/mips/libtest-rpath-multi.so.txt b/vndk/tools/definition-tool/tests/expected/mips/libtest-rpath-multi.so.txt
new file mode 100644
index 0000000..e560cc9
--- /dev/null
+++ b/vndk/tools/definition-tool/tests/expected/mips/libtest-rpath-multi.so.txt
@@ -0,0 +1,20 @@
+EI_CLASS	32
+EI_DATA		Little-Endian
+E_MACHINE	EM_MIPS
+DT_RPATH	/system/lib
+DT_RPATH	/vendor/lib
+DT_NEEDED	libc.so
+EXP_SYMBOL	__bss_end__
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	__end__
+EXP_SYMBOL	_bss_end__
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	_fbss
+EXP_SYMBOL	_fdata
+EXP_SYMBOL	_ftext
+EXP_SYMBOL	_gp_disp
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/mips/libtest-rpath.so.txt b/vndk/tools/definition-tool/tests/expected/mips/libtest-rpath.so.txt
index 647d419..45a48aa 100644
--- a/vndk/tools/definition-tool/tests/expected/mips/libtest-rpath.so.txt
+++ b/vndk/tools/definition-tool/tests/expected/mips/libtest-rpath.so.txt
@@ -3,14 +3,17 @@
 E_MACHINE	EM_MIPS
 DT_RPATH	$ORIGIN/../lib
 DT_NEEDED	libc.so
-SYMBOL		__bss_end__
-SYMBOL		__bss_start
-SYMBOL		__end__
-SYMBOL		_bss_end__
-SYMBOL		_edata
-SYMBOL		_end
-SYMBOL		_fbss
-SYMBOL		_fdata
-SYMBOL		_ftext
-SYMBOL		_gp_disp
-SYMBOL		test
+EXP_SYMBOL	__bss_end__
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	__end__
+EXP_SYMBOL	_bss_end__
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	_fbss
+EXP_SYMBOL	_fdata
+EXP_SYMBOL	_ftext
+EXP_SYMBOL	_gp_disp
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/mips/libtest-runpath-multi.so.txt b/vndk/tools/definition-tool/tests/expected/mips/libtest-runpath-multi.so.txt
new file mode 100644
index 0000000..51b821b
--- /dev/null
+++ b/vndk/tools/definition-tool/tests/expected/mips/libtest-runpath-multi.so.txt
@@ -0,0 +1,20 @@
+EI_CLASS	32
+EI_DATA		Little-Endian
+E_MACHINE	EM_MIPS
+DT_RUNPATH	/system/lib
+DT_RUNPATH	/vendor/lib
+DT_NEEDED	libc.so
+EXP_SYMBOL	__bss_end__
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	__end__
+EXP_SYMBOL	_bss_end__
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	_fbss
+EXP_SYMBOL	_fdata
+EXP_SYMBOL	_ftext
+EXP_SYMBOL	_gp_disp
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/mips/libtest-runpath.so.txt b/vndk/tools/definition-tool/tests/expected/mips/libtest-runpath.so.txt
index 15a93cd..0400e61 100644
--- a/vndk/tools/definition-tool/tests/expected/mips/libtest-runpath.so.txt
+++ b/vndk/tools/definition-tool/tests/expected/mips/libtest-runpath.so.txt
@@ -3,14 +3,17 @@
 E_MACHINE	EM_MIPS
 DT_RUNPATH	$ORIGIN/../lib
 DT_NEEDED	libc.so
-SYMBOL		__bss_end__
-SYMBOL		__bss_start
-SYMBOL		__end__
-SYMBOL		_bss_end__
-SYMBOL		_edata
-SYMBOL		_end
-SYMBOL		_fbss
-SYMBOL		_fdata
-SYMBOL		_ftext
-SYMBOL		_gp_disp
-SYMBOL		test
+EXP_SYMBOL	__bss_end__
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	__end__
+EXP_SYMBOL	_bss_end__
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	_fbss
+EXP_SYMBOL	_fdata
+EXP_SYMBOL	_ftext
+EXP_SYMBOL	_gp_disp
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/mips/libtest.so.txt b/vndk/tools/definition-tool/tests/expected/mips/libtest.so.txt
index 97fa2ce..ff112d5 100644
--- a/vndk/tools/definition-tool/tests/expected/mips/libtest.so.txt
+++ b/vndk/tools/definition-tool/tests/expected/mips/libtest.so.txt
@@ -2,14 +2,17 @@
 EI_DATA		Little-Endian
 E_MACHINE	EM_MIPS
 DT_NEEDED	libc.so
-SYMBOL		__bss_end__
-SYMBOL		__bss_start
-SYMBOL		__end__
-SYMBOL		_bss_end__
-SYMBOL		_edata
-SYMBOL		_end
-SYMBOL		_fbss
-SYMBOL		_fdata
-SYMBOL		_ftext
-SYMBOL		_gp_disp
-SYMBOL		test
+EXP_SYMBOL	__bss_end__
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	__end__
+EXP_SYMBOL	_bss_end__
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	_fbss
+EXP_SYMBOL	_fdata
+EXP_SYMBOL	_ftext
+EXP_SYMBOL	_gp_disp
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/mips/main.out.txt b/vndk/tools/definition-tool/tests/expected/mips/main.out.txt
index 3261684..5a81d93 100644
--- a/vndk/tools/definition-tool/tests/expected/mips/main.out.txt
+++ b/vndk/tools/definition-tool/tests/expected/mips/main.out.txt
@@ -4,20 +4,26 @@
 DT_NEEDED	libdl.so
 DT_NEEDED	libc.so
 DT_NEEDED	libstdc++.so
-SYMBOL		_DYNAMIC_LINKING
-SYMBOL		__CTOR_LIST__
-SYMBOL		__DTOR_LIST__
-SYMBOL		__FINI_ARRAY__
-SYMBOL		__INIT_ARRAY__
-SYMBOL		__PREINIT_ARRAY__
-SYMBOL		__RLD_MAP
-SYMBOL		__bss_end__
-SYMBOL		__bss_start
-SYMBOL		__end__
-SYMBOL		_bss_end__
-SYMBOL		_edata
-SYMBOL		_end
-SYMBOL		_fbss
-SYMBOL		_fdata
-SYMBOL		_ftext
-SYMBOL		main
+EXP_SYMBOL	_DYNAMIC_LINKING
+EXP_SYMBOL	__CTOR_LIST__
+EXP_SYMBOL	__DTOR_LIST__
+EXP_SYMBOL	__FINI_ARRAY__
+EXP_SYMBOL	__INIT_ARRAY__
+EXP_SYMBOL	__PREINIT_ARRAY__
+EXP_SYMBOL	__RLD_MAP
+EXP_SYMBOL	__bss_end__
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	__end__
+EXP_SYMBOL	_bss_end__
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	_fbss
+EXP_SYMBOL	_fdata
+EXP_SYMBOL	_ftext
+EXP_SYMBOL	main
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__libc_init
+IMP_SYMBOL	dlclose
+IMP_SYMBOL	dlopen
+IMP_SYMBOL	dlsym
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/mips64/libtest-rpath-multi.so.txt b/vndk/tools/definition-tool/tests/expected/mips64/libtest-rpath-multi.so.txt
new file mode 100644
index 0000000..cb3216e
--- /dev/null
+++ b/vndk/tools/definition-tool/tests/expected/mips64/libtest-rpath-multi.so.txt
@@ -0,0 +1,19 @@
+EI_CLASS	64
+EI_DATA		Little-Endian
+E_MACHINE	EM_MIPS
+DT_RPATH	/system/lib
+DT_RPATH	/vendor/lib
+DT_NEEDED	libc.so
+EXP_SYMBOL	__bss_end__
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	__end__
+EXP_SYMBOL	_bss_end__
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	_fbss
+EXP_SYMBOL	_fdata
+EXP_SYMBOL	_ftext
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/mips64/libtest-rpath.so.txt b/vndk/tools/definition-tool/tests/expected/mips64/libtest-rpath.so.txt
index 7a69f16..6cc3272 100644
--- a/vndk/tools/definition-tool/tests/expected/mips64/libtest-rpath.so.txt
+++ b/vndk/tools/definition-tool/tests/expected/mips64/libtest-rpath.so.txt
@@ -3,13 +3,16 @@
 E_MACHINE	EM_MIPS
 DT_RPATH	$ORIGIN/../lib
 DT_NEEDED	libc.so
-SYMBOL		__bss_end__
-SYMBOL		__bss_start
-SYMBOL		__end__
-SYMBOL		_bss_end__
-SYMBOL		_edata
-SYMBOL		_end
-SYMBOL		_fbss
-SYMBOL		_fdata
-SYMBOL		_ftext
-SYMBOL		test
+EXP_SYMBOL	__bss_end__
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	__end__
+EXP_SYMBOL	_bss_end__
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	_fbss
+EXP_SYMBOL	_fdata
+EXP_SYMBOL	_ftext
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/mips64/libtest-runpath-multi.so.txt b/vndk/tools/definition-tool/tests/expected/mips64/libtest-runpath-multi.so.txt
new file mode 100644
index 0000000..86578ac
--- /dev/null
+++ b/vndk/tools/definition-tool/tests/expected/mips64/libtest-runpath-multi.so.txt
@@ -0,0 +1,19 @@
+EI_CLASS	64
+EI_DATA		Little-Endian
+E_MACHINE	EM_MIPS
+DT_RUNPATH	/system/lib
+DT_RUNPATH	/vendor/lib
+DT_NEEDED	libc.so
+EXP_SYMBOL	__bss_end__
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	__end__
+EXP_SYMBOL	_bss_end__
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	_fbss
+EXP_SYMBOL	_fdata
+EXP_SYMBOL	_ftext
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/mips64/libtest-runpath.so.txt b/vndk/tools/definition-tool/tests/expected/mips64/libtest-runpath.so.txt
index cbe0d44..be2b32b 100644
--- a/vndk/tools/definition-tool/tests/expected/mips64/libtest-runpath.so.txt
+++ b/vndk/tools/definition-tool/tests/expected/mips64/libtest-runpath.so.txt
@@ -3,13 +3,16 @@
 E_MACHINE	EM_MIPS
 DT_RUNPATH	$ORIGIN/../lib
 DT_NEEDED	libc.so
-SYMBOL		__bss_end__
-SYMBOL		__bss_start
-SYMBOL		__end__
-SYMBOL		_bss_end__
-SYMBOL		_edata
-SYMBOL		_end
-SYMBOL		_fbss
-SYMBOL		_fdata
-SYMBOL		_ftext
-SYMBOL		test
+EXP_SYMBOL	__bss_end__
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	__end__
+EXP_SYMBOL	_bss_end__
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	_fbss
+EXP_SYMBOL	_fdata
+EXP_SYMBOL	_ftext
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/mips64/libtest.so.txt b/vndk/tools/definition-tool/tests/expected/mips64/libtest.so.txt
index 270e60d..fe0f6bb 100644
--- a/vndk/tools/definition-tool/tests/expected/mips64/libtest.so.txt
+++ b/vndk/tools/definition-tool/tests/expected/mips64/libtest.so.txt
@@ -2,13 +2,16 @@
 EI_DATA		Little-Endian
 E_MACHINE	EM_MIPS
 DT_NEEDED	libc.so
-SYMBOL		__bss_end__
-SYMBOL		__bss_start
-SYMBOL		__end__
-SYMBOL		_bss_end__
-SYMBOL		_edata
-SYMBOL		_end
-SYMBOL		_fbss
-SYMBOL		_fdata
-SYMBOL		_ftext
-SYMBOL		test
+EXP_SYMBOL	__bss_end__
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	__end__
+EXP_SYMBOL	_bss_end__
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	_fbss
+EXP_SYMBOL	_fdata
+EXP_SYMBOL	_ftext
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/mips64/main.out.txt b/vndk/tools/definition-tool/tests/expected/mips64/main.out.txt
index 7e7150c..441a815 100644
--- a/vndk/tools/definition-tool/tests/expected/mips64/main.out.txt
+++ b/vndk/tools/definition-tool/tests/expected/mips64/main.out.txt
@@ -4,18 +4,24 @@
 DT_NEEDED	libdl.so
 DT_NEEDED	libc.so
 DT_NEEDED	libstdc++.so
-SYMBOL		_DYNAMIC_LINKING
-SYMBOL		__FINI_ARRAY__
-SYMBOL		__INIT_ARRAY__
-SYMBOL		__PREINIT_ARRAY__
-SYMBOL		__RLD_MAP
-SYMBOL		__bss_end__
-SYMBOL		__bss_start
-SYMBOL		__end__
-SYMBOL		_bss_end__
-SYMBOL		_edata
-SYMBOL		_end
-SYMBOL		_fbss
-SYMBOL		_fdata
-SYMBOL		_ftext
-SYMBOL		main
+EXP_SYMBOL	_DYNAMIC_LINKING
+EXP_SYMBOL	__FINI_ARRAY__
+EXP_SYMBOL	__INIT_ARRAY__
+EXP_SYMBOL	__PREINIT_ARRAY__
+EXP_SYMBOL	__RLD_MAP
+EXP_SYMBOL	__bss_end__
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	__end__
+EXP_SYMBOL	_bss_end__
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	_fbss
+EXP_SYMBOL	_fdata
+EXP_SYMBOL	_ftext
+EXP_SYMBOL	main
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__libc_init
+IMP_SYMBOL	dlclose
+IMP_SYMBOL	dlopen
+IMP_SYMBOL	dlsym
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/x86/libtest-rpath-multi.so.txt b/vndk/tools/definition-tool/tests/expected/x86/libtest-rpath-multi.so.txt
new file mode 100644
index 0000000..73b0e89
--- /dev/null
+++ b/vndk/tools/definition-tool/tests/expected/x86/libtest-rpath-multi.so.txt
@@ -0,0 +1,14 @@
+EI_CLASS	32
+EI_DATA		Little-Endian
+E_MACHINE	EM_386
+DT_RPATH	/system/lib
+DT_RPATH	/vendor/lib
+DT_NEEDED	libc.so
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	__stack_chk_fail
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/x86/libtest-rpath.so.txt b/vndk/tools/definition-tool/tests/expected/x86/libtest-rpath.so.txt
index bb90882..f974860 100644
--- a/vndk/tools/definition-tool/tests/expected/x86/libtest-rpath.so.txt
+++ b/vndk/tools/definition-tool/tests/expected/x86/libtest-rpath.so.txt
@@ -3,7 +3,11 @@
 E_MACHINE	EM_386
 DT_RPATH	$ORIGIN/../lib
 DT_NEEDED	libc.so
-SYMBOL		__bss_start
-SYMBOL		_edata
-SYMBOL		_end
-SYMBOL		test
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	__stack_chk_fail
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/x86/libtest-runpath-multi.so.txt b/vndk/tools/definition-tool/tests/expected/x86/libtest-runpath-multi.so.txt
new file mode 100644
index 0000000..301c13d
--- /dev/null
+++ b/vndk/tools/definition-tool/tests/expected/x86/libtest-runpath-multi.so.txt
@@ -0,0 +1,14 @@
+EI_CLASS	32
+EI_DATA		Little-Endian
+E_MACHINE	EM_386
+DT_RUNPATH	/system/lib
+DT_RUNPATH	/vendor/lib
+DT_NEEDED	libc.so
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	__stack_chk_fail
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/x86/libtest-runpath.so.txt b/vndk/tools/definition-tool/tests/expected/x86/libtest-runpath.so.txt
index 55c338e..944a98c 100644
--- a/vndk/tools/definition-tool/tests/expected/x86/libtest-runpath.so.txt
+++ b/vndk/tools/definition-tool/tests/expected/x86/libtest-runpath.so.txt
@@ -3,7 +3,11 @@
 E_MACHINE	EM_386
 DT_RUNPATH	$ORIGIN/../lib
 DT_NEEDED	libc.so
-SYMBOL		__bss_start
-SYMBOL		_edata
-SYMBOL		_end
-SYMBOL		test
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	__stack_chk_fail
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/x86/libtest.so.txt b/vndk/tools/definition-tool/tests/expected/x86/libtest.so.txt
index cf33758..992f48b 100644
--- a/vndk/tools/definition-tool/tests/expected/x86/libtest.so.txt
+++ b/vndk/tools/definition-tool/tests/expected/x86/libtest.so.txt
@@ -2,7 +2,11 @@
 EI_DATA		Little-Endian
 E_MACHINE	EM_386
 DT_NEEDED	libc.so
-SYMBOL		__bss_start
-SYMBOL		_edata
-SYMBOL		_end
-SYMBOL		test
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	__stack_chk_fail
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/x86/main.out.txt b/vndk/tools/definition-tool/tests/expected/x86/main.out.txt
index 45c33b8..ec0edb9 100644
--- a/vndk/tools/definition-tool/tests/expected/x86/main.out.txt
+++ b/vndk/tools/definition-tool/tests/expected/x86/main.out.txt
@@ -4,6 +4,13 @@
 DT_NEEDED	libdl.so
 DT_NEEDED	libc.so
 DT_NEEDED	libstdc++.so
-SYMBOL		__bss_start
-SYMBOL		_edata
-SYMBOL		_end
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__libc_init
+IMP_SYMBOL	__stack_chk_fail
+IMP_SYMBOL	dlclose
+IMP_SYMBOL	dlopen
+IMP_SYMBOL	dlsym
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/x86_64/libtest-rpath-multi.so.txt b/vndk/tools/definition-tool/tests/expected/x86_64/libtest-rpath-multi.so.txt
new file mode 100644
index 0000000..efa204f
--- /dev/null
+++ b/vndk/tools/definition-tool/tests/expected/x86_64/libtest-rpath-multi.so.txt
@@ -0,0 +1,13 @@
+EI_CLASS	64
+EI_DATA		Little-Endian
+E_MACHINE	EM_X86_64
+DT_RPATH	/system/lib
+DT_RPATH	/vendor/lib
+DT_NEEDED	libc.so
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/x86_64/libtest-rpath.so.txt b/vndk/tools/definition-tool/tests/expected/x86_64/libtest-rpath.so.txt
index 2ec92a1..5fc5b01 100644
--- a/vndk/tools/definition-tool/tests/expected/x86_64/libtest-rpath.so.txt
+++ b/vndk/tools/definition-tool/tests/expected/x86_64/libtest-rpath.so.txt
@@ -3,7 +3,10 @@
 E_MACHINE	EM_X86_64
 DT_RPATH	$ORIGIN/../lib
 DT_NEEDED	libc.so
-SYMBOL		__bss_start
-SYMBOL		_edata
-SYMBOL		_end
-SYMBOL		test
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/x86_64/libtest-runpath-multi.so.txt b/vndk/tools/definition-tool/tests/expected/x86_64/libtest-runpath-multi.so.txt
new file mode 100644
index 0000000..bad50ed
--- /dev/null
+++ b/vndk/tools/definition-tool/tests/expected/x86_64/libtest-runpath-multi.so.txt
@@ -0,0 +1,13 @@
+EI_CLASS	64
+EI_DATA		Little-Endian
+E_MACHINE	EM_X86_64
+DT_RUNPATH	/system/lib
+DT_RUNPATH	/vendor/lib
+DT_NEEDED	libc.so
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/x86_64/libtest-runpath.so.txt b/vndk/tools/definition-tool/tests/expected/x86_64/libtest-runpath.so.txt
index ebdf490..adf06b4 100644
--- a/vndk/tools/definition-tool/tests/expected/x86_64/libtest-runpath.so.txt
+++ b/vndk/tools/definition-tool/tests/expected/x86_64/libtest-runpath.so.txt
@@ -3,7 +3,10 @@
 E_MACHINE	EM_X86_64
 DT_RUNPATH	$ORIGIN/../lib
 DT_NEEDED	libc.so
-SYMBOL		__bss_start
-SYMBOL		_edata
-SYMBOL		_end
-SYMBOL		test
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/x86_64/libtest.so.txt b/vndk/tools/definition-tool/tests/expected/x86_64/libtest.so.txt
index 62dc31a..c9f14fe 100644
--- a/vndk/tools/definition-tool/tests/expected/x86_64/libtest.so.txt
+++ b/vndk/tools/definition-tool/tests/expected/x86_64/libtest.so.txt
@@ -2,7 +2,10 @@
 EI_DATA		Little-Endian
 E_MACHINE	EM_X86_64
 DT_NEEDED	libc.so
-SYMBOL		__bss_start
-SYMBOL		_edata
-SYMBOL		_end
-SYMBOL		test
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+EXP_SYMBOL	test
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__cxa_finalize
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/expected/x86_64/main.out.txt b/vndk/tools/definition-tool/tests/expected/x86_64/main.out.txt
index 888a4cf..3a63951 100644
--- a/vndk/tools/definition-tool/tests/expected/x86_64/main.out.txt
+++ b/vndk/tools/definition-tool/tests/expected/x86_64/main.out.txt
@@ -4,6 +4,12 @@
 DT_NEEDED	libdl.so
 DT_NEEDED	libc.so
 DT_NEEDED	libstdc++.so
-SYMBOL		__bss_start
-SYMBOL		_edata
-SYMBOL		_end
+EXP_SYMBOL	__bss_start
+EXP_SYMBOL	_edata
+EXP_SYMBOL	_end
+IMP_SYMBOL	__cxa_atexit
+IMP_SYMBOL	__libc_init
+IMP_SYMBOL	dlclose
+IMP_SYMBOL	dlopen
+IMP_SYMBOL	dlsym
+IMP_SYMBOL	puts
diff --git a/vndk/tools/definition-tool/tests/test_elf.py b/vndk/tools/definition-tool/tests/test_elf.py
index e3065af..d8153b5 100755
--- a/vndk/tools/definition-tool/tests/test_elf.py
+++ b/vndk/tools/definition-tool/tests/test_elf.py
@@ -39,6 +39,15 @@
 
 
 class ELFTest(unittest.TestCase):
+    def test_repr(self):
+        elf = ELF()
+        self.assertEqual(elf, eval(repr(elf)))
+
+        elf = ELF(ei_class=ELF.ELFCLASS32, ei_data=ELF.ELFDATA2LSB,
+                  e_machine=183, dt_rpath=['a'], dt_runpath=['b'],
+                  dt_needed=['c', 'd'], exported_symbols={'e', 'f', 'g'})
+        self.assertEqual(elf, eval(repr(elf)))
+
     def test_class_name(self):
         self.assertEqual('None', ELF().elf_class_name)
 
@@ -69,20 +78,20 @@
 
     def test_dt_rpath_runpath(self):
         elf = ELF()
-        self.assertEqual(None, elf.dt_rpath)
-        self.assertEqual(None, elf.dt_runpath)
+        self.assertEqual([], elf.dt_rpath)
+        self.assertEqual([], elf.dt_runpath)
 
-        elf = ELF(None, None, 0, 'a', 'b')
-        self.assertEqual('a', elf.dt_rpath)
-        self.assertEqual('b', elf.dt_runpath)
+        elf = ELF(None, None, 0, ['a'], ['b'])
+        self.assertEqual(['a'], elf.dt_rpath)
+        self.assertEqual(['b'], elf.dt_runpath)
 
     def test_dump(self):
-        elf = ELF(ELF.ELFCLASS32, ELF.ELFDATA2LSB, 183, 'a', 'b',
-                  ['libc.so', 'libm.so'], ['hello', 'world'])
+        elf = ELF(ELF.ELFCLASS32, ELF.ELFDATA2LSB, 183, ['a'], ['b'],
+                  ['libc.so', 'libm.so'], {'hello', 'world'}, {'d', 'e'})
 
-        with StringIO() as f:
-            elf.dump(f)
-            actual_output = f.getvalue()
+        f = StringIO()
+        elf.dump(f)
+        actual_output = f.getvalue()
 
         self.assertEqual('EI_CLASS\t32\n'
                          'EI_DATA\t\tLittle-Endian\n'
@@ -91,17 +100,19 @@
                          'DT_RUNPATH\tb\n'
                          'DT_NEEDED\tlibc.so\n'
                          'DT_NEEDED\tlibm.so\n'
-                         'SYMBOL\t\thello\n'
-                         'SYMBOL\t\tworld\n',
+                         'EXP_SYMBOL\thello\n'
+                         'EXP_SYMBOL\tworld\n'
+                         'IMP_SYMBOL\td\n'
+                         'IMP_SYMBOL\te\n',
                          actual_output)
 
     def test_dump_exported_symbols(self):
-        elf = ELF(ELF.ELFCLASS32, ELF.ELFDATA2LSB, 183, 'a', 'b',
-                  ['libc.so', 'libm.so'], ['hello', 'world'])
+        elf = ELF(ELF.ELFCLASS32, ELF.ELFDATA2LSB, 183, ['a'], ['b'],
+                  ['libc.so', 'libm.so'], {'hello', 'world'})
 
-        with StringIO() as f:
-            elf.dump_exported_symbols(f)
-            actual_output = f.getvalue()
+        f = StringIO()
+        elf.dump_exported_symbols(f)
+        actual_output = f.getvalue()
 
         self.assertEqual('hello\nworld\n', actual_output)
 
diff --git a/vndk/tools/definition-tool/tests/test_elf_linker.py b/vndk/tools/definition-tool/tests/test_elf_linker.py
new file mode 100755
index 0000000..73fecce
--- /dev/null
+++ b/vndk/tools/definition-tool/tests/test_elf_linker.py
@@ -0,0 +1,202 @@
+#!/usr/bin/env python3
+
+from __future__ import print_function
+
+import os
+import sys
+sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+
+import unittest
+
+from compat import StringIO
+from vndk_definition_tool import ELF, ELFLinker, PT_SYSTEM, PT_VENDOR
+
+
+class GraphBuilder(object):
+    _PARTITION_NAMES = {
+        PT_SYSTEM: 'system',
+        PT_VENDOR: 'vendor',
+    }
+
+    _LIB_DIRS = {
+        ELF.ELFCLASS32: 'lib',
+        ELF.ELFCLASS64: 'lib64',
+    }
+
+    def __init__(self):
+        self.graph = ELFLinker()
+
+    def add_lib(self, partition, klass, name, dt_needed, exported_symbols,
+                imported_symbols):
+        """Create and add a shared library to ELFLinker."""
+
+        elf = ELF(klass, ELF.ELFDATA2LSB, dt_needed=dt_needed,
+                  exported_symbols=exported_symbols,
+                  imported_symbols=imported_symbols)
+        setattr(self, 'elf' + elf.elf_class_name + '_' + name, elf)
+
+        path = os.path.join('/', self._PARTITION_NAMES[partition],
+                            self._LIB_DIRS[klass], name + '.so')
+        self.graph.add(partition, path, elf)
+
+    def add_multilib(self, partition, name, dt_needed, exported_symbols,
+                     imported_symbols):
+        """Add 32-bit / 64-bit shared libraries to ELFLinker."""
+
+        for klass in (ELF.ELFCLASS32, ELF.ELFCLASS64):
+            self.add_lib(partition, klass, name, dt_needed,
+                         exported_symbols, imported_symbols)
+
+    def resolve(self):
+        self.graph.resolve_deps()
+
+
+class ELFLinkerTest(unittest.TestCase):
+    def _create_normal_graph(self):
+        gb = GraphBuilder()
+
+        gb.add_multilib(PT_SYSTEM, 'libdl', dt_needed=[],
+                        exported_symbols={'dlclose', 'dlopen', 'dlsym'},
+                        imported_symbols={})
+
+        gb.add_multilib(PT_SYSTEM, 'libm', dt_needed=[],
+                        exported_symbols={'cos', 'sin'},
+                        imported_symbols={})
+
+        gb.add_multilib(PT_SYSTEM, 'libc', dt_needed=['libdl.so', 'libm.so'],
+                        exported_symbols={'fclose', 'fopen', 'fread'},
+                        imported_symbols={'dlclose', 'dlopen', 'cos', 'sin'})
+
+        gb.add_multilib(PT_SYSTEM, 'libRS', dt_needed=['libdl.so'],
+                        exported_symbols={'rsContextCreate'},
+                        imported_symbols={'dlclose', 'dlopen', 'dlsym'})
+
+        gb.add_multilib(PT_SYSTEM, 'libcutils',
+                        dt_needed=['libc.so', 'libdl.so'],
+                        exported_symbols={},
+                        imported_symbols={'dlclose', 'dlopen', 'fclose',
+                                          'fopen'})
+
+        gb.add_multilib(PT_VENDOR, 'libEGL',
+                        dt_needed=['libc.so', 'libcutils.so', 'libdl.so'],
+                        exported_symbols={'eglGetDisplay'},
+                        imported_symbols={'fclose', 'fopen'})
+
+        gb.resolve()
+        return gb
+
+    def _get_paths_from_nodes(self, nodes):
+        return sorted([node.path for node in nodes])
+
+    def test_map_path_to_lib(self):
+        gb = self._create_normal_graph()
+        graph = gb.graph
+
+        node = graph.map_path_to_lib('/system/lib/libc.so')
+        self.assertEqual(gb.elf32_libc, node.elf)
+        self.assertEqual('/system/lib/libc.so', node.path)
+
+        node = graph.map_path_to_lib('/system/lib64/libdl.so')
+        self.assertEqual(gb.elf64_libdl, node.elf)
+        self.assertEqual('/system/lib64/libdl.so', node.path)
+
+        node = graph.map_path_to_lib('/vendor/lib64/libEGL.so')
+        self.assertEqual(gb.elf64_libEGL, node.elf)
+        self.assertEqual('/vendor/lib64/libEGL.so', node.path)
+
+        self.assertEqual(None, graph.map_path_to_lib('/no/such/path.so'))
+
+    def test_map_paths_to_libs(self):
+        gb = self._create_normal_graph()
+        graph = gb.graph
+
+        bad = []
+        paths = ['/system/lib/libc.so', '/system/lib/libdl.so']
+        nodes = graph.map_paths_to_libs(paths, bad.append)
+
+        self.assertEqual([], bad)
+        self.assertEqual(2, len(nodes))
+        self.assertEqual(paths, self._get_paths_from_nodes(nodes))
+
+        bad = []
+        paths = ['/no/such/path.so', '/system/lib64/libdl.so']
+        nodes = graph.map_paths_to_libs(paths, bad.append)
+        self.assertEqual(['/no/such/path.so'], bad)
+        self.assertEqual(['/system/lib64/libdl.so'],
+                         self._get_paths_from_nodes(nodes))
+
+    def test_elf_class(self):
+        gb = self._create_normal_graph()
+        graph = gb.graph
+        self.assertEqual(6, len(graph.lib32))
+        self.assertEqual(6, len(graph.lib64))
+
+    def test_partitions(self):
+        gb = self._create_normal_graph()
+        graph = gb.graph
+        self.assertEqual(10, len(gb.graph.lib_pt[PT_SYSTEM]))
+        self.assertEqual(2, len(gb.graph.lib_pt[PT_VENDOR]))
+
+    def test_deps(self):
+        gb = self._create_normal_graph()
+        graph = gb.graph
+
+        # Check the dependencies of libc.so.
+        node = gb.graph.map_path_to_lib('/system/lib/libc.so')
+        self.assertEqual(['/system/lib/libdl.so', '/system/lib/libm.so'],
+                         self._get_paths_from_nodes(node.deps))
+
+        # Check the dependencies of libRS.so.
+        node = gb.graph.map_path_to_lib('/system/lib64/libRS.so')
+        self.assertEqual(['/system/lib64/libdl.so'],
+                         self._get_paths_from_nodes(node.deps))
+
+        # Check the dependencies of libEGL.so.
+        node = gb.graph.map_path_to_lib('/vendor/lib64/libEGL.so')
+        self.assertEqual(['/system/lib64/libc.so', '/system/lib64/libcutils.so',
+                          '/system/lib64/libdl.so'],
+                         self._get_paths_from_nodes(node.deps))
+
+    def test_users(self):
+        gb = self._create_normal_graph()
+        graph = gb.graph
+
+        # Check the users of libc.so.
+        node = graph.map_path_to_lib('/system/lib/libc.so')
+        self.assertEqual(['/system/lib/libcutils.so', '/vendor/lib/libEGL.so'],
+                         self._get_paths_from_nodes(node.users))
+
+        # Check the users of libdl.so.
+        node = graph.map_path_to_lib('/system/lib/libdl.so')
+        self.assertEqual(['/system/lib/libRS.so', '/system/lib/libc.so',
+                          '/system/lib/libcutils.so', '/vendor/lib/libEGL.so'],
+                         self._get_paths_from_nodes(node.users))
+
+        # Check the users of libRS.so.
+        node = graph.map_path_to_lib('/system/lib64/libRS.so')
+        self.assertEqual([], self._get_paths_from_nodes(node.users))
+
+        # Check the users of libEGL.so.
+        node = graph.map_path_to_lib('/vendor/lib64/libEGL.so')
+        self.assertEqual([], self._get_paths_from_nodes(node.users))
+
+    def test_compute_vndk_libs(self):
+        gb = self._create_normal_graph()
+        graph = gb.graph
+
+        class MockBannedLibs(object):
+            def get(self, name):
+                return None
+
+        vndk_core, vndk_indirect, vndk_ext = \
+                graph.compute_vndk_libs(None, MockBannedLibs())
+
+        self.assertEqual(['/system/lib/libcutils.so',
+                          '/system/lib64/libcutils.so'],
+                         self._get_paths_from_nodes(vndk_core))
+        self.assertEqual([], self._get_paths_from_nodes(vndk_indirect))
+        self.assertEqual([], self._get_paths_from_nodes(vndk_ext))
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/vndk/tools/definition-tool/tests/test_elf_resolver.py b/vndk/tools/definition-tool/tests/test_elf_resolver.py
new file mode 100755
index 0000000..020ba5c
--- /dev/null
+++ b/vndk/tools/definition-tool/tests/test_elf_resolver.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python3
+
+from __future__ import print_function
+
+import os
+import sys
+sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+
+import unittest
+
+from vndk_definition_tool import ELFResolver
+
+class ELFResolverTest(unittest.TestCase):
+    def setUp(self):
+        lib_set = {
+            '/system/lib/liba.so': 'a',
+            '/system/lib/libb.so': 'b',
+            '/vendor/lib/liba.so': 'a2',
+            '/vendor/lib/libc.so': 'c',
+            '/vendor/lib/libd.so': 'd',
+            '/system/lib/hw/libe.so': 'e',
+            '/vendor/lib/hw/libf.so': 'f',
+        }
+
+        self.resolver = ELFResolver(lib_set, ['/system/lib', '/vendor/lib'])
+
+    def test_get_candidates(self):
+        r = self.resolver
+
+        self.assertEqual(
+                ['/system/lib/libx.so', '/vendor/lib/libx.so'],
+                list(r.get_candidates('libx.so')))
+
+        self.assertEqual(
+                ['/C/libx.so', '/system/lib/libx.so', '/vendor/lib/libx.so'],
+                list(r.get_candidates('libx.so', ['/C'])))
+
+        self.assertEqual(
+                ['/C/libx.so', '/D/libx.so', '/system/lib/libx.so',
+                 '/vendor/lib/libx.so'],
+                list(r.get_candidates('libx.so', ['/C', '/D'])))
+
+        self.assertEqual(
+                ['/E/libx.so', '/system/lib/libx.so', '/vendor/lib/libx.so'],
+                list(r.get_candidates('libx.so', None, ['/E'])))
+
+        self.assertEqual(
+                ['/E/libx.so', '/F/libx.so', '/system/lib/libx.so',
+                 '/vendor/lib/libx.so'],
+                list(r.get_candidates('libx.so', None, ['/E', '/F'])))
+
+        self.assertEqual(
+                ['/C/libx.so', '/D/libx.so', '/E/libx.so', '/F/libx.so',
+                 '/system/lib/libx.so', '/vendor/lib/libx.so'],
+                list(r.get_candidates('libx.so', ['/C', '/D'], ['/E', '/F'])))
+
+    def test_resolve(self):
+        r = self.resolver
+        self.assertEqual('a', r.resolve('liba.so'))
+        self.assertEqual('c', r.resolve('libc.so'))
+
+        self.assertEqual(None, r.resolve('libe.so'))
+        self.assertEqual('e', r.resolve('libe.so', dt_rpath=['/system/lib/hw']))
+        self.assertEqual(
+                'e', r.resolve('libe.so', dt_runpath=['/system/lib/hw']))
+
+        self.assertEqual('a2', r.resolve('liba.so', dt_rpath=['/vendor/lib']))
+        self.assertEqual('a2', r.resolve('liba.so', dt_runpath=['/vendor/lib']))
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/vndk/tools/definition-tool/tests/test_elfdump.py b/vndk/tools/definition-tool/tests/test_elfdump.py
index 4cecd96..44b7935 100755
--- a/vndk/tools/definition-tool/tests/test_elfdump.py
+++ b/vndk/tools/definition-tool/tests/test_elfdump.py
@@ -77,12 +77,23 @@
         target.link(out_file, [obj_file],
                     ['-shared', '-lc', '-Wl,-rpath,$ORIGIN/../lib'])
 
+        # Link libtest-rpath-multi.so.
+        out_file = os.path.join(cls.test_dir, 'libtest-rpath-multi.so')
+        target.link(out_file, [obj_file],
+                    ['-shared', '-lc', '-Wl,-rpath,/system/lib:/vendor/lib'])
+
         # Link libtest-runpath.so.
         out_file = os.path.join(cls.test_dir, 'libtest-runpath.so')
         target.link(out_file, [obj_file],
                     ['-shared', '-lc', '-Wl,-rpath,$ORIGIN/../lib',
                      '-Wl,--enable-new-dtags'])
 
+        # Link libtest-runpath-multi.so.
+        out_file = os.path.join(cls.test_dir, 'libtest-runpath-multi.so')
+        target.link(out_file, [obj_file],
+                    ['-shared', '-lc', '-Wl,-rpath,/system/lib:/vendor/lib',
+                     '-Wl,--enable-new-dtags'])
+
     def _assert_equal_to_file(self, expected_file_name, actual):
         actual = actual.splitlines(True)
         expected_file_path = os.path.join(self.expected_dir, expected_file_name)
@@ -94,7 +105,7 @@
         out_file = os.path.join(self.test_dir, 'main.out')
         self._assert_equal_to_file('main.out.txt', run_elf_dump(out_file))
 
-    def _test_libtest(self, ldflags, expected_file_name, lib_name):
+    def _test_libtest(self, expected_file_name, lib_name):
         lib_file = os.path.join(self.test_dir, lib_name)
         self._assert_equal_to_file(expected_file_name, run_elf_dump(lib_file))
 
@@ -104,17 +115,21 @@
         self._test_main_out()
 
     def test_libtest(self):
-        self._test_libtest([], 'libtest.so.txt', 'libtest.so')
+        self._test_libtest('libtest.so.txt', 'libtest.so')
 
     def test_libtest_rpath(self):
-        self._test_libtest(
-                ['-Wl,-rpath,$ORIGIN/../lib'],
-                'libtest-rpath.so.txt', 'libtest-rpath.so')
+        self._test_libtest('libtest-rpath.so.txt', 'libtest-rpath.so')
+
+    def test_libtest_rpath_multi(self):
+        self._test_libtest('libtest-rpath-multi.so.txt',
+                           'libtest-rpath-multi.so')
 
     def test_libtest_runpath(self):
-        self._test_libtest(
-                ['-Wl,-rpath,$ORIGIN/../lib', '-Wl,--enable-new-dtags'],
-                'libtest-runpath.so.txt', 'libtest-runpath.so')
+        self._test_libtest('libtest-runpath.so.txt', 'libtest-runpath.so')
+
+    def test_libtest_runpath_multi(self):
+        self._test_libtest('libtest-runpath-multi.so.txt',
+                           'libtest-runpath-multi.so')
 
     class_name = 'ELFDumpTest_' + target_name
     globals()[class_name] = type(
@@ -122,7 +137,9 @@
             dict(test_main=test_main,
                  test_libtest=test_libtest,
                  test_libtest_rpath=test_libtest_rpath,
+                 test_libtest_rpath_multi=test_libtest_rpath_multi,
                  test_libtest_runpath=test_libtest_runpath,
+                 test_libtest_runpath_multi=test_libtest_runpath_multi,
                  target_name=target_name))
 
 
diff --git a/vndk/tools/definition-tool/tests/test_generic_refs.py b/vndk/tools/definition-tool/tests/test_generic_refs.py
index 9789432..77f20bd 100755
--- a/vndk/tools/definition-tool/tests/test_generic_refs.py
+++ b/vndk/tools/definition-tool/tests/test_generic_refs.py
@@ -57,14 +57,14 @@
         self.assertIn('/system/lib64/libc.so', g.refs)
         self.assertIn('/system/lib64/libm.so', g.refs)
 
-        self.assertEqual(['fclose', 'fopen', 'fread', 'fwrite'],
+        self.assertEqual({'fclose', 'fopen', 'fread', 'fwrite'},
                          g.refs['/system/lib/libc.so'])
-        self.assertEqual(['fclose', 'fopen', 'fread', 'fwrite'],
+        self.assertEqual({'fclose', 'fopen', 'fread', 'fwrite'},
                          g.refs['/system/lib64/libc.so'])
 
-        self.assertEqual(['cos', 'sin', 'tan'],
+        self.assertEqual({'cos', 'sin', 'tan'},
                          g.refs['/system/lib/libm.so'])
-        self.assertEqual(['cos', 'sin', 'tan'],
+        self.assertEqual({'cos', 'sin', 'tan'},
                          g.refs['/system/lib64/libm.so'])
 
 
@@ -80,11 +80,11 @@
                 self.path = path
                 self.elf = MockELF(exported_symbols)
 
-        libc_sub = MockLib('/system/lib/libc.so', ['fclose', 'fopen', 'fread'])
+        libc_sub = MockLib('/system/lib/libc.so', {'fclose', 'fopen', 'fread'})
         libc_sup = MockLib('/system/lib/libc.so',
-                           ['fclose', 'fopen', 'fread', 'fwrite', 'open'])
+                           {'fclose', 'fopen', 'fread', 'fwrite', 'open'})
         libc_eq = MockLib('/system/lib/libc.so',
-                          ['fclose', 'fopen', 'fread', 'fwrite'])
+                          {'fclose', 'fopen', 'fread', 'fwrite'})
 
         self.assertFalse(g.is_equivalent_lib(libc_sub))
         self.assertFalse(g.is_equivalent_lib(libc_sup))
diff --git a/vndk/tools/definition-tool/tests/test_graph.py b/vndk/tools/definition-tool/tests/test_graph.py
deleted file mode 100755
index 3906939..0000000
--- a/vndk/tools/definition-tool/tests/test_graph.py
+++ /dev/null
@@ -1,179 +0,0 @@
-#!/usr/bin/env python3
-
-from __future__ import print_function
-
-import os
-import sys
-sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-
-import unittest
-
-from compat import StringIO
-from vndk_definition_tool import ELF, Graph, PT_SYSTEM, PT_VENDOR
-
-class GraphTest(unittest.TestCase):
-    def setUp(self):
-        # 32-bit libraries on the system partition.
-        self.elf_libdl_32 = ELF(
-                ELF.ELFCLASS32, ELF.ELFDATA2LSB,
-                exported_symbols=['dlclose', 'dlopen', 'dlsym'])
-
-        self.elf_libm_32 = ELF(
-                ELF.ELFCLASS32, ELF.ELFDATA2LSB,
-                exported_symbols=['cos', 'sin'])
-
-        self.elf_libc_32 = ELF(
-                ELF.ELFCLASS32, ELF.ELFDATA2LSB,
-                dt_needed=['libdl.so', 'libm.so'],
-                exported_symbols=['fclose', 'fopen', 'fread'])
-
-        self.elf_libRS_32 = ELF(
-                ELF.ELFCLASS32, ELF.ELFDATA2LSB,
-                dt_needed=['libdl.so'],
-                exported_symbols=['rsContextCreate'])
-
-        self.elf_libcutils_32 = ELF(
-                ELF.ELFCLASS32, ELF.ELFDATA2LSB,
-                dt_needed=['libc.so', 'libdl.so'])
-
-        # 64-bit libraries on the system partition.
-        self.elf_libdl_64 = ELF(
-                ELF.ELFCLASS64, ELF.ELFDATA2LSB,
-                exported_symbols=['dlclose', 'dlopen', 'dlsym'])
-
-        self.elf_libm_64 = ELF(
-                ELF.ELFCLASS64, ELF.ELFDATA2LSB,
-                exported_symbols=['cos', 'sin'])
-
-        self.elf_libc_64 = ELF(
-                ELF.ELFCLASS64, ELF.ELFDATA2LSB,
-                dt_needed=['libdl.so', 'libm.so'],
-                exported_symbols=['fclose', 'fopen', 'fread'])
-
-        self.elf_libRS_64 = ELF(
-                ELF.ELFCLASS64, ELF.ELFDATA2LSB,
-                dt_needed=['libdl.so'],
-                exported_symbols=['rsContextCreate'])
-
-        self.elf_libcutils_64 = ELF(
-                ELF.ELFCLASS64, ELF.ELFDATA2LSB,
-                dt_needed=['libc.so', 'libdl.so'])
-
-        # 32-bit libraries on the vendor partition.
-        self.elf_libEGL_32 = ELF(
-                ELF.ELFCLASS32, ELF.ELFDATA2LSB,
-                dt_needed=['libc.so', 'libcutils.so', 'libdl.so'],
-                exported_symbols=['eglGetDisplay'])
-
-        # 64-bit libraries on the vendor partition.
-        self.elf_libEGL_64 = ELF(
-                ELF.ELFCLASS64, ELF.ELFDATA2LSB,
-                dt_needed=['libc.so', 'libcutils.so', 'libdl.so'],
-                exported_symbols=['eglGetDisplay'])
-
-        # Build the linker.
-        g = Graph()
-        g.add(PT_SYSTEM, '/system/lib/libc.so', self.elf_libc_32)
-        g.add(PT_SYSTEM, '/system/lib/libcutils.so', self.elf_libcutils_32)
-        g.add(PT_SYSTEM, '/system/lib/libdl.so', self.elf_libdl_32)
-        g.add(PT_SYSTEM, '/system/lib/libm.so', self.elf_libm_32)
-        g.add(PT_SYSTEM, '/system/lib/libRS.so', self.elf_libRS_32)
-        g.add(PT_SYSTEM, '/system/lib64/libc.so', self.elf_libc_64)
-        g.add(PT_SYSTEM, '/system/lib64/libcutils.so', self.elf_libcutils_64)
-        g.add(PT_SYSTEM, '/system/lib64/libdl.so', self.elf_libdl_64)
-        g.add(PT_SYSTEM, '/system/lib64/libm.so', self.elf_libm_64)
-        g.add(PT_SYSTEM, '/system/lib64/libRS.so', self.elf_libRS_64)
-        g.add(PT_VENDOR, '/vendor/lib/libEGL.so', self.elf_libEGL_32)
-        g.add(PT_VENDOR, '/vendor/lib64/libEGL.so', self.elf_libEGL_64)
-        g.resolve_deps()
-        self.graph = g
-
-    def test_map_path_to_lib(self):
-        node = self.graph.map_path_to_lib('/system/lib/libc.so')
-        self.assertEqual(self.elf_libc_32, node.elf)
-        self.assertEqual('/system/lib/libc.so', node.path)
-
-        node = self.graph.map_path_to_lib('/system/lib64/libdl.so')
-        self.assertEqual(self.elf_libdl_64, node.elf)
-        self.assertEqual('/system/lib64/libdl.so', node.path)
-
-        node = self.graph.map_path_to_lib('/vendor/lib64/libEGL.so')
-        self.assertEqual(self.elf_libEGL_64, node.elf)
-        self.assertEqual('/vendor/lib64/libEGL.so', node.path)
-
-        self.assertEqual(None, self.graph.map_path_to_lib('/no/such/path.so'))
-
-    def _get_paths_from_nodes(self, nodes):
-        return sorted([node.path for node in nodes])
-
-    def test_map_paths_to_libs(self):
-        bad = []
-        paths = ['/system/lib/libc.so', '/system/lib/libdl.so']
-        nodes = self.graph.map_paths_to_libs(paths,  lambda x: bad.append(x))
-
-        self.assertEqual([], bad)
-        self.assertEqual(2, len(nodes))
-        self.assertEqual(paths, self._get_paths_from_nodes(nodes))
-
-        bad = []
-        paths = ['/no/such/path.so', '/system/lib64/libdl.so']
-        nodes = self.graph.map_paths_to_libs(paths, lambda x: bad.append(x))
-        self.assertEqual(['/no/such/path.so'], bad)
-        self.assertEqual(['/system/lib64/libdl.so'],
-                         self._get_paths_from_nodes(nodes))
-
-    def test_elf_class(self):
-        self.assertEqual(6, len(self.graph.lib32))
-        self.assertEqual(6, len(self.graph.lib64))
-
-    def test_partitions(self):
-        self.assertEqual(10, len(self.graph.lib_pt[PT_SYSTEM]))
-        self.assertEqual(2, len(self.graph.lib_pt[PT_VENDOR]))
-
-    def test_deps(self):
-        libc_32 = self.graph.map_path_to_lib('/system/lib/libc.so')
-        self.assertEqual(['/system/lib/libdl.so', '/system/lib/libm.so'],
-                         self._get_paths_from_nodes(libc_32.deps))
-
-        libRS_64 = self.graph.map_path_to_lib('/system/lib64/libRS.so')
-        self.assertEqual(['/system/lib64/libdl.so'],
-                         self._get_paths_from_nodes(libRS_64.deps))
-
-        libEGL_64 = self.graph.map_path_to_lib('/vendor/lib64/libEGL.so')
-        self.assertEqual(['/system/lib64/libc.so', '/system/lib64/libcutils.so',
-                          '/system/lib64/libdl.so'],
-                         self._get_paths_from_nodes(libEGL_64.deps))
-
-    def test_users(self):
-        libc_32 = self.graph.map_path_to_lib('/system/lib/libc.so')
-        self.assertEqual(['/system/lib/libcutils.so', '/vendor/lib/libEGL.so'],
-                         self._get_paths_from_nodes(libc_32.users))
-
-        libdl_32 = self.graph.map_path_to_lib('/system/lib/libdl.so')
-        self.assertEqual(['/system/lib/libRS.so', '/system/lib/libc.so',
-                          '/system/lib/libcutils.so', '/vendor/lib/libEGL.so'],
-                         self._get_paths_from_nodes(libdl_32.users))
-
-        libRS_64 = self.graph.map_path_to_lib('/system/lib64/libRS.so')
-        self.assertEqual([], self._get_paths_from_nodes(libRS_64.users))
-
-        libEGL_64 = self.graph.map_path_to_lib('/vendor/lib64/libEGL.so')
-        self.assertEqual([], self._get_paths_from_nodes(libEGL_64.users))
-
-    def test_compute_vndk_libs(self):
-        class MockBannedLibs(object):
-            def get(self, name):
-                return None
-
-        vndk_core, vndk_indirect, vndk_ext = \
-                self.graph.compute_vndk_libs(None, MockBannedLibs())
-
-        self.assertEqual(['/system/lib/libcutils.so',
-                          '/system/lib64/libcutils.so'],
-                         self._get_paths_from_nodes(vndk_core))
-        self.assertEqual([], self._get_paths_from_nodes(vndk_indirect))
-        self.assertEqual([], self._get_paths_from_nodes(vndk_ext))
-
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/vndk/tools/definition-tool/vndk_definition_tool.py b/vndk/tools/definition-tool/vndk_definition_tool.py
index bbdff23..f6895f0 100755
--- a/vndk/tools/definition-tool/vndk_definition_tool.py
+++ b/vndk/tools/definition-tool/vndk_definition_tool.py
@@ -140,26 +140,30 @@
     }
 
 
+    __slots__ = ('ei_class', 'ei_data', 'e_machine', 'dt_rpath', 'dt_runpath',
+                 'dt_needed', 'exported_symbols', 'imported_symbols',)
+
+
     def __init__(self, ei_class=ELFCLASSNONE, ei_data=ELFDATANONE, e_machine=0,
                  dt_rpath=None, dt_runpath=None, dt_needed=None,
-                 exported_symbols=None):
+                 exported_symbols=None, imported_symbols=None):
         self.ei_class = ei_class
         self.ei_data = ei_data
         self.e_machine = e_machine
-        self.dt_rpath = dt_rpath
-        self.dt_runpath = dt_runpath
+        self.dt_rpath = dt_rpath if dt_rpath is not None else []
+        self.dt_runpath = dt_runpath if dt_runpath is not None else []
         self.dt_needed = dt_needed if dt_needed is not None else []
         self.exported_symbols = \
-                exported_symbols if exported_symbols is not None else []
+                exported_symbols if exported_symbols is not None else set()
+        self.imported_symbols = \
+                imported_symbols if imported_symbols is not None else set()
 
-    def __str__(self):
-        return ('ELF(' +
-                'ei_class=' + repr(self.ei_class) + ', ' +
-                'ei_data=' + repr(self.ei_data) + ', ' +
-                'e_machine=' + repr(self.e_machine) + ', ' +
-                'dt_rpath=' + repr(self.dt_rpath) + ', ' +
-                'dt_runpath=' + repr(self.dt_runpath) + ', ' +
-                'dt_needed=' + repr(self.dt_needed) + ')')
+    def __repr__(self):
+        args = (a + '=' + repr(getattr(self, a)) for a in self.__slots__)
+        return 'ELF(' + ', '.join(args) + ')'
+
+    def __eq__(self, rhs):
+        return all(getattr(self, a) == getattr(rhs, a) for a in self.__slots__)
 
     @property
     def elf_class_name(self):
@@ -181,6 +185,14 @@
     def is_64bit(self):
         return self.ei_class == ELF.ELFCLASS64
 
+    @property
+    def sorted_exported_symbols(self):
+        return sorted(list(self.exported_symbols))
+
+    @property
+    def sorted_imported_symbols(self):
+        return sorted(list(self.imported_symbols))
+
     def dump(self, file=None):
         """Print parsed ELF information to the file"""
         file = file if file is not None else sys.stdout
@@ -188,19 +200,21 @@
         print('EI_CLASS\t' + self.elf_class_name, file=file)
         print('EI_DATA\t\t' + self.elf_data_name, file=file)
         print('E_MACHINE\t' + self.elf_machine_name, file=file)
-        if self.dt_rpath:
-            print('DT_RPATH\t' + self.dt_rpath, file=file)
-        if self.dt_runpath:
-            print('DT_RUNPATH\t' + self.dt_runpath, file=file)
+        for dt_rpath in self.dt_rpath:
+            print('DT_RPATH\t' + dt_rpath, file=file)
+        for dt_runpath in self.dt_runpath:
+            print('DT_RUNPATH\t' + dt_runpath, file=file)
         for dt_needed in self.dt_needed:
             print('DT_NEEDED\t' + dt_needed, file=file)
-        for symbol in self.exported_symbols:
-            print('SYMBOL\t\t' + symbol, file=file)
+        for symbol in self.sorted_exported_symbols:
+            print('EXP_SYMBOL\t' + symbol, file=file)
+        for symbol in self.sorted_imported_symbols:
+            print('IMP_SYMBOL\t' + symbol, file=file)
 
     def dump_exported_symbols(self, file=None):
         """Print exported symbols to the file"""
         file = file if file is not None else sys.stdout
-        for symbol in self.exported_symbols:
+        for symbol in self.sorted_exported_symbols:
             print(symbol, file=file)
 
     # Extract zero-terminated buffer slice.
@@ -330,24 +344,32 @@
             if ent.d_tag == ELF.DT_NEEDED:
                 self.dt_needed.append(extract_str(dynstr_off + ent.d_val))
             elif ent.d_tag == ELF.DT_RPATH:
-                self.dt_rpath = extract_str(dynstr_off + ent.d_val)
+                self.dt_rpath.extend(
+                        extract_str(dynstr_off + ent.d_val).split(':'))
             elif ent.d_tag == ELF.DT_RUNPATH:
-                self.dt_runpath = extract_str(dynstr_off + ent.d_val)
+                self.dt_runpath.extend(
+                        extract_str(dynstr_off + ent.d_val).split(':'))
 
         # Parse exported symbols in .dynsym section.
         dynsym_shdr = sections.get('.dynsym')
         if dynsym_shdr:
-            exported_symbols = []
+            exp_symbols = self.exported_symbols
+            imp_symbols = self.imported_symbols
+
             dynsym_off = dynsym_shdr.sh_offset
             dynsym_end = dynsym_off + dynsym_shdr.sh_size
             dynsym_entsize = dynsym_shdr.sh_entsize
+
+            # Skip first symbol entry (null symbol).
+            dynsym_off += dynsym_entsize
+
             for ent_off in range(dynsym_off, dynsym_end, dynsym_entsize):
                 ent = parse_elf_sym(ent_off)
-                if not ent.is_local and not ent.is_undef:
-                    exported_symbols.append(
-                            extract_str(dynstr_off + ent.st_name))
-            exported_symbols.sort()
-            self.exported_symbols = exported_symbols
+                symbol_name = extract_str(dynstr_off + ent.st_name)
+                if ent.is_undef:
+                    imp_symbols.add(symbol_name)
+                elif not ent.is_local:
+                    exp_symbols.add(symbol_name)
 
     def _parse_from_buf(self, buf):
         """Parse ELF image resides in the buffer"""
@@ -449,7 +471,31 @@
 NUM_PARTITIONS = 2
 
 
-class GraphNode(object):
+class ELFResolver(object):
+    def __init__(self, lib_set, default_search_path):
+        self.lib_set = lib_set
+        self.default_search_path = default_search_path
+
+    def get_candidates(self, name, dt_rpath=None, dt_runpath=None):
+        if dt_rpath:
+            for d in dt_rpath:
+                yield os.path.join(d, name)
+        if dt_runpath:
+            for d in dt_runpath:
+                yield os.path.join(d, name)
+        for d in self.default_search_path:
+            yield os.path.join(d, name)
+
+    def resolve(self, name, dt_rpath=None, dt_runpath=None):
+        for path in self.get_candidates(name, dt_rpath, dt_runpath):
+            try:
+                return self.lib_set[path]
+            except KeyError:
+                continue
+        return None
+
+
+class ELFLinkData(object):
     def __init__(self, partition, path, elf):
         self.partition = partition
         self.path = path
@@ -469,14 +515,14 @@
     return libs
 
 
-class Graph(object):
+class ELFLinker(object):
     def __init__(self):
         self.lib32 = dict()
         self.lib64 = dict()
         self.lib_pt = [dict() for i in range(NUM_PARTITIONS)]
 
     def add(self, partition, path, elf):
-        node = GraphNode(partition, path, elf)
+        node = ELFLinkData(partition, path, elf)
         if elf.is_32bit:
             self.lib32[path] = node
         else:
@@ -519,7 +565,7 @@
         prefix_len = len(root) + 1
 
         if alter_subdirs:
-            alter_patt = Graph._compile_path_matcher(root, alter_subdirs)
+            alter_patt = ELFLinker._compile_path_matcher(root, alter_subdirs)
 
         for path in scan_executables(root):
             try:
@@ -541,29 +587,33 @@
                 if match:
                     self.add_dep(match.group(1), match.group(2))
 
-    def _resolve_deps_lib_set(self, lib_set, system_lib, vendor_lib):
+    def _resolve_lib_dt_needed(self, lib, resolver):
+        for dt_needed in lib.elf.dt_needed:
+            dep = resolver.resolve(dt_needed, lib.elf.dt_rpath,
+                                   lib.elf.dt_runpath)
+            if not dep:
+                candidates = list(resolver.get_candidates(
+                    dt_needed, lib.elf.dt_rpath, lib.elf.dt_runpath))
+                print('warning: {}: Missing needed library: {}  Tried: {}'
+                      .format(lib.path, dt_needed, candidates), file=sys.stderr)
+                continue
+            lib.add_dep(dep)
+
+    def _resolve_lib_deps(self, lib, resolver):
+        self._resolve_lib_dt_needed(lib, resolver)
+
+    def _resolve_lib_set_deps(self, lib_set, resolver):
         for lib in lib_set.values():
-            for dt_needed in lib.elf.dt_needed:
-                candidates = [
-                    dt_needed,
-                    os.path.join(system_lib, dt_needed),
-                    os.path.join(vendor_lib, dt_needed),
-                ]
-                for candidate in candidates:
-                    dep = lib_set.get(candidate)
-                    if dep:
-                        break
-                if not dep:
-                    print('warning: {}: Missing needed library: {}  Tried: {}'
-                          .format(lib.path, dt_needed, candidates),
-                          file=sys.stderr)
-                    continue
-                lib.add_dep(dep)
+            self._resolve_lib_deps(lib, resolver)
 
     def resolve_deps(self):
-        self._resolve_deps_lib_set(self.lib32, '/system/lib', '/vendor/lib')
-        self._resolve_deps_lib_set(self.lib64, '/system/lib64',
-                                   '/vendor/lib64')
+        self._resolve_lib_set_deps(
+                self.lib32,
+                ELFResolver(self.lib32, ['/system/lib', '/vendor/lib']))
+
+        self._resolve_lib_set_deps(
+                self.lib64,
+                ELFResolver(self.lib64, ['/system/lib64', '/vendor/lib64']))
 
     def compute_vndk_libs(self, generic_refs, banned_libs):
         vndk_core = set()
@@ -655,7 +705,7 @@
     @staticmethod
     def create(system_dirs=None, system_dirs_as_vendor=None, vendor_dirs=None,
                vendor_dirs_as_system=None, extra_deps=None):
-        graph = Graph()
+        graph = ELFLinker()
 
         if system_dirs:
             for path in system_dirs:
@@ -694,7 +744,7 @@
                 path = os.path.join(base, filename)
                 lib_name = '/' + path[prefix_len:-4]
                 with open(path, 'r') as f:
-                    self.refs[lib_name] = [line.strip() for line in f]
+                    self.refs[lib_name] = set(line.strip() for line in f)
 
     @staticmethod
     def create_from_dir(root):
@@ -867,9 +917,9 @@
 
     def main(self, args):
         # Link ELF objects.
-        graph = Graph.create(args.system, args.system_dir_as_vendor,
-                             args.vendor, args.vendor_dir_as_system,
-                             args.load_extra_deps)
+        graph = ELFLinker.create(args.system, args.system_dir_as_vendor,
+                                 args.vendor, args.vendor_dir_as_system,
+                                 args.load_extra_deps)
 
         # Load the generic reference.
         generic_refs = None
@@ -924,9 +974,9 @@
                 help='print binaries without dependencies or usages')
 
     def main(self, args):
-        graph = Graph.create(args.system, args.system_dir_as_vendor,
-                             args.vendor, args.vendor_dir_as_system,
-                             args.load_extra_deps)
+        graph = ELFLinker.create(args.system, args.system_dir_as_vendor,
+                                 args.vendor, args.vendor_dir_as_system,
+                                 args.load_extra_deps)
 
         results = []
         for partition in range(NUM_PARTITIONS):
@@ -965,9 +1015,9 @@
                             help='exclude ndk libraries')
 
     def main(self, args):
-        graph = Graph.create(args.system, args.system_dir_as_vendor,
-                             args.vendor, args.vendor_dir_as_system,
-                             args.load_extra_deps)
+        graph = ELFLinker.create(args.system, args.system_dir_as_vendor,
+                                 args.vendor, args.vendor_dir_as_system,
+                                 args.load_extra_deps)
 
         # Find root/excluded libraries by their paths.
         def report_error(path):
@@ -1001,9 +1051,9 @@
                             help='show the closure')
 
     def main(self, args):
-        graph = Graph.create(args.system, args.system_dir_as_vendor,
-                             args.vendor, args.vendor_dir_as_system,
-                             args.load_extra_deps)
+        graph = ELFLinker.create(args.system, args.system_dir_as_vendor,
+                                 args.vendor, args.vendor_dir_as_system,
+                                 args.load_extra_deps)
 
         # Find SP HALs.
         name_patterns = (