Opened 4 years ago

Closed 4 years ago

Last modified 2 years ago

#4928 closed defect (wontfix)

Cannot load ffmpeg x86 build on Android 6.0 (Marshmallow) - libavcodec.so: has text relocations

Reported by: ioeir2 Owned by:
Priority: normal Component: avcodec
Version: git-master Keywords: android
Cc: Blocked By:
Blocking: Reproduced by developer: yes
Analyzed by developer: no

Description

Summary of the bug:
Shared libraries libswscale.so, libavcodec.so, libswresample.so, libswscale.so cannot be loaded on Android 6.0 device for x86 build due to text relocations.

Android OS: 6.0.
Android NDK: r10e
GCC: 4.7
Issue is reproducible only on x86 build. No such issue on armv7-a or x86_64 builds.

How to reproduce:

1. Compile libraries using attached script.
./build_ffmpeg.sh

2. Check for text relocations using NDK readelf executable.
./i686-linux-android-readelf -a libswscale.so  | grep TEXTREL
 0x00000016 (TEXTREL)                    0x0
 0x0000001e (FLAGS)                      SYMBOLIC TEXTREL BIND_NOW

./i686-linux-android-readelf -a libavcodec.so  | grep TEXTREL
 0x00000016 (TEXTREL)                    0x0
 0x0000001e (FLAGS)                      SYMBOLIC TEXTREL BIND_NOW

./i686-linux-android-readelf -a libavformat.so  | grep TEXTREL

./i686-linux-android-readelf -a libswresample.so  | grep TEXTREL
 0x00000016 (TEXTREL)                    0x0
 0x0000001e (FLAGS)                      SYMBOLIC TEXTREL BIND_NOW

./i686-linux-android-readelf -a libavutil.so  | grep TEXTREL

./i686-linux-android-readelf -a libswscale.so  | grep TEXTREL
 0x00000016 (TEXTREL)                    0x0
 0x0000001e (FLAGS)                      SYMBOLIC TEXTREL BIND_NOW

This means that libswscale.so, libavcodec.so, libswresample.so, libswscale.so libraries have text relocations.

Attachments (1)

build_ffmpeg.sh (4.6 KB) - added by ioeir2 4 years ago.

Download all attachments as: .zip

Change History (23)

Changed 4 years ago by ioeir2

comment:2 Changed 4 years ago by cehoyos

  • Version changed from 2.8.1 to git-master

This is reproducible with current FFmpeg git head, no?

Am I correct that this is "wontfix"?

comment:3 Changed 4 years ago by ioeir2

The issue is reproducible by using today snapshot from http://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2

comment:4 Changed 4 years ago by six66

hi ioeir, have you found any workaround for this?

comment:5 Changed 4 years ago by ioeir2

No workaround found.

comment:6 Changed 4 years ago by Gramner

  • Resolution set to wontfix
  • Status changed from new to closed

Text relocations are used on purpose on 32-bit x86, this is the intended functionality and not a bug.

The combination of the following two commits in Android is the root of the problem:
https://android.googlesource.com/platform/bionic/+/aa836f731016f7f1099d6a6ce47a35f1ec17dd4e
https://android.googlesource.com/platform/bionic/+/e4ad91f86a47b39612e030a162f4793cb3421d31

Neither of those commits gives any reason or explanation for why they were done.

Breaking user space for no apparent reason, especially when user space libraries cannot deal with said breakage in any reasonable way, is perplexing.

Any bug reports regarding this should be directed at Google in my opinion.

comment:8 Changed 4 years ago by ioeir2

Google guys closed the bug saying that they will fix that on their side. The fix should be done in ffmpeg library. All libraries with text relocations will not run on Android 6.0 and later.

Last edited 4 years ago by ioeir2 (previous) (diff)

comment:9 Changed 4 years ago by ioeir2

  • Resolution wontfix deleted
  • Status changed from closed to reopened

comment:10 follow-up: Changed 4 years ago by heleppkes

  • Resolution set to wontfix
  • Status changed from reopened to closed

Then we have a stalemate, because its not realistic for >60k lines of assembly to be rewritten on a whim of some Google engineer.

comment:11 Changed 4 years ago by ioeir2

But you can just provide C code as fallback for x86 binary and put some parameters for compiling that code using C instead of assembly.

comment:12 Changed 4 years ago by heleppkes

You can already do that by building with --disable-yasm, all optimized ASM has a C version as well, however the resulting binary will be painfully slow.

comment:13 follow-up: Changed 4 years ago by cehoyos

--disable-asm or --disable-asm --enable-pic might be needed.

comment:14 in reply to: ↑ 13 Changed 4 years ago by ioeir2

Replying to cehoyos:

--disable-asm or --disable-asm --enable-pic might be needed.

--disable-asm fixed the issue. Thanks!

comment:15 Changed 4 years ago by cehoyos

It should be emphasized that --disable-asm does not fix anything, it just creates horribly slow FFmpeg binaries.

comment:16 in reply to: ↑ 10 ; follow-up: Changed 4 years ago by anirudhd

Replying to heleppkes:

Then we have a stalemate, because its not realistic for >60k lines of assembly to be rewritten on a whim of some Google engineer.

Is there a plan to address this in the near future?

reply from Android Issue tracker
"as the warning used to say (and we've actually restored the warning in a future release --- it was an accident that we removed the warning in the same release that starts enforcing no text relocations), text relocations cause unnecessary dirty pages and have prevented us from tightening security. the VM needs the "execmem"
SELinux capability anyway, so the latter advantage doesn't extend to apps, but for other security domains (such as those used by the various native daemons on the platform) if you don't have text relocations, you don't need that capability. but the unnecessary dirty pages.
"

comment:17 in reply to: ↑ 16 Changed 4 years ago by Gramner

Replying to anirudhd:

Is there a plan to address this in the near future?

From the FFmpeg side? I doubt it.

The disadvantages of doing so (including, but not limited to, thousands of hours of digging through and rewriting code, a less maintainable code base, worse performance, etc.) vastly outnumber the advantages.

comment:18 Changed 3 years ago by adrienberaud

Hello,

Android is a very major platform that really can't just be ignored,
and they clearly won't be coming back on their decision to force PIC (justified by security reasons).
If this ASM code was written some day, then it can (and should) be re-written to support Android.

Even if it won't be done in a day, this ticket should at least (IMHO) be left open.

Regards,
Adrien

comment:19 Changed 3 years ago by adrienberaud

  • Reproduced by developer set

comment:20 Changed 3 years ago by heleppkes

We'll not be rewriting our entire ASM code to be slower and less maintainable, sorry.

comment:21 follow-up: Changed 2 years ago by reimar

Stating my opinion and for the benefit of anyone coming across this:
As far as I can tell (and an earlier post mentioned), this is not an Android issue, this is a (32-bit) x86 Android issue.
That is such a minority platform that that already doesn't justify any real effort, but especially if the result simply always will be really bad performance-wise. A potential workaround (at least for now) is to declare the app to be targeting Android L and not support M, possibly only for special 32-bit x86 apks.
If this were to affect ARM or x86_64 I think it would be worth investigating less brute-force fixes than --disable-asm.
I also think Google should reconsider their stance for 32-bit x86 (or start dropping support for it) as 32-bit x86 with PIC is a horrible idea performance-wise.

Last edited 2 years ago by reimar (previous) (diff)

comment:22 in reply to: ↑ 21 Changed 2 years ago by alexcohn

Replying to reimar:

As far as I can tell (and an earlier post mentioned), this is not an Android issue, this is a (32-bit) x86 Android issue.
That is such a minority platform that that already doesn't justify any real effort

+100

but especially if the result simply always will be really bad performance-wise. A potential workaround (at least for now) is to declare the app to be targeting Android L and not support M, possibly only for special 32-bit x86 apks.

There are two cases here. I believe that the new x86 devices running new versions of Android all have 64 bit. Manufacturers of lower-end TV sticks should simply stick (pun intended) to Lollipop. The other case, much smaller in magnitude, but very visible, is the developers who run the default emulator image (32-bit x86 with latest OS) to debug their apps.

For this second category my advice would be to ignore performance issues with codecs in debug sessions, or use older system image for these cases, and make sure that the performance of the app on real (mostly armv7 or armv8) devices is good enough.

Note: See TracTickets for help on using tickets.