12f09f445SMaksim Panchenko //===- bolt/Rewrite/ExecutableFileMemoryManager.cpp -----------------------===// 2a34c753fSRafael Auler // 3a34c753fSRafael Auler // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4a34c753fSRafael Auler // See https://llvm.org/LICENSE.txt for license information. 5a34c753fSRafael Auler // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6a34c753fSRafael Auler // 7a34c753fSRafael Auler //===----------------------------------------------------------------------===// 8a34c753fSRafael Auler 9a34c753fSRafael Auler #include "bolt/Rewrite/ExecutableFileMemoryManager.h" 10a34c753fSRafael Auler #include "bolt/Rewrite/RewriteInstance.h" 111d539352SMaksim Panchenko #include "llvm/Support/MemAlloc.h" 12a34c753fSRafael Auler 13a34c753fSRafael Auler #undef DEBUG_TYPE 14a34c753fSRafael Auler #define DEBUG_TYPE "efmm" 15a34c753fSRafael Auler 16a34c753fSRafael Auler using namespace llvm; 17a34c753fSRafael Auler using namespace object; 18a34c753fSRafael Auler using namespace bolt; 19a34c753fSRafael Auler 20a34c753fSRafael Auler namespace llvm { 21a34c753fSRafael Auler 22a34c753fSRafael Auler namespace bolt { 23a34c753fSRafael Auler 241d539352SMaksim Panchenko uint8_t *ExecutableFileMemoryManager::allocateSection( 251d539352SMaksim Panchenko uintptr_t Size, unsigned Alignment, unsigned SectionID, 261d539352SMaksim Panchenko StringRef SectionName, bool IsCode, bool IsReadOnly) { 271d539352SMaksim Panchenko uint8_t *Ret = static_cast<uint8_t *>(llvm::allocate_buffer(Size, Alignment)); 281d539352SMaksim Panchenko AllocatedSections.push_back(AllocInfo{Ret, Size, Alignment}); 291d539352SMaksim Panchenko 30*f3ea4228SJob Noorman // A Size of 1 might mean an empty section for which RuntimeDyld decided to 31*f3ea4228SJob Noorman // allocate 1 byte. In this case, the allocation will never be initialized 32*f3ea4228SJob Noorman // causing non-deterministic output section contents. 33*f3ea4228SJob Noorman if (Size == 1) 34*f3ea4228SJob Noorman *Ret = 0; 35*f3ea4228SJob Noorman 36a34c753fSRafael Auler // Register a debug section as a note section. 37a34c753fSRafael Auler if (!ObjectsLoaded && RewriteInstance::isDebugSection(SectionName)) { 38a34c753fSRafael Auler BinarySection &Section = 391d539352SMaksim Panchenko BC.registerOrUpdateNoteSection(SectionName, Ret, Size, Alignment); 40a34c753fSRafael Auler Section.setSectionID(SectionID); 41a34c753fSRafael Auler assert(!Section.isAllocatable() && "note sections cannot be allocatable"); 421d539352SMaksim Panchenko return Ret; 43a34c753fSRafael Auler } 44a34c753fSRafael Auler 4540c2e0faSMaksim Panchenko if (!IsCode && (SectionName == ".strtab" || SectionName == ".symtab" || 46ee0e9ccbSMaksim Panchenko SectionName == "" || SectionName.startswith(".rela."))) 471d539352SMaksim Panchenko return Ret; 48a34c753fSRafael Auler 49a34c753fSRafael Auler SmallVector<char, 256> Buf; 50a34c753fSRafael Auler if (ObjectsLoaded > 0) { 51a34c753fSRafael Auler if (BC.isELF()) { 52a34c753fSRafael Auler SectionName = (Twine(SectionName) + ".bolt.extra." + Twine(ObjectsLoaded)) 53a34c753fSRafael Auler .toStringRef(Buf); 54a34c753fSRafael Auler } else if (BC.isMachO()) { 55a34c753fSRafael Auler assert((SectionName == "__text" || SectionName == "__data" || 56a34c753fSRafael Auler SectionName == "__fini" || SectionName == "__setup" || 57a34c753fSRafael Auler SectionName == "__cstring" || SectionName == "__literal16") && 58a34c753fSRafael Auler "Unexpected section in the instrumentation library"); 59a34c753fSRafael Auler // Sections coming from the instrumentation runtime are prefixed with "I". 60a34c753fSRafael Auler SectionName = ("I" + Twine(SectionName)).toStringRef(Buf); 61a34c753fSRafael Auler } 62a34c753fSRafael Auler } 63a34c753fSRafael Auler 644d3a0cadSMaksim Panchenko BinarySection *Section = nullptr; 654d3a0cadSMaksim Panchenko if (!OrgSecPrefix.empty() && SectionName.startswith(OrgSecPrefix)) { 664d3a0cadSMaksim Panchenko // Update the original section contents. 674d3a0cadSMaksim Panchenko ErrorOr<BinarySection &> OrgSection = 684d3a0cadSMaksim Panchenko BC.getUniqueSectionByName(SectionName.substr(OrgSecPrefix.length())); 694d3a0cadSMaksim Panchenko assert(OrgSection && OrgSection->isAllocatable() && 704d3a0cadSMaksim Panchenko "Original section must exist and be allocatable."); 71a34c753fSRafael Auler 724d3a0cadSMaksim Panchenko Section = &OrgSection.get(); 734d3a0cadSMaksim Panchenko Section->updateContents(Ret, Size); 744d3a0cadSMaksim Panchenko } else { 754d3a0cadSMaksim Panchenko // If the input contains a section with the section name, rename it in the 764d3a0cadSMaksim Panchenko // output file to avoid the section name conflict and emit the new section 774d3a0cadSMaksim Panchenko // under a unique internal name. 784d3a0cadSMaksim Panchenko ErrorOr<BinarySection &> OrgSection = 794d3a0cadSMaksim Panchenko BC.getUniqueSectionByName(SectionName); 804d3a0cadSMaksim Panchenko bool UsePrefix = false; 814d3a0cadSMaksim Panchenko if (OrgSection && OrgSection->hasSectionRef()) { 824d3a0cadSMaksim Panchenko OrgSection->setOutputName(OrgSecPrefix + SectionName); 834d3a0cadSMaksim Panchenko UsePrefix = true; 844d3a0cadSMaksim Panchenko } 854d3a0cadSMaksim Panchenko 864d3a0cadSMaksim Panchenko // Register the new section under a unique name to avoid name collision with 874d3a0cadSMaksim Panchenko // sections in the input file. 884d3a0cadSMaksim Panchenko BinarySection &NewSection = BC.registerOrUpdateSection( 894d3a0cadSMaksim Panchenko UsePrefix ? NewSecPrefix + SectionName : SectionName, ELF::SHT_PROGBITS, 904d3a0cadSMaksim Panchenko BinarySection::getFlags(IsReadOnly, IsCode, true), Ret, Size, 914d3a0cadSMaksim Panchenko Alignment); 924d3a0cadSMaksim Panchenko if (UsePrefix) 934d3a0cadSMaksim Panchenko NewSection.setOutputName(SectionName); 944d3a0cadSMaksim Panchenko Section = &NewSection; 954d3a0cadSMaksim Panchenko } 964d3a0cadSMaksim Panchenko 974d3a0cadSMaksim Panchenko LLVM_DEBUG({ 98a34c753fSRafael Auler dbgs() << "BOLT: allocating " 99a34c753fSRafael Auler << (IsCode ? "code" : (IsReadOnly ? "read-only data" : "data")) 1004d3a0cadSMaksim Panchenko << " section : " << Section->getOutputName() << " (" 1014d3a0cadSMaksim Panchenko << Section->getName() << ")" 1024d3a0cadSMaksim Panchenko << " with size " << Size << ", alignment " << Alignment << " at " 1034d3a0cadSMaksim Panchenko << Ret << ", ID = " << SectionID << "\n"; 1044d3a0cadSMaksim Panchenko }); 1054d3a0cadSMaksim Panchenko 1064d3a0cadSMaksim Panchenko Section->setSectionID(SectionID); 1074d3a0cadSMaksim Panchenko 108a34c753fSRafael Auler return Ret; 109a34c753fSRafael Auler } 110a34c753fSRafael Auler 1111d539352SMaksim Panchenko ExecutableFileMemoryManager::~ExecutableFileMemoryManager() { 1121d539352SMaksim Panchenko for (const AllocInfo &AI : AllocatedSections) 1131d539352SMaksim Panchenko llvm::deallocate_buffer(AI.Address, AI.Size, AI.Alignment); 114a34c753fSRafael Auler } 115a34c753fSRafael Auler 11640c2e0faSMaksim Panchenko } // namespace bolt 117a34c753fSRafael Auler 11840c2e0faSMaksim Panchenko } // namespace llvm 119