Skip to content

Commit b18a181

Browse files
committed
OS X hybrid binaries: use sections for object files
lipo/fat binaries only work properly for executables as it isn't possible to build archives of fat binaries containing goto-cc sections (ranlib complains about invalid object files); conversely, adding additional sections isn't possible with executables, but fat binaries work fine.
1 parent 39bc679 commit b18a181

File tree

6 files changed

+46
-8
lines changed

6 files changed

+46
-8
lines changed

src/goto-cc/as_mode.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ int as_modet::doit()
241241
// We can generate hybrid ELF and Mach-O binaries
242242
// containing both executable machine code and the goto-binary.
243243
if(produce_hybrid_binary)
244-
return as_hybrid_binary();
244+
return as_hybrid_binary(compiler);
245245

246246
return EX_OK;
247247
}
@@ -270,7 +270,7 @@ int as_modet::run_as()
270270
return run(new_argv[0], new_argv, cmdline.stdin_file, "", "");
271271
}
272272

273-
int as_modet::as_hybrid_binary()
273+
int as_modet::as_hybrid_binary(const compilet &compiler)
274274
{
275275
std::string output_file="a.out";
276276

@@ -301,7 +301,11 @@ int as_modet::as_hybrid_binary()
301301
if(result == 0)
302302
{
303303
result = hybrid_binary(
304-
native_tool_name, saved, output_file, get_message_handler());
304+
native_tool_name,
305+
saved,
306+
output_file,
307+
compiler.mode == compilet::COMPILE_LINK_EXECUTABLE,
308+
get_message_handler());
305309
}
306310

307311
return result;

src/goto-cc/as_mode.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ Date: July 2016
1717
#include "gcc_message_handler.h"
1818
#include "goto_cc_mode.h"
1919

20+
class compilet;
21+
2022
class as_modet:public goto_cc_modet
2123
{
2224
public:
@@ -35,7 +37,7 @@ class as_modet:public goto_cc_modet
3537

3638
int run_as(); // call as with original command line
3739

38-
int as_hybrid_binary();
40+
int as_hybrid_binary(const compilet &compiler);
3941
};
4042

4143
#endif // CPROVER_GOTO_CC_AS_MODE_H

src/goto-cc/gcc_mode.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -982,7 +982,11 @@ int gcc_modet::gcc_hybrid_binary(compilet &compiler)
982982

983983
if(result==0)
984984
result = hybrid_binary(
985-
native_tool, goto_binary, *it, get_message_handler());
985+
native_tool,
986+
goto_binary,
987+
*it,
988+
compiler.mode == compilet::COMPILE_LINK_EXECUTABLE,
989+
get_message_handler());
986990
}
987991

988992
return result;

src/goto-cc/hybrid_binary.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,17 @@ int hybrid_binary(
2020
const std::string &compiler_or_linker,
2121
const std::string &goto_binary_file,
2222
const std::string &output_file,
23+
bool building_executable,
2324
message_handlert &message_handler)
2425
{
2526
messaget message(message_handler);
2627

2728
int result;
2829

2930
#if defined(__linux__) || defined(__FreeBSD_kernel__)
31+
// we can use objcopy for both object files and executables
32+
(void)building_executable;
33+
3034
std::string objcopy_cmd;
3135

3236
if(has_suffix(compiler_or_linker, "-ld"))
@@ -69,9 +73,10 @@ int hybrid_binary(
6973
// Mac
7074

7175
message.debug() << "merging " << output_file << " and " << goto_binary_file
72-
<< " using lipo"
76+
<< " using " << (building_executable ? "lipo" : "ld")
7377
<< messaget::eom;
7478

79+
if(building_executable)
7580
{
7681
// Add goto-binary as hppa7100LC section.
7782
// This overwrites if there's already one.
@@ -81,6 +86,21 @@ int hybrid_binary(
8186

8287
result = run(lipo_argv[0], lipo_argv);
8388
}
89+
else
90+
{
91+
// This fails if there's already one.
92+
std::vector<std::string> ld_argv = {"ld",
93+
"-r",
94+
"-sectcreate",
95+
"__TEXT",
96+
"goto-cc",
97+
goto_binary_file,
98+
output_file,
99+
"-o",
100+
output_file};
101+
102+
result = run(ld_argv[0], ld_argv);
103+
}
84104

85105
// delete the goto binary
86106
int remove_result = remove(goto_binary_file.c_str());
@@ -97,6 +117,7 @@ int hybrid_binary(
97117
(void)compiler_or_linker;
98118
(void)goto_binary_file;
99119
(void)output_file;
120+
(void)building_executable;
100121
message.error() << "binary merging not implemented for this platform"
101122
<< messaget::eom;
102123
result = 1;

src/goto-cc/hybrid_binary.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,13 @@ Date: May 2018
2323
/// deduce the name of objcopy
2424
/// \param goto_binary_file: The file name of the goto binary
2525
/// \param output_file: The name of the object file; the result is stored here.
26+
/// \param building_executable: The \p output_file is an executable.
27+
/// \param message_handler: Message handler for output.
2628
int hybrid_binary(
2729
const std::string &compiler_or_linker,
2830
const std::string &goto_binary_file,
2931
const std::string &output_file,
30-
message_handlert &);
32+
bool building_executable,
33+
message_handlert &message_handler);
3134

3235
#endif // CPROVER_GOTO_CC_HYBRID_BINARY_H

src/goto-cc/ld_mode.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,11 @@ int ld_modet::ld_hybrid_binary(compilet &compiler)
209209
std::string native_linker = linker_name(cmdline, base_name);
210210

211211
result = hybrid_binary(
212-
native_linker, goto_binary, output_file, get_message_handler());
212+
native_linker,
213+
goto_binary,
214+
output_file,
215+
compiler.mode == compilet::COMPILE_LINK_EXECUTABLE,
216+
get_message_handler());
213217
}
214218

215219
return result;

0 commit comments

Comments
 (0)