From b13cf7f42e3c0a92ffe6dbd705b2274a592ee2c6 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Fri, 8 Sep 2017 10:13:59 +0000 Subject: [PATCH 1/2] Cope with EFI binaries Running objcopy on EFI binaries does not work, hence we need to give up on the goto-cc sections in a graceful manner. --- src/goto-cc/gcc_mode.cpp | 57 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/src/goto-cc/gcc_mode.cpp b/src/goto-cc/gcc_mode.cpp index fade9d0307b..b98dde7875d 100644 --- a/src/goto-cc/gcc_mode.cpp +++ b/src/goto-cc/gcc_mode.cpp @@ -941,6 +941,34 @@ int gcc_modet::gcc_hybrid_binary(compilet &compiler) } objcopy_cmd+="objcopy"; + #ifdef __linux__ + if(act_as_ld && cmdline.get_value('m')=="i386pep") + { + for(const auto &object_file : compiler.object_files) + { + debug() << "stripping goto-cc sections before building EFI binary" << eom; + // create a backup copy + std::string bin_name=object_file+goto_binary_tmp_suffix; + + std::ifstream in(object_file, std::ios::binary); + std::ofstream out(bin_name, std::ios::binary); + out << in.rdbuf(); + + // remove any existing goto-cc section + std::vector objcopy_argv; + + objcopy_argv.push_back(objcopy_cmd); + objcopy_argv.push_back("--remove-section=goto-cc"); + objcopy_argv.push_back(object_file); + + int result=run(objcopy_argv[0], objcopy_argv, "", ""); + if(result!=0) + debug() << "EFI binary preparation: removing goto-cc section failed" + << eom; + } + } + #endif + int result=run_gcc(compiler); if(result==0) @@ -950,6 +978,21 @@ int gcc_modet::gcc_hybrid_binary(compilet &compiler) result=ls_merge.add_linker_script_definitions(); } + #ifdef __linux__ + if(act_as_ld && cmdline.get_value('m')=="i386pep") + { + debug() << "arch set with " << compiler.object_files.size() << eom; + for(const auto &object_file : compiler.object_files) + { + debug() << "EFI binary preparation: restoring object files" << eom; + std::string bin_name=object_file+goto_binary_tmp_suffix; + int mv_result=rename(bin_name.c_str(), object_file.c_str()); + if(mv_result!=0) + debug() << "Rename failed: " << std::strerror(errno) << eom; + } + } + #endif + // merge output from gcc with goto-binaries // using objcopy, or do cleanup if an earlier call failed for(std::list::const_iterator @@ -970,7 +1013,9 @@ int gcc_modet::gcc_hybrid_binary(compilet &compiler) objcopy_argv.push_back("--remove-section=goto-cc"); objcopy_argv.push_back(*it); - result=run(objcopy_argv[0], objcopy_argv, "", ""); + int rs_result=run(objcopy_argv[0], objcopy_argv, "", ""); + if(rs_result!=0 && (!act_as_ld || cmdline.get_value('m')!="i386pep")) + result=rs_result; } if(result==0) @@ -983,7 +1028,15 @@ int gcc_modet::gcc_hybrid_binary(compilet &compiler) objcopy_argv.push_back("goto-cc="+saved); objcopy_argv.push_back(*it); - result=run(objcopy_argv[0], objcopy_argv, "", ""); + int as_result=run(objcopy_argv[0], objcopy_argv, "", ""); + if(as_result!=0) + { + if(act_as_ld && cmdline.get_value('m')=="i386pep") + warning() << "cannot merge EFI binaries: goto-cc section lost" + << eom; + else + result=as_result; + } } int remove_result=remove(saved.c_str()); From 7a09ada625889c39aa770ef4d303524c5bc61927 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Fri, 8 Sep 2017 10:16:55 +0000 Subject: [PATCH 2/2] Accept more mismatching function definition/declaration pairs As long as the bit-width of parameters matches, we should be able to obtain sane results. --- src/linking/linking.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/linking/linking.cpp b/src/linking/linking.cpp index 5b5a1d36fd2..db78ffd1d02 100644 --- a/src/linking/linking.cpp +++ b/src/linking/linking.cpp @@ -703,6 +703,17 @@ void linkingt::duplicate_code_symbol( if(!found) break; } + // different non-pointer arguments with implementation - the + // implementation is always right, even though such code may + // be severely broken + else if(pointer_offset_bits(t1, ns)==pointer_offset_bits(t2, ns) && + old_symbol.value.is_nil()!=new_symbol.value.is_nil()) + { + if(warn_msg.empty()) + warn_msg="non-pointer parameter types differ between " + "declaration and definition"; + replace=new_symbol.value.is_not_nil(); + } else break;