llvm.org GIT mirror llvm / f6ea129 tools / llvm-readobj / llvm-readobj.cpp
f6ea129

Tree @f6ea129 (Download .tar.gz)

llvm-readobj.cpp @f6ea129

a9232f7
5c2b4ea
 
 
 
 
 
 
 
dd3aa9e
 
 
ee37b6e
dd3aa9e
 
 
ee37b6e
dd3aa9e
ee37b6e
 
5c2b4ea
d326d05
76e70f3
 
96bd923
47856b2
76e70f3
40e2251
71be19d
f010c46
96bd923
76e70f3
5c2b4ea
76e70f3
5c2b4ea
76e70f3
5248326
0b9d56a
f144b00
2448e9f
76e70f3
 
5c2b4ea
 
 
76e70f3
 
 
 
 
6856bcc
 
 
 
 
 
 
 
 
cd44df2
 
 
 
 
 
 
 
35375a3
6856bcc
 
 
35375a3
 
 
 
6856bcc
76e70f3
 
6856bcc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76e70f3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6856bcc
76e70f3
 
6856bcc
 
 
 
76e70f3
b899d19
 
 
 
4cbb2db
 
 
 
6856bcc
 
76e70f3
 
6856bcc
 
76e70f3
6856bcc
76e70f3
 
 
 
 
6856bcc
 
76e70f3
 
 
 
 
 
 
 
6856bcc
76e70f3
 
ddff628
6856bcc
 
ddff628
76e70f3
 
 
 
1c8dfa5
6856bcc
cf3b55a
 
ddff628
6856bcc
 
 
cf3b55a
6856bcc
064db43
 
 
 
 
6856bcc
94b0940
 
 
 
 
8109763
 
 
 
4598154
 
 
 
1c8dfa5
 
 
e493a99
eefdbb4
 
 
 
2371901
 
 
 
fed38e2
 
 
 
 
2371901
 
 
 
459c949
6856bcc
459c949
 
42469f6
 
 
 
 
f3cd10b
ef7c256
 
 
 
3bcfd46
 
 
 
125d646
 
 
 
f3cd10b
 
 
db02fa5
b19a485
 
 
 
db02fa5
 
 
6272b8c
 
 
 
 
 
63f4054
fb1a911
 
 
 
 
224acd2
 
 
 
367f21d
 
 
 
 
e7676fe
 
 
 
 
241f716
 
 
 
 
7ab2009
 
 
 
 
793616c
 
 
 
 
885eb98
 
 
 
 
7dbe74f
 
 
 
19c43a6
 
 
 
 
 
63f4054
 
 
 
 
6856bcc
c813f4c
 
 
 
 
8822b47
6856bcc
8822b47
 
6856bcc
 
 
8822b47
 
6856bcc
 
14dddbf
 
 
 
 
6856bcc
 
 
8822b47
6856bcc
56500c7
 
6856bcc
38b60af
a29ff2e
 
6856bcc
9645a0d
54f4d3a
 
3ffe113
54f4d3a
76e70f3
 
fa1a4b2
 
f671210
b98f7ad
 
d60ced8
b9adbd9
 
3483f21
92cd0ec
 
 
3483f21
92cd0ec
 
d60ced8
76e70f3
d60ced8
8a0ff18
148ee4f
 
76e70f3
297f505
fc73847
 
76e70f3
5c2b4ea
1ad4502
76e70f3
 
fc73847
b9adbd9
fc73847
 
aacf2fb
 
 
 
 
 
 
 
 
 
 
42469f6
 
 
 
 
 
 
 
 
 
 
be73fbc
7306956
d603192
 
42469f6
be73fbc
47856b2
 
be73fbc
 
7306956
fed38e2
0b24b74
2448e9f
 
1ad4502
76e70f3
 
 
 
 
 
 
 
 
c20099f
 
76e70f3
 
5c2b4ea
 
0b24b74
5248326
f4ccd11
3aa1034
76e70f3
fc73847
54f4d3a
5248326
 
 
 
 
 
 
54f4d3a
 
76e70f3
 
 
6856bcc
 
76e70f3
 
4cbb2db
 
76e70f3
 
 
 
 
 
 
 
 
 
cf3b55a
 
064db43
9f006d3
 
064db43
94b0940
cac968e
 
94b0940
8109763
 
4598154
 
c813f4c
 
8822b47
e7676fe
 
8822b47
 
 
 
 
 
 
 
 
 
125d646
 
8822b47
 
 
14dddbf
 
56500c7
 
a29ff2e
 
b899d19
 
ef7c256
c46ea19
 
 
 
 
 
 
 
 
fb1a911
 
224acd2
 
367f21d
 
38b60af
 
c81f000
 
fed38e2
d603192
c46ea19
6997c3a
241f716
 
7ab2009
 
793616c
 
885eb98
 
7dbe74f
 
19c43a6
 
6997c3a
63f4054
 
97f7787
 
0b24b74
5248326
df0b8bc
aacf2fb
77be094
 
 
2436e45
77be094
76e70f3
 
0659928
5248326
cec5045
5248326
76e70f3
 
5c2b4ea
aacf2fb
 
76e70f3
 
0b24b74
5248326
 
71be19d
e9ddf3a
2d35a46
5248326
e9ddf3a
2436e45
e9ddf3a
c827f2c
5248326
71be19d
 
5c2b4ea
0b24b74
96bd923
 
 
 
 
 
 
 
0b24b74
76e70f3
5248326
5c2b4ea
76e70f3
c6bf9be
 
2436e45
548f2b6
5c2b4ea
9aa0b5e
5248326
71be19d
 
5248326
9aa0b5e
5248326
40e2251
5248326
96bd923
 
76e70f3
 
 
87b47cc
6856bcc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76e70f3
0b9d56a
fc73847
76e70f3
 
 
6856bcc
f144b00
6856bcc
 
 
 
f144b00
76e70f3
d326d05
6856bcc
 
 
 
 
 
 
 
 
 
 
 
 
 
cd44df2
 
 
 
 
 
76e70f3
f6ea129
69d3274
 
 
 
 
 
d603192
fed38e2
 
d60ced8
5c2b4ea
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
//===- llvm-readobj.cpp - Dump contents of an Object File -----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This is a tool similar to readelf, except it works on multiple object file
// formats. The main purpose of this tool is to provide detailed output suitable
// for FileCheck.
//
// Flags should be similar to readelf where supported, but the output format
// does not need to be identical. The point is to not make users learn yet
// another set of flags.
//
// Output should be specialized for each format where appropriate.
//
//===----------------------------------------------------------------------===//

#include "llvm-readobj.h"
#include "Error.h"
#include "ObjDumper.h"
#include "WindowsResourceDumper.h"
#include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/COFFImportFile.h"
#include "llvm/Object/MachOUniversal.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/WindowsResource.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/TargetRegistry.h"

using namespace llvm;
using namespace llvm::object;

namespace opts {
  cl::list<std::string> InputFilenames(cl::Positional,
    cl::desc("<input object files>"),
    cl::ZeroOrMore);

  // -all, -a
  cl::opt<bool>
      All("all",
          cl::desc("Equivalent to setting: --file-headers, --program-headers, "
                   "--section-headers, --symbols, --relocations, "
                   "--dynamic-table, --notes, --version-info, --unwind, "
                   "--section-groups and --elf-hash-histogram."));
  cl::alias AllShort("a", cl::desc("Alias for --all"), cl::aliasopt(All));

  // --headers -e
  cl::opt<bool>
      Headers("headers",
          cl::desc("Equivalent to setting: --file-headers, --program-headers, "
                   "--section-headers"));
  cl::alias HeadersShort("e", cl::desc("Alias for --headers"),
     cl::aliasopt(Headers));

  // -wide, -W
  cl::opt<bool>
      WideOutput("wide", cl::desc("Ignored for compatibility with GNU readelf"),
                 cl::Hidden);
  cl::alias WideOutputShort("W",
    cl::desc("Alias for --wide"),
    cl::aliasopt(WideOutput));

  // -file-headers, -file-header, -h
  cl::opt<bool> FileHeaders("file-headers",
    cl::desc("Display file headers "));
  cl::alias FileHeadersShort("h", cl::desc("Alias for --file-headers"),
                             cl::aliasopt(FileHeaders), cl::NotHidden);
  cl::alias FileHeadersSingular("file-header",
                                cl::desc("Alias for --file-headers"),
                                cl::aliasopt(FileHeaders));

  // -section-headers, -sections, -S
  // Also -s in llvm-readobj mode.
  cl::opt<bool> SectionHeaders("section-headers",
                               cl::desc("Display all section headers."));
  cl::alias SectionsShortUpper("S", cl::desc("Alias for --section-headers"),
                               cl::aliasopt(SectionHeaders), cl::NotHidden);
  cl::alias SectionHeadersAlias("sections",
                                cl::desc("Alias for --section-headers"),
                                cl::aliasopt(SectionHeaders), cl::NotHidden);

  // -section-relocations, -sr
  cl::opt<bool> SectionRelocations("section-relocations",
    cl::desc("Display relocations for each section shown."));
  cl::alias SectionRelocationsShort("sr",
    cl::desc("Alias for --section-relocations"),
    cl::aliasopt(SectionRelocations));

  // -section-symbols, -st
  cl::opt<bool> SectionSymbols("section-symbols",
    cl::desc("Display symbols for each section shown."));
  cl::alias SectionSymbolsShort("st",
    cl::desc("Alias for --section-symbols"),
    cl::aliasopt(SectionSymbols));

  // -section-data, -sd
  cl::opt<bool> SectionData("section-data",
    cl::desc("Display section data for each section shown."));
  cl::alias SectionDataShort("sd",
    cl::desc("Alias for --section-data"),
    cl::aliasopt(SectionData));

  // -relocations, -relocs, -r
  cl::opt<bool> Relocations("relocations",
    cl::desc("Display the relocation entries in the file"));
  cl::alias RelocationsShort("r", cl::desc("Alias for --relocations"),
                             cl::aliasopt(Relocations), cl::NotHidden);
  cl::alias RelocationsGNU("relocs", cl::desc("Alias for --relocations"),
                           cl::aliasopt(Relocations));

  // -notes, -n
  cl::opt<bool> Notes("notes", cl::desc("Display the ELF notes in the file"));
  cl::alias NotesShort("n", cl::desc("Alias for --notes"), cl::aliasopt(Notes));

  // -dyn-relocations
  cl::opt<bool> DynRelocs("dyn-relocations",
    cl::desc("Display the dynamic relocation entries in the file"));

  // -symbols
  // Also -s in llvm-readelf mode, or -t in llvm-readobj mode.
  cl::opt<bool> Symbols("symbols",
    cl::desc("Display the symbol table"));
  cl::alias SymbolsGNU("syms", cl::desc("Alias for --symbols"),
                       cl::aliasopt(Symbols));

  // -dyn-symbols, -dyn-syms, -dt
  cl::opt<bool> DynamicSymbols("dyn-symbols",
    cl::desc("Display the dynamic symbol table"));
  cl::alias DynamicSymbolsShort("dt",
    cl::desc("Alias for --dyn-symbols"),
    cl::aliasopt(DynamicSymbols));
  cl::alias DynSymsGNU("dyn-syms", cl::desc("Alias for --dyn-symbols"),
                       cl::aliasopt(DynamicSymbols));

  // -unwind, -u
  cl::opt<bool> UnwindInfo("unwind",
    cl::desc("Display unwind information"));
  cl::alias UnwindInfoShort("u",
    cl::desc("Alias for --unwind"),
    cl::aliasopt(UnwindInfo));

  // -dynamic-table, -dynamic, -d
  cl::opt<bool> DynamicTable("dynamic-table",
    cl::desc("Display the ELF .dynamic section table"));
  cl::alias DynamicTableShort("d", cl::desc("Alias for --dynamic-table"),
                              cl::aliasopt(DynamicTable), cl::NotHidden);
  cl::alias DynamicTableAlias("dynamic", cl::desc("Alias for --dynamic-table"),
                              cl::aliasopt(DynamicTable));

  // -needed-libs
  cl::opt<bool> NeededLibraries("needed-libs",
    cl::desc("Display the needed libraries"));

  // -program-headers, -segments, -l
  cl::opt<bool> ProgramHeaders("program-headers",
    cl::desc("Display ELF program headers"));
  cl::alias ProgramHeadersShort("l", cl::desc("Alias for --program-headers"),
                                cl::aliasopt(ProgramHeaders), cl::NotHidden);
  cl::alias SegmentsAlias("segments", cl::desc("Alias for --program-headers"),
                          cl::aliasopt(ProgramHeaders));

  // -string-dump, -p
  cl::list<std::string> StringDump("string-dump", cl::desc("<number|name>"),
                                   cl::ZeroOrMore);
  cl::alias StringDumpShort("p", cl::desc("Alias for --string-dump"),
                            cl::aliasopt(StringDump));

  // -hex-dump, -x
  cl::list<std::string> HexDump("hex-dump", cl::desc("<number|name>"),
                                cl::ZeroOrMore);
  cl::alias HexDumpShort("x", cl::desc("Alias for --hex-dump"),
                         cl::aliasopt(HexDump));

  // -hash-table
  cl::opt<bool> HashTable("hash-table",
    cl::desc("Display ELF hash table"));

  // -gnu-hash-table
  cl::opt<bool> GnuHashTable("gnu-hash-table",
    cl::desc("Display ELF .gnu.hash section"));

  // -expand-relocs
  cl::opt<bool> ExpandRelocs("expand-relocs",
    cl::desc("Expand each shown relocation to multiple lines"));

  // -raw-relr
  cl::opt<bool> RawRelr("raw-relr",
    cl::desc("Do not decode relocations in SHT_RELR section, display raw contents"));

  // -codeview
  cl::opt<bool> CodeView("codeview",
                         cl::desc("Display CodeView debug information"));

  // -codeview-merged-types
  cl::opt<bool>
      CodeViewMergedTypes("codeview-merged-types",
                          cl::desc("Display the merged CodeView type stream"));

  // -codeview-subsection-bytes
  cl::opt<bool> CodeViewSubsectionBytes(
      "codeview-subsection-bytes",
      cl::desc("Dump raw contents of codeview debug sections and records"));

  // -arm-attributes
  cl::opt<bool> ARMAttributes("arm-attributes",
                              cl::desc("Display the ARM attributes section"));

  // -mips-plt-got
  cl::opt<bool>
  MipsPLTGOT("mips-plt-got",
             cl::desc("Display the MIPS GOT and PLT GOT sections"));

  // -mips-abi-flags
  cl::opt<bool> MipsABIFlags("mips-abi-flags",
                             cl::desc("Display the MIPS.abiflags section"));

  // -mips-reginfo
  cl::opt<bool> MipsReginfo("mips-reginfo",
                            cl::desc("Display the MIPS .reginfo section"));

  // -mips-options
  cl::opt<bool> MipsOptions("mips-options",
                            cl::desc("Display the MIPS .MIPS.options section"));

  // -coff-imports
  cl::opt<bool>
  COFFImports("coff-imports", cl::desc("Display the PE/COFF import table"));

  // -coff-exports
  cl::opt<bool>
  COFFExports("coff-exports", cl::desc("Display the PE/COFF export table"));

  // -coff-directives
  cl::opt<bool>
  COFFDirectives("coff-directives",
                 cl::desc("Display the PE/COFF .drectve section"));

  // -coff-basereloc
  cl::opt<bool>
  COFFBaseRelocs("coff-basereloc",
                 cl::desc("Display the PE/COFF .reloc section"));

  // -coff-debug-directory
  cl::opt<bool>
  COFFDebugDirectory("coff-debug-directory",
                     cl::desc("Display the PE/COFF debug directory"));

  // -coff-resources
  cl::opt<bool> COFFResources("coff-resources",
                              cl::desc("Display the PE/COFF .rsrc section"));

  // -coff-load-config
  cl::opt<bool>
  COFFLoadConfig("coff-load-config",
                 cl::desc("Display the PE/COFF load config"));

  // -elf-linker-options
  cl::opt<bool>
  ELFLinkerOptions("elf-linker-options",
                   cl::desc("Display the ELF .linker-options section"));

  // -macho-data-in-code
  cl::opt<bool>
  MachODataInCode("macho-data-in-code",
                  cl::desc("Display MachO Data in Code command"));

  // -macho-indirect-symbols
  cl::opt<bool>
  MachOIndirectSymbols("macho-indirect-symbols",
                  cl::desc("Display MachO indirect symbols"));

  // -macho-linker-options
  cl::opt<bool>
  MachOLinkerOptions("macho-linker-options",
                  cl::desc("Display MachO linker options"));

  // -macho-segment
  cl::opt<bool>
  MachOSegment("macho-segment",
                  cl::desc("Display MachO Segment command"));

  // -macho-version-min
  cl::opt<bool>
  MachOVersionMin("macho-version-min",
                  cl::desc("Display MachO version min command"));

  // -macho-dysymtab
  cl::opt<bool>
  MachODysymtab("macho-dysymtab",
                  cl::desc("Display MachO Dysymtab command"));

  // -stackmap
  cl::opt<bool>
  PrintStackMap("stackmap",
                cl::desc("Display contents of stackmap section"));

  // -version-info, -V
  cl::opt<bool>
      VersionInfo("version-info",
                  cl::desc("Display ELF version sections (if present)"));
  cl::alias VersionInfoShort("V", cl::desc("Alias for -version-info"),
                             cl::aliasopt(VersionInfo));

  // -elf-section-groups, -section-groups, -g
  cl::opt<bool> SectionGroups("elf-section-groups",
                              cl::desc("Display ELF section group contents"));
  cl::alias SectionGroupsAlias("section-groups",
                               cl::desc("Alias for -elf-sections-groups"),
                               cl::aliasopt(SectionGroups));
  cl::alias SectionGroupsShort("g", cl::desc("Alias for -elf-sections-groups"),
                               cl::aliasopt(SectionGroups));

  // -elf-hash-histogram, -histogram, -I
  cl::opt<bool> HashHistogram(
      "elf-hash-histogram",
      cl::desc("Display bucket list histogram for hash sections"));
  cl::alias HashHistogramShort("I", cl::desc("Alias for -elf-hash-histogram"),
                               cl::aliasopt(HashHistogram));
  cl::alias HistogramAlias("histogram",
                           cl::desc("Alias for --elf-hash-histogram"),
                           cl::aliasopt(HashHistogram));

  // -elf-cg-profile
  cl::opt<bool> CGProfile("elf-cg-profile", cl::desc("Display callgraph profile section"));

  // -addrsig
  cl::opt<bool> Addrsig("addrsig",
                        cl::desc("Display address-significance table"));

  // -elf-output-style
  cl::opt<OutputStyleTy>
      Output("elf-output-style", cl::desc("Specify ELF dump style"),
             cl::values(clEnumVal(LLVM, "LLVM default style"),
                        clEnumVal(GNU, "GNU readelf style")),
             cl::init(LLVM));
} // namespace opts

namespace llvm {

LLVM_ATTRIBUTE_NORETURN void reportError(Twine Msg) {
  errs() << "\nError reading file: " << Msg << ".\n";
  errs().flush();
  exit(1);
}

void error(Error EC) {
  if (!EC)
    return;
  handleAllErrors(std::move(EC),
                  [&](const ErrorInfoBase &EI) { reportError(EI.message()); });
}

void error(std::error_code EC) {
  if (!EC)
    return;
  reportError(EC.message());
}

bool relocAddressLess(RelocationRef a, RelocationRef b) {
  return a.getOffset() < b.getOffset();
}

} // namespace llvm

static void reportError(StringRef Input, std::error_code EC) {
  if (Input == "-")
    Input = "<stdin>";

  reportError(Twine(Input) + ": " + EC.message());
}

static void reportError(StringRef Input, Error Err) {
  if (Input == "-")
    Input = "<stdin>";
  std::string ErrMsg;
  {
    raw_string_ostream ErrStream(ErrMsg);
    logAllUnhandledErrors(std::move(Err), ErrStream, Input + ": ");
  }
  reportError(ErrMsg);
}

static bool isMipsArch(unsigned Arch) {
  switch (Arch) {
  case llvm::Triple::mips:
  case llvm::Triple::mipsel:
  case llvm::Triple::mips64:
  case llvm::Triple::mips64el:
    return true;
  default:
    return false;
  }
}
namespace {
struct ReadObjTypeTableBuilder {
  ReadObjTypeTableBuilder()
      : Allocator(), IDTable(Allocator), TypeTable(Allocator) {}

  llvm::BumpPtrAllocator Allocator;
  llvm::codeview::MergingTypeTableBuilder IDTable;
  llvm::codeview::MergingTypeTableBuilder TypeTable;
};
}
static ReadObjTypeTableBuilder CVTypes;

/// Creates an format-specific object file dumper.
static std::error_code createDumper(const ObjectFile *Obj,
                                    ScopedPrinter &Writer,
                                    std::unique_ptr<ObjDumper> &Result) {
  if (!Obj)
    return readobj_error::unsupported_file_format;

  if (Obj->isCOFF())
    return createCOFFDumper(Obj, Writer, Result);
  if (Obj->isELF())
    return createELFDumper(Obj, Writer, Result);
  if (Obj->isMachO())
    return createMachODumper(Obj, Writer, Result);
  if (Obj->isWasm())
    return createWasmDumper(Obj, Writer, Result);

  return readobj_error::unsupported_obj_file_format;
}

/// Dumps the specified object file.
static void dumpObject(const ObjectFile *Obj, ScopedPrinter &Writer) {
  std::unique_ptr<ObjDumper> Dumper;
  if (std::error_code EC = createDumper(Obj, Writer, Dumper))
    reportError(Obj->getFileName(), EC);

  if (opts::Output == opts::LLVM) {
    Writer.startLine() << "\n";
    Writer.printString("File", Obj->getFileName());
    Writer.printString("Format", Obj->getFileFormatName());
    Writer.printString("Arch", Triple::getArchTypeName(
                                   (llvm::Triple::ArchType)Obj->getArch()));
    Writer.printString("AddressSize",
                       formatv("{0}bit", 8 * Obj->getBytesInAddress()));
    Dumper->printLoadName();
  }

  if (opts::FileHeaders)
    Dumper->printFileHeaders();
  if (opts::SectionHeaders)
    Dumper->printSectionHeaders();
  if (opts::Relocations)
    Dumper->printRelocations();
  if (opts::DynRelocs)
    Dumper->printDynamicRelocations();
  if (opts::Symbols)
    Dumper->printSymbols();
  if (opts::DynamicSymbols)
    Dumper->printDynamicSymbols();
  if (opts::UnwindInfo)
    Dumper->printUnwindInfo();
  if (opts::DynamicTable)
    Dumper->printDynamicTable();
  if (opts::NeededLibraries)
    Dumper->printNeededLibraries();
  if (opts::ProgramHeaders)
    Dumper->printProgramHeaders();
  if (!opts::StringDump.empty())
    llvm::for_each(opts::StringDump, [&Dumper, Obj](StringRef SectionName) {
      Dumper->printSectionAsString(Obj, SectionName);
    });
  if (!opts::HexDump.empty())
    llvm::for_each(opts::HexDump, [&Dumper, Obj](StringRef SectionName) {
      Dumper->printSectionAsHex(Obj, SectionName);
    });
  if (opts::HashTable)
    Dumper->printHashTable();
  if (opts::GnuHashTable)
    Dumper->printGnuHashTable();
  if (opts::VersionInfo)
    Dumper->printVersionInfo();
  if (Obj->isELF()) {
    if (opts::ELFLinkerOptions)
      Dumper->printELFLinkerOptions();
    if (Obj->getArch() == llvm::Triple::arm)
      if (opts::ARMAttributes)
        Dumper->printAttributes();
    if (isMipsArch(Obj->getArch())) {
      if (opts::MipsPLTGOT)
        Dumper->printMipsPLTGOT();
      if (opts::MipsABIFlags)
        Dumper->printMipsABIFlags();
      if (opts::MipsReginfo)
        Dumper->printMipsReginfo();
      if (opts::MipsOptions)
        Dumper->printMipsOptions();
    }
    if (opts::SectionGroups)
      Dumper->printGroupSections();
    if (opts::HashHistogram)
      Dumper->printHashHistogram();
    if (opts::CGProfile)
      Dumper->printCGProfile();
    if (opts::Addrsig)
      Dumper->printAddrsig();
    if (opts::Notes)
      Dumper->printNotes();
  }
  if (Obj->isCOFF()) {
    if (opts::COFFImports)
      Dumper->printCOFFImports();
    if (opts::COFFExports)
      Dumper->printCOFFExports();
    if (opts::COFFDirectives)
      Dumper->printCOFFDirectives();
    if (opts::COFFBaseRelocs)
      Dumper->printCOFFBaseReloc();
    if (opts::COFFDebugDirectory)
      Dumper->printCOFFDebugDirectory();
    if (opts::COFFResources)
      Dumper->printCOFFResources();
    if (opts::COFFLoadConfig)
      Dumper->printCOFFLoadConfig();
    if (opts::Addrsig)
      Dumper->printAddrsig();
    if (opts::CodeView)
      Dumper->printCodeViewDebugInfo();
    if (opts::CodeViewMergedTypes)
      Dumper->mergeCodeViewTypes(CVTypes.IDTable, CVTypes.TypeTable);
  }
  if (Obj->isMachO()) {
    if (opts::MachODataInCode)
      Dumper->printMachODataInCode();
    if (opts::MachOIndirectSymbols)
      Dumper->printMachOIndirectSymbols();
    if (opts::MachOLinkerOptions)
      Dumper->printMachOLinkerOptions();
    if (opts::MachOSegment)
      Dumper->printMachOSegment();
    if (opts::MachOVersionMin)
      Dumper->printMachOVersionMin();
    if (opts::MachODysymtab)
      Dumper->printMachODysymtab();
  }
  if (opts::PrintStackMap)
    Dumper->printStackMap();
}

/// Dumps each object file in \a Arc;
static void dumpArchive(const Archive *Arc, ScopedPrinter &Writer) {
  Error Err = Error::success();
  for (auto &Child : Arc->children(Err)) {
    Expected<std::unique_ptr<Binary>> ChildOrErr = Child.getAsBinary();
    if (!ChildOrErr) {
      if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError())) {
        reportError(Arc->getFileName(), ChildOrErr.takeError());
      }
      continue;
    }
    if (ObjectFile *Obj = dyn_cast<ObjectFile>(&*ChildOrErr.get()))
      dumpObject(Obj, Writer);
    else if (COFFImportFile *Imp = dyn_cast<COFFImportFile>(&*ChildOrErr.get()))
      dumpCOFFImportFile(Imp, Writer);
    else
      reportError(Arc->getFileName(), readobj_error::unrecognized_file_format);
  }
  if (Err)
    reportError(Arc->getFileName(), std::move(Err));
}

/// Dumps each object file in \a MachO Universal Binary;
static void dumpMachOUniversalBinary(const MachOUniversalBinary *UBinary,
                                     ScopedPrinter &Writer) {
  for (const MachOUniversalBinary::ObjectForArch &Obj : UBinary->objects()) {
    Expected<std::unique_ptr<MachOObjectFile>> ObjOrErr = Obj.getAsObjectFile();
    if (ObjOrErr)
      dumpObject(&*ObjOrErr.get(), Writer);
    else if (auto E = isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) {
      reportError(UBinary->getFileName(), ObjOrErr.takeError());
    }
    else if (Expected<std::unique_ptr<Archive>> AOrErr = Obj.getAsArchive())
      dumpArchive(&*AOrErr.get(), Writer);
  }
}

/// Dumps \a WinRes, Windows Resource (.res) file;
static void dumpWindowsResourceFile(WindowsResource *WinRes) {
  ScopedPrinter Printer{outs()};
  WindowsRes::Dumper Dumper(WinRes, Printer);
  if (auto Err = Dumper.printData())
    reportError(WinRes->getFileName(), std::move(Err));
}


/// Opens \a File and dumps it.
static void dumpInput(StringRef File) {
  ScopedPrinter Writer(outs());

  // Attempt to open the binary.
  Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(File);
  if (!BinaryOrErr)
    reportError(File, BinaryOrErr.takeError());
  Binary &Binary = *BinaryOrErr.get().getBinary();

  if (Archive *Arc = dyn_cast<Archive>(&Binary))
    dumpArchive(Arc, Writer);
  else if (MachOUniversalBinary *UBinary =
               dyn_cast<MachOUniversalBinary>(&Binary))
    dumpMachOUniversalBinary(UBinary, Writer);
  else if (ObjectFile *Obj = dyn_cast<ObjectFile>(&Binary))
    dumpObject(Obj, Writer);
  else if (COFFImportFile *Import = dyn_cast<COFFImportFile>(&Binary))
    dumpCOFFImportFile(Import, Writer);
  else if (WindowsResource *WinRes = dyn_cast<WindowsResource>(&Binary))
    dumpWindowsResourceFile(WinRes);
  else
    reportError(File, readobj_error::unrecognized_file_format);
}

/// Registers aliases that should only be allowed by readobj.
static void registerReadobjAliases() {
  // -s has meant --sections for a very long time in llvm-readobj despite
  // meaning --symbols in readelf.
  static cl::alias SectionsShort("s", cl::desc("Alias for --section-headers"),
                                 cl::aliasopt(opts::SectionHeaders),
                                 cl::NotHidden);

  // Only register -t in llvm-readobj, as readelf reserves it for
  // --section-details (not implemented yet).
  static cl::alias SymbolsShort("t", cl::desc("Alias for --symbols"),
                                cl::aliasopt(opts::Symbols), cl::NotHidden);
}

/// Registers aliases that should only be allowed by readelf.
static void registerReadelfAliases() {
  // -s is here because for readobj it means --sections.
  static cl::alias SymbolsShort("s", cl::desc("Alias for --symbols"),
                                cl::aliasopt(opts::Symbols), cl::NotHidden);
}

int main(int argc, const char *argv[]) {
  InitLLVM X(argc, argv);

  // Register the target printer for --version.
  cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);

  if (sys::path::stem(argv[0]).contains("readelf")) {
    opts::Output = opts::GNU;
    registerReadelfAliases();
  } else {
    registerReadobjAliases();
  }

  cl::ParseCommandLineOptions(argc, argv, "LLVM Object Reader\n");

  if (opts::All) {
    opts::FileHeaders = true;
    opts::ProgramHeaders = true;
    opts::SectionHeaders = true;
    opts::Symbols = true;
    opts::Relocations = true;
    opts::DynamicTable = true;
    opts::Notes = true;
    opts::VersionInfo = true;
    opts::UnwindInfo = true;
    opts::SectionGroups = true;
    opts::HashHistogram = true;
  }

  if (opts::Headers) {
    opts::FileHeaders = true;
    opts::ProgramHeaders = true;
    opts::SectionHeaders = true;
  }

  // Default to stdin if no filename is specified.
  if (opts::InputFilenames.empty())
    opts::InputFilenames.push_back("-");

  llvm::for_each(opts::InputFilenames, dumpInput);

  if (opts::CodeViewMergedTypes) {
    ScopedPrinter W(outs());
    dumpCodeViewMergedTypes(W, CVTypes.IDTable, CVTypes.TypeTable);
  }

  return 0;
}