Skip to content

Commit cced593

Browse files
committed
Detect OSX fat archives or Mach-O objects on all architectures
Hard-code the magic values as extracted from OS X header files, but check them when actually building on OS X.
1 parent 22a1897 commit cced593

10 files changed

+66
-41
lines changed

jbmc/src/jdiff/jdiff_parse_options.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ int jdiff_parse_optionst::get_goto_program(
290290
{
291291
status() << "Reading program from `" << cmdline.args[0] << "'" << eom;
292292

293-
if(is_goto_binary(cmdline.args[0]))
293+
if(is_goto_binary(cmdline.args[0], languages.get_message_handler()))
294294
{
295295
if(read_goto_binary(
296296
cmdline.args[0],

src/cbmc/cbmc_parse_options.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -484,8 +484,9 @@ int cbmc_parse_optionst::doit()
484484

485485
if(cmdline.isset("show-parse-tree"))
486486
{
487-
if(cmdline.args.size()!=1 ||
488-
is_goto_binary(cmdline.args[0]))
487+
if(
488+
cmdline.args.size() != 1 ||
489+
is_goto_binary(cmdline.args[0], ui_message_handler))
489490
{
490491
error() << "Please give exactly one source file" << eom;
491492
return CPROVER_EXIT_INCORRECT_TASK;

src/goto-cc/compile.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,9 @@ enum class file_typet
125125
ELF_OBJECT
126126
};
127127

128-
static file_typet detect_file_type(const std::string &file_name)
128+
static file_typet detect_file_type(
129+
const std::string &file_name,
130+
message_handlert &message_handler)
129131
{
130132
// first of all, try to open the file
131133
std::ifstream in(file_name);
@@ -153,7 +155,7 @@ static file_typet detect_file_type(const std::string &file_name)
153155
if(ext == "a")
154156
return file_typet::NORMAL_ARCHIVE;
155157

156-
if(is_goto_binary(file_name))
158+
if(is_goto_binary(file_name, message_handler))
157159
return file_typet::GOTO_BINARY;
158160

159161
if(hdr[0] == 0x7f && memcmp(hdr + 1, "ELF", 3) == 0)
@@ -166,7 +168,7 @@ static file_typet detect_file_type(const std::string &file_name)
166168
/// \return false on success, true on error.
167169
bool compilet::add_input_file(const std::string &file_name)
168170
{
169-
switch(detect_file_type(file_name))
171+
switch(detect_file_type(file_name, get_message_handler()))
170172
{
171173
case file_typet::FAILED_TO_OPEN_FILE:
172174
warning() << "failed to open file `" << file_name
@@ -248,7 +250,7 @@ bool compilet::add_files_from_archive(
248250
{
249251
std::string t = concat_dir_file(tstr, line);
250252

251-
if(is_goto_binary(t))
253+
if(is_goto_binary(t, get_message_handler()))
252254
object_files.push_back(t);
253255
else
254256
debug() << "Object file is not a goto binary: " << line << eom;
@@ -279,7 +281,7 @@ bool compilet::find_library(const std::string &name)
279281
{
280282
library_file_name = concat_dir_file(library_path, "lib" + name + ".so");
281283

282-
switch(detect_file_type(library_file_name))
284+
switch(detect_file_type(library_file_name, get_message_handler()))
283285
{
284286
case file_typet::GOTO_BINARY:
285287
return !add_input_file(library_file_name);

src/goto-diff/goto_diff_parse_options.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ int goto_diff_parse_optionst::get_goto_program(
330330
{
331331
status() << "Reading program from `" << cmdline.args[0] << "'" << eom;
332332

333-
if(is_goto_binary(cmdline.args[0]))
333+
if(is_goto_binary(cmdline.args[0], languages.get_message_handler()))
334334
{
335335
if(read_goto_binary(
336336
cmdline.args[0],

src/goto-programs/initialize_goto_model.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ goto_modelt initialize_goto_model(
4949

5050
for(const auto &file : files)
5151
{
52-
if(is_goto_binary(file))
52+
if(is_goto_binary(file, message_handler))
5353
binaries.push_back(file);
5454
else
5555
sources.push_back(file);

src/goto-programs/lazy_goto_model.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ void lazy_goto_modelt::initialize(
128128

129129
for(const auto &file : files)
130130
{
131-
if(is_goto_binary(file))
131+
if(is_goto_binary(file, message_handler))
132132
binaries.push_back(file);
133133
else
134134
sources.push_back(file);

src/goto-programs/osx_fat_reader.cpp

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,35 +15,48 @@ Module: Read Mach-O
1515
#include <util/exception_utils.h>
1616
#include <util/invariant.h>
1717

18+
// we define file-type magic values for all platforms to detect when we find a
19+
// file that we might not be able to process
20+
#define CPROVER_FAT_MAGIC 0xcafebabe
21+
#define CPROVER_FAT_CIGAM 0xbebafeca
22+
#define CPROVER_MH_MAGIC 0xfeedface
23+
#define CPROVER_MH_CIGAM 0xcefaedfe
24+
#define CPROVER_MH_MAGIC_64 0xfeedfacf
25+
#define CPROVER_MH_CIGAM_64 0xcffaedfe
26+
1827
#ifdef __APPLE__
1928
#include <architecture/byte_order.h>
2029
#include <mach-o/fat.h>
2130
#include <mach-o/loader.h>
2231
#include <mach-o/swap.h>
32+
33+
#if(CPROVER_FAT_MAGIC != FAT_MAGIC) || (CPROVER_FAT_CIGAM != FAT_CIGAM) || \
34+
(CPROVER_MH_MAGIC != MH_MAGIC) || (CPROVER_MH_CIGAM != MH_CIGAM) || \
35+
(CPROVER_MH_MAGIC_64 != MH_MAGIC_64) || (CPROVER_MH_CIGAM != MH_CIGAM_64)
36+
#error "Mach-O magic has inconsistent value"
37+
#endif
2338
#endif
2439

2540
#include <util/run.h>
2641

2742
bool is_osx_fat_magic(char hdr[4])
2843
{
29-
#ifdef __APPLE__
3044
uint32_t *magic=reinterpret_cast<uint32_t*>(hdr);
3145

3246
switch(*magic)
3347
{
34-
case FAT_MAGIC:
35-
case FAT_CIGAM:
36-
return true;
48+
case CPROVER_FAT_MAGIC:
49+
case CPROVER_FAT_CIGAM:
50+
return true;
3751
}
38-
#else
39-
(void)hdr; // unused parameter
40-
#endif
4152

4253
return false;
4354
}
4455

45-
osx_fat_readert::osx_fat_readert(std::ifstream &in) :
46-
has_gb_arch(false)
56+
osx_fat_readert::osx_fat_readert(
57+
std::ifstream &in,
58+
message_handlert &message_handler)
59+
: log(message_handler), has_gb_arch(false)
4760
{
4861
#ifdef __APPLE__
4962
// NOLINTNEXTLINE(readability/identifiers)
@@ -82,6 +95,9 @@ osx_fat_readert::osx_fat_readert(std::ifstream &in) :
8295
}
8396
#else
8497
(void)in; // unused parameter
98+
99+
log.warning() << "Cannot read OSX fat archive on this platform"
100+
<< messaget::eom;
85101
#endif
86102
}
87103

@@ -99,20 +115,16 @@ bool osx_fat_readert::extract_gb(
99115
// guided by https://lowlevelbits.org/parsing-mach-o-files/
100116
bool is_osx_mach_object(char hdr[4])
101117
{
102-
#ifdef __APPLE__
103118
uint32_t *magic = reinterpret_cast<uint32_t *>(hdr);
104119

105120
switch(*magic)
106121
{
107-
case MH_MAGIC:
108-
case MH_CIGAM:
109-
case MH_MAGIC_64:
110-
case MH_CIGAM_64:
122+
case CPROVER_MH_MAGIC:
123+
case CPROVER_MH_CIGAM:
124+
case CPROVER_MH_MAGIC_64:
125+
case CPROVER_MH_CIGAM_64:
111126
return true;
112127
}
113-
#else
114-
(void)hdr; // unused parameter
115-
#endif
116128

117129
return false;
118130
}
@@ -236,7 +248,10 @@ void osx_mach_o_readert::process_commands(
236248
#endif
237249
}
238250

239-
osx_mach_o_readert::osx_mach_o_readert(std::istream &_in) : in(_in)
251+
osx_mach_o_readert::osx_mach_o_readert(
252+
std::istream &_in,
253+
message_handlert &message_handler)
254+
: log(message_handler), in(_in)
240255
{
241256
// read magic
242257
uint32_t magic;
@@ -249,16 +264,16 @@ osx_mach_o_readert::osx_mach_o_readert(std::istream &_in) : in(_in)
249264
bool is_64 = false, need_swap = false;
250265
switch(magic)
251266
{
252-
case MH_CIGAM:
267+
case CPROVER_MH_CIGAM:
253268
need_swap = true;
254269
break;
255-
case MH_MAGIC:
270+
case CPROVER_MH_MAGIC:
256271
break;
257-
case MH_CIGAM_64:
272+
case CPROVER_MH_CIGAM_64:
258273
need_swap = true;
259274
is_64 = true;
260275
break;
261-
case MH_MAGIC_64:
276+
case CPROVER_MH_MAGIC_64:
262277
is_64 = true;
263278
break;
264279
default:
@@ -303,5 +318,6 @@ osx_mach_o_readert::osx_mach_o_readert(std::istream &_in) : in(_in)
303318
}
304319

305320
process_commands(ncmds, offset, need_swap);
321+
#else
306322
#endif
307323
}

src/goto-programs/osx_fat_reader.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ Module: Read OS X Fat Binaries
1212
#ifndef CPROVER_GOTO_PROGRAMS_OSX_FAT_READER_H
1313
#define CPROVER_GOTO_PROGRAMS_OSX_FAT_READER_H
1414

15+
#include <util/message.h>
16+
1517
#include <fstream>
1618
#include <map>
1719
#include <string>
@@ -22,7 +24,7 @@ Module: Read OS X Fat Binaries
2224
class osx_fat_readert
2325
{
2426
public:
25-
explicit osx_fat_readert(std::ifstream &in);
27+
osx_fat_readert(std::ifstream &, message_handlert &);
2628

2729
bool has_gb() const { return has_gb_arch; }
2830

@@ -31,6 +33,7 @@ class osx_fat_readert
3133
const std::string &dest) const;
3234

3335
private:
36+
messaget log;
3437
bool has_gb_arch;
3538
};
3639

@@ -39,7 +42,7 @@ bool is_osx_fat_magic(char hdr[4]);
3942
class osx_mach_o_readert
4043
{
4144
public:
42-
explicit osx_mach_o_readert(std::istream &_in);
45+
osx_mach_o_readert(std::istream &, message_handlert &);
4346

4447
struct sectiont
4548
{
@@ -62,6 +65,7 @@ class osx_mach_o_readert
6265
}
6366

6467
private:
68+
messaget log;
6569
std::istream &in;
6670

6771
void process_commands(uint32_t ncmds, std::size_t offset, bool need_swap);

src/goto-programs/read_goto_binary.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ bool read_goto_binary(
130130

131131
// Mach-O universal binary
132132
// This _may_ have a goto binary as hppa7100LC architecture
133-
osx_fat_readert osx_fat_reader(in);
133+
osx_fat_readert osx_fat_reader(in, message_handler);
134134

135135
if(osx_fat_reader.has_gb())
136136
{
@@ -163,7 +163,7 @@ bool read_goto_binary(
163163
// Mach-O object file, may contain a goto-cc section
164164
try
165165
{
166-
osx_mach_o_readert mach_o_reader(in);
166+
osx_mach_o_readert mach_o_reader(in, message_handler);
167167

168168
osx_mach_o_readert::sectionst::const_iterator entry =
169169
mach_o_reader.sections.find("goto-cc");
@@ -193,7 +193,9 @@ bool read_goto_binary(
193193
return true;
194194
}
195195

196-
bool is_goto_binary(const std::string &filename)
196+
bool is_goto_binary(
197+
const std::string &filename,
198+
message_handlert &message_handler)
197199
{
198200
#ifdef _MSC_VER
199201
std::ifstream in(widen(filename), std::ios::binary);
@@ -240,7 +242,7 @@ bool is_goto_binary(const std::string &filename)
240242
try
241243
{
242244
in.seekg(0);
243-
osx_fat_readert osx_fat_reader(in);
245+
osx_fat_readert osx_fat_reader(in, message_handler);
244246
if(osx_fat_reader.has_gb())
245247
return true;
246248
}
@@ -256,7 +258,7 @@ bool is_goto_binary(const std::string &filename)
256258
try
257259
{
258260
in.seekg(0);
259-
osx_mach_o_readert mach_o_reader(in);
261+
osx_mach_o_readert mach_o_reader(in, message_handler);
260262
if(mach_o_reader.has_section("goto-cc"))
261263
return true;
262264
}

src/goto-programs/read_goto_binary.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ bool read_goto_binary(
3737
optionalt<goto_modelt>
3838
read_goto_binary(const std::string &filename, message_handlert &);
3939

40-
bool is_goto_binary(const std::string &filename);
40+
bool is_goto_binary(const std::string &filename, message_handlert &);
4141

4242
bool read_object_and_link(
4343
const std::string &file_name,

0 commit comments

Comments
 (0)