forked from OSchip/llvm-project
[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 llvm-svn: 351205
This commit is contained in:
parent
17dd4a2c5e
commit
58aac95081
|
@ -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: ]
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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[]) {
|
||||
|
|
Loading…
Reference in New Issue