[Lldb-commits] [lldb] r134779 - in /lldb/trunk: include/lldb/Symbol/ObjectFile.h source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp source/Plugins/ObjectFile/ELF/ObjectFileELF.h source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h

Greg Clayton gclayton at apple.com
Fri Jul 8 17:41:34 PDT 2011


Author: gclayton
Date: Fri Jul  8 19:41:34 2011
New Revision: 134779

URL: http://llvm.org/viewvc/llvm-project?rev=134779&view=rev
Log:
Added the ability to get an abstract file type (executable, object file, 
shared library, etc) and strata (user/kernel) from an object file. This will
help with plug-in and platform selection when given a new binary with the
"target create <file>" command.


Modified:
    lldb/trunk/include/lldb/Symbol/ObjectFile.h
    lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
    lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
    lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
    lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h

Modified: lldb/trunk/include/lldb/Symbol/ObjectFile.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ObjectFile.h?rev=134779&r1=134778&r2=134779&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ObjectFile.h (original)
+++ lldb/trunk/include/lldb/Symbol/ObjectFile.h Fri Jul  8 19:41:34 2011
@@ -56,6 +56,27 @@
 friend class lldb_private::Module;
 
 public:
+    typedef enum 
+    {
+        eTypeInvalid = 0,
+        eTypeCoreFile,      /// A core file that has a checkpoint of a program's execution state
+        eTypeExecutable,    /// A normal executable
+        eTypeDebugInfo,     /// An object file that contains only debug information
+        eTypeDynamicLinker, /// The platform's dynamic linker executable
+        eTypeObjectFile,    /// An intermediate object file
+        eTypeSharedLibrary, /// A shared library that can be used during execution
+        eTypeStubLibrary,   /// A library that can be linked against but not used for execution
+        eTypeUnknown,
+    } Type;
+
+    typedef enum 
+    {
+        eStrataInvalid = 0,
+        eStrataUnknown,
+        eStrataUser,
+        eStrataKernel
+    } Strata;
+        
     //------------------------------------------------------------------
     /// Construct with a parent module, offset, and header data.
     ///
@@ -66,6 +87,8 @@
     ObjectFile (Module* module, const FileSpec *file_spec_ptr, lldb::addr_t offset, lldb::addr_t length, lldb::DataBufferSP& headerDataSP) :
         ModuleChild (module),
         m_file (),  // This file could be different from the original module's file
+        m_type (eTypeInvalid),
+        m_strata (eStrataInvalid),
         m_offset (offset),
         m_length (length),
         m_data (headerDataSP, lldb::endian::InlHostByteOrder(), 4),
@@ -356,11 +379,64 @@
     virtual lldb_private::Address
     GetEntryPointAddress () { return Address();}
 
+    //------------------------------------------------------------------
+    /// The object file should be able to calculate its type by looking
+    /// at its file header and possibly the sections or other data in
+    /// the object file. The file type is used in the debugger to help
+    /// select the correct plug-ins for the job at hand, so this is 
+    /// important to get right. If any eTypeXXX definitions do not match
+    /// up with the type of file you are loading, please feel free to
+    /// add a new enumeration value.
+    ///
+    /// @return
+    ///     The calculated file type for the current object file.
+    //------------------------------------------------------------------
+    virtual Type
+    CalculateType() = 0;
+
+    //------------------------------------------------------------------
+    /// The object file should be able to calculate the strata of the
+    /// object file.
+    ///
+    /// Many object files for platforms might be for either user space
+    /// debugging or for kernel debugging. If your object file subclass
+    /// can figure this out, it will help with debugger plug-in selection
+    /// when it comes time to debug.
+    ///
+    /// @return
+    ///     The calculated object file strata for the current object 
+    ///     file.
+    //------------------------------------------------------------------
+    virtual Strata
+    CalculateStrata() = 0;
+    
+    //------------------------------------------------------------------
+    // Member Functions
+    //------------------------------------------------------------------
+    Type
+    GetType ()
+    {
+        if (m_type == eTypeInvalid)
+            m_type = CalculateType();
+        return m_type;
+    }
+    
+    Strata
+    GetStrata ()
+    {
+        if (m_strata == eStrataInvalid)
+            m_strata = CalculateStrata();
+        return m_strata;
+    }
+    
+
 protected:
     //------------------------------------------------------------------
     // Member variables.
     //------------------------------------------------------------------
     FileSpec m_file;
+    Type m_type;
+    Strata m_strata;
     lldb::addr_t m_offset; ///< The offset in bytes into the file, or the address in memory
     lldb::addr_t m_length; ///< The length of this object file if it is known (can be zero if length is unknown or can't be determined).
     DataExtractor m_data; ///< The data for this object file so things can be parsed lazily.

Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp?rev=134779&r1=134778&r2=134779&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp Fri Jul  8 19:41:34 2011
@@ -1421,3 +1421,74 @@
     return true;
 }
 
+ObjectFile::Type
+ObjectFileELF::CalculateType()
+{
+    switch (m_header.e_type)
+    {
+        case llvm::ELF::ET_NONE:
+            // 0 - No file type
+            return eTypeUnknown;
+
+        case llvm::ELF::ET_REL:
+            // 1 - Relocatable file
+            return eTypeObjectFile;
+
+        case llvm::ELF::ET_EXEC:
+            // 2 - Executable file
+            return eTypeExecutable;
+
+        case llvm::ELF::ET_DYN:
+            // 3 - Shared object file
+            return eTypeSharedLibrary;
+
+        case ET_CORE:
+            // 4 - Core file
+            return eTypeCoreFile;
+
+        default:
+            break;
+    }
+    return eTypeUnknown;
+}
+
+ObjectFile::Strata
+ObjectFileELF::CalculateStrata()
+{
+    switch (m_header.e_type)
+    {
+        case llvm::ELF::ET_NONE:    
+            // 0 - No file type
+            return eStrataUnknown;
+
+        case llvm::ELF::ET_REL:
+            // 1 - Relocatable file
+            return eStrataUnknown;
+
+        case llvm::ELF::ET_EXEC:
+            // 2 - Executable file
+            // TODO: is there any way to detect that an executable is a kernel
+            // related executable by inspecting the program headers, section 
+            // headers, symbols, or any other flag bits???
+            return eStrataUser;
+
+        case llvm::ELF::ET_DYN:
+            // 3 - Shared object file
+            // TODO: is there any way to detect that an shared library is a kernel
+            // related executable by inspecting the program headers, section 
+            // headers, symbols, or any other flag bits???
+            return eStrataUnknown;
+
+        case ET_CORE:
+            // 4 - Core file
+            // TODO: is there any way to detect that an core file is a kernel
+            // related executable by inspecting the program headers, section 
+            // headers, symbols, or any other flag bits???
+            return eStrataUnknown;
+
+        default:
+            break;
+    }
+    return eStrataUnknown;
+}
+

Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h?rev=134779&r1=134778&r2=134779&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h (original)
+++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h Fri Jul  8 19:41:34 2011
@@ -104,6 +104,12 @@
     
     virtual lldb_private::Address
     GetEntryPointAddress ();
+    
+    virtual ObjectFile::Type
+    CalculateType();
+    
+    virtual ObjectFile::Strata
+    CalculateStrata();
 
 private:
     ObjectFileELF(lldb_private::Module* module,

Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp?rev=134779&r1=134778&r2=134779&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Fri Jul  8 19:41:34 2011
@@ -1672,6 +1672,90 @@
 
 }
 
+ObjectFile::Type
+ObjectFileMachO::CalculateType()
+{
+    switch (m_header.filetype)
+    {
+        case HeaderFileTypeObject:                                          // 0x1u MH_OBJECT
+            if (GetAddressByteSize () == 4)
+            {
+                // 32 bit kexts are just object files, but they do have a valid
+                // UUID load command.
+                UUID uuid;
+                if (GetUUID(&uuid))
+                {
+                    // this checking for the UUID load command is not enough
+                    // we could eventually look for the symbol named 
+                    // "OSKextGetCurrentIdentifier" as this is required of kexts
+                    if (m_strata == eStrataInvalid)
+                        m_strata = eStrataKernel;
+                    return eTypeSharedLibrary;
+                }
+            }
+            return eTypeObjectFile;
+
+        case HeaderFileTypeExecutable:          return eTypeExecutable;     // 0x2u MH_EXECUTE
+        case HeaderFileTypeFixedVMShlib:        return eTypeSharedLibrary;  // 0x3u MH_FVMLIB
+        case HeaderFileTypeCore:                return eTypeCoreFile;       // 0x4u MH_CORE
+        case HeaderFileTypePreloadedExecutable: return eTypeSharedLibrary;  // 0x5u MH_PRELOAD
+        case HeaderFileTypeDynamicShlib:        return eTypeSharedLibrary;  // 0x6u MH_DYLIB
+        case HeaderFileTypeDynamicLinkEditor:   return eTypeDynamicLinker;  // 0x7u MH_DYLINKER
+        case HeaderFileTypeBundle:              return eTypeSharedLibrary;  // 0x8u MH_BUNDLE
+        case HeaderFileTypeDynamicShlibStub:    return eTypeStubLibrary;    // 0x9u MH_DYLIB_STUB
+        case HeaderFileTypeDSYM:                return eTypeDebugInfo;      // 0xAu MH_DSYM
+        case HeaderFileTypeKextBundle:          return eTypeSharedLibrary;  // 0xBu MH_KEXT_BUNDLE
+        default:
+            break;
+    }
+    return eTypeUnknown;
+}
+
+ObjectFile::Strata
+ObjectFileMachO::CalculateStrata()
+{
+    switch (m_header.filetype)
+    {
+        case HeaderFileTypeObject:      // 0x1u MH_OBJECT
+            {
+                // 32 bit kexts are just object files, but they do have a valid
+                // UUID load command.
+                UUID uuid;
+                if (GetUUID(&uuid))
+                {
+                    // this checking for the UUID load command is not enough
+                    // we could eventually look for the symbol named 
+                    // "OSKextGetCurrentIdentifier" as this is required of kexts
+                    if (m_type == eTypeInvalid)
+                        m_type = eTypeSharedLibrary;
+
+                    return eStrataKernel;
+                }
+            }
+            return eStrataUnknown;
+
+        case HeaderFileTypeExecutable:                                     // 0x2u MH_EXECUTE
+            // Check for the MH_DYLDLINK bit in the flags
+            if (m_header.flags & HeaderFlagBitIsDynamicLinkObject)
+                return eStrataUser;
+            return eStrataKernel;
+
+        case HeaderFileTypeFixedVMShlib:        return eStrataUser;         // 0x3u MH_FVMLIB
+        case HeaderFileTypeCore:                return eStrataUnknown;      // 0x4u MH_CORE
+        case HeaderFileTypePreloadedExecutable: return eStrataUser;         // 0x5u MH_PRELOAD
+        case HeaderFileTypeDynamicShlib:        return eStrataUser;         // 0x6u MH_DYLIB
+        case HeaderFileTypeDynamicLinkEditor:   return eStrataUser;         // 0x7u MH_DYLINKER
+        case HeaderFileTypeBundle:              return eStrataUser;         // 0x8u MH_BUNDLE
+        case HeaderFileTypeDynamicShlibStub:    return eStrataUser;         // 0x9u MH_DYLIB_STUB
+        case HeaderFileTypeDSYM:                return eStrataUnknown;      // 0xAu MH_DSYM
+        case HeaderFileTypeKextBundle:          return eStrataKernel;       // 0xBu MH_KEXT_BUNDLE
+        default:
+            break;
+    }
+    return eStrataUnknown;
+}
+
+
 bool
 ObjectFileMachO::GetArchitecture (ArchSpec &arch)
 {

Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h?rev=134779&r1=134778&r2=134779&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h (original)
+++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h Fri Jul  8 19:41:34 2011
@@ -110,6 +110,12 @@
     virtual lldb_private::Address
     GetEntryPointAddress ();
 
+    virtual ObjectFile::Type
+    CalculateType();
+    
+    virtual ObjectFile::Strata
+    CalculateStrata();
+
 protected:
     mutable lldb_private::Mutex m_mutex;
     llvm::MachO::mach_header m_header;





More information about the lldb-commits mailing list