Skip to content

Commit

Permalink
Create a metadata file named as the artifact id of the output file
Browse files Browse the repository at this point in the history
Signed-off-by: Bharathi Seshadri <bharathi.seshadri@gmail.com>
  • Loading branch information
bharsesh committed Sep 1, 2023
1 parent 3528e7c commit 3be68a5
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 8 deletions.
4 changes: 4 additions & 0 deletions llvm-project/clang/include/clang/Basic/CodeGenOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,10 @@ class CodeGenOptions : public CodeGenOptionsBase {
/// The string containing the gitoid of the omnibor file.
std::string RecordOmniBor;

/// The string containing the commandline for the Omnibor metadata,
/// if non-empty.
std::string OmniborCommandLine;

/// List of dependent source/header files.
/// This is shared with DependencyOuputOptions.
/// This has same contents as Dependencies in DependencyCollector.
Expand Down
3 changes: 3 additions & 0 deletions llvm-project/clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -4991,6 +4991,9 @@ def record_command_line : Separate<["-"], "record-command-line">,
def record_omnibor: Separate<["-"], "record-omnibor">,
HelpText<"The string to embed in the .note.omnibor section.">,
MarshallingInfoString<CodeGenOpts<"RecordOmniBor">>;
def omnibor_command_line : Separate<["-"], "omnibor-command-line">,
HelpText<"The command line string to be recorded in Omnibor metadata file.">,
MarshallingInfoString<CodeGenOpts<"OmniborCommandLine">>;
def compress_debug_sections_EQ : Joined<["-", "--"], "compress-debug-sections=">,
HelpText<"DWARF debug sections compression type">, Values<"none,zlib">,
NormalizedValuesScope<"llvm::DebugCompressionType">, NormalizedValues<["None", "Z"]>,
Expand Down
2 changes: 2 additions & 0 deletions llvm-project/clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6452,6 +6452,7 @@ static std::string ComputeSHA1OmniBorData(CodeGenModule &CGM,
gitoid = Result.str();

SmallString<128> gitoidPath(CGM.getCodeGenOpts().RecordOmniBor);
llvm::sys::path::append(gitoidPath, "objects");
llvm::sys::path::append(gitoidPath, "gitoid_blob_sha1");
llvm::sys::path::append(gitoidPath, gitoidHex.substr(0, 2));
std::error_code EC;
Expand Down Expand Up @@ -6496,6 +6497,7 @@ static std::string ComputeSHA256OmniBorData(CodeGenModule &CGM,
gitoid = Result.str();

SmallString<128> gitoidPath(CGM.getCodeGenOpts().RecordOmniBor);
llvm::sys::path::append(gitoidPath, "objects");
llvm::sys::path::append(gitoidPath, "gitoid_blob_sha256");
llvm::sys::path::append(gitoidPath, gitoidHex.substr(0, 2));
std::error_code EC;
Expand Down
20 changes: 18 additions & 2 deletions llvm-project/clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6822,10 +6822,26 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
OutputPath = env;
}
if (!OutputPath.str().empty()) {
llvm::sys::path::append(OutputPath, "objects");
CmdArgs.push_back("-record-omnibor");
CmdArgs.push_back(Args.MakeArgString(OutputPath));
// Create the .bom/objects directory

// Collect command line arguments as metadata
ArgStringList OriginalArgs;
for (const auto &Arg : Args)
Arg->render(Args, OriginalArgs);

SmallString<256> Flags;
EscapeSpacesAndBackslashes(Exec, Flags);
for (const char *OriginalArg : OriginalArgs) {
SmallString<128> EscapedArg;
EscapeSpacesAndBackslashes(OriginalArg, EscapedArg);
Flags += " ";
Flags += EscapedArg;
}
auto FlagsArgString = Args.MakeArgString(Flags);
CmdArgs.push_back("-omnibor-command-line");
CmdArgs.push_back(FlagsArgString);

auto EC =
llvm::sys::fs::create_directories(OutputPath, /*IgnoreExisting=*/true);
if (EC)
Expand Down
17 changes: 11 additions & 6 deletions llvm-project/clang/test/CodeGen/omnibor_test.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
// RUN: rm -rf %t && mkdir %t

// RUN: rm -f objects/gitoid_blob_sha1/0b/e9b91c3e456c910b32afc862ffd073b7c61d5f
// RUN: env OMNIBOR_DIR= %clang -c -frecord-omnibor=%t %S/Inputs/omnibor.c -I%S/Inputs/omnibor.h
// RUN: llvm-readelf -n omnibor.o | FileCheck --check-prefix=BOM_NOTE_SECTION %s
// RUN: cat %t/objects/gitoid_blob_sha1/0b/e9b91c3e456c910b32afc862ffd073b7c61d5f | FileCheck --check-prefix=BOM_FILE_SHA1_CONTENTS %s
// RUN: cat %t/objects/gitoid_blob_sha256/58/ed318e337ad6260f471c086e9c9985543c5fbd507c3b44924f5af37bd0ea96 | FileCheck --check-prefix=BOM_FILE_SHA256_CONTENTS %s
// RUN: cat %t/metadata/llvm/17274786fd44c95cae7ccb2d0b29ca1738c3cbb1 | FileCheck --check-prefix=METADATA_CONTENTS %s

// RUN: %clang -c -frecord-omnibor=%t -o %t/omnibor_1.o %S/Inputs/omnibor.c -I%S/Inputs/omnibor.h
// RUN: llvm-readelf -n %t/omnibor_1.o | FileCheck --check-prefix=BOM_NOTE_SECTION %s
// RUN: cat %t/objects/gitoid_blob_sha1/0b/e9b91c3e456c910b32afc862ffd073b7c61d5f | FileCheck --check-prefix=BOM_FILE_SHA1_CONTENTS %s
Expand Down Expand Up @@ -27,12 +34,6 @@
// RUN: cat %t/objects/gitoid_blob_sha1/0b/e9b91c3e456c910b32afc862ffd073b7c61d5f | FileCheck --check-prefix=BOM_FILE_SHA1_CONTENTS %s
// RUN: cat %t/objects/gitoid_blob_sha256/58/ed318e337ad6260f471c086e9c9985543c5fbd507c3b44924f5af37bd0ea96 | FileCheck --check-prefix=BOM_FILE_SHA256_CONTENTS %s

// RUN: rm -f objects/gitoid_blob_sha1/0b/e9b91c3e456c910b32afc862ffd073b7c61d5f
// RUN: env OMNIBOR_DIR= %clang -c -frecord-omnibor=%t %S/Inputs/omnibor.c -I%S/Inputs/omnibor.h
// RUN: llvm-readelf -n omnibor.o | FileCheck --check-prefix=BOM_NOTE_SECTION %s
// RUN: cat %t/objects/gitoid_blob_sha1/0b/e9b91c3e456c910b32afc862ffd073b7c61d5f | FileCheck --check-prefix=BOM_FILE_SHA1_CONTENTS %s
// RUN: cat %t/objects/gitoid_blob_sha256/58/ed318e337ad6260f471c086e9c9985543c5fbd507c3b44924f5af37bd0ea96 | FileCheck --check-prefix=BOM_FILE_SHA256_CONTENTS %s

// BOM_NOTE_SECTION: Displaying notes found in: .note.omnibor
// BOM_NOTE_SECTION: Owner Data size Description
// BOM_NOTE_SECTION: OMNIBOR 0x00000014 NT_GITOID_SHA1
Expand All @@ -47,3 +48,7 @@
// BOM_FILE_SHA256_CONTENTS: gitoid:blob:sha256
// BOM_FILE_SHA256_CONTENTS: blob 465be75836446b37f31c5db1f29a8689f37cd5625d4b30237877703fc1070f5e
// BOM_FILE_SHA256_CONTENTS: blob 8ad020236bd23736a75699ba4e83f52593d61c4c9f8d5932b57fce011f832bf8

// METADATA_CONTENTS: output: omnibor.o
// METADATA_CONTENTS_NEXT: input {{.*}}/omnibor.c
// METADATA_CONTENTS_NEXT: input {{.*}}/omnibor.h
78 changes: 78 additions & 0 deletions llvm-project/clang/tools/driver/cc1_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/SHA1.h"
#include "llvm/Support/SHA256.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/TimeProfiler.h"
Expand Down Expand Up @@ -181,6 +183,38 @@ static int PrintSupportedCPUs(std::string TargetStr) {
return 0;
}

static std::string convertToHex(StringRef Input) {
static const char *const LUT = "0123456789abcdef";
size_t Length = Input.size();

std::string Output;
Output.reserve(2 * Length);
for (size_t i = 0; i < Length; ++i) {
const unsigned char c = Input[i];
Output.push_back(LUT[c >> 4]);
Output.push_back(LUT[c & 15]);
}
return Output;
}

static std::string getSHA1Hash(std::string Filename) {
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> fileBuf =
llvm::MemoryBuffer::getFile(Filename, /*IsText=*/true);
if (!fileBuf) {
// Diags.Report(diag::err_fe_error_opening) << Filename;
llvm::errs() << "\n error opening " << Filename;
return std::string();
}

llvm::SHA1 Hash;
std::string initData =
"blob " + std::to_string(fileBuf.get()->getBufferSize()) + '\0';
Hash.update(StringRef(initData));
Hash.update(fileBuf.get()->getBuffer());
auto Result = Hash.final();
return convertToHex(Result);
}

int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
ensureSufficientStack();

Expand Down Expand Up @@ -272,6 +306,50 @@ int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
// later errors use the default handling behavior instead.
llvm::remove_fatal_error_handler();

if (!Clang->getCodeGenOpts().RecordOmniBor.empty()) {
SmallString<128> gitoidPath(Clang->getCodeGenOpts().RecordOmniBor);
llvm::sys::path::append(gitoidPath, "metadata/llvm");
auto EC =
llvm::sys::fs::create_directories(gitoidPath, /*IgnoreExisting=*/true);
if (EC)
llvm::errs() << "\nCannot create metadata file ";

std::vector<std::string> MetadataLines;
std::string outLine("\noutput: ");
outLine.append(Clang->getFrontendOpts().OutputFile);
MetadataLines.push_back(outLine);

if (Clang->getCodeGenOpts().BomDependencies->size()) {
std::vector<std::string> &Deps =
*(Clang->getCodeGenOpts().BomDependencies);
for (auto file : Deps) {
std::string Line = "\ninput " + file;
MetadataLines.push_back(Line);
}
}

// Metadata contents
std::string MetadataContents;
for (auto line : MetadataLines)
MetadataContents.append(line);

// Write command line
if (!Clang->getCodeGenOpts().OmniborCommandLine.empty()) {
MetadataContents.append("\nbuild_cmd: ");
MetadataContents.append(Clang->getCodeGenOpts().OmniborCommandLine);
}

// Write metadata
std::string artifact_id = getSHA1Hash(Clang->getFrontendOpts().OutputFile);
llvm::sys::path::append(gitoidPath, artifact_id);
std::string MetadataFile(gitoidPath);
llvm::raw_fd_ostream OSM(MetadataFile, EC, llvm::sys::fs::OF_TextWithCRLF);
if (EC) {
llvm::errs() << MetadataFile << EC.message();
}
OSM << MetadataContents;
}

// When running with -disable-free, don't do any destruction or shutdown.
if (Clang->getFrontendOpts().DisableFree) {
llvm::BuryPointer(std::move(Clang));
Expand Down

0 comments on commit 3be68a5

Please sign in to comment.