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