forked from OSchip/llvm-project
Add .bolt_info notes section containing BOLT revision and command line args.
Summary: Optinally add a .bolt_info notes section containing BOLT revision and command line args. The new section is controlled by the -add-bolt-info flag which is on by default. (cherry picked from FBD5125890)
This commit is contained in:
parent
2ee4bbd3c1
commit
5cd58961a9
|
@ -1,6 +1,49 @@
|
||||||
add_subdirectory(merge-fdata)
|
add_subdirectory(merge-fdata)
|
||||||
add_subdirectory(Passes)
|
add_subdirectory(Passes)
|
||||||
|
|
||||||
|
# Get the current git revision for BOLT.
|
||||||
|
function(get_version ofn)
|
||||||
|
find_program(git_executable NAMES git git.exe git.cmd)
|
||||||
|
if (git_executable)
|
||||||
|
execute_process(COMMAND ${git_executable} rev-parse HEAD
|
||||||
|
WORKING_DIRECTORY ${LLVM_MAIN_SRC_DIR}
|
||||||
|
TIMEOUT 5
|
||||||
|
RESULT_VARIABLE git_result
|
||||||
|
OUTPUT_VARIABLE git_output)
|
||||||
|
if( git_result EQUAL 0 )
|
||||||
|
string(STRIP "${git_output}" git_ref_id)
|
||||||
|
set(BOLT_REVISION "${git_ref_id}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# If we can't find a revision, set it to "<unknown>".
|
||||||
|
if (NOT BOLT_REVISION)
|
||||||
|
set(BOLT_REVISION "<unknown>")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${ofn}
|
||||||
|
COMMAND echo '"${BOLT_REVISION}"' > ${CMAKE_CURRENT_BINARY_DIR}/${ofn}
|
||||||
|
COMMENT "Generating bogus ${ofn}..."
|
||||||
|
)
|
||||||
|
|
||||||
|
set(VERSION_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${ofn} PARENT_SCOPE)
|
||||||
|
|
||||||
|
# `make clean' must remove all those generated files:
|
||||||
|
set_property(DIRECTORY APPEND
|
||||||
|
PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${ofn})
|
||||||
|
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${ofn} PROPERTIES
|
||||||
|
GENERATED 1)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# Creates a public target for generating the revision file.
|
||||||
|
function(add_public_gen_version_target target)
|
||||||
|
add_custom_target(${target} DEPENDS ${VERSION_OUTPUT})
|
||||||
|
set(LLVM_COMMON_DEPENDS ${LLVM_COMMON_DEPENDS} ${target} PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
get_version(BoltRevision.inc)
|
||||||
|
add_public_gen_version_target(GenBoltRevision)
|
||||||
|
|
||||||
set(LLVM_LINK_COMPONENTS
|
set(LLVM_LINK_COMPONENTS
|
||||||
${LLVM_TARGETS_TO_BUILD}
|
${LLVM_TARGETS_TO_BUILD}
|
||||||
BOLTPasses
|
BOLTPasses
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
#include "llvm/Support/TargetSelect.h"
|
#include "llvm/Support/TargetSelect.h"
|
||||||
#include "llvm/Support/TargetRegistry.h"
|
#include "llvm/Support/TargetRegistry.h"
|
||||||
#include "llvm/Support/ToolOutputFile.h"
|
#include "llvm/Support/ToolOutputFile.h"
|
||||||
|
#include "llvm/Support/raw_ostream.h"
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
@ -311,6 +312,13 @@ Verbosity("v",
|
||||||
cl::ZeroOrMore,
|
cl::ZeroOrMore,
|
||||||
cl::cat(BoltCategory));
|
cl::cat(BoltCategory));
|
||||||
|
|
||||||
|
static cl::opt<bool>
|
||||||
|
AddBoltInfo("add-bolt-info",
|
||||||
|
cl::desc("add BOLT version and command line argument information to "
|
||||||
|
"processed binaries"),
|
||||||
|
cl::init(true),
|
||||||
|
cl::cat(BoltCategory));
|
||||||
|
|
||||||
// Check against lists of functions from options if we should
|
// Check against lists of functions from options if we should
|
||||||
// optimize the function with a given name.
|
// optimize the function with a given name.
|
||||||
bool shouldProcess(const BinaryFunction &Function) {
|
bool shouldProcess(const BinaryFunction &Function) {
|
||||||
|
@ -392,6 +400,12 @@ const std::string RewriteInstance::OrgSecPrefix = ".bolt.org";
|
||||||
|
|
||||||
const std::string RewriteInstance::BOLTSecPrefix = ".bolt";
|
const std::string RewriteInstance::BOLTSecPrefix = ".bolt";
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
namespace bolt {
|
||||||
|
extern const char *BoltRevision;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void report_error(StringRef Message, std::error_code EC) {
|
static void report_error(StringRef Message, std::error_code EC) {
|
||||||
assert(EC);
|
assert(EC);
|
||||||
errs() << "BOLT-ERROR: '" << Message << "': " << EC.message() << ".\n";
|
errs() << "BOLT-ERROR: '" << Message << "': " << EC.message() << ".\n";
|
||||||
|
@ -597,8 +611,12 @@ std::unique_ptr<BinaryContext> createBinaryContext(
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
RewriteInstance::RewriteInstance(ELFObjectFileBase *File,
|
RewriteInstance::RewriteInstance(ELFObjectFileBase *File,
|
||||||
const DataReader &DR)
|
const DataReader &DR,
|
||||||
|
const int Argc,
|
||||||
|
const char *const *Argv)
|
||||||
: InputFile(File),
|
: InputFile(File),
|
||||||
|
Argc(Argc),
|
||||||
|
Argv(Argv),
|
||||||
BC(createBinaryContext("x86-64", "x86_64-unknown-linux", DR,
|
BC(createBinaryContext("x86-64", "x86_64-unknown-linux", DR,
|
||||||
std::unique_ptr<DWARFContext>(
|
std::unique_ptr<DWARFContext>(
|
||||||
new DWARFContextInMemory(*InputFile, nullptr, true)))) {
|
new DWARFContextInMemory(*InputFile, nullptr, true)))) {
|
||||||
|
@ -796,6 +814,8 @@ void RewriteInstance::run() {
|
||||||
if (opts::UpdateDebugSections)
|
if (opts::UpdateDebugSections)
|
||||||
updateDebugInfo();
|
updateDebugInfo();
|
||||||
|
|
||||||
|
addBoltInfoSection();
|
||||||
|
|
||||||
// Copy allocatable part of the input.
|
// Copy allocatable part of the input.
|
||||||
std::error_code EC;
|
std::error_code EC;
|
||||||
Out = llvm::make_unique<tool_output_file>(opts::OutputFilename, EC,
|
Out = llvm::make_unique<tool_output_file>(opts::OutputFilename, EC,
|
||||||
|
@ -2765,6 +2785,30 @@ void RewriteInstance::finalizeSectionStringTable(ELFObjectFile<ELFT> *File) {
|
||||||
EFMM->NoteSectionInfo[".shstrtab"].IsStrTab = true;
|
EFMM->NoteSectionInfo[".shstrtab"].IsStrTab = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RewriteInstance::addBoltInfoSection() {
|
||||||
|
if (opts::AddBoltInfo) {
|
||||||
|
std::string Str;
|
||||||
|
raw_string_ostream OS(Str);
|
||||||
|
|
||||||
|
OS << "BOLT revision: " << BoltRevision << ", " << "command line:";
|
||||||
|
for (auto I = 0; I < Argc; ++I) {
|
||||||
|
OS << " " << Argv[I];
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto BoltInfo = OS.str();
|
||||||
|
const auto SectionSize = BoltInfo.size();
|
||||||
|
uint8_t *SectionData = new uint8_t[SectionSize];
|
||||||
|
memcpy(SectionData, BoltInfo.data(), SectionSize);
|
||||||
|
EFMM->NoteSectionInfo[".bolt_info"] =
|
||||||
|
SectionInfo(reinterpret_cast<uint64_t>(SectionData),
|
||||||
|
SectionSize,
|
||||||
|
/*Alignment=*/1,
|
||||||
|
/*IsCode=*/false,
|
||||||
|
/*IsReadOnly=*/true,
|
||||||
|
/*IsLocal=*/false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Rewrite section header table inserting new entries as needed. The sections
|
// Rewrite section header table inserting new entries as needed. The sections
|
||||||
// header table size itself may affect the offsets of other sections,
|
// header table size itself may affect the offsets of other sections,
|
||||||
// so we are placing it at the end of the binary.
|
// so we are placing it at the end of the binary.
|
||||||
|
|
|
@ -146,7 +146,8 @@ public:
|
||||||
/// events.
|
/// events.
|
||||||
class RewriteInstance {
|
class RewriteInstance {
|
||||||
public:
|
public:
|
||||||
RewriteInstance(llvm::object::ELFObjectFileBase *File, const DataReader &DR);
|
RewriteInstance(llvm::object::ELFObjectFileBase *File, const DataReader &DR,
|
||||||
|
const int Argc, const char *const *Argv);
|
||||||
~RewriteInstance();
|
~RewriteInstance();
|
||||||
|
|
||||||
/// Reset all state except for split hints. Used to run a second pass with
|
/// Reset all state except for split hints. Used to run a second pass with
|
||||||
|
@ -320,6 +321,9 @@ private:
|
||||||
/// Finalize memory image of section header string table.
|
/// Finalize memory image of section header string table.
|
||||||
ELF_FUNCTION(finalizeSectionStringTable);
|
ELF_FUNCTION(finalizeSectionStringTable);
|
||||||
|
|
||||||
|
/// Add a notes section containing the BOLT revision and command line options.
|
||||||
|
void addBoltInfoSection();
|
||||||
|
|
||||||
/// Computes output .debug_line line table offsets for each compile unit,
|
/// Computes output .debug_line line table offsets for each compile unit,
|
||||||
/// and updates stmt_list for a corresponding compile unit.
|
/// and updates stmt_list for a corresponding compile unit.
|
||||||
void updateLineTableOffsets();
|
void updateLineTableOffsets();
|
||||||
|
@ -388,6 +392,10 @@ private:
|
||||||
/// An instance of the input binary we are processing, externally owned.
|
/// An instance of the input binary we are processing, externally owned.
|
||||||
llvm::object::ELFObjectFileBase *InputFile;
|
llvm::object::ELFObjectFileBase *InputFile;
|
||||||
|
|
||||||
|
/// Command line args used to process binary.
|
||||||
|
const int Argc;
|
||||||
|
const char *const *Argv;
|
||||||
|
|
||||||
std::unique_ptr<BinaryContext> BC;
|
std::unique_ptr<BinaryContext> BC;
|
||||||
std::unique_ptr<CFIReaderWriter> CFIRdWrt;
|
std::unique_ptr<CFIReaderWriter> CFIRdWrt;
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,18 @@ static void report_error(StringRef Message, std::error_code EC) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
namespace bolt {
|
||||||
|
const char *BoltRevision =
|
||||||
|
#include "BoltRevision.inc"
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void printBoltRevision() {
|
||||||
|
errs() << "BOLT revision " << BoltRevision << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
// Print a stack trace if we signal out.
|
// Print a stack trace if we signal out.
|
||||||
sys::PrintStackTraceOnErrorSignal();
|
sys::PrintStackTraceOnErrorSignal();
|
||||||
|
@ -88,6 +100,7 @@ int main(int argc, char **argv) {
|
||||||
cl::HideUnrelatedOptions(makeArrayRef(opts::BoltCategories));
|
cl::HideUnrelatedOptions(makeArrayRef(opts::BoltCategories));
|
||||||
|
|
||||||
// Register the target printer for --version.
|
// Register the target printer for --version.
|
||||||
|
cl::AddExtraVersionPrinter(printBoltRevision);
|
||||||
cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
|
cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
|
||||||
|
|
||||||
cl::ParseCommandLineOptions(argc, argv,
|
cl::ParseCommandLineOptions(argc, argv,
|
||||||
|
@ -122,7 +135,7 @@ int main(int argc, char **argv) {
|
||||||
Binary &Binary = *BinaryOrErr.get().getBinary();
|
Binary &Binary = *BinaryOrErr.get().getBinary();
|
||||||
|
|
||||||
if (auto *e = dyn_cast<ELFObjectFileBase>(&Binary)) {
|
if (auto *e = dyn_cast<ELFObjectFileBase>(&Binary)) {
|
||||||
RewriteInstance RI(e, *DR.get());
|
RewriteInstance RI(e, *DR.get(), argc, argv);
|
||||||
RI.run();
|
RI.run();
|
||||||
} else {
|
} else {
|
||||||
report_error(opts::InputFilename, object_error::invalid_file_type);
|
report_error(opts::InputFilename, object_error::invalid_file_type);
|
||||||
|
|
Loading…
Reference in New Issue