#include <gnu/lib-names.h>
#endif
+#ifdef TIZEN_ASAN_ENVIRONMENT
+#include "tizenasanenvmodule.h"
+#endif // TIZEN_ASAN_ENVIRONMENT
+
using namespace CorUnix;
// In safemath.h, Template SafeInt uses macro _ASSERTE, which need to use variable
PERF_EXIT(PAL_UnregisterModule);
}
+#ifdef TIZEN_ASAN_ENVIRONMENT
+PALIMPORT
+BOOL
+PALAPI
+PAL_IsSanitizedModule(
+ IN HINSTANCE hInstance)
+{
+ return ((MODSTRUCT *)hInstance)->is_sanitized;
+}
+#endif // TIZEN_ASAN_ENVIRONMENT
+
/*++
PAL_LOADLoadPEFile
#else // NEED_DLCOMPAT
module->refcount = 1;
#endif // NEED_DLCOMPAT
+
+#ifdef TIZEN_ASAN_ENVIRONMENT
+ module->is_sanitized = FALSE;
+#endif // TIZEN_ASAN_ENVIRONMENT
module->self = module;
module->hinstance = nullptr;
module->threadLibCalls = TRUE;
exe_module.prev->next = module;
exe_module.prev = module;
+#ifdef TIZEN_ASAN_ENVIRONMENT
+ module->is_sanitized = module_is_sanitized(dl_handle);
+#endif // TIZEN_ASAN_ENVIRONMENT
+
#if RETURNS_NEW_HANDLES_ON_REPEAT_DLOPEN
module->inode = stat_buf.st_ino;
module->device = stat_buf.st_dev;
--- /dev/null
+#include <string.h>
+#include "pal.h"
+#include "llvm/ELF.h"
+#include "tizenasanenvmodule.h"
+
+#include <bits/wordsize.h>
+
+#define __ELF_WORD_SIZE __WORDSIZE
+
+#define __ELF_CONCAT1(x,y) x ## y
+#define __ELF_CONCAT(x,y) __ELF_CONCAT1(x,y)
+
+#define __ElfN(x) __ELF_CONCAT(__ELF_CONCAT( \
+ __ELF_CONCAT(Elf,__ELF_WORD_SIZE), \
+ _), \
+ x)
+#define __ElfType(x) typedef __ElfN(x) __ELF_CONCAT(Elf_,x)
+
+/*
+ * Request arguments for dlinfo().
+ */
+#define RTLD_DI_LINKMAP 2 /* Obtain link map. */
+
+struct link_map {
+ __ElfN(Addr) l_addr; /* Base Address of library */
+ const char *l_name; /* Absolute Path to Library */
+ __ElfN(Dyn) *l_ld; /* Pointer to .dynamic in memory */
+ struct link_map *l_next, *l_prev; /* linked list of of mapped libs */
+};
+
+extern "C" int dlinfo(void *handle, int request, void *info);
+
+
+struct plt_sym_resolver {
+ void *dl_handle;
+ struct link_map *lm;
+ __ElfN(Dyn) *dynamic; // .dynamic section
+ __ElfN(Sym) *dynsym; // .dynsym section
+ char *dynstr; // .dynstr section
+ long reltype; // relocation type
+ size_t pltrel_size; // size of .rel(a).plt section
+ void *jmprel; // .rel(a).plt section. Exact relocation
+ // type is resolved at runtime
+
+ plt_sym_resolver(void *handle)
+ : dl_handle(handle), lm(nullptr), dynamic(nullptr), dynsym(nullptr),
+ dynstr(nullptr), reltype(-1), pltrel_size(0), jmprel(nullptr)
+ {
+ if (handle == nullptr ||
+ dlinfo(handle, RTLD_DI_LINKMAP, &lm) < 0 ||
+ lm == nullptr)
+ return;
+ dynamic = lm->l_ld;
+ }
+
+ void walk_dynamic_section()
+ {
+ if (dynamic == nullptr)
+ return;
+
+ for (__ElfN(Dyn) *dyn = dynamic; dyn->d_tag != DT_NULL; dyn++) {
+ switch (dyn->d_tag) {
+ case DT_SYMTAB:
+ dynsym = reinterpret_cast<__ElfN(Sym) *>(dyn->d_un.d_ptr);
+ break;
+ case DT_STRTAB:
+ dynstr = reinterpret_cast<char *>(dyn->d_un.d_ptr);
+ break;
+ case DT_JMPREL:
+ jmprel = reinterpret_cast<void *>(dyn->d_un.d_ptr);
+ break;
+ case DT_PLTRELSZ:
+ pltrel_size = dyn->d_un.d_val;
+ break;
+ case DT_PLTREL:
+ reltype = dyn->d_un.d_val;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ bool symbol_is_available(const char *sym) const
+ {
+ if (jmprel == nullptr)
+ return false;
+
+ switch (reltype) {
+ case DT_REL:
+ return do_symbol_is_available(reinterpret_cast<__ElfN(Rel) *>(jmprel), sym);
+ break;
+ case DT_RELA:
+ return do_symbol_is_available(reinterpret_cast<__ElfN(Rela) *>(jmprel), sym);
+ break;
+ default: // no relocations
+ break;
+ }
+ return false;
+ }
+
+private:
+ plt_sym_resolver();
+
+ template<typename Rel>
+ bool do_symbol_is_available(const Rel *rel_table, const char *sym) const
+ {
+ if (rel_table == nullptr || pltrel_size == 0)
+ return false;
+
+ size_t rel_cnt = pltrel_size / sizeof(Rel);
+ for (const Rel *rel = rel_table, *rel_end = rel_table + rel_cnt;
+ rel < rel_end; rel++) {
+ if (strcmp(sym, rel_to_symname(rel)) == 0)
+ return true;
+ }
+
+ return false;
+ }
+
+ template<typename Rel>
+ inline char *rel_to_symname(const Rel *rel) const
+ {
+ return dynstr + dynsym[rel->getSymbol()].st_name;
+ }
+};
+
+BOOL module_is_sanitized(void *handle)
+{
+ plt_sym_resolver psr(handle);
+ psr.walk_dynamic_section();
+ return psr.symbol_is_available("__asan_init") ? TRUE : FALSE;
+}