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(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
|
||||
${LLVM_TARGETS_TO_BUILD}
|
||||
BOLTPasses
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "llvm/Support/TargetSelect.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
#include "llvm/Support/ToolOutputFile.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
|
@ -311,6 +312,13 @@ Verbosity("v",
|
|||
cl::ZeroOrMore,
|
||||
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
|
||||
// optimize the function with a given name.
|
||||
bool shouldProcess(const BinaryFunction &Function) {
|
||||
|
@ -392,6 +400,12 @@ const std::string RewriteInstance::OrgSecPrefix = ".bolt.org";
|
|||
|
||||
const std::string RewriteInstance::BOLTSecPrefix = ".bolt";
|
||||
|
||||
namespace llvm {
|
||||
namespace bolt {
|
||||
extern const char *BoltRevision;
|
||||
}
|
||||
}
|
||||
|
||||
static void report_error(StringRef Message, std::error_code EC) {
|
||||
assert(EC);
|
||||
errs() << "BOLT-ERROR: '" << Message << "': " << EC.message() << ".\n";
|
||||
|
@ -597,8 +611,12 @@ std::unique_ptr<BinaryContext> createBinaryContext(
|
|||
} // namespace
|
||||
|
||||
RewriteInstance::RewriteInstance(ELFObjectFileBase *File,
|
||||
const DataReader &DR)
|
||||
const DataReader &DR,
|
||||
const int Argc,
|
||||
const char *const *Argv)
|
||||
: InputFile(File),
|
||||
Argc(Argc),
|
||||
Argv(Argv),
|
||||
BC(createBinaryContext("x86-64", "x86_64-unknown-linux", DR,
|
||||
std::unique_ptr<DWARFContext>(
|
||||
new DWARFContextInMemory(*InputFile, nullptr, true)))) {
|
||||
|
@ -796,6 +814,8 @@ void RewriteInstance::run() {
|
|||
if (opts::UpdateDebugSections)
|
||||
updateDebugInfo();
|
||||
|
||||
addBoltInfoSection();
|
||||
|
||||
// Copy allocatable part of the input.
|
||||
std::error_code 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;
|
||||
}
|
||||
|
||||
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
|
||||
// header table size itself may affect the offsets of other sections,
|
||||
// so we are placing it at the end of the binary.
|
||||
|
|
|
@ -146,7 +146,8 @@ public:
|
|||
/// events.
|
||||
class RewriteInstance {
|
||||
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();
|
||||
|
||||
/// 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.
|
||||
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,
|
||||
/// and updates stmt_list for a corresponding compile unit.
|
||||
void updateLineTableOffsets();
|
||||
|
@ -388,6 +392,10 @@ private:
|
|||
/// An instance of the input binary we are processing, externally owned.
|
||||
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<CFIReaderWriter> CFIRdWrt;
|
||||
|
||||
|
|
|
@ -69,6 +69,18 @@ static void report_error(StringRef Message, std::error_code EC) {
|
|||
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) {
|
||||
// Print a stack trace if we signal out.
|
||||
sys::PrintStackTraceOnErrorSignal();
|
||||
|
@ -88,6 +100,7 @@ int main(int argc, char **argv) {
|
|||
cl::HideUnrelatedOptions(makeArrayRef(opts::BoltCategories));
|
||||
|
||||
// Register the target printer for --version.
|
||||
cl::AddExtraVersionPrinter(printBoltRevision);
|
||||
cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
|
||||
|
||||
cl::ParseCommandLineOptions(argc, argv,
|
||||
|
@ -122,7 +135,7 @@ int main(int argc, char **argv) {
|
|||
Binary &Binary = *BinaryOrErr.get().getBinary();
|
||||
|
||||
if (auto *e = dyn_cast<ELFObjectFileBase>(&Binary)) {
|
||||
RewriteInstance RI(e, *DR.get());
|
||||
RewriteInstance RI(e, *DR.get(), argc, argv);
|
||||
RI.run();
|
||||
} else {
|
||||
report_error(opts::InputFilename, object_error::invalid_file_type);
|
||||
|
|
Loading…
Reference in New Issue