[llvm-objdump] Added -j flag to filter sections that are operated on.
[oota-llvm.git] / tools / llvm-objdump / llvm-objdump.cpp
index 8d906daecc0d9be57393c66337a1ed212c60a9c4..af8bc4a44b87ea9d1ba3ad900b8d77611af11c34 100644 (file)
@@ -72,6 +72,13 @@ static cl::alias
 Disassembled("d", cl::desc("Alias for --disassemble"),
              cl::aliasopt(Disassemble));
 
+cl::opt<bool>
+llvm::DisassembleAll("disassemble-all",
+  cl::desc("Display assembler mnemonics for the machine instructions"));
+static cl::alias
+DisassembleAlld("D", cl::desc("Alias for --disassemble-all"),
+             cl::aliasopt(DisassembleAll));
+
 cl::opt<bool>
 llvm::Relocations("r", cl::desc("Display the relocation entries in the file"));
 
@@ -128,6 +135,8 @@ SectionHeadersShort("headers", cl::desc("Alias for --section-headers"),
 static cl::alias
 SectionHeadersShorter("h", cl::desc("Alias for --section-headers"),
                       cl::aliasopt(SectionHeaders));
+cl::list<std::string>
+llvm::Sections("j", cl::desc("Operate on the specified sections only"));
 
 cl::list<std::string>
 llvm::MAttrs("mattr",
@@ -165,6 +174,75 @@ cl::opt<bool> PrintFaultMaps("fault-map-section",
 static StringRef ToolName;
 static int ReturnValue = EXIT_SUCCESS;
 
+namespace {
+typedef std::function<int(llvm::object::SectionRef const &)> 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;
@@ -471,7 +549,7 @@ static void printRelocationTargetName(const MachOObjectFile *O,
 
     // 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;
@@ -806,7 +884,7 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
   // in RelocSecs contain the relocations for section S.
   std::error_code EC;
   std::map<SectionRef, SmallVector<SectionRef, 1>> 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);
@@ -836,8 +914,8 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
     array_pod_sort(AllSymbols.begin(), AllSymbols.end());
   }
 
-  for (const SectionRef &Section : Obj->sections()) {
-    if (!Section.isText() || Section.isVirtual())
+  for (const SectionRef &Section : ToolSectionFilter(*Obj)) {
+    if (!DisassembleAll && (!Section.isText() || Section.isVirtual()))
       continue;
 
     uint64_t SectionAddr = Section.getAddress();
@@ -946,7 +1024,7 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
             if (MIA->evaluateBranch(Inst, SectionAddr + Index, Size, Target)) {
               auto TargetSym = std::upper_bound(
                   AllSymbols.begin(), AllSymbols.end(), Target,
-                  [](uint64_t LHS, std::pair<uint64_t, StringRef> &RHS) {
+                  [](uint64_t LHS, const std::pair<uint64_t, StringRef> &RHS) {
                     return LHS < RHS.first;
                   });
               if (TargetSym != AllSymbols.begin())
@@ -1004,7 +1082,7 @@ void llvm::PrintRelocations(const ObjectFile *Obj) {
   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;
@@ -1032,7 +1110,7 @@ void llvm::PrintSectionHeaders(const ObjectFile *Obj) {
   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;
@@ -1051,7 +1129,7 @@ void llvm::PrintSectionHeaders(const ObjectFile *Obj) {
 
 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)))
@@ -1329,7 +1407,7 @@ void llvm::printRawClangAST(const ObjectFile *Obj) {
   }
 
   Optional<object::SectionRef> ClangASTSection;
-  for (auto Sec : Obj->sections()) {
+  for (auto Sec : ToolSectionFilter(*Obj)) {
     StringRef Name;
     Sec.getName(Name);
     if (Name == ClangASTSectionName) {
@@ -1364,7 +1442,7 @@ static void printFaultMaps(const ObjectFile *Obj) {
 
   Optional<object::SectionRef> FaultMapSection;
 
-  for (auto Sec : Obj->sections()) {
+  for (auto Sec : ToolSectionFilter(*Obj)) {
     StringRef Name;
     Sec.getName(Name);
     if (Name == FaultMapSectionName) {
@@ -1514,6 +1592,8 @@ int main(int argc, char **argv) {
   if (InputFilenames.size() == 0)
     InputFilenames.push_back("a.out");
 
+  if (DisassembleAll)
+    Disassemble = true;
   if (!Disassemble
       && !Relocations
       && !SectionHeaders