Add options to make elf symbol changes as warnings.

Some elf symbols in the .dynsym table of an .so file may not be present
in the headers exported by a shared library. We must still know about
these changes. Therefore, add options to make notifications about
these changes warnings instead of errors.

Bug: 62060883

Test: tests/test.py pass

Change-Id: Ic0cbad3370597c251f9e2c0f2b8cbb089aed155f
This commit is contained in:
Jayant Chowdhary
2017-08-23 22:34:38 -07:00
parent 860b41407e
commit 1fdab142f7
3 changed files with 40 additions and 18 deletions

View File

@@ -51,6 +51,12 @@ static llvm::cl::opt<bool> advice_only(
"advice-only", llvm::cl::desc("Advisory mode only"), llvm::cl::Optional, "advice-only", llvm::cl::desc("Advisory mode only"), llvm::cl::Optional,
llvm::cl::cat(header_checker_category)); llvm::cl::cat(header_checker_category));
static llvm::cl::opt<bool> elf_unreferenced_symbol_errors(
"elf-unreferenced-symbol-errors",
llvm::cl::desc("Display erors on removal of elf symbols, unreferenced by"
"metadata in exported headers."),
llvm::cl::Optional, llvm::cl::cat(header_checker_category));
static llvm::cl::opt<bool> check_all_apis( static llvm::cl::opt<bool> check_all_apis(
"check-all-apis", "check-all-apis",
llvm::cl::desc("All apis, whether referenced or not, by exported symbols in" llvm::cl::desc("All apis, whether referenced or not, by exported symbols in"
@@ -66,6 +72,12 @@ static llvm::cl::opt<bool> allow_extensions(
llvm::cl::desc("Do not return a non zero status on extensions"), llvm::cl::desc("Do not return a non zero status on extensions"),
llvm::cl::Optional, llvm::cl::cat(header_checker_category)); llvm::cl::Optional, llvm::cl::cat(header_checker_category));
static llvm::cl::opt<bool> allow_unreferenced_elf_symbol_changes(
"allow-unreferenced-elf-symbol-changes",
llvm::cl::desc("Do not return a non zero status on changes to elf symbols"
"not referenced by metadata in exported headers"),
llvm::cl::Optional, llvm::cl::cat(header_checker_category));
static llvm::cl::opt<bool> allow_unreferenced_changes( static llvm::cl::opt<bool> allow_unreferenced_changes(
"allow-unreferenced-changes", "allow-unreferenced-changes",
llvm::cl::desc("Do not return a non zero status on changes to data" llvm::cl::desc("Do not return a non zero status on changes to data"
@@ -102,11 +114,21 @@ int main(int argc, const char **argv) {
std::string status_str = ""; std::string status_str = "";
std::string unreferenced_change_str = ""; std::string unreferenced_change_str = "";
std::string error_or_warning_str = "\033[36;1mwarning: \033[0m"; std::string error_or_warning_str = "\033[36;1mwarning: \033[0m";
switch (status) {
if (status == abi_util::CompatibilityStatusIR::Incompatible) { case abi_util::CompatibilityStatusIR::Incompatible:
error_or_warning_str = "\033[31;1merror: \033[0m"; error_or_warning_str = "\033[31;1merror: \033[0m";
status_str = "INCOMPATIBLE CHANGES"; status_str = "INCOMPATIBLE CHANGES";
} else if (status & abi_util::CompatibilityStatusIR::Extension) { break;
case abi_util::CompatibilityStatusIR::ElfIncompatible:
if (elf_unreferenced_symbol_errors) {
error_or_warning_str = "\033[31;1merror: \033[0m";
}
status_str = "ELF Symbols not referenced by exported headers removed";
break;
default:
break;
}
if (status & abi_util::CompatibilityStatusIR::Extension) {
status_str = "EXTENDING CHANGES"; status_str = "EXTENDING CHANGES";
} }
if (status & abi_util::CompatibilityStatusIR::UnreferencedChanges) { if (status & abi_util::CompatibilityStatusIR::UnreferencedChanges) {
@@ -114,7 +136,6 @@ int main(int argc, const char **argv) {
unreferenced_change_str += " not directly referenced by exported symbols."; unreferenced_change_str += " not directly referenced by exported symbols.";
unreferenced_change_str += " This MIGHT be an ABI breaking change due to"; unreferenced_change_str += " This MIGHT be an ABI breaking change due to";
unreferenced_change_str += " internal typecasts."; unreferenced_change_str += " internal typecasts.";
} }
if (!suppress_local_warnings && status) { if (!suppress_local_warnings && status) {
llvm::errs() << "******************************************************\n" llvm::errs() << "******************************************************\n"
@@ -132,11 +153,10 @@ int main(int argc, const char **argv) {
if ((allow_extensions && if ((allow_extensions &&
(status & abi_util::CompatibilityStatusIR::Extension)) || (status & abi_util::CompatibilityStatusIR::Extension)) ||
(allow_unreferenced_changes && (allow_unreferenced_changes &&
(status & abi_util::CompatibilityStatusIR::UnreferencedChanges))) { (status & abi_util::CompatibilityStatusIR::UnreferencedChanges)) ||
return abi_util::CompatibilityStatusIR::Compatible; (allow_unreferenced_elf_symbol_changes &&
} (status & abi_util::CompatibilityStatusIR::ElfIncompatible)) ||
advice_only) {
if (advice_only) {
return abi_util::CompatibilityStatusIR::Compatible; return abi_util::CompatibilityStatusIR::Compatible;
} }

View File

@@ -29,7 +29,8 @@ enum CompatibilityStatusIR {
Compatible = 0, Compatible = 0,
UnreferencedChanges = 1, UnreferencedChanges = 1,
Extension = 4, Extension = 4,
Incompatible = 8 Incompatible = 8,
ElfIncompatible = 16
}; };
static inline CompatibilityStatusIR operator|(CompatibilityStatusIR f, static inline CompatibilityStatusIR operator|(CompatibilityStatusIR f,

View File

@@ -1020,19 +1020,20 @@ CompatibilityStatusIR ProtobufIRDiffDumper::GetCompatibilityStatusIR() {
diff_tu_->function_diffs().size() != 0 || diff_tu_->function_diffs().size() != 0 ||
diff_tu_->global_var_diffs().size() != 0 || diff_tu_->global_var_diffs().size() != 0 ||
diff_tu_->enum_type_diffs().size() != 0 || diff_tu_->enum_type_diffs().size() != 0 ||
diff_tu_->record_type_diffs().size() != 0 || diff_tu_->record_type_diffs().size() != 0) {
diff_tu_->removed_elf_functions().size() != 0 ||
diff_tu_->removed_elf_objects().size() != 0) {
return CompatibilityStatusIR::Incompatible; return CompatibilityStatusIR::Incompatible;
} }
if(diff_tu_->removed_elf_functions().size() != 0 ||
diff_tu_->removed_elf_objects().size() != 0) {
return CompatibilityStatusIR::ElfIncompatible;
}
CompatibilityStatusIR combined_status = CompatibilityStatusIR::Compatible; CompatibilityStatusIR combined_status = CompatibilityStatusIR::Compatible;
if (diff_tu_->enum_type_extension_diffs().size() != 0 || if (diff_tu_->enum_type_extension_diffs().size() != 0 ||
diff_tu_->functions_added().size() != 0 || diff_tu_->functions_added().size() != 0 ||
diff_tu_->global_vars_added().size() !=0 || diff_tu_->global_vars_added().size() != 0) {
diff_tu_->added_elf_functions().size() != 0 ||
diff_tu_->added_elf_objects().size() != 0) {
combined_status = combined_status | CompatibilityStatusIR::Extension; combined_status = combined_status | CompatibilityStatusIR::Extension;
} }