Add elf_read_{,next_}uleb128
diff --git a/ltrace-elf.c b/ltrace-elf.c
index b2e6e07..b045d64 100644
--- a/ltrace-elf.c
+++ b/ltrace-elf.c
@@ -263,6 +263,38 @@
 #undef DEF_READER
 
 int
+elf_read_next_uleb128(Elf_Data *data, GElf_Xword *offset, uint64_t *retp)
+{
+	uint64_t result = 0;
+	int shift = 0;
+	int size = 8 * sizeof result;
+
+	while (1) {
+		uint8_t byte;
+		if (elf_read_next_u8(data, offset, &byte) < 0)
+			return -1;
+
+		uint8_t payload = byte & 0x7f;
+		result |= (uint64_t)payload << shift;
+		shift += 7;
+		if (shift > size && byte != 0x1)
+			return -1;
+		if ((byte & 0x80) == 0)
+			break;
+	}
+
+	if (retp != NULL)
+		*retp = result;
+	return 0;
+}
+
+int
+elf_read_uleb128(Elf_Data *data, GElf_Xword offset, uint64_t *retp)
+{
+	return elf_read_next_uleb128(data, &offset, retp);
+}
+
+int
 open_elf(struct ltelf *lte, const char *filename)
 {
 	lte->fd = open(filename, O_RDONLY);
diff --git a/ltrace-elf.h b/ltrace-elf.h
index a520e63..af97b0a 100644
--- a/ltrace-elf.h
+++ b/ltrace-elf.h
@@ -116,12 +116,17 @@
 int elf_read_u32(Elf_Data *data, GElf_Xword offset, uint32_t *retp);
 int elf_read_u64(Elf_Data *data, GElf_Xword offset, uint64_t *retp);
 
+/* Read at most 64-bit quantity recorded in an ULEB128 variable-length
+ * encoding.  */
+int elf_read_uleb128(Elf_Data *data, GElf_Xword offset, uint64_t *retp);
+
 /* These are same as above, but update *OFFSET with the width
  * of read datum.  */
 int elf_read_next_u8(Elf_Data *data, GElf_Xword *offset, uint8_t *retp);
 int elf_read_next_u16(Elf_Data *data, GElf_Xword *offset, uint16_t *retp);
 int elf_read_next_u32(Elf_Data *data, GElf_Xword *offset, uint32_t *retp);
 int elf_read_next_u64(Elf_Data *data, GElf_Xword *offset, uint64_t *retp);
+int elf_read_next_uleb128(Elf_Data *data, GElf_Xword *offset, uint64_t *retp);
 
 #if __WORDSIZE == 32
 #define PRI_ELF_ADDR		PRIx32