[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Fix build error when building a shared libunistring on Android
From: |
Bruno Haible |
Subject: |
Fix build error when building a shared libunistring on Android |
Date: |
Mon, 28 Jan 2019 22:01:54 +0100 |
User-agent: |
KMail/5.1.3 (Linux/4.4.0-141-generic; KDE/5.18.0; x86_64; ; ) |
The patch below fixes a build error when building libunistring
without --disable-shared on Android 4.3:
FAIL: test-nfc
==============
CANNOT LINK EXECUTABLE:
/data/data/com.spartacusrex.spartacuside/files/libunistring-0.9.10a/build/tests/.libs/test-nfc
invalid R_ARM_COPY relocation against DT_SYMBOLIC shared library
libunistring.so (built with -Bsymbolic?)
FAIL test-nfc (exit status: 1)
Some background about this error
"invalid R_ARM_COPY relocation against DT_SYMBOLIC shared library":
It indicates a reference to a variable (not function) in a shared library.
It is a runtime error, emitted by the dynamic linker of Android [1],
I saw it in two cases:
1) For a reference to 'stdin', 'stdout', 'stderr':
Compiling the following program
-------------------- hello.c --------------------
#include <stdio.h>
int main () {
fprintf(stdout, "Hello world\n");
return 0;
}
-------------------------------------------------
without -mandroid and without -fPIC and then running the program
produces this error.
In this case, the following relocations against __sF (an
array that contains stdin, stdout, stderr) remain:
$ arm-eabi-readelf -r hello.o
Relocation section '.rel.text' at offset 0x3f0 contains 3 entries:
Offset Info Type Sym.Value Sym. Name
00000020 00000d02 R_ARM_ABS32 00000000 __sF
...
$ arm-eabi-readelf -r hello
Relocation section '.rel.dyn' at offset 0x2cc contains 1 entries:
Offset Info Type Sym.Value Sym. Name
0000947c 00000714 R_ARM_COPY 0000947c __sF
$ ./hello
CANNOT LINK EXECUTABLE: ./hello invalid R_ARM_COPY relocation against
DT_SYMBOLIC shared library libc.so (built with -Bsymbolic?)
With -mandroid or -fPIC (implied by -mandroid), on the other hand, the
program executes fine:
$ arm-eabi-readelf -r hello.o
Relocation section '.rel.text' at offset 0x444 contains 4 entries:
Offset Info Type Sym.Value Sym. Name
00000034 00000e19 R_ARM_BASE_PREL 00000000 _GLOBAL_OFFSET_TABLE_
00000038 00000f1a R_ARM_GOT_BREL 00000000 __sF
0000003c 00000818 R_ARM_GOTOFF32 00000000 .LC0
...
$ arm-eabi-readelf -r hello
Relocation section '.rel.dyn' at offset 0x2cc contains 1 entries:
Offset Info Type Sym.Value Sym. Name
00009494 00000715 R_ARM_GLOB_DAT 00000000 __sF
$ ./hello
Hello world
So, a relocation of type R_ARM_ABS32 in the '.text' segment is handled
by the binutils, by passing '-mandroid' or '-fPIC'. Namely, the relocation
is converted to something the Android dynamic linker can handle.
2) The test program tests/uninorm/test-nfc.c contains a reference to a
variable, in an initializer of a variable:
uninorm_t n = UNINORM_NFC;
where uninorm.h contains:
extern const struct unicode_normalization_form uninorm_nfc;
#define UNINORM_NFC (&uninorm_nfc)
Here, compiling with -mandroid or -fPIC makes no difference. In both cases
$ arm-eabi-readelf -r test-nfc.o
Relocation section '.rel.data' at offset 0x42c contains 1 entries:
Offset Info Type Sym.Value Sym. Name
00000000 00000f02 R_ARM_ABS32 00000000 uninorm_nfc
$ arm-eabi-readelf -r .libs/test-nfc
Relocation section '.rel.dyn' at offset 0x49c contains 3 entries:
Offset Info Type Sym.Value Sym. Name
0000c80c 00000315 R_ARM_GLOB_DAT 0000c818 uninorm_nfc
0000c818 00000314 R_ARM_COPY 0000c818 uninorm_nfc
$ LD_LIBRARY_PATH=.... .libs/test-nfc
CANNOT LINK EXECUTABLE: .libs/test-nfc invalid R_ARM_COPY relocation against
DT_SYMBOLIC shared library libunistring.so (built with -Bsymbolic?)
So, a relocation of type R_ARM_ABS32 in the '.data' segment cannot be handled,
because '-fPIC' does not help and the dynamic linker does not support it.
For comparison, here's the situation of the same program on a glibc
system:
$ readelf -r test-nfc.o
Relocation section '.rel.data.rel' at offset 0x73c contains 1 entry:
Offset Info Type Sym.Value Sym. Name
00000000 00001802 R_ARM_ABS32 00000000 uninorm_nfc
$ readelf -r .libs/test-nfc
Relocation section '.rel.dyn' at offset 0x528 contains 14 entries:
Offset Info Type Sym.Value Sym. Name
00015070 00001415 R_ARM_GLOB_DAT 00000000 uninorm_nfc
00015080 00001402 R_ARM_ABS32 00000000 uninorm_nfc
...
$ LD_LIBRARY_PATH=../lib/.libs .libs/test-nfc
<works>
So, on glibc systems, R_ARM_ABS32 relocs in the .o file are not transformed
to R_ARM_COPY relocs, and glibc's ld.so handles them fine.
I'm not an expert in ELF for ARM [2]; I don't know whether there is a
linker option that would fix the issue. So, let me disable this code
on Android, like on Windows.
[1]
https://git.sphere.ly/Kevinjoa/bionic/blob/b69645248887ddb88517b07c1617d390fdce9c9f/linker/linker.cpp
line 1276
[2] https://static.docs.arm.com/ihi0044/e/IHI0044E_aaelf.pdf
2019-01-28 Bruno Haible <address@hidden>
Fix build error when building a shared libunistring on Android.
* tests/uninorm/test-nfc.c (n): Don't define on Android.
(main): Add 'volatile', to defeat a GCC optimization that would
eliminate the reference.
* tests/uninorm/test-nfd.c (n): Don't define on Android.
(main): Add 'volatile', to defeat a GCC optimization that would
eliminate the reference.
* tests/uninorm/test-nfkc.c (n): Don't define on Android.
(main): Add 'volatile', to defeat a GCC optimization that would
eliminate the reference.
* tests/uninorm/test-nfkd.c (n): Don't define on Android.
(main): Add 'volatile', to defeat a GCC optimization that would
eliminate the reference.
diff --git a/tests/uninorm/test-nfc.c b/tests/uninorm/test-nfc.c
index b5c4a01..1bda462 100644
--- a/tests/uninorm/test-nfc.c
+++ b/tests/uninorm/test-nfc.c
@@ -20,7 +20,7 @@
#include "uninorm.h"
-#if !WOE32DLL
+#if !(WOE32DLL || defined __ANDROID__)
/* Check that UNINORM_NFC is defined and links. */
uninorm_t n = UNINORM_NFC;
#endif
@@ -33,7 +33,7 @@ int
main ()
{
/* Check that UNINORM_NFC is defined and links. */
- uninorm_t nf = UNINORM_NFC;
+ volatile uninorm_t nf = UNINORM_NFC;
(void) nf;
test_u32_nfc ();
diff --git a/tests/uninorm/test-nfd.c b/tests/uninorm/test-nfd.c
index bcb2d02..e2e8b62 100644
--- a/tests/uninorm/test-nfd.c
+++ b/tests/uninorm/test-nfd.c
@@ -20,7 +20,7 @@
#include "uninorm.h"
-#if !WOE32DLL
+#if !(WOE32DLL || defined __ANDROID__)
/* Check that UNINORM_NFD is defined and links. */
uninorm_t n = UNINORM_NFD;
#endif
@@ -33,7 +33,7 @@ int
main ()
{
/* Check that UNINORM_NFD is defined and links. */
- uninorm_t nf = UNINORM_NFD;
+ volatile uninorm_t nf = UNINORM_NFD;
(void) nf;
test_u32_nfd ();
diff --git a/tests/uninorm/test-nfkc.c b/tests/uninorm/test-nfkc.c
index 6df038d..7e76fbb 100644
--- a/tests/uninorm/test-nfkc.c
+++ b/tests/uninorm/test-nfkc.c
@@ -20,7 +20,7 @@
#include "uninorm.h"
-#if !WOE32DLL
+#if !(WOE32DLL || defined __ANDROID__)
/* Check that UNINORM_NFKC is defined and links. */
uninorm_t n = UNINORM_NFKC;
#endif
@@ -33,7 +33,7 @@ int
main ()
{
/* Check that UNINORM_NFKC is defined and links. */
- uninorm_t nf = UNINORM_NFKC;
+ volatile uninorm_t nf = UNINORM_NFKC;
(void) nf;
test_u32_nfkc ();
diff --git a/tests/uninorm/test-nfkd.c b/tests/uninorm/test-nfkd.c
index ad89e2e..501630c 100644
--- a/tests/uninorm/test-nfkd.c
+++ b/tests/uninorm/test-nfkd.c
@@ -20,7 +20,7 @@
#include "uninorm.h"
-#if !WOE32DLL
+#if !(WOE32DLL || defined __ANDROID__)
/* Check that UNINORM_NFKD is defined and links. */
uninorm_t n = UNINORM_NFKD;
#endif
@@ -33,7 +33,7 @@ int
main ()
{
/* Check that UNINORM_NFKD is defined and links. */
- uninorm_t nf = UNINORM_NFKD;
+ volatile uninorm_t nf = UNINORM_NFKD;
(void) nf;
test_u32_nfkd ();
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Fix build error when building a shared libunistring on Android,
Bruno Haible <=