https://github.com/junior-jl updated https://github.com/llvm/llvm-project/pull/69422
From 8e5e67ff640aa0ff14b1a0bd0110b88c539ccfe8 Mon Sep 17 00:00:00 2001 From: taalhaataahir0102 <23100...@lums.edu.pk> Date: Wed, 11 Oct 2023 14:27:15 +0500 Subject: [PATCH 1/3] colorization --- lldb/include/lldb/Core/Address.h | 6 + lldb/include/lldb/Symbol/Symbol.h | 3 + lldb/include/lldb/Symbol/SymbolContext.h | 11 + lldb/source/Commands/CommandObjectTarget.cpp | 97 ++++- lldb/source/Core/Address.cpp | 428 +++++++++++++++++++ lldb/source/Symbol/Symbol.cpp | 68 +++ lldb/source/Symbol/SymbolContext.cpp | 248 +++++++++++ 7 files changed, 859 insertions(+), 2 deletions(-) diff --git a/lldb/include/lldb/Core/Address.h b/lldb/include/lldb/Core/Address.h index b19e694427546f8b..4151817813c7e352 100644 --- a/lldb/include/lldb/Core/Address.h +++ b/lldb/include/lldb/Core/Address.h @@ -249,6 +249,12 @@ class Address { uint32_t addr_byte_size = UINT32_MAX, bool all_ranges = false) const; + + bool Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,const char* name, + DumpStyle fallback_style = DumpStyleInvalid, + uint32_t addr_byte_size = UINT32_MAX, + bool all_ranges = false) const; + AddressClass GetAddressClass() const; /// Get the file address. diff --git a/lldb/include/lldb/Symbol/Symbol.h b/lldb/include/lldb/Symbol/Symbol.h index 44a2d560010fe403..a9e91fbac055a924 100644 --- a/lldb/include/lldb/Symbol/Symbol.h +++ b/lldb/include/lldb/Symbol/Symbol.h @@ -177,6 +177,9 @@ class Symbol : public SymbolContextScope { void GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target) const; + void GetDescription(Stream *s, lldb::DescriptionLevel level, + Target *target, const char* name) const; + bool IsSynthetic() const { return m_is_synthetic; } bool IsSyntheticWithAutoGeneratedName() const; diff --git a/lldb/include/lldb/Symbol/SymbolContext.h b/lldb/include/lldb/Symbol/SymbolContext.h index b0f5ffead2a16569..947c39eec96e53a9 100644 --- a/lldb/include/lldb/Symbol/SymbolContext.h +++ b/lldb/include/lldb/Symbol/SymbolContext.h @@ -153,6 +153,14 @@ class SymbolContext { bool show_function_arguments, bool show_function_name) const; + bool DumpStopContext(Stream *s, ExecutionContextScope *exe_scope, + const Address &so_addr, bool show_fullpaths, + bool show_module, bool show_inlined_frames, + bool show_function_arguments, + bool show_function_name, + const char* name) const; + + /// Get the address range contained within a symbol context. /// /// Address range priority is as follows: @@ -220,6 +228,9 @@ class SymbolContext { void GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target) const; + void GetDescription(Stream *s, lldb::DescriptionLevel level, + Target *target, const char* name) const; + uint32_t GetResolvedMask() const; lldb::LanguageType GetLanguage() const; diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp index 33330ef0926d61f0..aa59e3680a37872c 100644 --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -1513,6 +1513,98 @@ static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm, return false; } +//=========================================================================================== +static void PrintRed(Stream &strm, const char *text, const char *name) { + const char *red_start = "\033[31m"; // Set text color to red + const char *reset_color = "\033[0m"; // Reset text color to default + + // Escape1(ansi.red) + + const char *match = text; + size_t name_len = strlen(name); + + while ((match = strstr(match, name))) { + size_t prefix_len = match - text; + + strm.Write(text, prefix_len); + strm.PutCString(red_start); + strm.Write(match, name_len); + strm.PutCString(reset_color); + + text = match + name_len; + match = text; + } + + strm.PutCString(text); // Print any remaining text +} + + +// static void PrintRed(Stream &strm, const char *text, const char *name) { +// const char *red_start = "\033[31m"; // Set text color to red +// const char *reset_color = "\033[0m"; // Reset text color to default + +// const char *match = text; + +// // Split the name into parts using the delimiter '|' +// std::vector<std::string> name_parts; +// const char *delimiter = "|"; // Delimiter for splitting the name +// const char *token = strtok(const_cast<char *>(name), delimiter); +// while (token) { +// name_parts.push_back(token); +// token = strtok(nullptr, delimiter); +// } + +// // Initialize a variable to keep track of the current position in the text +// size_t current_pos = 0; + +// // Iterate through each name part and apply colorization +// for (const std::string &part : name_parts) { +// match = text + current_pos; +// match = strstr(match, part.c_str()); + +// if (match) { +// size_t prefix_len = match - (text + current_pos); +// current_pos += prefix_len; + +// strm.Write(text + current_pos, prefix_len); +// strm.PutCString(red_start); +// strm.Write(match, part.length()); +// strm.PutCString(reset_color); + +// current_pos += part.length(); +// } +// } + +// // Print any remaining text +// if (current_pos < strlen(text)) { +// strm.PutCString(text + current_pos); +// } +// } + +static void DumpAddress(ExecutionContextScope *exe_scope, + const Address &so_addr, bool verbose, bool all_ranges, + Stream &strm, const char *name) { + strm.IndentMore(); + strm.Indent(" Address: "); + so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress, name); + strm.PutCString(" ("); + so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset, name); + strm.PutCString(")\n"); + strm.Indent(" Summary: "); + const uint32_t save_indent = strm.GetIndentLevel(); + strm.SetIndentLevel(save_indent + 13); + so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription, name); + strm.SetIndentLevel(save_indent); + // Print out detailed address information when verbose is enabled + if (verbose) { + strm.EOL(); + so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext, name, + Address::DumpStyleInvalid, UINT32_MAX, all_ranges); + } + strm.IndentLess(); +} + +//=========================================================================================== static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, @@ -1550,12 +1642,13 @@ static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter, if (symbol->ValueIsAddress()) { DumpAddress( interpreter.GetExecutionContext().GetBestExecutionContextScope(), - symbol->GetAddressRef(), verbose, all_ranges, strm); + symbol->GetAddressRef(), verbose, all_ranges, strm, name); strm.EOL(); } else { strm.IndentMore(); strm.Indent(" Name: "); - strm.PutCString(symbol->GetDisplayName().GetStringRef()); + // strm.PutCString(symbol->GetDisplayName().GetStringRef()); + PrintRed(strm, symbol->GetDisplayName().GetStringRef().str().c_str(), name); strm.EOL(); strm.Indent(" Value: "); strm.Printf("0x%16.16" PRIx64 "\n", symbol->GetRawValue()); diff --git a/lldb/source/Core/Address.cpp b/lldb/source/Core/Address.cpp index 189d50fe962a651c..4a4a9ca01f39e721 100644 --- a/lldb/source/Core/Address.cpp +++ b/lldb/source/Core/Address.cpp @@ -802,6 +802,434 @@ bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, return true; } + +//================================================================================== +static void PrintRed(Stream *strm, const char *text, const char *name) { + const char *red_start = "\033[31m"; // Set text color to red + const char *reset_color = "\033[0m"; // Reset text color to default + + const char *match = text; + size_t name_len = strlen(name); + + while ((match = strstr(match, name))) { + size_t prefix_len = match - text; + + strm->Write(text, prefix_len); + strm->PutCString(red_start); + strm->Write(match, name_len); + strm->PutCString(reset_color); + + text = match + name_len; + match = text; + } + + strm->PutCString(text); // Print any remaining text +} + + +bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, const char* name, + DumpStyle fallback_style, uint32_t addr_size, + bool all_ranges) const { + // If the section was nullptr, only load address is going to work unless we + // are trying to deref a pointer + SectionSP section_sp(GetSection()); + if (!section_sp && style != DumpStyleResolvedPointerDescription) + style = DumpStyleLoadAddress; + + ExecutionContext exe_ctx(exe_scope); + Target *target = exe_ctx.GetTargetPtr(); + // If addr_byte_size is UINT32_MAX, then determine the correct address byte + // size for the process or default to the size of addr_t + if (addr_size == UINT32_MAX) { + if (target) + addr_size = target->GetArchitecture().GetAddressByteSize(); + else + addr_size = sizeof(addr_t); + } + + Address so_addr; + switch (style) { + case DumpStyleInvalid: + return false; + + case DumpStyleSectionNameOffset: + if (section_sp) { + section_sp->DumpName(s->AsRawOstream()); + s->Printf(" + %" PRIu64, m_offset); + } else { + DumpAddress(s->AsRawOstream(), m_offset, addr_size); + } + break; + + case DumpStyleSectionPointerOffset: + s->Printf("(Section *)%p + ", static_cast<void *>(section_sp.get())); + DumpAddress(s->AsRawOstream(), m_offset, addr_size); + break; + + case DumpStyleModuleWithFileAddress: + if (section_sp) { + ModuleSP module_sp = section_sp->GetModule(); + if (module_sp) + s->Printf("%s[", module_sp->GetFileSpec().GetFilename().AsCString( + "<Unknown>")); + else + s->Printf("%s[", "<Unknown>"); + } + [[fallthrough]]; + case DumpStyleFileAddress: { + addr_t file_addr = GetFileAddress(); + if (file_addr == LLDB_INVALID_ADDRESS) { + if (fallback_style != DumpStyleInvalid) + return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size); + return false; + } + DumpAddress(s->AsRawOstream(), file_addr, addr_size); + if (style == DumpStyleModuleWithFileAddress && section_sp) + s->PutChar(']'); + } break; + + case DumpStyleLoadAddress: { + addr_t load_addr = GetLoadAddress(target); + + /* + * MIPS: + * Display address in compressed form for MIPS16 or microMIPS + * if the address belongs to AddressClass::eCodeAlternateISA. + */ + if (target) { + const llvm::Triple::ArchType llvm_arch = + target->GetArchitecture().GetMachine(); + if (llvm_arch == llvm::Triple::mips || + llvm_arch == llvm::Triple::mipsel || + llvm_arch == llvm::Triple::mips64 || + llvm_arch == llvm::Triple::mips64el) + load_addr = GetCallableLoadAddress(target); + } + + if (load_addr == LLDB_INVALID_ADDRESS) { + if (fallback_style != DumpStyleInvalid) + return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size); + return false; + } + DumpAddress(s->AsRawOstream(), load_addr, addr_size); + } break; + + case DumpStyleResolvedDescription: + case DumpStyleResolvedDescriptionNoModule: + case DumpStyleResolvedDescriptionNoFunctionArguments: + case DumpStyleNoFunctionName: + if (IsSectionOffset()) { + uint32_t pointer_size = 4; + ModuleSP module_sp(GetModule()); + if (target) + pointer_size = target->GetArchitecture().GetAddressByteSize(); + else if (module_sp) + pointer_size = module_sp->GetArchitecture().GetAddressByteSize(); + + bool showed_info = false; + if (section_sp) { + SectionType sect_type = section_sp->GetType(); + switch (sect_type) { + case eSectionTypeData: + if (module_sp) { + if (Symtab *symtab = module_sp->GetSymtab()) { + const addr_t file_Addr = GetFileAddress(); + Symbol *symbol = + symtab->FindSymbolContainingFileAddress(file_Addr); + if (symbol) { + const char *symbol_name = symbol->GetName().AsCString(); + if (symbol_name) { + // s->printf(symbol_name) + PrintRed(s, symbol_name, name); + addr_t delta = + file_Addr - symbol->GetAddressRef().GetFileAddress(); + if (delta) + s->Printf(" + %" PRIu64, delta); + showed_info = true; + } + } + } + } + break; + + case eSectionTypeDataCString: + // Read the C string from memory and display it + showed_info = true; + ReadCStringFromMemory(exe_scope, *this, s); + break; + + case eSectionTypeDataCStringPointers: + if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) { +#if VERBOSE_OUTPUT + s->PutCString("(char *)"); + so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, + DumpStyleFileAddress); + s->PutCString(": "); +#endif + showed_info = true; + ReadCStringFromMemory(exe_scope, so_addr, s); + } + break; + + case eSectionTypeDataObjCMessageRefs: + if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) { + if (target && so_addr.IsSectionOffset()) { + SymbolContext func_sc; + target->GetImages().ResolveSymbolContextForAddress( + so_addr, eSymbolContextEverything, func_sc); + if (func_sc.function != nullptr || func_sc.symbol != nullptr) { + showed_info = true; +#if VERBOSE_OUTPUT + s->PutCString("(objc_msgref *) -> { (func*)"); + so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, + DumpStyleFileAddress); +#else + s->PutCString("{ "); +#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, true); + if (ReadAddress(exe_scope, cstr_addr, pointer_size, so_addr)) { +#if VERBOSE_OUTPUT + s->PutCString("), (char *)"); + so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, + DumpStyleFileAddress); + s->PutCString(" ("); +#else + s->PutCString(", "); +#endif + ReadCStringFromMemory(exe_scope, so_addr, s); + } +#if VERBOSE_OUTPUT + s->PutCString(") }"); +#else + s->PutCString(" }"); +#endif + } + } + } + break; + + case eSectionTypeDataObjCCFStrings: { + Address cfstring_data_addr(*this); + cfstring_data_addr.SetOffset(cfstring_data_addr.GetOffset() + + (2 * pointer_size)); + if (ReadAddress(exe_scope, cfstring_data_addr, pointer_size, + so_addr)) { +#if VERBOSE_OUTPUT + s->PutCString("(CFString *) "); + cfstring_data_addr.Dump(s, exe_scope, DumpStyleLoadAddress, + DumpStyleFileAddress); + s->PutCString(" -> @"); +#else + s->PutChar('@'); +#endif + if (so_addr.Dump(s, exe_scope, DumpStyleResolvedDescription)) + showed_info = true; + } + } break; + + case eSectionTypeData4: + // Read the 4 byte data and display it + showed_info = true; + s->PutCString("(uint32_t) "); + DumpUInt(exe_scope, *this, 4, s); + break; + + case eSectionTypeData8: + // Read the 8 byte data and display it + showed_info = true; + s->PutCString("(uint64_t) "); + DumpUInt(exe_scope, *this, 8, s); + break; + + case eSectionTypeData16: + // Read the 16 byte data and display it + showed_info = true; + s->PutCString("(uint128_t) "); + DumpUInt(exe_scope, *this, 16, s); + break; + + case eSectionTypeDataPointers: + // Read the pointer data and display it + if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) { + s->PutCString("(void *)"); + so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, + DumpStyleFileAddress); + + showed_info = true; + if (so_addr.IsSectionOffset()) { + SymbolContext pointer_sc; + if (target) { + target->GetImages().ResolveSymbolContextForAddress( + so_addr, eSymbolContextEverything, pointer_sc); + if (pointer_sc.function != nullptr || + pointer_sc.symbol != nullptr) { + s->PutCString(": "); + pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false, + false, true, true, name); + } + } + } + } + break; + + default: + break; + } + } + + if (!showed_info) { + if (module_sp) { + SymbolContext sc; + module_sp->ResolveSymbolContextForAddress( + *this, eSymbolContextEverything, sc); + if (sc.function || sc.symbol) { + bool show_stop_context = true; + const bool show_module = (style == DumpStyleResolvedDescription); + 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 == nullptr && sc.symbol != nullptr) { + // If we have just a symbol make sure it is in the right section + if (sc.symbol->ValueIsAddress()) { + if (sc.symbol->GetAddressRef().GetSection() != GetSection()) { + // don't show the module if the symbol is a trampoline symbol + show_stop_context = false; + } + } + } + if (show_stop_context) { + // We have a function or a symbol from the same sections as this + // address. + sc.DumpStopContext(s, exe_scope, *this, show_fullpaths, + show_module, show_inlined_frames, + show_function_arguments, show_function_name, name); + } else { + // We found a symbol but it was in a different section so it + // isn't the symbol we should be showing, just show the section + // name + offset + Dump(s, exe_scope, DumpStyleSectionNameOffset, name); + } + } + } + } + } else { + if (fallback_style != DumpStyleInvalid) + return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size, name); + return false; + } + break; + + case DumpStyleDetailedSymbolContext: + if (IsSectionOffset()) { + ModuleSP module_sp(GetModule()); + if (module_sp) { + SymbolContext sc; + module_sp->ResolveSymbolContextForAddress( + *this, eSymbolContextEverything | eSymbolContextVariable, sc); + if (sc.symbol) { + // If we have just a symbol make sure it is in the same section as + // our address. If it isn't, then we might have just found the last + // symbol that came before the address that we are looking up that + // has nothing to do with our address lookup. + if (sc.symbol->ValueIsAddress() && + sc.symbol->GetAddressRef().GetSection() != GetSection()) + sc.symbol = nullptr; + } + sc.GetDescription(s, eDescriptionLevelBrief, target, name); + + if (sc.block) { + bool can_create = true; + bool get_parent_variables = true; + bool stop_if_block_is_inlined_function = false; + VariableList variable_list; + addr_t file_addr = GetFileAddress(); + sc.block->AppendVariables( + can_create, get_parent_variables, + stop_if_block_is_inlined_function, + [&](Variable *var) { + return var && var->LocationIsValidForAddress(*this); + }, + &variable_list); + ABISP abi = + ABI::FindPlugin(ProcessSP(), module_sp->GetArchitecture()); + for (const VariableSP &var_sp : variable_list) { + s->Indent(); + s->Printf(" Variable: id = {0x%8.8" PRIx64 "}, name = \"%s\"", + var_sp->GetID(), var_sp->GetName().GetCString()); + Type *type = var_sp->GetType(); + if (type) + s->Printf(", type = \"%s\"", type->GetName().GetCString()); + else + s->PutCString(", type = <unknown>"); + s->PutCString(", valid ranges = "); + if (var_sp->GetScopeRange().IsEmpty()) + s->PutCString("<block>"); + else if (all_ranges) { + for (auto range : var_sp->GetScopeRange()) + DumpAddressRange(s->AsRawOstream(), range.GetRangeBase(), + range.GetRangeEnd(), addr_size); + } else if (auto *range = + var_sp->GetScopeRange().FindEntryThatContains( + file_addr)) + DumpAddressRange(s->AsRawOstream(), range->GetRangeBase(), + range->GetRangeEnd(), addr_size); + s->PutCString(", location = "); + var_sp->DumpLocations(s, all_ranges ? LLDB_INVALID_ADDRESS : *this); + s->PutCString(", decl = "); + var_sp->GetDeclaration().DumpStopContext(s, false); + s->EOL(); + } + } + } + } else { + if (fallback_style != DumpStyleInvalid) + return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size, name); + return false; + } + break; + + case DumpStyleResolvedPointerDescription: { + Process *process = exe_ctx.GetProcessPtr(); + if (process) { + addr_t load_addr = GetLoadAddress(target); + if (load_addr != LLDB_INVALID_ADDRESS) { + Status memory_error; + addr_t dereferenced_load_addr = + process->ReadPointerFromMemory(load_addr, memory_error); + if (dereferenced_load_addr != LLDB_INVALID_ADDRESS) { + Address dereferenced_addr; + if (dereferenced_addr.SetLoadAddress(dereferenced_load_addr, + target)) { + StreamString strm; + if (dereferenced_addr.Dump(&strm, exe_scope, + DumpStyleResolvedDescription, + DumpStyleInvalid, addr_size)) { + DumpAddress(s->AsRawOstream(), dereferenced_load_addr, addr_size, + " -> ", " "); + s->Write(strm.GetString().data(), strm.GetSize()); + return true; + } + } + } + } + } + if (fallback_style != DumpStyleInvalid) + return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size, name); + return false; + } break; + } + + return true; +} + + +//================================================================================== + bool Address::SectionWasDeleted() const { if (GetSection()) return false; diff --git a/lldb/source/Symbol/Symbol.cpp b/lldb/source/Symbol/Symbol.cpp index 26b4c4d62ad9c246..c395cbc3e049d131 100644 --- a/lldb/source/Symbol/Symbol.cpp +++ b/lldb/source/Symbol/Symbol.cpp @@ -224,6 +224,74 @@ bool Symbol::IsTrampoline() const { return m_type == eSymbolTypeTrampoline; } bool Symbol::IsIndirect() const { return m_type == eSymbolTypeResolver; } + +//======================================================================= +static void PrintRed(Stream *strm, const char *text, const char *name) { + const char *red_start = "\033[31m"; // Set text color to red + const char *reset_color = "\033[0m"; // Reset text color to default + + const char *match = text; + size_t name_len = strlen(name); + + while ((match = strstr(match, name))) { + size_t prefix_len = match - text; + + strm->Write(text, prefix_len); + strm->PutCString(red_start); + strm->Write(match, name_len); + strm->PutCString(reset_color); + + text = match + name_len; + match = text; + } + + strm->PutCString(text); // Print any remaining text +} + +void Symbol::GetDescription(Stream *s, lldb::DescriptionLevel level, + Target *target, const char* name) const { + s->Printf("id = {0x%8.8x}", m_uid); + + if (m_addr_range.GetBaseAddress().GetSection()) { + if (ValueIsAddress()) { + const lldb::addr_t byte_size = GetByteSize(); + if (byte_size > 0) { + s->PutCString(", range = "); + m_addr_range.Dump(s, target, Address::DumpStyleLoadAddress, + Address::DumpStyleFileAddress); + } else { + s->PutCString(", address = "); + m_addr_range.GetBaseAddress().Dump(s, target, + Address::DumpStyleLoadAddress, + Address::DumpStyleFileAddress); + } + } else + s->Printf(", value = 0x%16.16" PRIx64, + m_addr_range.GetBaseAddress().GetOffset()); + } else { + if (m_size_is_sibling) + s->Printf(", sibling = %5" PRIu64, + m_addr_range.GetBaseAddress().GetOffset()); + else + s->Printf(", value = 0x%16.16" PRIx64, + m_addr_range.GetBaseAddress().GetOffset()); + } + ConstString demangled = GetMangled().GetDemangledName(); + if (demangled){ + // s->Printf(", name=\"%s\"", demangled.AsCString()); + s->Printf(", name="); + PrintRed(s, demangled.AsCString(), name); + } + if (m_mangled.GetMangledName()){ + // s->Printf(", mangled=\"%s\"", m_mangled.GetMangledName().AsCString()); + s->Printf(", mangled="); + PrintRed(s, m_mangled.GetMangledName().AsCString(), name); + } +} + +//======================================================================== + + void Symbol::GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target) const { s->Printf("id = {0x%8.8x}", m_uid); diff --git a/lldb/source/Symbol/SymbolContext.cpp b/lldb/source/Symbol/SymbolContext.cpp index 63968ec2d1506705..3a2a25edbdc2d7e2 100644 --- a/lldb/source/Symbol/SymbolContext.cpp +++ b/lldb/source/Symbol/SymbolContext.cpp @@ -185,6 +185,254 @@ bool SymbolContext::DumpStopContext(Stream *s, ExecutionContextScope *exe_scope, return dumped_something; } + +//=========================================================================== +static void PrintRed(Stream *strm, const char *text, const char *name) { + const char *red_start = "\033[31m"; // Set text color to red + const char *reset_color = "\033[0m"; // Reset text color to default + + const char *match = text; + size_t name_len = strlen(name); + + while ((match = strstr(match, name))) { + size_t prefix_len = match - text; + + strm->Write(text, prefix_len); + strm->PutCString(red_start); + strm->Write(match, name_len); + strm->PutCString(reset_color); + + text = match + name_len; + match = text; + } + + strm->PutCString(text); // Print any remaining text +} + +bool 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_name, + const char* name) const { + bool dumped_something = false; + if (show_module && module_sp) { + if (show_fullpaths) + *s << module_sp->GetFileSpec(); + else + *s << module_sp->GetFileSpec().GetFilename(); + s->PutChar('`'); + dumped_something = true; + } + + if (function != nullptr) { + SymbolContext inline_parent_sc; + Address inline_parent_addr; + if (!show_function_name) { + s->Printf("<"); + dumped_something = true; + } else { + ConstString name1; + if (!show_function_arguments) + name1 = function->GetNameNoArguments(); + if (!name1) + name1 = function->GetName(); + if (name1){ + // name.Dump(s); + PrintRed(s, name1.GetCString() , name); + } + } + + if (addr.IsValid()) { + const addr_t function_offset = + addr.GetOffset() - + function->GetAddressRange().GetBaseAddress().GetOffset(); + if (!show_function_name) { + // 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); + } + } + + if (GetParentOfInlinedScope(addr, inline_parent_sc, inline_parent_addr)) { + dumped_something = true; + Block *inlined_block = block->GetContainingInlinedBlock(); + const InlineFunctionInfo *inlined_block_info = + inlined_block->GetInlinedFunctionInfo(); + s->Printf(" [inlined] %s", inlined_block_info->GetName().GetCString()); + + lldb_private::AddressRange block_range; + if (inlined_block->GetRangeContainingAddress(addr, block_range)) { + const addr_t inlined_function_offset = + addr.GetOffset() - block_range.GetBaseAddress().GetOffset(); + if (inlined_function_offset) { + s->Printf(" + %" PRIu64, inlined_function_offset); + } + } + // "line_entry" will always be valid as GetParentOfInlinedScope(...) will + // fill it in correctly with the calling file and line. Previous code + // was extracting the calling file and line from inlined_block_info and + // using it right away which is not correct. On the first call to this + // function "line_entry" will contain the actual line table entry. On + // susequent calls "line_entry" will contain the calling file and line + // from the previous inline info. + if (line_entry.IsValid()) { + s->PutCString(" at "); + line_entry.DumpStopContext(s, show_fullpaths); + } + + if (show_inlined_frames) { + s->EOL(); + s->Indent(); + 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 { + if (line_entry.IsValid()) { + dumped_something = true; + s->PutCString(" at "); + if (line_entry.DumpStopContext(s, show_fullpaths)) + dumped_something = true; + } + } + } else if (symbol != nullptr) { + if (!show_function_name) { + s->Printf("<"); + dumped_something = true; + } else if (symbol->GetName()) { + dumped_something = true; + if (symbol->GetType() == eSymbolTypeTrampoline) + s->PutCString("symbol stub for: "); + // symbol->GetName().Dump(s); + PrintRed(s, symbol->GetName().GetStringRef().str().c_str(), name); + } + + if (addr.IsValid() && symbol->ValueIsAddress()) { + const addr_t symbol_offset = + addr.GetOffset() - symbol->GetAddressRef().GetOffset(); + if (!show_function_name) { + // 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); + } + } + } else if (addr.IsValid()) { + addr.Dump(s, exe_scope, Address::DumpStyleModuleWithFileAddress); + dumped_something = true; + } + return dumped_something; +} + + +void SymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level, + Target *target, const char* name) const { + if (module_sp) { + s->Indent(" Module: file = \""); + module_sp->GetFileSpec().Dump(s->AsRawOstream()); + *s << '"'; + if (module_sp->GetArchitecture().IsValid()) + s->Printf(", arch = \"%s\"", + module_sp->GetArchitecture().GetArchitectureName()); + s->EOL(); + } + + if (comp_unit != nullptr) { + s->Indent("CompileUnit: "); + comp_unit->GetDescription(s, level); + s->EOL(); + } + + if (function != nullptr) { + s->Indent(" Function: "); + function->GetDescription(s, level, target); + s->EOL(); + + Type *func_type = function->GetType(); + if (func_type) { + s->Indent(" FuncType: "); + func_type->GetDescription(s, level, false, target); + s->EOL(); + } + } + + if (block != nullptr) { + std::vector<Block *> blocks; + blocks.push_back(block); + Block *parent_block = block->GetParent(); + + while (parent_block) { + blocks.push_back(parent_block); + parent_block = parent_block->GetParent(); + } + std::vector<Block *>::reverse_iterator pos; + std::vector<Block *>::reverse_iterator begin = blocks.rbegin(); + std::vector<Block *>::reverse_iterator end = blocks.rend(); + for (pos = begin; pos != end; ++pos) { + if (pos == begin) + s->Indent(" Blocks: "); + else + s->Indent(" "); + (*pos)->GetDescription(s, function, level, target); + s->EOL(); + } + } + + if (line_entry.IsValid()) { + s->Indent(" LineEntry: "); + line_entry.GetDescription(s, level, comp_unit, target, false); + s->EOL(); + } + + if (symbol != nullptr) { + s->Indent(" Symbol: "); + symbol->GetDescription(s, level, target, name); + s->EOL(); + } + + if (variable != nullptr) { + s->Indent(" Variable: "); + + s->Printf("id = {0x%8.8" PRIx64 "}, ", variable->GetID()); + + switch (variable->GetScope()) { + case eValueTypeVariableGlobal: + s->PutCString("kind = global, "); + break; + + case eValueTypeVariableStatic: + s->PutCString("kind = static, "); + break; + + case eValueTypeVariableArgument: + s->PutCString("kind = argument, "); + break; + + case eValueTypeVariableLocal: + s->PutCString("kind = local, "); + break; + + case eValueTypeVariableThreadLocal: + s->PutCString("kind = thread local, "); + break; + + default: + break; + } + + s->Printf("name = \"%s\"\n", variable->GetName().GetCString()); + } +} + +//=========================================================================== + void SymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target) const { if (module_sp) { From 14cf74105a358a028cd7e935b4304e16d6f901f2 Mon Sep 17 00:00:00 2001 From: taalhaataahir0102 <23100...@lums.edu.pk> Date: Mon, 16 Oct 2023 16:15:30 +0500 Subject: [PATCH 2/3] Comments --- lldb/source/Commands/CommandObjectTarget.cpp | 53 ++++---------------- lldb/source/Core/Address.cpp | 7 +++ lldb/source/Symbol/Symbol.cpp | 3 ++ lldb/source/Symbol/SymbolContext.cpp | 1 + 4 files changed, 21 insertions(+), 43 deletions(-) diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp index aa59e3680a37872c..2b6439ab7b10758b 100644 --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -1514,6 +1514,9 @@ static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm, } //=========================================================================================== + +// This function will print search the string name in string text and will colorize +// the name found inside text on the terminal. static void PrintRed(Stream &strm, const char *text, const char *name) { const char *red_start = "\033[31m"; // Set text color to red const char *reset_color = "\033[0m"; // Reset text color to default @@ -1538,49 +1541,9 @@ static void PrintRed(Stream &strm, const char *text, const char *name) { strm.PutCString(text); // Print any remaining text } - -// static void PrintRed(Stream &strm, const char *text, const char *name) { -// const char *red_start = "\033[31m"; // Set text color to red -// const char *reset_color = "\033[0m"; // Reset text color to default - -// const char *match = text; - -// // Split the name into parts using the delimiter '|' -// std::vector<std::string> name_parts; -// const char *delimiter = "|"; // Delimiter for splitting the name -// const char *token = strtok(const_cast<char *>(name), delimiter); -// while (token) { -// name_parts.push_back(token); -// token = strtok(nullptr, delimiter); -// } - -// // Initialize a variable to keep track of the current position in the text -// size_t current_pos = 0; - -// // Iterate through each name part and apply colorization -// for (const std::string &part : name_parts) { -// match = text + current_pos; -// match = strstr(match, part.c_str()); - -// if (match) { -// size_t prefix_len = match - (text + current_pos); -// current_pos += prefix_len; - -// strm.Write(text + current_pos, prefix_len); -// strm.PutCString(red_start); -// strm.Write(match, part.length()); -// strm.PutCString(reset_color); - -// current_pos += part.length(); -// } -// } - -// // Print any remaining text -// if (current_pos < strlen(text)) { -// strm.PutCString(text + current_pos); -// } -// } - +// This function is responsible for printing address and summary of the symbol found. +// The seached regex symbol is passed to this function as well so that it can be colorized +// in the summary as well. static void DumpAddress(ExecutionContextScope *exe_scope, const Address &so_addr, bool verbose, bool all_ranges, Stream &strm, const char *name) { @@ -1593,6 +1556,8 @@ static void DumpAddress(ExecutionContextScope *exe_scope, strm.Indent(" Summary: "); const uint32_t save_indent = strm.GetIndentLevel(); strm.SetIndentLevel(save_indent + 13); + // Using the new dump function for printing the summary where we've also passed + // the searched symbol as an argument. so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription, name); strm.SetIndentLevel(save_indent); // Print out detailed address information when verbose is enabled @@ -1640,6 +1605,7 @@ static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter, Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]); if (symbol) { if (symbol->ValueIsAddress()) { + // Using the new dump function to add colors in the summary. DumpAddress( interpreter.GetExecutionContext().GetBestExecutionContextScope(), symbol->GetAddressRef(), verbose, all_ranges, strm, name); @@ -1648,6 +1614,7 @@ static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter, strm.IndentMore(); strm.Indent(" Name: "); // strm.PutCString(symbol->GetDisplayName().GetStringRef()); + // Using the PrintRed function to colorize the searched symbol. PrintRed(strm, symbol->GetDisplayName().GetStringRef().str().c_str(), name); strm.EOL(); strm.Indent(" Value: "); diff --git a/lldb/source/Core/Address.cpp b/lldb/source/Core/Address.cpp index 4a4a9ca01f39e721..3da35a3be311051c 100644 --- a/lldb/source/Core/Address.cpp +++ b/lldb/source/Core/Address.cpp @@ -804,6 +804,10 @@ bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, //================================================================================== + +// This function will print search the string name in string text and will colorize +// the name found inside text on the terminal. + static void PrintRed(Stream *strm, const char *text, const char *name) { const char *red_start = "\033[31m"; // Set text color to red const char *reset_color = "\033[0m"; // Reset text color to default @@ -826,6 +830,8 @@ static void PrintRed(Stream *strm, const char *text, const char *name) { strm->PutCString(text); // Print any remaining text } +// Similar to the DumpAddress function inside CommandObjectTarget.cpp, we've reinitialized this Dump function +// by passing the searched symbol so that it can be colorized as well in the output stream. bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, const char* name, DumpStyle fallback_style, uint32_t addr_size, @@ -940,6 +946,7 @@ bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, const char *symbol_name = symbol->GetName().AsCString(); if (symbol_name) { // s->printf(symbol_name) + // Using the PrintRed function to colorize the symbol. PrintRed(s, symbol_name, name); addr_t delta = file_Addr - symbol->GetAddressRef().GetFileAddress(); diff --git a/lldb/source/Symbol/Symbol.cpp b/lldb/source/Symbol/Symbol.cpp index c395cbc3e049d131..ac99c63cc4d46ba0 100644 --- a/lldb/source/Symbol/Symbol.cpp +++ b/lldb/source/Symbol/Symbol.cpp @@ -248,6 +248,9 @@ static void PrintRed(Stream *strm, const char *text, const char *name) { strm->PutCString(text); // Print any remaining text } + +// This function is used to display the details of searched symbol i.e., when verbose flag is used. +// Adding colorization in this dump function as well usin the PrintRed function. void Symbol::GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target, const char* name) const { s->Printf("id = {0x%8.8x}", m_uid); diff --git a/lldb/source/Symbol/SymbolContext.cpp b/lldb/source/Symbol/SymbolContext.cpp index 3a2a25edbdc2d7e2..7c1db5cef75c4d2b 100644 --- a/lldb/source/Symbol/SymbolContext.cpp +++ b/lldb/source/Symbol/SymbolContext.cpp @@ -187,6 +187,7 @@ bool SymbolContext::DumpStopContext(Stream *s, ExecutionContextScope *exe_scope, //=========================================================================== +// Similar to the previous modules, using PrintRed and new dump function. static void PrintRed(Stream *strm, const char *text, const char *name) { const char *red_start = "\033[31m"; // Set text color to red const char *reset_color = "\033[0m"; // Reset text color to default From c387dae46deac35f9a28b90e1a1831c02681b021 Mon Sep 17 00:00:00 2001 From: taalhaataahir0102 <23100...@lums.edu.pk> Date: Mon, 16 Oct 2023 17:39:05 +0500 Subject: [PATCH 3/3] new PrintRed with | support --- lldb/source/Commands/CommandObjectTarget.cpp | 80 ++++++++++++++++---- lldb/source/Core/Address.cpp | 77 +++++++++++++++---- lldb/source/Symbol/SymbolContext.cpp | 72 ++++++++++++++---- 3 files changed, 188 insertions(+), 41 deletions(-) diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp index 2b6439ab7b10758b..88905b39dec9f5d9 100644 --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -1515,32 +1515,84 @@ static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm, //=========================================================================================== +#include <iostream> +#include <sstream> +#include <vector> + +// Function to split the string on "|" +std::vector<std::string> splitString(const std::string &s, char delimiter) { + std::vector<std::string> tokens; + std::stringstream ss(s); + std::string item; + + while (std::getline(ss, item, delimiter)) { + tokens.push_back(item); + } + + return tokens; +} + // This function will print search the string name in string text and will colorize // the name found inside text on the terminal. static void PrintRed(Stream &strm, const char *text, const char *name) { const char *red_start = "\033[31m"; // Set text color to red const char *reset_color = "\033[0m"; // Reset text color to default - // Escape1(ansi.red) + std::vector<std::string> parts = splitString(name, '|'); - const char *match = text; - size_t name_len = strlen(name); - - while ((match = strstr(match, name))) { - size_t prefix_len = match - text; + size_t text_len = strlen(text); + size_t current_pos = 0; - strm.Write(text, prefix_len); - strm.PutCString(red_start); - strm.Write(match, name_len); - strm.PutCString(reset_color); - - text = match + name_len; - match = text; + for (const auto &part : parts) { + const char *match = text; + size_t name_len = part.size(); + + while ((match = strstr(match, part.c_str()))) { + size_t prefix_len = match - text + current_pos; + + strm.Write(text + current_pos, prefix_len); + strm.PutCString(red_start); + strm.Write(match, name_len); + strm.PutCString(reset_color); + + // Update the current position and the match pointer + current_pos = (match - text) + name_len; + match += name_len; + } } - strm.PutCString(text); // Print any remaining text + // Print any remaining text + strm.PutCString(text + current_pos); } + + +// This function will print search the string name in string text and will colorize +// the name found inside text on the terminal. +// static void PrintRed(Stream &strm, const char *text, const char *name) { +// const char *red_start = "\033[31m"; // Set text color to red +// const char *reset_color = "\033[0m"; // Reset text color to default + +// // Escape1(ansi.red) + +// const char *match = text; +// size_t name_len = strlen(name); + +// while ((match = strstr(match, name))) { +// size_t prefix_len = match - text; + +// strm.Write(text, prefix_len); +// strm.PutCString(red_start); +// strm.Write(match, name_len); +// strm.PutCString(reset_color); + +// text = match + name_len; +// match = text; +// } + +// strm.PutCString(text); // Print any remaining text +// } + // This function is responsible for printing address and summary of the symbol found. // The seached regex symbol is passed to this function as well so that it can be colorized // in the summary as well. diff --git a/lldb/source/Core/Address.cpp b/lldb/source/Core/Address.cpp index 3da35a3be311051c..611086556c709890 100644 --- a/lldb/source/Core/Address.cpp +++ b/lldb/source/Core/Address.cpp @@ -805,31 +805,80 @@ bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, //================================================================================== +#include <iostream> +#include <sstream> +#include <vector> + +// Function to split the string on "|" +static std::vector<std::string> splitString(const std::string &s, char delimiter) { + std::vector<std::string> tokens; + std::stringstream ss(s); + std::string item; + + while (std::getline(ss, item, delimiter)) { + tokens.push_back(item); + } + + return tokens; +} + // This function will print search the string name in string text and will colorize // the name found inside text on the terminal. - static void PrintRed(Stream *strm, const char *text, const char *name) { const char *red_start = "\033[31m"; // Set text color to red const char *reset_color = "\033[0m"; // Reset text color to default - const char *match = text; - size_t name_len = strlen(name); - - while ((match = strstr(match, name))) { - size_t prefix_len = match - text; + std::vector<std::string> parts = splitString(name, '|'); - strm->Write(text, prefix_len); - strm->PutCString(red_start); - strm->Write(match, name_len); - strm->PutCString(reset_color); - - text = match + name_len; - match = text; + size_t text_len = strlen(text); + size_t current_pos = 0; + + for (const auto &part : parts) { + const char *match = text; + size_t name_len = part.size(); + + while ((match = strstr(match, part.c_str()))) { + size_t prefix_len = match - text + current_pos; + + strm->Write(text + current_pos, prefix_len); + strm->PutCString(red_start); + strm->Write(match, name_len); + strm->PutCString(reset_color); + + // Update the current position and the match pointer + current_pos = (match - text) + name_len; + match += name_len; + } } - strm->PutCString(text); // Print any remaining text + // Print any remaining text + strm->PutCString(text + current_pos); } + + +// static void PrintRed(Stream *strm, const char *text, const char *name) { +// const char *red_start = "\033[31m"; // Set text color to red +// const char *reset_color = "\033[0m"; // Reset text color to default + +// const char *match = text; +// size_t name_len = strlen(name); + +// while ((match = strstr(match, name))) { +// size_t prefix_len = match - text; + +// strm->Write(text, prefix_len); +// strm->PutCString(red_start); +// strm->Write(match, name_len); +// strm->PutCString(reset_color); + +// text = match + name_len; +// match = text; +// } + +// strm->PutCString(text); // Print any remaining text +// } + // Similar to the DumpAddress function inside CommandObjectTarget.cpp, we've reinitialized this Dump function // by passing the searched symbol so that it can be colorized as well in the output stream. diff --git a/lldb/source/Symbol/SymbolContext.cpp b/lldb/source/Symbol/SymbolContext.cpp index 7c1db5cef75c4d2b..7b9276940be3943c 100644 --- a/lldb/source/Symbol/SymbolContext.cpp +++ b/lldb/source/Symbol/SymbolContext.cpp @@ -187,29 +187,75 @@ bool SymbolContext::DumpStopContext(Stream *s, ExecutionContextScope *exe_scope, //=========================================================================== + +#include <sstream> +// Function to split the string on "|" +static std::vector<std::string> splitString(const std::string &s, char delimiter) { + std::vector<std::string> tokens; + std::stringstream ss(s); + std::string item; + + while (std::getline(ss, item, delimiter)) { + tokens.push_back(item); + } + + return tokens; +} + // Similar to the previous modules, using PrintRed and new dump function. static void PrintRed(Stream *strm, const char *text, const char *name) { const char *red_start = "\033[31m"; // Set text color to red const char *reset_color = "\033[0m"; // Reset text color to default - const char *match = text; - size_t name_len = strlen(name); - - while ((match = strstr(match, name))) { - size_t prefix_len = match - text; + std::vector<std::string> parts = splitString(name, '|'); - strm->Write(text, prefix_len); - strm->PutCString(red_start); - strm->Write(match, name_len); - strm->PutCString(reset_color); - - text = match + name_len; - match = text; + size_t text_len = strlen(text); + size_t current_pos = 0; + + for (const auto &part : parts) { + const char *match = text; + size_t name_len = part.size(); + + while ((match = strstr(match, part.c_str()))) { + size_t prefix_len = match - text + current_pos; + + strm->Write(text + current_pos, prefix_len); + strm->PutCString(red_start); + strm->Write(match, name_len); + strm->PutCString(reset_color); + + // Update the current position and the match pointer + current_pos = (match - text) + name_len; + match += name_len; + } } - strm->PutCString(text); // Print any remaining text + // Print any remaining text + strm->PutCString(text + current_pos); } +// static void PrintRed(Stream *strm, const char *text, const char *name) { +// const char *red_start = "\033[31m"; // Set text color to red +// const char *reset_color = "\033[0m"; // Reset text color to default + +// const char *match = text; +// size_t name_len = strlen(name); + +// while ((match = strstr(match, name))) { +// size_t prefix_len = match - text; + +// strm->Write(text, prefix_len); +// strm->PutCString(red_start); +// strm->Write(match, name_len); +// strm->PutCString(reset_color); + +// text = match + name_len; +// match = text; +// } + +// strm->PutCString(text); // Print any remaining text +// } + bool SymbolContext::DumpStopContext(Stream *s, ExecutionContextScope *exe_scope, const Address &addr, bool show_fullpaths, bool show_module, bool show_inlined_frames, _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits