llvm.org GIT mirror llvm / e55d66c
[llvm-readelf] Allow single-letter flags to be merged. Summary: This patch adds support for merged arguments (e.g. -SW == -S -W) for llvm-readelf. No changes are intended for llvm-readobj. There are a few short flags (-sd, -sr, -st, -dt) that would conflict with grouped single letter flags, and having only some grouped flags might be confusing. So, allow merged flags for readelf compatibility, but force separate args for llvm-readobj. From what I can tell, these two-letter flags are only used with llvm-readobj, not llvm-readelf. This fixes PR40064. Reviewers: jhenderson, kristina, echristo, phosek Reviewed By: jhenderson Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D56629 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351205 91177308-0d34-0410-b5e6-96231b3b80d8 Jordan Rupprecht 7 months ago
4 changed file(s) with 224 addition(s) and 19 deletion(s). Raw diff Collapse all Expand all
0 RUN: llvm-readobj --dyn-symbols %p/Inputs/dynamic-table-so.x86 | FileCheck %s
1
2 # Check the two-letter alias -dt is equivalent to the --dyn-symbols full flag
3 # name.
4 RUN: llvm-readobj -dt %p/Inputs/dynamic-table-so.x86 > %t.readobj-dt-alias
5 RUN: llvm-readobj --dyn-symbols %p/Inputs/dynamic-table-so.x86 > %t.readobj-dt-no-alias
6 RUN: diff %t.readobj-dt-alias %t.readobj-dt-no-alias
7
8 # CHECK: DynamicSymbols [
9 # CHECK-NEXT: Symbol {
10 # CHECK-NEXT: Name:
11 # CHECK-NEXT: Value: 0x0
12 # CHECK-NEXT: Size: 0
13 # CHECK-NEXT: Binding: Local
14 # CHECK-NEXT: Type: None
15 # CHECK-NEXT: Other: 0
16 # CHECK-NEXT: Section: Undefined
17 # CHECK-NEXT: }
18 # CHECK-NEXT: Symbol {
19 # CHECK-NEXT: Name:
20 # CHECK-NEXT: Value: 0x618
21 # CHECK-NEXT: Size: 0
22 # CHECK-NEXT: Binding: Local
23 # CHECK-NEXT: Type: Section
24 # CHECK-NEXT: Other: 0
25 # CHECK-NEXT: Section: .init
26 # CHECK-NEXT: }
27 # CHECK-NEXT: Symbol {
28 # CHECK-NEXT: Name:
29 # CHECK-NEXT: Value: 0x200DC0
30 # CHECK-NEXT: Size: 0
31 # CHECK-NEXT: Binding: Local
32 # CHECK-NEXT: Type: Section
33 # CHECK-NEXT: Other: 0
34 # CHECK-NEXT: Section: .tbss
35 # CHECK-NEXT: }
36 # CHECK-NEXT: Symbol {
37 # CHECK-NEXT: Name: _ITM_deregisterTMCloneTable{{ }}
38 # CHECK-NEXT: Value: 0x0
39 # CHECK-NEXT: Size: 0
40 # CHECK-NEXT: Binding: Weak
41 # CHECK-NEXT: Type: None
42 # CHECK-NEXT: Other: 0
43 # CHECK-NEXT: Section: Undefined
44 # CHECK-NEXT: }
45 # CHECK-NEXT: Symbol {
46 # CHECK-NEXT: Name: puts@GLIBC_2.2.5{{ }}
47 # CHECK-NEXT: Value: 0x0
48 # CHECK-NEXT: Size: 0
49 # CHECK-NEXT: Binding: Global
50 # CHECK-NEXT: Type: Function
51 # CHECK-NEXT: Other: 0
52 # CHECK-NEXT: Section: Undefined
53 # CHECK-NEXT: }
54 # CHECK-NEXT: Symbol {
55 # CHECK-NEXT: Name: __tls_get_addr@GLIBC_2.3{{ }}
56 # CHECK-NEXT: Value: 0x0
57 # CHECK-NEXT: Size: 0
58 # CHECK-NEXT: Binding: Global
59 # CHECK-NEXT: Type: Function
60 # CHECK-NEXT: Other: 0
61 # CHECK-NEXT: Section: Undefined
62 # CHECK-NEXT: }
63 # CHECK-NEXT: Symbol {
64 # CHECK-NEXT: Name: __gmon_start__{{ }}
65 # CHECK-NEXT: Value: 0x0
66 # CHECK-NEXT: Size: 0
67 # CHECK-NEXT: Binding: Weak
68 # CHECK-NEXT: Type: None
69 # CHECK-NEXT: Other: 0
70 # CHECK-NEXT: Section: Undefined
71 # CHECK-NEXT: }
72 # CHECK-NEXT: Symbol {
73 # CHECK-NEXT: Name: _Jv_RegisterClasses{{ }}
74 # CHECK-NEXT: Value: 0x0
75 # CHECK-NEXT: Size: 0
76 # CHECK-NEXT: Binding: Weak
77 # CHECK-NEXT: Type: None
78 # CHECK-NEXT: Other: 0
79 # CHECK-NEXT: Section: Undefined
80 # CHECK-NEXT: }
81 # CHECK-NEXT: Symbol {
82 # CHECK-NEXT: Name: _ITM_registerTMCloneTable{{ }}
83 # CHECK-NEXT: Value: 0x0
84 # CHECK-NEXT: Size: 0
85 # CHECK-NEXT: Binding: Weak
86 # CHECK-NEXT: Type: None
87 # CHECK-NEXT: Other: 0
88 # CHECK-NEXT: Section: Undefined
89 # CHECK-NEXT: }
90 # CHECK-NEXT: Symbol {
91 # CHECK-NEXT: Name: __cxa_finalize@GLIBC_2.2.5{{ }}
92 # CHECK-NEXT: Value: 0x0
93 # CHECK-NEXT: Size: 0
94 # CHECK-NEXT: Binding: Weak
95 # CHECK-NEXT: Type: Function
96 # CHECK-NEXT: Other: 0
97 # CHECK-NEXT: Section: Undefined
98 # CHECK-NEXT: }
99 # CHECK-NEXT: Symbol {
100 # CHECK-NEXT: Name: _edata{{ }}
101 # CHECK-NEXT: Value: 0x201030
102 # CHECK-NEXT: Size: 0
103 # CHECK-NEXT: Binding: Global
104 # CHECK-NEXT: Type: None
105 # CHECK-NEXT: Other: 0
106 # CHECK-NEXT: Section: .data
107 # CHECK-NEXT: }
108 # CHECK-NEXT: Symbol {
109 # CHECK-NEXT: Name: foo{{ }}
110 # CHECK-NEXT: Value: 0x0
111 # CHECK-NEXT: Size: 4
112 # CHECK-NEXT: Binding: Global
113 # CHECK-NEXT: Type: TLS
114 # CHECK-NEXT: Other: 0
115 # CHECK-NEXT: Section: .tbss
116 # CHECK-NEXT: }
117 # CHECK-NEXT: Symbol {
118 # CHECK-NEXT: Name: _end{{ }}
119 # CHECK-NEXT: Value: 0x201038
120 # CHECK-NEXT: Size: 0
121 # CHECK-NEXT: Binding: Global
122 # CHECK-NEXT: Type: None
123 # CHECK-NEXT: Other: 0
124 # CHECK-NEXT: Section: .bss
125 # CHECK-NEXT: }
126 # CHECK-NEXT: Symbol {
127 # CHECK-NEXT: Name: __bss_start{{ }}
128 # CHECK-NEXT: Value: 0x201030
129 # CHECK-NEXT: Size: 0
130 # CHECK-NEXT: Binding: Global
131 # CHECK-NEXT: Type: None
132 # CHECK-NEXT: Other: 0
133 # CHECK-NEXT: Section: .bss
134 # CHECK-NEXT: }
135 # CHECK-NEXT: Symbol {
136 # CHECK-NEXT: Name: main{{ }}
137 # CHECK-NEXT: Value: 0x780
138 # CHECK-NEXT: Size: 59
139 # CHECK-NEXT: Binding: Global
140 # CHECK-NEXT: Type: Function
141 # CHECK-NEXT: Other: 0
142 # CHECK-NEXT: Section: .text
143 # CHECK-NEXT: }
144 # CHECK-NEXT: Symbol {
145 # CHECK-NEXT: Name: _init{{ }}
146 # CHECK-NEXT: Value: 0x618
147 # CHECK-NEXT: Size: 0
148 # CHECK-NEXT: Binding: Global
149 # CHECK-NEXT: Type: Function
150 # CHECK-NEXT: Other: 0
151 # CHECK-NEXT: Section: .init
152 # CHECK-NEXT: }
153 # CHECK-NEXT: Symbol {
154 # CHECK-NEXT: Name: _fini{{ }}
155 # CHECK-NEXT: Value: 0x7BC
156 # CHECK-NEXT: Size: 0
157 # CHECK-NEXT: Binding: Global
158 # CHECK-NEXT: Type: Function
159 # CHECK-NEXT: Other: 0
160 # CHECK-NEXT: Section: .fini
161 # CHECK-NEXT: }
162 # CHECK-NEXT: ]
0 # Check merged args produce identical output to when not merged.
1 RUN: llvm-readelf -aeWhSrnudlVgIs %p/Inputs/trivial.obj.elf-i386 > %t.merged
2 RUN: llvm-readelf -a -e -W -h -S -r -n -u -d -l -V -g -I -s %p/Inputs/trivial.obj.elf-i386 > %t.not-merged
3 RUN: cmp %t.merged %t.not-merged
4 RUN: FileCheck %s --input-file %t.merged
5
6 # llvm-readobj does not support merged args, because it also supports some old
7 # flags (-st, -sd, etc.), and it would be confusing if only some merged args
8 # were supported.
9 RUN: not llvm-readobj -aeWhSrnudlVgIs %p/Inputs/trivial.obj.elf-i386 2>&1 | FileCheck %s --check-prefix=UNKNOWN
10
11 CHECK-NOT: Unknown command line argument
12 UNKNOWN: Unknown command line argument
1111 RUN: | FileCheck %s -check-prefix MACHO-PPC64
1212 RUN: llvm-readobj -expand-relocs -s -st -sr -sd %p/Inputs/trivial.obj.macho-arm \
1313 RUN: | FileCheck %s -check-prefix MACHO-ARM
14
15 # Check the two-letter aliases above (-st, -sr, -sd) are equivalent to their
16 # full flag names.
17 RUN: llvm-readobj -s -st %p/Inputs/trivial.obj.elf-i386 > %t.readobj-st-alias
18 RUN: llvm-readobj -s --section-symbols %p/Inputs/trivial.obj.elf-i386 > %t.readobj-st-no-alias
19 RUN: diff %t.readobj-st-alias %t.readobj-st-no-alias
20
21 RUN: llvm-readobj -s -sr %p/Inputs/trivial.obj.elf-i386 > %t.readobj-sr-alias
22 RUN: llvm-readobj -s --section-relocations %p/Inputs/trivial.obj.elf-i386 > %t.readobj-sr-no-alias
23 RUN: diff %t.readobj-sr-alias %t.readobj-sr-no-alias
24
25 RUN: llvm-readobj -s -sd %p/Inputs/trivial.obj.elf-i386 > %t.readobj-sd-alias
26 RUN: llvm-readobj -s --section-data %p/Inputs/trivial.obj.elf-i386 > %t.readobj-sd-no-alias
27 RUN: diff %t.readobj-sd-alias %t.readobj-sd-no-alias
1428
1529 COFF: Sections [
1630 COFF-NEXT: Section {
9191 cl::desc("Alias for --section-headers"),
9292 cl::aliasopt(SectionHeaders), cl::NotHidden);
9393
94 // -section-relocations, -sr
94 // -section-relocations
95 // Also -sr in llvm-readobj mode.
9596 cl::opt SectionRelocations("section-relocations",
9697 cl::desc("Display relocations for each section shown."));
97 cl::alias SectionRelocationsShort("sr",
98 cl::desc("Alias for --section-relocations"),
99 cl::aliasopt(SectionRelocations));
100
101 // -section-symbols, -st
98
99 // -section-symbols
100 // Also -st in llvm-readobj mode.
102101 cl::opt SectionSymbols("section-symbols",
103102 cl::desc("Display symbols for each section shown."));
104 cl::alias SectionSymbolsShort("st",
105 cl::desc("Alias for --section-symbols"),
106 cl::aliasopt(SectionSymbols));
107
108 // -section-data, -sd
103
104 // -section-data
105 // Also -sd in llvm-readobj mode.
109106 cl::opt SectionData("section-data",
110107 cl::desc("Display section data for each section shown."));
111 cl::alias SectionDataShort("sd",
112 cl::desc("Alias for --section-data"),
113 cl::aliasopt(SectionData));
114108
115109 // -relocations, -relocs, -r
116110 cl::opt Relocations("relocations",
135129 cl::alias SymbolsGNU("syms", cl::desc("Alias for --symbols"),
136130 cl::aliasopt(Symbols));
137131
138 // -dyn-symbols, -dyn-syms, -dt
132 // -dyn-symbols, -dyn-syms
133 // Also -dt in llvm-readobj mode.
139134 cl::opt DynamicSymbols("dyn-symbols",
140135 cl::desc("Display the dynamic symbol table"));
141 cl::alias DynamicSymbolsShort("dt",
142 cl::desc("Alias for --dyn-symbols"),
143 cl::aliasopt(DynamicSymbols));
144136 cl::alias DynSymsGNU("dyn-syms", cl::desc("Alias for --dyn-symbols"),
145137 cl::aliasopt(DynamicSymbols));
146138
635627 // --section-details (not implemented yet).
636628 static cl::alias SymbolsShort("t", cl::desc("Alias for --symbols"),
637629 cl::aliasopt(opts::Symbols), cl::NotHidden);
630
631 // The following two-letter aliases are only provided for readobj, as readelf
632 // allows single-letter args to be grouped together.
633 static cl::alias SectionRelocationsShort(
634 "sr", cl::desc("Alias for --section-relocations"),
635 cl::aliasopt(opts::SectionRelocations));
636 static cl::alias SectionDataShort("sd", cl::desc("Alias for --section-data"),
637 cl::aliasopt(opts::SectionData));
638 static cl::alias SectionSymbolsShort("st",
639 cl::desc("Alias for --section-symbols"),
640 cl::aliasopt(opts::SectionSymbols));
641 static cl::alias DynamicSymbolsShort("dt",
642 cl::desc("Alias for --dyn-symbols"),
643 cl::aliasopt(opts::DynamicSymbols));
638644 }
639645
640646 /// Registers aliases that should only be allowed by readelf.
641647 static void registerReadelfAliases() {
642648 // -s is here because for readobj it means --sections.
643649 static cl::alias SymbolsShort("s", cl::desc("Alias for --symbols"),
644 cl::aliasopt(opts::Symbols), cl::NotHidden);
650 cl::aliasopt(opts::Symbols), cl::NotHidden,
651 cl::Grouping);
652
653 // Allow all single letter flags to be grouped together.
654 for (auto &OptEntry : cl::getRegisteredOptions()) {
655 StringRef ArgName = OptEntry.getKey();
656 cl::Option *Option = OptEntry.getValue();
657 if (ArgName.size() == 1)
658 Option->setFormattingFlag(cl::Grouping);
659 }
645660 }
646661
647662 int main(int argc, const char *argv[]) {