Text file src/cmd/cgo/internal/test/stubtest_linux_ppc64x.S

     1  // Copyright 2023 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build (ppc64 || ppc64le) && linux && cgo
     6  
     7  // When linking C ELFv2 objects, the Go linker may need to insert calling stubs.
     8  // A call stub is usually needed when the ELFv2 st_other attribute is different
     9  // between caller and callee.
    10  //
    11  // The type of call stub inserted will vary depending on GOPPC64 and the
    12  // buildmode (e.g pie builds shared code, default builds fixed-position code).
    13  // CI is set up to run for P8 and P10 machines, and this test is run in both
    14  // pie and default modes.
    15  //
    16  // Several functions are written with interesting st_other attributes, and
    17  // call each other to test various calling combinations which require stubs.
    18  //
    19  // The call tree is as follows, starting from TestPPC64Stubs (A C function):
    20  // TestPPC64Stubs (compiled PIC by default by Go)
    21  //   notoc_func          [called TOC -> NOTOC (but R2 is preserved)]
    22  //     toc_func          [called NOTOC -> TOC]
    23  //       notoc_nor2_func [called TOC -> NOTOC]
    24  //       random          [dynamic TOC call]
    25  //     random		 [dynamic NOTOC call]
    26  //
    27  // Depending on the GOPPC64/buildmode used, and type of call, one of 7 stubs may need inserted:
    28  //
    29  // TOC   -> NOTOC:     Save R2, call global entry. (valid for any GOPPC64)
    30  //                      TOC save slot is rewrittent to restore TOC.
    31  // NOTOC -> TOC [P10]: A PIC call stub using P10 instructions to call the global entry
    32  // NOTOC -> TOC [P8]:  A PIC call stub using P8 instructions to call the global entry
    33  //
    34  // TOC   -> dynamic:              A PLT call stub is generated which saves R2.
    35  //                                 TOC save slot is rewritten to restore TOC.
    36  // NOTOC -> dynamic [P10]:        A stub using pcrel instructions is generated.
    37  // NOTOC -> dynamic [P8/default]: A P8 compatible, non-PIC stub is generated
    38  // NOTOC -> dynamic [P8/pie]:     A P8 compatible, PIC stub is generated
    39  //
    40  //
    41  // Some notes about other cases:
    42  //   TOC -> TOC, NOTOC -> NOTOC, NOTOC -> TOC  local calls do not require require call stubs.
    43  //   TOC -> NOTOC (R2 is preserved, st_other==0): A special case where a call stub is not needed.
    44  
    45  // This test requires a binutils with power10 and ELFv2 1.5 support. This is earliest verified version.
    46  .if .gasversion. >= 23500
    47  
    48  // A function which does not guarantee R2 is preserved.
    49  // R2 is clobbered here to ensure the stubs preserve it.
    50  	.globl	notoc_nor2_func
    51  	.type	notoc_nor2_func, @function
    52  notoc_nor2_func:
    53  	.localentry notoc_nor2_func,1
    54  	li	2,0
    55  	blr
    56  
    57  // A function which expects R2 to hold TOC, and has a distinct local entry.
    58  	.globl	toc_func
    59  	.type	toc_func, @function
    60  toc_func:
    61  	addis	2,12,.TOC.-toc_func@ha
    62  	addi	2,2,.TOC.-toc_func@l
    63  	.localentry toc_func, .-toc_func
    64  	mflr	0
    65  	std	0,16(1)
    66  	stdu	1,-32(1)
    67  
    68  	// Call a NOTOC function which clobbers R2.
    69  	bl	notoc_nor2_func
    70  	nop
    71  
    72  	// Call libc random. This should generate a TOC relative plt stub.
    73  	bl	random
    74  	nop
    75  
    76  	addi	1,1,32
    77  	ld 	0,16(1)
    78  	mtlr	0
    79  	blr
    80  
    81  // An ELFv2 st_other==0 function. It preserves R2 (TOC), but does not use it.
    82  	.globl	notoc_func
    83  	.type	notoc_func, @function
    84  notoc_func:
    85  	// Save R2 and LR and stack a frame.
    86  	mflr	0
    87  	std	0,16(1)
    88  	stdu	1,-32(1)
    89  
    90  	// Save R2 in TOC save slot.
    91  	std	2,24(1)
    92  
    93  	// clobber R2
    94  	li	2,0
    95  
    96  	// Call type2_func. A call stub from notoc to toc should be inserted.
    97  	bl	toc_func@notoc
    98  
    99  	// Call libc random. A notoc plt stub should be inserted.
   100  	bl	random@notoc
   101  
   102  	// Return 0 to indicate the test ran.
   103  	li	3,0
   104  
   105  	// Restore R2
   106  	ld	2,24(1)
   107  
   108  	// Restore LR and pop stack
   109  	addi	1,1,32
   110  	ld 	0,16(1)
   111  	mtlr	0
   112  	blr
   113  
   114  .else
   115  
   116  // A stub for older binutils
   117  	.globl	notoc_func
   118  	.type	notoc_func, @function
   119  notoc_func:
   120  	// Return 1 to indicate the test was skipped.
   121  	li	3,1
   122  	blr
   123  
   124  .endif
   125  

View as plain text