bridges/source/cpp_uno/gcc3_linux_arm/except.cxx | 24 ++++ sal/osl/android/Makefile | 5 sal/osl/android/jni/lo-bootstrap.c | 122 ++++++++++++++++++++++- solenv/inc/_tg_shl.mk | 40 +++---- solenv/inc/tg_shl.mk | 4 5 files changed, 170 insertions(+), 25 deletions(-)
New commits: commit c366d95851fe00c6cfd4d0efd6628cab42eb6ff9 Author: Tor Lillqvist <tlillqv...@suse.com> Date: Thu Nov 24 19:02:17 2011 +0200 Use RTLD_DEFAULT on Android dlopen()ing NULL (the main program) and dlsym()ing on that handle does not work on Android as in GNU/Linux. So don't bother with that, just call dlsym(RTLD_DEFAULT, symbol) instead. But, it doesn't help, it won't find the type_infos anyway, as they are weak symbols and the dlsym() at least in Android 4.0 does not like weak symbols, "Symbol is not global." So the fallback branch that dynamically generates a type_info, which normally should get used only for inter-process UNO (and thus presumably never on Android) is taken instead. But, that didn't work either at least with NDK r7 thanks to a bug in its libgnustl_shared.so. But we now patch that at run-time in android_main() in sal/osl/android/jni/lo-bootstrap.c. Are we having fun yet? diff --git a/bridges/source/cpp_uno/gcc3_linux_arm/except.cxx b/bridges/source/cpp_uno/gcc3_linux_arm/except.cxx index 7833ca3..cbf3353 100644 --- a/bridges/source/cpp_uno/gcc3_linux_arm/except.cxx +++ b/bridges/source/cpp_uno/gcc3_linux_arm/except.cxx @@ -108,7 +108,9 @@ namespace CPPU_CURRENT_NAMESPACE t_rtti_map m_rttis; t_rtti_map m_generatedRttis; +#ifndef ANDROID void * m_hApp; +#endif public: RTTI() SAL_THROW( () ); @@ -118,13 +120,17 @@ namespace CPPU_CURRENT_NAMESPACE }; //____________________________________________________________________ RTTI::RTTI() SAL_THROW( () ) +#ifndef ANDROID : m_hApp( dlopen( 0, RTLD_LAZY ) ) +#endif { } //____________________________________________________________________ RTTI::~RTTI() SAL_THROW( () ) { +#ifndef ANDROID dlclose( m_hApp ); +#endif } //____________________________________________________________________ @@ -153,7 +159,14 @@ namespace CPPU_CURRENT_NAMESPACE buf.append( 'E' ); OString symName( buf.makeStringAndClear() ); +#ifndef ANDROID rtti = (type_info *)dlsym( m_hApp, symName.getStr() ); +#else + rtti = (type_info *)dlsym( RTLD_DEFAULT, symName.getStr() ); + // Unfortunately dlsym for weak symbols doesn't work in + // Android 4.0 at least, sigh, so we will always take the + // else branch below. +#endif if (rtti) { @@ -165,11 +178,22 @@ namespace CPPU_CURRENT_NAMESPACE { // try to lookup the symbol in the generated rtti map t_rtti_map::const_iterator iFind2( m_generatedRttis.find( unoName ) ); + if (iFind2 == m_generatedRttis.end()) { // we must generate it ! // symbol and rtti-name is nearly identical, // the symbol is prefixed with _ZTI + +#ifdef ANDROID + // This code is supposed to be used only used for + // inter-process UNO, says sberg. Thus it should + // be unnecessary and never reached for + // Android. But see above... + + // OSL_ASSERT (iFind2 != m_generatedRttis.end()); + // return NULL; +#endif char const * rttiName = symName.getStr() +4; #if OSL_DEBUG_LEVEL > 1 fprintf( stderr,"generated rtti for %s\n", rttiName ); commit 5df86787093a8c9c73557fb8d01581a15bad5d86 Author: Tor Lillqvist <tlillqv...@suse.com> Date: Thu Nov 24 18:59:47 2011 +0200 Binary patch the mmapped libgnustl_shared.so from NDK r7 Poke in a jump to our replacement for std::type_info::operator==. See http://code.google.com/p/android/issues/detail?id=22165 . diff --git a/sal/osl/android/Makefile b/sal/osl/android/Makefile index a22ddfc..29dedef 100644 --- a/sal/osl/android/Makefile +++ b/sal/osl/android/Makefile @@ -107,12 +107,10 @@ install: ndk-build run: install # Note: these are just examples. # -# The first two ones should work adb shell am start -n org.libreoffice.android/.Bootstrap -e lo-main-library libcppunittester -e lo-main-cmdline "$(APP_DATA_PATH)/lib/libqa_sal_types.so" # adb shell am start -n org.libreoffice.android/.Bootstrap -e lo-main-library libcppunittester -e lo-main-cmdline "$(APP_DATA_PATH)/lib/libtest_i18npool_test_breakiterator.so --protector libunoexceptionprotector.so unoexceptionprotector '-env:UNO_TYPES=file:///assets/bin/udkapi.rdb file:///assets/bin/types.rdb' '-env:UNO_SERVICES=file:///assets/xml/ure/services.rdb file:///assets/ComponentTarget/i18npool/util/i18npool.component' -env:LO_LIB_DIR=file://$(APP_DATA_PATH)/lib" # -# This doesn't work yet adb shell am start -n org.libreoffice.android/.Bootstrap -e lo-main-library libunoexe -e lo-main-cmdline "-ro /assets/lib/uno_services.rdb -ro /assets/lib/uno_types.rdb -s com.sun.star.test.bridge.BridgeTest -- com.sun.star.test.bridge.CppTestObject" -e lo-main-delay 2 clean: diff --git a/sal/osl/android/jni/lo-bootstrap.c b/sal/osl/android/jni/lo-bootstrap.c index 0ddbe3f..1c2971d 100644 --- a/sal/osl/android/jni/lo-bootstrap.c +++ b/sal/osl/android/jni/lo-bootstrap.c @@ -56,6 +56,8 @@ #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "lo-bootstrap", __VA_ARGS__)) #define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "lo-bootstrap", __VA_ARGS__)) +#define ROUND_DOWN(ptr,multiple) (void *)(((unsigned) (ptr)) & ~((multiple)-1)) + struct engine { int dummy; }; @@ -69,6 +71,8 @@ static int lo_main_argc; static const char **lo_main_argv; static int sleep_time = 0; +/* Zip data structures */ + /* compression methods */ #define STORE 0 #define DEFLATE 8 @@ -124,6 +128,8 @@ struct cdir_end { char comment[0]; } __attribute__((__packed__)); +/* End of Zip data structures */ + static void engine_handle_cmd(struct android_app* app, int32_t cmd) @@ -818,7 +824,119 @@ lo_dlcall_argc_argv(void *function, return result; } -void android_main(struct android_app* state) +/* Replacement std::type_info::operator== */ + +static void +dummy_patched_operator_equals_arm(void) +{ + __asm(" .arm\n" + " .global patched_operator_equals_arm\n" + "patched_operator_equals_arm:\n" + " push {lr}\n" + + /* Load name pointers into r0 and r1 */ + " ldr r0, [r0, #4]\n" + " ldr r1, [r1, #4]\n" + + /* First compare pointers */ + " cmp r0, r1\n" + + /* If equal, return true */ + " beq .Lx1\n" + + /* Otherwise call strcmp */ + " bl strcmp\n" + + /* And return true or false */ + " cmp r0, #0\n" + " moveq r0, #1\n" + " movne r0, #0\n" + " b .Lx9\n" + + ".Lx1:\n" + " mov r0, #1\n" + + ".Lx9:\n" + " pop {pc}\n" + ); +} + +extern unsigned int patched_operator_equals_arm; + +static void +patch_type_info_operator_equals(void) +{ + /* There is a bug in std::type_info::operator== in + * libgnustl_shared.so in NDK r7 at least. It compares the type + * name pointers instead of comparing the type name strings. See + * http://code.google.com/p/android/issues/detail?id=22165 . So + * patch it, poke in a jump to our own code above instead. + */ + + void *libgnustl_shared; + void *operator_equals; + + void *base; + size_t size; + + /* ARM (not Thumb) code of the operator as in NDK r7 */ + static unsigned int expected_r7_code[] = { + 0xe5903004, /* ldr r3, [r0, #4] */ + 0xe5910004, /* ldr r0, [r1, #4] */ + 0xe1530000, /* cmp r3, r0 */ + 0x13a00000, /* movne, #0 */ + 0x03a00001, /* moveq r0, #1 */ + 0xe12fff1e /* bx lr */ + }; + + /* libgnustl_shared.so should be already loaded as we build + * all LO code against it, so as we have loaded the .so + * containing lo_main() already, libgnustl_shared.so will have + * been brought in, too. + */ + libgnustl_shared = dlopen("libgnustl_shared.so", RTLD_LOCAL); + if (libgnustl_shared == NULL) { + LOGI("android_main: libgnustl_shared.so not mapped??"); + exit(0); + } + + operator_equals = dlsym(libgnustl_shared, "_ZNKSt9type_infoeqERKS_"); + if (operator_equals == NULL) { + LOGI("android_main: std::type_info::operator== not found!?"); + exit(0); + } + LOGI("std::type_info::operator== is at %p", operator_equals); + + if (memcmp(operator_equals, expected_r7_code, sizeof(expected_r7_code)) != 0) { + LOGI("android_main: Code for std::type_info::operator== does not match that in NDK r7; not patching it"); + return; + } + + base = ROUND_DOWN(operator_equals, getpagesize()); + size = operator_equals + sizeof(expected_r7_code) - ROUND_DOWN(operator_equals, getpagesize()); + if (mprotect(base, size, PROT_READ|PROT_WRITE|PROT_EXEC) == -1) { + LOGI("android_main: mprotect() failed: %s", strerror(errno)); + return; + } + + if ((((unsigned) operator_equals) & 0x03) != 0) { + LOGI("android_main: Address of operator== is not at word boundary, huh?"); + return; + } + + if ((((unsigned) &patched_operator_equals_arm) & 0x03) != 0) { + LOGI("android_main: Address of patched_operator_equals_arm is not at word boundary, huh?"); + return; + } + + /* Poke a "b patched_operator_equals_arm" into it instead */ + *((unsigned *) operator_equals) = + (0xEA000000 | + ((((int) &patched_operator_equals_arm - ((int) operator_equals + 8)) / 4) & 0x00FFFFFF)); +} + +void +android_main(struct android_app* state) { struct engine engine; Dl_info lo_main_info; @@ -836,6 +954,8 @@ void android_main(struct android_app* state) if (sleep_time != 0) sleep(sleep_time); + patch_type_info_operator_equals(); + lo_main(lo_main_argc, lo_main_argv); exit(0); commit 0cc0df05888a4cacf4e654d4728c77822fd124a5 Author: Tor Lillqvist <tlillqv...@suse.com> Date: Wed Nov 23 21:09:42 2011 +0200 No symbol versioning on Android diff --git a/solenv/inc/_tg_shl.mk b/solenv/inc/_tg_shl.mk index 7c537be..8497d1f 100644 --- a/solenv/inc/_tg_shl.mk +++ b/solenv/inc/_tg_shl.mk @@ -101,7 +101,7 @@ $(USE_SHL1VERSIONMAP) .PHONY: .ENDIF # "$(SHL1VERSIONMAP)"!="" -.IF "$(OS)" != "AIX" +.IF "$(OS)" != "AIX" && "$(OS)" != "ANDROID" SHL1VERSIONMAPPARA=$(LINKVERSIONMAPFLAG) $(USE_SHL1VERSIONMAP) .ENDIF @@ -140,7 +140,7 @@ $(USE_SHL1VERSIONMAP) : #and now for the plain non-generic way... .IF "$(SHL1VERSIONMAP)"!="" USE_SHL1VERSIONMAP=$(MISC)/$(SHL1VERSIONMAP:b)_$(SHL1TARGET)$(SHL1VERSIONMAP:e) -.IF "$(OS)" != "AIX" +.IF "$(OS)" != "AIX" && "$(OS)" != "ANDROID" SHL1VERSIONMAPPARA=$(LINKVERSIONMAPFLAG) $(USE_SHL1VERSIONMAP) .ENDIF @@ -591,7 +591,7 @@ $(USE_SHL2VERSIONMAP) .PHONY: .ENDIF # "$(SHL2VERSIONMAP)"!="" -.IF "$(OS)" != "AIX" +.IF "$(OS)" != "AIX" && "$(OS)" != "ANDROID" SHL2VERSIONMAPPARA=$(LINKVERSIONMAPFLAG) $(USE_SHL2VERSIONMAP) .ENDIF @@ -630,7 +630,7 @@ $(USE_SHL2VERSIONMAP) : #and now for the plain non-generic way... .IF "$(SHL2VERSIONMAP)"!="" USE_SHL2VERSIONMAP=$(MISC)/$(SHL2VERSIONMAP:b)_$(SHL2TARGET)$(SHL2VERSIONMAP:e) -.IF "$(OS)" != "AIX" +.IF "$(OS)" != "AIX" && "$(OS)" != "ANDROID" SHL2VERSIONMAPPARA=$(LINKVERSIONMAPFLAG) $(USE_SHL2VERSIONMAP) .ENDIF @@ -1081,7 +1081,7 @@ $(USE_SHL3VERSIONMAP) .PHONY: .ENDIF # "$(SHL3VERSIONMAP)"!="" -.IF "$(OS)" != "AIX" +.IF "$(OS)" != "AIX" && "$(OS)" != "ANDROID" SHL3VERSIONMAPPARA=$(LINKVERSIONMAPFLAG) $(USE_SHL3VERSIONMAP) .ENDIF @@ -1120,7 +1120,7 @@ $(USE_SHL3VERSIONMAP) : #and now for the plain non-generic way... .IF "$(SHL3VERSIONMAP)"!="" USE_SHL3VERSIONMAP=$(MISC)/$(SHL3VERSIONMAP:b)_$(SHL3TARGET)$(SHL3VERSIONMAP:e) -.IF "$(OS)" != "AIX" +.IF "$(OS)" != "AIX" && "$(OS)" != "ANDROID" SHL3VERSIONMAPPARA=$(LINKVERSIONMAPFLAG) $(USE_SHL3VERSIONMAP) .ENDIF @@ -1571,7 +1571,7 @@ $(USE_SHL4VERSIONMAP) .PHONY: .ENDIF # "$(SHL4VERSIONMAP)"!="" -.IF "$(OS)" != "AIX" +.IF "$(OS)" != "AIX" && "$(OS)" != "ANDROID" SHL4VERSIONMAPPARA=$(LINKVERSIONMAPFLAG) $(USE_SHL4VERSIONMAP) .ENDIF @@ -1610,7 +1610,7 @@ $(USE_SHL4VERSIONMAP) : #and now for the plain non-generic way... .IF "$(SHL4VERSIONMAP)"!="" USE_SHL4VERSIONMAP=$(MISC)/$(SHL4VERSIONMAP:b)_$(SHL4TARGET)$(SHL4VERSIONMAP:e) -.IF "$(OS)" != "AIX" +.IF "$(OS)" != "AIX" && "$(OS)" != "ANDROID" SHL4VERSIONMAPPARA=$(LINKVERSIONMAPFLAG) $(USE_SHL4VERSIONMAP) .ENDIF @@ -2061,7 +2061,7 @@ $(USE_SHL5VERSIONMAP) .PHONY: .ENDIF # "$(SHL5VERSIONMAP)"!="" -.IF "$(OS)" != "AIX" +.IF "$(OS)" != "AIX" && "$(OS)" != "ANDROID" SHL5VERSIONMAPPARA=$(LINKVERSIONMAPFLAG) $(USE_SHL5VERSIONMAP) .ENDIF @@ -2100,7 +2100,7 @@ $(USE_SHL5VERSIONMAP) : #and now for the plain non-generic way... .IF "$(SHL5VERSIONMAP)"!="" USE_SHL5VERSIONMAP=$(MISC)/$(SHL5VERSIONMAP:b)_$(SHL5TARGET)$(SHL5VERSIONMAP:e) -.IF "$(OS)" != "AIX" +.IF "$(OS)" != "AIX" && "$(OS)" != "ANDROID" SHL5VERSIONMAPPARA=$(LINKVERSIONMAPFLAG) $(USE_SHL5VERSIONMAP) .ENDIF @@ -2551,7 +2551,7 @@ $(USE_SHL6VERSIONMAP) .PHONY: .ENDIF # "$(SHL6VERSIONMAP)"!="" -.IF "$(OS)" != "AIX" +.IF "$(OS)" != "AIX" && "$(OS)" != "ANDROID" SHL6VERSIONMAPPARA=$(LINKVERSIONMAPFLAG) $(USE_SHL6VERSIONMAP) .ENDIF @@ -2590,7 +2590,7 @@ $(USE_SHL6VERSIONMAP) : #and now for the plain non-generic way... .IF "$(SHL6VERSIONMAP)"!="" USE_SHL6VERSIONMAP=$(MISC)/$(SHL6VERSIONMAP:b)_$(SHL6TARGET)$(SHL6VERSIONMAP:e) -.IF "$(OS)" != "AIX" +.IF "$(OS)" != "AIX" && "$(OS)" != "ANDROID" SHL6VERSIONMAPPARA=$(LINKVERSIONMAPFLAG) $(USE_SHL6VERSIONMAP) .ENDIF @@ -3041,7 +3041,7 @@ $(USE_SHL7VERSIONMAP) .PHONY: .ENDIF # "$(SHL7VERSIONMAP)"!="" -.IF "$(OS)" != "AIX" +.IF "$(OS)" != "AIX" && "$(OS)" != "ANDROID" SHL7VERSIONMAPPARA=$(LINKVERSIONMAPFLAG) $(USE_SHL7VERSIONMAP) .ENDIF @@ -3080,7 +3080,7 @@ $(USE_SHL7VERSIONMAP) : #and now for the plain non-generic way... .IF "$(SHL7VERSIONMAP)"!="" USE_SHL7VERSIONMAP=$(MISC)/$(SHL7VERSIONMAP:b)_$(SHL7TARGET)$(SHL7VERSIONMAP:e) -.IF "$(OS)" != "AIX" +.IF "$(OS)" != "AIX" && "$(OS)" != "ANDROID" SHL7VERSIONMAPPARA=$(LINKVERSIONMAPFLAG) $(USE_SHL7VERSIONMAP) .ENDIF @@ -3531,7 +3531,7 @@ $(USE_SHL8VERSIONMAP) .PHONY: .ENDIF # "$(SHL8VERSIONMAP)"!="" -.IF "$(OS)" != "AIX" +.IF "$(OS)" != "AIX" && "$(OS)" != "ANDROID" SHL8VERSIONMAPPARA=$(LINKVERSIONMAPFLAG) $(USE_SHL8VERSIONMAP) .ENDIF @@ -3570,7 +3570,7 @@ $(USE_SHL8VERSIONMAP) : #and now for the plain non-generic way... .IF "$(SHL8VERSIONMAP)"!="" USE_SHL8VERSIONMAP=$(MISC)/$(SHL8VERSIONMAP:b)_$(SHL8TARGET)$(SHL8VERSIONMAP:e) -.IF "$(OS)" != "AIX" +.IF "$(OS)" != "AIX" && "$(OS)" != "ANDROID" SHL8VERSIONMAPPARA=$(LINKVERSIONMAPFLAG) $(USE_SHL8VERSIONMAP) .ENDIF @@ -4021,7 +4021,7 @@ $(USE_SHL9VERSIONMAP) .PHONY: .ENDIF # "$(SHL9VERSIONMAP)"!="" -.IF "$(OS)" != "AIX" +.IF "$(OS)" != "AIX" && "$(OS)" != "ANDROID" SHL9VERSIONMAPPARA=$(LINKVERSIONMAPFLAG) $(USE_SHL9VERSIONMAP) .ENDIF @@ -4060,7 +4060,7 @@ $(USE_SHL9VERSIONMAP) : #and now for the plain non-generic way... .IF "$(SHL9VERSIONMAP)"!="" USE_SHL9VERSIONMAP=$(MISC)/$(SHL9VERSIONMAP:b)_$(SHL9TARGET)$(SHL9VERSIONMAP:e) -.IF "$(OS)" != "AIX" +.IF "$(OS)" != "AIX" && "$(OS)" != "ANDROID" SHL9VERSIONMAPPARA=$(LINKVERSIONMAPFLAG) $(USE_SHL9VERSIONMAP) .ENDIF @@ -4511,7 +4511,7 @@ $(USE_SHL10VERSIONMAP) .PHONY: .ENDIF # "$(SHL10VERSIONMAP)"!="" -.IF "$(OS)" != "AIX" +.IF "$(OS)" != "AIX" && "$(OS)" != "ANDROID" SHL10VERSIONMAPPARA=$(LINKVERSIONMAPFLAG) $(USE_SHL10VERSIONMAP) .ENDIF @@ -4550,7 +4550,7 @@ $(USE_SHL10VERSIONMAP) : #and now for the plain non-generic way... .IF "$(SHL10VERSIONMAP)"!="" USE_SHL10VERSIONMAP=$(MISC)/$(SHL10VERSIONMAP:b)_$(SHL10TARGET)$(SHL10VERSIONMAP:e) -.IF "$(OS)" != "AIX" +.IF "$(OS)" != "AIX" && "$(OS)" != "ANDROID" SHL10VERSIONMAPPARA=$(LINKVERSIONMAPFLAG) $(USE_SHL10VERSIONMAP) .ENDIF diff --git a/solenv/inc/tg_shl.mk b/solenv/inc/tg_shl.mk index 111af2a..0c2882c 100644 --- a/solenv/inc/tg_shl.mk +++ b/solenv/inc/tg_shl.mk @@ -130,7 +130,7 @@ $(USE_SHL$(TNR)VERSIONMAP) .PHONY: .ENDIF # "$(SHL$(TNR)VERSIONMAP)"!="" -.IF "$(OS)" != "AIX" +.IF "$(OS)" != "AIX" && "$(OS)" != "ANDROID" SHL$(TNR)VERSIONMAPPARA=$(LINKVERSIONMAPFLAG) $(USE_SHL$(TNR)VERSIONMAP) .ENDIF @@ -169,7 +169,7 @@ $(USE_SHL$(TNR)VERSIONMAP) : #and now for the plain non-generic way... .IF "$(SHL$(TNR)VERSIONMAP)"!="" USE_SHL$(TNR)VERSIONMAP=$(MISC)/$(SHL$(TNR)VERSIONMAP:b)_$(SHL$(TNR)TARGET)$(SHL$(TNR)VERSIONMAP:e) -.IF "$(OS)" != "AIX" +.IF "$(OS)" != "AIX" && "$(OS)" != "ANDROID" SHL$(TNR)VERSIONMAPPARA=$(LINKVERSIONMAPFLAG) $(USE_SHL$(TNR)VERSIONMAP) .ENDIF commit 6f18ccfcd6a13ccaaceaf777a9b025c766bed176 Author: Tor Lillqvist <tlillqv...@suse.com> Date: Wed Nov 23 18:29:31 2011 +0200 Add "clean" target diff --git a/sal/osl/android/Makefile b/sal/osl/android/Makefile index 660126c..a22ddfc 100644 --- a/sal/osl/android/Makefile +++ b/sal/osl/android/Makefile @@ -114,3 +114,6 @@ run: install # # This doesn't work yet adb shell am start -n org.libreoffice.android/.Bootstrap -e lo-main-library libunoexe -e lo-main-cmdline "-ro /assets/lib/uno_services.rdb -ro /assets/lib/uno_types.rdb -s com.sun.star.test.bridge.BridgeTest -- com.sun.star.test.bridge.CppTestObject" -e lo-main-delay 2 + +clean: + rm -rf bin assets _______________________________________________ Libreoffice-commits mailing list Libreoffice-commits@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits