1 //===- bolt/Rewrite/ExecutableFileMemoryManager.cpp -----------------------===// 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 #include "bolt/Rewrite/ExecutableFileMemoryManager.h" 10 #include "bolt/Rewrite/RewriteInstance.h" 11 12 #undef DEBUG_TYPE 13 #define DEBUG_TYPE "efmm" 14 15 using namespace llvm; 16 using namespace object; 17 using namespace bolt; 18 19 namespace llvm { 20 21 namespace bolt { 22 23 uint8_t *ExecutableFileMemoryManager::allocateSection(intptr_t Size, 24 unsigned Alignment, 25 unsigned SectionID, 26 StringRef SectionName, 27 bool IsCode, 28 bool IsReadOnly) { 29 // Register a debug section as a note section. 30 if (!ObjectsLoaded && RewriteInstance::isDebugSection(SectionName)) { 31 uint8_t *DataCopy = new uint8_t[Size]; 32 BinarySection &Section = 33 BC.registerOrUpdateNoteSection(SectionName, DataCopy, Size, Alignment); 34 Section.setSectionID(SectionID); 35 assert(!Section.isAllocatable() && "note sections cannot be allocatable"); 36 return DataCopy; 37 } 38 39 if (!IsCode && (SectionName == ".strtab" || SectionName == ".symtab" || 40 SectionName == "" || SectionName.startswith(".rela."))) { 41 return SectionMemoryManager::allocateDataSection(Size, Alignment, SectionID, 42 SectionName, IsReadOnly); 43 } 44 45 uint8_t *Ret; 46 if (IsCode) { 47 Ret = SectionMemoryManager::allocateCodeSection(Size, Alignment, SectionID, 48 SectionName); 49 } else { 50 Ret = SectionMemoryManager::allocateDataSection(Size, Alignment, SectionID, 51 SectionName, IsReadOnly); 52 } 53 54 SmallVector<char, 256> Buf; 55 if (ObjectsLoaded > 0) { 56 if (BC.isELF()) { 57 SectionName = (Twine(SectionName) + ".bolt.extra." + Twine(ObjectsLoaded)) 58 .toStringRef(Buf); 59 } else if (BC.isMachO()) { 60 assert((SectionName == "__text" || SectionName == "__data" || 61 SectionName == "__fini" || SectionName == "__setup" || 62 SectionName == "__cstring" || SectionName == "__literal16") && 63 "Unexpected section in the instrumentation library"); 64 // Sections coming from the instrumentation runtime are prefixed with "I". 65 SectionName = ("I" + Twine(SectionName)).toStringRef(Buf); 66 } 67 } 68 69 BinarySection &Section = BC.registerOrUpdateSection( 70 SectionName, ELF::SHT_PROGBITS, 71 BinarySection::getFlags(IsReadOnly, IsCode, true), Ret, Size, Alignment); 72 Section.setSectionID(SectionID); 73 assert(Section.isAllocatable() && 74 "verify that allocatable is marked as allocatable"); 75 76 LLVM_DEBUG( 77 dbgs() << "BOLT: allocating " 78 << (IsCode ? "code" : (IsReadOnly ? "read-only data" : "data")) 79 << " section : " << SectionName << " with size " << Size 80 << ", alignment " << Alignment << " at 0x" << Ret 81 << ", ID = " << SectionID << "\n"); 82 return Ret; 83 } 84 85 bool ExecutableFileMemoryManager::finalizeMemory(std::string *ErrMsg) { 86 LLVM_DEBUG(dbgs() << "BOLT: finalizeMemory()\n"); 87 ++ObjectsLoaded; 88 return SectionMemoryManager::finalizeMemory(ErrMsg); 89 } 90 91 ExecutableFileMemoryManager::~ExecutableFileMemoryManager() {} 92 93 } // namespace bolt 94 95 } // namespace llvm 96