Android’s Linker makes Baby Jesus Cry

release-1.0 branch:

static int open_library(const char *name)
{
int fd;
char buf[512];
const char **path;

TRACE("[ %5d opening %s ]\n", pid, name);

if(strlen(name) > 256) return -1;
if(name == 0) return -1;

fd = open(name, O_RDONLY);
if(fd != -1) return fd;

for(path = sopaths; *path; path++){
sprintf(buf,"%s/%s", *path, name);
fd = open(buf, O_RDONLY);
if(fd != -1) return fd;
}

return -1;
}

cupcake branch:

/* TODO: Need to add support for initializing the so search path with
* LD_LIBRARY_PATH env variable for non-setuid programs. */
static int open_library(const char *name)
{
int fd;
char buf[512];
const char **path;

TRACE("[ %5d opening %s ]\n", pid, name);

if(name == 0) return -1;
if(strlen(name) > 256) return -1;

if ((name[0] == '/') && ((fd = _open_lib(name)) >= 0))
return fd;

for (path = sopaths; *path; path++) {
snprintf(buf, sizeof(buf), "%s/%s", *path, name);
if ((fd = _open_lib(buf)) >= 0)
return fd;
}

return -1;
}

Summary: Android’s linker used to look in the current working directory to resolve library references. Now it doesn’t. (And it never used LD_LIBRARY_PATH at all) This is really only annoying for 3rd party command line applications which have references to libraries that aren’t part of the standard Android build (and contained in /system/lib). I need to figure out how to make gcc, et al, create binaries that store the full path to the libraries they reference, rather than just the base file name...

Edit: I tried patching it to use LD_LIBRARY_PATH, but calling getenv from within the linker would always return NULL. Not sure why. So I did the next best thing and added “.” to the list of search paths. I think that is default behavior anyways on other Linux based systems (will verify later). Submitted the change, hope it gets accepted.

4 comments:

Tim said...

Wow that's some bad code. Well at least they fixed some of the glaring bugs...

cjcollier said...

chrpath ?

$ chrpath
Usage: chrpath [-v|-d|-c|-r <path>] <program> [<program> ...]

-v|--version Display program version number
-d|--delete Delete current rpath/runpath setting
-c|--convert Convert rpath to runpath
-r <path>|--replace <path> Replace current rpath/runpath setting
with the path given
-l|--list List the current rpath/runpath (default)
-h|--help Show this usage information.

Anonymous said...

Please refrain from using our God's name in vain.. Have respect.. Thanks..

Marcos Dione said...

where can I find the patch for android's linker? I cloned the repo in git://github.com/koush/androidmono.git and looked there, but didn't find anything.