Skip to content

Commit c9b1f06

Browse files
committed
[BOLT] Introduce MetadataRewriter interface
Introduce the MetadataRewriter interface to handle updates for various types of auxiliary data stored in a binary file. To implement metadata processing using this new interface, all metadata rewriters should derive from the RewriterBase class and implement one or more of the following methods, depending on the timing of metadata read and write operations: * preCFGInitializer() * postCFGInitializer() // TBD * preEmitFinalizer() // TBD * postEmitFinalizer() By adopting this approach, we aim to simplify the RewriteInstance class and improve its scalability to accommodate new extensions of file formats, including various metadata types of the Linux Kernel. Differential Revision: https://reviews.llvm.org/D154020
1 parent c1e2838 commit c9b1f06

File tree

7 files changed

+201
-1
lines changed

7 files changed

+201
-1
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//===- bolt/Rewrite/MetadataManager.h ---------------------------*- C++ -*-===//
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+
#ifndef BOLT_REWRITE_METADATA_MANAGER_H
10+
#define BOLT_REWRITE_METADATA_MANAGER_H
11+
12+
#include "bolt/Rewrite/MetadataRewriter.h"
13+
#include "llvm/ADT/SmallVector.h"
14+
#include "llvm/Support/Error.h"
15+
16+
namespace llvm {
17+
namespace bolt {
18+
19+
class BinaryContext;
20+
21+
/// This class manages a collection of metadata handlers/rewriters.
22+
/// It is responsible for registering new rewriters and invoking them at
23+
/// certain stages of the binary processing pipeline.
24+
class MetadataManager {
25+
using RewritersListType = SmallVector<std::unique_ptr<MetadataRewriter>, 1>;
26+
RewritersListType Rewriters;
27+
28+
public:
29+
/// Register a new \p Rewriter.
30+
void registerRewriter(std::unique_ptr<MetadataRewriter> Rewriter);
31+
32+
/// Execute initialization of rewriters while functions are disassembled, but
33+
/// CFG is not yet built.
34+
void runInitializersPreCFG();
35+
36+
/// Run finalization step of rewriters after code has been emitted.
37+
void runFinalizersAfterEmit();
38+
};
39+
40+
} // namespace bolt
41+
} // namespace llvm
42+
43+
#endif // BOLT_REWRITE_METADATA_MANAGER_H
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
//===- bolt/Rewrite/MetadataRewriter.h --------------------------*- C++ -*-===//
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+
// Interface for reading and updating metadata in a file.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef BOLT_REWRITE_METADATA_REWRITER_H
14+
#define BOLT_REWRITE_METADATA_REWRITER_H
15+
16+
#include "bolt/Core/BinaryContext.h"
17+
#include "llvm/Support/Error.h"
18+
19+
namespace llvm {
20+
namespace bolt {
21+
22+
/// Base class for handling file sections with metadata. In this context,
23+
/// metadata encompasses a wide range of data that references code and other
24+
/// data. Such metadata may or may not have an impact on program execution.
25+
/// Examples include: debug information, unwind information, exception handling
26+
/// tables, etc.
27+
//
28+
/// The metadata can occupy a section (e.g. .note.stapsdt), span a number of
29+
/// sections (e.g., DWARF debug info), or exist as subsection of another
30+
/// section in the binary (e.g., static-key jump tables embedded in .rodata
31+
/// section in the Linux Kernel).
32+
class MetadataRewriter {
33+
/// The name of the data type handled by an instance of this class.
34+
StringRef Name;
35+
36+
protected:
37+
/// Provides access to the binary context.
38+
BinaryContext &BC;
39+
40+
MetadataRewriter(StringRef Name, BinaryContext &BC) : Name(Name), BC(BC) {}
41+
42+
public:
43+
virtual ~MetadataRewriter() = default;
44+
45+
/// Return name for the rewriter.
46+
StringRef getName() const { return Name; }
47+
48+
/// Interface for modifying/annotating functions in the binary based on the
49+
/// contents of the section. Functions are in pre-cfg state.
50+
virtual Error preCFGInitializer() { return Error::success(); }
51+
52+
/// Finalize section contents based on the new context after the new code is
53+
/// emitted.
54+
virtual Error postEmitFinalizer() { return Error::success(); }
55+
};
56+
57+
} // namespace bolt
58+
} // namespace llvm
59+
60+
#endif // BOLT_REWRITE_METADATA_REWRITER_H
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//===- bolt/Rewrite/MetadataRewriters.h -------------------------*- C++ -*-===//
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+
#ifndef BOLT_REWRITE_METADATA_REWRITERS_H
10+
#define BOLT_REWRITE_METADATA_REWRITERS_H
11+
12+
#include <memory>
13+
14+
namespace llvm {
15+
namespace bolt {
16+
17+
class MetadataRewriter;
18+
19+
/// The list of rewriter build functions (e.g. createNewMetadataRewriter()) that
20+
/// return std::unique_ptr<MetadataRewriter>.
21+
22+
} // namespace bolt
23+
} // namespace llvm
24+
25+
#endif // BOLT_REWRITE_METADATA_REWRITERS_H

bolt/include/bolt/Rewrite/RewriteInstance.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "bolt/Core/BinaryContext.h"
1717
#include "bolt/Core/Linker.h"
18+
#include "bolt/Rewrite/MetadataManager.h"
1819
#include "bolt/Utils/NameResolver.h"
1920
#include "llvm/ADT/ArrayRef.h"
2021
#include "llvm/MC/StringTableBuilder.h"
@@ -94,6 +95,9 @@ class RewriteInstance {
9495
/// from meta data in the file.
9596
void discoverFileObjects();
9697

98+
/// Create and initialize metadata rewriters for this instance.
99+
void initializeMetadataManager();
100+
97101
/// Process fragments, locate parent functions.
98102
void registerFragments();
99103

@@ -188,6 +192,9 @@ class RewriteInstance {
188192
/// Link additional runtime code to support instrumentation.
189193
void linkRuntime();
190194

195+
/// Process metadata in special sections before CFG is built for functions.
196+
void processMetadataPreCFG();
197+
191198
/// Update debug and other auxiliary information in the file.
192199
void updateMetadata();
193200

@@ -424,6 +431,9 @@ class RewriteInstance {
424431
}
425432

426433
private:
434+
/// Manage a pipeline of metadata handlers.
435+
MetadataManager MetadataManager;
436+
427437
/// Get the contents of the LSDA section for this binary.
428438
ArrayRef<uint8_t> getLSDAData();
429439

bolt/lib/Rewrite/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ add_llvm_library(LLVMBOLTRewrite
1515
ExecutableFileMemoryManager.cpp
1616
JITLinkLinker.cpp
1717
MachORewriteInstance.cpp
18+
MetadataManager.cpp
1819
RewriteInstance.cpp
1920

2021
DISABLE_LLVM_LINK_LLVM_DYLIB

bolt/lib/Rewrite/MetadataManager.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//===- bolt/Rewrite/MetadataManager.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/MetadataManager.h"
10+
#include "llvm/Support/Debug.h"
11+
12+
#undef DEBUG_TYPE
13+
#define DEBUG_TYPE "bolt-metadata"
14+
15+
using namespace llvm;
16+
using namespace bolt;
17+
18+
void MetadataManager::registerRewriter(
19+
std::unique_ptr<MetadataRewriter> Rewriter) {
20+
Rewriters.emplace_back(std::move(Rewriter));
21+
}
22+
23+
void MetadataManager::runInitializersPreCFG() {
24+
for (auto &Rewriter : Rewriters) {
25+
LLVM_DEBUG(dbgs() << "BOLT-DEBUG: invoking " << Rewriter->getName()
26+
<< " before CFG construction\n");
27+
if (Error E = Rewriter->preCFGInitializer()) {
28+
errs() << "BOLT-ERROR: while running " << Rewriter->getName()
29+
<< " in pre-CFG state: " << toString(std::move(E)) << '\n';
30+
exit(1);
31+
}
32+
}
33+
}
34+
35+
void MetadataManager::runFinalizersAfterEmit() {
36+
for (auto &Rewriter : Rewriters) {
37+
LLVM_DEBUG(dbgs() << "BOLT-DEBUG: invoking " << Rewriter->getName()
38+
<< " after emit\n");
39+
if (Error E = Rewriter->postEmitFinalizer()) {
40+
errs() << "BOLT-ERROR: while running " << Rewriter->getName()
41+
<< " after emit: " << toString(std::move(E)) << '\n';
42+
exit(1);
43+
}
44+
}
45+
}

bolt/lib/Rewrite/RewriteInstance.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "bolt/Rewrite/DWARFRewriter.h"
2828
#include "bolt/Rewrite/ExecutableFileMemoryManager.h"
2929
#include "bolt/Rewrite/JITLinkLinker.h"
30+
#include "bolt/Rewrite/MetadataRewriters.h"
3031
#include "bolt/RuntimeLibs/HugifyRuntimeLibrary.h"
3132
#include "bolt/RuntimeLibs/InstrumentationRuntimeLibrary.h"
3233
#include "bolt/Utils/CommandLineOpts.h"
@@ -844,7 +845,7 @@ Error RewriteInstance::run() {
844845

845846
disassembleFunctions();
846847

847-
processProfileDataPreCFG();
848+
processMetadataPreCFG();
848849

849850
buildFunctionsCFG();
850851

@@ -3243,6 +3244,18 @@ void RewriteInstance::preprocessProfileData() {
32433244
}
32443245
}
32453246

3247+
void RewriteInstance::initializeMetadataManager() {
3248+
// TODO
3249+
}
3250+
3251+
void RewriteInstance::processMetadataPreCFG() {
3252+
initializeMetadataManager();
3253+
3254+
MetadataManager.runInitializersPreCFG();
3255+
3256+
processProfileDataPreCFG();
3257+
}
3258+
32463259
void RewriteInstance::processProfileDataPreCFG() {
32473260
if (!ProfileReader)
32483261
return;
@@ -3605,6 +3618,9 @@ void RewriteInstance::emitAndLink() {
36053618
}
36063619

36073620
void RewriteInstance::updateMetadata() {
3621+
MetadataManager.runFinalizersAfterEmit();
3622+
3623+
// TODO: use MetadataManager for updates.
36083624
updateSDTMarkers();
36093625
updateLKMarkers();
36103626
parsePseudoProbe();

0 commit comments

Comments
 (0)