boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

338-literal-addr-deref.c (1544B)


      1 /* Store/load through a pointer whose address is a plain integer
      2  * constant (no symbol). On aarch64, stock arm64-gen.c (0.9.26) handles
      3  * only the VT_CONST | VT_LVAL | VT_SYM case in store/load and asserts
      4  * out on bare VT_CONST | VT_LVAL — i.e. `*(volatile T*)0x1234`. The
      5  * matching x86_64 path goes through gen_modrm and the riscv64 path has
      6  * an explicit fr==VT_CONST branch, so neither tripped before. The
      7  * vendor/tcc/patches/arm64-{store,load}-const-lvalue
      8  * pair adds the missing case.
      9  *
     10  * The volatile global keeps tcc from constant-propagating the
     11  * branch to false, so the body must emit code; the runtime value
     12  * stays 0 so we never actually dereference 0x1234 / 0x5678. The test
     13  * passes if the program both compiles and exits 0.
     14  *
     15  * Surfaced when building musl on aarch64 (boot4): __libc_start_main,
     16  * the mallocng family, abort, asctime_r and friends emit this pattern
     17  * through folded weak-hidden references and trip the assert.
     18  */
     19 
     20 static volatile int never = 0;
     21 
     22 int main(void)
     23 {
     24 	if (never) {
     25 		*(volatile unsigned char *)0x1234 = 5;          /* store */
     26 		unsigned char b = *(volatile unsigned char *)0x1234;
     27 
     28 		*(volatile unsigned short *)0x2000 = 0xbeef;    /* sized variants */
     29 		unsigned short s = *(volatile unsigned short *)0x2000;
     30 
     31 		*(volatile unsigned int *)0x3000 = 0xdeadbeef;
     32 		unsigned int i = *(volatile unsigned int *)0x3000;
     33 
     34 		*(volatile unsigned long *)0x4000 = 0x1122334455667788UL;
     35 		unsigned long l = *(volatile unsigned long *)0x4000;
     36 
     37 		return (int)(b + s + i + l);
     38 	}
     39 	return 0;
     40 }