1 //===- bolt/Rewrite/ExecutableFileMemoryManager.h ---------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef BOLT_REWRITE_EXECUTABLE_FILE_MEMORY_MANAGER_H
10 #define BOLT_REWRITE_EXECUTABLE_FILE_MEMORY_MANAGER_H
11 
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
14 #include <cstdint>
15 #include <string>
16 
17 namespace llvm {
18 
19 namespace bolt {
20 class BinaryContext;
21 
22 /// Class responsible for allocating and managing code and data sections.
23 class ExecutableFileMemoryManager : public SectionMemoryManager {
24 private:
25   uint8_t *allocateSection(intptr_t Size, unsigned Alignment,
26                            unsigned SectionID, StringRef SectionName,
27                            bool IsCode, bool IsReadOnly);
28   BinaryContext &BC;
29   bool AllowStubs;
30 
31 public:
32   // Our linker's main purpose is to handle a single object file, created
33   // by RewriteInstance after reading the input binary and reordering it.
34   // After objects finish loading, we increment this. Therefore, whenever
35   // this is greater than zero, we are dealing with additional objects that
36   // will not be managed by BinaryContext but only exist to support linking
37   // user-supplied objects into the main input executable.
38   uint32_t ObjectsLoaded{0};
39 
ExecutableFileMemoryManager(BinaryContext & BC,bool AllowStubs)40   ExecutableFileMemoryManager(BinaryContext &BC, bool AllowStubs)
41       : BC(BC), AllowStubs(AllowStubs) {}
42 
43   ~ExecutableFileMemoryManager();
44 
allocateCodeSection(uintptr_t Size,unsigned Alignment,unsigned SectionID,StringRef SectionName)45   uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
46                                unsigned SectionID,
47                                StringRef SectionName) override {
48     return allocateSection(Size, Alignment, SectionID, SectionName,
49                            /*IsCode=*/true, true);
50   }
51 
allocateDataSection(uintptr_t Size,unsigned Alignment,unsigned SectionID,StringRef SectionName,bool IsReadOnly)52   uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
53                                unsigned SectionID, StringRef SectionName,
54                                bool IsReadOnly) override {
55     return allocateSection(Size, Alignment, SectionID, SectionName,
56                            /*IsCode=*/false, IsReadOnly);
57   }
58 
59   // Ignore TLS sections by treating them as a regular data section
allocateTLSSection(uintptr_t Size,unsigned Alignment,unsigned SectionID,StringRef SectionName)60   TLSSection allocateTLSSection(uintptr_t Size, unsigned Alignment,
61                                 unsigned SectionID,
62                                 StringRef SectionName) override {
63     TLSSection Res;
64     Res.Offset = 0;
65     Res.InitializationImage = allocateDataSection(
66         Size, Alignment, SectionID, SectionName, /*IsReadOnly=*/false);
67     return Res;
68   }
69 
allowStubAllocation()70   bool allowStubAllocation() const override { return AllowStubs; }
71 
72   bool finalizeMemory(std::string *ErrMsg = nullptr) override;
73 };
74 
75 } // namespace bolt
76 } // namespace llvm
77 
78 #endif
79