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