From a6bd6ed7bc1b082241d083cd5eba4cbd3d056904 Mon Sep 17 00:00:00 2001 From: Hsin-Yi Chen Date: Sat, 21 Mar 2020 01:55:48 +0800 Subject: [PATCH] Look up referenced types' compilation unit paths when linking ABI dumps When header-abi-linker merges a pointer, reference, array, or qualified type, it looks up the referenced type's compilation unit path, and uses the path to distinguish multiple definitions of the type as well as the types referencing it. Test: ./test.py Bug: 147396457 Change-Id: If6b35e941f9aa03616b236289450c9b10062b719 --- .../src/linker/module_merger.cpp | 53 ++++++++++++++++--- .../header-checker/src/linker/module_merger.h | 3 -- .../libmerge_multi_definitions.so.lsdump | 19 ++----- 3 files changed, 51 insertions(+), 24 deletions(-) diff --git a/vndk/tools/header-checker/src/linker/module_merger.cpp b/vndk/tools/header-checker/src/linker/module_merger.cpp index 54e13af64..5132d2fe6 100644 --- a/vndk/tools/header-checker/src/linker/module_merger.cpp +++ b/vndk/tools/header-checker/src/linker/module_merger.cpp @@ -349,6 +349,43 @@ MergeStatus ModuleMerger::MergeReferencingTypeInternalAndUpdateParent( } +static bool IsReferencingType(LinkableMessageKind kind) { + switch (kind) { + case PointerTypeKind: + case QualifiedTypeKind: + case ArrayTypeKind: + case LvalueReferenceTypeKind: + case RvalueReferenceTypeKind: + return true; + case RecordTypeKind: + case EnumTypeKind: + case BuiltinTypeKind: + case FunctionTypeKind: + case FunctionKind: + case GlobalVarKind: + return false; + } +} + + +// Trace the referenced type until reaching a RecordTypeIR, EnumTypeIR, +// FunctionTypeIR, or BuiltinTypeIR. Return nullptr if the referenced type is +// undefined or built-in. +static const TypeIR *DereferenceType(const ModuleIR &module, + const TypeIR *type_ir) { + auto &type_graph = module.GetTypeGraph(); + while (IsReferencingType(type_ir->GetKind())) { + auto it = type_graph.find(type_ir->GetReferencedType()); + // The referenced type is undefined in the module. + if (it == type_graph.end()) { + return nullptr; + } + type_ir = it->second; + } + return type_ir; +} + + // This method creates a new node for the addend node in the graph if MergeType // on the reference returned a MergeStatus with was_newly_added_ = true. MergeStatus ModuleMerger::MergeReferencingType( @@ -360,7 +397,15 @@ MergeStatus ModuleMerger::MergeReferencingType( std::string added_type_id = addend_node->GetSelfType(); auto type_id_it = module_->type_graph_.find(added_type_id); if (type_id_it != module_->type_graph_.end()) { - added_type_id = AllocateNewTypeId(added_type_id, addend); + const TypeIR *final_referenced_type = DereferenceType(addend, addend_node); + if (final_referenced_type != nullptr) { + std::string compilation_unit_path = + addend.GetCompilationUnitPath(final_referenced_type); + // The path is empty for built-in types. + if (compilation_unit_path != "") { + added_type_id = added_type_id + "#ODR:" + compilation_unit_path; + } + } } // Add the added record type to the local_to_global_type_id_map. @@ -507,12 +552,6 @@ void ModuleMerger::MergeFunction( } -std::string ModuleMerger::AllocateNewTypeId(const std::string &addend_type_id, - const ModuleIR &addend_module) { - return addend_type_id + "#ODR:" + addend_module.GetCompilationUnitPath(); -} - - void ModuleMerger::MergeGlobalVariable( const GlobalVarIR *addend_node, const ModuleIR &addend, AbiElementMap *local_to_global_type_id_map) { diff --git a/vndk/tools/header-checker/src/linker/module_merger.h b/vndk/tools/header-checker/src/linker/module_merger.h index 4e21eab8b..56acbfa69 100644 --- a/vndk/tools/header-checker/src/linker/module_merger.h +++ b/vndk/tools/header-checker/src/linker/module_merger.h @@ -144,9 +144,6 @@ private: const TypeIR *addend_type, const ModuleIR &addend, AbiElementMap *merged_types_cache); - std::string AllocateNewTypeId(const std::string &addend_type_id, - const ModuleIR &addend_module); - private: std::unique_ptr module_; diff --git a/vndk/tools/header-checker/tests/reference_dumps/arm64/libmerge_multi_definitions.so.lsdump b/vndk/tools/header-checker/tests/reference_dumps/arm64/libmerge_multi_definitions.so.lsdump index fa5cfe5f3..74a60065a 100644 --- a/vndk/tools/header-checker/tests/reference_dumps/arm64/libmerge_multi_definitions.so.lsdump +++ b/vndk/tools/header-checker/tests/reference_dumps/arm64/libmerge_multi_definitions.so.lsdump @@ -67,7 +67,7 @@ "linker_set_key" : "_ZTIP6Struct", "name" : "Struct *", "referenced_type" : "_ZTI6Struct#ODR:/def2.h.sdump", - "self_type" : "_ZTIP6Struct#ODR:", + "self_type" : "_ZTIP6Struct#ODR:/def2.h.sdump", "size" : 8, "source_file" : "/development/vndk/tools/header-checker/tests/integration/merge_multi_definitions/include/def2.h" }, @@ -80,15 +80,6 @@ "size" : 8, "source_file" : "/development/vndk/tools/header-checker/tests/integration/merge_multi_definitions/include/def1.h" }, - { - "alignment" : 8, - "linker_set_key" : "_ZTIPK6Opaque", - "name" : "const Opaque *", - "referenced_type" : "_ZTIK6Opaque#ODR:", - "self_type" : "_ZTIPK6Opaque#ODR:", - "size" : 8, - "source_file" : "/development/vndk/tools/header-checker/tests/integration/merge_multi_definitions/include/def2.h" - }, { "alignment" : 8, "linker_set_key" : "_ZTIPK6Struct", @@ -102,8 +93,8 @@ "alignment" : 8, "linker_set_key" : "_ZTIPK6Struct", "name" : "const Struct *", - "referenced_type" : "_ZTIK6Struct#ODR:", - "self_type" : "_ZTIPK6Struct#ODR:", + "referenced_type" : "_ZTIK6Struct#ODR:/def2.h.sdump", + "self_type" : "_ZTIPK6Struct#ODR:/def2.h.sdump", "size" : 8, "source_file" : "/development/vndk/tools/header-checker/tests/integration/merge_multi_definitions/include/def2.h" } @@ -124,7 +115,7 @@ "linker_set_key" : "_ZTIK6Struct", "name" : "const Struct", "referenced_type" : "_ZTI6Struct#ODR:/def2.h.sdump", - "self_type" : "_ZTIK6Struct#ODR:", + "self_type" : "_ZTIK6Struct#ODR:/def2.h.sdump", "size" : 8, "source_file" : "/development/vndk/tools/header-checker/tests/integration/merge_multi_definitions/include/def2.h" }, @@ -163,7 +154,7 @@ [ { "field_name" : "member2", - "referenced_type" : "_ZTIP6Struct#ODR:" + "referenced_type" : "_ZTIP6Struct#ODR:/def2.h.sdump" } ], "linker_set_key" : "_ZTI6Struct",