113 lines
4.1 KiB
C++
113 lines
4.1 KiB
C++
//===- bolt/Rewrite/ExecutableFileMemoryManager.cpp -----------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "bolt/Rewrite/ExecutableFileMemoryManager.h"
|
|
#include "bolt/Rewrite/RewriteInstance.h"
|
|
#include "llvm/Support/MemAlloc.h"
|
|
|
|
#undef DEBUG_TYPE
|
|
#define DEBUG_TYPE "efmm"
|
|
|
|
using namespace llvm;
|
|
using namespace object;
|
|
using namespace bolt;
|
|
|
|
namespace llvm {
|
|
|
|
namespace bolt {
|
|
|
|
uint8_t *ExecutableFileMemoryManager::allocateSection(
|
|
uintptr_t Size, unsigned Alignment, unsigned SectionID,
|
|
StringRef SectionName, bool IsCode, bool IsReadOnly) {
|
|
uint8_t *Ret = static_cast<uint8_t *>(llvm::allocate_buffer(Size, Alignment));
|
|
AllocatedSections.push_back(AllocInfo{Ret, Size, Alignment});
|
|
|
|
// Register a debug section as a note section.
|
|
if (!ObjectsLoaded && RewriteInstance::isDebugSection(SectionName)) {
|
|
BinarySection &Section =
|
|
BC.registerOrUpdateNoteSection(SectionName, Ret, Size, Alignment);
|
|
Section.setSectionID(SectionID);
|
|
assert(!Section.isAllocatable() && "note sections cannot be allocatable");
|
|
return Ret;
|
|
}
|
|
|
|
if (!IsCode && (SectionName == ".strtab" || SectionName == ".symtab" ||
|
|
SectionName == "" || SectionName.startswith(".rela.")))
|
|
return Ret;
|
|
|
|
SmallVector<char, 256> Buf;
|
|
if (ObjectsLoaded > 0) {
|
|
if (BC.isELF()) {
|
|
SectionName = (Twine(SectionName) + ".bolt.extra." + Twine(ObjectsLoaded))
|
|
.toStringRef(Buf);
|
|
} else if (BC.isMachO()) {
|
|
assert((SectionName == "__text" || SectionName == "__data" ||
|
|
SectionName == "__fini" || SectionName == "__setup" ||
|
|
SectionName == "__cstring" || SectionName == "__literal16") &&
|
|
"Unexpected section in the instrumentation library");
|
|
// Sections coming from the instrumentation runtime are prefixed with "I".
|
|
SectionName = ("I" + Twine(SectionName)).toStringRef(Buf);
|
|
}
|
|
}
|
|
|
|
BinarySection *Section = nullptr;
|
|
if (!OrgSecPrefix.empty() && SectionName.startswith(OrgSecPrefix)) {
|
|
// Update the original section contents.
|
|
ErrorOr<BinarySection &> OrgSection =
|
|
BC.getUniqueSectionByName(SectionName.substr(OrgSecPrefix.length()));
|
|
assert(OrgSection && OrgSection->isAllocatable() &&
|
|
"Original section must exist and be allocatable.");
|
|
|
|
Section = &OrgSection.get();
|
|
Section->updateContents(Ret, Size);
|
|
} else {
|
|
// If the input contains a section with the section name, rename it in the
|
|
// output file to avoid the section name conflict and emit the new section
|
|
// under a unique internal name.
|
|
ErrorOr<BinarySection &> OrgSection =
|
|
BC.getUniqueSectionByName(SectionName);
|
|
bool UsePrefix = false;
|
|
if (OrgSection && OrgSection->hasSectionRef()) {
|
|
OrgSection->setOutputName(OrgSecPrefix + SectionName);
|
|
UsePrefix = true;
|
|
}
|
|
|
|
// Register the new section under a unique name to avoid name collision with
|
|
// sections in the input file.
|
|
BinarySection &NewSection = BC.registerOrUpdateSection(
|
|
UsePrefix ? NewSecPrefix + SectionName : SectionName, ELF::SHT_PROGBITS,
|
|
BinarySection::getFlags(IsReadOnly, IsCode, true), Ret, Size,
|
|
Alignment);
|
|
if (UsePrefix)
|
|
NewSection.setOutputName(SectionName);
|
|
Section = &NewSection;
|
|
}
|
|
|
|
LLVM_DEBUG({
|
|
dbgs() << "BOLT: allocating "
|
|
<< (IsCode ? "code" : (IsReadOnly ? "read-only data" : "data"))
|
|
<< " section : " << Section->getOutputName() << " ("
|
|
<< Section->getName() << ")"
|
|
<< " with size " << Size << ", alignment " << Alignment << " at "
|
|
<< Ret << ", ID = " << SectionID << "\n";
|
|
});
|
|
|
|
Section->setSectionID(SectionID);
|
|
|
|
return Ret;
|
|
}
|
|
|
|
ExecutableFileMemoryManager::~ExecutableFileMemoryManager() {
|
|
for (const AllocInfo &AI : AllocatedSections)
|
|
llvm::deallocate_buffer(AI.Address, AI.Size, AI.Alignment);
|
|
}
|
|
|
|
} // namespace bolt
|
|
|
|
} // namespace llvm
|