1212#include " ThreadWriter.h"
1313#include " Utility.h"
1414#include " llvm/BinaryFormat/MachO.h"
15+ #include " llvm/Support/CommandLine.h"
1516#include < getopt.h>
1617#include < stdio.h>
1718#include < string>
1819#include < sys/stat.h>
1920
20- [[noreturn]] void print_help (void ) {
21- fprintf (stderr, " Create a Mach-O corefile from a YAML register and memory "
22- " description.\n " );
23- fprintf (stderr, " Usage:\n " );
24- fprintf (stderr, " -i|--input <yaml spec>\n " );
25- fprintf (stderr, " -o|--output <corefile name>\n " );
26- fprintf (stderr, " -u|--uuids <uuid,uuid,uuid>\n " );
27- fprintf (stderr, " -L|--uuids-and-load-addrs <uuid,vaddr,uuid,vaddr>\n " );
28- fprintf (stderr,
29- " -A|--address-bits <number of bits valid for addressing>\n " );
30- fprintf (stderr, " Add LC_NOTE 'load binary' for those UUIDs, "
31- " at slide 0.\n " );
32- exit (1 );
33- }
34-
3521std::vector<std::string> get_fields_from_delimited_string (std::string str,
3622 const char delim) {
3723 std::vector<std::string> result;
@@ -54,101 +40,77 @@ std::vector<std::string> get_fields_from_delimited_string(std::string str,
5440 return result;
5541}
5642
57- int main (int argc, char **argv) {
43+ llvm::cl::opt<std::string> InputFilename (" i" , llvm::cl::Required,
44+ llvm::cl::desc (" input yaml filename" ),
45+ llvm::cl::value_desc(" input" ));
46+ llvm::cl::opt<std::string>
47+ OutputFilename (" o" , llvm::cl::Required,
48+ llvm::cl::desc (" output core filenames" ),
49+ llvm::cl::value_desc(" output" ));
50+ llvm::cl::list<std::string>
51+ UUIDs (" u" , llvm::cl::desc(" uuid of binary loaded at slide 0" ),
52+ llvm::cl::value_desc(" uuid" ));
53+ llvm::cl::list<std::string>
54+ UUIDAndVAs (" L" , llvm::cl::desc(" UUID,virtual-address-loaded-at" ),
55+ llvm::cl::value_desc(" --uuid-and-load-addr" ));
56+ llvm::cl::opt<int >
57+ AddressableBitsOverride (" A" ,
58+ llvm::cl::desc (" number of bits used in addressing" ),
59+ llvm::cl::value_desc(" --address-bits" ));
5860
59- const char *const short_opts = " i:o:u:L:A:h" ;
60- const option long_opts[] = {
61- {" input" , required_argument, nullptr , ' i' },
62- {" output" , required_argument, nullptr , ' o' },
63- {" uuids" , required_argument, nullptr , ' u' },
64- {" uuids-and-load-addrs" , required_argument, nullptr , ' L' },
65- {" address-bits" , required_argument, nullptr , ' A' },
66- {" help" , no_argument, nullptr , ' h' },
67- {nullptr , no_argument, nullptr , 0 }};
61+ int main (int argc, char **argv) {
62+ llvm::cl::ParseCommandLineOptions (argc, argv);
6863
69- std::optional<std::string> infile, outfile;
70- std::optional<std::vector<std::string>> uuids;
71- std::optional<std::vector<std::string>> uuids_with_load_addrs;
72- std::optional<std::string> address_bits;
73- while (true ) {
74- const auto opt = getopt_long (argc, argv, short_opts, long_opts, nullptr );
75- if (opt == -1 )
76- break ;
77- switch (opt) {
78- case ' i' :
79- infile = optarg;
80- break ;
81- case ' o' :
82- outfile = optarg;
83- break ;
84- case ' u' :
85- uuids = get_fields_from_delimited_string (optarg, ' ,' );
86- break ;
87- case ' L' :
88- uuids_with_load_addrs = get_fields_from_delimited_string (optarg, ' ,' );
89- break ;
90- case ' A' :
91- address_bits = optarg;
92- break ;
93- case ' h' :
94- print_help ();
95- }
64+ if (InputFilename.empty () || OutputFilename.empty ()) {
65+ fprintf (stderr, " Missing input or outpur file.\n " );
66+ exit (1 );
9667 }
9768
98- if (!infile || !outfile)
99- print_help ();
100-
101- if (uuids_with_load_addrs && uuids_with_load_addrs->size () % 2 != 0 ) {
102- fprintf (stderr, " --uids-and-load-addrs should be comma separated list of "
103- " uuid,load addr for one or more tuples.\n " );
104- print_help ();
105- }
10669 struct stat sb;
10770
108- if (stat (infile-> c_str (), &sb) == -1 ) {
109- fprintf (stderr, " Unable to stat %s, exiting\n " , infile-> c_str ());
71+ if (stat (InputFilename. c_str (), &sb) == -1 ) {
72+ fprintf (stderr, " Unable to stat %s, exiting\n " , InputFilename. c_str ());
11073 exit (1 );
11174 }
11275
113- FILE *input = fopen (infile-> c_str (), " r" );
76+ FILE *input = fopen (InputFilename. c_str (), " r" );
11477 if (!input) {
115- fprintf (stderr, " Unable to open %s, exiting\n " , infile-> c_str ());
78+ fprintf (stderr, " Unable to open %s, exiting\n " , InputFilename. c_str ());
11679 exit (1 );
11780 }
11881 auto file_corespec = std::make_unique<char []>(sb.st_size );
11982 if (fread (file_corespec.get (), sb.st_size , 1 , input) != 1 ) {
120- fprintf (stderr, " Unable to read all of %s, exiting\n " , infile->c_str ());
83+ fprintf (stderr, " Unable to read all of %s, exiting\n " ,
84+ InputFilename.c_str ());
12185 exit (1 );
12286 }
12387 CoreSpec spec = from_yaml (file_corespec.get (), sb.st_size );
12488 fclose (input);
12589
126- if (uuids)
127- for (const std::string &uuid : *uuids) {
128- Binary binary;
129- binary.uuid = uuid;
130- binary.value = 0 ;
131- binary.value_is_slide = true ;
132- spec.binaries .push_back (binary);
133- }
90+ for (const std::string &uuid : UUIDs) {
91+ Binary binary;
92+ binary.uuid = uuid;
93+ binary.value = 0 ;
94+ binary.value_is_slide = true ;
95+ spec.binaries .push_back (binary);
96+ }
13497
135- if (uuids_with_load_addrs) {
136- int count = uuids_with_load_addrs->size () / 2 ;
137- for (int i = 0 ; i < count; i++) {
138- std::string uuid = uuids_with_load_addrs->at (i * 2 );
139- std::string va_str = uuids_with_load_addrs->at ((i * 2 ) + 1 );
140- uint64_t va = std::strtoull (va_str.c_str (), nullptr , 16 );
141- Binary binary;
142- binary.uuid = uuid;
143- binary.value = va;
144- binary.value_is_slide = false ;
145- spec.binaries .push_back (binary);
146- }
98+ for (const std::string &uuid_and_va : UUIDAndVAs) {
99+ std::vector<std::string> parts =
100+ get_fields_from_delimited_string (uuid_and_va, ' ,' );
101+
102+ std::string uuid = parts[0 ];
103+ uint64_t va = std::strtoull (parts[1 ].c_str (), nullptr , 16 );
104+ Binary binary;
105+ binary.uuid = uuid;
106+ binary.value = va;
107+ binary.value_is_slide = false ;
108+ spec.binaries .push_back (binary);
147109 }
148110
149- if (address_bits ) {
111+ if (AddressableBitsOverride ) {
150112 AddressableBits bits;
151- bits.lowmem_bits = bits.highmem_bits = std::stoi (*address_bits) ;
113+ bits.lowmem_bits = bits.highmem_bits = AddressableBitsOverride ;
152114 spec.addressable_bits = bits;
153115 }
154116
@@ -237,9 +199,10 @@ int main(int argc, char **argv) {
237199 if (lc_note_payload_bytes.size () > 0 )
238200 payload_fileoff = (payload_fileoff + 4096 - 1 ) & ~(4096 - 1 );
239201
240- FILE *f = fopen (outfile-> c_str (), " w" );
202+ FILE *f = fopen (OutputFilename. c_str (), " w" );
241203 if (f == nullptr ) {
242- fprintf (stderr, " Unable to open file %s for writing\n " , outfile->c_str ());
204+ fprintf (stderr, " Unable to open file %s for writing\n " ,
205+ OutputFilename.c_str ());
243206 exit (1 );
244207 }
245208
0 commit comments