diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index 76216f8f00125e8c22cacbe8b5610b4b1d105eb4..16447f15b05af3165b8bb2354437aa337ea3e304 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -3000,7 +3000,6 @@ elfNN_aarch64_mkobject (bfd *abfd) #define GOT_TLS_GD 2 #define GOT_TLS_IE 4 #define GOT_TLSDESC_GD 8 -#define GOT_CAP 16 #define GOT_TLS_GD_ANY_P(type) ((type & GOT_TLS_GD) || (type & GOT_TLSDESC_GD)) @@ -5915,7 +5914,7 @@ aarch64_reloc_got_type (bfd_reloc_code_real_type r_type) case BFD_RELOC_MORELLO_ADR_GOT_PAGE: case BFD_RELOC_MORELLO_LD128_GOT_LO12_NC: - return GOT_CAP; + return GOT_NORMAL; case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC: case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21: @@ -5930,7 +5929,7 @@ aarch64_reloc_got_type (bfd_reloc_code_real_type r_type) case BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20: case BFD_RELOC_MORELLO_TLSDESC_CALL: case BFD_RELOC_MORELLO_TLSDESC_LD128_LO12: - return GOT_TLSDESC_GD | GOT_CAP; + return GOT_TLSDESC_GD | GOT_NORMAL; case BFD_RELOC_AARCH64_TLSDESC_ADD: case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12: @@ -6775,8 +6774,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto, || bfd_link_executable (info)) { /* This symbol is resolved locally. */ - outrel.r_info = (elf_aarch64_hash_entry (h)->got_type - == GOT_CAP + outrel.r_info = (globals->c64_rel ? ELFNN_R_INFO (0, MORELLO_R (IRELATIVE)) : ELFNN_R_INFO (0, AARCH64_R (IRELATIVE))); outrel.r_addend = (h->root.u.def.value @@ -8827,6 +8825,15 @@ elfNN_aarch64_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) return TRUE; elf_elfheader (obfd)->e_flags = in_flags; + /* Determine if we are linking purecap or not based on the flags of the + input binaries. Among other things this decides the size of GOT + entries. */ + if (in_flags & EF_AARCH64_CHERI_PURECAP) + { + struct elf_aarch64_link_hash_table *globals; + globals = elf_aarch64_hash_table (info); + globals->c64_rel = 1; + } if (bfd_get_arch (obfd) == bfd_get_arch (ibfd) && bfd_get_arch_info (obfd)->the_default) @@ -9295,12 +9302,6 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info, case BFD_RELOC_MORELLO_CALL26: case BFD_RELOC_MORELLO_JUMP26: - /* For dynamic symbols record caller information so that we can - decide what kind of PLT stubs to emit. */ - if (h != NULL) - elf_aarch64_hash_entry (h)->got_type = GOT_CAP; - /* Fall through. */ - case BFD_RELOC_AARCH64_ADD_LO12: case BFD_RELOC_AARCH64_ADR_GOT_PAGE: case BFD_RELOC_MORELLO_ADR_GOT_PAGE: @@ -9581,9 +9582,8 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info, /* We will already have issued an error message if there is a TLS/non-TLS mismatch, based on the symbol type. So just combine any TLS types needed. */ - if (old_got_type != GOT_UNKNOWN && old_got_type != GOT_NORMAL - && got_type != GOT_NORMAL && old_got_type != GOT_CAP - && got_type != GOT_CAP) + if (old_got_type != GOT_UNKNOWN && old_got_type != GOT_NORMAL && + got_type != GOT_NORMAL) got_type |= old_got_type; /* If the symbol is accessed by both IE and GD methods, we @@ -9593,13 +9593,6 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info, if ((got_type & GOT_TLS_IE) && GOT_TLS_GD_ANY_P (got_type)) got_type &= ~ (GOT_TLSDESC_GD | GOT_TLS_GD); - /* Prefer the capability reference. */ - if ((old_got_type & GOT_CAP) && (got_type & GOT_NORMAL)) - { - got_type &= ~GOT_NORMAL; - got_type |= GOT_CAP; - } - if (old_got_type != got_type) { if (h != NULL) @@ -9623,9 +9616,6 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info, case BFD_RELOC_MORELLO_CALL26: case BFD_RELOC_MORELLO_JUMP26: htab->c64_rel = 1; - if (h != NULL) - elf_aarch64_hash_entry (h)->got_type = GOT_CAP; - /* Fall through. */ case BFD_RELOC_AARCH64_CALL26: case BFD_RELOC_AARCH64_JUMP26: @@ -10221,8 +10211,7 @@ elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) if (got_type == GOT_UNKNOWN) { } - else if (got_type == GOT_NORMAL - || got_type == GOT_CAP) + else if (got_type == GOT_NORMAL) { h->got.offset = htab->root.sgot->size; htab->root.sgot->size += GOT_ENTRY_SIZE (htab); @@ -10235,11 +10224,11 @@ elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)) /* Any capability relocations required in a dynamic binary should go in the srelgot. */ - || ((got_type == GOT_CAP) && dyn)) + || (htab->c64_rel && dyn)) { htab->root.srelgot->size += RELOC_SIZE (htab); } - else if (bfd_link_executable (info) && (got_type == GOT_CAP)) + else if (bfd_link_executable (info) && htab->c64_rel) { /* If we have a capability relocation that is not handled by the case above then this must be a statically linked executable. */ @@ -10279,7 +10268,7 @@ elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h) /* On Morello support only TLSDESC_GD to TLSLE relaxation; for everything else we must emit a dynamic relocation. */ - || got_type & GOT_CAP)) + || htab->c64_rel)) { if (got_type & GOT_TLSDESC_GD) { @@ -10562,8 +10551,7 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd, } if (got_type & GOT_TLS_IE - || got_type & GOT_NORMAL - || got_type & GOT_CAP) + || got_type & GOT_NORMAL) { locals[i].got_offset = htab->root.sgot->size; htab->root.sgot->size += GOT_ENTRY_SIZE (htab); @@ -10586,17 +10574,16 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd, htab->root.srelgot->size += RELOC_SIZE (htab) * 2; if (got_type & GOT_TLS_IE - || got_type & GOT_NORMAL - || got_type & GOT_CAP) + || got_type & GOT_NORMAL) htab->root.srelgot->size += RELOC_SIZE (htab); } /* Static binary; put relocs into srelcaps. */ else if (bfd_link_executable (info) && !htab->root.dynamic_sections_created - && (got_type & GOT_CAP)) + && htab->c64_rel) htab->srelcaps->size += RELOC_SIZE (htab); /* Else capability relocation needs to go into srelgot. */ - else if (got_type & GOT_CAP) + else if (htab->c64_rel) htab->root.srelgot->size += RELOC_SIZE (htab); } else @@ -10917,7 +10904,7 @@ elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry *h, { /* If an STT_GNU_IFUNC symbol is locally defined, generate R_AARCH64_IRELATIVE instead of R_AARCH64_JUMP_SLOT. */ - rela.r_info = (elf_aarch64_hash_entry (h)->got_type == GOT_CAP + rela.r_info = (htab->c64_rel ? ELFNN_R_INFO (0, MORELLO_R (IRELATIVE)) : ELFNN_R_INFO (0, AARCH64_R (IRELATIVE))); rela.r_addend = (h->root.u.def.value @@ -10927,7 +10914,7 @@ elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry *h, else { /* Fill in the entry in the .rela.plt section. */ - rela.r_info = (elf_aarch64_hash_entry (h)->got_type == GOT_CAP + rela.r_info = (htab->c64_rel ? ELFNN_R_INFO (h->dynindx, MORELLO_R (JUMP_SLOT)) : ELFNN_R_INFO (h->dynindx, AARCH64_R (JUMP_SLOT))); rela.r_addend = 0; @@ -11047,11 +11034,8 @@ elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd, } } - bfd_boolean is_c64 = elf_aarch64_hash_entry (h)->got_type == GOT_CAP; - if (h->got.offset != (bfd_vma) - 1 - && (elf_aarch64_hash_entry (h)->got_type == GOT_NORMAL - || elf_aarch64_hash_entry (h)->got_type == GOT_CAP) + && elf_aarch64_hash_entry (h)->got_type == GOT_NORMAL /* Undefined weak symbol in static PIE resolves to 0 without any dynamic relocations. */ && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)) @@ -11104,7 +11088,7 @@ elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd, bfd_vma value = h->root.u.def.value + h->root.u.def.section->output_section->vma + h->root.u.def.section->output_offset; - if (is_c64) + if (htab->c64_rel) { rela.r_info = ELFNN_R_INFO (0, MORELLO_R (RELATIVE)); bfd_vma base_value = 0; @@ -11127,7 +11111,8 @@ elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd, bfd_put_NN (output_bfd, (bfd_vma) 0, htab->root.sgot->contents + h->got.offset); rela.r_info = ELFNN_R_INFO (h->dynindx, - (is_c64 ? MORELLO_R (GLOB_DAT) + (htab->c64_rel + ? MORELLO_R (GLOB_DAT) : AARCH64_R (GLOB_DAT))); rela.r_addend = 0; } diff --git a/ld/testsuite/ld-aarch64/emit-relocs-morello.d b/ld/testsuite/ld-aarch64/emit-relocs-morello.d index 4613b776edbe5b900386da94b450b3f16d416440..1a9be9b60bb9fcf15d74e65e9ebe224ac3d769b8 100644 --- a/ld/testsuite/ld-aarch64/emit-relocs-morello.d +++ b/ld/testsuite/ld-aarch64/emit-relocs-morello.d @@ -21,7 +21,7 @@ Disassembly of section .got: .* <.got>: .*: [0-9a-f]+ .* -.*: 00000000 .* + \.\.\. Disassembly of section .data: diff --git a/ld/testsuite/ld-aarch64/morello-capinit.d b/ld/testsuite/ld-aarch64/morello-capinit.d index 0050df311ac03275d00d69bb57ad7ab48f92eeea..edb0f42d9eeb83e4cd81018ab3de1932d07bbb45 100644 --- a/ld/testsuite/ld-aarch64/morello-capinit.d +++ b/ld/testsuite/ld-aarch64/morello-capinit.d @@ -1,6 +1,6 @@ -# This testsuite is used largely to check our handling of linker script defined +# This testcase is used largely to check our handling of linker script defined # symbols. In the general case we want to be able to access the entire output -# section following this symbol (i.e. we treat this symbol as a start symbol). +# section following the symbol (i.e. we treat the symbol as a start symbol). # # There is an exception for a symbol that points into an executable section -- # we want this to have the bounds of the PCC as we see it. @@ -8,6 +8,12 @@ # There is also an exception for a symbol which is *outside* of an output # section where we have a compatibility hack to try and guess whether it # represents the start of the next section or end of the previous section. +# +# Rather than check the PCC bounds exactly, we check that the PCC bounds are +# consistent for all symbols pointing into the text section (which allows for +# variation between aarch64-linux-gnu and aarch64-none-elf coming from an extra +# GNU_HASH section or a differing start position of the text causing a +# differing bounds action). #source: morello-capinit.s #as: -march=morello+c64 #ld: -static -pie -T morello-capinit.ld @@ -22,35 +28,37 @@ Disassembly of section \.inspectionsection: .*: [0-9a-f]+ .* .*: R_MORELLO_RELATIVE \*ABS\* .*: 00000000 .* -.*: 00000278 .* +#record: PCC_BOUNDS +.*: ([0-9a-f]+) .* .*: 04000000 .* +#check: PCC_SIZE string tolower $PCC_BOUNDS [0-9a-f]+ : .*: [0-9a-f]+ .* .*: R_MORELLO_RELATIVE \*ABS\* .*: 00000000 .* -.*: 00000278 .* +.*: PCC_SIZE .* .*: 04000000 .* [0-9a-f]+ : .*: [0-9a-f]+ .* .*: R_MORELLO_RELATIVE \*ABS\*\+0x[0-9a-f]+ .*: 00000000 .* -.*: 00000278 .* +.*: PCC_SIZE .* .*: 04000000 .* [0-9a-f]+ : .*: [0-9a-f]+ .* .*: R_MORELLO_RELATIVE \*ABS\*\+0x[0-9a-f]+ .*: 00000000 .* -.*: 00000278 .* +.*: PCC_SIZE .* .*: 04000000 .* [0-9a-f]+ : .*: [0-9a-f]+ .* .*: R_MORELLO_RELATIVE \*ABS\*\+0x[0-9a-f]+ .*: 00000000 .* -.*: 00000278 .* +.*: PCC_SIZE .* .*: 04000000 .* [0-9a-f]+ :