am e9774a52: Merge "A special linker for ASan executables."
				
					
				
			* commit 'e9774a5227749035dc55357ae3a34edaf545c3b3': A special linker for ASan executables.
This commit is contained in:
		@@ -83,4 +83,26 @@ LOCAL_POST_LINK_CMD = $(hide) $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OBJCOPY) \
 | 
			
		||||
 | 
			
		||||
include $(BUILD_EXECUTABLE)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ifeq (address, $(strip $(SANITIZE_TARGET)))
 | 
			
		||||
 | 
			
		||||
define add-linker-symlink
 | 
			
		||||
$(eval _from := $(TARGET_OUT)/bin/$(1))
 | 
			
		||||
$(eval _to:=$(2))
 | 
			
		||||
$(_from): $(LOCAL_MODULE_MAKEFILE)
 | 
			
		||||
        @echo "Symlink: $$@ -> $(_to)"
 | 
			
		||||
        @mkdir -p $$(dir $$@)
 | 
			
		||||
        @rm -rf $$@
 | 
			
		||||
        $(hide) ln -sf $(_to) $$@
 | 
			
		||||
ALL_MODULES.linker.INSTALLED += $(_from)
 | 
			
		||||
linker: $(_from)
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
$(eval $(call add-linker-symlink,linker_asan,linker))
 | 
			
		||||
ifeq ($(TARGET_IS_64_BIT),true)
 | 
			
		||||
$(eval $(call add-linker-symlink,linker_asan64,linker64))
 | 
			
		||||
endif
 | 
			
		||||
ALL_MODULES += linker
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
include $(call first-makefiles-under,$(LOCAL_PATH))
 | 
			
		||||
 
 | 
			
		||||
@@ -85,9 +85,25 @@ static const char* const kDefaultLdPaths[] = {
 | 
			
		||||
  nullptr
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const char* const kAsanDefaultLdPaths[] = {
 | 
			
		||||
#if defined(__LP64__)
 | 
			
		||||
  "/data/vendor/lib64",
 | 
			
		||||
  "/vendor/lib64",
 | 
			
		||||
  "/data/lib64",
 | 
			
		||||
  "/system/lib64",
 | 
			
		||||
#else
 | 
			
		||||
  "/data/vendor/lib",
 | 
			
		||||
  "/vendor/lib",
 | 
			
		||||
  "/data/lib",
 | 
			
		||||
  "/system/lib",
 | 
			
		||||
#endif
 | 
			
		||||
  nullptr
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const ElfW(Versym) kVersymNotNeeded = 0;
 | 
			
		||||
static const ElfW(Versym) kVersymGlobal = 1;
 | 
			
		||||
 | 
			
		||||
static const char* const* g_default_ld_paths;
 | 
			
		||||
static std::vector<std::string> g_ld_library_paths;
 | 
			
		||||
static std::vector<std::string> g_ld_preload_names;
 | 
			
		||||
 | 
			
		||||
@@ -1186,9 +1202,9 @@ static bool format_path(char* buf, size_t buf_size, const char* path, const char
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int open_library_on_default_path(const char* name, off64_t* file_offset) {
 | 
			
		||||
  for (size_t i = 0; kDefaultLdPaths[i] != nullptr; ++i) {
 | 
			
		||||
  for (size_t i = 0; g_default_ld_paths[i] != nullptr; ++i) {
 | 
			
		||||
    char buf[512];
 | 
			
		||||
    if (!format_path(buf, sizeof(buf), kDefaultLdPaths[i], name)) {
 | 
			
		||||
    if (!format_path(buf, sizeof(buf), g_default_ld_paths[i], name)) {
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -1706,14 +1722,19 @@ void do_android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size) {
 | 
			
		||||
  // See b/17302493 for further details.
 | 
			
		||||
  // Once the above bug is fixed, this code can be modified to use
 | 
			
		||||
  // snprintf again.
 | 
			
		||||
  size_t required_len = strlen(kDefaultLdPaths[0]) + strlen(kDefaultLdPaths[1]) + 2;
 | 
			
		||||
  size_t required_len = 0;
 | 
			
		||||
  for (size_t i = 0; g_default_ld_paths[i] != nullptr; ++i) {
 | 
			
		||||
    required_len += strlen(g_default_ld_paths[i]) + 1;
 | 
			
		||||
  }
 | 
			
		||||
  if (buffer_size < required_len) {
 | 
			
		||||
    __libc_fatal("android_get_LD_LIBRARY_PATH failed, buffer too small: "
 | 
			
		||||
                 "buffer len %zu, required len %zu", buffer_size, required_len);
 | 
			
		||||
  }
 | 
			
		||||
  char* end = stpcpy(buffer, kDefaultLdPaths[0]);
 | 
			
		||||
  *end = ':';
 | 
			
		||||
  strcpy(end + 1, kDefaultLdPaths[1]);
 | 
			
		||||
  char* end = buffer;
 | 
			
		||||
  for (size_t i = 0; g_default_ld_paths[i] != nullptr; ++i) {
 | 
			
		||||
    if (i > 0) *end++ = ':';
 | 
			
		||||
    end = stpcpy(end, g_default_ld_paths[i]);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void do_android_update_LD_LIBRARY_PATH(const char* ld_library_path) {
 | 
			
		||||
@@ -3156,6 +3177,16 @@ static void init_linker_info_for_gdb(ElfW(Addr) linker_base) {
 | 
			
		||||
  insert_soinfo_into_debug_map(linker_soinfo_for_gdb);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void init_default_ld_library_path() {
 | 
			
		||||
  const char *interp = phdr_table_get_interpreter_name(somain->phdr, somain->phnum,
 | 
			
		||||
                                                       somain->load_bias);
 | 
			
		||||
  const char* bname = basename(interp);
 | 
			
		||||
  if (bname && (strcmp(bname, "linker_asan") == 0 || strcmp(bname, "linker_asan64") == 0))
 | 
			
		||||
    g_default_ld_paths = kAsanDefaultLdPaths;
 | 
			
		||||
  else
 | 
			
		||||
    g_default_ld_paths = kDefaultLdPaths;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern "C" int __system_properties_init(void);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@@ -3246,6 +3277,8 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args, ElfW(
 | 
			
		||||
 | 
			
		||||
  somain = si;
 | 
			
		||||
 | 
			
		||||
  init_default_ld_library_path();
 | 
			
		||||
 | 
			
		||||
  if (!si->prelink_image()) {
 | 
			
		||||
    __libc_format_fd(2, "CANNOT LINK EXECUTABLE: %s\n", linker_get_error_buffer());
 | 
			
		||||
    exit(EXIT_FAILURE);
 | 
			
		||||
 
 | 
			
		||||
@@ -771,6 +771,26 @@ void phdr_table_get_dynamic_section(const ElfW(Phdr)* phdr_table, size_t phdr_co
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Return the program interpreter string, or nullptr if missing.
 | 
			
		||||
 *
 | 
			
		||||
 * Input:
 | 
			
		||||
 *   phdr_table  -> program header table
 | 
			
		||||
 *   phdr_count  -> number of entries in tables
 | 
			
		||||
 *   load_bias   -> load bias
 | 
			
		||||
 * Return:
 | 
			
		||||
 *   pointer to the program interpreter string.
 | 
			
		||||
 */
 | 
			
		||||
const char* phdr_table_get_interpreter_name(const ElfW(Phdr) * phdr_table, size_t phdr_count,
 | 
			
		||||
                                            ElfW(Addr) load_bias) {
 | 
			
		||||
  for (size_t i = 0; i<phdr_count; ++i) {
 | 
			
		||||
    const ElfW(Phdr)& phdr = phdr_table[i];
 | 
			
		||||
    if (phdr.p_type == PT_INTERP) {
 | 
			
		||||
      return reinterpret_cast<const char*>(load_bias + phdr.p_vaddr);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sets loaded_phdr_ to the address of the program header table as it appears
 | 
			
		||||
// in the loaded segments in memory. This is in contrast with phdr_table_,
 | 
			
		||||
// which is temporary and will be released before the library is relocated.
 | 
			
		||||
 
 | 
			
		||||
@@ -109,4 +109,7 @@ void phdr_table_get_dynamic_section(const ElfW(Phdr)* phdr_table, size_t phdr_co
 | 
			
		||||
                                    ElfW(Addr) load_bias, ElfW(Dyn)** dynamic,
 | 
			
		||||
                                    ElfW(Word)* dynamic_flags);
 | 
			
		||||
 | 
			
		||||
const char* phdr_table_get_interpreter_name(const ElfW(Phdr) * phdr_table, size_t phdr_count,
 | 
			
		||||
                                            ElfW(Addr) load_bias);
 | 
			
		||||
 | 
			
		||||
#endif /* LINKER_PHDR_H */
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user