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