cprover
ld_cmdline.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: A special command line object for the ld-like options
4 
5 Author: Daniel Kroening, 2013
6 
7 \*******************************************************************/
8 
11 
12 #include "ld_cmdline.h"
13 
14 #include <cassert>
15 #include <iostream>
16 
17 #include <util/prefix.h>
18 
23 {
24  "--verbosity",
25  "--native-compiler",
26  "--native-linker",
27  nullptr
28 };
29 
31 {
32  "-a",
33  "--architecture",
34  "-A",
35  "--format",
36  "-b",
37  "--mri-script",
38  "-c",
39  "--entry",
40  "-e",
41  "--auxiliary",
42  "-f",
43  "--filter",
44  "-F",
45  "--gpsize",
46  "-G",
47  "--soname",
48  "-h",
49  "--dynamic-linker",
50  "-I",
51  "--library",
52  "-l",
53  "--library-path",
54  "-L",
55  "--sysroot",
56  "-m",
57  "--output",
58  "-o",
59  "-O",
60  "--plugin",
61  "--plugin-opt",
62  "--flto-partition",
63  "--just-symbols",
64  "-R",
65  "--script",
66  "-T",
67  "--default-script",
68  "--dT",
69  "--undefined",
70  "-u",
71  "--trace-symbol",
72  "-y",
73  "-Y",
74  "--assert",
75  "--defsym",
76  "--fini",
77  "--hash-size",
78  "--init",
79  "--Map",
80  "--oformat",
81  "--retain-symbols-file",
82  "--rpath",
83  "--rpath-link",
84  "--sort-section",
85  "--spare-dynamic-tags",
86  "--task-link",
87  "--section-start",
88  "--Tbss",
89  "--Tdata",
90  "--Ttext",
91  "--Ttext-segment",
92  "--unresolved-symbols",
93  "--version-exports-section",
94  "--dynamic-list",
95  "--wrap",
96  "--hash-style",
97  "-z",
98  "--arch", // Apple only
99  "--ios_version_min", // Apple only
100  "--macosx_version_min", // Apple only
101  "--install_name", // Apple only
102  nullptr
103 };
104 
106 {
107  "--dc",
108  "-d",
109  "--dp",
110  "--export-dynamic",
111  "-E",
112  "--no-export-dynamic",
113  "--EB",
114  "--EL",
115  "-g",
116  "--print-map",
117  "-M",
118  "--nmagic",
119  "-n",
120  "--omagic",
121  "-N",
122  "--no-omagic",
123  "--flto",
124  "--Qy",
125  "--emit-relocs",
126  "-q",
127  "--relocatable",
128  "-r",
129  "-i",
130  "--strip-all",
131  "-s",
132  "--strip-debug",
133  "-S",
134  "--strip-discarded",
135  "--no-strip-discarded",
136  "--trace",
137  "-t",
138  "--unique",
139  "--Ur",
140  "--version",
141  "-v",
142  "-V",
143  "--discard-all",
144  "-x",
145  "--discard-locals",
146  "-X",
147  "--discard-none",
148  "--start-group",
149  "-(",
150  "--end-group",
151  "-)",
152  "--accept-unknown-input-arch",
153  "--no-accept-unknown-input-arch",
154  "--add-needed",
155  "--no-add-needed",
156  "--as-needed",
157  "--no-as-needed",
158  "--Bdynamic",
159  "--dy",
160  "--call_shared",
161  "--Bstatic",
162  "--dn",
163  "--non_shared",
164  "--static",
165  "--Bsymbolic",
166  "--Bsymbolic-functions",
167  "--check-sections",
168  "--no-check-sections",
169  "--copy-dt-needed-entries",
170  "--no-copy-dt-needed-entries",
171  "--cref",
172  "--demangle",
173  "--embedded-relocs",
174  "--fatal-warnings",
175  "--no-fatal-warnings",
176  "--force-exe-suffix",
177  "--gc-sections",
178  "--no-gc-sections",
179  "--print-gc-sections",
180  "--no-print-gc-sections",
181  "--help",
182  "--no-define-common",
183  "--no-demangle",
184  "--no-keep-memory",
185  "--no-undefined",
186  "--allow-shlib-undefined",
187  "--no-allow-shlib-undefined",
188  "--allow-multiple-definition",
189  "--no-undefined-version",
190  "--default-symver",
191  "--default-imported-symver",
192  "--no-warn-mismatch",
193  "--no-warn-search-mismatch",
194  "--no-whole-archive",
195  "--noinhibit-exec",
196  "--noinhibit_exec",
197  "--nostdlib",
198  "--print-output-format",
199  "--qmagic",
200  "--reduce-memory-overheads",
201  "--relax",
202  "--no-relax",
203  "--shared",
204  "--Bshareable",
205  "--pie",
206  "--pic-executable",
207  "--sort-common",
208  "--sort_common",
209  "--split-by-file",
210  "--split-by-reloc",
211  "--stats",
212  "--target-help",
213  "--traditional-format",
214  "--verbose",
215  "--dll-verbose",
216  "--version-script",
217  "--dynamic-list-data",
218  "--dynamic-list-cpp-new",
219  "--dynamic-list-cpp-typeinfo",
220  "--warn-common",
221  "--warn-constructors",
222  "--warn-multiple-gp",
223  "--warn-once",
224  "--warn-section-align",
225  "--warn-shared-textrel",
226  "--warn-alternate-em",
227  "--warn-unresolved-symbols",
228  "--error-unresolved-symbols",
229  "--whole-archive",
230  "--build-id",
231  "--eh-frame-hdr",
232  "--enable-new-dtags",
233  "--dylib", // Apple only
234  "--dylinker", // Apple only
235  "--bundle", // Apple only
236  nullptr
237 };
238 
239 bool ld_cmdlinet::parse(int argc, const char **argv)
240 {
241  assert(argc>0);
242  add_arg(argv[0]);
243 
244  for(int i=1; i<argc; i++)
245  {
246  std::string argv_i=argv[i];
247 
248  // options file?
249  if(has_prefix(argv_i, "@"))
250  {
251  // TODO
252  continue;
253  }
254 
255  // file?
256  if(argv_i=="-" || !has_prefix(argv_i, "-"))
257  {
258  add_infile_arg(argv_i);
259  continue;
260  }
261 
262  bool found=false;
263 
264  for(const char **o=goto_ld_options_with_argument;
265  *o!=nullptr && !found;
266  ++o)
267  {
268  std::string os(*o);
269 
270  // separated?
271  if(argv_i==os ||
272  (os.size()>=3 && os[0]=='-' && os[1]=='-' && "-"+argv_i==os))
273  {
274  found=true;
275  if(i!=argc-1)
276  {
277  set(os, argv[i+1]);
278  i++;
279  }
280  else
281  {
282  std::cerr << "Warning: missing argument for " << argv_i << '\n';
283  set(os, ""); // end of command line
284  }
285  }
286  else if(os.size()>2 && has_prefix(argv_i, os+"=")) // concatenated, long
287  {
288  found=true;
289  set(os, argv[i]+os.size()+1);
290  }
291  }
292 
293  // goto-ld-only command line argument found
294  if(found)
295  continue;
296 
297  // add to new_argv
298  add_arg(argv_i);
299 
300  // also store in cmdlinet
301 
302  for(const char **o=ld_options_without_argument; *o!=nullptr && !found; o++)
303  {
304  std::string os(*o);
305  // ld accepts all long options also as short option
306  if(argv_i==os ||
307  (os.size()>=3 && os[0]=='-' && os[1]=='-' && "-"+argv_i==os))
308  {
309  found=true;
310  set(os); // record as long
311  }
312  }
313 
314  // arguments to options can be given as follows:
315  // 1) concatenated for short options
316  // 2) concatenated with '=' for long options
317  // 3) separate
318 
319  for(const char **o=ld_options_with_argument; *o!=nullptr && !found; o++)
320  {
321  std::string os(*o);
322 
323  // separated?
324  if(argv_i==os ||
325  (os.size()>=3 && os[0]=='-' && os[1]=='-' && "-"+argv_i==os))
326  {
327  found=true;
328  if(i!=argc-1)
329  {
330  set(os, argv[i+1]);
331  add_arg(argv[i+1]);
332  i++;
333  }
334  else
335  {
336  std::cerr << "Warning: missing argument for " << argv_i << '\n';
337  set(os, ""); // end of command line
338  }
339  }
340  else if(os.size()==2 && has_prefix(argv_i, os)) // concatenated, short
341  {
342  found=true;
343  set(os, argv[i]+os.size());
344  }
345  else if(os.size()>2 && has_prefix(argv_i, os+"=")) // concatenated, long
346  {
347  found=true;
348  set(os, argv[i]+os.size()+1);
349  }
350  // concatenated, long as short
351  else if(os.size()>2 && has_prefix("-"+argv_i, os+"="))
352  {
353  found=true;
354  set(os, argv[i]+os.size()+1-1);
355  }
356  }
357 
358  if(!found)
359  {
360  // unrecognized option
361  std::cerr << "Warning: uninterpreted ld option '" << argv_i
362  << "'\n";
363  }
364  }
365 
366  return false;
367 }
const char * ld_options_without_argument[]
Definition: ld_cmdline.cpp:105
virtual bool parse(int, const char **)
Definition: ld_cmdline.cpp:239
A special command line object for the ld-like options.
void add_arg(const std::string &arg)
bool has_prefix(const std::string &s, const std::string &prefix)
Definition: converter.cpp:13
const char * ld_options_with_argument[]
Definition: ld_cmdline.cpp:30
const char * goto_ld_options_with_argument[]
parses the command line options into a cmdlinet
Definition: ld_cmdline.cpp:22
void add_infile_arg(const std::string &arg)