| # REQUIRES: aarch64 |
| |
| # RUN: rm -rf %t |
| |
| ## Ensure MTE globals doesn't work with REL (only RELA). |
| # RUN: yaml2obj %s -o %t.rel.o |
| # RUN: not ld.lld -shared --android-memtag-mode=sync %t.rel.o -o %t1.so 2>&1 | FileCheck %s --check-prefix=CHECK-RELA |
| # CHECK-RELA: non-RELA relocations are not allowed with memtag globals |
| --- !ELF |
| FileHeader: |
| Class: ELFCLASS64 |
| Data: ELFDATA2LSB |
| Type: ET_REL |
| Machine: EM_AARCH64 |
| SectionHeaderStringTable: .strtab |
| Sections: |
| - Name: .text |
| Type: SHT_PROGBITS |
| Flags: [ SHF_ALLOC, SHF_EXECINSTR ] |
| AddressAlign: 0x4 |
| Content: '00' |
| - Name: .data |
| Type: SHT_PROGBITS |
| Flags: [ SHF_WRITE, SHF_ALLOC ] |
| AddressAlign: 0x10 |
| Content: '00' |
| - Name: .memtag.globals.static |
| Type: SHT_AARCH64_MEMTAG_GLOBALS_STATIC |
| AddressAlign: 0x1 |
| - Name: .rel.memtag.globals.static |
| Type: SHT_REL |
| Flags: [ SHF_INFO_LINK ] |
| Link: .symtab |
| AddressAlign: 0x8 |
| Info: .memtag.globals.static |
| Relocations: |
| - Symbol: four |
| Type: R_AARCH64_NONE |
| - Type: SectionHeaderTable |
| Sections: |
| - Name: .strtab |
| - Name: .text |
| - Name: .data |
| - Name: .memtag.globals.static |
| - Name: .rel.memtag.globals.static |
| - Name: .symtab |
| Symbols: |
| - Name: four |
| Type: STT_OBJECT |
| Section: .data |
| Binding: STB_GLOBAL |
| Value: 0x0 |
| Size: 0x10 |
| |
| ## Functional testing for MTE globals. |
| # RUN: split-file %S/Inputs/aarch64-memtag-globals.s %t |
| # RUN: llvm-mc --filetype=obj -triple=aarch64-none-linux-android \ |
| # RUN: %t/input_1.s -o %t1.o |
| # RUN: llvm-mc --filetype=obj -triple=aarch64-none-linux-android \ |
| # RUN: %t/input_2.s -o %t2.o |
| # RUN: ld.lld -shared --android-memtag-mode=sync %t1.o %t2.o -o %t.so |
| |
| ## Normally relocations are printed before the symbol tables, so reorder it a |
| ## bit to make it easier on matching addresses of relocations up with the |
| ## symbols. |
| # RUN: llvm-readelf %t.so -s > %t.out |
| # RUN: llvm-readelf %t.so --section-headers --relocs --memtag >> %t.out |
| # RUN: FileCheck %s < %t.out |
| # RUN: llvm-objdump -Dz %t.so | FileCheck %s --check-prefix=CHECK-SPECIAL-RELOCS |
| |
| ## And ensure that --apply-dynamic-relocs is banned. |
| # RUN: not ld.lld --apply-dynamic-relocs -shared --android-memtag-mode=sync \ |
| # RUN: %t1.o %t2.o -o %t1.so 2>&1 | FileCheck %s --check-prefix=CHECK-DYNRELOC |
| # CHECK-DYNRELOC: --apply-dynamic-relocs cannot be used with MTE globals |
| |
| ## Ensure that fully statically linked executables just simply drop the MTE |
| ## globals stuff: special relocations, data in the place to be relocated, |
| ## dynamic entries, etc. |
| # RUN: llvm-mc --filetype=obj -triple=aarch64-none-linux-android \ |
| # RUN: %t/input_3.s -o %t3.o |
| # RUN: ld.lld -static --android-memtag-mode=sync %t1.o %t2.o %t3.o -o %t.static.so |
| # RUN: llvm-readelf -s --section-headers --relocs --memtag %t.static.so | \ |
| # RUN: FileCheck %s --check-prefix=CHECK-STATIC |
| # CHECK-STATIC-NOT: .memtag.globals.static |
| # CHECK-STATIC-NOT: DT_AARCH64_MEMTAG_ |
| |
| # CHECK-STATIC: There are no relocations in this file |
| # CHECK-STATIC: Memtag Dynamic Entries: |
| # CHECK-STATIC-NEXT: < none found > |
| |
| # RUN: llvm-objdump -tDz %t.static.so | FileCheck %s --check-prefix=CHECK-STATIC-SPECIAL-RELOCS |
| # CHECK-STATIC-SPECIAL-RELOCS: [[#%x,HIDDEN_GLOBAL_ADDR:]] {{.*}} .bss {{0*}}10 hidden_global |
| # CHECK-STATIC-SPECIAL-RELOCS: <pointer_to_hidden_global_end>: |
| # CHECK-STATIC-SPECIAL-RELOCS-NEXT: .word 0x{{0*}}[[#HIDDEN_GLOBAL_ADDR + 12]] |
| # CHECK-STATIC-SPECIAL-RELOCS-NEXT: .word 0x00000000 |
| # CHECK-STATIC-SPECIAL-RELOCS-NEXT: .word 0x00000000 |
| # CHECK-STATIC-SPECIAL-RELOCS-NEXT: .word 0x00000000 |
| # CHECK-STATIC-SPECIAL-RELOCS: <pointer_past_hidden_global_end>: |
| # CHECK-STATIC-SPECIAL-RELOCS-NEXT: .word 0x{{0*}}[[#HIDDEN_GLOBAL_ADDR + 16]] |
| # CHECK-STATIC-SPECIAL-RELOCS-NEXT: .word 0x00000000 |
| # CHECK-STATIC-SPECIAL-RELOCS-NEXT: .word 0x00000000 |
| # CHECK-STATIC-SPECIAL-RELOCS-NEXT: .word 0x00000000 |
| |
| # CHECK: Symbol table '.dynsym' contains |
| # CHECK-DAG: [[#%x,GLOBAL:]] 32 OBJECT GLOBAL DEFAULT [[#]] global{{$}} |
| # CHECK-DAG: [[#%x,GLOBAL_UNTAGGED:]] 4 OBJECT GLOBAL DEFAULT [[#]] global_untagged{{$}} |
| # CHECK-DAG: [[#%x,CONST_GLOBAL:]] 4 OBJECT GLOBAL DEFAULT [[#]] const_global{{$}} |
| # CHECK-DAG: [[#%x,GLOBAL_EXTERN:]] 16 OBJECT GLOBAL DEFAULT [[#]] global_extern{{$}} |
| # CHECK-DAG: [[#%x,GLOBAL_EXTERN_UNTAGGED:]] 4 OBJECT GLOBAL DEFAULT [[#]] global_extern_untagged{{$}} |
| # CHECK-DAG: 0 NOTYPE GLOBAL DEFAULT UND global_extern_outside_this_dso{{$}} |
| # CHECK-DAG: [[#%x,GLOBAL_EXTERN_CONST_DEFINITION_BUT_NONCONST_IMPORT:]] 4 OBJECT GLOBAL DEFAULT [[#]] global_extern_untagged_definition_but_tagged_import{{$}} |
| # CHECK-DAG: [[#%x,GLOBAL_EXTERN_UNTAGGED_DEFINITION_BUT_TAGGED_IMPORT:]] 4 OBJECT GLOBAL DEFAULT [[#]] global_extern_const_definition_but_nonconst_import{{$}} |
| # CHECK-DAG: [[#%x,POINTER_TO_GLOBAL:]] 16 OBJECT GLOBAL DEFAULT [[#]] pointer_to_global{{$}} |
| # CHECK-DAG: [[#%x,POINTER_INSIDE_GLOBAL:]] 16 OBJECT GLOBAL DEFAULT [[#]] pointer_inside_global{{$}} |
| # CHECK-DAG: [[#%x,POINTER_TO_GLOBAL_END:]] 16 OBJECT GLOBAL DEFAULT [[#]] pointer_to_global_end{{$}} |
| # CHECK-DAG: [[#%x,POINTER_PAST_GLOBAL_END:]] 16 OBJECT GLOBAL DEFAULT [[#]] pointer_past_global_end{{$}} |
| # CHECK-DAG: [[#%x,POINTER_TO_GLOBAL_UNTAGGED:]] 16 OBJECT GLOBAL DEFAULT [[#]] pointer_to_global_untagged{{$}} |
| # CHECK-DAG: [[#%x,POINTER_TO_CONST_GLOBAL:]] 16 OBJECT GLOBAL DEFAULT [[#]] pointer_to_const_global{{$}} |
| # CHECK-DAG: [[#%x,POINTER_TO_HIDDEN_CONST_GLOBAL:]] 16 OBJECT GLOBAL DEFAULT [[#]] pointer_to_hidden_const_global{{$}} |
| # CHECK-DAG: [[#%x,POINTER_TO_HIDDEN_GLOBAL:]] 16 OBJECT GLOBAL DEFAULT [[#]] pointer_to_hidden_global{{$}} |
| # CHECK-DAG: [[#%x,POINTER_TO_HIDDEN_GLOBAL_END:]] 16 OBJECT GLOBAL DEFAULT [[#]] pointer_to_hidden_global_end{{$}} |
| # CHECK-DAG: [[#%x,POINTER_PAST_HIDDEN_GLOBAL_END:]] 16 OBJECT GLOBAL DEFAULT [[#]] pointer_past_hidden_global_end{{$}} |
| # CHECK-DAG: [[#%x,POINTER_TO_HIDDEN_ATTR_GLOBAL:]] 16 OBJECT GLOBAL DEFAULT [[#]] pointer_to_hidden_attr_global{{$}} |
| # CHECK-DAG: [[#%x,POINTER_TO_HIDDEN_ATTR_CONST_GLOBAL:]] 16 OBJECT GLOBAL DEFAULT [[#]] pointer_to_hidden_attr_const_global{{$}} |
| # CHECK-DAG: [[#%x,POINTER_TO_GLOBAL_EXTERN:]] 16 OBJECT GLOBAL DEFAULT [[#]] pointer_to_global_extern{{$}} |
| # CHECK-DAG: [[#%x,POINTER_TO_GLOBAL_EXTERN_UNTAGGED:]] 16 OBJECT GLOBAL DEFAULT [[#]] pointer_to_global_extern_untagged{{$}} |
| # CHECK-DAG: [[#%x,POINTER_TO_GLOBAL_EXTERN_OUTSIDE_THIS_DSO:]] 16 OBJECT GLOBAL DEFAULT [[#]] pointer_to_global_extern_outside_this_dso{{$}} |
| # CHECK-DAG: [[#%x,POINTER_TO_GLOBAL_EXTERN_CONST_DEFINITION_BUT_NONCONST_IMPORT:]] 16 OBJECT GLOBAL DEFAULT [[#]] pointer_to_global_extern_const_definition_but_nonconst_import{{$}} |
| # CHECK-DAG: [[#%x,POINTER_TO_GLOBAL_EXTERN_UNTAGGED_DEFINITION_BUT_TAGGED_IMPORT:]] 16 OBJECT GLOBAL DEFAULT [[#]] pointer_to_global_extern_untagged_definition_but_tagged_import{{$}} |
| |
| # CHECK: Symbol table '.symtab' contains |
| # CHECK-DAG: [[#%x,HIDDEN_CONST_GLOBAL:]] 4 OBJECT LOCAL DEFAULT [[#]] hidden_const_global{{$}} |
| # CHECK-DAG: [[#%x,HIDDEN_GLOBAL:]] 16 OBJECT LOCAL DEFAULT [[#]] hidden_global{{$}} |
| # CHECK-DAG: [[#%x,HIDDEN_ATTR_GLOBAL:]] 16 OBJECT LOCAL HIDDEN [[#]] hidden_attr_global{{$}} |
| # CHECK-DAG: [[#%x,HIDDEN_ATTR_CONST_GLOBAL:]] 4 OBJECT LOCAL HIDDEN [[#]] hidden_attr_const_global{{$}} |
| |
| # CHECK: Section Headers: |
| # CHECK: .memtag.globals.dynamic AARCH64_MEMTAG_GLOBALS_DYNAMIC |
| # CHECK-NOT: .memtag.globals.static |
| # CHECK-NOT: AARCH64_MEMTAG_GLOBALS_STATIC |
| |
| # CHECK: Relocation section '.rela.dyn' |
| # CHECK-DAG: [[#POINTER_TO_GLOBAL]] {{.*}} R_AARCH64_ABS64 {{.*}} global + 0 |
| # CHECK-DAG: [[#POINTER_INSIDE_GLOBAL]] {{.*}} R_AARCH64_ABS64 {{.*}} global + 11 |
| # CHECK-DAG: [[#POINTER_TO_GLOBAL_END]] {{.*}} R_AARCH64_ABS64 {{.*}} global + 1e |
| # CHECK-DAG: [[#POINTER_PAST_GLOBAL_END]] {{.*}} R_AARCH64_ABS64 {{.*}} global + 30 |
| # CHECK-DAG: [[#POINTER_TO_GLOBAL_UNTAGGED]] {{.*}} R_AARCH64_ABS64 {{.*}} global_untagged + 0 |
| # CHECK-DAG: [[#POINTER_TO_CONST_GLOBAL]] {{.*}} R_AARCH64_ABS64 {{.*}} const_global + 0 |
| |
| ## RELATIVE relocations. |
| # CHECK-DAG: [[#POINTER_TO_HIDDEN_CONST_GLOBAL]] {{.*}} R_AARCH64_RELATIVE {{0*}}[[#HIDDEN_CONST_GLOBAL]] |
| # CHECK-DAG: [[#POINTER_TO_HIDDEN_GLOBAL]] {{.*}} R_AARCH64_RELATIVE {{0*}}[[#HIDDEN_GLOBAL]] |
| |
| ## AArch64 MemtagABI special RELATIVE relocation semantics, where the offset is encoded in the place. |
| # CHECK-DAG: [[#POINTER_TO_HIDDEN_GLOBAL_END]] {{.*}} R_AARCH64_RELATIVE {{0*}}[[#HIDDEN_GLOBAL + 12]] |
| # CHECK-SPECIAL-RELOCS: <pointer_to_hidden_global_end>: |
| # CHECK-SPECIAL-RELOCS-NEXT: .word 0x00000000 |
| # CHECK-SPECIAL-RELOCS-NEXT: .word 0x00000000 |
| # CHECK-DAG: [[#POINTER_PAST_HIDDEN_GLOBAL_END]] {{.*}} R_AARCH64_RELATIVE {{0*}}[[#HIDDEN_GLOBAL + 16]] |
| # CHECK-SPECIAL-RELOCS: <pointer_past_hidden_global_end>: |
| # CHECK-SPECIAL-RELOCS-NEXT: .word 0xfffffff0 |
| # CHECK-SPECIAL-RELOCS-NEXT: .word 0xffffffff |
| |
| ## More ABS64 relocations. |
| # CHECK-DAG: [[#POINTER_TO_GLOBAL_EXTERN]] {{[0-9a-f]+}} R_AARCH64_ABS64 {{[0-9a-f]+}} global_extern + 0 |
| # CHECK-DAG: [[#POINTER_TO_GLOBAL_EXTERN_UNTAGGED]] {{[0-9a-f]+}} R_AARCH64_ABS64 {{[0-9a-f]+}} global_extern_untagged + 0 |
| # CHECK-DAG: [[#POINTER_TO_GLOBAL_EXTERN_OUTSIDE_THIS_DSO]] {{[0-9a-f]+}} R_AARCH64_ABS64 {{[0-9a-f]+}} global_extern_outside_this_dso + 0 |
| # CHECK-DAG: [[#POINTER_TO_GLOBAL_EXTERN_CONST_DEFINITION_BUT_NONCONST_IMPORT]] {{[0-9a-f]+}} R_AARCH64_ABS64 {{[0-9a-f]+}} global_extern_const_definition_but_nonconst_import + 0 |
| # CHECK-DAG: [[#POINTER_TO_GLOBAL_EXTERN_UNTAGGED_DEFINITION_BUT_TAGGED_IMPORT]] {{[0-9a-f]+}} R_AARCH64_ABS64 {{[0-9a-f]+}} global_extern_untagged_definition_but_tagged_import + 0 |
| |
| # CHECK: Memtag Dynamic Entries |
| # CHECK-NEXT: AARCH64_MEMTAG_MODE: Synchronous (0) |
| # CHECK-NEXT: AARCH64_MEMTAG_HEAP: Disabled (0) |
| # CHECK-NEXT: AARCH64_MEMTAG_STACK: Disabled (0) |
| # CHECK-NEXT: AARCH64_MEMTAG_GLOBALS: 0x{{[0-9a-f]+}} |
| # CHECK-NEXT: AARCH64_MEMTAG_GLOBALSSZ: 23 |
| |
| # CHECK: Memtag Android Note |
| # CHECK-NEXT: Tagging Mode: SYNC |
| # CHECK-NEXT: Heap: Disabled |
| # CHECK-NEXT: Stack: Disabled |
| |
| ## Global variable order hopefully isn't too brittle of a test here, but this allows us to make sure |
| ## that we have all the global variables we expect, and no more. |
| # CHECK: Memtag Global Descriptors: |
| # CHECK-NEXT: 0x[[#POINTER_TO_GLOBAL]]: 0x10 |
| # CHECK-NEXT: 0x[[#POINTER_INSIDE_GLOBAL]]: 0x10 |
| # CHECK-NEXT: 0x[[#POINTER_TO_GLOBAL_END]]: 0x10 |
| # CHECK-NEXT: 0x[[#POINTER_PAST_GLOBAL_END]]: 0x10 |
| # CHECK-NEXT: 0x[[#POINTER_TO_GLOBAL_UNTAGGED]]: 0x10 |
| # CHECK-NEXT: 0x[[#POINTER_TO_CONST_GLOBAL]]: 0x10 |
| # CHECK-NEXT: 0x[[#POINTER_TO_HIDDEN_CONST_GLOBAL]]: 0x10 |
| # CHECK-NEXT: 0x[[#POINTER_TO_HIDDEN_GLOBAL]]: 0x10 |
| # CHECK-NEXT: 0x[[#POINTER_TO_HIDDEN_ATTR_GLOBAL]]: 0x10 |
| # CHECK-NEXT: 0x[[#POINTER_TO_HIDDEN_ATTR_CONST_GLOBAL]]: 0x10 |
| # CHECK-NEXT: 0x[[#POINTER_TO_HIDDEN_GLOBAL_END]]: 0x10 |
| # CHECK-NEXT: 0x[[#POINTER_PAST_HIDDEN_GLOBAL_END]]: 0x10 |
| # CHECK-NEXT: 0x[[#POINTER_TO_GLOBAL_EXTERN]]: 0x10 |
| # CHECK-NEXT: 0x[[#POINTER_TO_GLOBAL_EXTERN_UNTAGGED]]: 0x10 |
| # CHECK-NEXT: 0x[[#POINTER_TO_GLOBAL_EXTERN_OUTSIDE_THIS_DSO]]: 0x10 |
| # CHECK-NEXT: 0x[[#POINTER_TO_GLOBAL_EXTERN_CONST_DEFINITION_BUT_NONCONST_IMPORT]]: 0x10 |
| # CHECK-NEXT: 0x[[#POINTER_TO_GLOBAL_EXTERN_UNTAGGED_DEFINITION_BUT_TAGGED_IMPORT]]: 0x10 |
| # CHECK-NEXT: 0x[[#GLOBAL]]: 0x20 |
| # CHECK-NEXT: 0x[[#HIDDEN_ATTR_GLOBAL]]: 0x10 |
| # CHECK-NEXT: 0x[[#HIDDEN_GLOBAL]]: 0x10 |
| # CHECK-NEXT: 0x[[#GLOBAL_EXTERN]]: 0x10 |
| # CHECK-NOT: 0x |