diff options
author | Rui Ueyama <ruiu@google.com> | 2016-04-07 22:49:21 +0000 |
---|---|---|
committer | Rui Ueyama <ruiu@google.com> | 2016-04-07 22:49:21 +0000 |
commit | 3a41be277a761d7687a2b860fa045ef5227d6e2d (patch) | |
tree | fea09726e818fcd3d62a4dccae500f7920d4fb8c /lld/ELF/OutputSections.cpp | |
parent | e918006a87012fbd6840108b08313bb55a11403a (diff) | |
download | bcm5719-llvm-3a41be277a761d7687a2b860fa045ef5227d6e2d.tar.gz bcm5719-llvm-3a41be277a761d7687a2b860fa045ef5227d6e2d.zip |
ELF: Implement --build-id=md5.
Previously, we supported only one hash function, FNV-1, so
BuildIdSection directly handled hash computation. In this patch,
I made BuildIdSection an abstract class and defined two subclasses,
BuildIdFnv1 and BuildIdMd5.
llvm-svn: 265737
Diffstat (limited to 'lld/ELF/OutputSections.cpp')
-rw-r--r-- | lld/ELF/OutputSections.cpp | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 9d00caf41e7..3a9de915791 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -14,6 +14,7 @@ #include "Target.h" #include "lld/Core/Parallel.h" #include "llvm/Support/Dwarf.h" +#include "llvm/Support/MD5.h" #include "llvm/Support/MathExtras.h" #include <map> @@ -1521,23 +1522,24 @@ uint8_t SymbolTableSection<ELFT>::getSymbolBinding(SymbolBody *Body) { } template <class ELFT> -BuildIdSection<ELFT>::BuildIdSection() - : OutputSectionBase<ELFT>(".note.gnu.build-id", SHT_NOTE, SHF_ALLOC) { - // 16 bytes for the note section header and 8 bytes for FNV1 hash. - this->Header.sh_size = 24; +BuildIdSection<ELFT>::BuildIdSection(size_t HashSize) + : OutputSectionBase<ELFT>(".note.gnu.build-id", SHT_NOTE, SHF_ALLOC), + HashSize(HashSize) { + // 16 bytes for the note section header. + this->Header.sh_size = 16 + HashSize; } template <class ELFT> void BuildIdSection<ELFT>::writeTo(uint8_t *Buf) { const endianness E = ELFT::TargetEndianness; write32<E>(Buf, 4); // Name size - write32<E>(Buf + 4, sizeof(Hash)); // Content size + write32<E>(Buf + 4, HashSize); // Content size write32<E>(Buf + 8, NT_GNU_BUILD_ID); // Type memcpy(Buf + 12, "GNU", 4); // Name string HashBuf = Buf + 16; } -template <class ELFT> void BuildIdSection<ELFT>::update(ArrayRef<uint8_t> Buf) { - // 64-bit FNV1 hash +template <class ELFT> void BuildIdFnv1<ELFT>::update(ArrayRef<uint8_t> Buf) { + // 64-bit FNV-1 hash const uint64_t Prime = 0x100000001b3; for (uint8_t B : Buf) { Hash *= Prime; @@ -1545,9 +1547,19 @@ template <class ELFT> void BuildIdSection<ELFT>::update(ArrayRef<uint8_t> Buf) { } } -template <class ELFT> void BuildIdSection<ELFT>::writeBuildId() { +template <class ELFT> void BuildIdFnv1<ELFT>::writeBuildId() { const endianness E = ELFT::TargetEndianness; - write64<E>(HashBuf, Hash); + write64<E>(this->HashBuf, Hash); +} + +template <class ELFT> void BuildIdMd5<ELFT>::update(ArrayRef<uint8_t> Buf) { + Hash.update(Buf); +} + +template <class ELFT> void BuildIdMd5<ELFT>::writeBuildId() { + MD5::MD5Result Res; + Hash.final(Res); + memcpy(this->HashBuf, Res, 16); } template <class ELFT> @@ -1658,5 +1670,15 @@ template class BuildIdSection<ELF32LE>; template class BuildIdSection<ELF32BE>; template class BuildIdSection<ELF64LE>; template class BuildIdSection<ELF64BE>; + +template class BuildIdFnv1<ELF32LE>; +template class BuildIdFnv1<ELF32BE>; +template class BuildIdFnv1<ELF64LE>; +template class BuildIdFnv1<ELF64BE>; + +template class BuildIdMd5<ELF32LE>; +template class BuildIdMd5<ELF32BE>; +template class BuildIdMd5<ELF64LE>; +template class BuildIdMd5<ELF64BE>; } } |