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