Generalize compression tool

 1. One binary for all architectures
 2. Generalize (and slightly improve) compression
 2.1 works on all relocation types (rela?.dyn section only so far)
 2.2 Uses same format to encode ElfW(Rel) as well as ElfW(Rela) tables

Bug: 18051137
Change-Id: I66c95d9076954ca115816fc577d0f5ef274e5e72
diff --git a/tools/relocation_packer/src/leb128.cc b/tools/relocation_packer/src/leb128.cc
index b48739c..101c557 100644
--- a/tools/relocation_packer/src/leb128.cc
+++ b/tools/relocation_packer/src/leb128.cc
@@ -12,40 +12,50 @@
 namespace relocation_packer {
 
 // Empty constructor and destructor to silence chromium-style.
-Leb128Encoder::Leb128Encoder() { }
-Leb128Encoder::~Leb128Encoder() { }
+template <typename uint_t>
+Leb128Encoder<uint_t>::Leb128Encoder() { }
+
+template <typename uint_t>
+Leb128Encoder<uint_t>::~Leb128Encoder() { }
 
 // Add a single value to the encoding.  Values are encoded with variable
 // length.  The least significant 7 bits of each byte hold 7 bits of data,
 // and the most significant bit is set on each byte except the last.
-void Leb128Encoder::Enqueue(ELF::Xword value) {
+template <typename uint_t>
+void Leb128Encoder<uint_t>::Enqueue(uint_t value) {
+  uint_t uvalue = static_cast<uint_t>(value);
   do {
-    const uint8_t byte = value & 127;
-    value >>= 7;
-    encoding_.push_back((value ? 128 : 0) | byte);
-  } while (value);
+    const uint8_t byte = uvalue & 127;
+    uvalue >>= 7;
+    encoding_.push_back((uvalue ? 128 : 0) | byte);
+  } while (uvalue);
 }
 
 // Add a vector of values to the encoding.
-void Leb128Encoder::EnqueueAll(const std::vector<ELF::Xword>& values) {
-  for (size_t i = 0; i < values.size(); ++i)
+template <typename uint_t>
+void Leb128Encoder<uint_t>::EnqueueAll(const std::vector<uint_t>& values) {
+  for (size_t i = 0; i < values.size(); ++i) {
     Enqueue(values[i]);
+  }
 }
 
 // Create a new decoder for the given encoded stream.
-Leb128Decoder::Leb128Decoder(const std::vector<uint8_t>& encoding) {
+template <typename uint_t>
+Leb128Decoder<uint_t>::Leb128Decoder(const std::vector<uint8_t>& encoding, size_t start_with) {
   encoding_ = encoding;
-  cursor_ = 0;
+  cursor_ = start_with;
 }
 
 // Empty destructor to silence chromium-style.
-Leb128Decoder::~Leb128Decoder() { }
+template <typename uint_t>
+Leb128Decoder<uint_t>::~Leb128Decoder() { }
 
 // Decode and retrieve a single value from the encoding.  Read forwards until
 // a byte without its most significant bit is found, then read the 7 bit
 // fields of the bytes spanned to re-form the value.
-ELF::Xword Leb128Decoder::Dequeue() {
-  ELF::Xword value = 0;
+template <typename uint_t>
+uint_t Leb128Decoder<uint_t>::Dequeue() {
+  uint_t value = 0;
 
   size_t shift = 0;
   uint8_t byte;
@@ -53,7 +63,7 @@
   // Loop until we reach a byte with its high order bit clear.
   do {
     byte = encoding_[cursor_++];
-    value |= static_cast<ELF::Xword>(byte & 127) << shift;
+    value |= static_cast<uint_t>(byte & 127) << shift;
     shift += 7;
   } while (byte & 128);
 
@@ -61,9 +71,17 @@
 }
 
 // Decode and retrieve all remaining values from the encoding.
-void Leb128Decoder::DequeueAll(std::vector<ELF::Xword>* values) {
-  while (cursor_ < encoding_.size())
+template <typename uint_t>
+void Leb128Decoder<uint_t>::DequeueAll(std::vector<uint_t>* values) {
+  while (cursor_ < encoding_.size()) {
     values->push_back(Dequeue());
+  }
 }
 
+template class Leb128Encoder<uint32_t>;
+template class Leb128Encoder<uint64_t>;
+
+template class Leb128Decoder<uint32_t>;
+template class Leb128Decoder<uint64_t>;
+
 }  // namespace relocation_packer