[llvm] r279770 - llvm-objdump: ELF: Handle code and data mix in all scenarios

Hemant Kulkarni via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 25 12:41:08 PDT 2016


Author: khemant
Date: Thu Aug 25 14:41:08 2016
New Revision: 279770

URL: http://llvm.org/viewvc/llvm-project?rev=279770&view=rev
Log:
llvm-objdump: ELF: Handle code and data mix in all scenarios

Differential Revision: https://reviews.llvm.org/D23621

Added:
    llvm/trunk/test/tools/llvm-objdump/ARM/disassemble-code-data-mix.s
    llvm/trunk/test/tools/llvm-objdump/X86/disassemble-code-data-mix.s
Modified:
    llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp

Added: llvm/trunk/test/tools/llvm-objdump/ARM/disassemble-code-data-mix.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/ARM/disassemble-code-data-mix.s?rev=279770&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objdump/ARM/disassemble-code-data-mix.s (added)
+++ llvm/trunk/test/tools/llvm-objdump/ARM/disassemble-code-data-mix.s Thu Aug 25 14:41:08 2016
@@ -0,0 +1,36 @@
+ at RUN: llvm-mc -triple arm-unknown-linux -filetype=obj %s | llvm-objdump -d - | FileCheck %s
+
+	.cpu arm7tdmi
+	.global	myInt
+	.data
+	.align	2
+	.type	myInt, %object
+	.size	myInt, 4
+myInt:
+	.word	1
+	.text
+	.align	2
+	.global	main
+	.type	main, %function
+main:
+	str	fp, [sp, #-4]!
+	add	fp, sp, #0
+	ldr	r3, .L3
+	ldr	r3, [r3]
+	mov	r0, r3
+	sub	sp, fp, #0
+	ldr	fp, [sp], #4
+	bx	lr
+.L4:
+	.align	2
+.L3:
+	.word	myInt
+	.size	main, .-main
+        .global myStr
+        .type myStr, %object
+myStr:
+        .string "test string"
+
+
+ at CHECK:     .word   0x00000000
+ at CHECK-DAG: 74 65 73 74 20 73 74 72         test str

Added: llvm/trunk/test/tools/llvm-objdump/X86/disassemble-code-data-mix.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/X86/disassemble-code-data-mix.s?rev=279770&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objdump/X86/disassemble-code-data-mix.s (added)
+++ llvm/trunk/test/tools/llvm-objdump/X86/disassemble-code-data-mix.s Thu Aug 25 14:41:08 2016
@@ -0,0 +1,19 @@
+// RUN: llvm-mc %s -filetype=obj -triple=x86_64-pc-linux | llvm-objdump -d - | FileCheck %s
+        .text
+        .globl  foo
+        .type   foo, @function
+foo:
+        pushq   %rbp
+        movq    %rsp, %rbp
+        movl    $0, %eax
+        popq    %rbp
+        ret
+
+        .globl bar
+        .type bar, @object
+bar:
+        .string "test string"
+
+// CHECK:        b:        74 65 73 74 20 73 74 72         test str
+// CHECK-NEXT:  13:        69 6e 67 00                     ing.
+

Modified: llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp?rev=279770&r1=279769&r2=279770&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp (original)
+++ llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp Thu Aug 25 14:41:08 2016
@@ -457,6 +457,15 @@ void SourcePrinter::printSourceLine(raw_
   OldLineInfo = LineInfo;
 }
 
+static bool isArmElf(const ObjectFile *Obj) {
+  return (Obj->isELF() &&
+          (Obj->getArch() == Triple::aarch64 ||
+           Obj->getArch() == Triple::aarch64_be ||
+           Obj->getArch() == Triple::arm || Obj->getArch() == Triple::armeb ||
+           Obj->getArch() == Triple::thumb ||
+           Obj->getArch() == Triple::thumbeb));
+}
+
 class PrettyPrinter {
 public:
   virtual ~PrettyPrinter(){}
@@ -1131,12 +1140,10 @@ static void DisassembleObject(const Obje
     section_iterator SecI = *SectionOrErr;
     if (SecI == Obj->section_end())
       continue;
-    
-    // For AMDGPU we need to track symbol types
+
     uint8_t SymbolType = ELF::STT_NOTYPE;
-    if (Obj->isELF() && Obj->getArch() == Triple::amdgcn) {
+    if (Obj->isELF())
       SymbolType = getElfSymbolType(Obj, Symbol);
-    }
 
     AllSymbols[*SecI].emplace_back(Address, *Name, SymbolType);
 
@@ -1193,7 +1200,7 @@ static void DisassembleObject(const Obje
     SectionSymbolsTy &Symbols = AllSymbols[Section];
     std::vector<uint64_t> DataMappingSymsAddr;
     std::vector<uint64_t> TextMappingSymsAddr;
-    if (Obj->isELF() && Obj->getArch() == Triple::aarch64) {
+    if (isArmElf(Obj)) {
       for (const auto &Symb : Symbols) {
         uint64_t Address = std::get<0>(Symb);
         StringRef Name = std::get<1>(Symb);
@@ -1201,6 +1208,10 @@ static void DisassembleObject(const Obje
           DataMappingSymsAddr.push_back(Address - SectionAddr);
         if (Name.startswith("$x"))
           TextMappingSymsAddr.push_back(Address - SectionAddr);
+        if (Name.startswith("$a"))
+          TextMappingSymsAddr.push_back(Address - SectionAddr);
+        if (Name.startswith("$t"))
+          TextMappingSymsAddr.push_back(Address - SectionAddr);
       }
     }
 
@@ -1234,7 +1245,10 @@ static void DisassembleObject(const Obje
 
     // If the section has no symbol at the start, just insert a dummy one.
     if (Symbols.empty() || std::get<0>(Symbols[0]) != 0) {
-      Symbols.insert(Symbols.begin(), std::make_tuple(SectionAddr, name, ELF::STT_NOTYPE));
+      Symbols.insert(Symbols.begin(),
+                     std::make_tuple(SectionAddr, name, Section.isText()
+                                                            ? ELF::STT_FUNC
+                                                            : ELF::STT_OBJECT));
     }
 
     SmallString<40> Comments;
@@ -1296,8 +1310,10 @@ static void DisassembleObject(const Obje
 
         // AArch64 ELF binaries can interleave data and text in the
         // same section. We rely on the markers introduced to
-        // understand what we need to dump.
-        if (Obj->isELF() && Obj->getArch() == Triple::aarch64) {
+        // understand what we need to dump. If the data marker is within a
+        // function, it is denoted as a word/short etc
+        if (isArmElf(Obj) && std::get<2>(Symbols[si]) != ELF::STT_OBJECT &&
+            !DisassembleAll) {
           uint64_t Stride = 0;
 
           auto DAI = std::lower_bound(DataMappingSymsAddr.begin(),
@@ -1310,15 +1326,41 @@ static void DisassembleObject(const Obje
               if (Index + 4 <= End) {
                 Stride = 4;
                 dumpBytes(Bytes.slice(Index, 4), outs());
-                outs() << "\t.word";
+                outs() << "\t.word\t";
+                uint32_t Data = 0;
+                if (Obj->isLittleEndian()) {
+                  const auto Word =
+                      reinterpret_cast<const support::ulittle32_t *>(
+                          Bytes.data() + Index);
+                  Data = *Word;
+                } else {
+                  const auto Word = reinterpret_cast<const support::ubig32_t *>(
+                      Bytes.data() + Index);
+                  Data = *Word;
+                }
+                outs() << "0x" << format("%08" PRIx32, Data);
               } else if (Index + 2 <= End) {
                 Stride = 2;
                 dumpBytes(Bytes.slice(Index, 2), outs());
-                outs() << "\t.short";
+                outs() << "\t\t.short\t";
+                uint16_t Data = 0;
+                if (Obj->isLittleEndian()) {
+                  const auto Short =
+                      reinterpret_cast<const support::ulittle16_t *>(
+                          Bytes.data() + Index);
+                  Data = *Short;
+                } else {
+                  const auto Short =
+                      reinterpret_cast<const support::ubig16_t *>(Bytes.data() +
+                                                                  Index);
+                  Data = *Short;
+                }
+                outs() << "0x" << format("%04" PRIx16, Data);
               } else {
                 Stride = 1;
                 dumpBytes(Bytes.slice(Index, 1), outs());
-                outs() << "\t.byte";
+                outs() << "\t\t.byte\t";
+                outs() << "0x" << format("%02" PRIx8, Bytes.slice(Index, 1)[0]);
               }
               Index += Stride;
               outs() << "\n";
@@ -1330,9 +1372,50 @@ static void DisassembleObject(const Obje
           }
         }
 
+        // If there is a data symbol inside an ELF text section and we are only
+        // disassembling text (applicable all architectures),
+        // we are in a situation where we must print the data and not
+        // disassemble it.
+        if (Obj->isELF() && std::get<2>(Symbols[si]) == ELF::STT_OBJECT &&
+            !DisassembleAll && Section.isText()) {
+          // print out data up to 8 bytes at a time in hex and ascii
+          uint8_t AsciiData[9] = {'\0'};
+          uint8_t Byte;
+          int NumBytes = 0;
+
+          for (Index = Start; Index < End; Index += 1) {
+            if (NumBytes == 0) {
+              outs() << format("%8" PRIx64 ":", SectionAddr + Index);
+              outs() << "\t";
+            }
+            Byte = Bytes.slice(Index)[0];
+            outs() << format(" %02x", Byte);
+            AsciiData[NumBytes] = isprint(Byte) ? Byte : '.';
+
+            uint8_t IndentOffset = 0;
+            NumBytes++;
+            if (Index == End - 1 || NumBytes > 8) {
+              // Indent the space for less than 8 bytes data.
+              // 2 spaces for byte and one for space between bytes
+              IndentOffset = 3 * (8 - NumBytes);
+              for (int Excess = 8 - NumBytes; Excess < 8; Excess++)
+                AsciiData[Excess] = '\0';
+              NumBytes = 8;
+            }
+            if (NumBytes == 8) {
+              AsciiData[8] = '\0';
+              outs() << std::string(IndentOffset, ' ') << "         ";
+              outs() << reinterpret_cast<char *>(AsciiData);
+              outs() << '\n';
+              NumBytes = 0;
+            }
+          }
+        }
         if (Index >= End)
           break;
 
+        // Disassemble a real instruction or a data when disassemble all is
+        // provided
         bool Disassembled = DisAsm->getInstruction(Inst, Size, Bytes.slice(Index),
                                                    SectionAddr + Index, DebugOut,
                                                    CommentStream);




More information about the llvm-commits mailing list