| # REQUIRES: system-linux |
| |
| ## Check that BOLT correctly updates ORC unwind information used by the Linux |
| ## kernel. |
| |
| # RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o |
| # RUN: %clang %cflags -nostdlib %t.o -o %t.exe \ |
| # RUN: -Wl,--image-base=0xffffffff80000000,--no-dynamic-linker,--no-eh-frame-hdr |
| |
| ## Verify reading contents of ORC sections. |
| |
| # RUN: llvm-bolt %t.exe --dump-orc -o /dev/null |& FileCheck %s \ |
| # RUN: --check-prefix=CHECK-ORC |
| |
| # CHECK-ORC: BOLT-INFO: ORC unwind information: |
| # CHECK-ORC-NEXT: {sp: 8, bp: 0, info: 0x5}: _start |
| # CHECK-ORC-NEXT: {terminator} |
| # CHECK-ORC-NEXT: {sp: 8, bp: 0, info: 0x5}: foo |
| # CHECK-ORC-NEXT: {sp: 16, bp: -16, info: 0x15}: foo |
| # CHECK-ORC-NEXT: {sp: 16, bp: -16, info: 0x14}: foo |
| # CHECK-ORC-NEXT: {sp: 8, bp: 0, info: 0x5}: foo |
| # CHECK-ORC-NEXT: {terminator} |
| # CHECK-ORC-NEXT: {terminator} |
| # CHECK-ORC-NEXT: {terminator} |
| |
| |
| ## Verify ORC bindings to instructions. |
| |
| # RUN: llvm-bolt %t.exe --print-normalized --dump-orc --print-orc -o %t.out \ |
| # RUN: --keep-nops=0 --bolt-info=0 |& FileCheck %s |
| |
| |
| ## Verify ORC bindings after rewrite. |
| |
| # RUN: llvm-bolt %t.out -o %t.out.1 --print-normalized --print-orc \ |
| # RUN: |& FileCheck %s |
| |
| ## Verify ORC binding after rewrite when some of the functions are skipped. |
| |
| # RUN: llvm-bolt %t.exe -o %t.out --skip-funcs=bar --bolt-info=0 --keep-nops=0 |
| # RUN: llvm-bolt %t.out -o %t.out.1 --print-normalized --print-orc \ |
| # RUN: |& FileCheck %s |
| |
| # CHECK: BOLT-INFO: Linux kernel binary detected |
| # CHECK: BOLT-INFO: parsed 9 ORC entries |
| |
| .text |
| .globl _start |
| .type _start, %function |
| _start: |
| # CHECK: Binary Function "_start" |
| |
| call foo |
| # CHECK: callq foo # ORC: {sp: 8, bp: 0, info: 0x5} |
| ret |
| .size _start, .-_start |
| |
| .globl foo |
| .type foo, %function |
| foo: |
| # CHECK: Binary Function "foo" |
| |
| push %rbp |
| # CHECK: pushq %rbp # ORC: {sp: 8, bp: 0, info: 0x5} |
| .L1: |
| mov %rsp, %rbp |
| # CHECK: movq %rsp, %rbp # ORC: {sp: 16, bp: -16, info: 0x15} |
| .L2: |
| pop %rbp |
| # CHECK: popq %rbp # ORC: {sp: 16, bp: -16, info: 0x14} |
| nop |
| .L3: |
| ret |
| # CHECK: retq # ORC: {sp: 8, bp: 0, info: 0x5} |
| .size foo, .-foo |
| |
| .globl bar |
| .type bar, %function |
| bar: |
| # CHECK: Binary Function "bar" |
| ret |
| ## Same ORC info propagated from foo above. |
| # CHECK: retq # ORC: {sp: 8, bp: 0, info: 0x5} |
| .L4: |
| .size bar, .-bar |
| |
| # CHECK: BOLT-WARNING: Linux kernel support is experimental |
| |
| .section .orc_unwind,"a",@progbits |
| .align 4 |
| .section .orc_unwind_ip,"a",@progbits |
| .align 4 |
| |
| ## ORC for _start. |
| .section .orc_unwind |
| .2byte 8 |
| .2byte 0 |
| .2byte 5 |
| .section .orc_unwind_ip |
| .long _start - . |
| |
| .section .orc_unwind |
| .2byte 0 |
| .2byte 0 |
| .2byte 0 |
| .section .orc_unwind_ip |
| .long foo - . |
| |
| ## ORC for foo. |
| .section .orc_unwind |
| .2byte 8 |
| .2byte 0 |
| .2byte 5 |
| .section .orc_unwind_ip |
| .long foo - . |
| |
| .section .orc_unwind |
| .2byte 16 |
| .2byte -16 |
| .2byte 21 |
| .section .orc_unwind_ip |
| .long .L1 - . |
| |
| .section .orc_unwind |
| .2byte 16 |
| .2byte -16 |
| .2byte 20 |
| .section .orc_unwind_ip |
| .long .L2 - . |
| |
| .section .orc_unwind |
| .2byte 8 |
| .2byte 0 |
| .2byte 5 |
| .section .orc_unwind_ip |
| .long .L3 - . |
| |
| .section .orc_unwind |
| .2byte 0 |
| .2byte 0 |
| .2byte 0 |
| .section .orc_unwind_ip |
| .long .L4 - . |
| |
| ## Duplicate terminator entries to test ORC reader. |
| .section .orc_unwind |
| .2byte 0 |
| .2byte 0 |
| .2byte 0 |
| .section .orc_unwind_ip |
| .long .L4 - . |
| |
| .section .orc_unwind |
| .2byte 0 |
| .2byte 0 |
| .2byte 0 |
| .section .orc_unwind_ip |
| .long .L4 - . |
| |
| ## Fake Linux Kernel sections. |
| .section __ksymtab,"a",@progbits |
| .section __ksymtab_gpl,"a",@progbits |