In r219544 (2014-10-10) I changed the default disassembly format to more 
closely resemble gdb's disassembly format.  After living on this format for a 
few months, there are obvious shortcomings with C++ and Objective-C programs 
and I want to try a new approach.

Originally lldb's disassembly would display the Module & Function/Symbol name 
on a line by itself when a new function/symbol began, on each line of assembly 
display the file/load address followed by opcode, operands, and comments (e.g. 
showing the target of a branch insn).  Branches to the same function would have 
a comment listing the full function name plus an offset.  Note that the 
addresses did not display the offset, just raw addresses, meaning you had to 
compare the full address of the branch target with the disassembly output to 
find the target of the branch.  When the branch target was in inlined code, 
lldb would print all of the inlined functions in the comment field (on separate 
lines).

In October I changed this to more closely resemble gdb's output:  Each line has 
the file/load address, the function name, the offset into the function ("+35"), 
opcode, operand, comment. Comments pointing to the same function behaved the 
same but inlined functions were not included.  I try to elide function argument 
types (e.g. from a demangled C++ name) but with templated methods it can be 
enormous.

This style of disassembly looks pretty good for short C function names.  Like

(lldb) disass -c 20
   0x7fff94fbe188 <mach_msg_trap>: movq   %rcx, %r10
   0x7fff94fbe18b <mach_msg_trap+3>: movl   $0x100001f, %eax
   0x7fff94fbe190 <mach_msg_trap+8>: syscall 
-> 0x7fff94fbe192 <mach_msg_trap+10>: retq   
   0x7fff94fbe193 <mach_msg_trap+11>: nop    
   0x7fff94fbe194 <mach_msg_overwrite_trap>: movq   %rcx, %r10
  
but as soon as you get a hefty C++ name in there, it becomes very messy:

0x107915454 <CommandObjectBreakpointList::DoExecute+68>: jne    0x1be9331       
          ; CommandObjectBreakpointList::DoExecute + 113 at 
CommandObjectBreakpoint.cpp:1420

Or, an extreme example that I found in lldb with 30 seconds of looking 
(function name only) -

std::__1::function<std::__1::shared_ptr<lldb_private::TypeSummaryImpl> 
(lldb_private::ValueObject&)>::function<CommandObjectTypeSummary::CommandObjectTypeSummary(lldb_private::CommandInterpreter&)::'lambda'(lldb_private::ValueObject&)>


I want to go with a hybrid approach between these two styles.  When there is a 
new symbol, we print the full module + function name.  On each assembly line, 
we print the file/load address, the offset into the function in angle brackets, 
opcode, operand, and in the comments branches to the SAME function follow the 
<+36> style.  An example:


(lldb) disass
LLDB`CommandObjectBreakpointList::DoExecute:
    0x107915410 <+0>:    pushq  %rbp
    0x107915411 <+1>:    movq   %rsp, %rbp
    0x107915414 <+4>:    subq   $0x170, %rsp
    0x10791541b <+11>:   movq   %rdi, -0x20(%rbp)
    0x10791541f <+15>:   movq   %rsi, -0x28(%rbp)
    0x107915423 <+19>:   movq   %rdx, -0x30(%rbp)
    0x107915427 <+23>:   movq   -0x20(%rbp), %rdx
->  0x10791542b <+27>:   movq   %rdx, %rsi
    0x10791542e <+30>:   movb   0x165(%rdx), %al
    0x107915434 <+36>:   andb   $0x1, %al
    0x107915436 <+38>:   movq   %rsi, %rdi
    0x107915439 <+41>:   movzbl %al, %esi
    0x10791543c <+44>:   movq   %rdx, -0xf8(%rbp)
    0x107915443 <+51>:   callq  0x107d87bb0               ; 
lldb_private::CommandObject::GetSelectedOrDummyTarget at CommandObject.cpp:1045
    0x107915448 <+56>:   movq   %rax, -0x38(%rbp)
    0x10791544c <+60>:   cmpq   $0x0, -0x38(%rbp)
    0x107915454 <+68>:   jne    0x107915481               ; <+113> at 
CommandObjectBreakpoint.cpp:1420
    0x10791545a <+74>:   leaq   0xf54d21(%rip), %rsi      ; "Invalid target. No 
current target or breakpoints."
    0x107915461 <+81>:   movq   -0x30(%rbp), %rdi
    0x107915465 <+85>:   callq  0x107d93640               ; 
lldb_private::CommandReturnObject::AppendError at CommandReturnObject.cpp:135
    0x10791546a <+90>:   movl   $0x1, %esi
    0x10791546f <+95>:   movq   -0x30(%rbp), %rdi
    0x107915473 <+99>:   callq  0x107d93760               ; 
lldb_private::CommandReturnObject::SetStatus at CommandReturnObject.cpp:172
    0x107915478 <+104>:  movb   $0x1, -0x11(%rbp)
    0x10791547c <+108>:  jmp    0x1079158bd               ; <+1197> at 
CommandObjectBreakpoint.cpp:1470
    0x107915481 <+113>:  movq   -0x38(%rbp), %rdi

The main drawback for this new arrangement is that you may be looking at a long 
series of instructions and forget the name of the function/method.  You'll need 
to scroll backwards to the beginning of the disassembly to find this function's 
names.  Minor details include doing a two-pass over the instruction list to 
find the maximum length of the address component and padding all the lines so 
the opcodes line up.  For instance,

(lldb)  disass -c 30 -n mach_msg_trap
libsystem_kernel.dylib`mach_msg_trap:
    0x7fff94fbe188 <+0>:  movq   %rcx, %r10
    0x7fff94fbe18b <+3>:  movl   $0x100001f, %eax
    0x7fff94fbe190 <+8>:  syscall 
    0x7fff94fbe192 <+10>: retq   
    0x7fff94fbe193 <+11>: nop    

dyld`mach_msg_trap:
    0x7fff6a867210 <+0>:  movq   %rcx, %r10
    0x7fff6a867213 <+3>:  movl   $0x100001f, %eax
    0x7fff6a867218 <+8>:  syscall 
    0x7fff6a86721a <+10>: retq   
    0x7fff6a86721b <+11>: nop    


The disassembly format can be overridden by the 'disassembly-format' setting if 
people have specific preferences.  But I think this new hybrid style of 
disassembly will work the best as a default given the kinds of method names we 
see with OO languages.

Comments?  I'd like to land this in a couple days if no one feels strongly 
about it.

REPOSITORY
  rL LLVM

http://reviews.llvm.org/D7578

Files:
  include/lldb/Core/Address.h
  include/lldb/Core/Disassembler.h
  include/lldb/Core/FormatEntity.h
  include/lldb/Symbol/SymbolContext.h
  source/API/SBInstruction.cpp
  source/API/SBInstructionList.cpp
  source/Breakpoint/BreakpointLocation.cpp
  source/Commands/CommandObjectSource.cpp
  source/Core/Address.cpp
  source/Core/Debugger.cpp
  source/Core/Disassembler.cpp
  source/Core/FormatEntity.cpp
  source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
  source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
  source/Symbol/SymbolContext.cpp
  source/Symbol/Variable.cpp
  source/Target/StackFrame.cpp
  source/Target/ThreadPlanTracer.cpp
  test/functionalities/abbreviation/TestAbbreviations.py
  test/functionalities/inferior-assert/TestInferiorAssert.py

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
Index: include/lldb/Core/Address.h
===================================================================
--- include/lldb/Core/Address.h
+++ include/lldb/Core/Address.h
@@ -88,6 +88,8 @@
                                         ///< if the address is in a section (section of pointers, c strings, etc).
         DumpStyleResolvedDescriptionNoModule,
         DumpStyleResolvedDescriptionNoFunctionArguments,
+        DumpStyleNoFunctionName,        ///< Elide the function name; display an offset into the current function.
+                                        ///< Used primarily in disassembly symbolication
         DumpStyleDetailedSymbolContext, ///< Detailed symbol context information for an address for all symbol
                                         ///< context members.
         DumpStyleResolvedPointerDescription ///< Dereference a pointer at the current address and then lookup the
Index: include/lldb/Core/Disassembler.h
===================================================================
--- include/lldb/Core/Disassembler.h
+++ include/lldb/Core/Disassembler.h
@@ -120,6 +120,12 @@
     /// @param[in] disassembly_addr_format
     ///     The format specification for how addresses are printed.
     ///     Only needed if show_address is true.
+    ///
+    /// @param[in] max_address_text_size
+    ///     The length of the longest address string at the start of the
+    ///     disassembly line that will be printed (the Debugger::FormatDisassemblerAddress() string)
+    ///     so this method can properly align the instruction opcodes.
+    ///     May be 0 to indicate no indentation/alignment of the opcodes.
     //------------------------------------------------------------------
 
     virtual void
@@ -130,7 +136,8 @@
           const ExecutionContext* exe_ctx,
           const SymbolContext *sym_ctx,
           const SymbolContext *prev_sym_ctx,
-          const FormatEntity::Entry *disassembly_addr_format);
+          const FormatEntity::Entry *disassembly_addr_format,
+          size_t max_address_text_size);
     
     virtual bool
     DoesBranch () = 0;
Index: include/lldb/Core/FormatEntity.h
===================================================================
--- include/lldb/Core/FormatEntity.h
+++ include/lldb/Core/FormatEntity.h
@@ -78,6 +78,8 @@
                 FunctionAddrOffsetConcrete,
                 FunctionLineOffset,
                 FunctionPCOffset,
+                FunctionInitial,
+                FunctionChanged,
                 LineEntryFile,
                 LineEntryLineNumber,
                 LineEntryStartAddress,
Index: include/lldb/Symbol/SymbolContext.h
===================================================================
--- include/lldb/Symbol/SymbolContext.h
+++ include/lldb/Symbol/SymbolContext.h
@@ -161,6 +161,32 @@
     ///
     /// @param[in] so_addr
     ///     The resolved section offset address.
+    ///
+    /// @param[in] show_fullpaths
+    ///     When printing file paths (with the Module), whether the
+    ///     base name of the Module should be printed or the full path.
+    ///     
+    /// @param[in] show_module
+    ///     Whether the module name should be printed followed by a 
+    ///     grave accent "`" character.
+    ///
+    /// @param[in] show_inlined_frames
+    ///     If a given pc is in inlined function(s), whether the inlined
+    ///     functions should be printed on separate lines in addition to
+    ///     the concrete function containing the pc.
+    ///
+    /// @param[in] show_function_arguments
+    ///     If false, this method will try to elide the function argument
+    ///     types when printing the function name.  This may be ambiguous
+    ///     for languages that have function overloading - but it may
+    ///     make the "function name" too long to include all the argument
+    ///     types.
+    ///
+    /// @param[in] show_function_name
+    ///     Normally this should be true - the function/symbol name should
+    ///     be printed.  In disassembly formatting, where we want a format
+    ///     like "<*+36>", this should be false and "*" will be printed
+    ///     instead.
     //------------------------------------------------------------------
     bool
     DumpStopContext (Stream *s,
@@ -169,7 +195,8 @@
                      bool show_fullpaths,
                      bool show_module,
                      bool show_inlined_frames,
-                     bool show_function_arguments) const;
+                     bool show_function_arguments,
+                     bool show_function_name) const;
 
     //------------------------------------------------------------------
     /// Get the address range contained within a symbol context.
Index: source/API/SBInstruction.cpp
===================================================================
--- source/API/SBInstruction.cpp
+++ source/API/SBInstruction.cpp
@@ -180,7 +180,7 @@
         // didn't have a stream already created, one will get created...
         FormatEntity::Entry format;
         FormatEntity::Parse("${addr}: ", format);
-        m_opaque_sp->Dump (&s.ref(), 0, true, false, NULL, &sc, NULL, &format);
+        m_opaque_sp->Dump (&s.ref(), 0, true, false, NULL, &sc, NULL, &format, 0);
         return true;
     }
     return false;
@@ -202,7 +202,7 @@
         StreamFile out_stream (out, false);
         FormatEntity::Entry format;
         FormatEntity::Parse("${addr}: ", format);
-        m_opaque_sp->Dump (&out_stream, 0, true, false, NULL, &sc, NULL, &format);
+        m_opaque_sp->Dump (&out_stream, 0, true, false, NULL, &sc, NULL, &format, 0);
     }
 }
 
Index: source/API/SBInstructionList.cpp
===================================================================
--- source/API/SBInstructionList.cpp
+++ source/API/SBInstructionList.cpp
@@ -120,7 +120,7 @@
                     module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
                 }
 
-                inst->Dump (&sref, max_opcode_byte_size, true, false, NULL, &sc, &prev_sc, &format);
+                inst->Dump (&sref, max_opcode_byte_size, true, false, NULL, &sc, &prev_sc, &format, 0);
                 sref.EOL();
             }
             return true;
Index: source/Breakpoint/BreakpointLocation.cpp
===================================================================
--- source/Breakpoint/BreakpointLocation.cpp
+++ source/Breakpoint/BreakpointLocation.cpp
@@ -590,7 +590,7 @@
                 s->PutCString ("re-exported target = ");
             else
                 s->PutCString("where = ");
-            sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false, true);
+            sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false, true, true);
         }
         else
         {
Index: source/Commands/CommandObjectSource.cpp
===================================================================
--- source/Commands/CommandObjectSource.cpp
+++ source/Commands/CommandObjectSource.cpp
@@ -690,13 +690,15 @@
                     bool show_module = true;
                     bool show_inlined_frames = true;
                     const bool show_function_arguments = true;
+                    const bool show_function_name = true;
                     sc.DumpStopContext(&result.GetOutputStream(),
                                        m_exe_ctx.GetBestExecutionContextScope(),
                                        sc.line_entry.range.GetBaseAddress(),
                                        show_fullpaths,
                                        show_module,
                                        show_inlined_frames,
-                                       show_function_arguments);
+                                       show_function_arguments,
+                                       show_function_name);
                     result.GetOutputStream().EOL();
 
                     if (m_options.num_lines == 0)
Index: source/Core/Address.cpp
===================================================================
--- source/Core/Address.cpp
+++ source/Core/Address.cpp
@@ -468,6 +468,7 @@
     case DumpStyleResolvedDescription:
     case DumpStyleResolvedDescriptionNoModule:
     case DumpStyleResolvedDescriptionNoFunctionArguments:
+    case DumpStyleNoFunctionName:
         if (IsSectionOffset())
         {
             uint32_t pointer_size = 4;
@@ -553,7 +554,7 @@
 #endif
                                     Address cstr_addr(*this);
                                     cstr_addr.SetOffset(cstr_addr.GetOffset() + pointer_size);
-                                    func_sc.DumpStopContext(s, exe_scope, so_addr, true, true, false, true);
+                                    func_sc.DumpStopContext(s, exe_scope, so_addr, true, true, false, true, true);
                                     if (ReadAddress (exe_scope, cstr_addr, pointer_size, so_addr))
                                     {
 #if VERBOSE_OUTPUT
@@ -636,7 +637,7 @@
                                     if (pointer_sc.function || pointer_sc.symbol)
                                     {
                                         s->PutCString(": ");
-                                        pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false, false, true);
+                                        pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false, false, true, true);
                                     }
                                 }
                             }
@@ -662,6 +663,7 @@
                         const bool show_fullpaths = false; 
                         const bool show_inlined_frames = true;
                         const bool show_function_arguments = (style != DumpStyleResolvedDescriptionNoFunctionArguments);
+                        const bool show_function_name = (style != DumpStyleNoFunctionName);
                         if (sc.function == NULL && sc.symbol != NULL)
                         {
                             // If we have just a symbol make sure it is in the right section
@@ -684,7 +686,8 @@
                                                 show_fullpaths, 
                                                 show_module, 
                                                 show_inlined_frames,
-                                                show_function_arguments);
+                                                show_function_arguments,
+                                                show_function_name);
                         }
                         else
                         {
Index: source/Core/Debugger.cpp
===================================================================
--- source/Core/Debugger.cpp
+++ source/Core/Debugger.cpp
@@ -126,8 +126,22 @@
     FILE_AND_LINE\
     "\\n"
 
-#define DEFAULT_DISASSEMBLY_FORMAT "${current-pc-arrow}${addr-file-or-load}{ <${function.name-without-args}${function.concrete-only-addr-offset-no-padding}>}: "
+// Three parts to this disassembly format specification:
+//   1. If this is a new function/symbol (no previous symbol/function), print
+//      dylib`funcname:\n
+//   2. If this is a symbol context change (different from previous symbol/function), print
+//      dylib`funcname:\n
+//   3. print 
+//      address <+offset>: 
+#define DEFAULT_DISASSEMBLY_FORMAT "{${function.initial-function}{${module.file.basename}`}{${function.name-without-args}}:\n}{${function.changed}\n{${module.file.basename}`}{${function.name-without-args}}:\n}{${current-pc-arrow} }${addr-file-or-load}{ <${function.concrete-only-addr-offset-no-padding}>}: "
 
+// gdb's disassembly format can be emulated with
+// ${current-pc-arrow}${addr-file-or-load}{ <${function.name-without-args}${function.concrete-only-addr-offset-no-padding}>}: 
+
+// lldb's original format for disassembly would look like this format string -
+// {${function.initial-function}{${module.file.basename}`}{${function.name-without-args}}:\n}{${function.changed}\n{${module.file.basename}`}{${function.name-without-args}}:\n}{${current-pc-arrow} }{${addr-file-or-load}}: 
+
+
 static PropertyDefinition
 g_properties[] =
 {
Index: source/Core/Disassembler.cpp
===================================================================
--- source/Core/Disassembler.cpp
+++ source/Core/Disassembler.cpp
@@ -421,12 +421,53 @@
     }
     const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
     const bool use_inline_block_range = false;
+
+    const FormatEntity::Entry *disassembly_format = NULL;
+    FormatEntity::Entry format;
+    if (exe_ctx.HasTargetScope())
+    {
+        disassembly_format = exe_ctx.GetTargetRef().GetDebugger().GetDisassemblyFormat ();
+    }
+    else
+    {
+        FormatEntity::Parse("${addr}: ", format);
+        disassembly_format = &format;
+    }
+
+    // First pass: step through the list of instructions, 
+    // find how long the initial addresses strings are, insert padding 
+    // in the second pass so the opcodes all line up nicely.
+    size_t address_text_size = 0;
     for (size_t i = 0; i < num_instructions_found; ++i)
     {
         Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
         if (inst)
         {
             const Address &addr = inst->GetAddress();
+            ModuleSP module_sp (addr.GetModule());
+            if (module_sp)
+            {
+                const uint32_t resolve_mask = eSymbolContextFunction | eSymbolContextSymbol;
+                uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, resolve_mask, sc);
+                if (resolved_mask)
+                {
+                    StreamString strmstr;
+                    Debugger::FormatDisassemblerAddress (disassembly_format, &sc, NULL, &exe_ctx, &addr, strmstr);
+                    size_t cur_line = strmstr.GetSizeOfLastLine();
+                    if (cur_line > address_text_size)
+                        address_text_size = cur_line;
+                }
+                sc.Clear(false);
+            }
+        }
+    }
+
+    for (size_t i = 0; i < num_instructions_found; ++i)
+    {
+        Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
+        if (inst)
+        {
+            const Address &addr = inst->GetAddress();
             const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;
 
             prev_sc = sc;
@@ -448,7 +489,7 @@
                                 if (offset != 0)
                                     strm.EOL();
                                 
-                                sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false, false);
+                                sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false, false, true);
                                 strm.EOL();
                                 
                                 if (sc.comp_unit && sc.line_entry.IsValid())
@@ -471,7 +512,7 @@
             }
 
             const bool show_bytes = (options & eOptionShowBytes) != 0;
-            inst->Dump (&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, &sc, &prev_sc, NULL);
+            inst->Dump (&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, &sc, &prev_sc, NULL, address_text_size);
             strm.EOL();            
         }
         else
@@ -561,7 +602,8 @@
                    const ExecutionContext* exe_ctx,
                    const SymbolContext *sym_ctx,
                    const SymbolContext *prev_sym_ctx,
-                   const FormatEntity::Entry *disassembly_addr_format)
+                   const FormatEntity::Entry *disassembly_addr_format,
+                   size_t max_address_text_size)
 {
     size_t opcode_column_width = 7;
     const size_t operand_column_width = 25;
@@ -573,6 +615,7 @@
     if (show_address)
     {
         Debugger::FormatDisassemblerAddress (disassembly_addr_format, sym_ctx, prev_sym_ctx, exe_ctx, &m_address, ss);
+        ss.FillLastLineToColumn (max_address_text_size, ' ');
     }
     
     if (show_bytes)
@@ -999,7 +1042,7 @@
     {
         if (pos != begin)
             s->EOL();
-        (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx, NULL, NULL, disassembly_format);
+        (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx, NULL, NULL, disassembly_format, 0);
     }
 }
 
Index: source/Core/FormatEntity.cpp
===================================================================
--- source/Core/FormatEntity.cpp
+++ source/Core/FormatEntity.cpp
@@ -94,7 +94,9 @@
     ENTRY ("addr-offset"         , FunctionAddrOffset     , UInt64),
     ENTRY ("concrete-only-addr-offset-no-padding", FunctionAddrOffsetConcrete, UInt64),
     ENTRY ("line-offset"         , FunctionLineOffset     , UInt64),
-    ENTRY ("pc-offset"           , FunctionPCOffset       , UInt64)
+    ENTRY ("pc-offset"           , FunctionPCOffset       , UInt64),
+    ENTRY ("initial-function"    , FunctionInitial        , None),
+    ENTRY ("changed"             , FunctionChanged        , None)
 };
 
 static FormatEntity::Entry::Definition g_line_child_entries[] =
@@ -335,6 +337,8 @@
     ENUM_TO_CSTR(FunctionAddrOffsetConcrete);
     ENUM_TO_CSTR(FunctionLineOffset);
     ENUM_TO_CSTR(FunctionPCOffset);
+    ENUM_TO_CSTR(FunctionInitial);
+    ENUM_TO_CSTR(FunctionChanged);
     ENUM_TO_CSTR(LineEntryFile);
     ENUM_TO_CSTR(LineEntryLineNumber);
     ENUM_TO_CSTR(LineEntryStartAddress);
@@ -444,7 +448,8 @@
                                const ExecutionContext *exe_ctx,
                                const Address &format_addr,
                                bool concrete_only,
-                               bool no_padding)
+                               bool no_padding,
+                               bool print_zero_offsets)
 {
     if (format_addr.IsValid())
     {
@@ -479,10 +484,15 @@
             {
                 addr_t func_file_addr = func_addr.GetFileAddress();
                 addr_t addr_file_addr = format_addr.GetFileAddress();
-                if (addr_file_addr > func_file_addr)
+                if (addr_file_addr > func_file_addr
+                    || (addr_file_addr == func_file_addr && print_zero_offsets))
+                {
                     s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding, addr_file_addr - func_file_addr);
+                }
                 else if (addr_file_addr < func_file_addr)
+                {
                     s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding, func_file_addr - addr_file_addr);
+                }
                 return true;
             }
             else
@@ -492,10 +502,15 @@
                 {
                     addr_t func_load_addr = func_addr.GetLoadAddress (target);
                     addr_t addr_load_addr = format_addr.GetLoadAddress (target);
-                    if (addr_load_addr > func_load_addr)
+                    if (addr_load_addr > func_load_addr
+                        || (addr_load_addr == func_load_addr && print_zero_offsets))
+                    {
                         s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding, addr_load_addr - func_load_addr);
+                    }
                     else if (addr_load_addr < func_load_addr)
+                    {
                         s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding, func_load_addr - addr_load_addr);
+                    }
                     return true;
                 }
             }
@@ -1803,7 +1818,7 @@
         case Entry::Type::FunctionAddrOffset:
             if (addr)
             {
-                if (DumpAddressOffsetFromFunction (s, sc, exe_ctx, *addr, false, false))
+                if (DumpAddressOffsetFromFunction (s, sc, exe_ctx, *addr, false, false, false))
                     return true;
             }
             return false;
@@ -1811,13 +1826,13 @@
         case Entry::Type::FunctionAddrOffsetConcrete:
             if (addr)
             {
-                if (DumpAddressOffsetFromFunction (s, sc, exe_ctx, *addr, true, true))
+                if (DumpAddressOffsetFromFunction (s, sc, exe_ctx, *addr, true, true, true))
                     return true;
             }
             return false;
 
         case Entry::Type::FunctionLineOffset:
-            if (DumpAddressOffsetFromFunction (s, sc, exe_ctx, sc->line_entry.range.GetBaseAddress(), false, false))
+            if (DumpAddressOffsetFromFunction (s, sc, exe_ctx, sc->line_entry.range.GetBaseAddress(), false, false, false))
                 return true;
             return false;
 
@@ -1827,12 +1842,18 @@
                 StackFrame *frame = exe_ctx->GetFramePtr();
                 if (frame)
                 {
-                    if (DumpAddressOffsetFromFunction (s, sc, exe_ctx, frame->GetFrameCodeAddress(), false, false))
+                    if (DumpAddressOffsetFromFunction (s, sc, exe_ctx, frame->GetFrameCodeAddress(), false, false, false))
                         return true;
                 }
             }
             return false;
 
+        case Entry::Type::FunctionChanged:
+            return function_changed == true;
+
+        case Entry::Type::FunctionInitial:
+            return initial_function == true;
+
         case Entry::Type::LineEntryFile:
             if (sc && sc->line_entry.IsValid())
             {
Index: source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
===================================================================
--- source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
+++ source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
@@ -792,25 +792,63 @@
             //std::string remove_this_prior_to_checkin;
             Target *target = m_exe_ctx ? m_exe_ctx->GetTargetPtr() : NULL;
             Address value_so_addr;
+            Address pc_so_addr;
             if (m_inst->UsingFileAddress())
             {
                 ModuleSP module_sp(m_inst->GetAddress().GetModule());
                 if (module_sp)
+                {
                     module_sp->ResolveFileAddress(value, value_so_addr);
+                    module_sp->ResolveFileAddress(pc, pc_so_addr);
+                }
             }
             else if (target && !target->GetSectionLoadList().IsEmpty())
             {
                 target->GetSectionLoadList().ResolveLoadAddress(value, value_so_addr);
+                target->GetSectionLoadList().ResolveLoadAddress(pc, pc_so_addr);
             }
 
+            SymbolContext sym_ctx;
+            const uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol;
+            if (pc_so_addr.IsValid() && pc_so_addr.GetModule())
+            {
+                pc_so_addr.GetModule()->ResolveSymbolContextForAddress (pc_so_addr, resolve_scope, sym_ctx);
+            }
+
             if (value_so_addr.IsValid() && value_so_addr.GetSection())
             {
                 StreamString ss;
 
-                value_so_addr.Dump (&ss,
-                                    target,
-                                    Address::DumpStyleResolvedDescriptionNoFunctionArguments,
-                                    Address::DumpStyleSectionNameOffset);
+                bool format_omitting_current_func_name = false;
+                if (sym_ctx.symbol || sym_ctx.function)
+                {
+                    AddressRange range;
+                    if (sym_ctx.GetAddressRange (resolve_scope, 0, false, range) 
+                        && range.GetBaseAddress().IsValid() 
+                        && range.ContainsLoadAddress (value_so_addr, target))
+                    {
+                        format_omitting_current_func_name = true;
+                    }
+                }
+                
+                // If the "value" address (the target address we're symbolicating)
+                // is inside the same SymbolContext as the current instruction pc
+                // (pc_so_addr), don't print the full function name - just print it
+                // with DumpStyleNoFunctionName style, e.g. "<*+36>".
+                if (format_omitting_current_func_name)
+                {
+                    value_so_addr.Dump (&ss,
+                                        target,
+                                        Address::DumpStyleNoFunctionName,
+                                        Address::DumpStyleSectionNameOffset);
+                }
+                else
+                {
+                    value_so_addr.Dump (&ss,
+                                        target,
+                                        Address::DumpStyleResolvedDescriptionNoFunctionArguments,
+                                        Address::DumpStyleSectionNameOffset);
+                }
 
                 if (!ss.GetString().empty())
                 {
Index: source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
===================================================================
--- source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
+++ source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
@@ -149,7 +149,7 @@
                             StreamString strm;
                             lldb_private::FormatEntity::Entry format;
                             FormatEntity::Parse("${frame.pc}: ", format);
-                            inst->Dump(&strm, inst_list.GetMaxOpcocdeByteSize (), show_address, show_bytes, NULL, NULL, NULL, &format);
+                            inst->Dump(&strm, inst_list.GetMaxOpcocdeByteSize (), show_address, show_bytes, NULL, NULL, NULL, &format, 0);
                             log->PutCString (strm.GetData());
                         }
 
Index: source/Symbol/SymbolContext.cpp
===================================================================
--- source/Symbol/SymbolContext.cpp
+++ source/Symbol/SymbolContext.cpp
@@ -129,15 +129,15 @@
 }
 
 bool
-SymbolContext::DumpStopContext
-(
+SymbolContext::DumpStopContext (
     Stream *s,
     ExecutionContextScope *exe_scope,
     const Address &addr,
     bool show_fullpaths,
     bool show_module,
     bool show_inlined_frames,
-    bool show_function_arguments
+    bool show_function_arguments,
+    bool show_function_name
 ) const
 {
     bool dumped_something = false;
@@ -155,9 +155,14 @@
     {
         SymbolContext inline_parent_sc;
         Address inline_parent_addr;
-        if (show_function_arguments == false && function->GetMangled().GetName(Mangled::ePreferDemangledWithoutArguments))
+        if (show_function_name == false)
         {
+            s->Printf("<");
             dumped_something = true;
+        }
+        else if (show_function_arguments == false && function->GetMangled().GetName(Mangled::ePreferDemangledWithoutArguments))
+        {
+            dumped_something = true;
             function->GetMangled().GetName(Mangled::ePreferDemangledWithoutArguments).Dump(s);
         }
         else if (function->GetMangled().GetName())
@@ -169,9 +174,15 @@
         if (addr.IsValid())
         {
             const addr_t function_offset = addr.GetOffset() - function->GetAddressRange().GetBaseAddress().GetOffset();
-            if (function_offset)
+            if (show_function_name == false)
             {
+                // Print +offset even if offset is 0
                 dumped_something = true;
+                s->Printf("+%" PRIu64 ">", function_offset);
+            }
+            else if (function_offset)
+            {
+                dumped_something = true;
                 s->Printf(" + %" PRIu64, function_offset);
             }
         }
@@ -202,7 +213,8 @@
             {
                 s->EOL();
                 s->Indent();
-                return inline_parent_sc.DumpStopContext (s, exe_scope, inline_parent_addr, show_fullpaths, show_module, show_inlined_frames, show_function_arguments);
+                const bool show_function_name = true;
+                return inline_parent_sc.DumpStopContext (s, exe_scope, inline_parent_addr, show_fullpaths, show_module, show_inlined_frames, show_function_arguments, show_function_name);
             }
         }
         else
@@ -218,9 +230,14 @@
     }
     else if (symbol != nullptr)
     {
-        if (symbol->GetMangled().GetName())
+        if (show_function_name == false)
         {
+            s->Printf("<");
             dumped_something = true;
+        }
+        else if (symbol->GetMangled().GetName())
+        {
+            dumped_something = true;
             if (symbol->GetType() == eSymbolTypeTrampoline)
                 s->PutCString("symbol stub for: ");
             symbol->GetMangled().GetName().Dump(s);
@@ -229,9 +246,15 @@
         if (addr.IsValid() && symbol->ValueIsAddress())
         {
             const addr_t symbol_offset = addr.GetOffset() - symbol->GetAddress().GetOffset();
-            if (symbol_offset)
+            if (show_function_name == false)
             {
+                // Print +offset even if offset is 0
                 dumped_something = true;
+                s->Printf("+%" PRIu64 ">", symbol_offset);
+            }
+            else if (symbol_offset)
+            {
+                dumped_something = true;
                 s->Printf(" + %" PRIu64, symbol_offset);
             }
         }
Index: source/Symbol/Variable.cpp
===================================================================
--- source/Symbol/Variable.cpp
+++ source/Symbol/Variable.cpp
@@ -175,6 +175,7 @@
         sc.line_entry.Clear();
         bool show_inlined_frames = false;
         const bool show_function_arguments = true;
+        const bool show_function_name = true;
     
         dumped_declaration_info = sc.DumpStopContext (s, 
                                                       nullptr,
@@ -182,7 +183,8 @@
                                                       show_fullpaths, 
                                                       show_module, 
                                                       show_inlined_frames,
-                                                      show_function_arguments);
+                                                      show_function_arguments,
+                                                      show_function_name);
         
         if (sc.function)
             s->PutChar(':');
Index: source/Target/StackFrame.cpp
===================================================================
--- source/Target/StackFrame.cpp
+++ source/Target/StackFrame.cpp
@@ -1406,13 +1406,15 @@
     const bool show_module = true;
     const bool show_inline = true;
     const bool show_function_arguments = true;
+    const bool show_function_name = true;
     m_sc.DumpStopContext (strm, 
                           exe_ctx.GetBestExecutionContextScope(), 
                           GetFrameCodeAddress(), 
                           show_fullpaths, 
                           show_module, 
                           show_inline,
-                          show_function_arguments);
+                          show_function_arguments,
+                          show_function_name);
 }
 
 void
Index: source/Target/ThreadPlanTracer.cpp
===================================================================
--- source/Target/ThreadPlanTracer.cpp
+++ source/Target/ThreadPlanTracer.cpp
@@ -220,7 +220,8 @@
                                    NULL,
                                    NULL,
                                    NULL,
-                                   disassemble_format);
+                                   disassemble_format,
+                                   0);
             }
         }
     }
Index: test/functionalities/abbreviation/TestAbbreviations.py
===================================================================
--- test/functionalities/abbreviation/TestAbbreviations.py
+++ test/functionalities/abbreviation/TestAbbreviations.py
@@ -150,8 +150,8 @@
         # ARCH, if not specified, defaults to x86_64.
         if self.getArchitecture() in ["", 'x86_64', 'i386']:
             self.expect("dis -f",
-                        substrs = ['<sum(int, int)>:',
-                                   ' mov',
+                        startstr = "a.out`sum(int, int)",
+                        substrs = [' mov',
                                    ' addl ',
                                    'ret'])
 
Index: test/functionalities/inferior-assert/TestInferiorAssert.py
===================================================================
--- test/functionalities/inferior-assert/TestInferiorAssert.py
+++ test/functionalities/inferior-assert/TestInferiorAssert.py
@@ -186,7 +186,7 @@
             if frame.GetFrameID() == 0:
                 pc_backup_offset = 0
             self.expect("disassemble -a %s" % (frame.GetPC() - pc_backup_offset),
-                    substrs = ['<%s>:' % frame.GetFunctionName()])
+                    substrs = ['<+0>: '])
 
     def check_expr_in_main(self, thread):
         depth = thread.GetNumFrames()
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits

Reply via email to