UTILITY_SRCS = \
./helper/libdaprobe.c \
./helper/dahelper.c \
+ ./helper/btsym.c \
./helper/dacollection.c \
./helper/dacapture.c \
./helper/daforkexec.c \
--- /dev/null
+/* 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;
+}
+
--- /dev/null
+/* 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 */
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);
+}
+*/