19 #define CPROVER_FAT_MAGIC 0xcafebabe
20 #define CPROVER_FAT_CIGAM 0xbebafeca
21 #define CPROVER_MH_MAGIC 0xfeedface
22 #define CPROVER_MH_CIGAM 0xcefaedfe
23 #define CPROVER_MH_MAGIC_64 0xfeedfacf
24 #define CPROVER_MH_CIGAM_64 0xcffaedfe
27 # include <architecture/byte_order.h>
28 # include <mach-o/fat.h>
29 # include <mach-o/loader.h>
30 # include <mach-o/swap.h>
32 # if(CPROVER_FAT_MAGIC != FAT_MAGIC) || (CPROVER_FAT_CIGAM != FAT_CIGAM) || \
33 (CPROVER_MH_MAGIC != MH_MAGIC) || (CPROVER_MH_CIGAM != MH_CIGAM) || \
34 (CPROVER_MH_MAGIC_64 != MH_MAGIC_64) || \
35 (CPROVER_MH_CIGAM_64 != MH_CIGAM_64)
36 # error "Mach-O magic has inconsistent value"
50 const uint8_t *input_as_bytes =
reinterpret_cast<uint8_t *
>(&input);
51 return (((uint32_t)input_as_bytes[0]) << 24) |
52 (((uint32_t)input_as_bytes[1]) << 16) |
53 (((uint32_t)input_as_bytes[2]) << 8) |
54 (((uint32_t)input_as_bytes[3]) << 0);
68 uint32_t n_architectures_native =
71 n_architectures_native >= 1 && n_architectures_native < 20;
77 :
log(message_handler), has_gb_arch(false)
83 in.read(
reinterpret_cast<char*
>(&fh),
sizeof(
struct fat_header));
88 static_assert(
sizeof(fh) >= 8,
"fat_header is at least 8 bytes");
93 sizeof(fh.nfat_arch) == 4,
"fat_header::nfat_arch is of type uint32_t");
101 in.read(
reinterpret_cast<char*
>(&fa),
sizeof(
struct fat_arch));
104 sizeof(fa.cputype) == 4 &&
sizeof(fa.cpusubtype) == 4 &&
105 sizeof(fa.size) == 4,
106 "This requires a specific fat architecture");
112 cpusubtype==CPU_SUBTYPE_HPPA_7100LC &&
118 log.
warning() <<
"Cannot read OSX fat archive on this platform"
124 const std::string &source,
125 const std::string &dest)
const
130 "lipo", {
"lipo",
"-thin",
"hppa7100LC",
"-output", dest, source}) !=
137 uint32_t *magic =
reinterpret_cast<uint32_t *
>(hdr);
154 for(uint32_t i = 0; i < nsects; ++i)
158 in.read(
reinterpret_cast<char *
>(&s),
sizeof(s));
164 swap_section(&s, 1, NXHostByteOrder());
178 for(uint32_t i = 0; i < nsects; ++i)
182 in.read(
reinterpret_cast<char *
>(&s),
sizeof(s));
188 swap_section_64(&s, 1, NXHostByteOrder());
205 for(uint32_t i = 0; i < ncmds; ++i)
210 struct load_command lc;
211 in.read(
reinterpret_cast<char *
>(&lc),
sizeof(lc));
217 swap_load_command(&lc, NXHostByteOrder());
229 struct segment_command seg;
230 in.read(
reinterpret_cast<char *
>(&seg),
sizeof(seg));
236 swap_segment_command(&seg, NXHostByteOrder());
244 struct segment_command_64 seg;
245 in.read(
reinterpret_cast<char *
>(&seg),
sizeof(seg));
251 swap_segment_command_64(&seg, NXHostByteOrder());
260 offset += lc.cmdsize;
273 :
log(message_handler), in(_in)
277 in.read(
reinterpret_cast<char *
>(&magic),
sizeof(magic));
283 bool is_64 =
false, need_swap =
false;
303 std::size_t offset = 0;
311 struct mach_header mh;
312 in.read(
reinterpret_cast<char *
>(&mh),
sizeof(mh));
318 swap_mach_header(&mh, NXHostByteOrder());
326 struct mach_header_64 mh;
327 in.read(
reinterpret_cast<char *
>(&mh),
sizeof(mh));
333 swap_mach_header_64(&mh, NXHostByteOrder());
Thrown when failing to deserialize a value from some low level format, like JSON or raw bytes.
mstreamt & warning() const
osx_fat_readert(std::ifstream &, message_handlert &)
bool extract_gb(const std::string &source, const std::string &dest) const
void process_commands(uint32_t ncmds, std::size_t offset, bool need_swap)
osx_mach_o_readert(std::istream &, message_handlert &)
void process_sections_32(uint32_t nsects, bool need_swap)
void process_sections_64(uint32_t nsects, bool need_swap)
Thrown when some external system fails unexpectedly.
bool is_osx_fat_header(char header_bytes[8])
#define CPROVER_FAT_MAGIC
static uint32_t u32_to_native_endian(uint32_t input)
#define CPROVER_MH_MAGIC_64
bool is_osx_mach_object(char hdr[4])
#define CPROVER_MH_CIGAM_64
int run(const std::string &what, const std::vector< std::string > &argv)
#define PRECONDITION(CONDITION)