• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2
3import os
4import sys
5import tempfile
6
7import_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
8import_path = os.path.abspath(os.path.join(import_path, 'utils'))
9sys.path.insert(1, import_path)
10
11from utils import run_header_abi_dumper
12from utils import run_header_abi_dumper_on_file
13from utils import run_header_abi_linker
14from utils import SOURCE_ABI_DUMP_EXT
15
16
17SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))
18ARCH_TARGET_CFLAGS = {
19    'arm': ('-target', 'arm-linux-androideabi'),
20    'arm64': ('-target', 'aarch64-linux-android'),
21    'x86': ('-target', 'i386-linux-androideabi'),
22    'x86_64': ('-target', 'x86_64-linux-android'),
23    'mips': ('-target', 'mips-linux-androideabi'),
24    'mips64': ('-target', 'mips64-linux-android'),
25}
26TARGET_ARCHES = ['arm', 'arm64', 'x86', 'x86_64', 'mips', 'mips64']
27
28
29def relative_to_abs_path(relative_path):
30    return os.path.join(SCRIPT_DIR, relative_path)
31
32
33def relative_to_abs_path_list(relative_path_list):
34    abs_paths = []
35    for relative_path in relative_path_list:
36        abs_paths.append(relative_to_abs_path(relative_path))
37    return abs_paths
38
39
40class Module(object):
41    def __init__(self, name, arch, cflags, export_include_dirs):
42        self.name = name
43        self.arch = arch
44        self.cflags = tuple(cflags)
45        self.arch_cflags = ARCH_TARGET_CFLAGS.get(self.arch, tuple())
46        self.export_include_dirs = relative_to_abs_path_list(
47            export_include_dirs)
48
49    def get_dump_name(self):
50        """Returns the module name followed by file extension."""
51        raise NotImplementedError()
52
53    def make_dump(self):
54        """Returns the dump content as a string."""
55        raise NotImplementedError()
56
57    def mutate_for_arch(self, target_arch):
58        """Returns a clone of this instance with arch=target_arch."""
59        raise NotImplementedError()
60
61    def mutate_for_all_arches(self):
62        if self.arch:
63            return [self]
64        modules = []
65        for target_arch in TARGET_ARCHES:
66            modules.append(self.mutate_for_arch(target_arch))
67        return modules
68
69    @staticmethod
70    def get_test_modules():
71        modules = []
72        for module in TEST_MODULES.values():
73            modules += module.mutate_for_all_arches()
74        return modules
75
76    @staticmethod
77    def get_test_modules_by_name(name):
78        return TEST_MODULES.get(name).mutate_for_all_arches()
79
80
81class SdumpModule(Module):
82    def __init__(self, name, src, export_include_dirs=tuple(), cflags=tuple(),
83                 arch='', dumper_flags=tuple()):
84        super(SdumpModule, self).__init__(name, arch, cflags,
85                                          export_include_dirs)
86        self.src = relative_to_abs_path(src)
87        self.dumper_flags = dumper_flags
88
89    def get_dump_name(self):
90        return self.name + '.sdump'
91
92    def make_dump(self):
93        return run_header_abi_dumper(
94            self.src, cflags=self.cflags,
95            export_include_dirs=self.export_include_dirs,
96            flags=self.dumper_flags)
97
98    def mutate_for_arch(self, target_arch):
99        return SdumpModule(self.name, self.src, self.export_include_dirs,
100                           self.cflags, target_arch, self.dumper_flags)
101
102
103class LsdumpModule(Module):
104    def __init__(self, name, srcs, version_script, export_include_dirs,
105                 cflags=tuple(), arch='', api='current', dumper_flags=tuple(),
106                 linker_flags=tuple()):
107        super(LsdumpModule, self).__init__(name, arch, cflags,
108                                           export_include_dirs)
109        self.srcs = relative_to_abs_path_list(srcs)
110        self.version_script = relative_to_abs_path(version_script)
111        self.api = api
112        self.dumper_flags = dumper_flags
113        self.linker_flags = linker_flags
114
115    def get_dump_name(self):
116        return self.name + SOURCE_ABI_DUMP_EXT
117
118    def make_dump(self):
119        """For each source file, produce a .sdump file, and link them to form
120           an lsump file."""
121        dumps_to_link = []
122        with tempfile.TemporaryDirectory() as tmp:
123            output_lsdump = os.path.join(tmp, self.get_dump_name())
124            for src in self.srcs:
125                output_path = os.path.join(tmp,
126                                           os.path.basename(src) + '.sdump')
127                dumps_to_link.append(output_path)
128                run_header_abi_dumper_on_file(
129                    src, output_path, self.export_include_dirs,
130                    self.cflags + self.arch_cflags,
131                    self.dumper_flags)
132            return run_header_abi_linker(output_lsdump, dumps_to_link,
133                                         self.version_script, self.api,
134                                         self.arch, self.linker_flags)
135
136    def mutate_for_arch(self, target_arch):
137        return LsdumpModule(self.name, self.srcs, self.version_script,
138                            self.export_include_dirs, self.cflags, target_arch,
139                            self.api, self.dumper_flags, self.linker_flags)
140
141
142TEST_MODULES = [
143    SdumpModule(
144        name='undeclared_types.h',
145        src='integration/cpp/header/undeclared_types.h',
146        arch='',
147        dumper_flags=['-suppress-errors', '-output-format', 'Json']),
148    SdumpModule(
149        name='known_issues.h',
150        src='integration/cpp/header/known_issues.h',
151        arch='',
152        dumper_flags=['-suppress-errors', '-output-format', 'Json']),
153    LsdumpModule(
154        name='libc_and_cpp',
155        srcs=[
156            'integration/c_and_cpp/source1.cpp',
157            'integration/c_and_cpp/source2.c',
158        ],
159        version_script='integration/c_and_cpp/map.txt',
160        export_include_dirs=['integration/c_and_cpp/include'],
161    ),
162    LsdumpModule(
163        name='libc_and_cpp_with_opaque_ptr_a',
164        srcs=[
165            'integration/c_and_cpp/source1.cpp',
166            'integration/c_and_cpp/source2.c',
167        ],
168        version_script='integration/c_and_cpp/map.txt',
169        export_include_dirs=['integration/c_and_cpp/include'],
170        cflags=['-DOPAQUE_STRUCT_A=1'],
171    ),
172    LsdumpModule(
173        name='libc_and_cpp_with_opaque_ptr_b',
174        srcs=[
175            'integration/c_and_cpp/source1.cpp',
176            'integration/c_and_cpp/source2.c',
177        ],
178        version_script='integration/c_and_cpp/map.txt',
179        export_include_dirs=['integration/c_and_cpp/include'],
180        cflags=['-DOPAQUE_STRUCT_B=1'],
181    ),
182    LsdumpModule(
183        name='libc_and_cpp_with_unused_struct',
184        srcs=[
185            'integration/c_and_cpp/source1.cpp',
186            'integration/c_and_cpp/source2.c',
187        ],
188        version_script='integration/c_and_cpp/map.txt',
189        export_include_dirs=['integration/c_and_cpp/include'],
190        cflags=['-DINCLUDE_UNUSED_STRUCTS=1'],
191    ),
192    LsdumpModule(
193        name='libc_and_cpp_with_unused_cstruct',
194        srcs=[
195            'integration/c_and_cpp/source1.cpp',
196            'integration/c_and_cpp/source2.c',
197        ],
198        version_script='integration/c_and_cpp/map.txt',
199        export_include_dirs=['integration/c_and_cpp/include'],
200        cflags=['-DINCLUDE_UNUSED_STRUCTS=1', '-DMAKE_UNUSED_STRUCT_C=1'],
201    ),
202    LsdumpModule(
203        name='libgolden_cpp',
204        srcs=[
205            'integration/cpp/gold/golden_1.cpp',
206            'integration/cpp/gold/high_volume_speaker.cpp',
207            'integration/cpp/gold/low_volume_speaker.cpp',
208        ],
209        version_script='integration/cpp/gold/map.txt',
210        export_include_dirs=['integration/cpp/gold/include'],
211    ),
212    LsdumpModule(
213        name='libgolden_cpp_odr',
214        srcs=[
215            'integration/cpp/gold/golden_1.cpp',
216            'integration/cpp/gold/high_volume_speaker.cpp',
217            'integration/cpp/gold/low_volume_speaker.cpp',
218        ],
219        version_script='integration/cpp/gold/map.txt',
220        export_include_dirs=['integration/cpp/gold/include'],
221        cflags=['-DTEST_ODR'],
222    ),
223    LsdumpModule(
224        name='libgolden_cpp_add_function',
225        srcs=[
226            'integration/cpp/gold/golden_1.cpp',
227            'integration/cpp/gold/high_volume_speaker.cpp',
228            'integration/cpp/gold/low_volume_speaker.cpp',
229        ],
230        version_script='integration/cpp/gold/map_add_function.txt',
231        export_include_dirs=['integration/cpp/gold/include'],
232        cflags=['-DGOLDEN_ADD_FUNCTION=1'],
233    ),
234    LsdumpModule(
235        name='libgolden_cpp_add_function_and_unexported_elf',
236        srcs=[
237            'integration/cpp/gold/golden_1.cpp',
238            'integration/cpp/gold/high_volume_speaker.cpp',
239            'integration/cpp/gold/low_volume_speaker.cpp',
240        ],
241        version_script='integration/cpp/gold/map_add_function_elf_symbol.txt',
242        export_include_dirs=['integration/cpp/gold/include'],
243        cflags=['-DGOLDEN_ADD_FUNCTION=1', '-DADD_UNEXPORTED_ELF_SYMBOL'],
244        arch='',
245        api='current',
246    ),
247    LsdumpModule(
248        name='libgolden_cpp_add_function_sybmol_only',
249        srcs=[
250            'integration/cpp/gold/golden_1.cpp',
251            'integration/cpp/gold/high_volume_speaker.cpp',
252            'integration/cpp/gold/low_volume_speaker.cpp',
253        ],
254        version_script='integration/cpp/gold/map_add_function.txt',
255        export_include_dirs=['integration/cpp/gold/include'],
256    ),
257    LsdumpModule(
258        name='libgolden_cpp_change_function_access',
259        srcs=[
260            'integration/cpp/gold/golden_1.cpp',
261            'integration/cpp/gold/high_volume_speaker.cpp',
262            'integration/cpp/gold/low_volume_speaker.cpp',
263        ],
264        version_script='integration/cpp/gold/map.txt',
265        export_include_dirs=['integration/cpp/gold/include'],
266        cflags=['-DGOLDEN_CHANGE_FUNCTION_ACCESS=1'],
267    ),
268    LsdumpModule(
269        name='libgolden_cpp_add_global_variable',
270        srcs=[
271            'integration/cpp/gold/golden_1.cpp',
272            'integration/cpp/gold/high_volume_speaker.cpp',
273            'integration/cpp/gold/low_volume_speaker.cpp',
274        ],
275        version_script='integration/cpp/gold/map_added_globvar.txt',
276        export_include_dirs=['integration/cpp/gold/include'],
277        cflags=['-DGOLDEN_ADD_GLOBVAR=1'],
278    ),
279    LsdumpModule(
280        name='libgolden_cpp_add_global_variable_private',
281        srcs=[
282            'integration/cpp/gold/golden_1.cpp',
283            'integration/cpp/gold/high_volume_speaker.cpp',
284            'integration/cpp/gold/low_volume_speaker.cpp',
285        ],
286        version_script='integration/cpp/gold/map_added_globvar.txt',
287        export_include_dirs=['integration/cpp/gold/include'],
288        cflags=['-DGOLDEN_ADD_GLOBVAR=1', '-DGOLDEN_ADD_GLOBVAR_PRIVATE'],
289    ),
290    LsdumpModule(
291        name='libgolden_cpp_return_type_diff',
292        srcs=[
293            'integration/cpp/gold/golden_1.cpp',
294            'integration/cpp/gold/high_volume_speaker.cpp',
295            'integration/cpp/gold/low_volume_speaker.cpp',
296        ],
297        version_script='integration/cpp/gold/map.txt',
298        export_include_dirs=['integration/cpp/gold/include'],
299        cflags=['-DGOLDEN_RETURN_TYPE_DIFF=1'],
300    ),
301    LsdumpModule(
302        name='libgolden_cpp_parameter_type_diff',
303        srcs=[
304            'integration/cpp/gold/golden_1.cpp',
305            'integration/cpp/gold/high_volume_speaker.cpp',
306            'integration/cpp/gold/low_volume_speaker.cpp',
307        ],
308        version_script='integration/cpp/gold/map_parameter_type_diff.txt',
309        export_include_dirs=['integration/cpp/gold/include'],
310        cflags=['-DGOLDEN_PARAMETER_TYPE_DIFF=1'],
311    ),
312    LsdumpModule(
313        name='libgolden_cpp_vtable_diff',
314        srcs=[
315            'integration/cpp/gold/golden_1.cpp',
316            'integration/cpp/gold/high_volume_speaker.cpp',
317            'integration/cpp/gold/low_volume_speaker.cpp',
318        ],
319        version_script='integration/cpp/gold/map.txt',
320        export_include_dirs=['integration/cpp/gold/include'],
321        cflags=['-DGOLDEN_VTABLE_DIFF=1'],
322    ),
323    LsdumpModule(
324        name='libgolden_cpp_member_diff',
325        srcs=[
326            'integration/cpp/gold/golden_1.cpp',
327            'integration/cpp/gold/high_volume_speaker.cpp',
328            'integration/cpp/gold/low_volume_speaker.cpp',
329        ],
330        version_script='integration/cpp/gold/map.txt',
331        export_include_dirs=['integration/cpp/gold/include'],
332        cflags=['-DGOLDEN_MEMBER_DIFF=1'],
333    ),
334    LsdumpModule(
335        name='libgolden_cpp_member_fake_diff',
336        srcs=[
337            'integration/cpp/gold/golden_1.cpp',
338            'integration/cpp/gold/high_volume_speaker.cpp',
339            'integration/cpp/gold/low_volume_speaker.cpp',
340        ],
341        version_script='integration/cpp/gold/map.txt',
342        export_include_dirs=['integration/cpp/gold/include'],
343        cflags=['-DGOLDEN_MEMBER_FAKE_DIFF=1'],
344    ),
345    LsdumpModule(
346        name='libgolden_cpp_member_cv_diff',
347        srcs=[
348            'integration/cpp/gold/golden_1.cpp',
349            'integration/cpp/gold/high_volume_speaker.cpp',
350            'integration/cpp/gold/low_volume_speaker.cpp',
351        ],
352        version_script='integration/cpp/gold/map.txt',
353        export_include_dirs=['integration/cpp/gold/include'],
354        cflags=['-DGOLDEN_MEMBER_CV_DIFF=1'],
355    ),
356    LsdumpModule(
357        name='libgolden_cpp_change_member_access',
358        srcs=[
359            'integration/cpp/gold/golden_1.cpp',
360            'integration/cpp/gold/high_volume_speaker.cpp',
361            'integration/cpp/gold/low_volume_speaker.cpp',
362        ],
363        version_script='integration/cpp/gold/map.txt',
364        export_include_dirs=['integration/cpp/gold/include'],
365        cflags=['-DGOLDEN_CHANGE_MEMBER_ACCESS=1'],
366    ),
367    LsdumpModule(
368        name='libgolden_cpp_member_integral_type_diff',
369        srcs=[
370            'integration/cpp/gold/golden_1.cpp',
371            'integration/cpp/gold/high_volume_speaker.cpp',
372            'integration/cpp/gold/low_volume_speaker.cpp',
373        ],
374        version_script='integration/cpp/gold/map.txt',
375        export_include_dirs=['integration/cpp/gold/include'],
376        cflags=['-DGOLDEN_MEMBER_INTEGRAL_TYPE_DIFF=1'],
377    ),
378    LsdumpModule(
379        name='libgolden_cpp_enum_diff',
380        srcs=[
381            'integration/cpp/gold/golden_1.cpp',
382            'integration/cpp/gold/high_volume_speaker.cpp',
383            'integration/cpp/gold/low_volume_speaker.cpp',
384        ],
385        version_script='integration/cpp/gold/map.txt',
386        export_include_dirs=['integration/cpp/gold/include'],
387        cflags=['-DGOLDEN_ENUM_DIFF=1'],
388    ),
389    LsdumpModule(
390        name='libgolden_cpp_enum_extended',
391        srcs=[
392            'integration/cpp/gold/golden_1.cpp',
393            'integration/cpp/gold/high_volume_speaker.cpp',
394            'integration/cpp/gold/low_volume_speaker.cpp',
395        ],
396        version_script='integration/cpp/gold/map.txt',
397        export_include_dirs=['integration/cpp/gold/include'],
398        cflags=['-DGOLDEN_ENUM_EXTENSION=1'],
399    ),
400    LsdumpModule(
401        name='libgolden_cpp_unreferenced_elf_symbol_removed',
402        srcs=[
403            'integration/cpp/gold/golden_1.cpp',
404            'integration/cpp/gold/high_volume_speaker.cpp',
405            'integration/cpp/gold/low_volume_speaker.cpp',
406        ],
407        version_script='integration/cpp/gold/map_elf_symbol_removed.txt',
408        export_include_dirs=['integration/cpp/gold/include'],
409    ),
410    LsdumpModule(
411        name='libreproducability',
412        srcs=['integration/c_and_cpp/reproducability.c'],
413        version_script='integration/c_and_cpp/repro_map.txt',
414        export_include_dirs=['integration/c_and_cpp/include'],
415    ),
416    LsdumpModule(
417        name='libgolden_cpp_member_name_changed',
418        srcs=[
419            'integration/cpp/gold/golden_1.cpp',
420            'integration/cpp/gold/high_volume_speaker.cpp',
421            'integration/cpp/gold/low_volume_speaker.cpp',
422        ],
423        version_script='integration/cpp/gold/map.txt',
424        export_include_dirs=['integration/cpp/gold/include'],
425        cflags=['-DGOLDEN_CHANGE_MEMBER_NAME_SAME_OFFSET=1'],
426    ),
427    LsdumpModule(
428        name='libgolden_cpp_function_pointer',
429        srcs=[
430            'integration/cpp/gold/golden_1.cpp',
431            'integration/cpp/gold/high_volume_speaker.cpp',
432            'integration/cpp/gold/low_volume_speaker.cpp',
433        ],
434        version_script='integration/cpp/gold/map.txt',
435        export_include_dirs=['integration/cpp/gold/include'],
436        cflags=['-DGOLDEN_FUNCTION_POINTER=1'],
437    ),
438    LsdumpModule(
439        name='libgolden_cpp_function_pointer_parameter_added',
440        srcs=[
441            'integration/cpp/gold/golden_1.cpp',
442            'integration/cpp/gold/high_volume_speaker.cpp',
443            'integration/cpp/gold/low_volume_speaker.cpp',
444        ],
445        version_script='integration/cpp/gold/map.txt',
446        export_include_dirs=['integration/cpp/gold/include'],
447        cflags=['-DGOLDEN_FUNCTION_POINTER_ADD_PARAM=1',
448                '-DGOLDEN_FUNCTION_POINTER=1'],
449    ),
450    LsdumpModule(
451        name='libgolden_cpp_internal_public_struct',
452        srcs=[
453            'integration/cpp/gold/golden_1.cpp',
454            'integration/cpp/gold/high_volume_speaker.cpp',
455            'integration/cpp/gold/low_volume_speaker.cpp',
456        ],
457        version_script='integration/cpp/gold/map.txt',
458        export_include_dirs=['integration/cpp/gold/include'],
459        cflags=['-DGOLDEN_WITH_INTERNAL_STRUCT',
460                '-DGOLDEN_WITH_PUBLIC_INTERNAL_STRUCT'],
461    ),
462    LsdumpModule(
463        name='libgolden_cpp_internal_private_struct',
464        srcs=[
465            'integration/cpp/gold/golden_1.cpp',
466            'integration/cpp/gold/high_volume_speaker.cpp',
467            'integration/cpp/gold/low_volume_speaker.cpp',
468        ],
469        version_script='integration/cpp/gold/map.txt',
470        export_include_dirs=['integration/cpp/gold/include'],
471        cflags=['-DGOLDEN_WITH_INTERNAL_STRUCT'],
472    ),
473    LsdumpModule(
474        name='libgolden_cpp_inheritance_type_changed',
475        srcs=[
476            'integration/cpp/gold/golden_1.cpp',
477            'integration/cpp/gold/high_volume_speaker.cpp',
478            'integration/cpp/gold/low_volume_speaker.cpp',
479        ],
480        version_script='integration/cpp/gold/map.txt',
481        export_include_dirs=['integration/cpp/gold/include'],
482        cflags=['-DGOLDEN_CHANGE_INHERITANCE_TYPE'],
483    ),
484    LsdumpModule(
485        name='libpure_virtual_function',
486        srcs=['integration/cpp/pure_virtual/pure_virtual_function.cpp'],
487        export_include_dirs=['integration/cpp/pure_virtual/include'],
488        version_script='',
489    ),
490    LsdumpModule(
491        name='libgolden_cpp_json',
492        srcs=[
493            'integration/cpp/gold/golden_1.cpp',
494            'integration/cpp/gold/high_volume_speaker.cpp',
495            'integration/cpp/gold/low_volume_speaker.cpp',
496        ],
497        version_script='integration/cpp/gold/map.txt',
498        export_include_dirs=['integration/cpp/gold/include'],
499        dumper_flags=['-output-format', 'Json'],
500        linker_flags=['-input-format', 'Json', '-output-format', 'Json']
501    ),
502    LsdumpModule(
503        name='libversion_script_example',
504        arch='arm64',
505        srcs=[
506            'integration/version_script_example/example.cpp',
507        ],
508        version_script='integration/version_script_example/example.map.txt',
509        export_include_dirs=['integration/version_script_example'],
510        dumper_flags=['-output-format', 'Json'],
511        linker_flags=[
512            '-input-format', 'Json',
513            '-output-format', 'Json',
514            '-so', relative_to_abs_path(
515                'integration/version_script_example/prebuilts/' +
516                'libversion_script_example.so'
517            ),
518        ]
519    ),
520    LsdumpModule(
521        name='libversion_script_example_no_private',
522        arch='arm64',
523        srcs=[
524            'integration/version_script_example/example.cpp',
525        ],
526        version_script='integration/version_script_example/example.map.txt',
527        export_include_dirs=['integration/version_script_example'],
528        dumper_flags=['-output-format', 'Json'],
529        linker_flags=[
530            '-input-format', 'Json',
531            '-output-format', 'Json',
532            '-so', relative_to_abs_path(
533                'integration/version_script_example/prebuilts/' +
534                'libversion_script_example.so'
535            ),
536            '--exclude-symbol-version', 'LIBVERSION_SCRIPT_EXAMPLE_PRIVATE',
537        ]
538    ),
539    LsdumpModule(
540        name='libversion_script_example_no_mytag',
541        arch='arm64',
542        srcs=[
543            'integration/version_script_example/example.cpp',
544        ],
545        version_script='integration/version_script_example/example.map.txt',
546        export_include_dirs=['integration/version_script_example'],
547        dumper_flags=['-output-format', 'Json'],
548        linker_flags=[
549            '-input-format', 'Json',
550            '-output-format', 'Json',
551            '-so', relative_to_abs_path(
552                'integration/version_script_example/prebuilts/' +
553                'libversion_script_example.so'
554            ),
555            '--exclude-symbol-tag', 'mytag',
556        ]
557    ),
558
559    # Test data for test_allow_adding_removing_weak_symbols
560    LsdumpModule(
561        name='libweak_symbols_old',
562        arch='arm64',
563        srcs=[
564            'integration/weak_symbols/example.c',
565        ],
566        version_script='integration/weak_symbols/libexample_old.map.txt',
567        export_include_dirs=[],
568        dumper_flags=['-output-format', 'Json'],
569        linker_flags=[
570            '-input-format', 'Json',
571            '-output-format', 'Json',
572        ]
573    ),
574    LsdumpModule(
575        name='libweak_symbols_new',
576        arch='arm64',
577        srcs=[
578            'integration/weak_symbols/example.c',
579        ],
580        version_script='integration/weak_symbols/libexample_new.map.txt',
581        export_include_dirs=[],
582        dumper_flags=['-output-format', 'Json'],
583        linker_flags=[
584            '-input-format', 'Json',
585            '-output-format', 'Json',
586        ],
587        cflags=['-DNEW=1']
588    ),
589]
590
591TEST_MODULES = {m.name: m for m in TEST_MODULES}
592