From 71f965b55ffaaa0853e60be2e8b97daf95544712 Mon Sep 17 00:00:00 2001
From: Kito Cheng <kito@0xlab.org>
Date: Fri, 12 Aug 2011 00:55:37 +0800
Subject: [PATCH] Basic GNU-style hash support for elfcopy

---
 elfcopy.c |   17 +++++++++++++++--
 1 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/elfcopy.c b/elfcopy.c
index ed1e6ce..cac10ea 100644
--- a/elfcopy.c
+++ b/elfcopy.c
@@ -34,6 +34,16 @@
 */
 #define ELF_STRPTR_IS_BROKEN     (1)
 
+/* Compatible for older elfutils.
+   elfutils support gnu-style hash since version 0.122
+*/
+#ifndef DT_GNU_HASH
+#define DT_GNU_HASH 0x6ffffef5
+#endif
+#ifndef SHT_GNU_HASH
+#define SHT_GNU_HASH 0x6ffffff6
+#endif
+
 static void update_relocations_section_symbol_references(Elf *newelf, Elf *elf,
                                                          shdr_info_t *info, int info_len,
                                                          shdr_info_t *relsect_info,
@@ -744,7 +754,6 @@ void adjust_elf(Elf *elf, const char *elf_name,
 
                 FAILIF(shdr_info[cnt].shdr.sh_entsize != sizeof (Elf32_Word),
                        "Can't handle 64-bit ELF files!\n");
-
                 update_hash_table(newelf,  /* new ELF */
                                   elf,     /* old ELF */
                                   shdr_info[cnt].idx, /* hash table index */
@@ -846,7 +855,9 @@ void adjust_elf(Elf *elf, const char *elf_name,
                     } /* for each symbol... */
                 }
             }
-
+            /* We don't support update gnu-style hash table now! */
+            FAILIF(shdr_info[cnt].shdr.sh_type == SHT_GNU_HASH,
+                   "Can't handle SHT_GNU_HASH!\n");
             FAILIF(shdr_info[cnt].shdr.sh_type == SHT_GNU_versym,
                    "Can't handle SHT_GNU_versym!\n");
             FAILIF(shdr_info[cnt].shdr.sh_type == SHT_GROUP,
@@ -1933,6 +1944,7 @@ static void adjust_dynamic_segment_offsets(Elf *elf, Ebl *oldebl,
 
         case DT_PLTGOT:
         case DT_HASH:
+        case DT_GNU_HASH:
         case DT_SYMTAB:
             (void)update_dyn_entry_address(elf, dyn, shdr_info, shdr_info_len);
             break;
@@ -2582,6 +2594,7 @@ static int get_end_of_range(shdr_info_t *shdr_info,
             (shdr_info[end].shdr.sh_type == SHT_INIT_ARRAY) ||
             (shdr_info[end].shdr.sh_type == SHT_FINI_ARRAY) ||
             (shdr_info[end].shdr.sh_type == SHT_PREINIT_ARRAY) ||
+            (shdr_info[end].shdr.sh_type == SHT_GNU_HASH) ||
          /* (shdr_info[end].shdr.sh_type == SHT_NOBITS) || */
 #ifdef ARM_SPECIFIC_HACKS
             /* SHF_ALLOC sections with with names starting with ".ARM." are
-- 
1.7.5.4

