From 4fb08dde4caf493ce4f4ffee59731da8dfd61e1e Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Jul 14 2006 21:03:01 +0000 Subject: - adding .gnu.hash patch to support new ELF hash table section - adding xfail patch to silent clone failing for missing privileges --- diff --git a/ltrace-0.5-gnuhash.patch b/ltrace-0.5-gnuhash.patch new file mode 100644 index 0000000..10d0142 --- /dev/null +++ b/ltrace-0.5-gnuhash.patch @@ -0,0 +1,168 @@ +diff -urpd ltrace-0.5-orig/elf.c ltrace-0.5/elf.c +--- ltrace-0.5-orig/elf.c 2006-07-14 12:28:32.000000000 -0400 ++++ ltrace-0.5/elf.c 2006-07-14 16:47:31.000000000 -0400 +@@ -169,6 +169,8 @@ static void do_init_elf(struct ltelf *lt + Elf_Data *data; + size_t j; + ++ lte->hash_type = SHT_HASH; ++ + data = elf_getdata(scn, NULL); + if (data == NULL || elf_getdata(scn, data) != NULL + || data->d_off || data->d_size != shdr.sh_size) +@@ -209,6 +211,33 @@ static void do_init_elf(struct ltelf *lt + error(EXIT_FAILURE, 0, + "Unknown .hash sh_entsize in \"%s\"", + filename); ++#ifdef SHT_GNU_HASH ++ } else if (shdr.sh_type == SHT_GNU_HASH ++ && lte->hash == NULL) { ++ Elf_Data *data; ++ size_t j; ++ ++ lte->hash_type = SHT_GNU_HASH; ++ ++ if (shdr.sh_entsize != 0) { ++ error(EXIT_FAILURE, 0, ++ ".gnu.hash sh_entsize in \"%s\" should be 0", ++ filename); ++ } ++ ++ data = elf_getdata(scn, NULL); ++ if (data == NULL || elf_getdata(scn, data) != NULL ++ || data->d_off || data->d_size != shdr.sh_size) ++ error(EXIT_FAILURE, 0, ++ "Couldn't get .gnu.hash data from \"%s\"", ++ filename); ++ ++ if (data->d_type != ELF_T_GNUHASH) ++ error(EXIT_FAILURE, 0, ++ "Couldn't get .gnu.hash data from \"%s\"", ++ filename); ++ lte->hash = (Elf32_Word *) data->d_buf; ++#endif + } else if (shdr.sh_type == SHT_PROGBITS + || shdr.sh_type == SHT_NOBITS) { + if (strcmp(name, ".plt") == 0) { +@@ -300,34 +329,81 @@ add_library_symbol(GElf_Addr addr, const + static int in_load_libraries(const char *name, struct ltelf *lte) + { + size_t i; +- unsigned long hash; ++ unsigned long hash ++#ifdef SHT_GNU_HASH ++ , gnu_hash ++#endif ++ ; + + if (!library_num) + return 1; + + hash = elf_hash((const unsigned char *)name); ++#ifdef SHT_GNU_HASH ++ gnu_hash = elf_gnu_hash((const unsigned char *)name); ++#endif + for (i = 1; i <= library_num; ++i) { +- Elf32_Word nbuckets, symndx; +- Elf32_Word *buckets, *chain; +- + if (lte[i].hash == NULL) + continue; + +- nbuckets = lte[i].hash[0]; +- buckets = <e[i].hash[2]; +- chain = <e[i].hash[2 + nbuckets]; +- for (symndx = buckets[hash % nbuckets]; +- symndx != STN_UNDEF; symndx = chain[symndx]) { +- GElf_Sym sym; ++#ifdef SHT_GNU_HASH ++ if (lte[i].hash_type == SHT_GNU_HASH) { ++ Elf32_Word * hashbase = lte[i].hash; ++ Elf32_Word nbuckets = *hashbase++; ++ Elf32_Word symbias = *hashbase++; ++ Elf32_Word bitmask_nwords = *hashbase++; ++ Elf32_Word bitmask_idxbits = bitmask_nwords - 1; ++ Elf32_Word shift = *hashbase++; ++ Elf32_Word * buckets; ++ Elf32_Word * chain_zero; ++ Elf32_Word bucket; + +- if (gelf_getsym(lte[i].dynsym, symndx, &sym) == NULL) +- error(EXIT_FAILURE, 0, +- "Couldn't get symbol from .dynsym"); ++ hashbase += LT_ELFCLASS * bitmask_nwords; ++ buckets = hashbase; ++ hashbase += nbuckets; ++ chain_zero = hashbase - symbias; ++ bucket = buckets[gnu_hash % nbuckets]; + +- if (sym.st_value != 0 +- && sym.st_shndx != SHN_UNDEF +- && strcmp(name, lte[i].dynstr + sym.st_name) == 0) +- return 1; ++ if (bucket != 0) { ++ const Elf32_Word *hasharr = &chain_zero[bucket]; ++ do ++ if ((*hasharr & ~1u) == (gnu_hash & ~1u)) { ++ int symidx = hasharr - chain_zero; ++ GElf_Sym sym; ++ ++ if (gelf_getsym(lte[i].dynsym, symidx, &sym) == NULL) ++ error(EXIT_FAILURE, 0, ++ "Couldn't get symbol from .dynsym"); ++ ++ if (sym.st_value != 0 ++ && sym.st_shndx != SHN_UNDEF ++ && strcmp(name, lte[i].dynstr + sym.st_name) == 0) ++ return 1; ++ } ++ while ((*hasharr++ & 1u) == 0); ++ } ++ } else ++#endif ++ { ++ Elf32_Word nbuckets, symndx; ++ Elf32_Word *buckets, *chain; ++ nbuckets = lte[i].hash[0]; ++ buckets = <e[i].hash[2]; ++ chain = <e[i].hash[2 + nbuckets]; ++ ++ for (symndx = buckets[hash % nbuckets]; ++ symndx != STN_UNDEF; symndx = chain[symndx]) { ++ GElf_Sym sym; ++ ++ if (gelf_getsym(lte[i].dynsym, symndx, &sym) == NULL) ++ error(EXIT_FAILURE, 0, ++ "Couldn't get symbol from .dynsym"); ++ ++ if (sym.st_value != 0 ++ && sym.st_shndx != SHN_UNDEF ++ && strcmp(name, lte[i].dynstr + sym.st_name) == 0) ++ return 1; ++ } + } + } + return 0; +diff -urpd ltrace-0.5-orig/elf.h ltrace-0.5/elf.h +--- ltrace-0.5-orig/elf.h 2006-07-14 12:28:32.000000000 -0400 ++++ ltrace-0.5/elf.h 2006-07-14 13:26:56.000000000 -0400 +@@ -24,6 +24,7 @@ struct ltelf { + GElf_Addr *opd_addr; + size_t opd_size; + Elf32_Word *hash; ++ int hash_type; + int lte_flags; + }; + +diff -urpd ltrace-0.5-orig/options.c ltrace-0.5/options.c +--- ltrace-0.5-orig/options.c 2006-07-14 12:28:32.000000000 -0400 ++++ ltrace-0.5/options.c 2006-07-14 16:46:01.000000000 -0400 +@@ -3,7 +3,7 @@ + #endif + + #ifndef PACKAGE_VERSION +-# define PACKAGE_VERSION "0.3.32" ++# error need package version + #endif + + #include diff --git a/ltrace.spec b/ltrace.spec index bc17cde..96b4472 100644 --- a/ltrace.spec +++ b/ltrace.spec @@ -1,10 +1,12 @@ Summary: Tracks runtime library calls from dynamically linked executables. Name: ltrace Version: 0.5 -Release: 1.0.45svn +Release: 1.0.45svn.1 Source: ltrace-0.5.tar.gz Patch2: ltrace-opd.patch Patch3: ltrace-ppc32fc5.patch +Patch4: ltrace-0.5-gnuhash.patch +Patch5: ltrace-0.5-xfail.patch License: GPL Group: Development/Debuggers ExclusiveArch: %{ix86} x86_64 ia64 ppc ppc64 s390 s390x alpha sparc @@ -26,6 +28,8 @@ execution of processes. %setup -q %patch2 -p1 %patch3 -p0 +%patch4 -p1 +%patch5 -p1 sed -i -e 's/-o root -g root//' Makefile.in %build @@ -52,6 +56,10 @@ rm -rf $RPM_BUILD_ROOT %config /etc/ltrace.conf %changelog +* Fri Jul 14 2006 Petr Machata - 0.5-1.0.45svn.1 +- adding .gnu.hash patch to support new ELF hash table section +- adding xfail patch to silent clone failing for missing privileges + * Fri Jul 14 2006 Petr Machata - 0.5-1.0.45svn - adding upstream (svn) version. It contains most of patches that we already use, and has support for secure PLTs.