From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-x42f.google.com (mail-wr1-x42f.google.com [IPv6:2a00:1450:4864:20::42f]) by sourceware.org (Postfix) with ESMTPS id 6DFA3382E464 for ; Fri, 16 Dec 2022 02:14:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 6DFA3382E464 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=harmstone.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-wr1-x42f.google.com with SMTP id y16so1210317wrm.2 for ; Thu, 15 Dec 2022 18:14:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=GEMfcukGMvdblNI4yEXEsFU/pDYCJ/+cmFoyJqHYp6o=; b=ajefdyiwOjmo2J1WBO5QmXO9JTKoT9SzlnUYSsTLDzbtz2Kyburh04NOkociFD0KTO tU6CL6WYeFxyJ03R1cpuyLEfRiwaQ5aaPWL/PWKVpf2D2j8OMeAewyS0q1yC4rT3a8eX p/+ugZ599FmiFNHM3QSefW+EBF6C92YhC7cbCNDpncId1kNzRUwmOHG5Osf28WYRDhmJ +/bK6RERCvxL7yU28fDOMv/caJ9lm4u/oKSzFgyJKy9qL9GdVxeBDoM6mFyobisuzVJD d7VkIjiSnpBggE8P3edNo9A9hUABV5dacVS9wBUfFlQ2CdMJ+3DjoxW+zLT/SGTiHnzO tRNA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=GEMfcukGMvdblNI4yEXEsFU/pDYCJ/+cmFoyJqHYp6o=; b=I/vQYEy7wEppxCHoRqDB7lvxjA77jQMUaXz35LWIyjb/nW13yLJkyMoCF826pJztlZ CP0kPTTJUl9jd47J2lcAtRuxDJKaShmQSCKVgDjobo/FszVw3OLeaqXbAyrRNabig4IV 7fpfGF3qvpPGyJ+PltlFD6FmOJlvOOee4H06MamzUSzVVLqVqZi2F4Nc5vXiCpaLad9k lKBxhQtVhj1nXQGbh84TkLX13zVySgfkuYbzVjoNSeiRvIl3ZbsK+4+YJeZiqZ/dz44s b4JmjN2sQEh/bJVZcz1Kdz6mlZcHEopY3HU5WFZAHO6qmFeYLeACQkxeVclTXPe6g5Mr f+bA== X-Gm-Message-State: ANoB5pntTJwOeDEzX+RvSHsEuH/k4R3v4HGMWZLz9FxyPIgNsPhfpPF7 qHGCXrgu7EasJSzfniVIWys511/P1I8= X-Google-Smtp-Source: AA0mqf6rws4RtNaFVee2gRU9pAdJkq26/IYgST9q3y7Mkzwn3DCk/MwDiVbR4FHLHmoQL0jKCi1Bkg== X-Received: by 2002:a5d:564a:0:b0:24c:f1ca:b2df with SMTP id j10-20020a5d564a000000b0024cf1cab2dfmr16914526wrw.67.1671156846268; Thu, 15 Dec 2022 18:14:06 -0800 (PST) Received: from beren.harmstone.com ([2a02:8010:64ea:0:8eb8:7eff:fe53:9d5f]) by smtp.gmail.com with ESMTPSA id s4-20020a5d5104000000b0024207ed4ce0sm883149wrt.58.2022.12.15.18.14.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 15 Dec 2022 18:14:05 -0800 (PST) Sender: Mark Harmstone From: Mark Harmstone To: binutils@sourceware.org, wej22007@outlook.com, zac.walker@linaro.org Cc: Mark Harmstone Subject: [PATCH 3/5] Add pe-aarch64 relocations Date: Fri, 16 Dec 2022 02:13:58 +0000 Message-Id: <20221216021400.22309-3-mark@harmstone.com> X-Mailer: git-send-email 2.37.4 In-Reply-To: <20221216021400.22309-1-mark@harmstone.com> References: <20221216021400.22309-1-mark@harmstone.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-9.4 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_EF,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM,GIT_PATCH_0,HEADER_FROM_DIFFERENT_DOMAINS,RCVD_IN_DNSWL_NONE,SCC_10_SHORT_WORD_LINES,SCC_20_SHORT_WORD_LINES,SCC_35_SHORT_WORD_LINES,SCC_5_SHORT_WORD_LINES,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: This adds the remaining pe-aarch64 relocations, and gets them working. It also brings in the constant directives from ELF, as otherwise .word would be 2 rather than 4 bytes, and .xword and .dword wouldn't be defined. --- bfd/coff-aarch64.c | 651 +++++++++++++++++++++++++++++- bfd/config.bfd | 6 - gas/config/tc-aarch64.c | 24 +- gas/testsuite/gas/pe/pe-aarch64.d | 214 +++++++++- gas/testsuite/gas/pe/pe-aarch64.s | 152 ++++++- ld/testsuite/ld-pe/aarch64.d | 148 +++++++ ld/testsuite/ld-pe/aarch64a.s | 149 +++++++ ld/testsuite/ld-pe/aarch64b.s | 6 + ld/testsuite/ld-pe/pe.exp | 10 +- 9 files changed, 1318 insertions(+), 42 deletions(-) create mode 100644 ld/testsuite/ld-pe/aarch64.d create mode 100644 ld/testsuite/ld-pe/aarch64a.s create mode 100644 ld/testsuite/ld-pe/aarch64b.s diff --git a/bfd/coff-aarch64.c b/bfd/coff-aarch64.c index 0faa75c63d2..e181ce66aa0 100644 --- a/bfd/coff-aarch64.c +++ b/bfd/coff-aarch64.c @@ -39,59 +39,296 @@ #include "libcoff.h" +static bfd_reloc_status_type +coff_aarch64_addr64_reloc (bfd *abfd ATTRIBUTE_UNUSED, + arelent *reloc_entry, + asymbol *symbol ATTRIBUTE_UNUSED, + void *data, + asection *input_section ATTRIBUTE_UNUSED, + bfd *output_bfd ATTRIBUTE_UNUSED, + char **error_message ATTRIBUTE_UNUSED) +{ + uint64_t val = reloc_entry->addend; + + bfd_putl64 (val, data + reloc_entry->address); + + return bfd_reloc_ok; +} + +static bfd_reloc_status_type +coff_aarch64_addr32_reloc (bfd *abfd ATTRIBUTE_UNUSED, + arelent *reloc_entry, + asymbol *symbol ATTRIBUTE_UNUSED, + void *data, + asection *input_section ATTRIBUTE_UNUSED, + bfd *output_bfd ATTRIBUTE_UNUSED, + char **error_message ATTRIBUTE_UNUSED) +{ + uint64_t val; + + if ((int64_t) reloc_entry->addend > 0x7fffffff + || (int64_t) reloc_entry->addend < -0x7fffffff) + return bfd_reloc_overflow; + + val = reloc_entry->addend; + + bfd_putl32 ((uint32_t) val, data + reloc_entry->address); + + return bfd_reloc_ok; +} + +static bfd_reloc_status_type +coff_aarch64_branch26_reloc (bfd *abfd ATTRIBUTE_UNUSED, + arelent *reloc_entry, + asymbol *symbol ATTRIBUTE_UNUSED, + void *data, + asection *input_section ATTRIBUTE_UNUSED, + bfd *output_bfd ATTRIBUTE_UNUSED, + char **error_message ATTRIBUTE_UNUSED) +{ + uint32_t op; + int32_t param; + + op = bfd_getl32 (data + reloc_entry->address); + param = reloc_entry->addend; + + if (param > 0x7ffffff || param < -0x8000000) + return bfd_reloc_overflow; + + op &= 0xfc000000; + op |= (param >> 2) & 0x3ffffff; + + bfd_putl32 (op, data + reloc_entry->address); + + return bfd_reloc_ok; +} + +static bfd_reloc_status_type +coff_aarch64_rel21_reloc (bfd *abfd ATTRIBUTE_UNUSED, + arelent *reloc_entry, + asymbol *symbol ATTRIBUTE_UNUSED, + void *data, + asection *input_section ATTRIBUTE_UNUSED, + bfd *output_bfd ATTRIBUTE_UNUSED, + char **error_message ATTRIBUTE_UNUSED) +{ + uint32_t op; + int32_t param; + + op = bfd_getl32 (data + reloc_entry->address); + param = reloc_entry->addend; + + if (param > 0xfffff || param < -0x100000) + return bfd_reloc_overflow; + + op &= 0x9f00001f; + op |= (param & 0x1ffffc) << 3; + op |= (param & 0x3) << 29; + + bfd_putl32 (op, data + reloc_entry->address); + + return bfd_reloc_ok; +} + +static bfd_reloc_status_type +coff_aarch64_po12l_reloc (bfd *abfd ATTRIBUTE_UNUSED, + arelent *reloc_entry, + asymbol *symbol ATTRIBUTE_UNUSED, + void *data, + asection *input_section ATTRIBUTE_UNUSED, + bfd *output_bfd ATTRIBUTE_UNUSED, + char **error_message ATTRIBUTE_UNUSED) +{ + uint32_t op; + int32_t param; + + op = bfd_getl32 (data + reloc_entry->address); + param = reloc_entry->addend & 0xfff; + + /* top two bits represent how much addend should be shifted */ + param >>= op >> 30; + + op &= 0xffc003ff; + op |= param << 10; + + bfd_putl32 (op, data + reloc_entry->address); + + return bfd_reloc_ok; +} + +static bfd_reloc_status_type +coff_aarch64_branch19_reloc (bfd *abfd ATTRIBUTE_UNUSED, + arelent *reloc_entry, + asymbol *symbol ATTRIBUTE_UNUSED, + void *data, + asection *input_section ATTRIBUTE_UNUSED, + bfd *output_bfd ATTRIBUTE_UNUSED, + char **error_message ATTRIBUTE_UNUSED) +{ + uint32_t op; + int32_t param; + + op = bfd_getl32 (data + reloc_entry->address); + param = reloc_entry->addend; + + if (param > 0xfffff || param < -0x100000) + return bfd_reloc_overflow; + + op &= 0xff00001f; + op |= ((param >> 2) & 0x7ffff) << 5; + + bfd_putl32 (op, data + reloc_entry->address); + + return bfd_reloc_ok; +} + +static bfd_reloc_status_type +coff_aarch64_branch14_reloc (bfd *abfd ATTRIBUTE_UNUSED, + arelent *reloc_entry, + asymbol *symbol ATTRIBUTE_UNUSED, + void *data, + asection *input_section ATTRIBUTE_UNUSED, + bfd *output_bfd ATTRIBUTE_UNUSED, + char **error_message ATTRIBUTE_UNUSED) +{ + uint32_t op; + int32_t param; + + op = bfd_getl32 (data + reloc_entry->address); + param = reloc_entry->addend; + + if (param > 0x7fff || param < -0x8000) + return bfd_reloc_overflow; + + op &= 0xfff8001f; + op |= ((param >> 2) & 0x3fff) << 5; + + bfd_putl32 (op, data + reloc_entry->address); + + return bfd_reloc_ok; +} + +static bfd_reloc_status_type +coff_aarch64_po12a_reloc (bfd *abfd ATTRIBUTE_UNUSED, + arelent *reloc_entry, + asymbol *symbol ATTRIBUTE_UNUSED, + void *data, + asection *input_section ATTRIBUTE_UNUSED, + bfd *output_bfd ATTRIBUTE_UNUSED, + char **error_message ATTRIBUTE_UNUSED) +{ + uint32_t op; + int32_t param; + + op = bfd_getl32 (data + reloc_entry->address); + param = reloc_entry->addend; + + op &= 0xffc003ff; + op |= (param & 0xfff) << 10; + + bfd_putl32 (op, data + reloc_entry->address); + + return bfd_reloc_ok; +} + +static bfd_reloc_status_type +coff_aarch64_addr32nb_reloc (bfd *abfd ATTRIBUTE_UNUSED, + arelent *reloc_entry, + asymbol *symbol ATTRIBUTE_UNUSED, + void *data, + asection *input_section ATTRIBUTE_UNUSED, + bfd *output_bfd ATTRIBUTE_UNUSED, + char **error_message ATTRIBUTE_UNUSED) +{ + uint64_t val; + + if ((int64_t) reloc_entry->addend > 0x7fffffff + || (int64_t) reloc_entry->addend < -0x7fffffff) + return bfd_reloc_overflow; + + val = reloc_entry->addend; + + bfd_putl32 ((uint32_t) val, data + reloc_entry->address); + + return bfd_reloc_ok; +} + /* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */ #define MINUS_ONE (~ (bfd_vma) 0) +static const reloc_howto_type arm64_reloc_howto_abs = HOWTO(IMAGE_REL_ARM64_ABSOLUTE, 0, 1, 0, false, 0, + complain_overflow_dont, + NULL, "IMAGE_REL_ARM64_ABSOLUTE", + false, 0, 0, false); + static const reloc_howto_type arm64_reloc_howto_64 = HOWTO(IMAGE_REL_ARM64_ADDR64, 0, 8, 64, false, 0, complain_overflow_bitfield, - NULL, "64", + coff_aarch64_addr64_reloc, "IMAGE_REL_ARM64_ADDR64", false, MINUS_ONE, MINUS_ONE, false); static const reloc_howto_type arm64_reloc_howto_32 = HOWTO (IMAGE_REL_ARM64_ADDR32, 0, 4, 32, false, 0, complain_overflow_bitfield, - NULL, "32", + coff_aarch64_addr32_reloc, "IMAGE_REL_ARM64_ADDR32", false, 0xffffffff, 0xffffffff, false); static const reloc_howto_type arm64_reloc_howto_32_pcrel = HOWTO (IMAGE_REL_ARM64_REL32, 0, 4, 32, true, 0, complain_overflow_bitfield, - NULL, "DISP32", + NULL, "IMAGE_REL_ARM64_REL32", false, 0xffffffff, 0xffffffff, true); static const reloc_howto_type arm64_reloc_howto_branch26 = HOWTO (IMAGE_REL_ARM64_BRANCH26, 0, 4, 26, true, 0, complain_overflow_bitfield, - NULL, "BRANCH26", + coff_aarch64_branch26_reloc, "IMAGE_REL_ARM64_BRANCH26", false, 0x03ffffff, 0x03ffffff, true); static const reloc_howto_type arm64_reloc_howto_page21 = HOWTO (IMAGE_REL_ARM64_PAGEBASE_REL21, 12, 4, 21, true, 0, complain_overflow_signed, - NULL, "PAGE21", + coff_aarch64_rel21_reloc, "IMAGE_REL_ARM64_PAGEBASE_REL21", false, 0x1fffff, 0x1fffff, false); static const reloc_howto_type arm64_reloc_howto_lo21 = HOWTO (IMAGE_REL_ARM64_REL21, 0, 4, 21, true, 0, complain_overflow_signed, - NULL, "LO21", + coff_aarch64_rel21_reloc, "IMAGE_REL_ARM64_REL21", false, 0x1fffff, 0x1fffff, true); -static const reloc_howto_type arm64_reloc_howto_pgoff12 = HOWTO (IMAGE_REL_ARM64_PAGEOFFSET_12L, 1, 4, 12, true, 0, +static const reloc_howto_type arm64_reloc_howto_pgoff12l = HOWTO (IMAGE_REL_ARM64_PAGEOFFSET_12L, 1, 4, 12, true, 0, complain_overflow_signed, - NULL, "PGOFF12", + coff_aarch64_po12l_reloc, "IMAGE_REL_ARM64_PAGEOFFSET_12L", false, 0xffe, 0xffe, true); static const reloc_howto_type arm64_reloc_howto_branch19 = HOWTO (IMAGE_REL_ARM64_BRANCH19, 2, 4, 19, true, 0, complain_overflow_signed, - NULL, "BRANCH19", + coff_aarch64_branch19_reloc, "IMAGE_REL_ARM64_BRANCH19", false, 0x7ffff, 0x7ffff, true); +static const reloc_howto_type arm64_reloc_howto_branch14 = HOWTO (IMAGE_REL_ARM64_BRANCH14, 2, 4, 14, true, 0, + complain_overflow_signed, + coff_aarch64_branch14_reloc, "IMAGE_REL_ARM64_BRANCH14", + false, 0x3fff, 0x3fff, true); + +static const reloc_howto_type arm64_reloc_howto_pgoff12a = HOWTO (IMAGE_REL_ARM64_PAGEOFFSET_12A, 2, 4, 12, true, 10, + complain_overflow_dont, + coff_aarch64_po12a_reloc, "IMAGE_REL_ARM64_PAGEOFFSET_12A", + false, 0x3ffc00, 0x3ffc00, false); + +static const reloc_howto_type arm64_reloc_howto_32nb = HOWTO (IMAGE_REL_ARM64_ADDR32NB, 0, 4, 32, false, 0, + complain_overflow_bitfield, + coff_aarch64_addr32nb_reloc, "IMAGE_REL_ARM64_ADDR32NB", + false, 0xffffffff, 0xffffffff, false); static const reloc_howto_type* const arm64_howto_table[] = { + &arm64_reloc_howto_abs, &arm64_reloc_howto_64, &arm64_reloc_howto_32, &arm64_reloc_howto_32_pcrel, &arm64_reloc_howto_branch26, &arm64_reloc_howto_page21, &arm64_reloc_howto_lo21, - &arm64_reloc_howto_pgoff12, - &arm64_reloc_howto_branch19 + &arm64_reloc_howto_pgoff12l, + &arm64_reloc_howto_branch19, + &arm64_reloc_howto_branch14, + &arm64_reloc_howto_pgoff12a, + &arm64_reloc_howto_32nb }; #ifndef NUM_ELEM @@ -118,13 +355,23 @@ coff_aarch64_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real case BFD_RELOC_AARCH64_JUMP26: return &arm64_reloc_howto_branch26; case BFD_RELOC_AARCH64_ADR_HI21_PCREL: + case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL: return &arm64_reloc_howto_page21; + case BFD_RELOC_AARCH64_TSTBR14: + return &arm64_reloc_howto_branch14; case BFD_RELOC_AARCH64_ADR_LO21_PCREL: return &arm64_reloc_howto_lo21; + case BFD_RELOC_AARCH64_ADD_LO12: + return &arm64_reloc_howto_pgoff12a; + case BFD_RELOC_AARCH64_LDST8_LO12: case BFD_RELOC_AARCH64_LDST16_LO12: - return &arm64_reloc_howto_pgoff12; + case BFD_RELOC_AARCH64_LDST32_LO12: + case BFD_RELOC_AARCH64_LDST64_LO12: + return &arm64_reloc_howto_pgoff12l; case BFD_RELOC_AARCH64_BRANCH19: return &arm64_reloc_howto_branch19; + case BFD_RELOC_RVA: + return &arm64_reloc_howto_32nb; default: BFD_FAIL (); return NULL; @@ -155,6 +402,8 @@ coff_aarch64_rtype_lookup (unsigned int code) { switch (code) { + case IMAGE_REL_ARM64_ABSOLUTE: + return &arm64_reloc_howto_abs; case IMAGE_REL_ARM64_ADDR64: return &arm64_reloc_howto_64; case IMAGE_REL_ARM64_ADDR32: @@ -168,9 +417,15 @@ coff_aarch64_rtype_lookup (unsigned int code) case IMAGE_REL_ARM64_REL21: return &arm64_reloc_howto_lo21; case IMAGE_REL_ARM64_PAGEOFFSET_12L: - return &arm64_reloc_howto_pgoff12; + return &arm64_reloc_howto_pgoff12l; case IMAGE_REL_ARM64_BRANCH19: return &arm64_reloc_howto_branch19; + case IMAGE_REL_ARM64_BRANCH14: + return &arm64_reloc_howto_branch14; + case IMAGE_REL_ARM64_PAGEOFFSET_12A: + return &arm64_reloc_howto_pgoff12a; + case IMAGE_REL_ARM64_ADDR32NB: + return &arm64_reloc_howto_32nb; default: BFD_FAIL (); return NULL; @@ -188,6 +443,7 @@ coff_aarch64_rtype_lookup (unsigned int code) #define bfd_pe_print_pdata NULL #endif +#ifdef COFF_WITH_PE /* Return TRUE if this relocation should appear in the output .reloc section. */ @@ -197,9 +453,376 @@ in_reloc_p (bfd * abfd ATTRIBUTE_UNUSED, { return !howto->pc_relative; } +#endif + +static bool +coff_pe_aarch64_relocate_section (bfd *output_bfd, + struct bfd_link_info *info, + bfd *input_bfd, + asection *input_section, + bfd_byte *contents, + struct internal_reloc *relocs, + struct internal_syment *syms, + asection **sections) +{ + struct internal_reloc *rel; + struct internal_reloc *relend; + + if (bfd_link_relocatable (info)) + return true; + + rel = relocs; + relend = rel + input_section->reloc_count; + + /* The addend for a relocation is stored in the immediate bits of each + opcode. So for each relocation, we need to extract the immediate value, + use this to calculate what it should be for the symbol, and rewrite the + opcode into the section stream. */ + + for (; rel < relend; rel++) + { + long symndx; + struct coff_link_hash_entry *h; + bfd_vma sym_value; + asection *sec = NULL; + + /* skip trivial relocations */ + if (rel->r_type == IMAGE_REL_ARM64_ADDR32 + || rel->r_type == IMAGE_REL_ARM64_ADDR64 + || rel->r_type == IMAGE_REL_ARM64_ABSOLUTE) + continue; + + symndx = rel->r_symndx; + sym_value = syms[symndx].n_value; + + h = obj_coff_sym_hashes (input_bfd)[symndx]; + + if (h && h->root.type == bfd_link_hash_defined) + { + sec = h->root.u.def.section; + sym_value = h->root.u.def.value; + } + else + { + sec = sections[symndx]; + } + + if (!sec) + continue; + + if (bfd_is_und_section (sec)) + continue; + + if (bfd_is_abs_section (sec)) + continue; + + if (discarded_section (sec)) + continue; + + if (symndx < 0 + || (unsigned long) symndx >= obj_raw_syment_count (input_bfd)) + continue; + + switch (rel->r_type) + { + case IMAGE_REL_ARM64_ADDR32NB: + { + uint64_t dest_vma, val; + int32_t addend; + + addend = bfd_getl32 (contents + rel->r_vaddr); + + dest_vma = sec->output_section->vma + sec->output_offset + + sym_value + addend; + + val = dest_vma; + val -= pe_data (output_bfd)->pe_opthdr.ImageBase; + + if (val > 0xffffffff) + (*info->callbacks->reloc_overflow) + (info, h ? &h->root : NULL, syms[symndx]._n._n_name, + "IMAGE_REL_ARM64_ADDR32NB", addend, input_bfd, + input_section, rel->r_vaddr - input_section->vma); + + bfd_putl32 (val, contents + rel->r_vaddr); + rel->r_type = IMAGE_REL_ARM64_ABSOLUTE; + + break; + } + + case IMAGE_REL_ARM64_BRANCH26: + { + uint64_t dest_vma, cur_vma; + uint32_t opcode; + int64_t addend, val; + + opcode = bfd_getl32 (contents + rel->r_vaddr); + + addend = (opcode & 0x3ffffff) << 2; + + if (addend & 0x8000000) + addend |= 0xfffffffff0000000; + + dest_vma = sec->output_section->vma + sec->output_offset + + sym_value + addend; + cur_vma = input_section->output_section->vma + + input_section->output_offset + + rel->r_vaddr; + + val = (dest_vma >> 2) - (cur_vma >> 2); + + if (val > 0x1ffffff || val < -0x2000000) + (*info->callbacks->reloc_overflow) + (info, h ? &h->root : NULL, syms[symndx]._n._n_name, + "IMAGE_REL_ARM64_BRANCH26", addend, input_bfd, + input_section, rel->r_vaddr - input_section->vma); + + opcode &= 0xfc000000; + opcode |= val & 0x3ffffff; + + bfd_putl32 (opcode, contents + rel->r_vaddr); + rel->r_type = IMAGE_REL_ARM64_ABSOLUTE; + + break; + } + + case IMAGE_REL_ARM64_BRANCH19: + { + uint64_t dest_vma, cur_vma; + uint32_t opcode; + int64_t addend, val; + + opcode = bfd_getl32 (contents + rel->r_vaddr); + + addend = (opcode & 0xffffe0) >> 3; + + if (addend & 0x100000) + addend |= 0xffffffffffe00000; + + dest_vma = sec->output_section->vma + sec->output_offset + + sym_value + addend; + cur_vma = input_section->output_section->vma + + input_section->output_offset + + rel->r_vaddr; + + val = (dest_vma >> 2) - (cur_vma >> 2); + + if (val > 0x3ffff || val < -0x40000) + (*info->callbacks->reloc_overflow) + (info, h ? &h->root : NULL, syms[symndx]._n._n_name, + "IMAGE_REL_ARM64_BRANCH19", addend, input_bfd, + input_section, rel->r_vaddr - input_section->vma); + + opcode &= 0xff00001f; + opcode |= (val & 0x7ffff) << 5; + + bfd_putl32 (opcode, contents + rel->r_vaddr); + rel->r_type = IMAGE_REL_ARM64_ABSOLUTE; + + break; + } + + case IMAGE_REL_ARM64_BRANCH14: + { + uint64_t dest_vma, cur_vma; + uint32_t opcode; + int64_t addend, val; + + opcode = bfd_getl32 (contents + rel->r_vaddr); + + addend = (opcode & 0x7ffe0) >> 3; + + if (addend & 0x8000) + addend |= 0xffffffffffff0000; + + dest_vma = sec->output_section->vma + sec->output_offset + + sym_value + addend; + cur_vma = input_section->output_section->vma + + input_section->output_offset + + rel->r_vaddr; + + val = (dest_vma >> 2) - (cur_vma >> 2); + + if (val > 0x1fff || val < -0x2000) + (*info->callbacks->reloc_overflow) + (info, h ? &h->root : NULL, syms[symndx]._n._n_name, + "IMAGE_REL_ARM64_BRANCH14", addend, input_bfd, + input_section, rel->r_vaddr - input_section->vma); + + opcode &= 0xfff8001f; + opcode |= (val & 0x3fff) << 5; + + bfd_putl32 (opcode, contents + rel->r_vaddr); + rel->r_type = IMAGE_REL_ARM64_ABSOLUTE; + + break; + } + + case IMAGE_REL_ARM64_PAGEBASE_REL21: + { + uint64_t dest_vma, cur_vma; + uint32_t opcode; + int64_t addend, val; + + opcode = bfd_getl32 (contents + rel->r_vaddr); + + addend = ((opcode & 0xffffe0) >> 3) + | ((opcode & 0x60000000) >> 29); + + if (addend & 0x100000) + addend |= 0xffffffffffe00000; + + dest_vma = sec->output_section->vma + sec->output_offset + + sym_value + addend; + cur_vma = input_section->output_section->vma + + input_section->output_offset + + rel->r_vaddr; + + val = (dest_vma >> 12) - (cur_vma >> 12); + + if (val > 0xfffff || val < -0x100000) + (*info->callbacks->reloc_overflow) + (info, h ? &h->root : NULL, syms[symndx]._n._n_name, + "IMAGE_REL_ARM64_PAGEBASE_REL21", addend, input_bfd, + input_section, rel->r_vaddr - input_section->vma); + + opcode &= 0x9f00001f; + opcode |= (val & 0x3) << 29; + opcode |= (val & 0x1ffffc) << 3; + + bfd_putl32 (opcode, contents + rel->r_vaddr); + rel->r_type = IMAGE_REL_ARM64_ABSOLUTE; + + break; + } + + case IMAGE_REL_ARM64_REL21: + { + uint64_t dest_vma, cur_vma; + uint32_t opcode; + int64_t addend, val; + + opcode = bfd_getl32 (contents + rel->r_vaddr); + + addend = ((opcode & 0xffffe0) >> 3) + | ((opcode & 0x60000000) >> 29); + + if (addend & 0x100000) + addend |= 0xffffffffffe00000; + + dest_vma = sec->output_section->vma + sec->output_offset + + sym_value + addend; + cur_vma = input_section->output_section->vma + + input_section->output_offset + + rel->r_vaddr; + + val = dest_vma - cur_vma; + + if (val > 0xfffff || val < -0x100000) + (*info->callbacks->reloc_overflow) + (info, h ? &h->root : NULL, syms[symndx]._n._n_name, + "IMAGE_REL_ARM64_REL21", addend, input_bfd, + input_section, rel->r_vaddr - input_section->vma); + + opcode &= 0x9f00001f; + opcode |= (val & 0x3) << 29; + opcode |= (val & 0x1ffffc) << 3; + + bfd_putl32 (opcode, contents + rel->r_vaddr); + rel->r_type = IMAGE_REL_ARM64_ABSOLUTE; + + break; + } + + case IMAGE_REL_ARM64_PAGEOFFSET_12L: + { + uint64_t dest_vma; + uint32_t opcode, val; + int32_t addend; + + opcode = bfd_getl32 (contents + rel->r_vaddr); + + addend = (opcode & 0x3ffc00) >> 10; + + /* top two bits represent how much addend should be shifted */ + addend <<= opcode >> 30; + + dest_vma = sec->output_section->vma + sec->output_offset + + sym_value + addend; + + /* only interested in bottom 12 bits */ + val = dest_vma & 0xfff; + val >>= opcode >> 30; + + opcode &= 0xffc003ff; + opcode |= val << 10; + + bfd_putl32 (opcode, contents + rel->r_vaddr); + rel->r_type = IMAGE_REL_ARM64_ABSOLUTE; + + break; + } + + case IMAGE_REL_ARM64_PAGEOFFSET_12A: + { + uint64_t dest_vma; + uint32_t opcode, val; + int32_t addend; + + opcode = bfd_getl32 (contents + rel->r_vaddr); + + addend = (opcode & 0x3ffc00) >> 10; + + dest_vma = sec->output_section->vma + sec->output_offset + + sym_value + addend; + + /* only interested in bottom 12 bits */ + val = dest_vma & 0xfff; + + opcode &= 0xffc003ff; + opcode |= val << 10; + + bfd_putl32 (opcode, contents + rel->r_vaddr); + rel->r_type = IMAGE_REL_ARM64_ABSOLUTE; + + break; + } + + default: + info->callbacks->einfo (_("%F%P: Unhandled relocation type %u\n"), + rel->r_type); + BFD_FAIL (); + return false; + } + } + + return _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd, + input_section, contents, + relocs, syms, sections); +} + +#define coff_relocate_section coff_pe_aarch64_relocate_section #include "coffcode.h" +/* Prevent assertion in md_apply_fix by forcing use_rela_p on for new + sections. */ +static bool +coff_aarch64_new_section_hook (bfd *abfd, asection *section) +{ + if (!coff_new_section_hook (abfd, section)) + return false; + + section->use_rela_p = 1; + + return true; +} + +#define coff_aarch64_close_and_cleanup coff_close_and_cleanup +#define coff_aarch64_bfd_free_cached_info coff_bfd_free_cached_info +#define coff_aarch64_get_section_contents coff_get_section_contents +#define coff_aarch64_get_section_contents_in_window coff_get_section_contents_in_window + /* Target vectors. */ const bfd_target #ifdef TARGET_SYM @@ -266,7 +889,7 @@ const bfd_target _bfd_bool_bfd_false_error }, - BFD_JUMP_TABLE_GENERIC (coff), + BFD_JUMP_TABLE_GENERIC (coff_aarch64), BFD_JUMP_TABLE_COPY (coff), BFD_JUMP_TABLE_CORE (_bfd_nocore), BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), diff --git a/bfd/config.bfd b/bfd/config.bfd index 0bc27fdce97..92a6cff938b 100644 --- a/bfd/config.bfd +++ b/bfd/config.bfd @@ -1495,12 +1495,6 @@ case "${targ}" in ;; esac -if test x"$targ_defvec" = x"aarch64-pe"; then - # Not currently complete (and probably not stable), warn user - echo "*** WARNING BFD aarch64-pe support not complete nor stable" - echo "*** Do not rely on this for production purposes" -fi - # All MIPS ELF targets need a 64-bit bfd_vma. case "${targ_defvec} ${targ_selvecs}" in *mips_elf*) diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index c679d930e88..a50cdb019e6 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -1889,10 +1889,9 @@ s_ltorg (int ignored ATTRIBUTE_UNUSED) } } -#ifdef OBJ_ELF +#if defined(OBJ_ELF) || defined(OBJ_COFF) /* Forward declarations for functions below, in the MD interface section. */ -static fixS *fix_new_aarch64 (fragS *, int, short, expressionS *, int, int); static struct reloc_table_entry * find_reloc_table_entry (char **); /* Directives: Data. */ @@ -1900,7 +1899,7 @@ static struct reloc_table_entry * find_reloc_table_entry (char **); implemented properly. */ static void -s_aarch64_elf_cons (int nbytes) +s_aarch64_cons (int nbytes) { expressionS exp; @@ -1950,6 +1949,12 @@ s_aarch64_elf_cons (int nbytes) input_line_pointer--; demand_empty_rest_of_line (); } +#endif + +#ifdef OBJ_ELF +/* Forward declarations for functions below, in the MD interface + section. */ + static fixS *fix_new_aarch64 (fragS *, int, short, expressionS *, int, int); /* Mark symbol that it follows a variant PCS convention. */ @@ -2119,11 +2124,13 @@ const pseudo_typeS md_pseudo_table[] = { {"tlsdescadd", s_tlsdescadd, 0}, {"tlsdesccall", s_tlsdesccall, 0}, {"tlsdescldr", s_tlsdescldr, 0}, - {"word", s_aarch64_elf_cons, 4}, - {"long", s_aarch64_elf_cons, 4}, - {"xword", s_aarch64_elf_cons, 8}, - {"dword", s_aarch64_elf_cons, 8}, {"variant_pcs", s_variant_pcs, 0}, +#endif +#if defined(OBJ_ELF) || defined(OBJ_COFF) + {"word", s_aarch64_cons, 4}, + {"long", s_aarch64_cons, 4}, + {"xword", s_aarch64_cons, 8}, + {"dword", s_aarch64_cons, 8}, #endif {"float16", float_cons, 'h'}, {"bfloat16", float_cons, 'b'}, @@ -9260,6 +9267,9 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg) /* An error will already have been reported. */ break; + case BFD_RELOC_RVA: + break; + default: as_bad_where (fixP->fx_file, fixP->fx_line, _("unexpected %s fixup"), diff --git a/gas/testsuite/gas/pe/pe-aarch64.d b/gas/testsuite/gas/pe/pe-aarch64.d index 0b8009da5c4..cd9529af8e2 100644 --- a/gas/testsuite/gas/pe/pe-aarch64.d +++ b/gas/testsuite/gas/pe/pe-aarch64.d @@ -1,14 +1,218 @@ #as: -#objdump: -d +#objdump: -dr .*: file format pe-aarch64-little Disassembly of section .text: -0000000000000000 <_start>: - 0: d2800281 mov x1, #0x14 // #20 - 4: 14000001 b 8 +0000000000000000 <.text>: + ... 0000000000000008 : - 8: d65f03c0 ret + 8: 12345678 and w24, w19, #0xfffff003 + c: 12345678 and w24, w19, #0xfffff003 + 10: 00000008 udf #8 + 10: IMAGE_REL_ARM64_ADDR32 .text + 14: 00000008 udf #8 + 14: IMAGE_REL_ARM64_ADDR32 .text + ... + 18: IMAGE_REL_ARM64_ADDR32 bar + 1c: IMAGE_REL_ARM64_ADDR32 bar + 20: 00000009 udf #9 + 20: IMAGE_REL_ARM64_ADDR32 .text + 24: 00000009 udf #9 + 24: IMAGE_REL_ARM64_ADDR32 .text + 28: 00000001 udf #1 + 28: IMAGE_REL_ARM64_ADDR32 bar + 2c: 00000001 udf #1 + 2c: IMAGE_REL_ARM64_ADDR32 bar + 30: 00000007 udf #7 + 30: IMAGE_REL_ARM64_ADDR32 .text + 34: 00000007 udf #7 + 34: IMAGE_REL_ARM64_ADDR32 .text + 38: ffffffff .inst 0xffffffff ; undefined + 38: IMAGE_REL_ARM64_ADDR32 bar + 3c: ffffffff .inst 0xffffffff ; undefined + 3c: IMAGE_REL_ARM64_ADDR32 bar + 40: 9abcdef0 .inst 0x9abcdef0 ; undefined + 44: 12345678 and w24, w19, #0xfffff003 + 48: 9abcdef0 .inst 0x9abcdef0 ; undefined + 4c: 12345678 and w24, w19, #0xfffff003 + 50: 00000008 udf #8 + 50: IMAGE_REL_ARM64_ADDR64 .text + 54: 00000000 udf #0 + 58: 00000008 udf #8 + 58: IMAGE_REL_ARM64_ADDR64 .text + ... + 60: IMAGE_REL_ARM64_ADDR64 bar + 68: IMAGE_REL_ARM64_ADDR64 bar + 70: 00000009 udf #9 + 70: IMAGE_REL_ARM64_ADDR64 .text + 74: 00000000 udf #0 + 78: 00000009 udf #9 + 78: IMAGE_REL_ARM64_ADDR64 .text + 7c: 00000000 udf #0 + 80: 00000001 udf #1 + 80: IMAGE_REL_ARM64_ADDR64 bar + 84: 00000000 udf #0 + 88: 00000001 udf #1 + 88: IMAGE_REL_ARM64_ADDR64 bar + 8c: 00000000 udf #0 + 90: 00000007 udf #7 + 90: IMAGE_REL_ARM64_ADDR64 .text + 94: 00000000 udf #0 + 98: 00000007 udf #7 + 98: IMAGE_REL_ARM64_ADDR64 .text + 9c: 00000000 udf #0 + a0: ffffffff .inst 0xffffffff ; undefined + a0: IMAGE_REL_ARM64_ADDR64 bar + a4: ffffffff .inst 0xffffffff ; undefined + a8: ffffffff .inst 0xffffffff ; undefined + a8: IMAGE_REL_ARM64_ADDR64 bar + ac: ffffffff .inst 0xffffffff ; undefined + b0: 00000008 udf #8 + b0: IMAGE_REL_ARM64_ADDR32NB .text + b4: 00000000 udf #0 + b4: IMAGE_REL_ARM64_ADDR32NB bar + b8: 00000009 udf #9 + b8: IMAGE_REL_ARM64_ADDR32NB .text + bc: 00000001 udf #1 + bc: IMAGE_REL_ARM64_ADDR32NB bar + c0: 00000007 udf #7 + c0: IMAGE_REL_ARM64_ADDR32NB .text + c4: ffffffff .inst 0xffffffff ; undefined + c4: IMAGE_REL_ARM64_ADDR32NB bar + c8: 17ffffd0 b 8 + cc: 17ffffd0 b c + d0: 17ffffcd b 4 <.text\+0x4> + d4: 14000000 b 0 + d4: IMAGE_REL_ARM64_BRANCH26 bar + d8: 14000001 b 4 + d8: IMAGE_REL_ARM64_BRANCH26 bar + dc: 17ffffff b fffffffffffffffc + dc: IMAGE_REL_ARM64_BRANCH26 bar + e0: 97ffffca bl 8 + e4: 97ffffca bl c + e8: 97ffffc7 bl 4 <.text\+0x4> + ec: 94000000 bl 0 + ec: IMAGE_REL_ARM64_BRANCH26 bar + f0: 94000001 bl 4 + f0: IMAGE_REL_ARM64_BRANCH26 bar + f4: 97ffffff bl fffffffffffffffc + f4: IMAGE_REL_ARM64_BRANCH26 bar + f8: 97ffffc1 bl fffffffffffffffc + fc: b4fff860 cbz x0, 8 + 100: b4fff860 cbz x0, c + 104: b4fff800 cbz x0, 4 <.text\+0x4> + 108: b4000000 cbz x0, 0 + 108: IMAGE_REL_ARM64_BRANCH19 bar + 10c: b4000020 cbz x0, 4 + 10c: IMAGE_REL_ARM64_BRANCH19 bar + 110: b4ffffe0 cbz x0, fffffffffffffffc + 110: IMAGE_REL_ARM64_BRANCH19 bar + 114: b4fff740 cbz x0, fffffffffffffffc + 118: 3607f780 tbz w0, #0, 8 + 11c: 3607f780 tbz w0, #0, c + 120: 3607f720 tbz w0, #0, 4 <.text\+0x4> + 124: 36000000 tbz w0, #0, 0 + 124: IMAGE_REL_ARM64_BRANCH14 bar + 128: 36000020 tbz w0, #0, 4 + 128: IMAGE_REL_ARM64_BRANCH14 bar + 12c: 3607ffe0 tbz w0, #0, fffffffffffffffc + 12c: IMAGE_REL_ARM64_BRANCH14 bar + 130: 3607f660 tbz w0, #0, fffffffffffffffc + 134: 90000040 adrp x0, 8000 + 134: IMAGE_REL_ARM64_PAGEBASE_REL21 .text + 138: b0000040 adrp x0, 9000 + 138: IMAGE_REL_ARM64_PAGEBASE_REL21 .text + 13c: f0000020 adrp x0, 7000 + 13c: IMAGE_REL_ARM64_PAGEBASE_REL21 .text + 140: 90000000 adrp x0, 0 + 140: IMAGE_REL_ARM64_PAGEBASE_REL21 bar + 144: b0000000 adrp x0, 1000 + 144: IMAGE_REL_ARM64_PAGEBASE_REL21 bar + 148: f0ffffe0 adrp x0, fffffffffffff000 + 148: IMAGE_REL_ARM64_PAGEBASE_REL21 bar + 14c: 90ffffe0 adrp x0, ffffffffffffc000 + 14c: IMAGE_REL_ARM64_PAGEBASE_REL21 .text + 150: 10fff5c0 adr x0, 8 + 154: 30fff5a0 adr x0, 9 + 158: 70fff560 adr x0, 7 <.text\+0x7> + 15c: 10000000 adr x0, 0 + 15c: IMAGE_REL_ARM64_REL21 bar + 160: 30000000 adr x0, 1 + 160: IMAGE_REL_ARM64_REL21 bar + 164: 70ffffe0 adr x0, ffffffffffffffff + 164: IMAGE_REL_ARM64_REL21 bar + 168: 70fff4a0 adr x0, ffffffffffffffff + 16c: 39002000 strb w0, \[x0, #8\] + 16c: IMAGE_REL_ARM64_PAGEOFFSET_12L .text + 170: 39003000 strb w0, \[x0, #12\] + 170: IMAGE_REL_ARM64_PAGEOFFSET_12L .text + 174: 39001000 strb w0, \[x0, #4\] + 174: IMAGE_REL_ARM64_PAGEOFFSET_12L .text + 178: 39000000 strb w0, \[x0\] + 178: IMAGE_REL_ARM64_PAGEOFFSET_12L bar + 17c: 39001000 strb w0, \[x0, #4\] + 17c: IMAGE_REL_ARM64_PAGEOFFSET_12L bar + 180: 393ff000 strb w0, \[x0, #4092\] + 180: IMAGE_REL_ARM64_PAGEOFFSET_12L bar + 184: 393ff000 strb w0, \[x0, #4092\] + 184: IMAGE_REL_ARM64_PAGEOFFSET_12L .text + 188: 79001000 strh w0, \[x0, #8\] + 188: IMAGE_REL_ARM64_PAGEOFFSET_12L .text + 18c: 79001800 strh w0, \[x0, #12\] + 18c: IMAGE_REL_ARM64_PAGEOFFSET_12L .text + 190: 79000800 strh w0, \[x0, #4\] + 190: IMAGE_REL_ARM64_PAGEOFFSET_12L .text + 194: 79000000 strh w0, \[x0\] + 194: IMAGE_REL_ARM64_PAGEOFFSET_12L bar + 198: 79000800 strh w0, \[x0, #4\] + 198: IMAGE_REL_ARM64_PAGEOFFSET_12L bar + 19c: 791ff800 strh w0, \[x0, #4092\] + 19c: IMAGE_REL_ARM64_PAGEOFFSET_12L bar + 1a0: 791ff800 strh w0, \[x0, #4092\] + 1a0: IMAGE_REL_ARM64_PAGEOFFSET_12L .text + 1a4: b9000800 str w0, \[x0, #8\] + 1a4: IMAGE_REL_ARM64_PAGEOFFSET_12L .text + 1a8: b9000c00 str w0, \[x0, #12\] + 1a8: IMAGE_REL_ARM64_PAGEOFFSET_12L .text + 1ac: b9000400 str w0, \[x0, #4\] + 1ac: IMAGE_REL_ARM64_PAGEOFFSET_12L .text + 1b0: b9000000 str w0, \[x0\] + 1b0: IMAGE_REL_ARM64_PAGEOFFSET_12L bar + 1b4: b9000400 str w0, \[x0, #4\] + 1b4: IMAGE_REL_ARM64_PAGEOFFSET_12L bar + 1b8: b90ffc00 str w0, \[x0, #4092\] + 1b8: IMAGE_REL_ARM64_PAGEOFFSET_12L bar + 1bc: b90ffc00 str w0, \[x0, #4092\] + 1bc: IMAGE_REL_ARM64_PAGEOFFSET_12L .text + 1c0: f9000400 str x0, \[x0, #8\] + 1c0: IMAGE_REL_ARM64_PAGEOFFSET_12L .text + 1c4: f9000800 str x0, \[x0, #16\] + 1c4: IMAGE_REL_ARM64_PAGEOFFSET_12L .text + 1c8: f9000000 str x0, \[x0\] + 1c8: IMAGE_REL_ARM64_PAGEOFFSET_12L .text + 1cc: f9000000 str x0, \[x0\] + 1cc: IMAGE_REL_ARM64_PAGEOFFSET_12L bar + 1d0: f9000400 str x0, \[x0, #8\] + 1d0: IMAGE_REL_ARM64_PAGEOFFSET_12L bar + 1d4: f907fc00 str x0, \[x0, #4088\] + 1d4: IMAGE_REL_ARM64_PAGEOFFSET_12L bar + 1d8: f907fc00 str x0, \[x0, #4088\] + 1d8: IMAGE_REL_ARM64_PAGEOFFSET_12L .text + 1dc: 91002000 add x0, x0, #0x8 + 1dc: IMAGE_REL_ARM64_PAGEOFFSET_12A .text + 1e0: 91002400 add x0, x0, #0x9 + 1e0: IMAGE_REL_ARM64_PAGEOFFSET_12A .text + 1e4: 91001c00 add x0, x0, #0x7 + 1e4: IMAGE_REL_ARM64_PAGEOFFSET_12A .text + 1e8: 91000000 add x0, x0, #0x0 + 1e8: IMAGE_REL_ARM64_PAGEOFFSET_12A bar + 1ec: 91000400 add x0, x0, #0x1 + 1ec: IMAGE_REL_ARM64_PAGEOFFSET_12A bar + 1f0: 913ffc00 add x0, x0, #0xfff + 1f0: IMAGE_REL_ARM64_PAGEOFFSET_12A bar + 1f4: 913ffc00 add x0, x0, #0xfff + 1f4: IMAGE_REL_ARM64_PAGEOFFSET_12A .text diff --git a/gas/testsuite/gas/pe/pe-aarch64.s b/gas/testsuite/gas/pe/pe-aarch64.s index 546d55fc361..62f223fe8e2 100644 --- a/gas/testsuite/gas/pe/pe-aarch64.s +++ b/gas/testsuite/gas/pe/pe-aarch64.s @@ -1,11 +1,147 @@ -# A little test to ensure pe-aarch64 is working in GAS. -# Currently, the poor pe-aarch64 implementation in binutils -# couldn't do anything useful, hence, this test is rather short +.text -.section .text +.dword 0 -_start: - mov x1, 20 - b foo foo: - ret + +# 4-byte literal +.long 0x12345678 +.word 0x12345678 + +# IMAGE_REL_ARM64_ADDR32 (BFD_RELOC_32) +.long foo +.word foo +.long bar +.word bar +.long foo + 1 +.word foo + 1 +.long bar + 1 +.word bar + 1 +.long foo - 1 +.word foo - 1 +.long bar - 1 +.word bar - 1 + +# 8-byte literal +.dword 0x123456789abcdef0 +.xword 0x123456789abcdef0 + +# IMAGE_REL_ARM64_ADDR64 (BFD_RELOC_64) +.dword foo +.xword foo +.dword bar +.xword bar +.dword foo + 1 +.xword foo + 1 +.dword bar + 1 +.xword bar + 1 +.dword foo - 1 +.xword foo - 1 +.dword bar - 1 +.xword bar - 1 + +# IMAGE_REL_ARM64_ADDR32NB (BFD_RELOC_RVA) +.rva foo +.rva bar +.rva foo + 1 +.rva bar + 1 +.rva foo - 1 +.rva bar - 1 + +# IMAGE_REL_ARM64_BRANCH26 (BFD_RELOC_AARCH64_JUMP26) +b foo +b foo + 4 +b foo - 4 +b bar +b bar + 4 +b bar - 4 + +# IMAGE_REL_ARM64_BRANCH26 (BFD_RELOC_AARCH64_CALL26) +bl foo +bl foo + 4 +bl foo - 4 +bl bar +bl bar + 4 +bl bar - 4 +bl .text - 4 + +# IMAGE_REL_ARM64_BRANCH19 (BFD_RELOC_AARCH64_BRANCH19) +cbz x0, foo +cbz x0, foo + 4 +cbz x0, foo - 4 +cbz x0, bar +cbz x0, bar + 4 +cbz x0, bar - 4 +cbz x0, .text - 4 + +# IMAGE_REL_ARM64_BRANCH14 (BFD_RELOC_AARCH64_TSTBR14) +tbz x0, 0, foo +tbz x0, 0, foo + 4 +tbz x0, 0, foo - 4 +tbz x0, 0, bar +tbz x0, 0, bar + 4 +tbz x0, 0, bar - 4 +tbz x0, 0, .text - 4 + +# IMAGE_REL_ARM64_PAGEBASE_REL21 (BFD_RELOC_AARCH64_ADR_HI21_PCREL) +adrp x0, foo +adrp x0, foo + 1 +adrp x0, foo - 1 +adrp x0, bar +adrp x0, bar + 1 +adrp x0, bar - 1 +adrp x0, .text - 4 + +# IMAGE_REL_ARM64_REL21 (BFD_RELOC_AARCH64_ADR_LO21_PCREL) +adr x0, foo +adr x0, foo + 1 +adr x0, foo - 1 +adr x0, bar +adr x0, bar + 1 +adr x0, bar - 1 +adr x0, .text - 1 + +# IMAGE_REL_ARM64_PAGEOFFSET_12L (BFD_RELOC_AARCH64_LDST8_LO12) +strb w0, [x0,:lo12:foo] +strb w0, [x0,:lo12:foo + 4] +strb w0, [x0,:lo12:foo - 4] +strb w0, [x0,:lo12:bar] +strb w0, [x0,:lo12:bar + 4] +strb w0, [x0,:lo12:bar - 4] +strb w0, [x0,:lo12:.text - 4] + +# IMAGE_REL_ARM64_PAGEOFFSET_12L (BFD_RELOC_AARCH64_LDST16_LO12) +strh w0, [x0,:lo12:foo] +strh w0, [x0,:lo12:foo + 4] +strh w0, [x0,:lo12:foo - 4] +strh w0, [x0,:lo12:bar] +strh w0, [x0,:lo12:bar + 4] +strh w0, [x0,:lo12:bar - 4] +strh w0, [x0,:lo12:.text - 4] + +# IMAGE_REL_ARM64_PAGEOFFSET_12L (BFD_RELOC_AARCH64_LDST32_LO12) +str w0, [x0,:lo12:foo] +str w0, [x0,:lo12:foo + 4] +str w0, [x0,:lo12:foo - 4] +str w0, [x0,:lo12:bar] +str w0, [x0,:lo12:bar + 4] +str w0, [x0,:lo12:bar - 4] +str w0, [x0,:lo12:.text - 4] + +# IMAGE_REL_ARM64_PAGEOFFSET_12L (BFD_RELOC_AARCH64_LDST64_LO12) +str x0, [x0,:lo12:foo] +str x0, [x0,:lo12:foo + 8] +str x0, [x0,:lo12:foo - 8] +str x0, [x0,:lo12:bar] +str x0, [x0,:lo12:bar + 8] +str x0, [x0,:lo12:bar - 8] +str x0, [x0,:lo12:.text - 8] + +# IMAGE_REL_ARM64_PAGEOFFSET_12A (BFD_RELOC_AARCH64_ADD_LO12) +add x0, x0, #:lo12:foo +add x0, x0, #:lo12:foo + 1 +add x0, x0, #:lo12:foo - 1 +add x0, x0, #:lo12:bar +add x0, x0, #:lo12:bar + 1 +add x0, x0, #:lo12:bar - 1 +add x0, x0, #:lo12:.text - 1 diff --git a/ld/testsuite/ld-pe/aarch64.d b/ld/testsuite/ld-pe/aarch64.d new file mode 100644 index 00000000000..604e614e0ea --- /dev/null +++ b/ld/testsuite/ld-pe/aarch64.d @@ -0,0 +1,148 @@ + +tmpdir/aarch64.x: file format pei-aarch64-little + + +Disassembly of section .text: + +0000000000002000 <__rt_psrelocs_end>: + ... + +0000000000002008 : + 2008: 12345678 and w24, w19, #0xfffff003 + 200c: 12345678 and w24, w19, #0xfffff003 + 2010: 00002000 udf #8192 + 2014: 00002000 udf #8192 + 2018: 000021f8 udf #8696 + 201c: 000021f8 udf #8696 + 2020: 00002001 udf #8193 + 2024: 00002001 udf #8193 + 2028: 000021f9 udf #8697 + 202c: 000021f9 udf #8697 + 2030: 00001fff udf #8191 + 2034: 00001fff udf #8191 + 2038: 000021f7 udf #8695 + 203c: 000021f7 udf #8695 + 2040: 9abcdef0 .inst 0x9abcdef0 ; undefined + 2044: 12345678 and w24, w19, #0xfffff003 + 2048: 9abcdef0 .inst 0x9abcdef0 ; undefined + 204c: 12345678 and w24, w19, #0xfffff003 + 2050: 00002000 udf #8192 + 2054: 00000000 udf #0 + 2058: 00002000 udf #8192 + 205c: 00000000 udf #0 + 2060: 000021f8 udf #8696 + 2064: 00000000 udf #0 + 2068: 000021f8 udf #8696 + 206c: 00000000 udf #0 + 2070: 00002001 udf #8193 + 2074: 00000000 udf #0 + 2078: 00002001 udf #8193 + 207c: 00000000 udf #0 + 2080: 000021f9 udf #8697 + 2084: 00000000 udf #0 + 2088: 000021f9 udf #8697 + 208c: 00000000 udf #0 + 2090: 00001fff udf #8191 + 2094: 00000000 udf #0 + 2098: 00001fff udf #8191 + 209c: 00000000 udf #0 + 20a0: 000021f7 udf #8695 + 20a4: 00000000 udf #0 + 20a8: 000021f7 udf #8695 + 20ac: 00000000 udf #0 + 20b0: 00001008 udf #4104 + 20b4: 000011f8 udf #4600 + 20b8: 00001009 udf #4105 + 20bc: 000011f9 udf #4601 + 20c0: 00001007 udf #4103 + 20c4: 000011f7 udf #4599 + 20c8: 17ffffd0 b 2008 + 20cc: 17ffffd0 b 200c + 20d0: 17ffffcd b 2004 <__rt_psrelocs_end\+0x4> + 20d4: 14000049 b 21f8 + 20d8: 14000049 b 21fc + 20dc: 14000046 b 21f4 + 20e0: 97ffffca bl 2008 + 20e4: 97ffffca bl 200c + 20e8: 97ffffc7 bl 2004 <__rt_psrelocs_end\+0x4> + 20ec: 94000043 bl 21f8 + 20f0: 94000043 bl 21fc + 20f4: 94000040 bl 21f4 + 20f8: 97ffffc1 bl 1ffc <__ImageBase\+0xffc> + 20fc: b4fff860 cbz x0, 2008 + 2100: b4fff860 cbz x0, 200c + 2104: b4fff800 cbz x0, 2004 <__rt_psrelocs_end\+0x4> + 2108: b4000780 cbz x0, 21f8 + 210c: b4000780 cbz x0, 21fc + 2110: b4000720 cbz x0, 21f4 + 2114: b4fff740 cbz x0, 1ffc <__ImageBase\+0xffc> + 2118: 3607f780 tbz w0, #0, 2008 + 211c: 3607f780 tbz w0, #0, 200c + 2120: 3607f720 tbz w0, #0, 2004 <__rt_psrelocs_end\+0x4> + 2124: 360006a0 tbz w0, #0, 21f8 + 2128: 360006a0 tbz w0, #0, 21fc + 212c: 36000640 tbz w0, #0, 21f4 + 2130: 3607f660 tbz w0, #0, 1ffc <__ImageBase\+0xffc> + 2134: 90000000 adrp x0, 2000 <__rt_psrelocs_end> + 2138: 90000000 adrp x0, 2000 <__rt_psrelocs_end> + 213c: 90000000 adrp x0, 2000 <__rt_psrelocs_end> + 2140: 90000000 adrp x0, 2000 <__rt_psrelocs_end> + 2144: 90000000 adrp x0, 2000 <__rt_psrelocs_end> + 2148: 90000000 adrp x0, 2000 <__rt_psrelocs_end> + 214c: f0ffffe0 adrp x0, 1000 <__ImageBase> + 2150: 10fff5c0 adr x0, 2008 + 2154: 30fff5a0 adr x0, 2009 + 2158: 70fff560 adr x0, 2007 <__rt_psrelocs_end\+0x7> + 215c: 100004e0 adr x0, 21f8 + 2160: 300004c0 adr x0, 21f9 + 2164: 70000480 adr x0, 21f7 + 2168: 70fff4a0 adr x0, 1fff <__ImageBase\+0xfff> + 216c: 39002000 strb w0, \[x0, #8\] + 2170: 39003000 strb w0, \[x0, #12\] + 2174: 39001000 strb w0, \[x0, #4\] + 2178: 3907e000 strb w0, \[x0, #504\] + 217c: 3907f000 strb w0, \[x0, #508\] + 2180: 3907d000 strb w0, \[x0, #500\] + 2184: 393ff000 strb w0, \[x0, #4092\] + 2188: 79001000 strh w0, \[x0, #8\] + 218c: 79001800 strh w0, \[x0, #12\] + 2190: 79000800 strh w0, \[x0, #4\] + 2194: 7903f000 strh w0, \[x0, #504\] + 2198: 7903f800 strh w0, \[x0, #508\] + 219c: 7903e800 strh w0, \[x0, #500\] + 21a0: 791ff800 strh w0, \[x0, #4092\] + 21a4: b9000800 str w0, \[x0, #8\] + 21a8: b9000c00 str w0, \[x0, #12\] + 21ac: b9000400 str w0, \[x0, #4\] + 21b0: b901f800 str w0, \[x0, #504\] + 21b4: b901fc00 str w0, \[x0, #508\] + 21b8: b901f400 str w0, \[x0, #500\] + 21bc: b90ffc00 str w0, \[x0, #4092\] + 21c0: f9000400 str x0, \[x0, #8\] + 21c4: f9000800 str x0, \[x0, #16\] + 21c8: f9000000 str x0, \[x0\] + 21cc: f900fc00 str x0, \[x0, #504\] + 21d0: f9010000 str x0, \[x0, #512\] + 21d4: f900f800 str x0, \[x0, #496\] + 21d8: f907fc00 str x0, \[x0, #4088\] + 21dc: 91002000 add x0, x0, #0x8 + 21e0: 91002400 add x0, x0, #0x9 + 21e4: 91001c00 add x0, x0, #0x7 + 21e8: 9107e000 add x0, x0, #0x1f8 + 21ec: 9107e400 add x0, x0, #0x1f9 + 21f0: 9107dc00 add x0, x0, #0x1f7 + 21f4: 913ffc00 add x0, x0, #0xfff + +00000000000021f8 : + 21f8: 9abcdef0 .inst 0x9abcdef0 ; undefined + 21fc: 12345678 and w24, w19, #0xfffff003 + +0000000000002200 <__CTOR_LIST__>: + 2200: ffffffff .inst 0xffffffff ; undefined + 2204: ffffffff .inst 0xffffffff ; undefined + ... + +0000000000002210 <__DTOR_LIST__>: + 2210: ffffffff .inst 0xffffffff ; undefined + 2214: ffffffff .inst 0xffffffff ; undefined + ... diff --git a/ld/testsuite/ld-pe/aarch64a.s b/ld/testsuite/ld-pe/aarch64a.s new file mode 100644 index 00000000000..e7ecabba64b --- /dev/null +++ b/ld/testsuite/ld-pe/aarch64a.s @@ -0,0 +1,149 @@ +.text + +.dword 0 + +# 2008 +.global foo +foo: + +# 4-byte literal +.long 0x12345678 +.word 0x12345678 + +# IMAGE_REL_ARM64_ADDR32 (BFD_RELOC_32) +.long foo +.word foo +.long bar +.word bar +.long foo + 1 +.word foo + 1 +.long bar + 1 +.word bar + 1 +.long foo - 1 +.word foo - 1 +.long bar - 1 +.word bar - 1 + +# 8-byte literal +.dword 0x123456789abcdef0 +.xword 0x123456789abcdef0 + +# IMAGE_REL_ARM64_ADDR64 (BFD_RELOC_64) +.dword foo +.xword foo +.dword bar +.xword bar +.dword foo + 1 +.xword foo + 1 +.dword bar + 1 +.xword bar + 1 +.dword foo - 1 +.xword foo - 1 +.dword bar - 1 +.xword bar - 1 + +# IMAGE_REL_ARM64_ADDR32NB (BFD_RELOC_RVA) +.rva foo +.rva bar +.rva foo + 1 +.rva bar + 1 +.rva foo - 1 +.rva bar - 1 + +# IMAGE_REL_ARM64_BRANCH26 (BFD_RELOC_AARCH64_JUMP26) +b foo +b foo + 4 +b foo - 4 +b bar +b bar + 4 +b bar - 4 + +# IMAGE_REL_ARM64_BRANCH26 (BFD_RELOC_AARCH64_CALL26) +bl foo +bl foo + 4 +bl foo - 4 +bl bar +bl bar + 4 +bl bar - 4 +bl .text - 4 + +# IMAGE_REL_ARM64_BRANCH19 (BFD_RELOC_AARCH64_BRANCH19) +cbz x0, foo +cbz x0, foo + 4 +cbz x0, foo - 4 +cbz x0, bar +cbz x0, bar + 4 +cbz x0, bar - 4 +cbz x0, .text - 4 + +# IMAGE_REL_ARM64_BRANCH14 (BFD_RELOC_AARCH64_TSTBR14) +tbz x0, 0, foo +tbz x0, 0, foo + 4 +tbz x0, 0, foo - 4 +tbz x0, 0, bar +tbz x0, 0, bar + 4 +tbz x0, 0, bar - 4 +tbz x0, 0, .text - 4 + +# IMAGE_REL_ARM64_PAGEBASE_REL21 (BFD_RELOC_AARCH64_ADR_HI21_PCREL) +adrp x0, foo +adrp x0, foo + 1 +adrp x0, foo - 1 +adrp x0, bar +adrp x0, bar + 1 +adrp x0, bar - 1 +adrp x0, .text - 4 + +# IMAGE_REL_ARM64_REL21 (BFD_RELOC_AARCH64_ADR_LO21_PCREL) +adr x0, foo +adr x0, foo + 1 +adr x0, foo - 1 +adr x0, bar +adr x0, bar + 1 +adr x0, bar - 1 +adr x0, .text - 1 + +# IMAGE_REL_ARM64_PAGEOFFSET_12L (BFD_RELOC_AARCH64_LDST8_LO12) +strb w0, [x0,:lo12:foo] +strb w0, [x0,:lo12:foo + 4] +strb w0, [x0,:lo12:foo - 4] +strb w0, [x0,:lo12:bar] +strb w0, [x0,:lo12:bar + 4] +strb w0, [x0,:lo12:bar - 4] +strb w0, [x0,:lo12:.text - 4] + +# IMAGE_REL_ARM64_PAGEOFFSET_12L (BFD_RELOC_AARCH64_LDST16_LO12) +strh w0, [x0,:lo12:foo] +strh w0, [x0,:lo12:foo + 4] +strh w0, [x0,:lo12:foo - 4] +strh w0, [x0,:lo12:bar] +strh w0, [x0,:lo12:bar + 4] +strh w0, [x0,:lo12:bar - 4] +strh w0, [x0,:lo12:.text - 4] + +# IMAGE_REL_ARM64_PAGEOFFSET_12L (BFD_RELOC_AARCH64_LDST32_LO12) +str w0, [x0,:lo12:foo] +str w0, [x0,:lo12:foo + 4] +str w0, [x0,:lo12:foo - 4] +str w0, [x0,:lo12:bar] +str w0, [x0,:lo12:bar + 4] +str w0, [x0,:lo12:bar - 4] +str w0, [x0,:lo12:.text - 4] + +# IMAGE_REL_ARM64_PAGEOFFSET_12L (BFD_RELOC_AARCH64_LDST64_LO12) +str x0, [x0,:lo12:foo] +str x0, [x0,:lo12:foo + 8] +str x0, [x0,:lo12:foo - 8] +str x0, [x0,:lo12:bar] +str x0, [x0,:lo12:bar + 8] +str x0, [x0,:lo12:bar - 8] +str x0, [x0,:lo12:.text - 8] + +# IMAGE_REL_ARM64_PAGEOFFSET_12A (BFD_RELOC_AARCH64_ADD_LO12) +add x0, x0, #:lo12:foo +add x0, x0, #:lo12:foo + 1 +add x0, x0, #:lo12:foo - 1 +add x0, x0, #:lo12:bar +add x0, x0, #:lo12:bar + 1 +add x0, x0, #:lo12:bar - 1 +add x0, x0, #:lo12:.text - 1 diff --git a/ld/testsuite/ld-pe/aarch64b.s b/ld/testsuite/ld-pe/aarch64b.s new file mode 100644 index 00000000000..9f0bdde758f --- /dev/null +++ b/ld/testsuite/ld-pe/aarch64b.s @@ -0,0 +1,6 @@ +.text + +# 21f8 +.global bar +bar: +.dword 0x123456789abcdef0 diff --git a/ld/testsuite/ld-pe/pe.exp b/ld/testsuite/ld-pe/pe.exp index d8595ee61e8..80019a48778 100644 --- a/ld/testsuite/ld-pe/pe.exp +++ b/ld/testsuite/ld-pe/pe.exp @@ -79,9 +79,15 @@ if {[istarget i*86-*-cygwin*] } if {[istarget "aarch64-*-pe*"]} { - run_dump_test "pe-aarch64" -} + run_dump_test "pe-aarch64" + + set pe_tests { + {"aarch64" "--image-base 0x1000" "" "" {aarch64a.s aarch64b.s} + {{objdump -dr aarch64.d}} "aarch64.x"} + } + run_ld_link_tests $pe_tests +} run_dump_test "image_size" run_dump_test "export_dynamic_warning" -- 2.37.4