From d86f995f4f957e4380b3765ebad1f4977f1d9a45 Mon Sep 17 00:00:00 2001 From: Nelson Chu Date: Thu, 23 Aug 2018 15:28:25 +0800 Subject: [PATCH 12/13] NDS32: Allow to link the generic object with any objects. The input object with zero e_flags shall be treat as the generic one which can be linked with any other objects. bfd/ * elf32-nds32.c (nds32_elf_merge_private_bfd_data): Allow to link the generic object. --- bfd/ChangeLog | 5 + bfd/elf32-nds32.c | 238 ++++++++++++++++++++++++---------------------- 2 files changed, 131 insertions(+), 112 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 6425cfb7b7..a2d3511d3a 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2018-09-17 Nelson Chu + + * elf32-nds32.c (nds32_elf_merge_private_bfd_data): Allow to link the + generic object. + 2018-09-17 Nelson Chu * elf32-nds32.c (elf32_nds32_allocate_dynrelocs): New function. diff --git a/bfd/elf32-nds32.c b/bfd/elf32-nds32.c index 097a98f442..efd9bc91a6 100644 --- a/bfd/elf32-nds32.c +++ b/bfd/elf32-nds32.c @@ -6087,134 +6087,148 @@ nds32_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) return FALSE; } - in_version = elf_elfheader (ibfd)->e_flags & EF_NDS32_ELF_VERSION; - if (in_version == E_NDS32_ELF_VER_1_2) + /* -B option in objcopy cannot work as expected. e_flags = 0 shall be + treat as generic one without checking and merging. */ + if (elf_elfheader (ibfd)->e_flags) { - _bfd_error_handler - (_("%pB: warning: older version of object file encountered, " - "please recompile with current tool chain"), ibfd); - } - - /* We may need to merge V1 and V2 arch object files to V2. */ - if ((elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH) - != (elf_elfheader (obfd)->e_flags & EF_NDS_ARCH)) - { - /* Need to convert version. */ - if ((elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH) - == E_NDS_ARCH_STAR_RESERVED) - { - elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags; - } - else if ((elf_elfheader (obfd)->e_flags & EF_NDS_ARCH) == E_NDS_ARCH_STAR_V0_9 - || (elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH) - > (elf_elfheader (obfd)->e_flags & EF_NDS_ARCH)) + in_version = elf_elfheader (ibfd)->e_flags & EF_NDS32_ELF_VERSION; + if (in_version == E_NDS32_ELF_VER_1_2) { - elf_elfheader (obfd)->e_flags = - convert_e_flags (elf_elfheader (obfd)->e_flags, - (elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH)); + _bfd_error_handler + (_("%pB: warning: older version of object file encountered, " + "please recompile with current tool chain"), ibfd); } - else - { - elf_elfheader (ibfd)->e_flags = - convert_e_flags (elf_elfheader (ibfd)->e_flags, - (elf_elfheader (obfd)->e_flags & EF_NDS_ARCH)); - } - } - - /* Extract some flags. */ - in_flags = elf_elfheader (ibfd)->e_flags - & (~(E_NDS32_HAS_REDUCED_REGS | EF_NDS32_ELF_VERSION - | E_NDS32_HAS_NO_MAC_INST | E_NDS32_FPU_REG_CONF)); - - /* The following flags need special treatment. */ - in_16regs = elf_elfheader (ibfd)->e_flags & E_NDS32_HAS_REDUCED_REGS; - in_no_mac = elf_elfheader (ibfd)->e_flags & E_NDS32_HAS_NO_MAC_INST; - in_fpu_config = elf_elfheader (ibfd)->e_flags & E_NDS32_FPU_REG_CONF; - - /* Extract some flags. */ - out_flags = elf_elfheader (obfd)->e_flags - & (~(E_NDS32_HAS_REDUCED_REGS | EF_NDS32_ELF_VERSION - | E_NDS32_HAS_NO_MAC_INST | E_NDS32_FPU_REG_CONF)); - - /* The following flags need special treatment. */ - out_16regs = elf_elfheader (obfd)->e_flags & E_NDS32_HAS_REDUCED_REGS; - out_no_mac = elf_elfheader (obfd)->e_flags & E_NDS32_HAS_NO_MAC_INST; - out_fpu_config = elf_elfheader (obfd)->e_flags & E_NDS32_FPU_REG_CONF; - out_version = elf_elfheader (obfd)->e_flags & EF_NDS32_ELF_VERSION; - if (!elf_flags_init (obfd)) - { - /* If the input is the default architecture then do not - bother setting the flags for the output architecture, - instead allow future merges to do this. If no future - merges ever set these flags then they will retain their - unitialised values, which surprise surprise, correspond - to the default values. */ - if (bfd_get_arch_info (ibfd)->the_default) - return TRUE; - - elf_flags_init (obfd) = TRUE; - elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags; - if (bfd_get_arch (obfd) == bfd_get_arch (ibfd) - && bfd_get_arch_info (obfd)->the_default) + /* We may need to merge V1 and V2 arch object files to V2. */ + if ((elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH) + != (elf_elfheader (obfd)->e_flags & EF_NDS_ARCH)) { - return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), - bfd_get_mach (ibfd)); + /* Need to convert version. */ + if ((elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH) + == E_NDS_ARCH_STAR_RESERVED) + { + elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags; + } + else if ((elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH) + == E_NDS_ARCH_STAR_V3_M + && (elf_elfheader (obfd)->e_flags & EF_NDS_ARCH) + == E_NDS_ARCH_STAR_V3_0) + { + elf_elfheader (ibfd)->e_flags = + (elf_elfheader (ibfd)->e_flags & (~EF_NDS_ARCH)) + | E_NDS_ARCH_STAR_V3_0; + } + else if ((elf_elfheader (obfd)->e_flags & EF_NDS_ARCH) + == E_NDS_ARCH_STAR_V0_9 + || (elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH) + > (elf_elfheader (obfd)->e_flags & EF_NDS_ARCH)) + { + elf_elfheader (obfd)->e_flags = + convert_e_flags (elf_elfheader (obfd)->e_flags, + (elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH)); + } + else + { + elf_elfheader (ibfd)->e_flags = + convert_e_flags (elf_elfheader (ibfd)->e_flags, + (elf_elfheader (obfd)->e_flags & EF_NDS_ARCH)); + } } - return TRUE; - } + /* Extract some flags. */ + in_flags = elf_elfheader (ibfd)->e_flags + & (~(E_NDS32_HAS_REDUCED_REGS | EF_NDS32_ELF_VERSION + | E_NDS32_HAS_NO_MAC_INST | E_NDS32_FPU_REG_CONF)); + + /* The following flags need special treatment. */ + in_16regs = elf_elfheader (ibfd)->e_flags & E_NDS32_HAS_REDUCED_REGS; + in_no_mac = elf_elfheader (ibfd)->e_flags & E_NDS32_HAS_NO_MAC_INST; + in_fpu_config = elf_elfheader (ibfd)->e_flags & E_NDS32_FPU_REG_CONF; + + /* Extract some flags. */ + out_flags = elf_elfheader (obfd)->e_flags + & (~(E_NDS32_HAS_REDUCED_REGS | EF_NDS32_ELF_VERSION + | E_NDS32_HAS_NO_MAC_INST | E_NDS32_FPU_REG_CONF)); + + /* The following flags need special treatment. */ + out_16regs = elf_elfheader (obfd)->e_flags & E_NDS32_HAS_REDUCED_REGS; + out_no_mac = elf_elfheader (obfd)->e_flags & E_NDS32_HAS_NO_MAC_INST; + out_fpu_config = elf_elfheader (obfd)->e_flags & E_NDS32_FPU_REG_CONF; + out_version = elf_elfheader (obfd)->e_flags & EF_NDS32_ELF_VERSION; + if (!elf_flags_init (obfd)) + { + /* If the input is the default architecture then do not + bother setting the flags for the output architecture, + instead allow future merges to do this. If no future + merges ever set these flags then they will retain their + unitialised values, which surprise surprise, correspond + to the default values. */ + if (bfd_get_arch_info (ibfd)->the_default) + return TRUE; + + elf_flags_init (obfd) = TRUE; + elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags; - /* Check flag compatibility. */ - if ((in_flags & EF_NDS_ABI) != (out_flags & EF_NDS_ABI)) - { - _bfd_error_handler - (_("%pB: error: ABI mismatch with previous modules"), ibfd); + if (bfd_get_arch (obfd) == bfd_get_arch (ibfd) + && bfd_get_arch_info (obfd)->the_default) + { + return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), + bfd_get_mach (ibfd)); + } - bfd_set_error (bfd_error_bad_value); - return FALSE; - } + return TRUE; + } - if ((in_flags & EF_NDS_ARCH) != (out_flags & EF_NDS_ARCH)) - { - if (((in_flags & EF_NDS_ARCH) != E_N1_ARCH)) + /* Check flag compatibility. */ + if ((in_flags & EF_NDS_ABI) != (out_flags & EF_NDS_ABI)) { _bfd_error_handler - (_("%pB: error: instruction set mismatch with previous modules"), - ibfd); - + (_("%pB: error: ABI mismatch with previous modules"), ibfd); bfd_set_error (bfd_error_bad_value); return FALSE; } - } - /* When linking with V1.2 and V1.3 objects together the output is V1.2. - and perf ext1 and DIV are mergerd to perf ext1. */ - if (in_version == E_NDS32_ELF_VER_1_2 || out_version == E_NDS32_ELF_VER_1_2) - { - elf_elfheader (obfd)->e_flags = - (in_flags & (~(E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST))) - | (out_flags & (~(E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST))) - | (((in_flags & (E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST))) - ? E_NDS32_HAS_EXT_INST : 0) - | (((out_flags & (E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST))) - ? E_NDS32_HAS_EXT_INST : 0) - | (in_16regs & out_16regs) | (in_no_mac & out_no_mac) - | ((in_version > out_version) ? out_version : in_version); - } - else - { - if (in_version != out_version) - _bfd_error_handler - /* xgettext:c-format */ - (_("%pB: warning: incompatible elf-versions %s and %s"), - ibfd, nds32_elfver_strtab[out_version], - nds32_elfver_strtab[in_version]); - - elf_elfheader (obfd)->e_flags = in_flags | out_flags - | (in_16regs & out_16regs) | (in_no_mac & out_no_mac) - | (in_fpu_config > out_fpu_config ? in_fpu_config : out_fpu_config) - | (in_version > out_version ? out_version : in_version); + if ((in_flags & EF_NDS_ARCH) != (out_flags & EF_NDS_ARCH)) + { + if (((in_flags & EF_NDS_ARCH) != E_N1_ARCH)) + { + _bfd_error_handler + (_("%pB: error: instruction set mismatch with previous modules"), + ibfd); + + bfd_set_error (bfd_error_bad_value); + return FALSE; + } + } + + /* When linking with V1.2 and V1.3 objects together the output is V1.2. + and perf ext1 and DIV are mergerd to perf ext1. */ + if (in_version == E_NDS32_ELF_VER_1_2 || out_version == E_NDS32_ELF_VER_1_2) + { + elf_elfheader (obfd)->e_flags = + (in_flags & (~(E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST))) + | (out_flags & (~(E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST))) + | (((in_flags & (E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST))) + ? E_NDS32_HAS_EXT_INST : 0) + | (((out_flags & (E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST))) + ? E_NDS32_HAS_EXT_INST : 0) + | (in_16regs & out_16regs) | (in_no_mac & out_no_mac) + | ((in_version > out_version) ? out_version : in_version); + } + else + { + if (in_version != out_version) + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB: warning: incompatible elf-versions %s and %s"), + ibfd, nds32_elfver_strtab[out_version], + nds32_elfver_strtab[in_version]); + + elf_elfheader (obfd)->e_flags = in_flags | out_flags + | (in_16regs & out_16regs) | (in_no_mac & out_no_mac) + | (in_fpu_config > out_fpu_config ? in_fpu_config : out_fpu_config) + | (in_version > out_version ? out_version : in_version); + } } return TRUE; -- 2.17.0