diff --git a/vndk/tools/header-checker/header-abi-diff/src/abi_diff.cpp b/vndk/tools/header-checker/header-abi-diff/src/abi_diff.cpp index 2968f40c5..e13d04f0a 100644 --- a/vndk/tools/header-checker/header-abi-diff/src/abi_diff.cpp +++ b/vndk/tools/header-checker/header-abi-diff/src/abi_diff.cpp @@ -18,9 +18,6 @@ #include -#include -#include - #include #include #include @@ -30,16 +27,16 @@ abi_util::CompatibilityStatusIR HeaderAbiDiff::GenerateCompatibilityReport() { using abi_util::TextFormatToIRReader; std::unique_ptr old_reader = - TextFormatToIRReader::CreateTextFormatToIRReader("protobuf", old_dump_); + TextFormatToIRReader::CreateTextFormatToIRReader(text_format_old_); std::unique_ptr new_reader = - TextFormatToIRReader::CreateTextFormatToIRReader("protobuf", new_dump_); - if (!old_reader || !new_reader || !old_reader->ReadDump() || - !new_reader->ReadDump()) { + TextFormatToIRReader::CreateTextFormatToIRReader(text_format_new_); + if (!old_reader || !new_reader || !old_reader->ReadDump(old_dump_) || + !new_reader->ReadDump(new_dump_)) { llvm::errs() << "Could not create Text Format readers\n"; ::exit(1); } std::unique_ptr ir_diff_dumper = - abi_util::IRDiffDumper::CreateIRDiffDumper("protobuf", cr_); + abi_util::IRDiffDumper::CreateIRDiffDumper(text_format_diff_, cr_); abi_util::CompatibilityStatusIR status = CompareTUs(old_reader.get(), new_reader.get(), ir_diff_dumper.get()); if (!ir_diff_dumper->Dump()) { @@ -49,17 +46,18 @@ abi_util::CompatibilityStatusIR HeaderAbiDiff::GenerateCompatibilityReport() { return status; } -template -static void AddTypesToMap(std::map *dst, - const abi_util::TextFormatToIRReader *tu, F func) { - AddToMap(dst, tu->GetRecordTypes(), func); - AddToMap(dst, tu->GetEnumTypes(), func); - AddToMap(dst, tu->GetPointerTypes(), func); - AddToMap(dst, tu->GetBuiltinTypes(), func); - AddToMap(dst, tu->GetArrayTypes(), func); - AddToMap(dst, tu->GetLvalueReferenceTypes(), func); - AddToMap(dst, tu->GetRvalueReferenceTypes(), func); - AddToMap(dst, tu->GetQualifiedTypes(), func); +template +static void AddTypesToMap(AbiElementMap *dst, + const abi_util::TextFormatToIRReader *tu, + KeyGetter get_key, ValueGetter get_value) { + AddToMap(dst, tu->GetRecordTypes(), get_key, get_value); + AddToMap(dst, tu->GetEnumTypes(), get_key, get_value); + AddToMap(dst, tu->GetPointerTypes(), get_key, get_value); + AddToMap(dst, tu->GetBuiltinTypes(), get_key, get_value); + AddToMap(dst, tu->GetArrayTypes(), get_key, get_value); + AddToMap(dst, tu->GetLvalueReferenceTypes(), get_key, get_value); + AddToMap(dst, tu->GetRvalueReferenceTypes(), get_key, get_value); + AddToMap(dst, tu->GetQualifiedTypes(), get_key, get_value); } abi_util::CompatibilityStatusIR HeaderAbiDiff::CompareTUs( @@ -68,12 +66,14 @@ abi_util::CompatibilityStatusIR HeaderAbiDiff::CompareTUs( abi_util::IRDiffDumper *ir_diff_dumper) { // Collect all old and new types in maps, so that we can refer to them by // type name / linker_set_key later. - std::map old_types; - std::map new_types; + AbiElementMap old_types; + AbiElementMap new_types; AddTypesToMap(&old_types, old_tu, - [](const abi_util::TypeIR *e) {return e->GetLinkerSetKey();}); + [](auto e) {return e->first;}, + [](auto e) {return &(e->second);}); AddTypesToMap(&new_types, new_tu, - [](const abi_util::TypeIR *e) {return e->GetLinkerSetKey();}); + [](auto e) {return e->first;}, + [](auto e) {return &(e->second);}); // Collect fills in added, removed ,unsafe and safe function diffs. if (!CollectDynsymExportables(old_tu->GetFunctions(), new_tu->GetFunctions(), @@ -111,8 +111,8 @@ abi_util::CompatibilityStatusIR HeaderAbiDiff::CompareTUs( bool HeaderAbiDiff::CollectUserDefinedTypes( const abi_util::TextFormatToIRReader *old_tu, const abi_util::TextFormatToIRReader *new_tu, - const std::map &old_types_map, - const std::map &new_types_map, + const AbiElementMap &old_types_map, + const AbiElementMap &new_types_map, abi_util::IRDiffDumper *ir_diff_dumper) { return CollectUserDefinedTypesInternal( old_tu->GetRecordTypes(), new_tu->GetRecordTypes(), old_types_map, @@ -124,22 +124,23 @@ bool HeaderAbiDiff::CollectUserDefinedTypes( template bool HeaderAbiDiff::CollectUserDefinedTypesInternal( - const std::vector &old_ud_types, - const std::vector &new_ud_types, - const std::map &old_types_map, - const std::map &new_types_map, + const AbiElementMap &old_ud_types, + const AbiElementMap &new_ud_types, + const AbiElementMap &old_types_map, + const AbiElementMap &new_types_map, abi_util::IRDiffDumper *ir_diff_dumper) { + // No elf information for records and enums. - std::map old_ud_types_map; - std::map new_ud_types_map; + AbiElementMap old_ud_types_map; + AbiElementMap new_ud_types_map; abi_util::AddToMap(&old_ud_types_map, old_ud_types, - [](const T *e) - { return e->GetLinkerSetKey();}); + [](auto e) { return e->first;}, + [](auto e) {return &(e->second);}); abi_util::AddToMap(&new_ud_types_map, new_ud_types, - [](const T *e) - { return e->GetLinkerSetKey();}); + [](auto e) { return e->first;}, + [](auto e) {return &(e->second);}); return Collect(old_ud_types_map, new_ud_types_map, nullptr, nullptr, ir_diff_dumper) && @@ -150,30 +151,34 @@ bool HeaderAbiDiff::CollectUserDefinedTypesInternal( template bool HeaderAbiDiff::CollectDynsymExportables( - const std::vector &old_exportables, - const std::vector &new_exportables, - const std::vector &old_elf_symbols, - const std::vector &new_elf_symbols, - const std::map &old_types_map, - const std::map &new_types_map, + const AbiElementMap &old_exportables, + const AbiElementMap &new_exportables, + const AbiElementMap &old_elf_symbols, + const AbiElementMap &new_elf_symbols, + const AbiElementMap &old_types_map, + const AbiElementMap &new_types_map, abi_util::IRDiffDumper *ir_diff_dumper) { - std::map old_exportables_map; - std::map new_exportables_map; - std::map old_elf_symbol_map; - std::map new_elf_symbol_map; + AbiElementMap old_exportables_map; + AbiElementMap new_exportables_map; + AbiElementMap old_elf_symbol_map; + AbiElementMap new_elf_symbol_map; abi_util::AddToMap(&old_exportables_map, old_exportables, - [](const T *e) - { return e->GetLinkerSetKey();}); + [](auto e) { return e->first;}, + [](auto e) {return &(e->second);}); abi_util::AddToMap(&new_exportables_map, new_exportables, - [](const T *e) - { return e->GetLinkerSetKey();}); + [](auto e) { return e->first;}, + [](auto e) { return &(e->second);}); + abi_util::AddToMap( &old_elf_symbol_map, old_elf_symbols, - [](const ElfSymbolType *symbol) { return symbol->GetName();}); + [](auto e) { return e->first;}, + [](auto e) {return &(e->second);}); + abi_util::AddToMap( &new_elf_symbol_map, new_elf_symbols, - [](const ElfSymbolType *symbol) { return symbol->GetName();}); + [](auto e) { return e->first;}, + [](auto e) {return &(e->second);}); if (!Collect(old_exportables_map, new_exportables_map, &old_elf_symbol_map, &new_elf_symbol_map, @@ -197,10 +202,10 @@ bool HeaderAbiDiff::CollectDynsymExportables( template bool HeaderAbiDiff::Collect( - const std::map &old_elements_map, - const std::map &new_elements_map, - const std::map *old_elf_map, - const std::map *new_elf_map, + const AbiElementMap &old_elements_map, + const AbiElementMap &new_elements_map, + const AbiElementMap *old_elf_map, + const AbiElementMap *new_elf_map, abi_util::IRDiffDumper *ir_diff_dumper) { if (!PopulateRemovedElements( old_elements_map, new_elements_map, new_elf_map, ir_diff_dumper, @@ -215,8 +220,8 @@ bool HeaderAbiDiff::Collect( } bool HeaderAbiDiff::CollectElfSymbols( - const std::map &old_symbols, - const std::map &new_symbols, + const AbiElementMap &old_symbols, + const AbiElementMap &new_symbols, abi_util::IRDiffDumper *ir_diff_dumper) { std::vector removed_elements = abi_util::FindRemovedElements(old_symbols, new_symbols); @@ -244,9 +249,9 @@ bool HeaderAbiDiff::PopulateElfElements( template bool HeaderAbiDiff::PopulateRemovedElements( - const std::map &old_elements_map, - const std::map &new_elements_map, - const std::map *elf_map, + const AbiElementMap &old_elements_map, + const AbiElementMap &new_elements_map, + const AbiElementMap *elf_map, abi_util::IRDiffDumper *ir_diff_dumper, abi_util::IRDiffDumper::DiffKind diff_kind) { std::vector removed_elements = @@ -258,12 +263,15 @@ bool HeaderAbiDiff::PopulateRemovedElements( return true; } +// Find the common elements (common records, common enums, common functions etc) +// Dump the differences (we need type maps for this diff since we'll get +// reachable types from here) template bool HeaderAbiDiff::PopulateCommonElements( - const std::map &old_elements_map, - const std::map &new_elements_map, - const std::map &old_types, - const std::map &new_types, + const AbiElementMap &old_elements_map, + const AbiElementMap &new_elements_map, + const AbiElementMap &old_types, + const AbiElementMap &new_types, abi_util::IRDiffDumper *ir_diff_dumper, abi_util::IRDiffDumper::DiffKind diff_kind) { std::vector> common_elements = @@ -279,7 +287,7 @@ bool HeaderAbiDiff::PopulateCommonElements( template bool HeaderAbiDiff::DumpLoneElements( std::vector &elements, - const std::map *elf_map, + const AbiElementMap *elf_map, abi_util::IRDiffDumper *ir_diff_dumper, abi_util::IRDiffDumper::DiffKind diff_kind) { // If the record / enum has source file information, skip it. @@ -310,12 +318,11 @@ bool HeaderAbiDiff::DumpLoneElements( return true; } - template bool HeaderAbiDiff::DumpDiffElements( std::vector> &pairs, - const std::map &old_types, - const std::map &new_types, + const AbiElementMap &old_types, + const AbiElementMap &new_types, abi_util::IRDiffDumper *ir_diff_dumper, abi_util::IRDiffDumper::DiffKind diff_kind) { for (auto &&pair : pairs) { diff --git a/vndk/tools/header-checker/header-abi-diff/src/abi_diff.h b/vndk/tools/header-checker/header-abi-diff/src/abi_diff.h index 3cabc8bdb..7803c4b24 100644 --- a/vndk/tools/header-checker/header-abi-diff/src/abi_diff.h +++ b/vndk/tools/header-checker/header-abi-diff/src/abi_diff.h @@ -26,16 +26,22 @@ #include #include +using abi_util::AbiElementMap; + class HeaderAbiDiff { public: HeaderAbiDiff(const std::string &lib_name, const std::string &arch, const std::string &old_dump, const std::string &new_dump, const std::string &compatibility_report, const std::set &ignored_symbols, - bool check_all_apis) + bool check_all_apis, abi_util::TextFormatIR text_format_old, + abi_util::TextFormatIR text_format_new, + abi_util::TextFormatIR text_format_diff) : lib_name_(lib_name), arch_(arch), old_dump_(old_dump), new_dump_(new_dump), cr_(compatibility_report), - ignored_symbols_(ignored_symbols), check_all_apis_(check_all_apis) { } + ignored_symbols_(ignored_symbols), check_all_apis_(check_all_apis), + text_format_old_(text_format_old), text_format_new_(text_format_new), + text_format_diff_(text_format_diff) { } abi_util::CompatibilityStatusIR GenerateCompatibilityReport(); @@ -47,25 +53,25 @@ class HeaderAbiDiff { template bool CollectDynsymExportables( - const std::vector &old_exportables, - const std::vector &new_exportables, - const std::vector &old_elf_symbols, - const std::vector &new_elf_symbols, - const std::map &old_types_map, - const std::map &new_types_map, + const AbiElementMap &old_exportables, + const AbiElementMap &new_exportables, + const AbiElementMap &old_elf_symbols, + const AbiElementMap &new_elf_symbols, + const AbiElementMap &old_types_map, + const AbiElementMap &new_types_map, abi_util::IRDiffDumper *ir_diff_dumper); template bool Collect( - const std::map &old_elements_map, - const std::map &new_elements_map, - const std::map *old_elf_map, - const std::map *new_elf_map, + const AbiElementMap &old_elements_map, + const AbiElementMap &new_elements_map, + const AbiElementMap *old_elf_map, + const AbiElementMap *new_elf_map, abi_util::IRDiffDumper *ir_diff_dumper); bool CollectElfSymbols( - const std::map &old_symbols, - const std::map &new_symbols, + const AbiElementMap &old_symbols, + const AbiElementMap &new_symbols, abi_util::IRDiffDumper *ir_diff_dumper); bool PopulateElfElements( @@ -75,49 +81,49 @@ class HeaderAbiDiff { template bool PopulateRemovedElements( - const std::map &old_elements_map, - const std::map &new_elements_map, - const std::map *elf_map, + const AbiElementMap &old_elements_map, + const AbiElementMap &new_elements_map, + const AbiElementMap *elf_map, abi_util::IRDiffDumper *ir_diff_dumper, abi_util::IRDiffDumper::DiffKind diff_kind); template bool PopulateCommonElements( - const std::map &old_elements_map, - const std::map &new_elements_map, - const std::map &old_types, - const std::map &new_types, + const AbiElementMap &old_elements_map, + const AbiElementMap &new_elements_map, + const AbiElementMap &old_types, + const AbiElementMap &new_types, abi_util::IRDiffDumper *ir_diff_dumper, abi_util::IRDiffDumper::DiffKind diff_kind); template bool DumpDiffElements( std::vector> &pairs, - const std::map &old_types, - const std::map &new_types, + const AbiElementMap &old_types, + const AbiElementMap &new_types, abi_util::IRDiffDumper *ir_diff_dumper, abi_util::IRDiffDumper::DiffKind diff_kind); template bool DumpLoneElements( std::vector &elements, - const std::map *elf_map, + const AbiElementMap *elf_map, abi_util::IRDiffDumper *ir_diff_dumper, abi_util::IRDiffDumper::DiffKind diff_kind); bool CollectUserDefinedTypes( const abi_util::TextFormatToIRReader *old_tu, const abi_util::TextFormatToIRReader *new_tu, - const std::map &old_types_map, - const std::map &new_types_map, + const AbiElementMap &old_types_map, + const AbiElementMap &new_types_map, abi_util::IRDiffDumper *ir_diff_dumper); template bool CollectUserDefinedTypesInternal( - const std::vector &old_ud_types, - const std::vector &new_ud_types, - const std::map &old_types_map, - const std::map &new_types_map, + const AbiElementMap &old_ud_types, + const AbiElementMap &new_ud_types, + const AbiElementMap &old_types_map, + const AbiElementMap &new_types_map, abi_util::IRDiffDumper *ir_diff_dumper); private: @@ -129,4 +135,7 @@ class HeaderAbiDiff { const std::set &ignored_symbols_; bool check_all_apis_; std::set type_cache_; + abi_util::TextFormatIR text_format_old_; + abi_util::TextFormatIR text_format_new_; + abi_util::TextFormatIR text_format_diff_; }; diff --git a/vndk/tools/header-checker/header-abi-diff/src/abi_diff_wrappers.cpp b/vndk/tools/header-checker/header-abi-diff/src/abi_diff_wrappers.cpp index 34b9642a6..ed3ccfe30 100644 --- a/vndk/tools/header-checker/header-abi-diff/src/abi_diff_wrappers.cpp +++ b/vndk/tools/header-checker/header-abi-diff/src/abi_diff_wrappers.cpp @@ -20,6 +20,8 @@ namespace abi_diff_wrappers { +using abi_util::AbiElementMap; + static bool IsAccessDownGraded(abi_util::AccessSpecifierIR old_access, abi_util::AccessSpecifierIR new_access) { bool access_downgraded = false; @@ -57,14 +59,16 @@ void DiffWrapperBase::CompareEnumFields( const std::vector &old_fields, const std::vector &new_fields, abi_util::EnumTypeDiffIR *enum_type_diff_ir) { - std::map old_fields_map; - std::map new_fields_map; + AbiElementMap old_fields_map; + AbiElementMap new_fields_map; abi_util::AddToMap(&old_fields_map, old_fields, - [](const abi_util::EnumFieldIR *f) - {return f->GetName();}); + [](const abi_util::EnumFieldIR *f) {return f->GetName();}, + [](const abi_util::EnumFieldIR *f) {return f;}); + abi_util::AddToMap(&new_fields_map, new_fields, - [](const abi_util::EnumFieldIR *f) - {return f->GetName();}); + [](const abi_util::EnumFieldIR *f) {return f->GetName();}, + [](const abi_util::EnumFieldIR *f) {return f;}); + std::vector removed_fields = abi_util::FindRemovedElements(old_fields_map, new_fields_map); @@ -184,23 +188,27 @@ DiffWrapperBase::CompareRecordFields( abi_util::DiffMessageIR::DiffKind diff_kind) { std::pair, std::vector> diffed_and_removed_fields; - std::map old_fields_map; - std::map new_fields_map; + AbiElementMap old_fields_map; + AbiElementMap new_fields_map; std::map old_fields_offset_map; std::map new_fields_offset_map; - abi_util::AddToMap(&old_fields_map, old_fields, - [](const abi_util::RecordFieldIR *f) - {return f->GetName();}); - abi_util::AddToMap(&new_fields_map, new_fields, - [](const abi_util::RecordFieldIR *f) - {return f->GetName();}); - abi_util::AddToMap(&old_fields_offset_map, old_fields, - [](const abi_util::RecordFieldIR *f) - {return f->GetOffset();}); - abi_util::AddToMap(&new_fields_offset_map, new_fields, - [](const abi_util::RecordFieldIR *f) - {return f->GetOffset();}); + abi_util::AddToMap( + &old_fields_map, old_fields, + [](const abi_util::RecordFieldIR *f) {return f->GetName();}, + [](const abi_util::RecordFieldIR *f) {return f;}); + abi_util::AddToMap( + &new_fields_map, new_fields, + [](const abi_util::RecordFieldIR *f) {return f->GetName();}, + [](const abi_util::RecordFieldIR *f) {return f;}); + abi_util::AddToMap( + &old_fields_offset_map, old_fields, + [](const abi_util::RecordFieldIR *f) {return f->GetOffset();}, + [](const abi_util::RecordFieldIR *f) {return f;}); + abi_util::AddToMap( + &new_fields_offset_map, new_fields, + [](const abi_util::RecordFieldIR *f) {return f->GetOffset();}, + [](const abi_util::RecordFieldIR *f) {return f;}); // If a field is removed from the map field_name -> offset see if another // field is present at the same offset and compare the size and type etc, // remove it from the removed fields if they're compatible. @@ -522,9 +530,9 @@ DiffStatus DiffWrapperBase::CompareAndDumpTypeDiff( } type_queue->push_back(old_type_str); } - std::map::const_iterator old_it = + AbiElementMap::const_iterator old_it = old_types_.find(old_type_str); - std::map::const_iterator new_it = + AbiElementMap::const_iterator new_it = new_types_.find(new_type_str); if (old_it == old_types_.end() || new_it == new_types_.end()) { // Do a simple string comparison. diff --git a/vndk/tools/header-checker/header-abi-diff/src/abi_diff_wrappers.h b/vndk/tools/header-checker/header-abi-diff/src/abi_diff_wrappers.h index 9b0a7f57e..1018ce545 100644 --- a/vndk/tools/header-checker/header-abi-diff/src/abi_diff_wrappers.h +++ b/vndk/tools/header-checker/header-abi-diff/src/abi_diff_wrappers.h @@ -28,6 +28,8 @@ namespace abi_diff_wrappers { +using abi_util::AbiElementMap; + template static bool IgnoreSymbol(const T *element, const std::set &ignored_symbols, @@ -50,8 +52,8 @@ class DiffWrapperBase { protected: DiffWrapperBase( abi_util::IRDiffDumper *ir_diff_dumper, - const std::map &old_types, - const std::map &new_types, + const AbiElementMap &old_types, + const AbiElementMap &new_types, std::set *type_cache) : ir_diff_dumper_(ir_diff_dumper), old_types_(old_types), new_types_(new_types), @@ -157,8 +159,8 @@ class DiffWrapperBase { std::deque *type_queue = nullptr); protected: abi_util::IRDiffDumper *ir_diff_dumper_; - const std::map &old_types_; - const std::map &new_types_; + const AbiElementMap &old_types_; + const AbiElementMap &new_types_; std::set *type_cache_; }; @@ -167,8 +169,8 @@ class DiffWrapper : public DiffWrapperBase { public: DiffWrapper(const T *oldp, const T *newp, abi_util::IRDiffDumper *ir_diff_dumper, - const std::map &old_types, - const std::map &new_types, + const AbiElementMap &old_types, + const AbiElementMap &new_types, std::set *type_cache) : DiffWrapperBase(ir_diff_dumper, old_types, new_types, type_cache), oldp_(oldp), newp_(newp) { } diff --git a/vndk/tools/header-checker/header-abi-diff/src/header_abi_diff.cpp b/vndk/tools/header-checker/header-abi-diff/src/header_abi_diff.cpp index 15dc3db24..bfa20d00e 100644 --- a/vndk/tools/header-checker/header-abi-diff/src/header_abi_diff.cpp +++ b/vndk/tools/header-checker/header-abi-diff/src/header_abi_diff.cpp @@ -85,6 +85,30 @@ static llvm::cl::opt allow_unreferenced_changes( " APIs."), llvm::cl::Optional, llvm::cl::cat(header_checker_category)); +static llvm::cl::opt text_format_old( + "text-format-old", llvm::cl::desc("Specify text format of old abi dump"), + llvm::cl::values(clEnumValN(abi_util::TextFormatIR::ProtobufTextFormat, + "ProtobufTextFormat","ProtobufTextFormat"), + clEnumValEnd), + llvm::cl::init(abi_util::TextFormatIR::ProtobufTextFormat), + llvm::cl::cat(header_checker_category)); + +static llvm::cl::opt text_format_new( + "text-format-new", llvm::cl::desc("Specify text format of new abi dump"), + llvm::cl::values(clEnumValN(abi_util::TextFormatIR::ProtobufTextFormat, + "ProtobufTextFormat", "ProtobugTextFormat"), + clEnumValEnd), + llvm::cl::init(abi_util::TextFormatIR::ProtobufTextFormat), + llvm::cl::cat(header_checker_category)); + +static llvm::cl::opt text_format_diff( + "text-format-diff", llvm::cl::desc("Specify text format of abi-diff"), + llvm::cl::values(clEnumValN(abi_util::TextFormatIR::ProtobufTextFormat, + "ProtobufTextFormat", "ProtobufTextFormat"), + clEnumValEnd), + llvm::cl::init(abi_util::TextFormatIR::ProtobufTextFormat), + llvm::cl::cat(header_checker_category)); + static std::set LoadIgnoredSymbols(std::string &symbol_list_path) { std::ifstream symbol_ifstream(symbol_list_path); std::set ignored_symbols; @@ -100,14 +124,14 @@ static std::set LoadIgnoredSymbols(std::string &symbol_list_path) { } int main(int argc, const char **argv) { - GOOGLE_PROTOBUF_VERIFY_VERSION; llvm::cl::ParseCommandLineOptions(argc, argv, "header-checker"); std::set ignored_symbols; if (llvm::sys::fs::exists(ignore_symbol_list)) { ignored_symbols = LoadIgnoredSymbols(ignore_symbol_list); } HeaderAbiDiff judge(lib_name, arch, old_dump, new_dump, compatibility_report, - ignored_symbols, check_all_apis); + ignored_symbols, check_all_apis, text_format_old, + text_format_new, text_format_diff); abi_util::CompatibilityStatusIR status = judge.GenerateCompatibilityReport(); diff --git a/vndk/tools/header-checker/header-abi-dumper/src/ast_processing.cpp b/vndk/tools/header-checker/header-abi-dumper/src/ast_processing.cpp index f0022e2df..bf5623d0d 100644 --- a/vndk/tools/header-checker/header-abi-dumper/src/ast_processing.cpp +++ b/vndk/tools/header-checker/header-abi-dumper/src/ast_processing.cpp @@ -33,7 +33,6 @@ HeaderASTVisitor::HeaderASTVisitor( clang::MangleContext *mangle_contextp, clang::ASTContext *ast_contextp, const clang::CompilerInstance *compiler_instance_p, - const std::string ¤t_file_name, const std::set &exported_headers, const clang::Decl *tu_decl, std::set *type_cache, @@ -41,7 +40,6 @@ HeaderASTVisitor::HeaderASTVisitor( : mangle_contextp_(mangle_contextp), ast_contextp_(ast_contextp), cip_(compiler_instance_p), - current_file_name_(current_file_name), exported_headers_(exported_headers), tu_decl_(tu_decl), type_cache_(type_cache), @@ -167,14 +165,14 @@ bool HeaderASTVisitor::TraverseDecl(clang::Decl *decl) { } HeaderASTConsumer::HeaderASTConsumer( - const std::string &file_name, clang::CompilerInstance *compiler_instancep, const std::string &out_dump_name, - const std::set &exported_headers) - : file_name_(file_name), - cip_(compiler_instancep), + const std::set &exported_headers, + abi_util::TextFormatIR text_format) + : cip_(compiler_instancep), out_dump_name_(out_dump_name), - exported_headers_(exported_headers) { } + exported_headers_(exported_headers), + text_format_(text_format){ } void HeaderASTConsumer::HandleTranslationUnit(clang::ASTContext &ctx) { clang::PrintingPolicy policy(ctx.getPrintingPolicy()); @@ -188,10 +186,9 @@ void HeaderASTConsumer::HandleTranslationUnit(clang::ASTContext &ctx) { ctx.createMangleContext()); std::set type_cache; std::unique_ptr ir_dumper = - abi_util::IRDumper::CreateIRDumper("protobuf", out_dump_name_); - HeaderASTVisitor v(mangle_contextp.get(), &ctx, cip_, file_name_, - exported_headers_, translation_unit, &type_cache, - ir_dumper.get()); + abi_util::IRDumper::CreateIRDumper(text_format_, out_dump_name_); + HeaderASTVisitor v(mangle_contextp.get(), &ctx, cip_, exported_headers_, + translation_unit, &type_cache, ir_dumper.get()); if (!v.TraverseDecl(translation_unit) || !ir_dumper->Dump()) { llvm::errs() << "Serialization to ostream failed\n"; ::exit(1); diff --git a/vndk/tools/header-checker/header-abi-dumper/src/ast_processing.h b/vndk/tools/header-checker/header-abi-dumper/src/ast_processing.h index 0a8f7f7ce..02ad65dcb 100644 --- a/vndk/tools/header-checker/header-abi-dumper/src/ast_processing.h +++ b/vndk/tools/header-checker/header-abi-dumper/src/ast_processing.h @@ -38,7 +38,6 @@ class HeaderASTVisitor HeaderASTVisitor(clang::MangleContext *mangle_contextp, clang::ASTContext *ast_contextp, const clang::CompilerInstance *compiler_instance_p, - const std::string ¤t_file_name, const std::set &exported_headers, const clang::Decl *tu_decl, std::set *type_cache, @@ -63,7 +62,6 @@ class HeaderASTVisitor clang::MangleContext *mangle_contextp_; clang::ASTContext *ast_contextp_; const clang::CompilerInstance *cip_; - const std::string current_file_name_; const std::set &exported_headers_; // To optimize recursion into only exported abi. const clang::Decl *tu_decl_; @@ -76,18 +74,18 @@ class HeaderASTVisitor class HeaderASTConsumer : public clang::ASTConsumer { public: - HeaderASTConsumer(const std::string &file_name, - clang::CompilerInstance *compiler_instancep, + HeaderASTConsumer(clang::CompilerInstance *compiler_instancep, const std::string &out_dump_name, - const std::set &exported_headers); + const std::set &exported_headers, + abi_util::TextFormatIR text_format); void HandleTranslationUnit(clang::ASTContext &ctx) override; private: - std::string file_name_; clang::CompilerInstance *cip_; - std::string out_dump_name_; + const std::string &out_dump_name_; const std::set &exported_headers_; + abi_util::TextFormatIR text_format_; }; #endif // AST_PROCESSING_H_ diff --git a/vndk/tools/header-checker/header-abi-dumper/src/frontend_action.cpp b/vndk/tools/header-checker/header-abi-dumper/src/frontend_action.cpp index 764fc2382..082b8141a 100644 --- a/vndk/tools/header-checker/header-abi-dumper/src/frontend_action.cpp +++ b/vndk/tools/header-checker/header-abi-dumper/src/frontend_action.cpp @@ -16,6 +16,7 @@ #include "ast_processing.h" #include "frontend_action.h" #include +#include #include #include @@ -25,13 +26,15 @@ #include HeaderCheckerFrontendAction::HeaderCheckerFrontendAction( - const std::string &dump_name, const std::set &exported_headers) - : dump_name_(dump_name), exported_headers_(exported_headers) { } + const std::string &dump_name, const std::set &exported_headers, + abi_util::TextFormatIR text_format) + : dump_name_(dump_name), exported_headers_(exported_headers), + text_format_(text_format) { } std::unique_ptr HeaderCheckerFrontendAction::CreateASTConsumer(clang::CompilerInstance &ci, llvm::StringRef header_file) { // Create AST consumers. - return llvm::make_unique(header_file, &ci, dump_name_, - exported_headers_); + return llvm::make_unique(&ci, dump_name_, + exported_headers_, text_format_); } diff --git a/vndk/tools/header-checker/header-abi-dumper/src/frontend_action.h b/vndk/tools/header-checker/header-abi-dumper/src/frontend_action.h index 1981c737e..24e1e247f 100644 --- a/vndk/tools/header-checker/header-abi-dumper/src/frontend_action.h +++ b/vndk/tools/header-checker/header-abi-dumper/src/frontend_action.h @@ -15,6 +15,8 @@ #ifndef FRONTEND_ACTION_H_ #define FRONTEND_ACTION_H_ +#include + #include #include @@ -30,13 +32,15 @@ namespace clang { class HeaderCheckerFrontendAction : public clang::ASTFrontendAction { private: - std::string dump_name_; + const std::string &dump_name_; const std::set &exported_headers_; + abi_util::TextFormatIR text_format_; public: HeaderCheckerFrontendAction( const std::string &dump_name, - const std::set &exported_headers); + const std::set &exported_headers, + abi_util::TextFormatIR text_format); protected: std::unique_ptr CreateASTConsumer( diff --git a/vndk/tools/header-checker/header-abi-dumper/src/frontend_action_factory.cpp b/vndk/tools/header-checker/header-abi-dumper/src/frontend_action_factory.cpp index 318877634..c879ff0c6 100644 --- a/vndk/tools/header-checker/header-abi-dumper/src/frontend_action_factory.cpp +++ b/vndk/tools/header-checker/header-abi-dumper/src/frontend_action_factory.cpp @@ -20,9 +20,12 @@ HeaderCheckerFrontendActionFactory::HeaderCheckerFrontendActionFactory( const std::string &dump_name, - const std::set &exported_headers) - : dump_name_(dump_name), exported_headers_(exported_headers) { } + const std::set &exported_headers, + abi_util::TextFormatIR text_format) + : dump_name_(dump_name), exported_headers_(exported_headers), + text_format_(text_format) { } clang::FrontendAction *HeaderCheckerFrontendActionFactory::create() { - return new HeaderCheckerFrontendAction(dump_name_, exported_headers_); + return new HeaderCheckerFrontendAction(dump_name_, exported_headers_, + text_format_); } diff --git a/vndk/tools/header-checker/header-abi-dumper/src/frontend_action_factory.h b/vndk/tools/header-checker/header-abi-dumper/src/frontend_action_factory.h index 2de0f0ebe..a2a6c3817 100644 --- a/vndk/tools/header-checker/header-abi-dumper/src/frontend_action_factory.h +++ b/vndk/tools/header-checker/header-abi-dumper/src/frontend_action_factory.h @@ -15,6 +15,7 @@ #ifndef FRONTEND_ACTION_FACTORY_H_ #define FRONTEND_ACTION_FACTORY_H_ +#include #include #include @@ -22,13 +23,15 @@ class HeaderCheckerFrontendActionFactory : public clang::tooling::FrontendActionFactory { private: - std::string dump_name_; + const std::string &dump_name_; const std::set &exported_headers_; + abi_util::TextFormatIR text_format_; public: HeaderCheckerFrontendActionFactory( const std::string &dump_name, - const std::set &exported_headers); + const std::set &exported_headers, + abi_util::TextFormatIR text_format); clang::FrontendAction *create() override; }; diff --git a/vndk/tools/header-checker/header-abi-dumper/src/header_checker.cpp b/vndk/tools/header-checker/header-abi-dumper/src/header_checker.cpp index 407573b4c..1b1db9075 100644 --- a/vndk/tools/header-checker/header-abi-dumper/src/header_checker.cpp +++ b/vndk/tools/header-checker/header-abi-dumper/src/header_checker.cpp @@ -49,6 +49,14 @@ static llvm::cl::opt no_filter( "no-filter", llvm::cl::desc("Do not filter any abi"), llvm::cl::Optional, llvm::cl::cat(header_checker_category)); +static llvm::cl::opt text_format( + "text-format", llvm::cl::desc("Specify text format of abi dump"), + llvm::cl::values(clEnumValN(abi_util::TextFormatIR::ProtobufTextFormat, + "ProtobufTextFormat", "ProtobufTextFormat"), + clEnumValEnd), + llvm::cl::init(abi_util::TextFormatIR::ProtobufTextFormat), + llvm::cl::cat(header_checker_category)); + // Hide irrelevant command line options defined in LLVM libraries. static void HideIrrelevantCommandLineOptions() { llvm::StringMap &map = llvm::cl::getRegisteredOptions(); @@ -108,7 +116,8 @@ int main(int argc, const char **argv) { clang::tooling::ClangTool tool(*compilations, header_files); std::unique_ptr factory( - new HeaderCheckerFrontendActionFactory(out_dump, exported_headers)); + new HeaderCheckerFrontendActionFactory(out_dump, exported_headers, + text_format)); return tool.run(factory.get()); } diff --git a/vndk/tools/header-checker/header-abi-linker/src/header_abi_linker.cpp b/vndk/tools/header-checker/header-abi-linker/src/header_abi_linker.cpp index b02092d9e..110eb65fd 100644 --- a/vndk/tools/header-checker/header-abi-linker/src/header_abi_linker.cpp +++ b/vndk/tools/header-checker/header-abi-linker/src/header_abi_linker.cpp @@ -12,28 +12,24 @@ // See the License for the specific language governing permissions and // limitations under the License. -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-parameter" -#pragma clang diagnostic ignored "-Wnested-anon-types" -#include "proto/abi_dump.pb.h" -#pragma clang diagnostic pop - #include +#include #include #include -#include -#include - #include +#include #include #include #include +#include #include #include +static constexpr std::size_t kSourcesPerBatchThread = 7; + static llvm::cl::OptionCategory header_linker_category( "header-abi-linker options"); @@ -69,6 +65,14 @@ static llvm::cl::opt so_file( "so", llvm::cl::desc(""), llvm::cl::Optional, llvm::cl::cat(header_linker_category)); +static llvm::cl::opt text_format( + "text-format", llvm::cl::desc("Specify text format of abi dumps"), + llvm::cl::values(clEnumValN(abi_util::TextFormatIR::ProtobufTextFormat, + "ProtobufTextFormat", "ProtobufTextFormat"), + clEnumValEnd), + llvm::cl::init(abi_util::TextFormatIR::ProtobufTextFormat), + llvm::cl::cat(header_linker_category)); + class HeaderAbiLinker { public: HeaderAbiLinker( @@ -85,36 +89,30 @@ class HeaderAbiLinker { bool LinkAndDump(); - template - static std::string GetLinkageName(T &element) { - return element.type_info().linker_set_key(); - } - template - static std::string GetSourceFile(T &element) { - return element.type_info().source_file(); - } private: - bool LinkTypes(const abi_dump::TranslationUnit &dump_tu, - abi_dump::TranslationUnit *linked_tu); - bool LinkFunctions(const abi_dump::TranslationUnit &dump_tu, - abi_dump::TranslationUnit *linked_tu); - - bool LinkGlobalVars(const abi_dump::TranslationUnit &dump_tu, - abi_dump::TranslationUnit *linked_tu); - template - inline bool LinkDecl(google::protobuf::RepeatedPtrField *dst, + inline bool LinkDecl(abi_util::IRDumper *dst, std::set *link_set, std::set *regex_matched_link_set, const std::regex *vs_regex, - const google::protobuf::RepeatedPtrField &src, + const std::map &src, bool use_version_script); bool ParseVersionScriptFiles(); bool ParseSoFile(); - bool AddElfSymbols(abi_dump::TranslationUnit *linked_tu); + bool LinkTypes(const abi_util::TextFormatToIRReader *ir_reader, + abi_util::IRDumper *ir_dumper); + + bool LinkFunctions(const abi_util::TextFormatToIRReader *ir_reader, + abi_util::IRDumper *ir_dumper); + + bool LinkGlobalVars(const abi_util::TextFormatToIRReader *ir_reader, + abi_util::IRDumper *ir_dumper); + + bool AddElfSymbols(abi_util::IRDumper *ir_dumper); + private: const std::vector &dump_files_; @@ -138,29 +136,56 @@ class HeaderAbiLinker { }; template -static bool AddElfSymbols(google::protobuf::RepeatedPtrField *dst, - Iterable symbols) { +static bool AddElfSymbols(abi_util::IRDumper *dst, const Iterable &symbols) { for (auto &&symbol : symbols) { - auto *added_symbol = dst->Add(); - if (added_symbol == nullptr) { + T elf_symbol(symbol); + if (!dst->AddElfSymbolMessageIR(&elf_symbol)) { return false; } - added_symbol->set_name(symbol); } return true; } // To be called right after parsing the .so file / version script. -bool HeaderAbiLinker::AddElfSymbols(abi_dump::TranslationUnit *linked_tu) { +bool HeaderAbiLinker::AddElfSymbols(abi_util::IRDumper *ir_dumper) { + return ::AddElfSymbols(ir_dumper, + function_decl_set_) && + ::AddElfSymbols(ir_dumper, + globvar_decl_set_); +} - return ::AddElfSymbols(linked_tu->mutable_elf_functions(), function_decl_set_) - && ::AddElfSymbols(linked_tu->mutable_elf_objects(), globvar_decl_set_); +static void DeDuplicateAbiElementsThread( + const std::vector &dump_files, + const std::set *exported_headers, + abi_util::TextFormatToIRReader *greader, std::mutex *greader_lock, + std::atomic *cnt) { + std::unique_ptr local_reader = + abi_util::TextFormatToIRReader::CreateTextFormatToIRReader( + text_format, exported_headers); + auto begin_it = dump_files.begin(); + std::size_t num_sources = dump_files.size(); + while (1) { + std::size_t i = cnt->fetch_add(kSourcesPerBatchThread); + if (i >= num_sources) { + break; + } + std::size_t end = std::min(i + kSourcesPerBatchThread, num_sources); + std::unique_ptr reader = + abi_util::TextFormatToIRReader::CreateTextFormatToIRReader( + text_format, exported_headers); + assert(reader != nullptr); + if (!reader->ReadDumps(begin_it + i, begin_it + end)) { + llvm::errs() << "ReadDump failed\n"; + ::exit(1); + } + // This merge is needed since the iterators might not be contigous. + local_reader->Merge(std::move(*reader)); + } + std::lock_guard lock(*greader_lock); + greader->Merge(std::move(*local_reader)); } bool HeaderAbiLinker::LinkAndDump() { - abi_dump::TranslationUnit linked_tu; - std::ofstream text_output(out_dump_name_); - google::protobuf::io::OstreamOutputStream text_os(&text_output); // If the user specifies that a version script should be used, use that. if (!so_file_.empty()) { exported_headers_ = @@ -173,22 +198,40 @@ bool HeaderAbiLinker::LinkAndDump() { llvm::errs() << "Failed to parse stub files for exported symbols\n"; return false; } - - AddElfSymbols(&linked_tu); - - for (auto &&i : dump_files_) { - abi_dump::TranslationUnit dump_tu; - std::ifstream input(i); - google::protobuf::io::IstreamInputStream text_is(&input); - if (!google::protobuf::TextFormat::Parse(&text_is, &dump_tu) || - !LinkTypes(dump_tu, &linked_tu) || - !LinkFunctions(dump_tu, &linked_tu) || - !LinkGlobalVars(dump_tu, &linked_tu)) { - llvm::errs() << "Failed to link elements\n"; - return false; - } + std::unique_ptr ir_dumper = + abi_util::IRDumper::CreateIRDumper(text_format, out_dump_name_); + assert(ir_dumper != nullptr); + AddElfSymbols(ir_dumper.get()); + // Create a reader, on which we never actually call ReadDump(), since multiple + // dump files are associated with it. + std::unique_ptr greader = + abi_util::TextFormatToIRReader::CreateTextFormatToIRReader( + text_format, &exported_headers_); + std::size_t max_threads = std::thread::hardware_concurrency(); + std::size_t num_threads = kSourcesPerBatchThread < dump_files_.size() ? + std::min(dump_files_.size() / kSourcesPerBatchThread, + max_threads) : 0; + std::vector threads; + std::atomic cnt(0); + std::mutex greader_lock; + for (std::size_t i = 1; i < num_threads; i++) { + threads.emplace_back(DeDuplicateAbiElementsThread, dump_files_, + &exported_headers_, greader.get(), &greader_lock, + &cnt); } - if (!google::protobuf::TextFormat::Print(linked_tu, &text_os)) { + DeDuplicateAbiElementsThread(dump_files_, &exported_headers_, greader.get(), + &greader_lock, &cnt); + for (auto &thread : threads) { + thread.join(); + } + + if (!LinkTypes(greader.get(), ir_dumper.get()) || + !LinkFunctions(greader.get(), ir_dumper.get()) || + !LinkGlobalVars(greader.get(), ir_dumper.get())) { + llvm::errs() << "Failed to link elements\n"; + return false; + } + if (!ir_dumper->Dump()) { llvm::errs() << "Serialization to ostream failed\n"; return false; } @@ -228,25 +271,24 @@ static std::regex CreateRegexMatchExprFromSet( return std::regex(all_regex_match_str); } -//TODO: make linking decls multi-threaded b/63590537. template inline bool HeaderAbiLinker::LinkDecl( - google::protobuf::RepeatedPtrField *dst, std::set *link_set, + abi_util::IRDumper *dst, std::set *link_set, std::set *regex_matched_link_set, const std::regex *vs_regex, - const google::protobuf::RepeatedPtrField &src, bool use_version_script) { + const std::map &src, bool use_version_script) { assert(dst != nullptr); assert(link_set != nullptr); for (auto &&element : src) { // If we are not using a version script and exported headers are available, // filter out unexported abi. - std::string source_file = GetSourceFile(element); + std::string source_file = element.second.GetSourceFile(); // Builtin types will not have source file information. if (!exported_headers_.empty() && !source_file.empty() && exported_headers_.find(source_file) == exported_headers_.end()) { continue; } - std::string element_str = GetLinkageName(element); + const std::string &element_str = element.first; // Check for the existence of the element in linked dump / symbol file. if (!use_version_script) { if (!link_set->insert(element_str).second) { @@ -264,86 +306,67 @@ inline bool HeaderAbiLinker::LinkDecl( link_set->erase(*it); // Avoid multiple instances of the same symbol. } } - T *added_element = dst->Add(); - if (!added_element) { + if (!dst->AddLinkableMessageIR(&(element.second))) { llvm::errs() << "Failed to add element to linked dump\n"; return false; } - *added_element = element; + } return true; } - -template<> -std::string HeaderAbiLinker::GetLinkageName ( - const abi_dump::FunctionDecl &element) { - return element.linker_set_key(); -} - -template<> -std::string HeaderAbiLinker::GetSourceFile ( - const abi_dump::FunctionDecl &element) { - return element.source_file(); -} - -template<> -std::string HeaderAbiLinker::GetLinkageName ( - const abi_dump::GlobalVarDecl &element) { - return element.linker_set_key(); -} - -template<> -std::string HeaderAbiLinker::GetSourceFile ( - const abi_dump::GlobalVarDecl &element) { - return element.source_file(); -} - -bool HeaderAbiLinker::LinkTypes(const abi_dump::TranslationUnit &dump_tu, - abi_dump::TranslationUnit *linked_tu) { - assert(linked_tu != nullptr); +bool HeaderAbiLinker::LinkTypes(const abi_util::TextFormatToIRReader *reader, + abi_util::IRDumper *ir_dumper) { + assert(reader != nullptr); + assert(ir_dumper != nullptr); // Even if version scripts are available we take in types, since the symbols // in the version script might reference a type exposed by the library. - return LinkDecl(linked_tu->mutable_record_types(), &types_set_, nullptr, - nullptr, dump_tu.record_types(), false) && - LinkDecl(linked_tu->mutable_enum_types(), &types_set_, nullptr, - nullptr, dump_tu.enum_types(), false) && - LinkDecl(linked_tu->mutable_builtin_types(), &types_set_, nullptr, - nullptr, dump_tu.builtin_types(), false) && - LinkDecl(linked_tu->mutable_pointer_types(), &types_set_, nullptr, - nullptr, dump_tu.pointer_types(), false) && - LinkDecl(linked_tu->mutable_rvalue_reference_types(), &types_set_, nullptr, - nullptr, dump_tu.rvalue_reference_types(), false) && - LinkDecl(linked_tu->mutable_lvalue_reference_types(), &types_set_, nullptr, - nullptr, dump_tu.lvalue_reference_types(), false) && - LinkDecl(linked_tu->mutable_array_types(), &types_set_, nullptr, - nullptr, dump_tu.array_types(), false) && - LinkDecl(linked_tu->mutable_qualified_types(), &types_set_, nullptr, - nullptr, dump_tu.qualified_types(), false); + return LinkDecl(ir_dumper, &types_set_, nullptr, + nullptr, reader->GetRecordTypes(), false) && + LinkDecl(ir_dumper, &types_set_, nullptr, + nullptr, reader->GetEnumTypes(), false) && + LinkDecl(ir_dumper, &types_set_, nullptr, + nullptr, reader->GetBuiltinTypes(), false) && + LinkDecl(ir_dumper, &types_set_, nullptr, + nullptr, reader->GetPointerTypes(), false) && + LinkDecl(ir_dumper, &types_set_, nullptr, + nullptr, reader->GetRvalueReferenceTypes(), false) && + LinkDecl(ir_dumper, &types_set_, nullptr, + nullptr, reader->GetLvalueReferenceTypes(), false) && + LinkDecl(ir_dumper, &types_set_, nullptr, + nullptr, reader->GetArrayTypes(), false) && + LinkDecl(ir_dumper, &types_set_, nullptr, + nullptr, reader->GetQualifiedTypes(), false); } -bool HeaderAbiLinker::LinkFunctions(const abi_dump::TranslationUnit &dump_tu, - abi_dump::TranslationUnit *linked_tu) { - assert(linked_tu != nullptr); - return LinkDecl(linked_tu->mutable_functions(), &function_decl_set_, +bool HeaderAbiLinker::LinkFunctions( + const abi_util::TextFormatToIRReader *reader, + abi_util::IRDumper *ir_dumper) { + + assert(reader != nullptr); + return LinkDecl(ir_dumper, &function_decl_set_, &functions_regex_matched_set, &functions_vs_regex_, - dump_tu.functions(), + reader->GetFunctions(), (!version_script_.empty() || !so_file_.empty())); } -bool HeaderAbiLinker::LinkGlobalVars(const abi_dump::TranslationUnit &dump_tu, - abi_dump::TranslationUnit *linked_tu) { - assert(linked_tu != nullptr); - return LinkDecl(linked_tu->mutable_global_vars(), &globvar_decl_set_, +bool HeaderAbiLinker::LinkGlobalVars( + const abi_util::TextFormatToIRReader *reader, + abi_util::IRDumper *ir_dumper) { + + assert(reader != nullptr); + return LinkDecl(ir_dumper, &globvar_decl_set_, &globvars_regex_matched_set, &globvars_vs_regex_, - dump_tu.global_vars(), + reader->GetGlobalVariables(), (!version_script.empty() || !so_file_.empty())); + } bool HeaderAbiLinker::ParseVersionScriptFiles() { abi_util::VersionScriptParser version_script_parser(version_script_, arch_, api_); if (!version_script_parser.Parse()) { + llvm::errs() << "Failed to parse version script\n"; return false; } function_decl_set_ = version_script_parser.GetFunctions(); @@ -384,7 +407,6 @@ bool HeaderAbiLinker::ParseSoFile() { } int main(int argc, const char **argv) { - GOOGLE_PROTOBUF_VERIFY_VERSION; llvm::cl::ParseCommandLineOptions(argc, argv, "header-linker"); if (so_file.empty() && version_script.empty()) { llvm::errs() << "One of -so or -v needs to be specified\n"; @@ -397,6 +419,7 @@ int main(int argc, const char **argv) { so_file, linked_dump, arch, api); if (!Linker.LinkAndDump()) { + llvm::errs() << "Failed to link and dump elements\n"; return -1; } return 0; diff --git a/vndk/tools/header-checker/header-abi-util/include/header_abi_util.h b/vndk/tools/header-checker/header-abi-util/include/header_abi_util.h index 4b50ed885..aa5602f5d 100644 --- a/vndk/tools/header-checker/header-abi-util/include/header_abi_util.h +++ b/vndk/tools/header-checker/header-abi-util/include/header_abi_util.h @@ -146,15 +146,17 @@ std::vector FindRemovedElements( return removed_elements; } -template -inline void AddToMap(std::map *dst, Iterable &src, F get_key) { +template +inline void AddToMap(std::map *dst, Iterable &src, KeyGetter get_key, + ValueGetter get_value) { for (auto &&element : src) { - dst->insert(std::make_pair(get_key(&element), &element)); + dst->insert(std::make_pair(get_key(&element), get_value(&element))); } } -template -inline void AddToSet(std::set *dst, Iterable &src, F get_key) { +template +inline void AddToSet(std::set *dst, Iterable &src, KeyGetter get_key) { for (auto &&element : src) { dst->insert(get_key(element)); } diff --git a/vndk/tools/header-checker/header-abi-util/include/ir_representation.h b/vndk/tools/header-checker/header-abi-util/include/ir_representation.h index 97dd008a8..2fd43058b 100644 --- a/vndk/tools/header-checker/header-abi-util/include/ir_representation.h +++ b/vndk/tools/header-checker/header-abi-util/include/ir_representation.h @@ -25,6 +25,13 @@ // message format specific dumpers. namespace abi_util { +template +using AbiElementMap = std::map; + +enum TextFormatIR { + ProtobufTextFormat = 0, +}; + enum CompatibilityStatusIR { Compatible = 0, UnreferencedChanges = 1, @@ -691,11 +698,13 @@ class IRDumper { public: IRDumper(const std::string &dump_path) : dump_path_(dump_path) { } - static std::unique_ptr CreateIRDumper(const std::string &type, - const std::string &dump_path); + static std::unique_ptr CreateIRDumper( + TextFormatIR text_format, const std::string &dump_path); virtual bool AddLinkableMessageIR(const LinkableMessageIR *) = 0; + virtual bool AddElfSymbolMessageIR(const ElfSymbolIR *) = 0; + virtual bool Dump() = 0; virtual ~IRDumper() {} @@ -706,77 +715,116 @@ class IRDumper { class TextFormatToIRReader { public: - TextFormatToIRReader(const std::string &dump_path) : dump_path_(dump_path) { } - const std::vector &GetFunctions() const { + TextFormatToIRReader(const std::set *exported_headers) + : exported_headers_(exported_headers) { } + + const AbiElementMap &GetFunctions() const { return functions_; } - const std::vector &GetGlobalVariables() const { + const AbiElementMap &GetGlobalVariables() const { return global_variables_; } - const std::vector &GetRecordTypes() const { + const AbiElementMap &GetRecordTypes() const { return record_types_; } - const std::vector &GetEnumTypes() const { + const AbiElementMap &GetEnumTypes() const { return enum_types_; } - const std::vector &GetLvalueReferenceTypes() const { + const AbiElementMap & + GetLvalueReferenceTypes() const { return lvalue_reference_types_; } - const std::vector &GetRvalueReferenceTypes() const { + const AbiElementMap & + GetRvalueReferenceTypes() const { return rvalue_reference_types_; } - const std::vector &GetQualifiedTypes() const { + const AbiElementMap &GetQualifiedTypes() const { return qualified_types_; } - const std::vector &GetArrayTypes() const { + const AbiElementMap &GetArrayTypes() const { return array_types_; } - const std::vector &GetPointerTypes() const { + const AbiElementMap &GetPointerTypes() const { return pointer_types_; } - const std::vector &GetBuiltinTypes() const { + const AbiElementMap &GetBuiltinTypes() const { return builtin_types_; } - const std::vector &GetElfFunctions() const { + const AbiElementMap &GetElfFunctions() const { return elf_functions_; } - const std::vector &GetElfObjects() const { + const AbiElementMap &GetElfObjects() const { return elf_objects_; } - virtual bool ReadDump() = 0; + virtual bool ReadDump(const std::string &dump_file) = 0; + + template + bool ReadDumps(Iterator begin, Iterator end) { + Iterator it = begin; + while(it != end) { + if (!ReadDump(*it)) { + return false; + } + ++it; + } + return true; + } virtual ~TextFormatToIRReader() { } + void Merge(TextFormatToIRReader &&addend) { + MergeElements(&functions_, std::move(addend.functions_)); + MergeElements(&global_variables_, std::move(addend.global_variables_)); + MergeElements(&record_types_, std::move(addend.record_types_)); + MergeElements(&enum_types_, std::move(addend.enum_types_)); + MergeElements(&pointer_types_, std::move(addend.pointer_types_)); + MergeElements(&lvalue_reference_types_, + std::move(addend.lvalue_reference_types_)); + MergeElements(&rvalue_reference_types_, + std::move(addend.rvalue_reference_types_)); + MergeElements(&array_types_, std::move(addend.array_types_)); + MergeElements(&builtin_types_, std::move(addend.builtin_types_)); + MergeElements(&qualified_types_, std::move(addend.qualified_types_)); + } + static std::unique_ptr CreateTextFormatToIRReader( - const std::string &text_format, const std::string &dump_path); + TextFormatIR text_format, + const std::set *exported_headers = nullptr); protected: - const std::string &dump_path_; - std::vector functions_; - std::vector global_variables_; - std::vector record_types_; - std::vector enum_types_; - std::vector pointer_types_; - std::vector lvalue_reference_types_; - std::vector rvalue_reference_types_; - std::vector array_types_; - std::vector builtin_types_; - std::vector qualified_types_; - std::vector elf_functions_; - std::vector elf_objects_; + + template + inline void MergeElements(Augend *augend, Addend &&addend) { + augend->insert(std::make_move_iterator(addend.begin()), + std::make_move_iterator(addend.end())); + } + + AbiElementMap functions_; + AbiElementMap global_variables_; + AbiElementMap record_types_; + AbiElementMap enum_types_; + AbiElementMap pointer_types_; + AbiElementMap lvalue_reference_types_; + AbiElementMap rvalue_reference_types_; + AbiElementMap array_types_; + AbiElementMap builtin_types_; + AbiElementMap qualified_types_; + AbiElementMap elf_functions_; + AbiElementMap elf_objects_; + const std::set *exported_headers_; }; class DiffMessageIR { @@ -1120,7 +1168,7 @@ class IRDiffDumper { virtual ~IRDiffDumper() {} static std::unique_ptr CreateIRDiffDumper( - const std::string &type, const std::string &dump_path); + TextFormatIR, const std::string &dump_path); protected: const std::string &dump_path_; }; diff --git a/vndk/tools/header-checker/header-abi-util/include/ir_representation_protobuf.h b/vndk/tools/header-checker/header-abi-util/include/ir_representation_protobuf.h index e5cf61e64..9325b09a6 100644 --- a/vndk/tools/header-checker/header-abi-util/include/ir_representation_protobuf.h +++ b/vndk/tools/header-checker/header-abi-util/include/ir_representation_protobuf.h @@ -270,11 +270,17 @@ class ProtobufIRDumper : public IRDumper, public IRToProtobufConverter { bool AddGlobalVarIR(const GlobalVarIR *); + bool AddElfFunctionIR(const ElfFunctionIR *); + + bool AddElfObjectIR(const ElfObjectIR *); + public: ProtobufIRDumper(const std::string &dump_path) : IRDumper(dump_path), tu_ptr_(new abi_dump::TranslationUnit()) { } - bool AddLinkableMessageIR(const LinkableMessageIR *); + bool AddLinkableMessageIR(const LinkableMessageIR *) override; + + bool AddElfSymbolMessageIR(const ElfSymbolIR *) override; bool Dump() override; @@ -288,44 +294,35 @@ class ProtobufIRDumper : public IRDumper, public IRToProtobufConverter { class ProtobufTextFormatToIRReader : public TextFormatToIRReader { public: - virtual bool ReadDump() override; + ProtobufTextFormatToIRReader(const std::set *exported_headers) + : TextFormatToIRReader(exported_headers) { } - ProtobufTextFormatToIRReader(const std::string &dump_path) - : TextFormatToIRReader(dump_path) { } + bool ReadDump(const std::string &dump_file) override; private: - std::vector ReadFunctions( - const abi_dump::TranslationUnit &tu); + void ReadFunctions(const abi_dump::TranslationUnit &tu); - std::vector ReadGlobalVariables( - const abi_dump::TranslationUnit &tu); + void ReadGlobalVariables(const abi_dump::TranslationUnit &tu); - std::vector ReadEnumTypes(const abi_dump::TranslationUnit &tu); + void ReadEnumTypes(const abi_dump::TranslationUnit &tu); - std::vector ReadRecordTypes( - const abi_dump::TranslationUnit &tu); + void ReadRecordTypes(const abi_dump::TranslationUnit &tu); - std::vector ReadPointerTypes( - const abi_dump::TranslationUnit &tu); + void ReadPointerTypes(const abi_dump::TranslationUnit &tu); - std::vector ReadBuiltinTypes( - const abi_dump::TranslationUnit &tu); + void ReadBuiltinTypes(const abi_dump::TranslationUnit &tu); - std::vector ReadQualifiedTypes( - const abi_dump::TranslationUnit &tu); + void ReadQualifiedTypes(const abi_dump::TranslationUnit &tu); - std::vector ReadArrayTypes(const abi_dump::TranslationUnit &tu); + void ReadArrayTypes(const abi_dump::TranslationUnit &tu); - std::vector ReadLvalueReferenceTypes( - const abi_dump::TranslationUnit &tu); + void ReadLvalueReferenceTypes(const abi_dump::TranslationUnit &tu); - std::vector ReadRvalueReferenceTypes( - const abi_dump::TranslationUnit &tu); + void ReadRvalueReferenceTypes(const abi_dump::TranslationUnit &tu); - std::vector ReadElfFunctions ( - const abi_dump::TranslationUnit &tu); + void ReadElfFunctions (const abi_dump::TranslationUnit &tu); - std::vector ReadElfObjects (const abi_dump::TranslationUnit &tu); + void ReadElfObjects (const abi_dump::TranslationUnit &tu); void ReadTypeInfo(const abi_dump::BasicNamedAndTypedDecl &type_info, TypeIR *typep); diff --git a/vndk/tools/header-checker/header-abi-util/src/ir_representation.cpp b/vndk/tools/header-checker/header-abi-util/src/ir_representation.cpp index 0cf58e196..f82046a27 100644 --- a/vndk/tools/header-checker/header-abi-util/src/ir_representation.cpp +++ b/vndk/tools/header-checker/header-abi-util/src/ir_representation.cpp @@ -33,34 +33,40 @@ namespace abi_util { std::unique_ptr IRDumper::CreateIRDumper( - const std::string &type, const std::string &dump_path) { - if (type == "protobuf") { - return std::make_unique(dump_path); + TextFormatIR text_format, const std::string &dump_path) { + switch (text_format) { + case TextFormatIR::ProtobufTextFormat: + return std::make_unique(dump_path); + default: + // Nothing else is supported yet. + llvm::errs() << "Text format not supported yet\n"; + return nullptr; } - // Nothing else is supported yet. - llvm::errs() << type << " message format is not supported yet!\n"; - return nullptr; } std::unique_ptr IRDiffDumper::CreateIRDiffDumper( - const std::string &type, const std::string &dump_path) { - if (type == "protobuf") { - return std::make_unique(dump_path); + TextFormatIR text_format, const std::string &dump_path) { + switch (text_format) { + case TextFormatIR::ProtobufTextFormat: + return std::make_unique(dump_path); + default: + // Nothing else is supported yet. + llvm::errs() << "Text format not supported yet\n"; + return nullptr; } - // Nothing else is supported yet. - llvm::errs() << type << " message format is not supported yet!\n"; - return nullptr; } std::unique_ptr TextFormatToIRReader::CreateTextFormatToIRReader( - const std::string &type, const std::string &dump_path) { - if (type == "protobuf") { - return std::make_unique(dump_path); + TextFormatIR text_format, const std::set *exported_headers) { + switch (text_format) { + case TextFormatIR::ProtobufTextFormat: + return std::make_unique(exported_headers); + default: + // Nothing else is supported yet. + llvm::errs() << "Text format not supported yet\n"; + return nullptr; } - // Nothing else is supported yet. - llvm::errs() << type << " message format is not supported yet!\n"; - return nullptr; } } // namespace abi_util diff --git a/vndk/tools/header-checker/header-abi-util/src/ir_representation_protobuf.cpp b/vndk/tools/header-checker/header-abi-util/src/ir_representation_protobuf.cpp index 8f7285a8c..3b3e9c91e 100644 --- a/vndk/tools/header-checker/header-abi-util/src/ir_representation_protobuf.cpp +++ b/vndk/tools/header-checker/header-abi-util/src/ir_representation_protobuf.cpp @@ -23,6 +23,16 @@ namespace abi_util { +static bool IsPresentInExportedHeaders( + const LinkableMessageIR &linkable_message, + const std::set *exported_headers) { + if (exported_headers == nullptr || exported_headers->empty()) { + return true; + } + return exported_headers->find(linkable_message.GetSourceFile()) + != exported_headers->end(); +} + void ProtobufTextFormatToIRReader::ReadTypeInfo( const abi_dump::BasicNamedAndTypedDecl &type_info, TypeIR *typep) { @@ -34,9 +44,9 @@ void ProtobufTextFormatToIRReader::ReadTypeInfo( typep->SetAlignment(type_info.alignment()); } -bool ProtobufTextFormatToIRReader::ReadDump() { +bool ProtobufTextFormatToIRReader::ReadDump(const std::string &dump_file) { abi_dump::TranslationUnit tu; - std::ifstream input(dump_path_); + std::ifstream input(dump_file); google::protobuf::io::IstreamInputStream text_is(&input); if (!google::protobuf::TextFormat::Parse(&text_is, &tu)) { @@ -44,21 +54,20 @@ bool ProtobufTextFormatToIRReader::ReadDump() { return false; } - functions_ = ReadFunctions(tu); - global_variables_ = ReadGlobalVariables(tu); + ReadFunctions(tu); + ReadGlobalVariables(tu); - enum_types_ = ReadEnumTypes(tu); - record_types_ = ReadRecordTypes(tu); - array_types_ = ReadArrayTypes(tu); - pointer_types_ = ReadPointerTypes(tu); - qualified_types_ = ReadQualifiedTypes(tu); - builtin_types_ = ReadBuiltinTypes(tu); - lvalue_reference_types_ = ReadLvalueReferenceTypes(tu); - rvalue_reference_types_ = ReadRvalueReferenceTypes(tu); - - elf_functions_ = ReadElfFunctions(tu); - elf_objects_ = ReadElfObjects(tu); + ReadEnumTypes(tu); + ReadRecordTypes(tu); + ReadArrayTypes(tu); + ReadPointerTypes(tu); + ReadQualifiedTypes(tu); + ReadBuiltinTypes(tu); + ReadLvalueReferenceTypes(tu); + ReadRvalueReferenceTypes(tu); + ReadElfFunctions(tu); + ReadElfObjects(tu); return true; } @@ -171,9 +180,8 @@ EnumTypeIR ProtobufTextFormatToIRReader::EnumTypeProtobufToIR( return enum_type_ir; } -std::vector ProtobufTextFormatToIRReader::ReadGlobalVariables( +void ProtobufTextFormatToIRReader::ReadGlobalVariables( const abi_dump::TranslationUnit &tu) { - std::vector global_variables; for (auto &&global_variable_protobuf : tu.global_vars()) { GlobalVarIR global_variable_ir; global_variable_ir.SetName(global_variable_protobuf.name()); @@ -182,38 +190,44 @@ std::vector ProtobufTextFormatToIRReader::ReadGlobalVariables( global_variable_protobuf.referenced_type()); global_variable_ir.SetLinkerSetKey( global_variable_protobuf.linker_set_key()); - global_variables.emplace_back(std::move(global_variable_ir)); + if (!IsPresentInExportedHeaders(global_variable_ir, exported_headers_)) { + continue; + } + global_variables_.insert( + {global_variable_ir.GetLinkerSetKey(), std::move(global_variable_ir)}); } - return global_variables; } -std::vector ProtobufTextFormatToIRReader::ReadPointerTypes( +void ProtobufTextFormatToIRReader::ReadPointerTypes( const abi_dump::TranslationUnit &tu) { - std::vector pointer_types; for (auto &&pointer_type_protobuf : tu.pointer_types()) { PointerTypeIR pointer_type_ir; ReadTypeInfo(pointer_type_protobuf.type_info(), &pointer_type_ir); - pointer_types.emplace_back(std::move(pointer_type_ir)); + if (!IsPresentInExportedHeaders(pointer_type_ir, exported_headers_)) { + continue; + } + pointer_types_.insert( + {pointer_type_ir.GetLinkerSetKey(), std::move(pointer_type_ir)}); } - return pointer_types; } -std::vector ProtobufTextFormatToIRReader::ReadBuiltinTypes( +void ProtobufTextFormatToIRReader::ReadBuiltinTypes( const abi_dump::TranslationUnit &tu) { - std::vector builtin_types; for (auto &&builtin_type_protobuf : tu.builtin_types()) { BuiltinTypeIR builtin_type_ir; ReadTypeInfo(builtin_type_protobuf.type_info(), &builtin_type_ir); builtin_type_ir.SetSignedness(builtin_type_protobuf.is_unsigned()); builtin_type_ir.SetIntegralType(builtin_type_protobuf.is_integral()); - builtin_types.emplace_back(std::move(builtin_type_ir)); + if (!IsPresentInExportedHeaders(builtin_type_ir, exported_headers_)) { + continue; + } + builtin_types_.insert( + {builtin_type_ir.GetLinkerSetKey(), std::move(builtin_type_ir)}); } - return builtin_types; } -std::vector ProtobufTextFormatToIRReader::ReadQualifiedTypes( +void ProtobufTextFormatToIRReader::ReadQualifiedTypes( const abi_dump::TranslationUnit &tu) { - std::vector qualified_types; for (auto &&qualified_type_protobuf : tu.qualified_types()) { QualifiedTypeIR qualified_type_ir; ReadTypeInfo(qualified_type_protobuf.type_info(), &qualified_type_ir); @@ -221,94 +235,110 @@ std::vector ProtobufTextFormatToIRReader::ReadQualifiedTypes( qualified_type_ir.SetVolatility(qualified_type_protobuf.is_volatile()); qualified_type_ir.SetRestrictedness( qualified_type_protobuf.is_restricted()); - qualified_types.emplace_back(std::move(qualified_type_ir)); + if (!IsPresentInExportedHeaders(qualified_type_ir, exported_headers_)) { + continue; + } + qualified_types_.insert( + {qualified_type_ir.GetLinkerSetKey(), std::move(qualified_type_ir)}); } - return qualified_types; } -std::vector ProtobufTextFormatToIRReader::ReadArrayTypes( +void ProtobufTextFormatToIRReader::ReadArrayTypes( const abi_dump::TranslationUnit &tu) { - std::vector array_types; for (auto &&array_type_protobuf : tu.array_types()) { ArrayTypeIR array_type_ir; ReadTypeInfo(array_type_protobuf.type_info(), &array_type_ir); - array_types.emplace_back(std::move(array_type_ir)); + if (!IsPresentInExportedHeaders(array_type_ir, exported_headers_)) { + continue; + } + array_types_.insert( + {array_type_ir.GetLinkerSetKey(), std::move(array_type_ir)}); } - return array_types; } -std::vector -ProtobufTextFormatToIRReader::ReadLvalueReferenceTypes( +void ProtobufTextFormatToIRReader::ReadLvalueReferenceTypes( const abi_dump::TranslationUnit &tu) { - std::vector lvalue_reference_types; for (auto &&lvalue_reference_type_protobuf : tu.lvalue_reference_types()) { LvalueReferenceTypeIR lvalue_reference_type_ir; ReadTypeInfo(lvalue_reference_type_protobuf.type_info(), &lvalue_reference_type_ir); - lvalue_reference_types.emplace_back(std::move(lvalue_reference_type_ir)); + if (!IsPresentInExportedHeaders(lvalue_reference_type_ir, + exported_headers_)) { + continue; + } + lvalue_reference_types_.insert( + {lvalue_reference_type_ir.GetLinkerSetKey(), + std::move(lvalue_reference_type_ir)}); } - return lvalue_reference_types; } -std::vector -ProtobufTextFormatToIRReader::ReadRvalueReferenceTypes( +void ProtobufTextFormatToIRReader::ReadRvalueReferenceTypes( const abi_dump::TranslationUnit &tu) { - std::vector rvalue_reference_types; for (auto &&rvalue_reference_type_protobuf : tu.rvalue_reference_types()) { RvalueReferenceTypeIR rvalue_reference_type_ir; ReadTypeInfo(rvalue_reference_type_protobuf.type_info(), &rvalue_reference_type_ir); - rvalue_reference_types.emplace_back(std::move(rvalue_reference_type_ir)); + if (!IsPresentInExportedHeaders(rvalue_reference_type_ir, + exported_headers_)) { + continue; + } + rvalue_reference_types_.insert( + {rvalue_reference_type_ir.GetLinkerSetKey(), + std::move(rvalue_reference_type_ir)}); } - return rvalue_reference_types; } -std::vector ProtobufTextFormatToIRReader::ReadFunctions( +void ProtobufTextFormatToIRReader::ReadFunctions( const abi_dump::TranslationUnit &tu) { - std::vector functions; for (auto &&function_protobuf : tu.functions()) { FunctionIR function_ir = FunctionProtobufToIR(function_protobuf); - functions.emplace_back(std::move(function_ir)); + if (!IsPresentInExportedHeaders(function_ir, exported_headers_)) { + continue; + } + functions_.insert({function_ir.GetLinkerSetKey(), std::move(function_ir)}); } - return functions; } -std::vector ProtobufTextFormatToIRReader::ReadRecordTypes( +void ProtobufTextFormatToIRReader::ReadRecordTypes( const abi_dump::TranslationUnit &tu) { - std::vector record_types; for (auto &&record_type_protobuf : tu.record_types()) { RecordTypeIR record_type_ir = RecordTypeProtobufToIR(record_type_protobuf); - record_types.emplace_back(std::move(record_type_ir)); + if (!IsPresentInExportedHeaders(record_type_ir, exported_headers_)) { + continue; + } + record_types_.insert( + {record_type_ir.GetLinkerSetKey(), std::move(record_type_ir)}); } - return record_types; } -std::vector ProtobufTextFormatToIRReader::ReadEnumTypes( +void ProtobufTextFormatToIRReader::ReadEnumTypes( const abi_dump::TranslationUnit &tu) { - std::vector enum_types; for (auto &&enum_type_protobuf : tu.enum_types()) { EnumTypeIR enum_type_ir = EnumTypeProtobufToIR(enum_type_protobuf); - enum_types.emplace_back(std::move(enum_type_ir)); + if (!IsPresentInExportedHeaders(enum_type_ir, exported_headers_)) { + continue; + } + enum_types_.insert( + {enum_type_ir.GetLinkerSetKey(), std::move(enum_type_ir)}); } - return enum_types; } -std::vector ProtobufTextFormatToIRReader::ReadElfFunctions( +void ProtobufTextFormatToIRReader::ReadElfFunctions( const abi_dump::TranslationUnit &tu) { - std::vector elf_functions; for (auto &&elf_function : tu.elf_functions()) { - elf_functions.emplace_back(ElfFunctionIR(elf_function.name())); + ElfFunctionIR elf_function_ir(elf_function.name()); + elf_functions_.insert( + {elf_function_ir.GetName(), std::move(elf_function_ir)}); } - return elf_functions; } -std::vector ProtobufTextFormatToIRReader::ReadElfObjects( +void ProtobufTextFormatToIRReader::ReadElfObjects( const abi_dump::TranslationUnit &tu) { - std::vector elf_objects; for (auto &&elf_object : tu.elf_objects()) { - elf_objects.emplace_back(ElfObjectIR(elf_object.name())); + ElfObjectIR elf_object_ir(elf_object.name()); + elf_objects_.insert( + {elf_object_ir.GetName(), std::move(elf_object_ir)}); } - return elf_objects; } bool IRToProtobufConverter::AddTemplateInformation( @@ -903,6 +933,34 @@ bool ProtobufIRDumper::AddLinkableMessageIR (const LinkableMessageIR *lm) { return false; } +bool ProtobufIRDumper::AddElfFunctionIR(const ElfFunctionIR *elf_function) { + abi_dump::ElfFunction *added_elf_function = tu_ptr_->add_elf_functions(); + if (!added_elf_function) { + return false; + } + added_elf_function->set_name(elf_function->GetName()); + return true; +} + +bool ProtobufIRDumper::AddElfObjectIR(const ElfObjectIR *elf_object) { + abi_dump::ElfObject *added_elf_object = tu_ptr_->add_elf_objects(); + if (!added_elf_object) { + return false; + } + added_elf_object->set_name(elf_object->GetName()); + return true; +} + +bool ProtobufIRDumper::AddElfSymbolMessageIR(const ElfSymbolIR *em) { + switch (em->GetKind()) { + case ElfSymbolIR::ElfFunctionKind: + return AddElfFunctionIR(static_cast(em)); + case ElfSymbolIR::ElfObjectKind: + return AddElfObjectIR(static_cast(em)); + } + return false; +} + bool ProtobufIRDumper::AddRecordTypeIR(const RecordTypeIR *recordp) { abi_dump::RecordType *added_record_type = tu_ptr_->add_record_types(); if (!added_record_type) {