Skip to content

elf: Add Android-specific REL,RELA and RELR constants#875

Merged
philipc merged 1 commit intogimli-rs:mainfrom
mati865:push-qstwxkvqxwos
Apr 7, 2026
Merged

elf: Add Android-specific REL,RELA and RELR constants#875
philipc merged 1 commit intogimli-rs:mainfrom
mati865:push-qstwxkvqxwos

Conversation

@mati865
Copy link
Copy Markdown
Contributor

@mati865 mati865 commented Apr 5, 2026

For the context, RELR constants would be useful for wild-linker/wild#1805. While at it, I went further and added also REL/RELA constants.

I think a test would be useful, but I don't know how to add one. Probably dissecting real Android binary would be the best, but to test most the relocations added in this PR, even regular Linux binary would be fine.
To achieve that one needs to link using LLD and --pack-dyn-relocs=android+relr --use-android-relr-tags, but there is a catch: to have both variants of relative relocations (RELA and RELR) at the same time you need relocations with even and odd offsets.
For example, using Wild's test:

❯ gcc ~/Projects/wild/wild/tests/sources/elf/pack-relative-relocs/pack-relative-relocs.c -I ~/Projects/wild/wild/tests/sources/elf/common/ -nostdlib ~/Projects/wild/wild/tests/sources/elf/common/init.c ~/Projects/wild/wild/tests/sources/elf/common/runtime.c -o /tmp/bin.lld -fuse-ld=lld -Wl,--pack-dyn-relocs=android+relr,--use-android-relr-tags

❯ llvm-readelf -Wr /tmp/bin.lld
Relocation section '.rela.dyn' at offset 0x320 contains 1 entries:
    Offset             Info             Type               Symbol's Value  Symbol's Name + Addend
00000000000037c1  0000000000000008 R_X86_64_RELATIVE                 37b0

Relocation section '.relr.dyn' at offset 0x330 contains 6 entries:
Index: Entry            Address           Symbolic Address
0000:  0000000000002670 0000000000002670  __init_array_start
0001:  000000000000000f 0000000000002678  __init_array_start + 0x8
                        0000000000002680  __init_array_start + 0x10
                        0000000000002688  __init_array_end
0002:  00000000000037b8 00000000000037b8  aligned_ptr
0003:  00000000000037d2 00000000000037d2  unaligned_ptr_even + 0x2

❯ llvm-readelf -Wd /tmp/bin.lld | rg ANDROID
  0x0000000060000011 (ANDROID_RELA)    0x320
  0x0000000060000012 (ANDROID_RELASZ)  15 (bytes)
  0x000000006fffe000 (ANDROID_RELR)    0x330
  0x000000006fffe001 (ANDROID_RELRSZ)  0x20
  0x000000006fffe003 (ANDROID_RELRENT) 0x8

@philipc
Copy link
Copy Markdown
Contributor

philipc commented Apr 5, 2026

We don't usually add tests for just constants, only if you're also adding code that uses them.

Normally I'd ask to add these to the readobj example, but I'm currently in the process of refactoring all the constant definitions to avoid the need for that. As a result, I may also delay merging this PR until after that lands.

These constants are in the OS-specific range. What's the normal way to check for an android binary to know if we should be interpreting these as such?

@mati865
Copy link
Copy Markdown
Contributor Author

mati865 commented Apr 6, 2026

Sorry, I confused examples with tests. I meant examples here.

Currently, if I add the constants to readobj, it doesn't change any of the existing outputs.

As a result, I may also delay merging this PR until after that lands.

No worries, take your time.

These constants are in the OS-specific range. What's the normal way to check for an android binary to know if we should be interpreting these as such?

Oh, that's a tough question. I don't think you can reliably do that. Lower level internals of Android don't differ that much from a regular Linux distro.
Using the Wild's test that I mentioned earlier as an example (I did it on x86_64 Arch Linux) you can see that GNU readelf recognises section types but not the dynamic tags, while LLVM readelf identifies them all:

❯ readelf -Wd /tmp/bin.lld | rg "ANDROID| 6000| 6fff"
 0x0000000060000011 (Operating System specific: 60000011)                0x320
 0x0000000060000012 (Operating System specific: 60000012)                0xf
 0x000000006fffe000 (Operating System specific: 6fffe000)                0x330
 0x000000006fffe001 (Operating System specific: 6fffe001)                0x20
 0x000000006fffe003 (Operating System specific: 6fffe003)                0x8

❯ llvm-readelf -Wd /tmp/bin.lld | rg "ANDROID| 6000| 6fff"
  0x0000000060000011 (ANDROID_RELA)    0x320
  0x0000000060000012 (ANDROID_RELASZ)  15 (bytes)
  0x000000006fffe000 (ANDROID_RELR)    0x330
  0x000000006fffe001 (ANDROID_RELRSZ)  0x20
  0x000000006fffe003 (ANDROID_RELRENT) 0x8

❯ readelf -WS /tmp/bin.lld | rg "ANDROID"
  [ 6] .rela.dyn         ANDROID_RELA    0000000000000320 000320 00000f 01   A  3   0  8
  [ 7] .relr.dyn         ANDROID_RELR    0000000000000330 000330 000020 08   A  0   0  8

❯ llvm-readelf -WS /tmp/bin.lld | rg "ANDROID"
  [ 6] .rela.dyn         ANDROID_RELA    0000000000000320 000320 00000f 01   A  3   0  8
  [ 7] .relr.dyn         ANDROID_RELR    0000000000000330 000330 000020 08   A  0   0  8

Those outputs are on a binary built for regular x86_64-unknown-linux-gnu target, but if you really want to identify Android executable you could perhaps rely on what is set as the dynamic linker for binary:

❯ clang --target=x86_64-linux-android ~/tmp/hello.c -### 2>&1 | tr " " "\n" | rg dynamic-linker -A1 | tr "\n" " "
"-dynamic-linker" "/system/bin/linker64"

The same trick won't work for shared objects though.

@mati865 mati865 marked this pull request as ready for review April 6, 2026 11:05
@philipc
Copy link
Copy Markdown
Contributor

philipc commented Apr 7, 2026

Currently, if I add the constants to readobj, it doesn't change any of the existing outputs.

That's fine, there's lot of constants that are listed in readobj with but have no tests.

if you really want to identify Android executable you could perhaps rely on what is set as the dynamic linker for binary

Thanks for the info. Let's leave that until we need it. I guess for now it's ok to treat these as if they weren't OS-specific constants. That's what LLVM seems to do.

Copy link
Copy Markdown
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 fbdc200 into gimli-rs:main Apr 7, 2026
10 checks passed
@mati865 mati865 deleted the push-qstwxkvqxwos branch April 7, 2026 18:22
@mati865
Copy link
Copy Markdown
Contributor Author

mati865 commented Apr 7, 2026

Thanks.

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