Index: test/tools/llvm-objdump/section-filter.test =================================================================== --- test/tools/llvm-objdump/section-filter.test +++ test/tools/llvm-objdump/section-filter.test @@ -0,0 +1,7 @@ +// This test checks that --section works correctly +// RUN: llvm-objdump -h %p/Inputs/section-filter.obj --section=.text \ +// RUN: --section=.bss | FileCheck %s + +# CHECK: .text +# CHECK-NOT: .data +# CHECK: .bss \ No newline at end of file Index: tools/llvm-objdump/MachODump.cpp =================================================================== --- tools/llvm-objdump/MachODump.cpp +++ tools/llvm-objdump/MachODump.cpp @@ -97,11 +97,6 @@ cl::desc("Print the linker optimization hints for " "Mach-O objects (requires -macho)")); -cl::list - llvm::DumpSections("section", - cl::desc("Prints the specified segment,section for " - "Mach-O objects (requires -macho)")); - cl::opt llvm::InfoPlist("info-plist", cl::desc("Print the info plist section as strings for " @@ -1006,8 +1001,8 @@ if (verbose) CreateSymbolAddressMap(O, &AddrMap); - for (unsigned i = 0; i < DumpSections.size(); ++i) { - StringRef DumpSection = DumpSections[i]; + for (unsigned i = 0; i < Sections.size(); ++i) { + StringRef DumpSection = Sections[i]; std::pair DumpSegSectName; DumpSegSectName = DumpSection.split(','); StringRef DumpSegName, DumpSectName; @@ -1171,7 +1166,7 @@ // UniversalHeaders or ArchiveHeaders. if (Disassemble || PrivateHeaders || ExportsTrie || Rebase || Bind || LazyBind || WeakBind || IndirectSymbols || DataInCode || LinkOptHints || - DylibsUsed || DylibId || ObjcMetaData || (DumpSections.size() != 0)) { + DylibsUsed || DylibId || ObjcMetaData || (Sections.size() != 0)) { outs() << Filename; if (!ArchiveMemberName.empty()) outs() << '(' << ArchiveMemberName << ')'; @@ -1194,7 +1189,7 @@ PrintSectionHeaders(MachOOF); if (SectionContents) PrintSectionContents(MachOOF); - if (DumpSections.size() != 0) + if (Sections.size() != 0) DumpSectionContents(Filename, MachOOF, !NonVerbose); if (InfoPlist) DumpInfoPlistSectionContents(Filename, MachOOF); @@ -6065,7 +6060,7 @@ diContext.reset(new DWARFContextInMemory(*DbgObj)); } - if (DumpSections.size() == 0) + if (Sections.size() == 0) outs() << "(" << DisSegName << "," << DisSectName << ") section\n"; for (unsigned SectIdx = 0; SectIdx != Sections.size(); SectIdx++) { Index: tools/llvm-objdump/llvm-objdump.h =================================================================== --- tools/llvm-objdump/llvm-objdump.h +++ tools/llvm-objdump/llvm-objdump.h @@ -25,8 +25,8 @@ extern cl::opt ArchName; extern cl::opt MCPU; extern cl::list MAttrs; -extern cl::list DumpSections; -extern cl::opt Disassemble; +extern cl::list Sections; +extern cl::opt Disassemble; extern cl::opt DisassembleAll; extern cl::opt NoShowRawInsn; extern cl::opt PrivateHeaders; Index: tools/llvm-objdump/llvm-objdump.cpp =================================================================== --- tools/llvm-objdump/llvm-objdump.cpp +++ tools/llvm-objdump/llvm-objdump.cpp @@ -137,6 +137,13 @@ cl::aliasopt(SectionHeaders)); cl::list +llvm::Sections("section", + cl::desc("Operate on the specified section only" + " Mach-O specific: Spcify as segment,section pair")); +static cl::alias +Sectionsj("j", cl::desc("Alias for --section"), cl::aliasopt(Sections)); + +cl::list llvm::MAttrs("mattr", cl::CommaSeparated, cl::desc("Target specific attributes"), @@ -172,6 +179,73 @@ static StringRef ToolName; static int ReturnValue = EXIT_SUCCESS; +namespace { +typedef std::function FilterPredicate; +class SectionFilterIterator { +public: + SectionFilterIterator(FilterPredicate P, + llvm::object::section_iterator const &I, + llvm::object::section_iterator const &E) + : Predicate(P), Iterator(I), End(E) { + ScanPredicate(); + } + llvm::object::SectionRef operator*() const { return *Iterator; } + SectionFilterIterator &operator++() { + ++Iterator; + ScanPredicate(); + return *this; + } + bool operator!=(SectionFilterIterator const &Other) const { + return Iterator != Other.Iterator; + } + +private: + void ScanPredicate() { + while (Iterator != End && Predicate(*Iterator)) { + ++Iterator; + } + } + FilterPredicate Predicate; + llvm::object::section_iterator Iterator; + llvm::object::section_iterator End; +}; +class SectionFilter { +public: + SectionFilter(FilterPredicate P, llvm::object::ObjectFile const &O) + : Predicate(P), Object(O) {} + SectionFilterIterator begin() { + return SectionFilterIterator(Predicate, Object.section_begin(), + Object.section_end()); + } + SectionFilterIterator end() { + return SectionFilterIterator(Predicate, Object.section_end(), + Object.section_end()); + } + +private: + FilterPredicate Predicate; + llvm::object::ObjectFile const &Object; +}; +SectionFilter ToolSectionFilter(llvm::object::ObjectFile const &O) { + if (Sections.empty()) { + return SectionFilter([](llvm::object::SectionRef const &) { return 0; }, O); + } + return SectionFilter([](llvm::object::SectionRef const &S) { + llvm::StringRef String; + std::error_code error = S.getName(String); + if (error) { + return error.value(); + } + if (std::find(Sections.begin(), Sections.end(), + String) != Sections.end()) { + return 0; + } + return 1; + }, + O); +} +} + bool llvm::error(std::error_code EC) { if (!EC) return false; @@ -478,7 +552,7 @@ // If we couldn't find a symbol that this relocation refers to, try // to find a section beginning instead. - for (const SectionRef &Section : O->sections()) { + for (const SectionRef &Section : ToolSectionFilter(*O)) { std::error_code ec; StringRef Name; @@ -813,7 +887,7 @@ // in RelocSecs contain the relocations for section S. std::error_code EC; std::map> SectionRelocMap; - for (const SectionRef &Section : Obj->sections()) { + for (const SectionRef &Section : ToolSectionFilter(*Obj)) { section_iterator Sec2 = Section.getRelocatedSection(); if (Sec2 != Obj->section_end()) SectionRelocMap[*Sec2].push_back(Section); @@ -843,7 +917,7 @@ array_pod_sort(AllSymbols.begin(), AllSymbols.end()); } - for (const SectionRef &Section : Obj->sections()) { + for (const SectionRef &Section : ToolSectionFilter(*Obj)) { if (!DisassembleAll && (!Section.isText() || Section.isVirtual())) continue; @@ -1011,7 +1085,7 @@ if (!Obj->isRelocatableObject()) return; - for (const SectionRef &Section : Obj->sections()) { + for (const SectionRef &Section : ToolSectionFilter(*Obj)) { if (Section.relocation_begin() == Section.relocation_end()) continue; StringRef secname; @@ -1039,7 +1113,7 @@ outs() << "Sections:\n" "Idx Name Size Address Type\n"; unsigned i = 0; - for (const SectionRef &Section : Obj->sections()) { + for (const SectionRef &Section : ToolSectionFilter(*Obj)) { StringRef Name; if (error(Section.getName(Name))) return; @@ -1058,7 +1132,7 @@ void llvm::PrintSectionContents(const ObjectFile *Obj) { std::error_code EC; - for (const SectionRef &Section : Obj->sections()) { + for (const SectionRef &Section : ToolSectionFilter(*Obj)) { StringRef Name; StringRef Contents; if (error(Section.getName(Name))) @@ -1336,7 +1410,7 @@ } Optional ClangASTSection; - for (auto Sec : Obj->sections()) { + for (auto Sec : ToolSectionFilter(*Obj)) { StringRef Name; Sec.getName(Name); if (Name == ClangASTSectionName) { @@ -1371,7 +1445,7 @@ Optional FaultMapSection; - for (auto Sec : Obj->sections()) { + for (auto Sec : ToolSectionFilter(*Obj)) { StringRef Name; Sec.getName(Name); if (Name == FaultMapSectionName) { @@ -1545,7 +1619,7 @@ && !(DylibsUsed && MachOOpt) && !(DylibId && MachOOpt) && !(ObjcMetaData && MachOOpt) - && !(DumpSections.size() != 0 && MachOOpt) + && !(Sections.size() != 0 && MachOOpt) && !PrintFaultMaps) { cl::PrintHelpMessage(); return 2;