From 7e5a8cc5230dcc027686813e51a1b001cee4c602 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Tue, 18 Jun 2013 13:15:00 -0700 Subject: [PATCH] Make LD_PRELOAD failures just warnings. This matches glibc and makes life easier for developers who want to sometimes preload a library from init (which has no conditionals); they can simply move/remove the library to disable. Change-Id: I579b8633f958235af6e46bb53b378b9e363afb1f --- linker/linker.cpp | 15 ++++++++------- linker/linker.h | 11 ++++++++++- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/linker/linker.cpp b/linker/linker.cpp index 80dc62437..c53d52f68 100644 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -1492,18 +1492,19 @@ static bool soinfo_link_image(soinfo* si) { return false; } - /* if this is the main executable, then load all of the preloads now */ + // If this is the main executable, then load all of the libraries from LD_PRELOAD now. if (si->flags & FLAG_EXE) { memset(gLdPreloads, 0, sizeof(gLdPreloads)); + size_t preload_count = 0; for (size_t i = 0; gLdPreloadNames[i] != NULL; i++) { soinfo* lsi = find_library(gLdPreloadNames[i]); - if (lsi == NULL) { - strlcpy(tmp_err_buf, linker_get_error_buffer(), sizeof(tmp_err_buf)); - DL_ERR("could not load library \"%s\" needed by \"%s\"; caused by %s", - gLdPreloadNames[i], si->name, tmp_err_buf); - return false; + if (lsi != NULL) { + gLdPreloads[preload_count++] = lsi; + } else { + // As with glibc, failure to load an LD_PRELOAD library is just a warning. + DL_WARN("could not load library \"%s\" from LD_PRELOAD for \"%s\"; caused by %s", + gLdPreloadNames[i], si->name, linker_get_error_buffer()); } - gLdPreloads[i] = lsi; } } diff --git a/linker/linker.h b/linker/linker.h index 61d623a96..200a68277 100644 --- a/linker/linker.h +++ b/linker/linker.h @@ -43,7 +43,16 @@ __libc_format_buffer(linker_get_error_buffer(), linker_get_error_buffer_size(), fmt, ##x); \ /* If LD_DEBUG is set high enough, log every dlerror(3) message. */ \ DEBUG("%s\n", linker_get_error_buffer()); \ - } while(0) + } while (false) + +#define DL_WARN(fmt, x...) \ + do { \ + __libc_format_log(ANDROID_LOG_WARN, "linker", fmt, ##x); \ + __libc_format_fd(2, "WARNING: linker: "); \ + __libc_format_fd(2, fmt, ##x); \ + __libc_format_fd(2, "\n"); \ + } while (false) + // Returns the address of the page containing address 'x'. #define PAGE_START(x) ((x) & PAGE_MASK)