cprover
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/file_util.h>
15#include <util/message.h>
16#include <util/run.h>
17#include <util/suffix.h>
18
19#include <cstring>
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__) || defined(__OpenBSD__)
52 // we can use objcopy for both object files and executables
54
56
57 // merge output from gcc or ld with goto-binary using objcopy
58
59 message.debug() << "merging " << output_file << " and " << goto_binary_file
60 << " using " << objcopy_cmd
62
63 {
64 // Now add goto-binary as goto-cc section.
65 // Remove if it exists before, or otherwise adding fails.
66 std::vector<std::string> objcopy_argv = {
68 "--remove-section", "goto-cc",
69 "--add-section", "goto-cc=" + goto_binary_file, output_file};
70
72 if(add_section_result != 0)
73 {
74 if(linking_efi)
75 message.warning() << "cannot merge EFI binaries: goto-cc section lost"
77 else
78 result = add_section_result;
79 }
80 }
81
82 // delete the goto binary
84 if(!remove_result)
85 {
86 message.error() << "Remove failed: " << std::strerror(errno)
88 if(result == 0)
89 result = remove_result;
90 }
91
92#elif defined(__APPLE__)
93 // Mac
94
95 message.debug() << "merging " << output_file << " and " << goto_binary_file
96 << " using " << (building_executable ? "lipo" : "ld")
98
100 {
101 // Add goto-binary as hppa7100LC section.
102 // This overwrites if there's already one.
103 std::vector<std::string> lipo_argv = {
104 "lipo", output_file, "-create", "-arch", "hppa7100LC", goto_binary_file,
105 "-output", output_file };
106
107 result = run(lipo_argv[0], lipo_argv);
108
109 if(result == 0)
110 {
111 // lipo creates an output file, but it does not set execute permissions,
112 // so the user is unable to directly execute the output file until its
113 // chmod +x
116 int chmod_result = chmod(
118 if(chmod_result != 0)
119 {
120 message.error() << "Setting execute permissions failed: "
121 << std::strerror(errno) << messaget::eom;
122 result = chmod_result;
123 }
124 }
125 }
126 else
127 {
128 // This fails if there's already one.
129 std::vector<std::string> ld_argv = {"ld",
130 "-r",
131 "-sectcreate",
132 "__TEXT",
133 "goto-cc",
136 "-o",
138
139 result = run(ld_argv[0], ld_argv);
140 }
141
142 // delete the goto binary
144 if(!remove_result)
145 {
146 message.error() << "Remove failed: " << std::strerror(errno)
147 << messaget::eom;
148 if(result == 0)
149 result = remove_result;
150 }
151
152#else
153 // unused parameters
158 message.error() << "binary merging not implemented for this platform"
159 << messaget::eom;
160 result = 1;
161#endif
162
163 return result;
164}
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:563
Class that provides messages with a built-in verbosity 'level'.
Definition message.h:155
mstreamt & error() const
Definition message.h:399
mstreamt & debug() const
Definition message.h:429
mstreamt & warning() const
Definition message.h:404
static eomt eom
Definition message.h:297
bool file_remove(const std::string &path)
C++17 will allow us to use std::filesystem::remove.
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:48
bool has_suffix(const std::string &s, const std::string &suffix)
Definition suffix.h:17