cprover
osx_fat_reader.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Read Mach-O
4 
5 Author:
6 
7 \*******************************************************************/
8 
11 
12 #include "osx_fat_reader.h"
13 
14 #include <cstdlib>
15 #include <util/exception_utils.h>
16 #include <util/invariant.h>
17 
18 #ifdef __APPLE__
19 #include <mach-o/fat.h>
20 #endif
21 
22 #include <util/run.h>
23 
24 bool is_osx_fat_magic(char hdr[4])
25 {
26 #ifdef __APPLE__
27  uint32_t *magic=reinterpret_cast<uint32_t*>(hdr);
28 
29  switch(*magic)
30  {
31  case FAT_MAGIC:
32  case FAT_CIGAM:
33  return true;
34  }
35 #else
36  (void)hdr; // unused parameter
37 #endif
38 
39  return false;
40 }
41 
43  has_gb_arch(false)
44 {
45 #ifdef __APPLE__
46  // NOLINTNEXTLINE(readability/identifiers)
47  struct fat_header fh;
48  // NOLINTNEXTLINE(readability/identifiers)
49  in.read(reinterpret_cast<char*>(&fh), sizeof(struct fat_header));
50 
51  if(!in)
52  throw system_exceptiont("failed to read OSX fat header");
53 
54  if(!is_osx_fat_magic(reinterpret_cast<char*>(&(fh.magic))))
55  throw deserialization_exceptiont("OSX fat header malformed (magic)");
56 
57  static_assert(
58  sizeof(fh.nfat_arch) == 4, "fat_header::nfat_arch is of type uint32_t");
59  unsigned narch=__builtin_bswap32(fh.nfat_arch);
60 
61  for(unsigned i=0; !has_gb_arch && i<narch; ++i)
62  {
63  // NOLINTNEXTLINE(readability/identifiers)
64  struct fat_arch fa;
65  // NOLINTNEXTLINE(readability/identifiers)
66  in.read(reinterpret_cast<char*>(&fa), sizeof(struct fat_arch));
67 
68  static_assert(
69  sizeof(fa.cputype) == 4 && sizeof(fa.cpusubtype) == 4 &&
70  sizeof(fa.size) == 4,
71  "This requires a specific fat architecture");
72  int cputype=__builtin_bswap32(fa.cputype);
73  int cpusubtype=__builtin_bswap32(fa.cpusubtype);
74  unsigned size=__builtin_bswap32(fa.size);
75 
76  has_gb_arch=cputype==CPU_TYPE_HPPA &&
77  cpusubtype==CPU_SUBTYPE_HPPA_7100LC &&
78  size > 0;
79  }
80 #else
81  (void)in; // unused parameter
82 #endif
83 }
84 
86  const std::string &source,
87  const std::string &dest) const
88 {
90 
91  return run(
92  "lipo", {"lipo", "-thin", "hppa7100LC", "-output", dest, source}) !=
93  0;
94 }
exception_utils.h
PRECONDITION
#define PRECONDITION(CONDITION)
Definition: invariant.h:438
deserialization_exceptiont
Thrown when failing to deserialize a value from some low level format, like JSON or raw bytes.
Definition: exception_utils.h:72
osx_fat_reader.h
run
int run(const std::string &what, const std::vector< std::string > &argv)
Definition: run.cpp:47
invariant.h
run.h
system_exceptiont
Thrown when some external system fails unexpectedly.
Definition: exception_utils.h:60
osx_fat_readert::osx_fat_readert
osx_fat_readert(std::ifstream &in)
Definition: osx_fat_reader.cpp:42
osx_fat_readert::extract_gb
bool extract_gb(const std::string &source, const std::string &dest) const
Definition: osx_fat_reader.cpp:85
__builtin_bswap32
unsigned int __builtin_bswap32(unsigned int)
is_osx_fat_magic
bool is_osx_fat_magic(char hdr[4])
Definition: osx_fat_reader.cpp:24
osx_fat_readert::has_gb_arch
bool has_gb_arch
Definition: osx_fat_reader.h:33