brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.6 KiB · 26f3ab3 Raw
154 lines · plain
1# This reproduces a bug with instrumentation when trying to instrument2# functions that share a jump table with multiple indirect jumps. Usually,3# each indirect jump that uses a JT will have its own copy of it. When4# this does not happen, we need to duplicate the jump table safely, so5# we can split the edges correctly (each copy of the jump table may have6# different split edges). For this to happen, we need to correctly match7# the sequence of instructions that perform the indirect jump to identify8# the base address of the jump table and patch it to point to the new9# cloned JT.10#11# Here we test this variant:12#	  movq	jt.2397(,%rax,8), %rax13#   jmp	*%rax14#15# Which is suboptimal since the compiler could've avoided using an intermediary16# register, but GCC does generate this code and it triggered a bug in our17# matcher. Usual jumps in non-PIC code have this format:18#19#   jmp	*jt.2397(,%rax,8)20#21# This is the C code fed to GCC:22#  #include <stdio.h>23#int interp(char* code) {24#    static void* jt[] = { &&op_end, &&op_inc, &&do_dec };25#    int pc = 0;26#    int res = 0;27#    goto *jt[code[pc++] - '0'];28#29#op_inc:30#    res += 1;31#    printf("%d\n", res);32#    goto *jt[code[pc++] - '0'];33#do_dec:34#    res -= 1;35#    printf("%d\n", res);36#    goto *jt[code[pc++] - '0'];37#op_end:38#    return res;39#}40#int main(int argc, char** argv) {41#    return interp(argv[1]);42#}43 44 45# REQUIRES: system-linux,bolt-runtime46 47# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown \48# RUN:   %s -o %t.o49# RUN: %clang %cflags -no-pie %t.o -o %t.exe -Wl,-q50 51# RUN: llvm-bolt %t.exe --instrument --instrumentation-file=%t.fdata \52# RUN:   -o %t.instrumented53 54# Instrumented program needs to finish returning zero55# RUN: %t.instrumented 12056 57# Test that the instrumented data makes sense58# RUN:  llvm-bolt %t.exe -o %t.bolted --data %t.fdata \59# RUN:    --reorder-blocks=ext-tsp --reorder-functions=hfsort+ \60# RUN:    --print-only=interp --print-finalized | FileCheck %s61 62# RUN: %t.bolted 12063 64# Check that our two indirect jumps are recorded in the fdata file and that65# each has its own independent profile66# CHECK:  Successors: .Ltmp1 (mispreds: 0, count: 1), .Ltmp0 (mispreds: 0, count: 0), .Ltmp2 (mispreds: 0, count: 0)67# CHECK:  Successors: .Ltmp0 (mispreds: 0, count: 1), .Ltmp2 (mispreds: 0, count: 1), .Ltmp1 (mispreds: 0, count: 0)68 69	.file	"test.c"70	.text71	.section	.rodata.str1.1,"aMS",@progbits,172.LC0:73	.string	"%d\n"74	.text75	.p2align 4,,1576	.globl	interp77	.type	interp, @function78interp:79.LFB11:80	.cfi_startproc81	pushq	%rbp82	.cfi_def_cfa_offset 1683	.cfi_offset 6, -1684	xorl	%ebp, %ebp85	pushq	%rbx86	.cfi_def_cfa_offset 2487	.cfi_offset 3, -2488	leaq	1(%rdi), %rbx89	subq	$8, %rsp90	.cfi_def_cfa_offset 3291	movsbl	(%rdi), %eax92	subl	$48, %eax93	cltq94	movq	jt.2397(,%rax,8), %rax95	jmp	*%rax96	.p2align 4,,1097	.p2align 398.L3:99	addl	$1, %ebp100.L8:101	movl	%ebp, %esi102	movl	$.LC0, %edi103	xorl	%eax, %eax104	addq	$1, %rbx105	call	printf106	movsbl	-1(%rbx), %eax107	subl	$48, %eax108	cltq109	movq	jt.2397(,%rax,8), %rax110	jmp	*%rax111	.p2align 4,,10112	.p2align 3113.L6:114	addq	$8, %rsp115	.cfi_remember_state116	.cfi_def_cfa_offset 24117	movl	%ebp, %eax118	popq	%rbx119	.cfi_def_cfa_offset 16120	popq	%rbp121	.cfi_def_cfa_offset 8122	ret123	.p2align 4,,10124	.p2align 3125.L4:126	.cfi_restore_state127	subl	$1, %ebp128	jmp	.L8129	.cfi_endproc130.LFE11:131	.size	interp, .-interp132	.section	.text.startup,"ax",@progbits133	.p2align 4,,15134	.globl	main135	.type	main, @function136main:137.LFB12:138	.cfi_startproc139	movq	8(%rsi), %rdi140	jmp	interp141	.cfi_endproc142.LFE12:143	.size	main, .-main144	.section	.rodata145	.align 16146	.type	jt.2397, @object147	.size	jt.2397, 24148jt.2397:149	.quad	.L6150	.quad	.L3151	.quad	.L4152	.ident	"GCC: (GNU) 8"153	.section	.note.GNU-stack,"",@progbits154