File: instrumentation-dup-jts.s

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (153 lines) | stat: -rwxr-xr-x 3,694 bytes parent folder | download | duplicates (15)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# This reproduces a bug with instrumentation when trying to instrument
# functions that share a jump table with multiple indirect jumps. Usually,
# each indirect jump that uses a JT will have its own copy of it. When
# this does not happen, we need to duplicate the jump table safely, so
# we can split the edges correctly (each copy of the jump table may have
# different split edges). For this to happen, we need to correctly match
# the sequence of instructions that perform the indirect jump to identify
# the base address of the jump table and patch it to point to the new
# cloned JT.
#
# Here we test this variant:
#	  movq	jt.2397(,%rax,8), %rax
#   jmp	*%rax
#
# Which is suboptimal since the compiler could've avoided using an intermediary
# register, but GCC does generate this code and it triggered a bug in our
# matcher. Usual jumps in non-PIC code have this format:
#
#   jmp	*jt.2397(,%rax,8)
#
# This is the C code fed to GCC:
#  #include <stdio.h>
#int interp(char* code) {
#    static void* jt[] = { &&op_end, &&op_inc, &&do_dec };
#    int pc = 0;
#    int res = 0;
#    goto *jt[code[pc++] - '0'];
#
#op_inc:
#    res += 1;
#    printf("%d\n", res);
#    goto *jt[code[pc++] - '0'];
#do_dec:
#    res -= 1;
#    printf("%d\n", res);
#    goto *jt[code[pc++] - '0'];
#op_end:
#    return res;
#}
#int main(int argc, char** argv) {
#    return interp(argv[1]);
#}


# REQUIRES: system-linux,bolt-runtime

# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown \
# RUN:   %s -o %t.o
# RUN: %clang %cflags -no-pie %t.o -o %t.exe -Wl,-q

# RUN: llvm-bolt %t.exe --instrument --instrumentation-file=%t.fdata \
# RUN:   -o %t.instrumented

# Instrumented program needs to finish returning zero
# RUN: %t.instrumented 120

# Test that the instrumented data makes sense
# RUN:  llvm-bolt %t.exe -o %t.bolted --data %t.fdata \
# RUN:    --reorder-blocks=ext-tsp --reorder-functions=hfsort+ \
# RUN:    --print-only=interp --print-finalized | FileCheck %s

# RUN: %t.bolted 120

# Check that our two indirect jumps are recorded in the fdata file and that
# each has its own independent profile
# CHECK:  Successors: .Ltmp1 (mispreds: 0, count: 1), .Ltmp0 (mispreds: 0, count: 0), .Ltmp2 (mispreds: 0, count: 0)
# CHECK:  Successors: .Ltmp0 (mispreds: 0, count: 1), .Ltmp2 (mispreds: 0, count: 1), .Ltmp1 (mispreds: 0, count: 0)

	.file	"test.c"
	.text
	.section	.rodata.str1.1,"aMS",@progbits,1
.LC0:
	.string	"%d\n"
	.text
	.p2align 4,,15
	.globl	interp
	.type	interp, @function
interp:
.LFB11:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	xorl	%ebp, %ebp
	pushq	%rbx
	.cfi_def_cfa_offset 24
	.cfi_offset 3, -24
	leaq	1(%rdi), %rbx
	subq	$8, %rsp
	.cfi_def_cfa_offset 32
	movsbl	(%rdi), %eax
	subl	$48, %eax
	cltq
	movq	jt.2397(,%rax,8), %rax
	jmp	*%rax
	.p2align 4,,10
	.p2align 3
.L3:
	addl	$1, %ebp
.L8:
	movl	%ebp, %esi
	movl	$.LC0, %edi
	xorl	%eax, %eax
	addq	$1, %rbx
	call	printf
	movsbl	-1(%rbx), %eax
	subl	$48, %eax
	cltq
	movq	jt.2397(,%rax,8), %rax
	jmp	*%rax
	.p2align 4,,10
	.p2align 3
.L6:
	addq	$8, %rsp
	.cfi_remember_state
	.cfi_def_cfa_offset 24
	movl	%ebp, %eax
	popq	%rbx
	.cfi_def_cfa_offset 16
	popq	%rbp
	.cfi_def_cfa_offset 8
	ret
	.p2align 4,,10
	.p2align 3
.L4:
	.cfi_restore_state
	subl	$1, %ebp
	jmp	.L8
	.cfi_endproc
.LFE11:
	.size	interp, .-interp
	.section	.text.startup,"ax",@progbits
	.p2align 4,,15
	.globl	main
	.type	main, @function
main:
.LFB12:
	.cfi_startproc
	movq	8(%rsi), %rdi
	jmp	interp
	.cfi_endproc
.LFE12:
	.size	main, .-main
	.section	.rodata
	.align 16
	.type	jt.2397, @object
	.size	jt.2397, 24
jt.2397:
	.quad	.L6
	.quad	.L3
	.quad	.L4
	.ident	"GCC: (GNU) 8"
	.section	.note.GNU-stack,"",@progbits