summaryrefslogtreecommitdiffstats
path: root/lld/ELF/OutputSections.cpp
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2016-04-07 22:49:21 +0000
committerRui Ueyama <ruiu@google.com>2016-04-07 22:49:21 +0000
commit3a41be277a761d7687a2b860fa045ef5227d6e2d (patch)
treefea09726e818fcd3d62a4dccae500f7920d4fb8c /lld/ELF/OutputSections.cpp
parente918006a87012fbd6840108b08313bb55a11403a (diff)
downloadbcm5719-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.cpp40
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>;
}
}
OpenPOWER on IntegriCloud