diff options
author | Logan Chien <loganchien@google.com> | 2012-03-27 17:13:35 +0800 |
---|---|---|
committer | Logan Chien <loganchien@google.com> | 2012-03-27 17:13:38 +0800 |
commit | 5cfca93f7c7279365114e8feded33b94dbcd38c6 (patch) | |
tree | 4acf1514a1b1a423e72d07322a009073e9188a49 | |
parent | aaf2b9cdd3b76565d5f194ce52032d38849e0a17 (diff) | |
download | linkloader-5cfca93f7c7279365114e8feded33b94dbcd38c6.tar.gz |
Split rsloaderCreateExec into 2 functions.
In some scenerio, such as cross-compilation, we have to
load the ELF object file but not relocate them. Thus,
we are going to provide 2 functions:
1. rsloaderLoadExecutable
2. rsloaderRelocateExecutable
So that we can load the executable WITHOUT relocation.
The behavior of rsloaderCreateExec is remained unchanged
in this commit, though rsloaderCreateExec will become
the composition of these 2 functions.
Change-Id: Idb64aa77ac53161aa95879ccad8f46ce56c1d993
-rw-r--r-- | android/librsloader.cpp | 38 | ||||
-rw-r--r-- | android/librsloader.h | 10 |
2 files changed, 36 insertions, 12 deletions
diff --git a/android/librsloader.cpp b/android/librsloader.cpp index 1af18f7..e0004f2 100644 --- a/android/librsloader.cpp +++ b/android/librsloader.cpp @@ -36,12 +36,25 @@ static inline ELFObject<32> *unwrap(RSExecRef object) { return reinterpret_cast<ELFObject<32> *>(object); } -extern "C" RSExecRef -rsloaderCreateExec(unsigned char const *buf, - size_t buf_size, - void *(*find_symbol)(void *, char const *), - void *find_symbol_context) { +extern "C" RSExecRef rsloaderCreateExec(unsigned char const *buf, + size_t buf_size, + RSFindSymbolFn find_symbol, + void *find_symbol_context) { + RSExecRef object = rsloaderLoadExecutable(buf, buf_size); + if (!object) { + return NULL; + } + + if (!rsloaderRelocateExecutable(object, find_symbol, find_symbol_context)) { + rsloaderDisposeExec(object); + return NULL; + } + + return object; +} +extern "C" RSExecRef rsloaderLoadExecutable(unsigned char const *buf, + size_t buf_size) { ArchiveReaderLE AR(buf, buf_size); llvm::OwningPtr<ELFObject<32> > object(ELFObject<32>::read(AR)); @@ -50,15 +63,18 @@ rsloaderCreateExec(unsigned char const *buf, return NULL; } - //object->print(); - object->relocate(find_symbol, find_symbol_context); - if (object->getMissingSymbols()) { - return NULL; - } - return wrap(object.take()); } +extern "C" int rsloaderRelocateExecutable(RSExecRef object_, + RSFindSymbolFn find_symbol, + void *find_symbol_context) { + ELFObject<32>* object = unwrap(object_); + + object->relocate(find_symbol, find_symbol_context); + return (object->getMissingSymbols() == 0); +} + extern "C" void rsloaderUpdateSectionHeaders(RSExecRef object_, unsigned char *buf) { ELFObject<32> *object = unwrap(object_); diff --git a/android/librsloader.h b/android/librsloader.h index e12fe63..ab8361a 100644 --- a/android/librsloader.h +++ b/android/librsloader.h @@ -25,12 +25,20 @@ extern "C" { struct RSExecOpaque; typedef struct RSExecOpaque *RSExecRef; +typedef void *(*RSFindSymbolFn)(void *, char const *); RSExecRef rsloaderCreateExec(unsigned char const *buf, size_t buf_size, - void *(*find_symbol)(void *, char const *), + RSFindSymbolFn find_symbol, void *find_symbol_context); +RSExecRef rsloaderLoadExecutable(unsigned char const *buf, + size_t buf_size); + +int rsloaderRelocateExecutable(RSExecRef object, + RSFindSymbolFn find_symbol, + void *find_symbol_context); + void rsloaderUpdateSectionHeaders(RSExecRef object, unsigned char *buf); void rsloaderDisposeExec(RSExecRef object); |