Skip to content

Instantly share code, notes, and snippets.

@rprichard
rprichard / patch-to-features.py
Created September 1, 2022 23:16
Current API19 (and 23) libc++ bug feature detection
# Android added %a printf starting with Android L (API 21).
Feature(name='android-no-printf-a',
when=lambda cfg: _isAndroid(cfg) and not _isAndroidApiAtLeast(cfg, 21) and
not programSucceeds(cfg, """
#include <stdio.h>
#include <string.h>
int main(int, char**) {
char buf[100];
snprintf(buf, sizeof(buf), "%a", 0.0);
@rprichard
rprichard / demo1.sh
Last active August 18, 2022 00:49
Demonstrate LLVM behavior with LTO and libcalls
#!/bin/bash
#
# Both the builtins archive and libc.so expose __aeabi_uidiv. Normally, when
# generating a shared library, the linker links __aeabi_uidiv from the builtins
# archive because it comes first on the linker command-line. However, when
# the only reference to __aeabi_uidiv results from LTO code generation, then the
# linker instead prefers the __aeabi_uidiv from libc.so.
set -e
@rprichard
rprichard / lldb-bugs.sh
Created June 26, 2021 01:00
lldb-bugs.sh
#!/bin/bash
cat >dso1.c <<EOF
#include <stdio.h>
void foo(void) {
printf("foo");
printf("\n");
}
EOF
@rprichard
rprichard / llvm-asm-thumb2-oddities.s
Created May 11, 2021 03:04
llvm-asm-thumb2-oddities.s
// GAS:
// arm-linux-gnueabi-gcc -march=armv7-a -c test.s
// GNU assembler (GNU Binutils for Debian) 2.35.2
// LLVM:
// /x/clang12/bin/clang -target armv7-linux-androideabi -c test.s
// clang version 12.0.0 (https://github.com/llvm/llvm-project/ b978a93635b584db380274d7c8963c73989944a1)
.syntax unified
.thumb
@rprichard
rprichard / scalbn-ldexp-test.c
Last active February 26, 2021 12:16
scalbn and ldexp rounding edge cases
#include <errno.h>
#include <fenv.h>
#include <float.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const char* round_mode_to_str(int round_mode) {
switch (round_mode) {
@rprichard
rprichard / output.txt
Created February 10, 2021 01:27
Mach-O doesn't have weak aliases
The linker seems to delete the weak version of _bar because it's overridden by a strong
version, and when it does, it also deletes _foo's instructions, so calling _foo actually
calls an unrelated function, _baz.
$ ./weak-to-weak-alias.sh
=== objdump
a.out: file format Mach-O 64-bit x86-64
@rprichard
rprichard / build.sh
Last active September 18, 2020 01:51
unwinder benchmark: lookup unwind info with many libraries
#!/bin/bash
set -e
NDK=/x/android-ndk-r21d
LIBUNWIND=/x/llvm-upstream/unwind-arm64-21/lib/libunwind.a
CXX="$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang++ -fuse-ld=lld $LIBUNWIND"
rm -fr out
mkdir -p out
@rprichard
rprichard / segv_leaf_unwind.c
Last active July 9, 2020 02:37
AArch64 Bionic unwind through __kernel_rt_sigreturn and either a kill syscall or a segfaulting leaf function (https://android-review.googlesource.com/c/platform/bionic/+/1355684)
/*
$ /x/android-ndk-r21d/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android28-clang segv_leaf_unwind.c -funwind-tables -Wl,--export-dynamic -Os
$ adb push a.out /data/local/tmp
./a.out: 1 file pushed, 0 skipped. 49.8 MB/s (119472 bytes in 0.002s)
$ adb shell /data/local/tmp/a.out
0x60e1e2f3a8 [sigsegv_handler]
0x73fcfe58c0 [__kernel_rt_sigreturn]
@rprichard
rprichard / run-gap-test.sh
Created April 4, 2020 07:11
Expose disjoint mapping unwinder bug with older Android devices
#!/bin/bash -e
#
# On an older device (Galaxy Nexus S running Android 4.1.2), an executable built
# with -z,max-page-size=0x10000 has a gap of size 0x1e000 between its R+E and
# R+W segments. If a DSO is loaded into the gap, then that DSO may hit a bug in
# old versions of Android where dl_unwind_find_exidx searches the executable
# rather than the DSO.
#
# This test program runs 10 times and typically fails a few times, depending on
# whether ASLR puts a DSO into the gap. Failure looks like so:
// https://issuetracker.google.com/147619573
// https://bugs.llvm.org/show_bug.cgi?id=43703
// The program waits for 7200 seconds, and prints the elapsed time every 10 seconds.
// It should always print an elapsed time of just over 10 seconds, but about every 1845
// seconds, it instead prints -1834.66 or so. (The performance counter frequency was 10MHz
// on Wine and the Windows 10 laptop I tested.)
#include <windows.h>