Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add android support for api version 21+ #65

Merged
merged 4 commits into from
Oct 11, 2021
Merged

add android support for api version 21+ #65

merged 4 commits into from
Oct 11, 2021

Conversation

name1e5s
Copy link
Contributor

@name1e5s name1e5s commented Oct 9, 2021

Since this PR, libc crate supports dl_iterate_phdr for android api version 21+. Hence gives us the ability to support android.

@@ -27,6 +27,19 @@ type Phdr = libc::Elf32_Phdr;
type Phdr = libc::Elf64_Phdr;

const NT_GNU_BUILD_ID: u32 = 3;
const PT_NULL: u32 = 0;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sadly libc crate does not add these constants to android, we need to manually copy them here for now.

@name1e5s name1e5s changed the title add android support for api version 21+ WIP: add android support for api version 21+ Oct 9, 2021
@name1e5s name1e5s changed the title WIP: add android support for api version 21+ add android support for api version 21+ Oct 10, 2021
src/linux/mod.rs Outdated
@@ -273,6 +286,10 @@ impl<'a> SharedLibrary<'a> {
F: FnMut(&Self) -> C,
C: Into<IterationControl>,
{
#[cfg(target_os = "android")]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dl_iterate_phdr on android under api 27(8.1) will pass a zero-filled dl_phdr_info struct before any real shared library info, we should ignore it.

@@ -273,6 +286,10 @@ impl<'a> SharedLibrary<'a> {
F: FnMut(&Self) -> C,
C: Into<IterationControl>,
{
if (*info).dlpi_phdr.is_null() {
return CONTINUE;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do these null entries have valid values for the other fields (name and addr)? If so, what are they?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Result differs by android api version:

  • on android 8.0 and older the null entries does not contain any useful fields,

截屏2021-10-10 下午4 42 56

- on android 8.1 and android 9, the entry with a null dlpi_phdr contains the name of '/system/bin/linker' and its load address

截屏2021-10-10 下午4 51 00

- android 10+ won't return any null entries

截屏2021-10-10 下午4 52 15

The screenshots are the result of running example program at https://man7.org/linux/man-pages/man3/dl_iterate_phdr.3.html on devices of different android versions.

Copy link
Contributor Author

@name1e5s name1e5s Oct 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PS:
'/system/bin/linker' with base address on android 8.1:
截屏2021-10-11 上午11 00 02
May be we should create a SharedLibrary with no headers for this situation?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could, but I'm happy to wait until someone needs it, since I don't see what use it is without the program headers.

src/linux/mod.rs Show resolved Hide resolved
Copy link
Contributor

@philipc philipc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@philipc philipc merged commit c5a0293 into gimli-rs:master Oct 11, 2021
@philipc philipc mentioned this pull request Oct 14, 2021
MarijnS95 added a commit to rust-mobile/xbuild that referenced this pull request Jan 7, 2025
We haven't set the SDK/API level via the `__ANDROID_API__` define for
a very long time and so far got away with it.  However, while debugging
why `backtrace` (and by extension Rust `std` which reuses that crate)
wasn't generating symbolicated stacktraces in `panic_log`, and why
`findshlibs` wasn't providing the list of loaded libraries to `sentry`,
we found that both rely on expanding the `__ANDROID_API__` define
via compiling a small C file via `cc` to make the code conditional on
SDK/API >= 21:

gimli-rs/findshlibs#65
rust-lang/backtrace-rs#415

(It would have been lovely if these crates emitted a `cargo:warning`
when the define wasn't set at all, indicating an "incomplete"
cross-compiler setup, and/or looked at the runtime Android API version
via something like rust-mobile/ndk#479.)

Note that `backtrace 0.3.74` / Rust 1.82
(rust-lang/rust@0763a3a) no longer rely on
this because Rust 1.82 bumped the minimum SDK/API level to 21:
rust-lang/backtrace-rs#656

We could set this define directly, or rely on `clang` to set it
for us by appending the SDK/API level to the target triple, of
the form `<arch>-linux-android<sdk level>`.  The latter is more
common. Keep in mind that the `cc` crate adds an unversioned
`--target=<arch>-linux-android` to the command line arguments as well,
but clang seems to deduplicate them (or look at the latter `--target`
which contains our version).

Note that this effectively reverts
32efed6 because
we must now always pass the SDK level via the triple again, even if the
host also happens to be Android with the same architecture.
MarijnS95 added a commit to Traverse-Research/xbuild that referenced this pull request Jan 7, 2025
We haven't set the SDK/API level via the `__ANDROID_API__` define for
a very long time and so far got away with it.  However, while debugging
why `backtrace` (and by extension Rust `std` which reuses that crate)
wasn't generating symbolicated stacktraces in `panic_log`, and why
`findshlibs` wasn't providing the list of loaded libraries to `sentry`,
we found that both rely on expanding the `__ANDROID_API__` define
via compiling a small C file via `cc` to make the code conditional on
SDK/API >= 21:

gimli-rs/findshlibs#65
rust-lang/backtrace-rs#415

(It would have been lovely if these crates emitted a `cargo:warning`
when the define wasn't set at all, indicating an "incomplete"
cross-compiler setup, and/or looked at the runtime Android API version
via something like rust-mobile/ndk#479.)

Note that `backtrace 0.3.74` / Rust 1.82
(rust-lang/rust@0763a3a) no longer rely on
this because Rust 1.82 bumped the minimum SDK/API level to 21:
rust-lang/backtrace-rs#656

We could set this define directly, or rely on `clang` to set it
for us by appending the SDK/API level to the target triple, of
the form `<arch>-linux-android<sdk level>`.  The latter is more
common. Keep in mind that the `cc` crate adds an unversioned
`--target=<arch>-linux-android` to the command line arguments as well,
but clang seems to deduplicate them (or look at the latter `--target`
which contains our version).

Note that this effectively reverts
rust-mobile@32efed6 because
we must now always pass the SDK level via the triple again, even if the
host also happens to be Android with the same architecture.
MarijnS95 added a commit to Traverse-Research/xbuild that referenced this pull request Jan 9, 2025
We haven't set the SDK/API level via the `__ANDROID_API__` define for
a very long time and so far got away with it.  However, while debugging
why `backtrace` (and by extension Rust `std` which reuses that crate)
wasn't generating symbolicated stacktraces in `panic_log`, and why
`findshlibs` wasn't providing the list of loaded libraries to `sentry`,
we found that both rely on expanding the `__ANDROID_API__` define
via compiling a small C file via `cc` to make the code conditional on
SDK/API >= 21:

gimli-rs/findshlibs#65
rust-lang/backtrace-rs#415

(It would have been lovely if these crates emitted a `cargo:warning`
when the define wasn't set at all, indicating an "incomplete"
cross-compiler setup, and/or looked at the runtime Android API version
via something like rust-mobile/ndk#479.)

Note that `backtrace 0.3.74` / Rust 1.82
(rust-lang/rust@0763a3a) no longer rely on
this because Rust 1.82 bumped the minimum SDK/API level to 21:
rust-lang/backtrace-rs#656

We could set this define directly, or rely on `clang` to set it
for us by appending the SDK/API level to the target triple, of
the form `<arch>-linux-android<sdk level>`.  The latter is more
common. Keep in mind that the `cc` crate adds an unversioned
`--target=<arch>-linux-android` to the command line arguments as well,
but clang seems to deduplicate them (or look at the latter `--target`
which contains our version).

Note that this effectively reverts
rust-mobile@32efed6 because
we must now always pass the SDK level via the triple again, even if the
host also happens to be Android with the same architecture.
MarijnS95 added a commit to rust-mobile/xbuild that referenced this pull request Jan 9, 2025
We haven't set the SDK/API level via the `__ANDROID_API__` define for
a very long time and so far got away with it.  However, while debugging
why `backtrace` (and by extension Rust `std` which reuses that crate)
wasn't generating symbolicated stacktraces in `panic_log`, and why
`findshlibs` wasn't providing the list of loaded libraries to `sentry`,
we found that both rely on expanding the `__ANDROID_API__` define
via compiling a small C file via `cc` to make the code conditional on
SDK/API >= 21:

gimli-rs/findshlibs#65
rust-lang/backtrace-rs#415

(It would have been lovely if these crates emitted a `cargo:warning`
when the define wasn't set at all, indicating an "incomplete"
cross-compiler setup, and/or looked at the runtime Android API version
via something like rust-mobile/ndk#479.)

Note that `backtrace 0.3.74` / Rust 1.82
(rust-lang/rust@0763a3a) no longer rely on
this because Rust 1.82 bumped the minimum SDK/API level to 21:
rust-lang/backtrace-rs#656

We could set this define directly, or rely on `clang` to set it
for us by appending the SDK/API level to the target triple, of
the form `<arch>-linux-android<sdk level>`.  The latter is more
common. Keep in mind that the `cc` crate adds an unversioned
`--target=<arch>-linux-android` to the command line arguments as well,
but clang seems to deduplicate them (or look at the latter `--target`
which contains our version).

Note that this effectively reverts
32efed6 because
we must now always pass the SDK level via the triple again, even if the
host also happens to be Android with the same architecture.
MarijnS95 added a commit to Traverse-Research/xbuild that referenced this pull request Jan 9, 2025
We haven't set the SDK/API level via the `__ANDROID_API__` define for
a very long time and so far got away with it.  However, while debugging
why `backtrace` (and by extension Rust `std` which reuses that crate)
wasn't generating symbolicated stacktraces in `panic_log`, and why
`findshlibs` wasn't providing the list of loaded libraries to `sentry`,
we found that both rely on expanding the `__ANDROID_API__` define
via compiling a small C file via `cc` to make the code conditional on
SDK/API >= 21:

gimli-rs/findshlibs#65
rust-lang/backtrace-rs#415

(It would have been lovely if these crates emitted a `cargo:warning`
when the define wasn't set at all, indicating an "incomplete"
cross-compiler setup, and/or looked at the runtime Android API version
via something like rust-mobile/ndk#479.)

Note that `backtrace 0.3.74` / Rust 1.82
(rust-lang/rust@0763a3a) no longer rely on
this because Rust 1.82 bumped the minimum SDK/API level to 21:
rust-lang/backtrace-rs#656

We could set this define directly, or rely on `clang` to set it
for us by appending the SDK/API level to the target triple, of
the form `<arch>-linux-android<sdk level>`.  The latter is more
common. Keep in mind that the `cc` crate adds an unversioned
`--target=<arch>-linux-android` to the command line arguments as well,
but clang seems to deduplicate them (or look at the latter `--target`
which contains our version).

Note that this effectively reverts
rust-mobile@32efed6 because
we must now always pass the SDK level via the triple again, even if the
host also happens to be Android with the same architecture.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants