Revert "[CLEAN] rm unused code and rm comments" 98/32698/1
authorVitaliy Cherepanov <v.cherepanov@samsung.com>
Mon, 22 Dec 2014 15:34:39 +0000 (18:34 +0300)
committerVitaliy Cherepanov <v.cherepanov@samsung.com>
Mon, 22 Dec 2014 15:35:44 +0000 (18:35 +0300)
This reverts commit 49dc7a7ec8664920c844e5017b249f738ddb98d4.

Change-Id: I4401c9a0fa852a615337255cb34bd91bbac8aa4f

Makefile
helper/btsym.c [new file with mode: 0755]
helper/private_link.h [new file with mode: 0644]
probe_event/keytouch.c

index b9c2b7e..3b85a57 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -70,6 +70,7 @@ COMMON_SRCS = $(UTILITY_SRCS) $(PROBE_SRCS)
 UTILITY_SRCS =                         \
        ./helper/libdaprobe.c           \
        ./helper/dahelper.c             \
+       ./helper/btsym.c                \
        ./helper/dacollection.c         \
        ./helper/dacapture.c            \
        ./helper/daforkexec.c           \
diff --git a/helper/btsym.c b/helper/btsym.c
new file mode 100755 (executable)
index 0000000..95f01e7
--- /dev/null
@@ -0,0 +1,481 @@
+/* Return list with names for address in backtrace.
+   Copyright (C) 1998,1999,2000,2001,2003,2009 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+
+/*
+2011-12-15 Jaewon Lim <jaewon81.lim@samsung.com> add hashing for symbols
+
+2011-12-08 Jaewon Lim <jaewon81.lim@samsung.com> get symbol data from binary's symtab when dladdr cannot resolve symbol
+*/
+
+#include <assert.h>            // for assert
+#include <stdio.h>             // for printf, sprintf
+#include <stdlib.h>            // for malloc
+#include <string.h>            // for strlen
+#include <stddef.h>            // for ptrdiff_t
+#include <errno.h>             // for program_invocation_name
+
+#include <sys/types.h> // for open, fstat
+#include <sys/stat.h>  // for open, fstat
+#include <fcntl.h>             // for open
+#include <unistd.h>            // for fstat
+#include <sys/mman.h>  // for mmap, munmap
+
+#include "private_link.h"              // for link_map, ElfW
+#include "dahelper.h"
+#include "dacollection.h"
+
+#if __ELF_NATIVE_CLASS == 32
+# define WORD_WIDTH 8
+#else
+/* We assyme 64bits.  */
+# define WORD_WIDTH 16
+#endif
+
+#define FILEPATH_MAX 1024
+
+/* We use this macro to refer to ELF types independent of the native wordsize.
+   'ElfW(TYPE)' is used in place of 'Elf32_TYPE' or 'Elf64_TYPE'.  */
+#define ELFW(type)  _ElfW (ELF, __ELF_NATIVE_CLASS, type)
+
+/* Result of the lookup functions and how to retrieve the base address.  */
+typedef struct link_map *lookup_t;
+#define LOOKUP_VALUE(map) map
+#define LOOKUP_VALUE_ADDRESS(map) ((map) ? (map)->l_addr : 0)
+
+/* On some architectures a pointer to a function is not just a pointer
+   to the actual code of the function but rather an architecture
+   specific descriptor. */
+#ifndef ELF_FUNCTION_PTR_IS_SPECIAL
+# define DL_SYMBOL_ADDRESS(map, ref) \
+       (void *) (LOOKUP_VALUE_ADDRESS (map) + ref->st_value)
+# define DL_LOOKUP_ADDRESS(addr) ((ElfW(Addr)) (addr))
+# define DL_DT_INIT_ADDRESS(map, start) (start)
+# define DL_DT_FINI_ADDRESS(map, start) (start)
+#endif
+
+/* On some architectures dladdr can't use st_size of all symbols this way.  */
+#define DL_ADDR_SYM_MATCH(L, SYM, ADDR) \
+       (((ADDR) >= (L)->l_addr + (SYM)->st_value)              \
+               && ((((SYM)->st_shndx == SHN_UNDEF || (SYM)->st_size == 0)       \
+                       && ((ADDR) == (L)->l_addr + (SYM)->st_value))         \
+                       || ((ADDR) < (L)->l_addr + (SYM)->st_value + (SYM)->st_size)))
+
+// start of implementation by Jaewon Lim
+struct _symdata
+{
+       ElfW(Shdr)      symhdr;
+       ElfW(Shdr)      strhdr;
+       ElfW(Sym)*      symtab;
+       char*           strtab;
+};
+
+typedef struct _symdata symdata_t;
+
+// get symbol data from file binary
+static symdata_t* _get_symboldata(char* filepath)
+{
+       int fd;
+       struct stat st;
+       char *contents;
+       symdata_t* pdata;
+
+       // first find in glist
+       pdata = (symdata_t*)find_glist(filepath);
+       if(pdata != NULL)
+       {
+               return pdata;
+       }
+
+       fd = open(filepath, O_RDONLY | O_CLOEXEC);
+       if(fd == -1)
+       {
+               return pdata;
+       }
+
+       if(fstat(fd, &st) == -1)
+       {
+               close(fd);
+               return pdata;
+       }
+
+       contents = (char*)mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
+       if(likely(contents != NULL))
+       {
+               ElfW(Ehdr) * elf_hdr = (ElfW(Ehdr) *)(contents);
+               ElfW(Shdr) * sec_hdr = (ElfW(Shdr) *)(contents + elf_hdr->e_shoff);
+               int i, symtab_idx = -1;
+
+               for (i = 0; i < elf_hdr->e_shnum; ++i)
+               {
+                       if(unlikely(sec_hdr[i].sh_type == SHT_SYMTAB))
+                       {
+                               symtab_idx = i;
+                               break;
+                       }
+               }
+
+               if(symtab_idx != -1)    //there is symbol table
+               {
+                       int strtab_idx = sec_hdr[symtab_idx].sh_link;
+                       if(likely((strtab_idx != 0) && (sec_hdr[strtab_idx].sh_type == SHT_STRTAB)))    // associated string table is valid
+                       {
+                               pdata = (symdata_t*)malloc(sizeof(symdata_t) +
+                                               sec_hdr[symtab_idx].sh_size +
+                                               sec_hdr[strtab_idx].sh_size);
+
+                               if(likely(pdata != NULL))
+                               {
+                                       memcpy(&(pdata->symhdr), &(sec_hdr[symtab_idx]), sizeof(ElfW(Shdr)));
+                                       memcpy(&(pdata->strhdr), &(sec_hdr[strtab_idx]), sizeof(ElfW(Shdr)));
+                                       pdata->symtab = (ElfW(Sym) *)(pdata + 1);
+                                       pdata->strtab = ((char*)pdata) + sizeof(symdata_t) + sec_hdr[symtab_idx].sh_size;
+                                       memcpy((void*)(pdata->symtab), (void*)(contents + sec_hdr[symtab_idx].sh_offset), sec_hdr[symtab_idx].sh_size);
+                                       memcpy((void*)(pdata->strtab), (void*)(contents + sec_hdr[strtab_idx].sh_offset), sec_hdr[strtab_idx].sh_size);
+
+                                       if(add_to_glist(filepath, (void*)pdata) == 0)   // fail to add
+                                       {
+                                               free(pdata);
+                                               pdata = NULL;
+                                       }
+                               }
+                       }
+               }
+
+               munmap((void*)contents, st.st_size);
+       }
+
+       close(fd);
+
+       return pdata;
+}
+
+int get_map_address(void* symbol, void** map_start, void** map_end)
+{
+       Dl_info info;
+       int status, ret = 0;
+       struct link_map* map = NULL;
+
+       status = dladdr1(symbol, &info, (void**)&map, RTLD_DL_LINKMAP);
+       if(status && map != NULL)
+       {
+               *map_start = (void*)(map->l_map_start);
+               *map_end = (void*)(map->l_map_end);
+               ret = 1;
+       }
+       else
+               ret = 0;
+
+       return ret;
+}
+
+// end of implementation by Jaewon Lim
+
+char** cached_backtrace_symbols (void* const* array, int size)
+{
+       Dl_info info[MAX_STACK_DEPTH];
+       int status[MAX_STACK_DEPTH];
+       char* chararr[MAX_STACK_DEPTH];
+       int cnt;
+       size_t total = 0;
+       char **result;
+       char* foundsym;
+
+       memset(chararr, 0, MAX_STACK_DEPTH * sizeof(char*));
+
+       /* Fill in the information we can get from `dladdr'.  */
+       for (cnt = 0; cnt < size; ++cnt)
+       {
+               struct link_map* map;
+
+               if(find_symbol_hash(array[cnt], &foundsym) <= 0)        // not found or error
+               {
+                       status[cnt] = dladdr1 (array[cnt], &info[cnt], (void**)&map, RTLD_DL_LINKMAP);
+                       if (status[cnt] && info[cnt].dli_fname && info[cnt].dli_fname[0] != '\0')
+                       {
+                               /* We have some info, compute the length of the string which will be
+                               "<file-name>(<sym-name>+offset) [address].  */
+                               total += (strlen (info[cnt].dli_fname ?: "")
+                                               + strlen (info[cnt].dli_sname ?: "")
+                                               + 3 + WORD_WIDTH + 3 + WORD_WIDTH + 5);
+
+                               /* The load bias is more useful to the user than the load
+                               address.  The use of these addresses is to calculate an
+                               address in the ELF file, so its prelinked bias is not
+                               something we want to subtract out.  */
+                               info[cnt].dli_fbase = (void *) map->l_addr;
+                       }
+                       else
+                               total += 5 + WORD_WIDTH;
+               }
+               else            // there is a entry for key
+               {
+                       status[cnt] = 0;
+                       chararr[cnt] = foundsym;
+                       if(chararr[cnt] != NULL)
+                               total += (strlen(chararr[cnt]) + 1);
+                       else
+                       {
+                               // this never happened
+                               total += 100;
+                       }
+               }
+       }
+
+       /* Allocate memory for the result.  */
+       result = (char **) malloc (size * sizeof (char *) + total);
+       if (result != NULL)
+       {
+               char *last = (char *) (result + size);
+
+               for (cnt = 0; cnt < size; ++cnt)
+               {
+                       result[cnt] = last;
+
+                       if(chararr[cnt] != NULL)                // there is a cache
+                       {
+                               last += (1 + sprintf(last, "%s", chararr[cnt]));
+                       }
+                       else            // there is no cache
+                       {
+                               int tstrlen;
+                               if (status[cnt] && info[cnt].dli_fname != NULL && info[cnt].dli_fname[0] != '\0')
+                               {
+                                       // We found no symbol name to use, so describe it as relative to the file.
+                                       if (info[cnt].dli_sname == NULL)
+                                               info[cnt].dli_saddr = info[cnt].dli_fbase;
+
+                                       if (info[cnt].dli_sname == NULL && info[cnt].dli_saddr == 0)
+                                       {
+                                               tstrlen = sprintf (last, "%s(%s) [%p]", info[cnt].dli_fname ?: "", info[cnt].dli_sname ?: "", array[cnt]);
+                                       }
+                                       else
+                                       {
+                                               char sign;
+                                               ptrdiff_t offset;
+                                               if (array[cnt] >= (void *) info[cnt].dli_saddr)
+                                               {
+                                                       sign = '+';
+                                                       offset = array[cnt] - info[cnt].dli_saddr;
+                                               }
+                                               else
+                                               {
+                                                       sign = '-';
+                                                       offset = info[cnt].dli_saddr - array[cnt];
+                                               }
+
+                                               tstrlen = sprintf (last, "%s(%s%c%#tx) [%p]",
+                                                               info[cnt].dli_fname ?: "",
+                                                               info[cnt].dli_sname ?: "",
+                                                               sign, offset, array[cnt]);
+                                       }
+                               }
+                               else
+                               {
+                                       tstrlen = sprintf (last, "[%p]", array[cnt]);
+                               }
+                               tstrlen++;
+
+                               add_symbol_hash(array[cnt], last, tstrlen);
+
+                               last += tstrlen;
+                       }
+               }
+
+               assert (last <= (char *) result + size * sizeof (char *) + total);
+       }
+       else            // fail to malloc
+       {
+               // do nothing
+       }
+
+       return result;
+}
+
+char** da_backtrace_symbols (void* const* array, int size)
+{
+       Dl_info info[MAX_STACK_DEPTH];
+       int status[MAX_STACK_DEPTH];
+       char* chararr[MAX_STACK_DEPTH];
+       int cnt;
+       size_t total = 0;
+       char **result;
+       char* foundsym;
+
+       memset(chararr, 0, MAX_STACK_DEPTH * sizeof(char*));
+
+       /* Fill in the information we can get from `dladdr'.  */
+       for (cnt = 0; cnt < size; ++cnt)
+       {
+               struct link_map* map;
+
+               if(find_symbol_hash(array[cnt], &foundsym) <= 0)        // not found or error
+               {
+                       status[cnt] = dladdr1 (array[cnt], &info[cnt], (void**)&map, RTLD_DL_LINKMAP);
+                       if(info[cnt].dli_sname == NULL)
+                       {
+                               char filepath[FILEPATH_MAX];    // for file path
+
+                               /* If this is the main program the information is incomplete.  */
+                               if (map->l_name[0] == '\0' && map->l_type == lt_executable)
+                               {
+                                       strncpy(filepath, program_invocation_name, FILEPATH_MAX - 1);
+                               }
+                               else
+                               {
+                                       int len;
+                                       if(map->l_origin)
+                                       {
+                                               strcpy(filepath, map->l_origin);
+                                               len = strlen(filepath);
+                                               if(len > 0 && filepath[len-1] != '/')
+                                               {
+                                                       filepath[len] = '/';
+                                                       filepath[len+1] = '\0';
+                                               }
+                                       }
+                                       else
+                                               filepath[0] = '\0';
+                                       strcat(filepath, map->l_name);
+                               }
+
+                               symdata_t* pdata = _get_symboldata(filepath);
+                               if(pdata != NULL)
+                               {
+                                       ElfW(Sym) * sym_ent = pdata->symtab;
+                                       char* strtab = pdata->strtab;
+                                       int i, num_syms = pdata->symhdr.sh_size / pdata->symhdr.sh_entsize;
+
+                                       for(i = 0; i < num_syms; ++i)
+                                       {
+                                               if (ELFW(ST_TYPE) (sym_ent[i].st_info) != STT_TLS
+                                                               && (sym_ent[i].st_shndx != SHN_UNDEF || sym_ent[i].st_value != 0)
+                                                               && DL_ADDR_SYM_MATCH (map, &(sym_ent[i]), DL_LOOKUP_ADDRESS (array[cnt]))
+                                                               && sym_ent[i].st_name < pdata->strhdr.sh_size)
+                                               {
+                                                       // We found a symbol close by.  Fill in its name and exact address.
+                                                       info[cnt].dli_sname = strtab + ((ElfW(Sym) *)(sym_ent + i))->st_name;
+                                                       info[cnt].dli_saddr = DL_SYMBOL_ADDRESS (map, ((ElfW(Sym) *)(sym_ent + i)));
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+
+                       if (status[cnt] && info[cnt].dli_fname && info[cnt].dli_fname[0] != '\0')
+                       {
+                               /* We have some info, compute the length of the string which will be
+                               "<file-name>(<sym-name>+offset) [address].  */
+                               total += (strlen (info[cnt].dli_fname ?: "")
+                                               + strlen (info[cnt].dli_sname ?: "")
+                                               + 3 + WORD_WIDTH + 3 + WORD_WIDTH + 5);
+
+                               /* The load bias is more useful to the user than the load
+                               address.  The use of these addresses is to calculate an
+                               address in the ELF file, so its prelinked bias is not
+                               something we want to subtract out.  */
+//                             info[cnt].dli_fbase = (void *) map->l_addr;
+                       }
+                       else
+                               total += 5 + WORD_WIDTH;
+               }
+               else            // there is a entry for key
+               {
+                       chararr[cnt] = foundsym;
+                       if(chararr[cnt] != NULL)
+                               total += (strlen(chararr[cnt]) + 1);
+                       else
+                       {
+                               assert(false);
+                               total += 100;
+                       }
+               }
+       }
+
+       /* Allocate memory for the result.  */
+       result = (char **) malloc (size * sizeof (char *) + total);
+       if (result != NULL)
+       {
+               char *last = (char *) (result + size);
+
+               for (cnt = 0; cnt < size; ++cnt)
+               {
+                       result[cnt] = last;
+
+                       if(chararr[cnt] != NULL)                // there is a cache
+                       {
+                               last += (1 + sprintf(last, "%s", chararr[cnt]));
+                       }
+                       else            // there is no cache
+                       {
+                               int tstrlen;
+                               if (status[cnt] && info[cnt].dli_fname != NULL && info[cnt].dli_fname[0] != '\0')
+                               {
+                                       // We found no symbol name to use, so describe it as relative to the file.
+                                       if (info[cnt].dli_sname == NULL)
+                                               info[cnt].dli_saddr = info[cnt].dli_fbase;
+
+                                       if (info[cnt].dli_sname == NULL && info[cnt].dli_saddr == 0)
+                                       {
+                                               tstrlen = sprintf (last, "%s(%s) [%p]", info[cnt].dli_fname ?: "", info[cnt].dli_sname ?: "", array[cnt]);
+                                       }
+                                       else
+                                       {
+                                               char sign;
+                                               ptrdiff_t offset;
+                                               if (array[cnt] >= (void *) info[cnt].dli_saddr)
+                                               {
+                                                       sign = '+';
+                                                       offset = array[cnt] - info[cnt].dli_saddr;
+                                               }
+                                               else
+                                               {
+                                                       sign = '-';
+                                                       offset = info[cnt].dli_saddr - array[cnt];
+                                               }
+
+                                               tstrlen = sprintf (last, "%s(%s%c%#tx) [%p]",
+                                                               info[cnt].dli_fname ?: "",
+                                                               info[cnt].dli_sname ?: "",
+                                                               sign, offset, array[cnt]);
+                                       }
+                               }
+                               else
+                               {
+                                       tstrlen = sprintf (last, "[%p]", array[cnt]);
+                               }
+                               tstrlen++;
+
+                               add_symbol_hash(array[cnt], last, tstrlen);
+
+                               last += tstrlen;
+                       }
+               }
+
+               assert (last <= (char *) result + size * sizeof (char *) + total);
+       }
+       else            // fail to malloc
+       {
+               // do nothing
+       }
+
+       return result;
+}
+
diff --git a/helper/private_link.h b/helper/private_link.h
new file mode 100644 (file)
index 0000000..443d911
--- /dev/null
@@ -0,0 +1,374 @@
+/* Data structure for communication from the run-time dynamic linker for
+   loaded ELF shared objects.
+   Copyright (C) 1995-2006, 2007 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef        _PRIVATE_LINK_H
+#define        _PRIVATE_LINK_H 1
+
+#ifdef _LINK_H
+# error this should be impossible
+#endif
+
+/* Get most of the contents from the public header, but we define a
+   different `struct link_map' type for private use.  The la_objopen
+   prototype uses the type, so we have to declare it separately.  */
+#define link_map       link_map_public
+#define la_objopen     la_objopen_wrongproto
+#include <link.h>
+#undef link_map
+#undef la_objopen
+
+struct link_map;
+extern unsigned int la_objopen (struct link_map *__map, Lmid_t __lmid, uintptr_t *__cookie);
+
+#include <stddef.h>            // for ptrdiff_t
+//#include <tls.h>
+//#include <bits/libc-lock.h>
+
+/* Number of extra dynamic section entries for this architecture.
+   By default there are none.  */
+#define DT_THISPROCNUM  0
+
+// The type of the return value of fixup/profile_fixup.
+#define DL_FIXUP_VALUE_TYPE ElfW(Addr)
+// Construct a value of type DL_FIXUP_VALUE_TYPE from a code address and a link map.
+#define DL_FIXUP_MAKE_VALUE(map, addr) (addr)
+// Extract the code address from a value of type DL_FIXUP_MAKE_VALUE.
+#define DL_FIXUP_VALUE_CODE_ADDR(value) (value)
+#define DL_FIXUP_VALUE_ADDR(value) (value)
+#define DL_FIXUP_ADDR_VALUE(addr) (addr)
+
+struct link_map_machine
+{
+       // empty by default
+};
+
+/* Some internal data structures of the dynamic linker used in the
+   linker map.  We only provide forward declarations.  */
+
+/* For the version handling we need an array with only names and their
+   hash values.  */
+struct r_found_version
+{
+       const char *name;
+       ElfW(Word) hash;
+       int hidden;
+       const char *filename;
+};
+
+/* We want to cache information about the searches for shared objects.  */
+
+enum r_dir_status { unknown, nonexisting, existing };
+
+struct r_search_path_elem
+{
+       /* This link is only used in the `all_dirs' member of `r_search_path'.  */
+       struct r_search_path_elem *next;
+
+       /* Strings saying where the definition came from.  */
+       const char *what;
+       const char *where;
+
+       /* Basename for this search path element.  The string must end with     a slash character.  */
+       const char *dirname;
+       size_t dirnamelen;
+
+       enum r_dir_status status[0];
+};
+
+/* A data structure for a simple single linked list of strings.  */
+struct libname_list
+{
+       const char *name;       /* Name requested (before search).  */
+       struct libname_list *next;  /* Link to next name for this object.  */
+       int dont_free;      /* Flag whether this element should be freed
+                                               if the object is not entirely unloaded.  */
+};
+
+/* Forward declaration.  */
+struct link_map;
+
+/* Structure to describe a single list of scope elements.  The lookup
+   functions get passed an array of pointers to such structures.  */
+struct r_scope_elem
+{
+       /* Array of maps for the scope.  */
+       struct link_map **r_list;
+       /* Number of entries in the scope.  */
+       unsigned int r_nlist;
+};
+
+
+/* Structure to record search path and allocation mechanism.  */
+struct r_search_path_struct
+{
+       struct r_search_path_elem **dirs;
+       int malloced;
+};
+
+
+/* Structure describing a loaded shared object.  The `l_next' and `l_prev'
+   members form a chain of all the shared objects loaded at startup.
+
+   These data structures exist in space used by the run-time dynamic linker;
+   modifying them may have disastrous results.
+
+   This data structure might change in future, if necessary.  User-level
+   programs must avoid defining objects of this type.  */
+
+struct link_map
+  {
+    /* These first few members are part of the protocol with the debugger.
+       This is the same format used in SVR4.  */
+
+    ElfW(Addr) l_addr;         /* Base address shared object is loaded at.  */
+    char *l_name;              /* Absolute file name object was found in.  */
+    ElfW(Dyn) *l_ld;           /* Dynamic section of the shared object.  */
+    struct link_map *l_next, *l_prev; /* Chain of loaded objects.  */
+
+    /* All following members are internal to the dynamic linker.
+       They may change without notice.  */
+
+    /* This is an element which is only ever different from a pointer to
+       the very same copy of this type for ld.so when it is used in more
+       than one namespace.  */
+    struct link_map *l_real;
+
+    /* Number of the namespace this link map belongs to.  */
+    Lmid_t l_ns;
+
+    struct libname_list *l_libname;
+    /* Indexed pointers to dynamic section.
+       [0,DT_NUM) are indexed by the processor-independent tags.
+       [DT_NUM,DT_NUM+DT_THISPROCNUM) are indexed by the tag minus DT_LOPROC.
+       [DT_NUM+DT_THISPROCNUM,DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM) are
+       indexed by DT_VERSIONTAGIDX(tagvalue).
+       [DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM,
+       DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM) are indexed by
+       DT_EXTRATAGIDX(tagvalue).
+       [DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM,
+       DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM+DT_VALNUM) are
+       indexed by DT_VALTAGIDX(tagvalue) and
+       [DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM+DT_VALNUM,
+       DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM+DT_VALNUM+DT_ADDRNUM)
+       are indexed by DT_ADDRTAGIDX(tagvalue), see <elf.h>.  */
+
+    ElfW(Dyn) *l_info[DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM
+                     + DT_EXTRANUM + DT_VALNUM + DT_ADDRNUM];
+    const ElfW(Phdr) *l_phdr;  /* Pointer to program header table in core.  */
+    ElfW(Addr) l_entry;                /* Entry point location.  */
+    ElfW(Half) l_phnum;                /* Number of program header entries.  */
+    ElfW(Half) l_ldnum;                /* Number of dynamic segment entries.  */
+
+    /* Array of DT_NEEDED dependencies and their dependencies, in
+       dependency order for symbol lookup (with and without
+       duplicates).  There is no entry before the dependencies have
+       been loaded.  */
+    struct r_scope_elem l_searchlist;
+
+    /* We need a special searchlist to process objects marked with
+       DT_SYMBOLIC.  */
+    struct r_scope_elem l_symbolic_searchlist;
+
+    /* Dependent object that first caused this object to be loaded.  */
+    struct link_map *l_loader;
+
+    /* Array with version names.  */
+    struct r_found_version *l_versions;
+    unsigned int l_nversions;
+
+    /* Symbol hash table.  */
+    Elf_Symndx l_nbuckets;
+    Elf32_Word l_gnu_bitmask_idxbits;
+    Elf32_Word l_gnu_shift;
+    const ElfW(Addr) *l_gnu_bitmask;
+    union
+    {
+      const Elf32_Word *l_gnu_buckets;
+      const Elf_Symndx *l_chain;
+    };
+    union
+    {
+      const Elf32_Word *l_gnu_chain_zero;
+      const Elf_Symndx *l_buckets;
+    };
+
+    unsigned int l_direct_opencount; /* Reference count for dlopen/dlclose.  */
+    enum                       /* Where this object came from.  */
+      {
+       lt_executable,          /* The main executable program.  */
+       lt_library,             /* Library needed by main executable.  */
+       lt_loaded               /* Extra run-time loaded shared object.  */
+      } l_type:2;
+    unsigned int l_relocated:1;        /* Nonzero if object's relocations done.  */
+    unsigned int l_init_called:1; /* Nonzero if DT_INIT function called.  */
+    unsigned int l_global:1;   /* Nonzero if object in _dl_global_scope.  */
+    unsigned int l_reserved:2; /* Reserved for internal use.  */
+    unsigned int l_phdr_allocated:1; /* Nonzero if the data structure pointed
+                                       to by `l_phdr' is allocated.  */
+    unsigned int l_soname_added:1; /* Nonzero if the SONAME is for sure in
+                                     the l_libname list.  */
+    unsigned int l_faked:1;    /* Nonzero if this is a faked descriptor
+                                  without associated file.  */
+    unsigned int l_need_tls_init:1; /* Nonzero if GL(dl_init_static_tls)
+                                      should be called on this link map
+                                      when relocation finishes.  */
+    unsigned int l_used:1;     /* Nonzero if the DSO is used.  */
+    unsigned int l_auditing:1; /* Nonzero if the DSO is used in auditing.  */
+    unsigned int l_audit_any_plt:1; /* Nonzero if at least one audit module
+                                      is interested in the PLT interception.*/
+    unsigned int l_removed:1;  /* Nozero if the object cannot be used anymore
+                                  since it is removed.  */
+    unsigned int l_contiguous:1; /* Nonzero if inter-segment holes are
+                                   mprotected or if no holes are present at
+                                   all.  */
+
+    /* Collected information about own RPATH directories.  */
+    struct r_search_path_struct l_rpath_dirs;
+
+    /* Collected results of relocation while profiling.  */
+    struct reloc_result
+    {
+      DL_FIXUP_VALUE_TYPE addr;
+      struct link_map *bound;
+      unsigned int boundndx;
+      uint32_t enterexit;
+      unsigned int flags;
+    } *l_reloc_result;
+
+    /* Pointer to the version information if available.  */
+    ElfW(Versym) *l_versyms;
+
+    /* String specifying the path where this object was found.  */
+    const char *l_origin;
+
+    /* Start and finish of memory map for this object.  l_map_start
+       need not be the same as l_addr.  */
+    ElfW(Addr) l_map_start, l_map_end;
+    /* End of the executable part of the mapping.  */
+    ElfW(Addr) l_text_end;
+
+    /* Default array for 'l_scope'.  */
+    struct r_scope_elem *l_scope_mem[4];
+    /* Size of array allocated for 'l_scope'.  */
+    size_t l_scope_max;
+    /* This is an array defining the lookup scope for this link map.
+       There are initially at most three different scope lists.  */
+    struct r_scope_elem **l_scope;
+
+    /* A similar array, this time only with the local scope.  This is
+       used occasionally.  */
+    struct r_scope_elem *l_local_scope[2];
+
+    /* This information is kept to check for sure whether a shared
+       object is the same as one already loaded.  */
+    dev_t l_dev;
+    ino64_t l_ino;
+
+    /* Collected information about own RUNPATH directories.  */
+    struct r_search_path_struct l_runpath_dirs;
+
+    /* List of object in order of the init and fini calls.  */
+    struct link_map **l_initfini;
+
+    /* List of the dependencies introduced through symbol binding.  */
+    unsigned int l_reldepsmax;
+    struct link_map_reldeps
+      {
+       unsigned int act;
+       struct link_map *list[];
+      } *l_reldeps;
+
+    /* Various flag words.  */
+    ElfW(Word) l_feature_1;
+    ElfW(Word) l_flags_1;
+    ElfW(Word) l_flags;
+
+    /* Temporarily used in `dl_close'.  */
+    int l_idx;
+
+    struct link_map_machine l_mach;
+
+    struct
+    {
+      const ElfW(Sym) *sym;
+      int type_class;
+      struct link_map *value;
+      const ElfW(Sym) *ret;
+    } l_lookup_cache;
+
+    /* Thread-local storage related info.  */
+
+    /* Start of the initialization image.  */
+    void *l_tls_initimage;
+    /* Size of the initialization image.  */
+    size_t l_tls_initimage_size;
+    /* Size of the TLS block.  */
+    size_t l_tls_blocksize;
+    /* Alignment requirement of the TLS block.  */
+    size_t l_tls_align;
+    /* Offset of first byte module alignment.  */
+    size_t l_tls_firstbyte_offset;
+#ifndef NO_TLS_OFFSET
+# define NO_TLS_OFFSET 0
+#endif
+#ifndef FORCED_DYNAMIC_TLS_OFFSET
+# if NO_TLS_OFFSET == 0
+#  define FORCED_DYNAMIC_TLS_OFFSET 1
+# elif NO_TLS_OFFSET == -1
+#  define FORCED_DYNAMIC_TLS_OFFSET -2
+# else
+#  error "FORCED_DYNAMIC_TLS_OFFSET is not defined"
+# endif
+#endif
+    /* For objects present at startup time: offset in the static TLS block.  */
+    ptrdiff_t l_tls_offset;
+    /* Index of the module in the dtv array.  */
+    size_t l_tls_modid;
+
+    /* Information used to change permission after the relocations are
+       done.  */
+    ElfW(Addr) l_relro_addr;
+    size_t l_relro_size;
+
+    unsigned long long int l_serial;
+
+    /* Audit information.  This array apparent must be the last in the
+       structure.  Never add something after it.  */
+    struct auditstate
+    {
+      uintptr_t cookie;
+      unsigned int bindflags;
+    } l_audit[0];
+  };
+
+
+#if __ELF_NATIVE_CLASS == 32
+# define symbind symbind32
+#elif __ELF_NATIVE_CLASS == 64
+# define symbind symbind64
+#else
+# error "__ELF_NATIVE_CLASS must be defined"
+#endif
+
+extern int __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
+                                              size_t size, void *data),
+                             void *data);
+
+#endif /* include/link.h */
index 1ac3d91..4daee81 100755 (executable)
@@ -192,3 +192,104 @@ Eina_Bool ecore_event_evas_mouse_move(void *data, int type, void *event)
 
        return ecore_event_evas_mouse_movep(data, type, event);
 }
+
+
+/*
+void evas_event_feed_mouse_down(Evas *e, int b, Evas_Button_Flags flags,
+               unsigned int timestamp, const void *data)
+{
+       static void (*evas_event_feed_mouse_downp)(Evas *e, int b, Evas_Button_Flags flags, unsigned int timestamp, const void *data);
+
+       probeInfo_t     probeInfo;
+
+       GET_REAL_FUNC(evas_event_feed_mouse_down, LIBEVAS);
+
+       PRE_UNCONDITIONAL_BLOCK_BEGIN();
+       HW_EVENT_LOG(_EVENT_TOUCH, _TOUCH_PRESSED, )
+       PRE_UNCONDITIONAL_BLOCK_END();
+
+
+       DECLARE_VARIABLE_EVENT;
+       int x, y;
+
+       PRE_PROBEBLOCK_BEGIN_EVENT(evas_event_feed_mouse_down, LIBEVAS, EVENT_TYPE_DOWN);
+               evas_pointer_output_xy_get(e, &x, &y);
+       PRE_PROBEBLOCK_END_EVENT();
+
+       evas_event_feed_mouse_downp(e, b, flags, timestamp, data);
+
+       AFTER_ORIGINAL_EVENT(EVENT_TYPE_DOWN, "%d", b);
+}
+
+void evas_event_feed_mouse_up(Evas *e, int b, Evas_Button_Flags flags,
+               unsigned int timestamp, const void *data)
+{
+       static void (*evas_event_feed_mouse_upp)(Evas *e, int b, Evas_Button_Flags flags, unsigned int timestamp, const void *data);
+
+       DECLARE_VARIABLE_EVENT;
+       int x, y;
+
+       PRE_PROBEBLOCK_BEGIN_EVENT(evas_event_feed_mouse_up, LIBEVAS, EVENT_TYPE_UP);
+               evas_pointer_output_xy_get(e, &x, &y);
+       PRE_PROBEBLOCK_END_EVENT();
+
+       evas_event_feed_mouse_upp(e, b, flags, timestamp, data);
+
+       AFTER_ORIGINAL_EVENT(EVENT_TYPE_UP, "%d", b);
+}
+
+void evas_event_feed_mouse_move(Evas *e, int x, int y,
+               unsigned int timestamp, const void *data)
+{
+       static void (*evas_event_feed_mouse_movep)(Evas *e, int x, int y, unsigned int timestamp, const void *data);
+
+       BEFORE_ORIGINAL_EVENT(evas_event_feed_mouse_move, LIBEVAS, EVENT_TYPE_MOVE);
+
+       evas_event_feed_mouse_movep(e, x, y, timestamp, data);
+
+       AFTER_ORIGINAL_EVENT(EVENT_TYPE_MOVE, "%u", timestamp);
+}
+
+void evas_event_feed_multi_down(Evas *e, int d, int x, int y,
+               double rad, double radx, double rady,
+               double pres, double ang, double fx, double fy,
+               Evas_Button_Flags flags, unsigned int timestamp, const void *data)
+{
+       static void (*evas_event_feed_multi_downp)(Evas *e, int d, int x, int y, double rad, double radx, double rady, double pres, double ang, double fx, double fy, Evas_Button_Flags flags, unsigned int timestamp, const void *data);
+
+       BEFORE_ORIGINAL_EVENT(evas_event_feed_multi_down, LIBEVAS, EVENT_TYPE_DOWN);
+
+       evas_event_feed_multi_downp(e, d, x, y, rad, radx,
+                       rady, pres, ang, fx, fy, flags, timestamp, data);
+
+       AFTER_ORIGINAL_EVENT(EVENT_TYPE_DOWN, "%d", d);
+}
+
+void evas_event_feed_multi_up(Evas *e, int d, int x, int y, double rad, double radx,
+               double rady, double pres, double ang, double fx, double fy,
+               Evas_Button_Flags flags, unsigned int timestamp, const void *data)
+{
+       static void (*evas_event_feed_multi_upp)(Evas *e, int d, int x, int y, double rad, double radx, double rady, double pres, double ang, double fx, double fy, Evas_Button_Flags flags, unsigned int timestamp, const void *data);
+
+       BEFORE_ORIGINAL_EVENT(evas_event_feed_multi_up, LIBEVAS, EVENT_TYPE_UP);
+
+       evas_event_feed_multi_upp(e, d, x, y, rad, radx, rady,
+                       pres, ang, fx, fy, flags, timestamp, data);
+
+       AFTER_ORIGINAL_EVENT(EVENT_TYPE_UP, "%d", d);
+}
+
+void evas_event_feed_multi_move (Evas *e, int d, int x, int y, double rad, double radx,
+               double rady, double pres, double ang, double fx, double fy,
+               unsigned int timestamp, const void *data)
+{
+       static void (*evas_event_feed_multi_movep)(Evas *e, int d, int x, int y, double rad, double radx, double rady, double pres, double ang, double fx, double fy, unsigned int timestamp, const void *data);
+
+       BEFORE_ORIGINAL_EVENT(evas_event_feed_multi_move, LIBEVAS, EVENT_TYPE_MOVE);
+
+       evas_event_feed_multi_movep(e, d, x, y, rad, radx, rady,
+                       pres, ang, fx, fy, timestamp, data);
+
+       AFTER_ORIGINAL_EVENT(EVENT_TYPE_MOVE, "%d", d);
+}
+*/