Added Paul Gilliam's secure PLT patch
diff --git a/elf.c b/elf.c
index d791bfe..b459b79 100644
--- a/elf.c
+++ b/elf.c
@@ -21,9 +21,9 @@
 static void do_close_elf(struct ltelf *lte);
 static void add_library_symbol(GElf_Addr addr, const char *name,
 			       struct library_symbol **library_symbolspp,
-			       int use_elf_plt2addr, int is_weak);
+			       enum toplt type_of_plt, int is_weak);
 static int in_load_libraries(const char *name, struct ltelf *lte);
-static GElf_Addr elf_plt2addr(struct ltelf *ltc, void *addr);
+static GElf_Addr opd2addr(struct ltelf *ltc, void *addr);
 
 #ifdef PLT_REINITALISATION_BP
 extern char *PLTs_initialized_by_here;
@@ -194,7 +194,7 @@
 					error(EXIT_FAILURE, 0,
 					      "Couldn't convert .hash section from \"%s\"",
 					      filename);
-				lte->hash_malloced = 1;
+				lte->lte_flags |= LTE_HASH_MALLOCED;
 				dst = lte->hash;
 				src = (Elf32_Word *) data->d_buf;
 				if ((data->d_type == ELF_T_WORD
@@ -214,6 +214,9 @@
 			if (strcmp(name, ".plt") == 0) {
 				lte->plt_addr = shdr.sh_addr;
 				lte->plt_size = shdr.sh_size;
+				if (shdr.sh_flags & SHF_EXECINSTR) {
+					lte->lte_flags |= LTE_PLT_EXECUTABLE;
+				}
 			} else if (strcmp(name, ".opd") == 0) {
 				lte->opd_addr = (GElf_Addr *) (long) shdr.sh_addr;
 				lte->opd_size = shdr.sh_size;
@@ -265,7 +268,7 @@
 
 static void do_close_elf(struct ltelf *lte)
 {
-	if (lte->hash_malloced)
+	if (lte->lte_flags & LTE_HASH_MALLOCED)
 		free((char *)lte->hash);
 	elf_end(lte->elf);
 	close(lte->fd);
@@ -274,7 +277,7 @@
 static void
 add_library_symbol(GElf_Addr addr, const char *name,
 		   struct library_symbol **library_symbolspp,
-		   int use_elf_plt2addr, int is_weak)
+		   enum toplt type_of_plt, int is_weak)
 {
 	struct library_symbol *s;
 	s = malloc(sizeof(struct library_symbol) + strlen(name) + 1);
@@ -283,7 +286,7 @@
 
 	s->needs_init = 1;
 	s->is_weak = is_weak;
-	s->static_plt2addr = use_elf_plt2addr;
+	s->plt_type = type_of_plt;
 	s->next = *library_symbolspp;
 	s->enter_addr = (void *)(uintptr_t) addr;
 	s->brkpnt = NULL;
@@ -330,7 +333,7 @@
 	return 0;
 }
 
-static GElf_Addr elf_plt2addr(struct ltelf *lte, void *addr)
+static GElf_Addr opd2addr(struct ltelf *lte, void *addr)
 {
 	long base;
 	long offset;
@@ -397,7 +400,9 @@
 		name = lte->dynstr + sym.st_name;
 		if (in_load_libraries(name, lte)) {
 			addr = arch_plt_sym_val(lte, i, &rela);
-			add_library_symbol(addr, name, &library_symbols, 0,
+			add_library_symbol(addr, name, &library_symbols,
+					   (PLTS_ARE_EXECUTABLE(lte)
+					   ?  LS_TOPLT_EXEC : LS_TOPLT_POINT),
 					   ELF64_ST_BIND(sym.st_info) != 0);
 			if (!lib_tail)
 				lib_tail = &(library_symbols->next);
@@ -446,9 +451,8 @@
 			if (xptr->name && strcmp(xptr->name, name) == 0) {
 				/* FIXME: Should be able to use &library_symbols as above.  But
 				   when you do, none of the real library symbols cause breaks. */
-				add_library_symbol(elf_plt2addr
-						   (lte, (void *) (long) addr),
-						   name, lib_tail, 1, 0);
+				add_library_symbol(opd2addr(lte, (void*)addr),
+						   name, lib_tail, LS_TOPLT_NONE, 0);
 				xptr->found = 1;
 				break;
 			}