CBMC
Loading...
Searching...
No Matches
hybrid_binary.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Create hybrid binary with goto-binary section
4
5Author: Michael Tautschnig, 2018
6
7\*******************************************************************/
8
11
12#include "hybrid_binary.h"
13
14#include <util/message.h>
15#include <util/run.h>
16#include <util/suffix.h>
17
18#include <cstring>
19#include <filesystem>
20
21#if defined(__APPLE__)
22# include <sys/stat.h>
23#endif
24
25std::string objcopy_command(const std::string &compiler_or_linker)
26{
28 {
29 std::string objcopy_cmd = compiler_or_linker;
30 objcopy_cmd.erase(objcopy_cmd.size() - 2);
31 objcopy_cmd += "objcopy";
32
33 return objcopy_cmd;
34 }
35 else
36 return "objcopy";
37}
38
40 const std::string &compiler_or_linker,
41 const std::string &goto_binary_file,
42 const std::string &output_file,
44 message_handlert &message_handler,
45 bool linking_efi)
46{
47 messaget message(message_handler);
48
49 int result = 0;
50
51#if defined(__linux__) || defined(__FreeBSD_kernel__) || \
52 defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || \
53 defined(__gnu_hurd__)
54 // we can use objcopy for both object files and executables
56
58
59 // merge output from gcc or ld with goto-binary using objcopy
60
61 message.debug() << "merging " << output_file << " and " << goto_binary_file
62 << " using " << objcopy_cmd
64
65 {
66 // Now add goto-binary as goto-cc section.
67 // Remove if it exists before, or otherwise adding fails.
68 std::vector<std::string> objcopy_argv = {
70 "--remove-section", "goto-cc",
71 "--add-section", "goto-cc=" + goto_binary_file, output_file};
72
74 if(add_section_result != 0)
75 {
76 if(linking_efi)
77 message.warning() << "cannot merge EFI binaries: goto-cc section lost"
79 else
80 result = add_section_result;
81 }
82 }
83
84 // delete the goto binary
85 bool remove_result = std::filesystem::remove(goto_binary_file);
86 if(!remove_result)
87 {
88 message.error() << "Remove failed: " << std::strerror(errno)
90 if(result == 0)
91 result = remove_result;
92 }
93
94#elif defined(__APPLE__)
95 // Mac
96
97 message.debug() << "merging " << output_file << " and " << goto_binary_file
98 << " using " << (building_executable ? "lipo" : "ld")
100
102 {
103 // Add goto-binary as hppa7100LC section.
104 // This overwrites if there's already one.
105 std::vector<std::string> lipo_argv = {
106 "lipo", output_file, "-create", "-arch", "hppa7100LC", goto_binary_file,
107 "-output", output_file };
108
109 result = run(lipo_argv[0], lipo_argv);
110
111 if(result == 0)
112 {
113 // lipo creates an output file, but it does not set execute permissions,
114 // so the user is unable to directly execute the output file until its
115 // chmod +x
118 int chmod_result = chmod(
120 if(chmod_result != 0)
121 {
122 message.error() << "Setting execute permissions failed: "
123 << std::strerror(errno) << messaget::eom;
124 result = chmod_result;
125 }
126 }
127 }
128 else
129 {
130 // This fails if there's already one.
131 std::vector<std::string> ld_argv = {"ld",
132 "-r",
133 "-sectcreate",
134 "__TEXT",
135 "goto-cc",
138 "-o",
140
141 result = run(ld_argv[0], ld_argv);
142 }
143
144 // delete the goto binary
145 bool remove_result = std::filesystem::remove(goto_binary_file);
146 if(!remove_result)
147 {
148 message.error() << "Remove failed: " << std::strerror(errno)
149 << messaget::eom;
150 if(result == 0)
151 result = remove_result;
152 }
153
154#else
155 // unused parameters
160 message.error() << "binary merging not implemented for this platform"
161 << messaget::eom;
162 result = 1;
163#endif
164
165 return result;
166}
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
Class that provides messages with a built-in verbosity 'level'.
Definition message.h:154
mstreamt & error() const
Definition message.h:391
mstreamt & debug() const
Definition message.h:421
mstreamt & warning() const
Definition message.h:396
static eomt eom
Definition message.h:289
int hybrid_binary(const std::string &compiler_or_linker, const std::string &goto_binary_file, const std::string &output_file, bool building_executable, message_handlert &message_handler, bool linking_efi)
Merges a goto binary into an object file (e.g.
std::string objcopy_command(const std::string &compiler_or_linker)
Return the name of the objcopy tool matching the chosen compiler or linker command.
Create hybrid binary with goto-binary section.
int run(const std::string &what, const std::vector< std::string > &argv)
Definition run.cpp:49
bool has_suffix(const std::string &s, const std::string &suffix)
Definition suffix.h:17