blob: 35efaa6fcb973fc1162be897dc8869330f718f5e [file] [log] [blame]
Chris Lattnerb342b7c2008-04-01 03:10:22 +00001//===- Unix/MappedFile.inc - Unix MappedFile Implementation -----*- C++ -*-===//
Dan Gohmanf17a25c2007-07-18 16:29:46 +00002//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner081ce942007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Dan Gohmanf17a25c2007-07-18 16:29:46 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file provides the generic Unix implementation of the MappedFile concept.
11//
12//===----------------------------------------------------------------------===//
13
Dan Gohmanf17a25c2007-07-18 16:29:46 +000014#include "Unix.h"
15#include "llvm/System/Process.h"
16
17#ifdef HAVE_FCNTL_H
18#include <fcntl.h>
19#endif
20
21#ifdef HAVE_SYS_MMAN_H
22#include <sys/mman.h>
23#endif
24
25#ifdef HAVE_SYS_STAT_H
26#include <sys/stat.h>
27#endif
28
Chris Lattnerb8a0afe2008-04-01 00:53:25 +000029using namespace llvm;
Dan Gohmanf17a25c2007-07-18 16:29:46 +000030using namespace sys;
31
Chris Lattnerb8a0afe2008-04-01 00:53:25 +000032namespace llvm {
33 namespace sys {
34 struct MappedFileInfo {
35 int FD;
36 off_t Size;
37 };
38 }
39}
Dan Gohmanf17a25c2007-07-18 16:29:46 +000040
41bool MappedFile::initialize(std::string* ErrMsg) {
Chris Lattnerb342b7c2008-04-01 03:10:22 +000042 int FD = ::open(Path.c_str(), O_RDONLY);
Dan Gohmanf17a25c2007-07-18 16:29:46 +000043 if (FD < 0) {
Chris Lattnerb8a0afe2008-04-01 00:53:25 +000044 MakeErrMsg(ErrMsg, "can't open file '" + Path.toString() + "'");
Dan Gohmanf17a25c2007-07-18 16:29:46 +000045 return true;
46 }
Chris Lattnerb8a0afe2008-04-01 00:53:25 +000047 const FileStatus *Status = Path.getFileStatus(false, ErrMsg);
Dan Gohmanf17a25c2007-07-18 16:29:46 +000048 if (!Status) {
49 ::close(FD);
50 return true;
51 }
Chris Lattnerb8a0afe2008-04-01 00:53:25 +000052 MapInfo = new MappedFileInfo();
53 MapInfo->FD = FD;
54 MapInfo->Size = Status->getSize();
Dan Gohmanf17a25c2007-07-18 16:29:46 +000055 return false;
56}
57
58void MappedFile::terminate() {
Chris Lattner8ffa1ff2008-04-01 03:49:38 +000059 unmap();
Chris Lattnerb8a0afe2008-04-01 00:53:25 +000060 assert(MapInfo && "MappedFile not initialized");
61 ::close(MapInfo->FD);
62 delete MapInfo;
63 MapInfo = 0;
Dan Gohmanf17a25c2007-07-18 16:29:46 +000064}
65
66void MappedFile::unmap() {
Chris Lattnerb8a0afe2008-04-01 00:53:25 +000067 assert(MapInfo && "MappedFile not initialized");
68 if (!isMapped()) return;
69
Chris Lattnerb8a0afe2008-04-01 00:53:25 +000070 ::munmap(BasePtr, MapInfo->Size);
71 BasePtr = 0; // Mark this as non-mapped.
Dan Gohmanf17a25c2007-07-18 16:29:46 +000072}
73
Chris Lattner8ffa1ff2008-04-01 03:49:38 +000074const void* MappedFile::map(std::string* ErrMsg) {
Chris Lattnerb8a0afe2008-04-01 00:53:25 +000075 assert(MapInfo && "MappedFile not initialized");
76 if (isMapped()) return BasePtr;
77
Chris Lattnerb342b7c2008-04-01 03:10:22 +000078 int prot = PROT_READ;
79 int flags = MAP_PRIVATE;
Dan Gohmanf17a25c2007-07-18 16:29:46 +000080#ifdef MAP_FILE
Chris Lattnerb8a0afe2008-04-01 00:53:25 +000081 flags |= MAP_FILE;
Dan Gohmanf17a25c2007-07-18 16:29:46 +000082#endif
Chris Lattnerb342b7c2008-04-01 03:10:22 +000083 size_t PageSize = Process::GetPageSize();
84 size_t map_size = ((MapInfo->Size / PageSize)+1) * PageSize;
Chris Lattnerb8a0afe2008-04-01 00:53:25 +000085
86 BasePtr = ::mmap(0, map_size, prot, flags, MapInfo->FD, 0);
87 if (BasePtr == MAP_FAILED) {
88 MakeErrMsg(ErrMsg, "Can't map file:" + Path.toString());
89 return 0;
90 }
91 return BasePtr;
Dan Gohmanf17a25c2007-07-18 16:29:46 +000092}
93
94size_t MappedFile::size() const {
Chris Lattnerb8a0afe2008-04-01 00:53:25 +000095 assert(MapInfo && "MappedFile not initialized");
96 return MapInfo->Size;
Dan Gohmanf17a25c2007-07-18 16:29:46 +000097}
98