File ltrace-ppc64le_git6.patch of Package ltrace

--- ltrace-elf.c.ori
+++ ltrace-elf.c
@@ -202,6 +202,66 @@ elf_get_section_named(struct ltelf *lte, const char *name,
 				  &name_p, &data);
 }
 
+static struct elf_each_symbol_t
+each_symbol_in(Elf_Data *symtab, const char *strtab, size_t count,
+	       unsigned i,
+	       enum callback_status (*cb)(GElf_Sym *symbol,
+					  const char *name, void *data),
+	       void *data)
+{
+	for (; i < count; ++i) {
+		GElf_Sym sym;
+		if (gelf_getsym(symtab, i, &sym) == NULL)
+			return (struct elf_each_symbol_t){ i, -2 };
+
+		switch (cb(&sym, strtab + sym.st_name, data)) {
+		case CBS_FAIL:
+			return (struct elf_each_symbol_t){ i, -1 };
+		case CBS_STOP:
+			return (struct elf_each_symbol_t){ i + 1, 0 };
+		case CBS_CONT:
+			break;
+		}
+	}
+
+	return (struct elf_each_symbol_t){ 0, 0 };
+}
+
+/* N.B.: gelf_getsym takes integer argument.  Since negative values
+ * are invalid as indices, we can use the extra bit to encode which
+ * symbol table we are looking into.  ltrace currently doesn't handle
+ * more than two symbol tables anyway, nor does it handle the xindex
+ * stuff.  */
+struct elf_each_symbol_t
+elf_each_symbol(struct ltelf *lte, unsigned start_after,
+		enum callback_status (*cb)(GElf_Sym *symbol,
+					   const char *name, void *data),
+		void *data)
+{
+	unsigned index = start_after == 0 ? 0 : start_after >> 1;
+
+	/* Go through static symbol table first.  */
+	if ((start_after & 0x1) == 0) {
+		struct elf_each_symbol_t st
+			= each_symbol_in(lte->symtab, lte->strtab,
+					 lte->symtab_count, index, cb, data);
+
+		/* If the iteration stopped prematurely, bail out.  */
+		if (st.restart != 0)
+			return ((struct elf_each_symbol_t)
+				{ st.restart << 1, st.status });
+	}
+
+	struct elf_each_symbol_t st
+		= each_symbol_in(lte->dynsym, lte->dynstr, lte->dynsym_count,
+				 index, cb, data);
+	if (st.restart != 0)
+		return ((struct elf_each_symbol_t)
+			{ st.restart << 1 | 0x1, st.status });
+
+	return (struct elf_each_symbol_t){ 0, 0 };
+}
+
 static int
 need_data(Elf_Data *data, GElf_Xword offset, GElf_Xword size)
 {
--- ltrace-elf.h.ori
+++ ltrace-elf.h
@@ -26,6 +26,7 @@
 
 #include <gelf.h>
 #include <stdlib.h>
+#include <callback.h>
 #include "sysdep.h"
 
 struct Process;
@@ -104,6 +105,17 @@ int elf_get_section_type(struct ltelf *lte, GElf_Word type,
 int elf_get_section_named(struct ltelf *lte, const char *name,
 			  Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr);
 
+/* Iterate through all symbols in LTE.  See callback.h for notes on
+ * iteration interfaces.  START_AFTER is 0 in initial call.  */
+struct elf_each_symbol_t {
+	unsigned restart;
+	int status;
+} elf_each_symbol(struct ltelf *lte, unsigned start_after,
+		  enum callback_status (*cb)(GElf_Sym *symbol,
+					     const char *name,
+					     void *data),
+		  void *data);
+
 /* Read, respectively, 2, 4, or 8 bytes from Elf data at given OFFSET,
  * and store it in *RETP.  Returns 0 on success or a negative value if
  * there's not enough data.  */

openSUSE Build Service is sponsored by