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