reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    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
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178
  179
  180
  181
  182
  183
  184
  185
  186
  187
  188
  189
  190
  191
  192
  193
  194
  195
  196
  197
  198
  199
  200
  201
  202
  203
  204
  205
  206
  207
  208
  209
  210
  211
  212
  213
  214
  215
  216
  217
  218
  219
  220
  221
  222
  223
  224
  225
  226
  227
  228
  229
  230
  231
  232
  233
  234
  235
  236
  237
  238
  239
  240
  241
  242
  243
  244
  245
  246
  247
  248
  249
  250
  251
  252
  253
  254
  255
  256
  257
  258
  259
  260
  261
  262
  263
  264
  265
  266
  267
  268
  269
  270
  271
  272
  273
  274
  275
  276
  277
  278
  279
  280
  281
  282
  283
  284
  285
  286
  287
  288
  289
  290
  291
  292
  293
  294
  295
  296
  297
  298
  299
  300
  301
  302
  303
  304
  305
  306
  307
  308
  309
  310
  311
  312
  313
  314
  315
  316
  317
  318
  319
  320
  321
  322
  323
  324
  325
  326
  327
  328
  329
  330
  331
  332
  333
  334
  335
  336
  337
  338
  339
# RUN: rm -rf %t && mkdir -p %t
# RUN: llvm-mc -triple=arm64-apple-darwin19 -filetype=obj -o %t/macho_reloc.o %s
# RUN: llvm-jitlink -noexec -define-abs external_data=0xdeadbeef -define-abs external_func=0xcafef00d -check=%s %t/macho_reloc.o

        .section        __TEXT,__text,regular,pure_instructions

        .p2align  2
Lanon_func:
        ret

        .globl  named_func
        .p2align  2
named_func:
        ret

# Check ARM64_RELOC_BRANCH26 handling with a call to a local function.
# The branch instruction only encodes 26 bits of the 28-bit possible branch
# range, since the low 2 bits will always be zero.
#
# jitlink-check: decode_operand(test_local_call, 0)[25:0] = (named_func - test_local_call)[27:2]
        .globl  test_local_call
        .p2align  2
test_local_call:
        bl   named_func

        .globl  _main
        .p2align  2
_main:
        ret

# Check ARM64_RELOC_GOTPAGE21 / ARM64_RELOC_GOTPAGEOFF12 handling with a
# reference to an external symbol. Validate both the reference to the GOT entry,
# and also the content of the GOT entry.
#
# For the GOTPAGE21/ADRP instruction we have the 21-bit delta to the 4k page
# containing the GOT entry for external_data.
#
# For the GOTPAGEOFF/LDR instruction we have the 12-bit offset of the entry
# within the page.
#
# jitlink-check: *{8}(got_addr(macho_reloc.o, external_data)) = external_data
# jitlink-check: decode_operand(test_gotpage21, 1) = (got_addr(macho_reloc.o, external_data)[32:12] - test_gotpage21[32:12])
# jitlink-check: decode_operand(test_gotpageoff12, 2) = got_addr(macho_reloc.o, external_data)[11:3]
        .globl  test_gotpage21
        .p2align  2
test_gotpage21:
        adrp  x0, external_data@GOTPAGE
        .globl  test_gotpageoff12
test_gotpageoff12:
        ldr   x0, [x0, external_data@GOTPAGEOFF]

# Check ARM64_RELOC_PAGE21 / ARM64_RELOC_PAGEOFF12 handling with a reference to
# a local symbol.
#
# For the PAGE21/ADRP instruction we have the 21-bit delta to the 4k page
# containing the global.
#
# For the GOTPAGEOFF12 relocation we test the ADD instruction, all LDR/GPR
# variants and all LDR/Neon variants.
#
# jitlink-check: decode_operand(test_page21, 1) = (named_data[32:12] - test_page21[32:12])
# jitlink-check: decode_operand(test_pageoff12add, 2) = named_data[11:0]
# jitlink-check: decode_operand(test_pageoff12gpr8, 2) = named_data[11:0]
# jitlink-check: decode_operand(test_pageoff12gpr16, 2) = named_data[11:1]
# jitlink-check: decode_operand(test_pageoff12gpr32, 2) = named_data[11:2]
# jitlink-check: decode_operand(test_pageoff12gpr64, 2) = named_data[11:3]
# jitlink-check: decode_operand(test_pageoff12neon8, 2) = named_data[11:0]
# jitlink-check: decode_operand(test_pageoff12neon16, 2) = named_data[11:1]
# jitlink-check: decode_operand(test_pageoff12neon32, 2) = named_data[11:2]
# jitlink-check: decode_operand(test_pageoff12neon64, 2) = named_data[11:3]
# jitlink-check: decode_operand(test_pageoff12neon128, 2) = named_data[11:4]
        .globl  test_page21
        .p2align  2
test_page21:
        adrp  x0, named_data@PAGE

        .globl  test_pageoff12add
test_pageoff12add:
        add   x0, x0, named_data@PAGEOFF

        .globl  test_pageoff12gpr8
test_pageoff12gpr8:
        ldrb  w0, [x0, named_data@PAGEOFF]

        .globl  test_pageoff12gpr16
test_pageoff12gpr16:
        ldrh  w0, [x0, named_data@PAGEOFF]

        .globl  test_pageoff12gpr32
test_pageoff12gpr32:
        ldr   w0, [x0, named_data@PAGEOFF]

        .globl  test_pageoff12gpr64
test_pageoff12gpr64:
        ldr   x0, [x0, named_data@PAGEOFF]

        .globl  test_pageoff12neon8
test_pageoff12neon8:
        ldr   b0, [x0, named_data@PAGEOFF]

        .globl  test_pageoff12neon16
test_pageoff12neon16:
        ldr   h0, [x0, named_data@PAGEOFF]

        .globl  test_pageoff12neon32
test_pageoff12neon32:
        ldr   s0, [x0, named_data@PAGEOFF]

        .globl  test_pageoff12neon64
test_pageoff12neon64:
        ldr   d0, [x0, named_data@PAGEOFF]

        .globl  test_pageoff12neon128
test_pageoff12neon128:
        ldr   q0, [x0, named_data@PAGEOFF]

# Check that calls to external functions trigger the generation of stubs and GOT
# entries.
#
# jitlink-check: decode_operand(test_external_call, 0) = (stub_addr(macho_reloc.o, external_func) - test_external_call)[27:2]
# jitlink-check: *{8}(got_addr(macho_reloc.o, external_func)) = external_func
        .globl  test_external_call
        .p2align  2
test_external_call:
        bl   external_func

        .section        __DATA,__data

# Storage target for non-extern ARM64_RELOC_SUBTRACTOR relocs.
        .p2align  3
Lanon_data:
        .quad   0x1111111111111111

# Check ARM64_RELOC_SUBTRACTOR Quad/Long in anonymous storage with anonymous
# minuend: "LA: .quad LA - B + C". The anonymous subtrahend form
# "LA: .quad B - LA + C" is not tested as subtrahends are not permitted to be
# anonymous.
#
# Note: +8 offset in expression below to accounts for sizeof(Lanon_data).
# jitlink-check: *{8}(section_addr(macho_reloc.o, __data) + 8) = (section_addr(macho_reloc.o, __data) + 8) - named_data + 2
        .p2align  3
Lanon_minuend_quad:
        .quad Lanon_minuend_quad - named_data + 2

# Note: +16 offset in expression below to accounts for sizeof(Lanon_data) + sizeof(Lanon_minuend_long).
# jitlink-check: *{4}(section_addr(macho_reloc.o, __data) + 16) = ((section_addr(macho_reloc.o, __data) + 16) - named_data + 2)[31:0]
        .p2align  2
Lanon_minuend_long:
        .long Lanon_minuend_long - named_data + 2

# Named quad storage target (first named atom in __data).
# Align to 16 for use as 128-bit load target.
        .globl named_data
        .p2align  4
named_data:
        .quad   0x2222222222222222
        .quad   0x3333333333333333

# An alt-entry point for named_data
        .globl named_data_alt_entry
        .p2align  3
        .alt_entry named_data_alt_entry
named_data_alt_entry:
        .quad   0

# Check ARM64_RELOC_UNSIGNED / quad / extern handling by putting the address of
# a local named function into a quad symbol.
#
# jitlink-check: *{8}named_func_addr_quad = named_func
        .globl  named_func_addr_quad
        .p2align  3
named_func_addr_quad:
        .quad   named_func

# Check ARM64_RELOC_UNSIGNED / quad / non-extern handling by putting the
# address of a local anonymous function into a quad symbol.
#
# jitlink-check: *{8}anon_func_addr_quad = section_addr(macho_reloc.o, __text)
        .globl  anon_func_addr_quad
        .p2align  3
anon_func_addr_quad:
        .quad   Lanon_func

# ARM64_RELOC_SUBTRACTOR Quad/Long in named storage with anonymous minuend
#
# jitlink-check: *{8}anon_minuend_quad1 = section_addr(macho_reloc.o, __data) - anon_minuend_quad1 + 2
# Only the form "B: .quad LA - B + C" is tested. The form "B: .quad B - LA + C" is
# invalid because the subtrahend can not be local.
        .globl  anon_minuend_quad1
        .p2align  3
anon_minuend_quad1:
        .quad Lanon_data - anon_minuend_quad1 + 2

# jitlink-check: *{4}anon_minuend_long1 = (section_addr(macho_reloc.o, __data) - anon_minuend_long1 + 2)[31:0]
        .globl  anon_minuend_long1
        .p2align  2
anon_minuend_long1:
        .long Lanon_data - anon_minuend_long1 + 2

# Check ARM64_RELOC_SUBTRACTOR Quad/Long in named storage with minuend and subtrahend.
# Both forms "A: .quad A - B + C" and "A: .quad B - A + C" are tested.
#
# Check "A: .quad B - A + C".
# jitlink-check: *{8}subtrahend_quad2 = (named_data - subtrahend_quad2 - 2)
        .globl  subtrahend_quad2
        .p2align  3
subtrahend_quad2:
        .quad named_data - subtrahend_quad2 - 2

# Check "A: .long B - A + C".
# jitlink-check: *{4}subtrahend_long2 = (named_data - subtrahend_long2 - 2)[31:0]
        .globl  subtrahend_long2
        .p2align  2
subtrahend_long2:
        .long named_data - subtrahend_long2 - 2

# Check "A: .quad A - B + C".
# jitlink-check: *{8}minuend_quad3 = (minuend_quad3 - named_data - 2)
        .globl  minuend_quad3
        .p2align  3
minuend_quad3:
        .quad minuend_quad3 - named_data - 2

# Check "A: .long B - A + C".
# jitlink-check: *{4}minuend_long3 = (minuend_long3 - named_data - 2)[31:0]
        .globl  minuend_long3
        .p2align  2
minuend_long3:
        .long minuend_long3 - named_data - 2

# Check ARM64_RELOC_SUBTRACTOR handling for exprs of the form
# "A: .quad/long B - C + D", where 'B' or 'C' is at a fixed offset from 'A'
# (i.e. is part of an alt_entry chain that includes 'A').
#
# Check "A: .long B - C + D" where 'B' is an alt_entry for 'A'.
# jitlink-check: *{4}subtractor_with_alt_entry_minuend_long = (subtractor_with_alt_entry_minuend_long_B - named_data + 2)[31:0]
        .globl  subtractor_with_alt_entry_minuend_long
        .p2align  2
subtractor_with_alt_entry_minuend_long:
        .long subtractor_with_alt_entry_minuend_long_B - named_data + 2

        .globl  subtractor_with_alt_entry_minuend_long_B
        .p2align  2
        .alt_entry subtractor_with_alt_entry_minuend_long_B
subtractor_with_alt_entry_minuend_long_B:
        .long 0

# Check "A: .quad B - C + D" where 'B' is an alt_entry for 'A'.
# jitlink-check: *{8}subtractor_with_alt_entry_minuend_quad = (subtractor_with_alt_entry_minuend_quad_B - named_data + 2)
        .globl  subtractor_with_alt_entry_minuend_quad
        .p2align  3
subtractor_with_alt_entry_minuend_quad:
        .quad subtractor_with_alt_entry_minuend_quad_B - named_data + 2

        .globl  subtractor_with_alt_entry_minuend_quad_B
        .p2align  3
        .alt_entry subtractor_with_alt_entry_minuend_quad_B
subtractor_with_alt_entry_minuend_quad_B:
        .quad 0

# Check "A: .long B - C + D" where 'C' is an alt_entry for 'A'.
# jitlink-check: *{4}subtractor_with_alt_entry_subtrahend_long = (named_data - subtractor_with_alt_entry_subtrahend_long_B + 2)[31:0]
        .globl  subtractor_with_alt_entry_subtrahend_long
        .p2align  2
subtractor_with_alt_entry_subtrahend_long:
        .long named_data - subtractor_with_alt_entry_subtrahend_long_B + 2

        .globl  subtractor_with_alt_entry_subtrahend_long_B
        .p2align  2
        .alt_entry subtractor_with_alt_entry_subtrahend_long_B
subtractor_with_alt_entry_subtrahend_long_B:
        .long 0

# Check "A: .quad B - C + D" where 'B' is an alt_entry for 'A'.
# jitlink-check: *{8}subtractor_with_alt_entry_subtrahend_quad = (named_data - subtractor_with_alt_entry_subtrahend_quad_B + 2)
        .globl  subtractor_with_alt_entry_subtrahend_quad
        .p2align  3
subtractor_with_alt_entry_subtrahend_quad:
        .quad named_data - subtractor_with_alt_entry_subtrahend_quad_B + 2

        .globl  subtractor_with_alt_entry_subtrahend_quad_B
        .p2align  3
        .alt_entry subtractor_with_alt_entry_subtrahend_quad_B
subtractor_with_alt_entry_subtrahend_quad_B:
        .quad 0

# Check ARM64_POINTER_TO_GOT handling.
# ARM64_POINTER_TO_GOT is a delta-32 to a GOT entry.
#
# jitlink-check: *{4}test_got = (got_addr(macho_reloc.o, external_data) - test_got)[31:0]
        .globl test_got
        .p2align  2
test_got:
        .long   external_data@got - .

# Check that unreferenced atoms in no-dead-strip sections are not dead stripped.
# We need to use a local symbol for this as any named symbol will end up in the
# ORC responsibility set, which is automatically marked live and would couse
# spurious passes.
#
# jitlink-check: *{8}section_addr(macho_reloc.o, __nds_test_sect) = 0
        .section        __DATA,__nds_test_sect,regular,no_dead_strip
        .quad 0

# Check that unreferenced local symbols that have been marked no-dead-strip are
# not dead-striped.
#
# jitlink-check: *{8}section_addr(macho_reloc.o, __nds_test_nlst) = 0
        .section       __DATA,__nds_test_nlst,regular
        .no_dead_strip no_dead_strip_test_symbol
no_dead_strip_test_symbol:
        .quad 0

# Check that explicit zero-fill symbols are supported
# jitlink-check: *{8}zero_fill_test = 0
        .globl zero_fill_test
.zerofill __DATA,__zero_fill_test,zero_fill_test,8,3

# Check that section alignments are respected.
# We test this by introducing two segments with alignment 8, each containing one
# byte of data. We require both symbols to have an aligned address.
#
# jitlink-check: section_alignment_check1[2:0] = 0
# jitlink-check: section_alignment_check2[2:0] = 0
        .section        __DATA,__sec_align_chk1
        .p2align 3

        .globl section_alignment_check1
section_alignment_check1:
        .byte 0

        .section        __DATA,__sec_align_chk2
        .p2align 3

        .globl section_alignment_check2
section_alignment_check2:
        .byte 0

.subsections_via_symbols