canyie/pine

Seems some android 8.0 are using 8.1 modifiers

canyie opened this issue · 1 comments

modifiers.h in android 8.0:

// This is set by the class linker during LinkInterfaceMethods. Prior to that point we do not know
// if any particular method needs to be a default conflict. Used to figure out at runtime if
// invoking this method will throw an exception.
static constexpr uint32_t kAccDefaultConflict =       0x00800000;  // method (runtime)

// Set by the verifier for a method we do not want the compiler to compile.
static constexpr uint32_t kAccCompileDontBother =     0x01000000;  // method (runtime)

In android 8.1:

static constexpr uint32_t kAccDefaultConflict =       0x01000000;  // method (runtime)
static constexpr uint32_t kAccCompileDontBother =     0x02000000;  // method (runtime)

The value of kAccCompileDontBother in Android 8.0 is 0x01000000, which is the same as the value of kAccDefaultConflict in Android 8.1.
For these devices, if we set kAccCompileDontBother for it, it will throw errors like this:

java.lang.IncompatibleClassChangeError: Conflicting default method implementations <your hooked method>

We have no way to identify these devices. If you encounter such a situation, please provide information to help us.

A possible method to identify these devices: add kAccCompileDontBother and kAccAbstract to an ArtMethod, and actively call ThrowInvocationTimeError() on it, and then determine whether an IncompatibleClassChangeError is thrown.
Note: ThrowInvocationTimeError has a DCHECK(IsAbstract()), so we should add kAccAbstract to prevent it from failing.

EDIT: Implemented in b572c74