mirror of
https://github.com/intel/llvm.git
synced 2026-01-21 20:53:29 +08:00
lldb was mmap'ing archive files once per .o file it loads, now it correctly shares the archive between modules. LLDB was also always mapping entire contents of universal mach-o files, now it maps just the slice that is required. Added a new logging channel for "lldb" called "mmap" to help track future regressions. Modified the ObjectFile and ObjectContainer plugin interfaces to take a data offset along with the file offset and size so we can implement the correct caching and efficient reading of parts of files without mmap'ing the entire file like we used to. The current implementation still keeps entire .a files mmaped (once) and entire slices from universal files mmaped to ensure that if a client builds their binaries during a debug session we don't lose our data and get corrupt object file info and debug info. llvm-svn: 174524
237 lines
8.5 KiB
C++
237 lines
8.5 KiB
C++
//===-- ObjectContainer.h ---------------------------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef liblldb_ObjectContainer_h_
|
|
#define liblldb_ObjectContainer_h_
|
|
|
|
// C Includes
|
|
// C++ Includes
|
|
// Other libraries and framework includes
|
|
// Project includes
|
|
|
|
#include "lldb/lldb-private.h"
|
|
#include "lldb/Core/DataExtractor.h"
|
|
#include "lldb/Host/FileSpec.h"
|
|
#include "lldb/Core/ModuleChild.h"
|
|
#include "lldb/Core/PluginInterface.h"
|
|
#include "lldb/Host/Endian.h"
|
|
|
|
namespace lldb_private {
|
|
|
|
//----------------------------------------------------------------------
|
|
/// @class ObjectContainer ObjectContainer.h "lldb/Symbol/ObjectContainer.h"
|
|
/// @brief A plug-in interface definition class for object containers.
|
|
///
|
|
/// Object containers contain object files from one or more
|
|
/// architectures, and also can contain one or more named objects.
|
|
///
|
|
/// Typical object containers are static libraries (.a files) that
|
|
/// contain multiple named object files, and universal files that contain
|
|
/// multiple architectures.
|
|
//----------------------------------------------------------------------
|
|
class ObjectContainer :
|
|
public PluginInterface,
|
|
public ModuleChild
|
|
{
|
|
public:
|
|
//------------------------------------------------------------------
|
|
/// Construct with a parent module, offset, and header data.
|
|
///
|
|
/// Object files belong to modules and a valid module must be
|
|
/// supplied upon construction. The at an offset within a file for
|
|
/// objects that contain more than one architecture or object.
|
|
//------------------------------------------------------------------
|
|
ObjectContainer (const lldb::ModuleSP &module_sp,
|
|
const FileSpec *file,
|
|
lldb::offset_t file_offset,
|
|
lldb::offset_t length,
|
|
lldb::DataBufferSP& data_sp,
|
|
lldb::offset_t data_offset) :
|
|
ModuleChild (module_sp),
|
|
m_file (), // This file can be different than the module's file spec
|
|
m_offset (file_offset),
|
|
m_length (length),
|
|
m_data ()
|
|
{
|
|
if (file)
|
|
m_file = *file;
|
|
if (data_sp)
|
|
m_data.SetData (data_sp, data_offset, length);
|
|
}
|
|
|
|
//------------------------------------------------------------------
|
|
/// Destructor.
|
|
///
|
|
/// The destructor is virtual since this class is designed to be
|
|
/// inherited from by the plug-in instance.
|
|
//------------------------------------------------------------------
|
|
virtual
|
|
~ObjectContainer()
|
|
{
|
|
}
|
|
|
|
//------------------------------------------------------------------
|
|
/// Dump a description of this object to a Stream.
|
|
///
|
|
/// Dump a description of the current contents of this object
|
|
/// to the supplied stream \a s. The dumping should include the
|
|
/// section list if it has been parsed, and the symbol table
|
|
/// if it has been parsed.
|
|
///
|
|
/// @param[in] s
|
|
/// The stream to which to dump the object descripton.
|
|
//------------------------------------------------------------------
|
|
virtual void
|
|
Dump (Stream *s) const = 0;
|
|
|
|
//------------------------------------------------------------------
|
|
/// Gets the architecture given an index.
|
|
///
|
|
/// Copies the architecture specification for index \a idx.
|
|
///
|
|
/// @param[in] idx
|
|
/// The architecture index to extract.
|
|
///
|
|
/// @param[out] arch
|
|
/// A architecture object that will be filled in if \a idx is a
|
|
/// architecture valid index.
|
|
///
|
|
/// @return
|
|
/// Returns \b true if \a idx is valid and \a arch has been
|
|
/// filled in, \b false otherwise.
|
|
///
|
|
/// @see ObjectContainer::GetNumArchitectures() const
|
|
//------------------------------------------------------------------
|
|
virtual bool
|
|
GetArchitectureAtIndex (uint32_t idx, ArchSpec& arch) const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//------------------------------------------------------------------
|
|
/// Returns the offset into a file at which this object resides.
|
|
///
|
|
/// Some files contain many object files, and this function allows
|
|
/// access to an object's offset within the file.
|
|
///
|
|
/// @return
|
|
/// The offset in bytes into the file. Defaults to zero for
|
|
/// simple object files that a represented by an entire file.
|
|
//------------------------------------------------------------------
|
|
virtual lldb::addr_t
|
|
GetOffset () const
|
|
{ return m_offset; }
|
|
|
|
virtual lldb::addr_t
|
|
GetByteSize () const
|
|
{ return m_length; }
|
|
|
|
//------------------------------------------------------------------
|
|
/// Get the number of objects within this object file (archives).
|
|
///
|
|
/// @return
|
|
/// Zero for object files that are not archives, or the number
|
|
/// of objects contained in the archive.
|
|
//------------------------------------------------------------------
|
|
virtual size_t
|
|
GetNumObjects () const
|
|
{ return 0; }
|
|
|
|
//------------------------------------------------------------------
|
|
/// Get the number of architectures in this object file.
|
|
///
|
|
/// The default implementation returns 1 as for object files that
|
|
/// contain a single architecture. ObjectContainer instances that
|
|
/// contain more than one architecture should override this function
|
|
/// and return an appropriate value.
|
|
///
|
|
/// @return
|
|
/// The number of architectures contained in this object file.
|
|
//------------------------------------------------------------------
|
|
virtual size_t
|
|
GetNumArchitectures () const
|
|
{ return 0; }
|
|
|
|
//------------------------------------------------------------------
|
|
/// Attempts to parse the object header.
|
|
///
|
|
/// This function is used as a test to see if a given plug-in
|
|
/// instance can parse the header data already contained in
|
|
/// ObjectContainer::m_data. If an object file parser does not
|
|
/// recognize that magic bytes in a header, false should be returned
|
|
/// and the next plug-in can attempt to parse an object file.
|
|
///
|
|
/// @return
|
|
/// Returns \b true if the header was parsed succesfully, \b
|
|
/// false otherwise.
|
|
//------------------------------------------------------------------
|
|
virtual bool
|
|
ParseHeader () = 0;
|
|
|
|
//------------------------------------------------------------------
|
|
/// Selects an architecture in an object file.
|
|
///
|
|
/// Object files that contain a single architecture should verify
|
|
/// that the specified \a arch matches the architecture in in
|
|
/// object file and return \b true or \b false accordingly.
|
|
///
|
|
/// Object files that contain more than one architecture should
|
|
/// attempt to select that architecture, and if successful, clear
|
|
/// out any previous state from any previously selected architecture
|
|
/// and prepare to return information for the new architecture.
|
|
///
|
|
/// @return
|
|
/// Returns a pointer to the object file of the requested \a
|
|
/// arch and optional \a name. Returns NULL of no such object
|
|
/// file exists in the container.
|
|
//------------------------------------------------------------------
|
|
virtual lldb::ObjectFileSP
|
|
GetObjectFile (const FileSpec *file) = 0;
|
|
|
|
virtual bool
|
|
ObjectAtIndexIsContainer (uint32_t object_idx)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
virtual ObjectFile *
|
|
GetObjectFileAtIndex (uint32_t object_idx)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
virtual ObjectContainer *
|
|
GetObjectContainerAtIndex (uint32_t object_idx)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
virtual const char *
|
|
GetObjectNameAtIndex (uint32_t object_idx) const
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
protected:
|
|
//------------------------------------------------------------------
|
|
// Member variables.
|
|
//------------------------------------------------------------------
|
|
FileSpec m_file; ///< The file that represents this container objects (which can be different from the module's file).
|
|
lldb::addr_t m_offset; ///< The offset in bytes into the file, or the address in memory
|
|
lldb::addr_t m_length; ///< The size in bytes if known (can be zero).
|
|
DataExtractor m_data; ///< The data for this object file so things can be parsed lazily.
|
|
|
|
private:
|
|
DISALLOW_COPY_AND_ASSIGN (ObjectContainer);
|
|
};
|
|
|
|
} // namespace lldb_private
|
|
|
|
#endif // liblldb_ObjectContainer_h_
|