Skip to content

Commit d16fdcb

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 7bf0fbc commit d16fdcb

File tree

3 files changed

+52
-29
lines changed

3 files changed

+52
-29
lines changed

src/goto-programs/osx_fat_reader.cpp

Lines changed: 39 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_64 != 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,7 @@ osx_mach_o_readert::osx_mach_o_readert(std::istream &_in) : in(_in)
303318
}
304319

305320
process_commands(ncmds, offset, need_swap);
321+
#else
322+
log.warning() << "Cannot read OSX Mach-O on this platform" << messaget::eom;
306323
#endif
307324
}

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
@@ -120,7 +120,7 @@ static bool read_goto_binary(
120120

121121
// Mach-O universal binary
122122
// This _may_ have a goto binary as hppa7100LC architecture
123-
osx_fat_readert osx_fat_reader(in);
123+
osx_fat_readert osx_fat_reader(in, message_handler);
124124

125125
if(osx_fat_reader.has_gb())
126126
{
@@ -153,7 +153,7 @@ static bool read_goto_binary(
153153
// Mach-O object file, may contain a goto-cc section
154154
try
155155
{
156-
osx_mach_o_readert mach_o_reader(in);
156+
osx_mach_o_readert mach_o_reader(in, message_handler);
157157

158158
osx_mach_o_readert::sectionst::const_iterator entry =
159159
mach_o_reader.sections.find("goto-cc");
@@ -183,7 +183,9 @@ static bool read_goto_binary(
183183
return true;
184184
}
185185

186-
bool is_goto_binary(const std::string &filename, message_handlert &)
186+
bool is_goto_binary(
187+
const std::string &filename,
188+
message_handlert &message_handler)
187189
{
188190
#ifdef _MSC_VER
189191
std::ifstream in(widen(filename), std::ios::binary);
@@ -230,7 +232,7 @@ bool is_goto_binary(const std::string &filename, message_handlert &)
230232
try
231233
{
232234
in.seekg(0);
233-
osx_fat_readert osx_fat_reader(in);
235+
osx_fat_readert osx_fat_reader(in, message_handler);
234236
if(osx_fat_reader.has_gb())
235237
return true;
236238
}
@@ -246,7 +248,7 @@ bool is_goto_binary(const std::string &filename, message_handlert &)
246248
try
247249
{
248250
in.seekg(0);
249-
osx_mach_o_readert mach_o_reader(in);
251+
osx_mach_o_readert mach_o_reader(in, message_handler);
250252
if(mach_o_reader.has_section("goto-cc"))
251253
return true;
252254
}

0 commit comments

Comments
 (0)