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