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 = (