1#!/usr/bin/env python3
2
3import os
4
5from vndk_definition_tool import (ELF, ELFLinker, PT_SYSTEM, PT_VENDOR)
6
7
8class GraphBuilder(object):
9    _PARTITION_NAMES = {
10        PT_SYSTEM: 'system',
11        PT_VENDOR: 'vendor',
12    }
13
14
15    _LIB_DIRS = {
16        ELF.ELFCLASS32: 'lib',
17        ELF.ELFCLASS64: 'lib64',
18    }
19
20
21    def __init__(self):
22        self.graph = ELFLinker()
23
24
25    def add_lib(self, partition, klass, name, dt_needed=tuple(),
26                exported_symbols=tuple(), imported_symbols=tuple(),
27                extra_dir=None):
28        """Create and add a shared library to ELFLinker."""
29
30        lib_dir = os.path.join('/', self._PARTITION_NAMES[partition],
31                               self._LIB_DIRS[klass])
32        if extra_dir:
33            lib_dir = os.path.join(lib_dir, extra_dir)
34
35        path = os.path.join(lib_dir, name + '.so')
36
37        elf = ELF(klass, ELF.ELFDATA2LSB, dt_needed=dt_needed,
38                  exported_symbols=set(exported_symbols),
39                  imported_symbols=set(imported_symbols))
40
41        lib = self.graph.add_lib(partition, path, elf)
42        setattr(self, name + '_' + elf.elf_class_name, lib)
43        return lib
44
45
46    def add_lib32(self, partition, name, dt_needed=tuple(),
47                  exported_symbols=tuple(), imported_symbols=tuple(),
48                  extra_dir=None):
49        return self.add_lib(partition, ELF.ELFCLASS32, name, dt_needed,
50                            exported_symbols, imported_symbols, extra_dir)
51
52
53    def add_lib64(self, partition, name, dt_needed=tuple(),
54                  exported_symbols=tuple(), imported_symbols=tuple(),
55                  extra_dir=None):
56        return self.add_lib(partition, ELF.ELFCLASS64, name, dt_needed,
57                            exported_symbols, imported_symbols, extra_dir)
58
59
60    def add_multilib(self, partition, name, dt_needed=tuple(),
61                     exported_symbols=tuple(), imported_symbols=tuple(),
62                     extra_dir=None):
63        """Add 32-bit / 64-bit shared libraries to ELFLinker."""
64        return (
65            self.add_lib(partition, ELF.ELFCLASS32, name, dt_needed,
66                         exported_symbols, imported_symbols, extra_dir),
67            self.add_lib(partition, ELF.ELFCLASS64, name, dt_needed,
68                         exported_symbols, imported_symbols, extra_dir)
69        )
70
71
72    def resolve(self, vndk_lib_dirs=None, ro_vndk_version=None):
73        if vndk_lib_dirs is not None:
74            self.graph.vndk_lib_dirs = vndk_lib_dirs
75        if ro_vndk_version is not None:
76            self.graph.ro_vndk_version = ro_vndk_version
77        self.graph.resolve_deps()
78