Skip to content

Commit c7e8bcc

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 d155d87 commit c7e8bcc

File tree

3 files changed

+53
-29
lines changed

3 files changed

+53
-29
lines changed

src/goto-programs/osx_fat_reader.cpp

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,35 +15,49 @@ 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) || \
36+
(CPROVER_MH_CIGAM_64 != MH_CIGAM_64)
37+
# error "Mach-O magic has inconsistent value"
38+
# endif
2339
#endif
2440

2541
#include <util/run.h>
2642

2743
bool is_osx_fat_magic(char hdr[4])
2844
{
29-
#ifdef __APPLE__
3045
uint32_t *magic=reinterpret_cast<uint32_t*>(hdr);
3146

3247
switch(*magic)
3348
{
34-
case FAT_MAGIC:
35-
case FAT_CIGAM:
36-
return true;
49+
case CPROVER_FAT_MAGIC:
50+
case CPROVER_FAT_CIGAM:
51+
return true;
3752
}
38-
#else
39-
(void)hdr; // unused parameter
40-
#endif
4153

4254
return false;
4355
}
4456

45-
osx_fat_readert::osx_fat_readert(std::ifstream &in) :
46-
has_gb_arch(false)
57+
osx_fat_readert::osx_fat_readert(
58+
std::ifstream &in,
59+
message_handlert &message_handler)
60+
: log(message_handler), has_gb_arch(false)
4761
{
4862
#ifdef __APPLE__
4963
// NOLINTNEXTLINE(readability/identifiers)
@@ -82,6 +96,9 @@ osx_fat_readert::osx_fat_readert(std::ifstream &in) :
8296
}
8397
#else
8498
(void)in; // unused parameter
99+
100+
log.warning() << "Cannot read OSX fat archive on this platform"
101+
<< messaget::eom;
85102
#endif
86103
}
87104

@@ -99,20 +116,16 @@ bool osx_fat_readert::extract_gb(
99116
// guided by https://lowlevelbits.org/parsing-mach-o-files/
100117
bool is_osx_mach_object(char hdr[4])
101118
{
102-
#ifdef __APPLE__
103119
uint32_t *magic = reinterpret_cast<uint32_t *>(hdr);
104120

105121
switch(*magic)
106122
{
107-
case MH_MAGIC:
108-
case MH_CIGAM:
109-
case MH_MAGIC_64:
110-
case MH_CIGAM_64:
123+
case CPROVER_MH_MAGIC:
124+
case CPROVER_MH_CIGAM:
125+
case CPROVER_MH_MAGIC_64:
126+
case CPROVER_MH_CIGAM_64:
111127
return true;
112128
}
113-
#else
114-
(void)hdr; // unused parameter
115-
#endif
116129

117130
return false;
118131
}
@@ -236,7 +249,10 @@ void osx_mach_o_readert::process_commands(
236249
#endif
237250
}
238251

239-
osx_mach_o_readert::osx_mach_o_readert(std::istream &_in) : in(_in)
252+
osx_mach_o_readert::osx_mach_o_readert(
253+
std::istream &_in,
254+
message_handlert &message_handler)
255+
: log(message_handler), in(_in)
240256
{
241257
// read magic
242258
uint32_t magic;
@@ -249,16 +265,16 @@ osx_mach_o_readert::osx_mach_o_readert(std::istream &_in) : in(_in)
249265
bool is_64 = false, need_swap = false;
250266
switch(magic)
251267
{
252-
case MH_CIGAM:
268+
case CPROVER_MH_CIGAM:
253269
need_swap = true;
254270
break;
255-
case MH_MAGIC:
271+
case CPROVER_MH_MAGIC:
256272
break;
257-
case MH_CIGAM_64:
273+
case CPROVER_MH_CIGAM_64:
258274
need_swap = true;
259275
is_64 = true;
260276
break;
261-
case MH_MAGIC_64:
277+
case CPROVER_MH_MAGIC_64:
262278
is_64 = true;
263279
break;
264280
default:
@@ -303,5 +319,7 @@ osx_mach_o_readert::osx_mach_o_readert(std::istream &_in) : in(_in)
303319
}
304320

305321
process_commands(ncmds, offset, need_swap);
322+
#else
323+
log.warning() << "Cannot read OSX Mach-O on this platform" << messaget::eom;
306324
#endif
307325
}

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)