X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Felfxx-aarch64.c;h=61a5ffb8a81bfc26fc307fb5d8c1d44ab9ddb5b1;hb=b939d8a0dedbe0f0667500e1741e25baf03fe64c;hp=34bd1a690226690d6ad58668b8c56fb0821daed7;hpb=07c9aa07cdcf00eff8e186f3ca1779e5e3ffdb75;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elfxx-aarch64.c b/bfd/elfxx-aarch64.c index 34bd1a6902..61a5ffb8a8 100644 --- a/bfd/elfxx-aarch64.c +++ b/bfd/elfxx-aarch64.c @@ -1,5 +1,5 @@ /* AArch64-specific support for ELF. - Copyright (C) 2009-2015 Free Software Foundation, Inc. + Copyright (C) 2009-2018 Free Software Foundation, Inc. Contributed by ARM Ltd. This file is part of BFD, the Binary File Descriptor library. @@ -247,7 +247,7 @@ _bfd_aarch64_elf_put_addend (bfd *abfd, break; case BFD_RELOC_AARCH64_ADD_LO12: - case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC: + case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12: case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC: case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_HI12: case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12: @@ -257,14 +257,15 @@ _bfd_aarch64_elf_put_addend (bfd *abfd, case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12: case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC: /* Corresponds to: add rd, rn, #uimm12 to provide the low order - 12 bits of the page offset following - BFD_RELOC_AARCH64_ADR_HI21_PCREL which computes the - (pc-relative) page base. */ + 12 bits of the page offset following + BFD_RELOC_AARCH64_ADR_HI21_PCREL which computes the + (pc-relative) page base. */ contents = reencode_add_imm (contents, addend); break; case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14: case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC: + case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15: case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15: case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC: case BFD_RELOC_AARCH64_LDST128_LO12: @@ -273,7 +274,7 @@ _bfd_aarch64_elf_put_addend (bfd *abfd, case BFD_RELOC_AARCH64_LDST64_LO12: case BFD_RELOC_AARCH64_LDST8_LO12: case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC: - case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC: + case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12: case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC: case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12: @@ -284,22 +285,33 @@ _bfd_aarch64_elf_put_addend (bfd *abfd, case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC: case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12: case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC: + case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12: + case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC: + case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12: + case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC: + case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12: + case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC: + case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12: + case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC: if (old_addend & ((1 << howto->rightshift) - 1)) return bfd_reloc_overflow; /* Used for ldr*|str* rt, [rn, #uimm12] to provide the low order - 12 bits of the page offset following BFD_RELOC_AARCH64_ADR_HI21_PCREL - which computes the (pc-relative) page base. */ + 12 bits address offset. */ contents = reencode_ldst_pos_imm (contents, addend); break; /* Group relocations to create high bits of a 16, 32, 48 or 64 - bit signed data or abs address inline. Will change - instruction to MOVN or MOVZ depending on sign of calculated - value. */ + bit signed data or abs address inline. Will change + instruction to MOVN or MOVZ depending on sign of calculated + value. */ case BFD_RELOC_AARCH64_MOVW_G0_S: case BFD_RELOC_AARCH64_MOVW_G1_S: case BFD_RELOC_AARCH64_MOVW_G2_S: + case BFD_RELOC_AARCH64_MOVW_PREL_G0: + case BFD_RELOC_AARCH64_MOVW_PREL_G1: + case BFD_RELOC_AARCH64_MOVW_PREL_G2: + case BFD_RELOC_AARCH64_MOVW_PREL_G3: case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0: case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1: case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2: @@ -318,10 +330,10 @@ _bfd_aarch64_elf_put_addend (bfd *abfd, /* Force use of MOVZ. */ contents = reencode_movzn_to_movz (contents); } - /* fall through */ + /* Fall through. */ /* Group relocations to create a 16, 32, 48 or 64 bit unsigned - data or abs address inline. */ + data or abs address inline. */ case BFD_RELOC_AARCH64_MOVW_G0: case BFD_RELOC_AARCH64_MOVW_G0_NC: @@ -330,6 +342,17 @@ _bfd_aarch64_elf_put_addend (bfd *abfd, case BFD_RELOC_AARCH64_MOVW_G2: case BFD_RELOC_AARCH64_MOVW_G2_NC: case BFD_RELOC_AARCH64_MOVW_G3: + case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC: + case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1: + case BFD_RELOC_AARCH64_MOVW_PREL_G0_NC: + case BFD_RELOC_AARCH64_MOVW_PREL_G1_NC: + case BFD_RELOC_AARCH64_MOVW_PREL_G2_NC: + case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC: + case BFD_RELOC_AARCH64_TLSDESC_OFF_G1: + case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC: + case BFD_RELOC_AARCH64_TLSGD_MOVW_G1: + case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC: + case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1: case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0_NC: case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC: case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC: @@ -386,6 +409,13 @@ _bfd_aarch64_elf_resolve_relocation (bfd_reloc_code_real_type r_type, case BFD_RELOC_AARCH64_ADR_LO21_PCREL: case BFD_RELOC_AARCH64_BRANCH19: case BFD_RELOC_AARCH64_LD_LO19_PCREL: + case BFD_RELOC_AARCH64_MOVW_PREL_G0: + case BFD_RELOC_AARCH64_MOVW_PREL_G0_NC: + case BFD_RELOC_AARCH64_MOVW_PREL_G1: + case BFD_RELOC_AARCH64_MOVW_PREL_G1_NC: + case BFD_RELOC_AARCH64_MOVW_PREL_G2: + case BFD_RELOC_AARCH64_MOVW_PREL_G2_NC: + case BFD_RELOC_AARCH64_MOVW_PREL_G3: case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21: case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19: case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21: @@ -414,22 +444,26 @@ _bfd_aarch64_elf_resolve_relocation (bfd_reloc_code_real_type r_type, case BFD_RELOC_AARCH64_MOVW_G2_NC: case BFD_RELOC_AARCH64_MOVW_G2_S: case BFD_RELOC_AARCH64_MOVW_G3: + case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC: + case BFD_RELOC_AARCH64_TLSDESC_OFF_G1: + case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC: + case BFD_RELOC_AARCH64_TLSGD_MOVW_G1: case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_HI12: case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12: case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12_NC: case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12: - case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC: case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12: - case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC: case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12: - case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC: case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12: - case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC: case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0: case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0_NC: case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1: case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC: case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2: + case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12: + case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12: + case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12: + case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12: value = value + addend; break; @@ -452,10 +486,15 @@ _bfd_aarch64_elf_resolve_relocation (bfd_reloc_code_real_type r_type, value = PG (value + addend) - PG (place); break; + /* Caller must make sure addend is the base address of .got section. */ case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14: case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15: - /* Caller must make sure addend is the base address of .got section. */ - value = value - PG (addend); + addend = PG (addend); + /* Fall through. */ + case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15: + case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC: + case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1: + value = value - addend; break; case BFD_RELOC_AARCH64_ADD_LO12: @@ -467,14 +506,22 @@ _bfd_aarch64_elf_resolve_relocation (bfd_reloc_code_real_type r_type, case BFD_RELOC_AARCH64_LDST64_LO12: case BFD_RELOC_AARCH64_LDST8_LO12: case BFD_RELOC_AARCH64_TLSDESC_ADD: - case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC: + case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12: case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC: - case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC: + case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12: case BFD_RELOC_AARCH64_TLSDESC_LDR: case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC: case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC: case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: + case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC: + case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC: + case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC: + case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC: case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC: + case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC: + case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC: + case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC: + case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC: value = PG_OFFSET (value + addend); break; @@ -482,6 +529,7 @@ _bfd_aarch64_elf_resolve_relocation (bfd_reloc_code_real_type r_type, value = value + addend; break; + case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1: case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1: case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC: value = (value + addend) & (bfd_vma) 0xffff0000; @@ -492,6 +540,7 @@ _bfd_aarch64_elf_resolve_relocation (bfd_reloc_code_real_type r_type, value = (value + addend) & ~(bfd_vma) 0xfff; break; + case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC: case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0: case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC: value = (value + addend) & (bfd_vma) 0xffff; @@ -509,26 +558,6 @@ _bfd_aarch64_elf_resolve_relocation (bfd_reloc_code_real_type r_type, return value; } -/* Hook called by the linker routine which adds symbols from an object - file. */ - -bfd_boolean -_bfd_aarch64_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info, - Elf_Internal_Sym *sym, - const char **namep ATTRIBUTE_UNUSED, - flagword *flagsp ATTRIBUTE_UNUSED, - asection **secp ATTRIBUTE_UNUSED, - bfd_vma *valp ATTRIBUTE_UNUSED) -{ - if ((ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC - || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE) - && (abfd->flags & DYNAMIC) == 0 - && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour) - elf_tdata (info->output_bfd)->has_gnu_symbols = elf_gnu_symbol_any; - - return TRUE; -} - /* Support for core dump NOTE sections. */ bfd_boolean @@ -571,7 +600,7 @@ _bfd_aarch64_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) default: return FALSE; - case 136: /* This is sizeof(struct elf_prpsinfo) on Linux/aarch64. */ + case 136: /* This is sizeof(struct elf_prpsinfo) on Linux/aarch64. */ elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, note->descdata + 24); elf_tdata (abfd)->core->program = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16); @@ -605,38 +634,47 @@ _bfd_aarch64_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_ty case NT_PRPSINFO: { - char data[136]; - va_list ap; - - va_start (ap, note_type); - memset (data, 0, sizeof (data)); - strncpy (data + 40, va_arg (ap, const char *), 16); - strncpy (data + 56, va_arg (ap, const char *), 80); - va_end (ap); - - return elfcore_write_note (abfd, buf, bufsiz, "CORE", + char data[136] ATTRIBUTE_NONSTRING; + va_list ap; + + va_start (ap, note_type); + memset (data, 0, sizeof (data)); + strncpy (data + 40, va_arg (ap, const char *), 16); + DIAGNOSTIC_PUSH; + /* GCC 8.1 warns about 80 equals destination size with + -Wstringop-truncation: + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85643 + */ +#if GCC_VERSION == 8001 + DIAGNOSTIC_IGNORE_STRINGOP_TRUNCATION; +#endif + strncpy (data + 56, va_arg (ap, const char *), 80); + DIAGNOSTIC_POP; + va_end (ap); + + return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type, data, sizeof (data)); } case NT_PRSTATUS: { - char data[392]; - va_list ap; - long pid; - int cursig; - const void *greg; - - va_start (ap, note_type); - memset (data, 0, sizeof (data)); - pid = va_arg (ap, long); - bfd_put_32 (abfd, pid, data + 32); - cursig = va_arg (ap, int); - bfd_put_16 (abfd, cursig, data + 12); - greg = va_arg (ap, const void *); - memcpy (data + 112, greg, 272); - va_end (ap); - - return elfcore_write_note (abfd, buf, bufsiz, "CORE", + char data[392]; + va_list ap; + long pid; + int cursig; + const void *greg; + + va_start (ap, note_type); + memset (data, 0, sizeof (data)); + pid = va_arg (ap, long); + bfd_put_32 (abfd, pid, data + 32); + cursig = va_arg (ap, int); + bfd_put_16 (abfd, cursig, data + 12); + greg = va_arg (ap, const void *); + memcpy (data + 112, greg, 272); + va_end (ap); + + return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type, data, sizeof (data)); } }