1254721Semaste//===-- Address.h -----------------------------------------------*- C++ -*-===// 2254721Semaste// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6254721Semaste// 7254721Semaste//===----------------------------------------------------------------------===// 8254721Semaste 9254721Semaste#ifndef liblldb_Address_h_ 10254721Semaste#define liblldb_Address_h_ 11254721Semaste 12344779Sdim#include "lldb/lldb-defines.h" 13344779Sdim#include "lldb/lldb-forward.h" 14344779Sdim#include "lldb/lldb-private-enumerations.h" 15344779Sdim#include "lldb/lldb-types.h" 16296417Sdim 17344779Sdim#include <stddef.h> 18344779Sdim#include <stdint.h> 19254721Semaste 20254721Semastenamespace lldb_private { 21321369Sdimclass Block; 22321369Sdimclass CompileUnit; 23321369Sdimclass ExecutionContextScope; 24321369Sdimclass Function; 25321369Sdimclass SectionList; 26321369Sdimclass Stream; 27321369Sdimclass Symbol; 28321369Sdimclass SymbolContext; 29321369Sdimclass Target; 30321369Sdimstruct LineEntry; 31254721Semaste 32353358Sdim/// \class Address Address.h "lldb/Core/Address.h" 33341825Sdim/// A section + offset based address class. 34254721Semaste/// 35341825Sdim/// The Address class allows addresses to be relative to a section that can 36341825Sdim/// move during runtime due to images (executables, shared libraries, bundles, 37341825Sdim/// frameworks) being loaded at different addresses than the addresses found 38341825Sdim/// in the object file that represents them on disk. There are currently two 39341825Sdim/// types of addresses for a section: 40353358Sdim/// \li file addresses 41353358Sdim/// \li load addresses 42254721Semaste/// 43341825Sdim/// File addresses represent the virtual addresses that are in the "on disk" 44341825Sdim/// object files. These virtual addresses are converted to be relative to 45341825Sdim/// unique sections scoped to the object file so that when/if the addresses 46341825Sdim/// slide when the images are loaded/unloaded in memory, we can easily track 47341825Sdim/// these changes without having to update every object (compile unit ranges, 48341825Sdim/// line tables, function address ranges, lexical block and inlined subroutine 49341825Sdim/// address ranges, global and static variables) each time an image is loaded 50341825Sdim/// or unloaded. 51254721Semaste/// 52341825Sdim/// Load addresses represent the virtual addresses where each section ends up 53341825Sdim/// getting loaded at runtime. Before executing a program, it is common for 54341825Sdim/// all of the load addresses to be unresolved. When a DynamicLoader plug-in 55341825Sdim/// receives notification that shared libraries have been loaded/unloaded, the 56341825Sdim/// load addresses of the main executable and any images (shared libraries) 57341825Sdim/// will be resolved/unresolved. When this happens, breakpoints that are in 58341825Sdim/// one of these sections can be set/cleared. 59314564Sdimclass Address { 60254721Semastepublic: 61341825Sdim /// Dump styles allow the Address::Dump(Stream *,DumpStyle) const function 62341825Sdim /// to display Address contents in a variety of ways. 63353358Sdim enum DumpStyle { 64360784Sdim /// Invalid dump style. 65360784Sdim DumpStyleInvalid, 66360784Sdim /// Display as the section name + offset. 67360784Sdim /// \code 68314564Sdim /// // address for printf in libSystem.B.dylib as a section name + offset 69360784Sdim /// libSystem.B.dylib.__TEXT.__text + 0x0005cfdf 70360784Sdim /// \endcode 71360784Sdim DumpStyleSectionNameOffset, 72360784Sdim /// Display as the section pointer + offset (debug output). 73360784Sdim /// \code 74341825Sdim /// // address for printf in libSystem.B.dylib as a section pointer + 75360784Sdim /// offset (lldb::Section *)0x35cc50 + 0x000000000005cfdf 76360784Sdim /// \endcode 77360784Sdim DumpStyleSectionPointerOffset, 78360784Sdim /// Display as the file address (if any). 79360784Sdim /// \code 80314564Sdim /// // address for printf in libSystem.B.dylib as a file address 81360784Sdim /// 0x000000000005dcff 82360784Sdim /// \endcode 83360784Sdim /// 84360784Sdim DumpStyleFileAddress, 85360784Sdim /// Display as the file address with the module name prepended (if any). 86360784Sdim /// \code 87314564Sdim /// // address for printf in libSystem.B.dylib as a file address 88360784Sdim /// libSystem.B.dylib[0x000000000005dcff] 89360784Sdim /// \endcode 90360784Sdim DumpStyleModuleWithFileAddress, 91360784Sdim /// Display as the load address (if resolved). 92360784Sdim /// \code 93314564Sdim /// // address for printf in libSystem.B.dylib as a load address 94360784Sdim /// 0x00007fff8306bcff 95360784Sdim /// \endcode 96360784Sdim DumpStyleLoadAddress, 97360784Sdim /// Display the details about what an address resolves to. This can be 98360784Sdim /// anything from a symbol context summary (module, function/symbol, and 99360784Sdim /// file and line), to information about what the pointer points to if the 100360784Sdim /// address is in a section (section of pointers, c strings, etc). 101360784Sdim DumpStyleResolvedDescription, 102314564Sdim DumpStyleResolvedDescriptionNoModule, 103314564Sdim DumpStyleResolvedDescriptionNoFunctionArguments, 104360784Sdim /// Elide the function name; display an offset into the current function. 105360784Sdim /// Used primarily in disassembly symbolication 106360784Sdim DumpStyleNoFunctionName, 107360784Sdim /// Detailed symbol context information for an address for all symbol 108360784Sdim /// context members. 109360784Sdim DumpStyleDetailedSymbolContext, 110360784Sdim /// Dereference a pointer at the current address and then lookup the 111360784Sdim /// dereferenced address using DumpStyleResolvedDescription 112360784Sdim DumpStyleResolvedPointerDescription 113353358Sdim }; 114254721Semaste 115314564Sdim /// Default constructor. 116314564Sdim /// 117341825Sdim /// Initialize with a invalid section (NULL) and an invalid offset 118341825Sdim /// (LLDB_INVALID_ADDRESS). 119314564Sdim Address() : m_section_wp(), m_offset(LLDB_INVALID_ADDRESS) {} 120254721Semaste 121314564Sdim /// Copy constructor 122314564Sdim /// 123314564Sdim /// Makes a copy of the another Address object \a rhs. 124314564Sdim /// 125353358Sdim /// \param[in] rhs 126314564Sdim /// A const Address object reference to copy. 127314564Sdim Address(const Address &rhs) 128314564Sdim : m_section_wp(rhs.m_section_wp), m_offset(rhs.m_offset) {} 129254721Semaste 130314564Sdim /// Construct with a section pointer and offset. 131314564Sdim /// 132341825Sdim /// Initialize the address with the supplied \a section and \a offset. 133314564Sdim /// 134360784Sdim /// \param[in] section_sp 135314564Sdim /// A section pointer to a valid lldb::Section, or NULL if the 136314564Sdim /// address doesn't have a section or will get resolved later. 137314564Sdim /// 138353358Sdim /// \param[in] offset 139314564Sdim /// The offset in bytes into \a section. 140314564Sdim Address(const lldb::SectionSP §ion_sp, lldb::addr_t offset) 141314564Sdim : m_section_wp(), // Don't init with section_sp in case section_sp is 142314564Sdim // invalid (the weak_ptr will throw) 143314564Sdim m_offset(offset) { 144314564Sdim if (section_sp) 145314564Sdim m_section_wp = section_sp; 146314564Sdim } 147254721Semaste 148314564Sdim /// Construct with a virtual address and section list. 149314564Sdim /// 150341825Sdim /// Initialize and resolve the address with the supplied virtual address \a 151341825Sdim /// file_addr. 152314564Sdim /// 153353358Sdim /// \param[in] file_addr 154314564Sdim /// A virtual file address. 155314564Sdim /// 156353358Sdim /// \param[in] section_list 157314564Sdim /// A list of sections, one of which may contain the \a file_addr. 158314564Sdim Address(lldb::addr_t file_addr, const SectionList *section_list); 159254721Semaste 160314564Sdim Address(lldb::addr_t abs_addr); 161254721Semaste 162314564Sdim/// Assignment operator. 163314564Sdim/// 164341825Sdim/// Copies the address value from another Address object \a rhs into \a this 165341825Sdim/// object. 166314564Sdim/// 167353358Sdim/// \param[in] rhs 168314564Sdim/// A const Address object reference to copy. 169314564Sdim/// 170353358Sdim/// \return 171314564Sdim/// A const Address object reference to \a this. 172314564Sdim const Address &operator=(const Address &rhs); 173296417Sdim 174314564Sdim /// Clear the object's state. 175314564Sdim /// 176341825Sdim /// Sets the section to an invalid value (NULL) and an invalid offset 177341825Sdim /// (LLDB_INVALID_ADDRESS). 178314564Sdim void Clear() { 179314564Sdim m_section_wp.reset(); 180314564Sdim m_offset = LLDB_INVALID_ADDRESS; 181314564Sdim } 182314564Sdim 183314564Sdim /// Compare two Address objects. 184314564Sdim /// 185353358Sdim /// \param[in] lhs 186314564Sdim /// The Left Hand Side const Address object reference. 187314564Sdim /// 188353358Sdim /// \param[in] rhs 189314564Sdim /// The Right Hand Side const Address object reference. 190314564Sdim /// 191353358Sdim /// \return 192360784Sdim /// -1 if lhs < rhs 193360784Sdim /// 0 if lhs == rhs 194360784Sdim /// 1 if lhs > rhs 195314564Sdim static int CompareFileAddress(const Address &lhs, const Address &rhs); 196314564Sdim 197314564Sdim static int CompareLoadAddress(const Address &lhs, const Address &rhs, 198314564Sdim Target *target); 199314564Sdim 200314564Sdim static int CompareModulePointerAndOffset(const Address &lhs, 201314564Sdim const Address &rhs); 202314564Sdim 203314564Sdim // For use with std::map, std::multi_map 204314564Sdim class ModulePointerAndOffsetLessThanFunctionObject { 205314564Sdim public: 206314564Sdim ModulePointerAndOffsetLessThanFunctionObject() = default; 207314564Sdim 208314564Sdim bool operator()(const Address &a, const Address &b) const { 209314564Sdim return Address::CompareModulePointerAndOffset(a, b) < 0; 210254721Semaste } 211314564Sdim }; 212254721Semaste 213314564Sdim /// Dump a description of this object to a Stream. 214314564Sdim /// 215341825Sdim /// Dump a description of the contents of this object to the supplied stream 216341825Sdim /// \a s. There are many ways to display a section offset based address, and 217341825Sdim /// \a style lets the user choose. 218314564Sdim /// 219353358Sdim /// \param[in] s 220314564Sdim /// The stream to which to dump the object description. 221314564Sdim /// 222353358Sdim /// \param[in] style 223314564Sdim /// The display style for the address. 224314564Sdim /// 225353358Sdim /// \param[in] fallback_style 226314564Sdim /// The display style for the address. 227314564Sdim /// 228353358Sdim /// \return 229314564Sdim /// Returns \b true if the address was able to be displayed. 230314564Sdim /// File and load addresses may be unresolved and it may not be 231314564Sdim /// possible to display a valid value, \b false will be returned 232314564Sdim /// in such cases. 233314564Sdim /// 234353358Sdim /// \see Address::DumpStyle 235314564Sdim bool Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, 236314564Sdim DumpStyle fallback_style = DumpStyleInvalid, 237314564Sdim uint32_t addr_byte_size = UINT32_MAX) const; 238254721Semaste 239341825Sdim AddressClass GetAddressClass() const; 240254721Semaste 241314564Sdim /// Get the file address. 242314564Sdim /// 243341825Sdim /// If an address comes from a file on disk that has section relative 244341825Sdim /// addresses, then it has a virtual address that is relative to unique 245341825Sdim /// section in the object file. 246314564Sdim /// 247353358Sdim /// \return 248314564Sdim /// The valid file virtual address, or LLDB_INVALID_ADDRESS if 249314564Sdim /// the address doesn't have a file virtual address (image is 250314564Sdim /// from memory only with no representation on disk). 251314564Sdim lldb::addr_t GetFileAddress() const; 252254721Semaste 253314564Sdim /// Get the load address. 254314564Sdim /// 255341825Sdim /// If an address comes from a file on disk that has section relative 256341825Sdim /// addresses, then it has a virtual address that is relative to unique 257341825Sdim /// section in the object file. Sections get resolved at runtime by 258341825Sdim /// DynamicLoader plug-ins as images (executables and shared libraries) get 259341825Sdim /// loaded/unloaded. If a section is loaded, then the load address can be 260341825Sdim /// resolved. 261314564Sdim /// 262353358Sdim /// \return 263314564Sdim /// The valid load virtual address, or LLDB_INVALID_ADDRESS if 264314564Sdim /// the address is currently not loaded. 265314564Sdim lldb::addr_t GetLoadAddress(Target *target) const; 266254721Semaste 267314564Sdim /// Get the load address as a callable code load address. 268314564Sdim /// 269341825Sdim /// This function will first resolve its address to a load address. Then, if 270341825Sdim /// the address turns out to be in code address, return the load address 271341825Sdim /// that would be required to call or return to. The address might have 272341825Sdim /// extra bits set (bit zero will be set to Thumb functions for an ARM 273341825Sdim /// target) that are required when changing the program counter to setting a 274341825Sdim /// return address. 275314564Sdim /// 276353358Sdim /// \return 277314564Sdim /// The valid load virtual address, or LLDB_INVALID_ADDRESS if 278314564Sdim /// the address is currently not loaded. 279314564Sdim lldb::addr_t GetCallableLoadAddress(Target *target, 280314564Sdim bool is_indirect = false) const; 281254721Semaste 282314564Sdim /// Get the load address as an opcode load address. 283314564Sdim /// 284341825Sdim /// This function will first resolve its address to a load address. Then, if 285341825Sdim /// the address turns out to be in code address, return the load address for 286341825Sdim /// an opcode. This address object might have extra bits set (bit zero will 287341825Sdim /// be set to Thumb functions for an 288314564Sdim /// ARM target) that are required for changing the program counter 289341825Sdim /// and this function will remove any bits that are intended for these 290341825Sdim /// special purposes. The result of this function can be used to safely 291341825Sdim /// write a software breakpoint trap to memory. 292314564Sdim /// 293353358Sdim /// \return 294314564Sdim /// The valid load virtual address with extra callable bits 295314564Sdim /// removed, or LLDB_INVALID_ADDRESS if the address is currently 296314564Sdim /// not loaded. 297314564Sdim lldb::addr_t GetOpcodeLoadAddress( 298314564Sdim Target *target, 299341825Sdim AddressClass addr_class = AddressClass::eInvalid) const; 300254721Semaste 301314564Sdim /// Get the section relative offset value. 302314564Sdim /// 303353358Sdim /// \return 304314564Sdim /// The current offset, or LLDB_INVALID_ADDRESS if this address 305314564Sdim /// doesn't contain a valid offset. 306314564Sdim lldb::addr_t GetOffset() const { return m_offset; } 307254721Semaste 308314564Sdim /// Check if an address is section offset. 309314564Sdim /// 310341825Sdim /// When converting a virtual file or load address into a section offset 311341825Sdim /// based address, we often need to know if, given a section list, if the 312341825Sdim /// address was able to be converted to section offset. This function 313341825Sdim /// returns true if the current value contained in this object is section 314341825Sdim /// offset based. 315314564Sdim /// 316353358Sdim /// \return 317314564Sdim /// Returns \b true if the address has a valid section and 318314564Sdim /// offset, \b false otherwise. 319314564Sdim bool IsSectionOffset() const { 320314564Sdim return IsValid() && (GetSection().get() != nullptr); 321314564Sdim } 322254721Semaste 323314564Sdim /// Check if the object state is valid. 324314564Sdim /// 325314564Sdim /// A valid Address object contains either a section pointer and 326341825Sdim /// offset (for section offset based addresses), or just a valid offset 327341825Sdim /// (for absolute addresses that have no section). 328314564Sdim /// 329353358Sdim /// \return 330314564Sdim /// Returns \b true if the offset is valid, \b false 331314564Sdim /// otherwise. 332314564Sdim bool IsValid() const { return m_offset != LLDB_INVALID_ADDRESS; } 333254721Semaste 334314564Sdim /// Get the memory cost of this object. 335314564Sdim /// 336353358Sdim /// \return 337314564Sdim /// The number of bytes that this object occupies in memory. 338314564Sdim size_t MemorySize() const; 339254721Semaste 340314564Sdim /// Resolve a file virtual address using a section list. 341314564Sdim /// 342341825Sdim /// Given a list of sections, attempt to resolve \a addr as an offset into 343341825Sdim /// one of the file sections. 344314564Sdim /// 345353358Sdim /// \return 346314564Sdim /// Returns \b true if \a addr was able to be resolved, \b false 347314564Sdim /// otherwise. 348314564Sdim bool ResolveAddressUsingFileSections(lldb::addr_t addr, 349314564Sdim const SectionList *sections); 350254721Semaste 351360784Sdim /// Resolve this address to its containing function and optionally get 352360784Sdim /// that function's address range. 353360784Sdim /// 354360784Sdim /// \param[out] sym_ctx 355360784Sdim /// The symbol context describing the function in which this address lies 356360784Sdim /// 357360784Sdim /// \parm[out] addr_range_ptr 358360784Sdim /// Pointer to the AddressRange to fill in with the function's address 359360784Sdim /// range. Caller may pass null if they don't need the address range. 360360784Sdim /// 361360784Sdim /// \return 362360784Sdim /// Returns \b false if the function/symbol could not be resolved 363360784Sdim /// or if the address range was requested and could not be resolved; 364360784Sdim /// returns \b true otherwise. 365360784Sdim bool ResolveFunctionScope(lldb_private::SymbolContext &sym_ctx, 366360784Sdim lldb_private::AddressRange *addr_range_ptr = nullptr); 367360784Sdim 368314564Sdim /// Set the address to represent \a load_addr. 369314564Sdim /// 370341825Sdim /// The address will attempt to find a loaded section within \a target that 371341825Sdim /// contains \a load_addr. If successful, this address object will have a 372341825Sdim /// valid section and offset. Else this address object will have no section 373341825Sdim /// (NULL) and the offset will be \a load_addr. 374314564Sdim /// 375353358Sdim /// \param[in] load_addr 376314564Sdim /// A load address from a current process. 377314564Sdim /// 378353358Sdim /// \param[in] target 379314564Sdim /// The target to use when trying resolve the address into 380314564Sdim /// a section + offset. The Target's SectionLoadList object 381314564Sdim /// is used to resolve the address. 382314564Sdim /// 383353358Sdim /// \param[in] allow_section_end 384321369Sdim /// If true, treat an address pointing to the end of the module as 385321369Sdim /// belonging to that module. 386321369Sdim /// 387353358Sdim /// \return 388314564Sdim /// Returns \b true if the load address was resolved to be 389314564Sdim /// section/offset, \b false otherwise. It is often ok for an 390353358Sdim /// address to not resolve to a section in a module, this often 391314564Sdim /// happens for JIT'ed code, or any load addresses on the stack 392314564Sdim /// or heap. 393321369Sdim bool SetLoadAddress(lldb::addr_t load_addr, Target *target, 394321369Sdim bool allow_section_end = false); 395254721Semaste 396314564Sdim bool SetOpcodeLoadAddress( 397314564Sdim lldb::addr_t load_addr, Target *target, 398341825Sdim AddressClass addr_class = AddressClass::eInvalid, 399321369Sdim bool allow_section_end = false); 400254721Semaste 401314564Sdim bool SetCallableLoadAddress(lldb::addr_t load_addr, Target *target); 402254721Semaste 403314564Sdim /// Get accessor for the module for this address. 404314564Sdim /// 405353358Sdim /// \return 406314564Sdim /// Returns the Module pointer that this address is an offset 407314564Sdim /// in, or NULL if this address doesn't belong in a module, or 408314564Sdim /// isn't resolved yet. 409314564Sdim lldb::ModuleSP GetModule() const; 410254721Semaste 411314564Sdim /// Get const accessor for the section. 412314564Sdim /// 413353358Sdim /// \return 414314564Sdim /// Returns the const lldb::Section pointer that this address is an 415314564Sdim /// offset in, or NULL if this address is absolute. 416314564Sdim lldb::SectionSP GetSection() const { return m_section_wp.lock(); } 417254721Semaste 418314564Sdim /// Set accessor for the offset. 419314564Sdim /// 420353358Sdim /// \param[in] offset 421314564Sdim /// A new offset value for this object. 422314564Sdim /// 423353358Sdim /// \return 424314564Sdim /// Returns \b true if the offset changed, \b false otherwise. 425314564Sdim bool SetOffset(lldb::addr_t offset) { 426314564Sdim bool changed = m_offset != offset; 427314564Sdim m_offset = offset; 428314564Sdim return changed; 429314564Sdim } 430254721Semaste 431314564Sdim void SetRawAddress(lldb::addr_t addr) { 432314564Sdim m_section_wp.reset(); 433314564Sdim m_offset = addr; 434314564Sdim } 435254721Semaste 436314564Sdim bool Slide(int64_t offset) { 437314564Sdim if (m_offset != LLDB_INVALID_ADDRESS) { 438314564Sdim m_offset += offset; 439314564Sdim return true; 440254721Semaste } 441314564Sdim return false; 442314564Sdim } 443254721Semaste 444314564Sdim /// Set accessor for the section. 445314564Sdim /// 446360784Sdim /// \param[in] section_sp 447314564Sdim /// A new lldb::Section pointer to use as the section base. Can 448314564Sdim /// be NULL for absolute addresses that are not relative to 449314564Sdim /// any section. 450314564Sdim void SetSection(const lldb::SectionSP §ion_sp) { 451314564Sdim m_section_wp = section_sp; 452314564Sdim } 453254721Semaste 454314564Sdim void ClearSection() { m_section_wp.reset(); } 455254721Semaste 456314564Sdim /// Reconstruct a symbol context from an address. 457314564Sdim /// 458341825Sdim /// This class doesn't inherit from SymbolContextScope because many address 459341825Sdim /// objects have short lifespans. Address objects that are section offset 460341825Sdim /// can reconstruct their symbol context by looking up the address in the 461341825Sdim /// module found in the section. 462314564Sdim /// 463353358Sdim /// \see SymbolContextScope::CalculateSymbolContext(SymbolContext*) 464344779Sdim uint32_t CalculateSymbolContext(SymbolContext *sc, 465344779Sdim lldb::SymbolContextItem resolve_scope = 466344779Sdim lldb::eSymbolContextEverything) const; 467296417Sdim 468314564Sdim lldb::ModuleSP CalculateSymbolContextModule() const; 469254721Semaste 470314564Sdim CompileUnit *CalculateSymbolContextCompileUnit() const; 471254721Semaste 472314564Sdim Function *CalculateSymbolContextFunction() const; 473254721Semaste 474314564Sdim Block *CalculateSymbolContextBlock() const; 475254721Semaste 476314564Sdim Symbol *CalculateSymbolContextSymbol() const; 477258884Semaste 478314564Sdim bool CalculateSymbolContextLineEntry(LineEntry &line_entry) const; 479314564Sdim 480341825Sdim // Returns true if the section should be valid, but isn't because the shared 481341825Sdim // pointer to the section can't be reconstructed from a weak pointer that 482341825Sdim // contains a valid weak reference to a section. Returns false if the section 483341825Sdim // weak pointer has no reference to a section, or if the section is still 484341825Sdim // valid 485314564Sdim bool SectionWasDeleted() const; 486314564Sdim 487254721Semasteprotected: 488314564Sdim // Member variables. 489314564Sdim lldb::SectionWP m_section_wp; ///< The section for the address, can be NULL. 490314564Sdim lldb::addr_t m_offset; ///< Offset into section if \a m_section_wp is valid... 491314564Sdim 492341825Sdim // Returns true if the m_section_wp once had a reference to a valid section 493341825Sdim // shared pointer, but no longer does. This can happen if we have an address 494341825Sdim // from a module that gets unloaded and deleted. This function should only be 495341825Sdim // called if GetSection() returns an empty shared pointer and you want to 496341825Sdim // know if this address used to have a valid section. 497314564Sdim bool SectionWasDeletedPrivate() const; 498254721Semaste}; 499254721Semaste 500314564Sdim// NOTE: Be careful using this operator. It can correctly compare two 501341825Sdim// addresses from the same Module correctly. It can't compare two addresses 502341825Sdim// from different modules in any meaningful way, but it will compare the module 503341825Sdim// pointers. 504314564Sdim// 505254721Semaste// To sum things up: 506341825Sdim// - works great for addresses within the same module - it works for addresses 507341825Sdim// across multiple modules, but don't expect the 508254721Semaste// address results to make much sense 509254721Semaste// 510341825Sdim// This basically lets Address objects be used in ordered collection classes. 511314564Sdimbool operator<(const Address &lhs, const Address &rhs); 512314564Sdimbool operator>(const Address &lhs, const Address &rhs); 513314564Sdimbool operator==(const Address &lhs, const Address &rhs); 514314564Sdimbool operator!=(const Address &lhs, const Address &rhs); 515254721Semaste 516254721Semaste} // namespace lldb_private 517254721Semaste 518296417Sdim#endif // liblldb_Address_h_ 519