diff options
Diffstat (limited to 'compiler/elf_writer_quick.cc')
-rw-r--r-- | compiler/elf_writer_quick.cc | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/compiler/elf_writer_quick.cc b/compiler/elf_writer_quick.cc index 36cd2327c4..0d6575cffd 100644 --- a/compiler/elf_writer_quick.cc +++ b/compiler/elf_writer_quick.cc @@ -16,6 +16,7 @@ #include "elf_writer_quick.h" +#include <openssl/sha.h> #include <unordered_map> #include <unordered_set> @@ -126,6 +127,8 @@ class ElfWriterQuick FINAL : public ElfWriter { std::unique_ptr<DebugInfoTask> debug_info_task_; std::unique_ptr<ThreadPool> debug_info_thread_pool_; + void ComputeFileBuildId(uint8_t (*build_id)[ElfBuilder<ElfTypes>::kBuildIdLen]); + DISALLOW_IMPLICIT_CONSTRUCTORS(ElfWriterQuick); }; @@ -167,6 +170,9 @@ ElfWriterQuick<ElfTypes>::~ElfWriterQuick() {} template <typename ElfTypes> void ElfWriterQuick<ElfTypes>::Start() { builder_->Start(); + if (compiler_options_->GetGenerateBuildId()) { + builder_->WriteBuildIdSection(); + } } template <typename ElfTypes> @@ -275,11 +281,36 @@ void ElfWriterQuick<ElfTypes>::WritePatchLocations( template <typename ElfTypes> bool ElfWriterQuick<ElfTypes>::End() { builder_->End(); - + if (compiler_options_->GetGenerateBuildId()) { + uint8_t build_id[ElfBuilder<ElfTypes>::kBuildIdLen]; + ComputeFileBuildId(&build_id); + builder_->WriteBuildId(build_id); + } return builder_->Good(); } template <typename ElfTypes> +void ElfWriterQuick<ElfTypes>::ComputeFileBuildId( + uint8_t (*build_id)[ElfBuilder<ElfTypes>::kBuildIdLen]) { + constexpr int kBufSize = 8192; + std::vector<char> buffer(kBufSize); + int64_t offset = 0; + SHA_CTX ctx; + SHA1_Init(&ctx); + while (true) { + int64_t bytes_read = elf_file_->Read(buffer.data(), kBufSize, offset); + CHECK_GE(bytes_read, 0); + if (bytes_read == 0) { + // End of file. + break; + } + SHA1_Update(&ctx, buffer.data(), bytes_read); + offset += bytes_read; + } + SHA1_Final(*build_id, &ctx); +} + +template <typename ElfTypes> OutputStream* ElfWriterQuick<ElfTypes>::GetStream() { return builder_->GetStream(); } |