124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- DataBufferMemoryMap.cpp ---------------------------------*- C++ -*-===//
224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//                     The LLVM Compiler Infrastructure
424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source
624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details.
724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===//
924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <errno.h>
1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <fcntl.h>
13ec2d9787bed36e9eda6eac1996c7bed76c8d3da4Stephen Wilson#include <limits.h>
1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <sys/stat.h>
1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <sys/mman.h>
1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/DataBufferMemoryMap.h"
1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Error.h"
19b42c2adff30e145b8435faec0d9f9e2355b6007cGreg Clayton#include "lldb/Host/File.h"
205f54ac373b119a4c6693e4875c48aa761fba0c86Greg Clayton#include "lldb/Host/FileSpec.h"
2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Host/Host.h"
22cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton#include "lldb/Core/Log.h"
23cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton#include "lldb/lldb-private-log.h"
2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
25cbe61bd26db663fa3036866dc33315c6ffc37910Greg Claytonusing namespace lldb;
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private;
2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Default Constructor
3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDataBufferMemoryMap::DataBufferMemoryMap() :
3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_mmap_addr(NULL),
3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_mmap_size(0),
3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_data(NULL),
3506d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton    m_size(0)
3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Virtual destructor since this class inherits from a pure virtual
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// base class.
4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDataBufferMemoryMap::~DataBufferMemoryMap()
4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Clear();
4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Return a pointer to the bytes owned by this object, or NULL if
5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// the object contains no bytes.
5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint8_t *
5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDataBufferMemoryMap::GetBytes()
5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return m_data;
5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Return a const pointer to the bytes owned by this object, or NULL
6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// if the object contains no bytes.
6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerconst uint8_t *
6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDataBufferMemoryMap::GetBytes() const
6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return m_data;
6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Return the number of bytes this object currently contains.
7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
71fe6dc6e241c52822710380cec0931351a1d7b2d3Greg Claytonuint64_t
7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDataBufferMemoryMap::GetByteSize() const
7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return m_size;
7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Reverts this object to an empty state by unmapping any memory
7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// that is currently owned.
8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDataBufferMemoryMap::Clear()
8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (m_mmap_addr != NULL)
8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
86952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MMAP));
87cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton        if (log)
88cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton            log->Printf("DataBufferMemoryMap::Clear() m_mmap_addr = %p, m_mmap_size = %zu", m_mmap_addr, m_mmap_size);
8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ::munmap((void *)m_mmap_addr, m_mmap_size);
9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_mmap_addr = NULL;
9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_mmap_size = 0;
9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_data = NULL;
9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_size = 0;
9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Memory map "length" bytes from "file" starting "offset"
99ced18cd66f0f32ec1d2226005044dd1cd44710c6Eli Friedman// bytes into the file. If "length" is set to SIZE_MAX, then
10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// map as many bytes as possible.
10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Returns the number of bytes mapped starting from the requested
10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// offset.
10424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnersize_t
106bf41e19c78f0c84671d21eadec3954ab6db550c1Jason MolendaDataBufferMemoryMap::MemoryMapFromFileSpec (const FileSpec* filespec,
107fe6dc6e241c52822710380cec0931351a1d7b2d3Greg Clayton                                            lldb::offset_t offset,
108fe6dc6e241c52822710380cec0931351a1d7b2d3Greg Clayton                                            lldb::offset_t length,
10906d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton                                            bool writeable)
11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
111bf41e19c78f0c84671d21eadec3954ab6db550c1Jason Molenda    if (filespec != NULL)
11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
113952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MMAP));
114cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton        if (log)
115cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton        {
11697a19b21dacd9063bb5475812df7781777262198Greg Clayton            log->Printf("DataBufferMemoryMap::MemoryMapFromFileSpec(file=\"%s\", offset=0x%" PRIx64 ", length=0x%" PRIx64 ", writeable=%i",
11797a19b21dacd9063bb5475812df7781777262198Greg Clayton                        filespec->GetPath().c_str(),
118cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton                        offset,
119cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton                        length,
120cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton                        writeable);
121cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton        }
12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        char path[PATH_MAX];
123bf41e19c78f0c84671d21eadec3954ab6db550c1Jason Molenda        if (filespec->GetPath(path, sizeof(path)))
12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
125b42c2adff30e145b8435faec0d9f9e2355b6007cGreg Clayton            uint32_t options = File::eOpenOptionRead;
12606d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton            if (writeable)
127b42c2adff30e145b8435faec0d9f9e2355b6007cGreg Clayton                options |= File::eOpenOptionWrite;
12806d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton
129b42c2adff30e145b8435faec0d9f9e2355b6007cGreg Clayton            File file;
130b42c2adff30e145b8435faec0d9f9e2355b6007cGreg Clayton            Error error (file.Open(path, options));
131b42c2adff30e145b8435faec0d9f9e2355b6007cGreg Clayton            if (error.Success())
13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
13306d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton                const bool fd_is_file = true;
13436da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton                return MemoryMapFromFileDescriptor (file.GetDescriptor(), offset, length, writeable, fd_is_file);
13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // We should only get here if there was an error
13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Clear();
14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return 0;
14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// The file descriptor FD is assumed to already be opened as read only
14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// and the STAT structure is assumed to a valid pointer and already
14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// containing valid data from a call to stat().
14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Memory map FILE_LENGTH bytes in FILE starting FILE_OFFSET bytes into
150ced18cd66f0f32ec1d2226005044dd1cd44710c6Eli Friedman// the file. If FILE_LENGTH is set to SIZE_MAX, then map as many bytes
15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// as possible.
15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// RETURNS
15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  Number of bytes mapped starting from the requested offset.
15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnersize_t
15706d7cc86937caca0acf2b990a02a641dc9c7579aGreg ClaytonDataBufferMemoryMap::MemoryMapFromFileDescriptor (int fd,
158fe6dc6e241c52822710380cec0931351a1d7b2d3Greg Clayton                                                  lldb::offset_t offset,
159fe6dc6e241c52822710380cec0931351a1d7b2d3Greg Clayton                                                  lldb::offset_t length,
16006d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton                                                  bool writeable,
16106d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton                                                  bool fd_is_file)
16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Clear();
16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (fd >= 0)
16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
166952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MMAP|LIBLLDB_LOG_VERBOSE));
167cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton        if (log)
168cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton        {
169fe6dc6e241c52822710380cec0931351a1d7b2d3Greg Clayton            log->Printf("DataBufferMemoryMap::MemoryMapFromFileSpec(fd=%i, offset=0x%" PRIx64 ", length=0x%" PRIx64 ", writeable=%i, fd_is_file=%i)",
170cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton                        fd,
171cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton                        offset,
172cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton                        length,
173cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton                        writeable,
174cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton                        fd_is_file);
175cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton        }
17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        struct stat stat;
17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (::fstat(fd, &stat) == 0)
17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
179f38b76b91b243f6ff845387278beea78887aef3bJason Molenda            if (S_ISREG(stat.st_mode) && (stat.st_size > offset))
18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
18154e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton                const size_t max_bytes_available = stat.st_size - offset;
182ced18cd66f0f32ec1d2226005044dd1cd44710c6Eli Friedman                if (length == SIZE_MAX)
18354e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton                {
18454e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton                    length = max_bytes_available;
18554e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton                }
18654e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton                else if (length > max_bytes_available)
18754e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton                {
18854e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton                    // Cap the length if too much data was requested
18954e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton                    length = max_bytes_available;
19054e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton                }
19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (length > 0)
19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
19406d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton                    int prot = PROT_READ;
19506d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton                    if (writeable)
19606d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton                        prot |= PROT_WRITE;
19706d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton
198b01327fc79e484f0716de7c87829c180083cd8ccGreg Clayton                    int flags = MAP_PRIVATE;
19906d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton                    if (fd_is_file)
20006d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton                        flags |= MAP_FILE;
20106d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton
20206d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton                    m_mmap_addr = (uint8_t *)::mmap(NULL, length, prot, flags, fd, offset);
203cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton                    Error error;
20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (m_mmap_addr == (void*)-1)
20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    {
20706d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton                        error.SetErrorToErrno ();
20806d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton                        if (error.GetError() == EINVAL)
20924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        {
21024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            // We may still have a shot at memory mapping if we align things correctly
21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            size_t page_offset = offset % Host::GetPageSize();
21224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            if (page_offset != 0)
21324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            {
21406d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton                                m_mmap_addr = (uint8_t *)::mmap(NULL, length + page_offset, prot, flags, fd, offset - page_offset);
21524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                if (m_mmap_addr == (void*)-1)
21624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                {
21724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                    // Failed to map file
21824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                    m_mmap_addr = NULL;
21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                }
22024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                else if (m_mmap_addr != NULL)
22124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                {
22224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                    // We recovered and were able to memory map
22324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                    // after we aligned things to page boundaries
22424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
22524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                    // Save the actual mmap'ed size
22624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                    m_mmap_size = length + page_offset;
22724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                    // Our data is at an offset into the the mapped data
22824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                    m_data = m_mmap_addr + page_offset;
22924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                    // Our pretend size is the size that was requestd
23024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                    m_size = length;
23124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                }
23224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            }
23324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        }
23487677ee7c3935a7be891034c7ee6ef93bdc5de8dJason Molenda                        if (error.GetError() == ENOMEM)
23587677ee7c3935a7be891034c7ee6ef93bdc5de8dJason Molenda                        {
2365f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea                           error.SetErrorStringWithFormat("could not allocate %" PRId64 " bytes of memory to mmap in file", (uint64_t) length);
23787677ee7c3935a7be891034c7ee6ef93bdc5de8dJason Molenda                        }
23824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    }
23924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    else
24024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    {
24124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        // We were able to map the requested data in one chunk
24224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        // where our mmap and actual data are the same.
24324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        m_mmap_size = length;
24424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        m_data = m_mmap_addr;
24524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        m_size = length;
24624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    }
247cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton
248cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton                    if (log)
249cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton                    {
250cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton                        log->Printf("DataBufferMemoryMap::MemoryMapFromFileSpec() m_mmap_addr = %p, m_mmap_size = %zu, error = %s",
251cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton                                    m_mmap_addr, m_mmap_size, error.AsCString());
252cbe61bd26db663fa3036866dc33315c6ffc37910Greg Clayton                    }
25324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
25424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
25524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
25624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
25724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return GetByteSize ();
25824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
259