diff options
author | Jordan Rupprecht <rupprecht@google.com> | 2019-01-15 17:04:40 +0000 |
---|---|---|
committer | Jordan Rupprecht <rupprecht@google.com> | 2019-01-15 17:04:40 +0000 |
commit | c8da389137b1260c8dceac52c413adf3b12eb50e (patch) | |
tree | 2f540923729037dbe2a97c98cf611f0c91dcd2be /llvm | |
parent | a5b03966bac48b620adf31240dc07fa9e191c57f (diff) |
[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
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/test/tools/llvm-readobj/dyn-symbols.test | 163 | ||||
-rw-r--r-- | llvm/test/tools/llvm-readobj/merged.test | 13 | ||||
-rw-r--r-- | llvm/test/tools/llvm-readobj/sections-ext.test | 14 | ||||
-rw-r--r-- | llvm/tools/llvm-readobj/llvm-readobj.cpp | 49 |
4 files changed, 222 insertions, 17 deletions
diff --git a/llvm/test/tools/llvm-readobj/dyn-symbols.test b/llvm/test/tools/llvm-readobj/dyn-symbols.test new file mode 100644 index 00000000000..16a2aba99e1 --- /dev/null +++ b/llvm/test/tools/llvm-readobj/dyn-symbols.test @@ -0,0 +1,163 @@ +RUN: llvm-readobj --dyn-symbols %p/Inputs/dynamic-table-so.x86 | FileCheck %s + +# Check the two-letter alias -dt is equivalent to the --dyn-symbols full flag +# name. +RUN: llvm-readobj -dt %p/Inputs/dynamic-table-so.x86 > %t.readobj-dt-alias +RUN: llvm-readobj --dyn-symbols %p/Inputs/dynamic-table-so.x86 > %t.readobj-dt-no-alias +RUN: diff %t.readobj-dt-alias %t.readobj-dt-no-alias + +# CHECK: DynamicSymbols [ +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Local +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: +# CHECK-NEXT: Value: 0x618 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Local +# CHECK-NEXT: Type: Section +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .init +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: +# CHECK-NEXT: Value: 0x200DC0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Local +# CHECK-NEXT: Type: Section +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .tbss +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: _ITM_deregisterTMCloneTable{{ }} +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Weak +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: puts@GLIBC_2.2.5{{ }} +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: Function +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: __tls_get_addr@GLIBC_2.3{{ }} +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: Function +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: __gmon_start__{{ }} +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Weak +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: _Jv_RegisterClasses{{ }} +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Weak +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: _ITM_registerTMCloneTable{{ }} +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Weak +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: __cxa_finalize@GLIBC_2.2.5{{ }} +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Weak +# CHECK-NEXT: Type: Function +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: _edata{{ }} +# CHECK-NEXT: Value: 0x201030 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .data +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: foo{{ }} +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 4 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: TLS +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .tbss +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: _end{{ }} +# CHECK-NEXT: Value: 0x201038 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .bss +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: __bss_start{{ }} +# CHECK-NEXT: Value: 0x201030 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .bss +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: main{{ }} +# CHECK-NEXT: Value: 0x780 +# CHECK-NEXT: Size: 59 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: Function +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .text +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: _init{{ }} +# CHECK-NEXT: Value: 0x618 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: Function +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .init +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: _fini{{ }} +# CHECK-NEXT: Value: 0x7BC +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: Function +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .fini +# CHECK-NEXT: } +# CHECK-NEXT: ] diff --git a/llvm/test/tools/llvm-readobj/merged.test b/llvm/test/tools/llvm-readobj/merged.test new file mode 100644 index 00000000000..0fcc14f1f95 --- /dev/null +++ b/llvm/test/tools/llvm-readobj/merged.test @@ -0,0 +1,13 @@ +# Check merged args produce identical output to when not merged. +RUN: llvm-readelf -aeWhSrnudlVgIs %p/Inputs/trivial.obj.elf-i386 > %t.merged +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 +RUN: cmp %t.merged %t.not-merged +RUN: FileCheck %s --input-file %t.merged + +# llvm-readobj does not support merged args, because it also supports some old +# flags (-st, -sd, etc.), and it would be confusing if only some merged args +# were supported. +RUN: not llvm-readobj -aeWhSrnudlVgIs %p/Inputs/trivial.obj.elf-i386 2>&1 | FileCheck %s --check-prefix=UNKNOWN + +CHECK-NOT: Unknown command line argument +UNKNOWN: Unknown command line argument diff --git a/llvm/test/tools/llvm-readobj/sections-ext.test b/llvm/test/tools/llvm-readobj/sections-ext.test index 70ae0f22a0e..085693829c3 100644 --- a/llvm/test/tools/llvm-readobj/sections-ext.test +++ b/llvm/test/tools/llvm-readobj/sections-ext.test @@ -13,6 +13,20 @@ RUN: | FileCheck %s -check-prefix MACHO-PPC64 RUN: llvm-readobj -expand-relocs -s -st -sr -sd %p/Inputs/trivial.obj.macho-arm \ RUN: | FileCheck %s -check-prefix MACHO-ARM +# Check the two-letter aliases above (-st, -sr, -sd) are equivalent to their +# full flag names. +RUN: llvm-readobj -s -st %p/Inputs/trivial.obj.elf-i386 > %t.readobj-st-alias +RUN: llvm-readobj -s --section-symbols %p/Inputs/trivial.obj.elf-i386 > %t.readobj-st-no-alias +RUN: diff %t.readobj-st-alias %t.readobj-st-no-alias + +RUN: llvm-readobj -s -sr %p/Inputs/trivial.obj.elf-i386 > %t.readobj-sr-alias +RUN: llvm-readobj -s --section-relocations %p/Inputs/trivial.obj.elf-i386 > %t.readobj-sr-no-alias +RUN: diff %t.readobj-sr-alias %t.readobj-sr-no-alias + +RUN: llvm-readobj -s -sd %p/Inputs/trivial.obj.elf-i386 > %t.readobj-sd-alias +RUN: llvm-readobj -s --section-data %p/Inputs/trivial.obj.elf-i386 > %t.readobj-sd-no-alias +RUN: diff %t.readobj-sd-alias %t.readobj-sd-no-alias + COFF: Sections [ COFF-NEXT: Section { COFF-NEXT: Number: 1 diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp index f66564b02fb..81ce7a59036 100644 --- a/llvm/tools/llvm-readobj/llvm-readobj.cpp +++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp @@ -92,26 +92,20 @@ namespace opts { cl::desc("Alias for --section-headers"), cl::aliasopt(SectionHeaders), cl::NotHidden); - // -section-relocations, -sr + // -section-relocations + // Also -sr in llvm-readobj mode. 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 + // -section-symbols + // Also -st in llvm-readobj mode. 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 + // -section-data + // Also -sd in llvm-readobj mode. 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", @@ -136,12 +130,10 @@ namespace opts { cl::alias SymbolsGNU("syms", cl::desc("Alias for --symbols"), cl::aliasopt(Symbols)); - // -dyn-symbols, -dyn-syms, -dt + // -dyn-symbols, -dyn-syms + // Also -dt in llvm-readobj mode. 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)); @@ -636,13 +628,36 @@ static void registerReadobjAliases() { // --section-details (not implemented yet). static cl::alias SymbolsShort("t", cl::desc("Alias for --symbols"), cl::aliasopt(opts::Symbols), cl::NotHidden); + + // The following two-letter aliases are only provided for readobj, as readelf + // allows single-letter args to be grouped together. + static cl::alias SectionRelocationsShort( + "sr", cl::desc("Alias for --section-relocations"), + cl::aliasopt(opts::SectionRelocations)); + static cl::alias SectionDataShort("sd", cl::desc("Alias for --section-data"), + cl::aliasopt(opts::SectionData)); + static cl::alias SectionSymbolsShort("st", + cl::desc("Alias for --section-symbols"), + cl::aliasopt(opts::SectionSymbols)); + static cl::alias DynamicSymbolsShort("dt", + cl::desc("Alias for --dyn-symbols"), + cl::aliasopt(opts::DynamicSymbols)); } /// 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); + cl::aliasopt(opts::Symbols), cl::NotHidden, + cl::Grouping); + + // Allow all single letter flags to be grouped together. + for (auto &OptEntry : cl::getRegisteredOptions()) { + StringRef ArgName = OptEntry.getKey(); + cl::Option *Option = OptEntry.getValue(); + if (ArgName.size() == 1) + Option->setFormattingFlag(cl::Grouping); + } } int main(int argc, const char *argv[]) { |