[LLVMdev] llvm-objdump related patch

Michael Spencer bigcheesegs at gmail.com
Thu Oct 13 11:06:07 PDT 2011


On Wed, Oct 12, 2011 at 3:17 AM, Songmao <smtian at ingenic.cn> wrote:
> Michael,
>    I have rework the patch according to your suggestion.  And I have read
> binutil/objdump source code and found that it has a logic that if there's no
> symtab, it will use dynsym, which is missing in llvm-objdump.
>
> Songmao
>

@@ -747,12 +747,28 @@ error_code ELFObjectFile<target_endianness, is64Bits>
 template<support::endianness target_endianness, bool is64Bits>
 error_code ELFObjectFile<target_endianness, is64Bits>
                           ::sectionContainsSymbol(DataRefImpl Sec,
                                                   DataRefImpl Symb,
                                                   bool &Result) const {
-  // FIXME: Unimplemented.
+
   Result = false;
+  const Elf_Sym  *sym = getSymbol(Symb);
+  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
+
+  if (getSection(sym->st_shndx) != sec) {

This version of getSection will not handle extended section indices
properly. Use the version that takes a const Elf_Sym*. This also fails
when there is no section table, which is not required for executables
or shared libraries.

+    Result = false;
+    return object_error::success;
+  }
+
+  uint64_t Address;
+  getSymbolOffset(Symb, Address);
+
+  if (sym->getType() == ELF::STT_FUNC

Again, this will only work for functions. Symbols without this type
can also be in a section.

+		  && Address >= sec->sh_addr
+		  && Address < (sec->sh_addr + sec->sh_size))
+	  Result = true;
+
   return object_error::success;
 }

 template<support::endianness target_endianness, bool is64Bits>
 relocation_iterator ELFObjectFile<target_endianness, is64Bits>

@@ -232,11 +235,11 @@ static void DisassembleObject(const ObjectFile *Obj) {
     if (error(i->getSize(SectSize))) break;

     // Disassemble symbol by symbol.
     for (unsigned si = 0, se = Symbols.size(); si != se; ++si) {
       uint64_t Start = Symbols[si].first;
-      uint64_t End = si == se-1 ? SectSize : Symbols[si + 1].first - 1;
+      uint64_t End = si == se-1 ? SectionVMA + SectSize : Symbols[si
+ 1].first - 1;

This goes over 80 col.

       outs() << '\n' << Symbols[si].second << ":\n";

 #ifndef NDEBUG
         raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
 #else
@@ -244,22 +247,22 @@ static void DisassembleObject(const ObjectFile *Obj) {
 #endif

       for (Index = Start; Index < End; Index += Size) {
         MCInst Inst;

-        if (DisAsm->getInstruction(Inst, Size, memoryObject, Index,
+        outs() << format("%8x:\t", Index);
+        if (DisAsm->getInstruction(Inst, Size, memoryObject, Index -
SectionVMA,
                                    DebugOut, nulls())) {
-          uint64_t addr;
-          if (error(i->getAddress(addr))) break;
-          outs() << format("%8x:\t", addr + Index);
-          DumpBytes(StringRef(Bytes.data() + Index, Size));
+          DumpBytes(StringRef(Bytes.data() + Index - SectionVMA, Size));
           IP->printInst(&Inst, outs(), "");
           outs() << "\n";
         } else {
           errs() << ToolName << ": warning: invalid instruction encoding\n";
           if (Size == 0)
-            Size = 1; // skip illegible bytes
+            Size = 4; // skip illegible bytes

This isn't right for most instruction sets. This value needs to be
computed based on the current instruction set being disassembled.

+          DumpBytes(StringRef(Bytes.data() + Index - SectionVMA, Size));
+          outs() << "\n";
         }
       }
     }
   }
 }

Once you fix these, I think it will be good to commit. Thanks for
working on this!

- Michael Spencer




More information about the llvm-dev mailing list