diff --git a/Sw64-Add-support-for-EFI.patch b/Sw64-Add-support-for-EFI.patch new file mode 100644 index 0000000000000000000000000000000000000000..eac62a64b73682eef6b794a52a2aeea8371d3a59 --- /dev/null +++ b/Sw64-Add-support-for-EFI.patch @@ -0,0 +1,3443 @@ +diff --git a/bfd/Makefile.am b/bfd/Makefile.am +index 4009f0a2..733a1d45 100644 +--- a/bfd/Makefile.am ++++ b/bfd/Makefile.am +@@ -592,7 +592,9 @@ BFD64_BACKENDS = \ + pei-x86_64.lo \ + pepigen.lo \ + pex64igen.lo \ +- vms-alpha.lo ++ vms-alpha.lo \ ++ pe-sw_64igen.lo \ ++ pei-sw_64.lo + + BFD64_BACKENDS_CFILES = \ + aix5ppc-core.c \ +@@ -636,7 +638,8 @@ BFD64_BACKENDS_CFILES = \ + pei-ia64.c \ + pei-loongarch64.c \ + pei-x86_64.c \ +- vms-alpha.c ++ vms-alpha.c \ ++ pei-sw_64.c + + OPTIONAL_BACKENDS = \ + cisco-core.lo \ +@@ -690,7 +693,7 @@ BUILD_CFILES = \ + elf32-ia64.c elf64-ia64.c \ + elf32-loongarch.c elf64-loongarch.c \ + elf32-riscv.c elf64-riscv.c \ +- peigen.c pepigen.c pex64igen.c pe-aarch64igen.c pe-loongarch64igen.c ++ peigen.c pepigen.c pex64igen.c pe-aarch64igen.c pe-loongarch64igen.c pe-sw_64igen.c + + CFILES = $(SOURCE_CFILES) $(BUILD_CFILES) + +@@ -892,6 +895,10 @@ pe-loongarch64igen.c: peXXigen.c + $(AM_V_at)echo "#line 1 \"peXXigen.c\"" > $@ + $(AM_V_GEN)$(SED) -e s/XX/peLoongArch64/g < $< >> $@ + ++pe-sw_64igen.c: peXXigen.c ++ $(AM_V_at)echo "#line 1 \"peXXigen.c\"" > $@ ++ $(AM_V_GEN)$(SED) -e s/XX/peSW_64/g < $< >> $@ ++ + host-aout.lo: Makefile + + # The following program can be used to generate a simple config file +diff --git a/bfd/Makefile.in b/bfd/Makefile.in +index e929a9e4..d99d974b 100644 +--- a/bfd/Makefile.in ++++ b/bfd/Makefile.in +@@ -1049,7 +1049,9 @@ BFD64_BACKENDS = \ + pei-x86_64.lo \ + pepigen.lo \ + pex64igen.lo \ +- vms-alpha.lo ++ vms-alpha.lo \ ++ pe-sw_64igen.lo \ ++ pei-sw_64.lo + + BFD64_BACKENDS_CFILES = \ + aix5ppc-core.c \ +@@ -1093,7 +1095,8 @@ BFD64_BACKENDS_CFILES = \ + pei-ia64.c \ + pei-loongarch64.c \ + pei-x86_64.c \ +- vms-alpha.c ++ vms-alpha.c \ ++ pei-sw_64.c + + OPTIONAL_BACKENDS = \ + cisco-core.lo \ +@@ -1146,7 +1149,7 @@ BUILD_CFILES = \ + elf32-ia64.c elf64-ia64.c \ + elf32-loongarch.c elf64-loongarch.c \ + elf32-riscv.c elf64-riscv.c \ +- peigen.c pepigen.c pex64igen.c pe-aarch64igen.c pe-loongarch64igen.c ++ peigen.c pepigen.c pex64igen.c pe-aarch64igen.c pe-loongarch64igen.c pe-sw_64igen.c + + CFILES = $(SOURCE_CFILES) $(BUILD_CFILES) + SOURCE_HFILES = \ +@@ -1703,6 +1706,8 @@ distclean-compile: + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-loongarch64.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-mcore.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-sh.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-sw_64.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-sw_64igen.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-x86_64.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/peigen.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pepigen.Plo@am__quote@ +@@ -2393,6 +2398,10 @@ pe-loongarch64igen.c: peXXigen.c + $(AM_V_at)echo "#line 1 \"peXXigen.c\"" > $@ + $(AM_V_GEN)$(SED) -e s/XX/peLoongArch64/g < $< >> $@ + ++pe-sw_64igen.c: peXXigen.c ++ $(AM_V_at)echo "#line 1 \"peXXigen.c\"" > $@ ++ $(AM_V_GEN)$(SED) -e s/XX/peSW_64/g < $< >> $@ ++ + host-aout.lo: Makefile + + # The following program can be used to generate a simple config file +diff --git a/bfd/bfd.c b/bfd/bfd.c +index e43a388a..752db8c5 100644 +--- a/bfd/bfd.c ++++ b/bfd/bfd.c +@@ -1948,6 +1948,7 @@ bfd_get_sign_extend_vma (bfd *abfd) + || strcmp (name, "pe-arm-wince-little") == 0 + || strcmp (name, "pei-arm-wince-little") == 0 + || strcmp (name, "pei-loongarch64") == 0 ++ || strcmp (name, "pei-sw_64") == 0 + || strcmp (name, "aixcoff-rs6000") == 0 + || strcmp (name, "aix5coff64-rs6000") == 0) + return 1; +diff --git a/bfd/coff-sw_64.c b/bfd/coff-sw_64.c +index c5d515a5..2607f518 100644 +--- a/bfd/coff-sw_64.c ++++ b/bfd/coff-sw_64.c +@@ -1,7 +1,5 @@ +-/* BFD back-end for SW_64 Extended-Coff files. +- Copyright (C) 1993-2023 Free Software Foundation, Inc. +- Modified from coff-mips.c by Steve Chamberlain and +- Ian Lance Taylor . ++/* BFD back-end for SW_64 COFF files. ++ Copyright (C) 2022-2023 Free Software Foundation, Inc. + + This file is part of BFD, the Binary File Descriptor library. + +@@ -20,2440 +18,213 @@ + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + ++ ++#ifndef COFF_WITH_peSW_64 ++#define COFF_WITH_peSW_64 ++#endif ++ ++/* Note we have to make sure not to include headers twice. ++ Not all headers are wrapped in #ifdef guards, so we define ++ PEI_HEADERS to prevent double including here. */ ++#ifndef PEI_HEADERS + #include "sysdep.h" + #include "bfd.h" +-#include "bfdlink.h" + #include "libbfd.h" +-#include "coff/internal.h" +-#include "coff/sym.h" +-#include "coff/symconst.h" +-#include "coff/ecoff.h" + #include "coff/sw_64.h" +-#include "aout/ar.h" ++#include "coff/internal.h" ++#include "coff/pe.h" + #include "libcoff.h" +-#include "libecoff.h" +- +-/* Prototypes for static functions. */ +- +-/* ECOFF has COFF sections, but the debugging information is stored in +- a completely different format. ECOFF targets use some of the +- swapping routines from coffswap.h, and some of the generic COFF +- routines in coffgen.c, but, unlike the real COFF targets, do not +- use coffcode.h itself. +- +- Get the generic COFF swapping routines, except for the reloc, +- symbol, and lineno ones. Give them ecoff names. Define some +- accessor macros for the large sizes used for SW_64 ECOFF. */ +- +-#define GET_FILEHDR_SYMPTR H_GET_64 +-#define PUT_FILEHDR_SYMPTR H_PUT_64 +-#define GET_AOUTHDR_TSIZE H_GET_64 +-#define PUT_AOUTHDR_TSIZE H_PUT_64 +-#define GET_AOUTHDR_DSIZE H_GET_64 +-#define PUT_AOUTHDR_DSIZE H_PUT_64 +-#define GET_AOUTHDR_BSIZE H_GET_64 +-#define PUT_AOUTHDR_BSIZE H_PUT_64 +-#define GET_AOUTHDR_ENTRY H_GET_64 +-#define PUT_AOUTHDR_ENTRY H_PUT_64 +-#define GET_AOUTHDR_TEXT_START H_GET_64 +-#define PUT_AOUTHDR_TEXT_START H_PUT_64 +-#define GET_AOUTHDR_DATA_START H_GET_64 +-#define PUT_AOUTHDR_DATA_START H_PUT_64 +-#define GET_SCNHDR_PADDR H_GET_64 +-#define PUT_SCNHDR_PADDR H_PUT_64 +-#define GET_SCNHDR_VADDR H_GET_64 +-#define PUT_SCNHDR_VADDR H_PUT_64 +-#define GET_SCNHDR_SIZE H_GET_64 +-#define PUT_SCNHDR_SIZE H_PUT_64 +-#define GET_SCNHDR_SCNPTR H_GET_64 +-#define PUT_SCNHDR_SCNPTR H_PUT_64 +-#define GET_SCNHDR_RELPTR H_GET_64 +-#define PUT_SCNHDR_RELPTR H_PUT_64 +-#define GET_SCNHDR_LNNOPTR H_GET_64 +-#define PUT_SCNHDR_LNNOPTR H_PUT_64 +- +-#define SW_64ECOFF +- +-#define NO_COFF_RELOCS +-#define NO_COFF_SYMBOLS +-#define NO_COFF_LINENOS +-#define coff_swap_filehdr_in sw_64_ecoff_swap_filehdr_in +-#define coff_swap_filehdr_out sw_64_ecoff_swap_filehdr_out +-#define coff_swap_aouthdr_in sw_64_ecoff_swap_aouthdr_in +-#define coff_swap_aouthdr_out sw_64_ecoff_swap_aouthdr_out +-#define coff_swap_scnhdr_in sw_64_ecoff_swap_scnhdr_in +-#define coff_swap_scnhdr_out sw_64_ecoff_swap_scnhdr_out +-#include "coffswap.h" +- +-/* Get the ECOFF swapping routines. */ +-#define ECOFF_64 +-#include "ecoffswap.h" +- +-/* How to process the various reloc types. */ +- +-static bfd_reloc_status_type +-reloc_nil (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc ATTRIBUTE_UNUSED, +- asymbol *sym ATTRIBUTE_UNUSED, void *data ATTRIBUTE_UNUSED, +- asection *sec ATTRIBUTE_UNUSED, bfd *output_bfd ATTRIBUTE_UNUSED, +- char **error_message ATTRIBUTE_UNUSED) +-{ +- return bfd_reloc_ok; +-} +- +-/* In case we're on a 32-bit machine, construct a 64-bit "-1" value +- from smaller values. Start with zero, widen, *then* decrement. */ +-#define MINUS_ONE (((bfd_vma) 0) - 1) +- +-static reloc_howto_type sw_64_howto_table[] = { +- /* Reloc type 0 is ignored by itself. However, it appears after a +- GPDISP reloc to identify the location where the low order 16 bits +- of the gp register are loaded. */ +- HOWTO (SW_64_R_IGNORE, /* type */ +- 0, /* rightshift */ +- 0, /* size (0 = byte, 1 = short, 2 = long) */ +- 8, /* bitsize */ +- true, /* pc_relative */ +- 0, /* bitpos */ +- complain_overflow_dont, /* complain_on_overflow */ +- reloc_nil, /* special_function */ +- "IGNORE", /* name */ +- true, /* partial_inplace */ +- 0, /* src_mask */ +- 0, /* dst_mask */ +- true), /* pcrel_offset */ +- +- /* A 32 bit reference to a symbol. */ +- HOWTO (SW_64_R_REFLONG, /* type */ +- 0, /* rightshift */ +- 2, /* size (0 = byte, 1 = short, 2 = long) */ +- 32, /* bitsize */ +- false, /* pc_relative */ +- 0, /* bitpos */ +- complain_overflow_bitfield, /* complain_on_overflow */ +- 0, /* special_function */ +- "REFLONG", /* name */ +- true, /* partial_inplace */ +- 0xffffffff, /* src_mask */ +- 0xffffffff, /* dst_mask */ +- false), /* pcrel_offset */ +- +- /* A 64 bit reference to a symbol. */ +- HOWTO (SW_64_R_REFQUAD, /* type */ +- 0, /* rightshift */ +- 4, /* size (0 = byte, 1 = short, 2 = long) */ +- 64, /* bitsize */ +- false, /* pc_relative */ +- 0, /* bitpos */ +- complain_overflow_bitfield, /* complain_on_overflow */ +- 0, /* special_function */ +- "REFQUAD", /* name */ +- true, /* partial_inplace */ +- MINUS_ONE, /* src_mask */ +- MINUS_ONE, /* dst_mask */ +- false), /* pcrel_offset */ +- +- /* A 32 bit GP relative offset. This is just like REFLONG except +- that when the value is used the value of the gp register will be +- added in. */ +- HOWTO (SW_64_R_GPREL32, /* type */ +- 0, /* rightshift */ +- 2, /* size (0 = byte, 1 = short, 2 = long) */ +- 32, /* bitsize */ +- false, /* pc_relative */ +- 0, /* bitpos */ +- complain_overflow_bitfield, /* complain_on_overflow */ +- 0, /* special_function */ +- "GPREL32", /* name */ +- true, /* partial_inplace */ +- 0xffffffff, /* src_mask */ +- 0xffffffff, /* dst_mask */ +- false), /* pcrel_offset */ +- +- /* Used for an instruction that refers to memory off the GP +- register. The offset is 16 bits of the 32 bit instruction. This +- reloc always seems to be against the .lita section. */ +- HOWTO (SW_64_R_LITERAL, /* type */ +- 0, /* rightshift */ +- 2, /* size (0 = byte, 1 = short, 2 = long) */ +- 16, /* bitsize */ +- false, /* pc_relative */ +- 0, /* bitpos */ +- complain_overflow_signed, /* complain_on_overflow */ +- 0, /* special_function */ +- "LITERAL", /* name */ +- true, /* partial_inplace */ +- 0xffff, /* src_mask */ +- 0xffff, /* dst_mask */ +- false), /* pcrel_offset */ +- +- /* This reloc only appears immediately following a LITERAL reloc. +- It identifies a use of the literal. It seems that the linker can +- use this to eliminate a portion of the .lita section. The symbol +- index is special: 1 means the literal address is in the base +- register of a memory format instruction; 2 means the literal +- address is in the byte offset register of a byte-manipulation +- instruction; 3 means the literal address is in the target +- register of a jsr instruction. This does not actually do any +- relocation. */ +- HOWTO (SW_64_R_LITUSE, /* type */ +- 0, /* rightshift */ +- 2, /* size (0 = byte, 1 = short, 2 = long) */ +- 32, /* bitsize */ +- false, /* pc_relative */ +- 0, /* bitpos */ +- complain_overflow_dont, /* complain_on_overflow */ +- reloc_nil, /* special_function */ +- "LITUSE", /* name */ +- false, /* partial_inplace */ +- 0, /* src_mask */ +- 0, /* dst_mask */ +- false), /* pcrel_offset */ +- +- /* Load the gp register. This is always used for a ldah instruction +- which loads the upper 16 bits of the gp register. The next reloc +- will be an IGNORE reloc which identifies the location of the lda +- instruction which loads the lower 16 bits. The symbol index of +- the GPDISP instruction appears to actually be the number of bytes +- between the ldah and lda instructions. This gives two different +- ways to determine where the lda instruction is; I don't know why +- both are used. The value to use for the relocation is the +- difference between the GP value and the current location; the +- load will always be done against a register holding the current +- address. */ +- HOWTO (SW_64_R_GPDISP, /* type */ +- 16, /* rightshift */ +- 2, /* size (0 = byte, 1 = short, 2 = long) */ +- 16, /* bitsize */ +- true, /* pc_relative */ +- 0, /* bitpos */ +- complain_overflow_dont, /* complain_on_overflow */ +- reloc_nil, /* special_function */ +- "GPDISP", /* name */ +- true, /* partial_inplace */ +- 0xffff, /* src_mask */ +- 0xffff, /* dst_mask */ +- true), /* pcrel_offset */ +- +- /* A 21 bit branch. The native assembler generates these for +- branches within the text segment, and also fills in the PC +- relative offset in the instruction. */ +- HOWTO (SW_64_R_BRADDR, /* type */ +- 2, /* rightshift */ +- 2, /* size (0 = byte, 1 = short, 2 = long) */ +- 21, /* bitsize */ +- true, /* pc_relative */ +- 0, /* bitpos */ +- complain_overflow_signed, /* complain_on_overflow */ +- 0, /* special_function */ +- "BRADDR", /* name */ +- true, /* partial_inplace */ +- 0x1fffff, /* src_mask */ +- 0x1fffff, /* dst_mask */ +- false), /* pcrel_offset */ +- +- /* A 26 bit branch. The native assembler generates these for +- branches within the text segment, and also fills in the PC +- relative offset in the instruction. */ +- HOWTO (SW_64_R_BR26ADDR, /* type */ +- 2, /* rightshift */ +- 2, /* size (0 = byte, 1 = short, 2 = long) */ +- 26, /* bitsize */ +- true, /* pc_relative */ +- 0, /* bitpos */ +- complain_overflow_signed, /* complain_on_overflow */ +- 0, /* special_function */ +- "BR26ADDR", /* name */ +- true, /* partial_inplace */ +- 0x3ffffff, /* src_mask */ +- 0x3ffffff, /* dst_mask */ +- false), /* pcrel_offset */ +- +- /* A hint for a jump to a register. */ +- HOWTO (SW_64_R_HINT, /* type */ +- 2, /* rightshift */ +- 2, /* size (0 = byte, 1 = short, 2 = long) */ +- 14, /* bitsize */ +- true, /* pc_relative */ +- 0, /* bitpos */ +- complain_overflow_dont, /* complain_on_overflow */ +- 0, /* special_function */ +- "HINT", /* name */ +- true, /* partial_inplace */ +- 0x3fff, /* src_mask */ +- 0x3fff, /* dst_mask */ +- false), /* pcrel_offset */ +- +- /* 16 bit PC relative offset. */ +- HOWTO (SW_64_R_SREL16, /* type */ +- 0, /* rightshift */ +- 1, /* size (0 = byte, 1 = short, 2 = long) */ +- 16, /* bitsize */ +- true, /* pc_relative */ +- 0, /* bitpos */ +- complain_overflow_signed, /* complain_on_overflow */ +- 0, /* special_function */ +- "SREL16", /* name */ +- true, /* partial_inplace */ +- 0xffff, /* src_mask */ +- 0xffff, /* dst_mask */ +- false), /* pcrel_offset */ +- +- /* 32 bit PC relative offset. */ +- HOWTO (SW_64_R_SREL32, /* type */ +- 0, /* rightshift */ +- 2, /* size (0 = byte, 1 = short, 2 = long) */ +- 32, /* bitsize */ +- true, /* pc_relative */ +- 0, /* bitpos */ +- complain_overflow_signed, /* complain_on_overflow */ +- 0, /* special_function */ +- "SREL32", /* name */ +- true, /* partial_inplace */ +- 0xffffffff, /* src_mask */ +- 0xffffffff, /* dst_mask */ +- false), /* pcrel_offset */ +- +- /* A 64 bit PC relative offset. */ +- HOWTO (SW_64_R_SREL64, /* type */ +- 0, /* rightshift */ +- 4, /* size (0 = byte, 1 = short, 2 = long) */ +- 64, /* bitsize */ +- true, /* pc_relative */ +- 0, /* bitpos */ +- complain_overflow_signed, /* complain_on_overflow */ +- 0, /* special_function */ +- "SREL64", /* name */ +- true, /* partial_inplace */ +- MINUS_ONE, /* src_mask */ +- MINUS_ONE, /* dst_mask */ +- false), /* pcrel_offset */ +- +- /* Push a value on the reloc evaluation stack. */ +- HOWTO (SW_64_R_OP_PUSH, /* type */ +- 0, /* rightshift */ +- 0, /* size (0 = byte, 1 = short, 2 = long) */ +- 0, /* bitsize */ +- false, /* pc_relative */ +- 0, /* bitpos */ +- complain_overflow_dont, /* complain_on_overflow */ +- 0, /* special_function */ +- "OP_PUSH", /* name */ +- false, /* partial_inplace */ +- 0, /* src_mask */ +- 0, /* dst_mask */ +- false), /* pcrel_offset */ +- +- /* Store the value from the stack at the given address. Store it in +- a bitfield of size r_size starting at bit position r_offset. */ +- HOWTO (SW_64_R_OP_STORE, /* type */ +- 0, /* rightshift */ +- 4, /* size (0 = byte, 1 = short, 2 = long) */ +- 64, /* bitsize */ +- false, /* pc_relative */ +- 0, /* bitpos */ +- complain_overflow_dont, /* complain_on_overflow */ +- 0, /* special_function */ +- "OP_STORE", /* name */ +- false, /* partial_inplace */ +- 0, /* src_mask */ +- MINUS_ONE, /* dst_mask */ +- false), /* pcrel_offset */ +- +- /* Subtract the reloc address from the value on the top of the +- relocation stack. */ +- HOWTO (SW_64_R_OP_PSUB, /* type */ +- 0, /* rightshift */ +- 0, /* size (0 = byte, 1 = short, 2 = long) */ +- 0, /* bitsize */ +- false, /* pc_relative */ +- 0, /* bitpos */ +- complain_overflow_dont, /* complain_on_overflow */ +- 0, /* special_function */ +- "OP_PSUB", /* name */ +- false, /* partial_inplace */ +- 0, /* src_mask */ +- 0, /* dst_mask */ +- false), /* pcrel_offset */ +- +- /* Shift the value on the top of the relocation stack right by the +- given value. */ +- HOWTO (SW_64_R_OP_PRSHIFT, /* type */ +- 0, /* rightshift */ +- 0, /* size (0 = byte, 1 = short, 2 = long) */ +- 0, /* bitsize */ +- false, /* pc_relative */ +- 0, /* bitpos */ +- complain_overflow_dont, /* complain_on_overflow */ +- 0, /* special_function */ +- "OP_PRSHIFT", /* name */ +- false, /* partial_inplace */ +- 0, /* src_mask */ +- 0, /* dst_mask */ +- false), /* pcrel_offset */ +- +- /* Adjust the GP value for a new range in the object file. */ +- HOWTO (SW_64_R_GPVALUE, /* type */ +- 0, /* rightshift */ +- 0, /* size (0 = byte, 1 = short, 2 = long) */ +- 0, /* bitsize */ +- false, /* pc_relative */ +- 0, /* bitpos */ +- complain_overflow_dont, /* complain_on_overflow */ +- 0, /* special_function */ +- "GPVALUE", /* name */ +- false, /* partial_inplace */ +- 0, /* src_mask */ +- 0, /* dst_mask */ +- false) /* pcrel_offset */ +-}; +- +-/* Recognize an SW_64 ECOFF file. */ +- +-static bfd_cleanup +-sw_64_ecoff_object_p (bfd *abfd) +-{ +- bfd_cleanup ret; +- +- ret = coff_object_p (abfd); +- +- if (ret != NULL) +- { +- asection *sec; +- +- /* SW_64 ECOFF has a .pdata section. The lnnoptr field of the +- .pdata section is the number of entries it contains. Each +- entry takes up 8 bytes. The number of entries is required +- since the section is aligned to a 16 byte boundary. When we +- link .pdata sections together, we do not want to include the +- alignment bytes. We handle this on input by faking the size +- of the .pdata section to remove the unwanted alignment bytes. +- On output we will set the lnnoptr field and force the +- alignment. */ +- sec = bfd_get_section_by_name (abfd, _PDATA); +- if (sec != (asection *) NULL) +- { +- bfd_size_type size; +- +- size = (bfd_size_type) sec->line_filepos * 8; +- BFD_ASSERT (size == sec->size || size + 8 == sec->size); +- if (!bfd_set_section_size (sec, size)) +- return NULL; +- } +- } +- +- return ret; +-} +- +-/* See whether the magic number matches. */ +- +-static bool +-sw_64_ecoff_bad_format_hook (bfd *abfd ATTRIBUTE_UNUSED, void *filehdr) +-{ +- struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; +- +- if (!SW_64_ECOFF_BADMAG (*internal_f)) +- return true; +- +- if (SW_64_ECOFF_COMPRESSEDMAG (*internal_f)) +- _bfd_error_handler ( +- _ ("%pB: cannot handle compressed SW_64 binaries; " +- "use compiler flags, or objZ, to generate uncompressed binaries"), +- abfd); +- +- return false; +-} +- +-/* This is a hook called by coff_real_object_p to create any backend +- specific information. */ +- +-static void * +-sw_64_ecoff_mkobject_hook (bfd *abfd, void *filehdr, void *aouthdr) +-{ +- void *ecoff; +- +- ecoff = _bfd_ecoff_mkobject_hook (abfd, filehdr, aouthdr); +- +- if (ecoff != NULL) +- { +- struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; +- +- /* Set additional BFD flags according to the object type from the +- machine specific file header flags. */ +- switch (internal_f->f_flags & F_SW_64_OBJECT_TYPE_MASK) +- { +- case F_SW_64_SHARABLE: +- abfd->flags |= DYNAMIC; +- break; +- case F_SW_64_CALL_SHARED: +- /* Always executable if using shared libraries as the run time +- loader might resolve undefined references. */ +- abfd->flags |= (DYNAMIC | EXEC_P); +- break; +- } +- } +- return ecoff; +-} +- +-/* Reloc handling. */ +- +-/* Swap a reloc in. */ +- +-static void +-sw_64_ecoff_swap_reloc_in (bfd *abfd, void *ext_ptr, +- struct internal_reloc *intern) +-{ +- const RELOC *ext = (RELOC *) ext_ptr; +- +- intern->r_vaddr = H_GET_64 (abfd, ext->r_vaddr); +- intern->r_symndx = H_GET_32 (abfd, ext->r_symndx); +- +- BFD_ASSERT (bfd_header_little_endian (abfd)); +- +- intern->r_type = ((ext->r_bits[0] & RELOC_BITS0_TYPE_LITTLE) +- >> RELOC_BITS0_TYPE_SH_LITTLE); +- intern->r_extern = (ext->r_bits[1] & RELOC_BITS1_EXTERN_LITTLE) != 0; +- intern->r_offset = ((ext->r_bits[1] & RELOC_BITS1_OFFSET_LITTLE) +- >> RELOC_BITS1_OFFSET_SH_LITTLE); +- /* Ignored the reserved bits. */ +- intern->r_size = ((ext->r_bits[3] & RELOC_BITS3_SIZE_LITTLE) +- >> RELOC_BITS3_SIZE_SH_LITTLE); +- +- if (intern->r_type == SW_64_R_LITUSE || intern->r_type == SW_64_R_GPDISP) +- { +- /* Handle the LITUSE and GPDISP relocs specially. Its symndx +- value is not actually a symbol index, but is instead a +- special code. We put the code in the r_size field, and +- clobber the symndx. */ +- if (intern->r_size != 0) +- abort (); +- intern->r_size = intern->r_symndx; +- intern->r_symndx = RELOC_SECTION_NONE; +- } +- else if (intern->r_type == SW_64_R_IGNORE) +- { +- /* The IGNORE reloc generally follows a GPDISP reloc, and is +- against the .lita section. The section is irrelevant. */ +- if (!intern->r_extern && intern->r_symndx == RELOC_SECTION_ABS) +- abort (); +- if (!intern->r_extern && intern->r_symndx == RELOC_SECTION_LITA) +- intern->r_symndx = RELOC_SECTION_ABS; +- } +-} +- +-/* Swap a reloc out. */ +- +-static void +-sw_64_ecoff_swap_reloc_out (bfd *abfd, const struct internal_reloc *intern, +- void *dst) +-{ +- RELOC *ext = (RELOC *) dst; +- long symndx; +- unsigned char size; +- +- /* Undo the hackery done in swap_reloc_in. */ +- if (intern->r_type == SW_64_R_LITUSE || intern->r_type == SW_64_R_GPDISP) +- { +- symndx = intern->r_size; +- size = 0; +- } +- else if (intern->r_type == SW_64_R_IGNORE && !intern->r_extern +- && intern->r_symndx == RELOC_SECTION_ABS) +- { +- symndx = RELOC_SECTION_LITA; +- size = intern->r_size; +- } +- else +- { +- symndx = intern->r_symndx; +- size = intern->r_size; +- } +- +- /* XXX FIXME: The maximum symndx value used to be 14 but this +- fails with object files produced by DEC's C++ compiler. +- Where does the value 14 (or 15) come from anyway ? */ +- BFD_ASSERT (intern->r_extern +- || (intern->r_symndx >= 0 && intern->r_symndx <= 15)); +- +- H_PUT_64 (abfd, intern->r_vaddr, ext->r_vaddr); +- H_PUT_32 (abfd, symndx, ext->r_symndx); +- +- BFD_ASSERT (bfd_header_little_endian (abfd)); +- +- ext->r_bits[0] = ((intern->r_type << RELOC_BITS0_TYPE_SH_LITTLE) +- & RELOC_BITS0_TYPE_LITTLE); +- ext->r_bits[1] = ((intern->r_extern ? RELOC_BITS1_EXTERN_LITTLE : 0) +- | ((intern->r_offset << RELOC_BITS1_OFFSET_SH_LITTLE) +- & RELOC_BITS1_OFFSET_LITTLE)); +- ext->r_bits[2] = 0; +- ext->r_bits[3] +- = ((size << RELOC_BITS3_SIZE_SH_LITTLE) & RELOC_BITS3_SIZE_LITTLE); +-} +- +-/* Finish canonicalizing a reloc. Part of this is generic to all +- ECOFF targets, and that part is in ecoff.c. The rest is done in +- this backend routine. It must fill in the howto field. */ +- +-static void +-sw_64_adjust_reloc_in (bfd *abfd, const struct internal_reloc *intern, +- arelent *rptr) +-{ +- if (intern->r_type > SW_64_R_GPVALUE) +- { +- /* xgettext:c-format */ +- _bfd_error_handler (_ ("%pB: unsupported relocation type %#x"), abfd, +- intern->r_type); +- bfd_set_error (bfd_error_bad_value); +- rptr->addend = 0; +- rptr->howto = NULL; +- return; +- } +- +- switch (intern->r_type) +- { +- case SW_64_R_BRADDR: +- case SW_64_R_BR26ADDR: +- case SW_64_R_SREL16: +- case SW_64_R_SREL32: +- case SW_64_R_SREL64: +- /* This relocs appear to be fully resolved when they are against +- internal symbols. Against external symbols, BRADDR at least +- appears to be resolved against the next instruction. */ +- if (!intern->r_extern) +- rptr->addend = 0; +- else +- rptr->addend = -(intern->r_vaddr + 4); +- break; +- +- case SW_64_R_GPREL32: +- case SW_64_R_LITERAL: +- /* Copy the gp value for this object file into the addend, to +- ensure that we are not confused by the linker. */ +- if (!intern->r_extern) +- rptr->addend += ecoff_data (abfd)->gp; +- break; +- +- case SW_64_R_LITUSE: +- case SW_64_R_GPDISP: +- /* The LITUSE and GPDISP relocs do not use a symbol, or an +- addend, but they do use a special code. Put this code in the +- addend field. */ +- rptr->addend = intern->r_size; +- break; +- +- case SW_64_R_OP_STORE: +- /* The STORE reloc needs the size and offset fields. We store +- them in the addend. */ +- BFD_ASSERT (intern->r_offset <= 256); +- rptr->addend = (intern->r_offset << 8) + intern->r_size; +- break; +- +- case SW_64_R_OP_PUSH: +- case SW_64_R_OP_PSUB: +- case SW_64_R_OP_PRSHIFT: +- /* The PUSH, PSUB and PRSHIFT relocs do not actually use an +- address. I believe that the address supplied is really an +- addend. */ +- rptr->addend = intern->r_vaddr; +- break; +- +- case SW_64_R_GPVALUE: +- /* Set the addend field to the new GP value. */ +- rptr->addend = intern->r_symndx + ecoff_data (abfd)->gp; +- break; +- +- case SW_64_R_IGNORE: +- /* If the type is SW_64_R_IGNORE, make sure this is a reference +- to the absolute section so that the reloc is ignored. For +- some reason the address of this reloc type is not adjusted by +- the section vma. We record the gp value for this object file +- here, for convenience when doing the GPDISP relocation. */ +- rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; +- rptr->address = intern->r_vaddr; +- rptr->addend = ecoff_data (abfd)->gp; +- break; +- +- default: +- break; +- } +- +- rptr->howto = &sw_64_howto_table[intern->r_type]; +-} +- +-/* When writing out a reloc we need to pull some values back out of +- the addend field into the reloc. This is roughly the reverse of +- sw_64_adjust_reloc_in, except that there are several changes we do +- not need to undo. */ +- +-static void +-sw_64_adjust_reloc_out (bfd *abfd ATTRIBUTE_UNUSED, const arelent *rel, +- struct internal_reloc *intern) +-{ +- switch (intern->r_type) +- { +- case SW_64_R_LITUSE: +- case SW_64_R_GPDISP: +- intern->r_size = rel->addend; +- break; +- +- case SW_64_R_OP_STORE: +- intern->r_size = rel->addend & 0xff; +- intern->r_offset = (rel->addend >> 8) & 0xff; +- break; +- +- case SW_64_R_OP_PUSH: +- case SW_64_R_OP_PSUB: +- case SW_64_R_OP_PRSHIFT: +- intern->r_vaddr = rel->addend; +- break; +- +- case SW_64_R_IGNORE: +- intern->r_vaddr = rel->address; +- break; +- +- default: +- break; +- } +-} +- +-/* The size of the stack for the relocation evaluator. */ +-#define RELOC_STACKSIZE (10) +- +-/* SW_64 ECOFF relocs have a built in expression evaluator as well as +- other interdependencies. Rather than use a bunch of special +- functions and global variables, we use a single routine to do all +- the relocation for a section. I haven't yet worked out how the +- assembler is going to handle this. */ +- +-static bfd_byte * +-sw_64_ecoff_get_relocated_section_contents (bfd *abfd, +- struct bfd_link_info *link_info, +- struct bfd_link_order *link_order, +- bfd_byte *data, bool relocatable, +- asymbol **symbols) +-{ +- bfd *input_bfd = link_order->u.indirect.section->owner; +- asection *input_section = link_order->u.indirect.section; +- long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section); +- arelent **reloc_vector = NULL; +- long reloc_count; +- bfd *output_bfd = relocatable ? abfd : (bfd *) NULL; +- bfd_vma gp; +- bfd_size_type sz; +- bool gp_undefined; +- bfd_vma stack[RELOC_STACKSIZE]; +- int tos = 0; +- +- if (reloc_size < 0) +- goto error_return; +- reloc_vector = (arelent **) bfd_malloc ((bfd_size_type) reloc_size); +- if (reloc_vector == NULL && reloc_size != 0) +- goto error_return; +- +- sz = input_section->rawsize ? input_section->rawsize : input_section->size; +- if (!bfd_get_section_contents (input_bfd, input_section, data, 0, sz)) +- goto error_return; +- +- reloc_count +- = bfd_canonicalize_reloc (input_bfd, input_section, reloc_vector, symbols); +- if (reloc_count < 0) +- goto error_return; +- if (reloc_count == 0) +- goto successful_return; +- +- /* Get the GP value for the output BFD. */ +- gp_undefined = false; +- gp = _bfd_get_gp_value (abfd); +- if (gp == 0) +- { +- if (relocatable) +- { +- asection *sec; +- bfd_vma lo; +- +- /* Make up a value. */ +- lo = (bfd_vma) -1; +- for (sec = abfd->sections; sec != NULL; sec = sec->next) +- { +- if (sec->vma < lo +- && (strcmp (sec->name, ".sbss") == 0 +- || strcmp (sec->name, ".sdata") == 0 +- || strcmp (sec->name, ".lit4") == 0 +- || strcmp (sec->name, ".lit8") == 0 +- || strcmp (sec->name, ".lita") == 0)) +- lo = sec->vma; +- } +- gp = lo + 0x8000; +- _bfd_set_gp_value (abfd, gp); +- } +- else +- { +- struct bfd_link_hash_entry *h; +- +- h = bfd_link_hash_lookup (link_info->hash, "_gp", false, false, true); +- if (h == (struct bfd_link_hash_entry *) NULL +- || h->type != bfd_link_hash_defined) +- gp_undefined = true; +- else +- { +- gp = (h->u.def.value + h->u.def.section->output_section->vma +- + h->u.def.section->output_offset); +- _bfd_set_gp_value (abfd, gp); +- } +- } +- } +- +- for (; *reloc_vector != (arelent *) NULL; reloc_vector++) +- { +- arelent *rel; +- bfd_reloc_status_type r; +- char *err; +- +- rel = *reloc_vector; +- r = bfd_reloc_ok; +- switch (rel->howto->type) +- { +- case SW_64_R_IGNORE: +- rel->address += input_section->output_offset; +- break; +- +- case SW_64_R_REFLONG: +- case SW_64_R_REFQUAD: +- case SW_64_R_BRADDR: +- case SW_64_R_BR26ADDR: +- case SW_64_R_HINT: +- case SW_64_R_SREL16: +- case SW_64_R_SREL32: +- case SW_64_R_SREL64: +- if (relocatable +- && ((*rel->sym_ptr_ptr)->flags & BSF_SECTION_SYM) == 0) +- { +- rel->address += input_section->output_offset; +- break; +- } +- r = bfd_perform_relocation (input_bfd, rel, data, input_section, +- output_bfd, &err); +- break; +- +- case SW_64_R_GPREL32: +- /* This relocation is used in a switch table. It is a 32 +- bit offset from the current GP value. We must adjust it +- by the different between the original GP value and the +- current GP value. The original GP value is stored in the +- addend. We adjust the addend and let +- bfd_perform_relocation finish the job. */ +- rel->addend -= gp; +- r = bfd_perform_relocation (input_bfd, rel, data, input_section, +- output_bfd, &err); +- if (r == bfd_reloc_ok && gp_undefined) +- { +- r = bfd_reloc_dangerous; +- err = (char *) _ ( +- "GP relative relocation used when GP not defined"); +- } +- break; +- +- case SW_64_R_LITERAL: +- /* This is a reference to a literal value, generally +- (always?) in the .lita section. This is a 16 bit GP +- relative relocation. Sometimes the subsequent reloc is a +- LITUSE reloc, which indicates how this reloc is used. +- This sometimes permits rewriting the two instructions +- referred to by the LITERAL and the LITUSE into different +- instructions which do not refer to .lita. This can save +- a memory reference, and permits removing a value from +- .lita thus saving GP relative space. +- +- We do not these optimizations. To do them we would need +- to arrange to link the .lita section first, so that by +- the time we got here we would know the final values to +- use. This would not be particularly difficult, but it is +- not currently implemented. */ +- +- { +- unsigned long insn; +- +- /* I believe that the LITERAL reloc will only apply to a +- ldq or ldl instruction, so check my assumption. */ +- insn = bfd_get_32 (input_bfd, data + rel->address); +- BFD_ASSERT (((insn >> 26) & 0x3f) == 0x29 +- || ((insn >> 26) & 0x3f) == 0x28); +- +- rel->addend -= gp; +- r = bfd_perform_relocation (input_bfd, rel, data, input_section, +- output_bfd, &err); +- if (r == bfd_reloc_ok && gp_undefined) +- { +- r = bfd_reloc_dangerous; +- err = (char *) _ ( +- "GP relative relocation used when GP not defined"); +- } +- } +- break; +- +- case SW_64_R_LITUSE: +- /* See SW_64_R_LITERAL above for the uses of this reloc. It +- does not cause anything to happen, itself. */ +- rel->address += input_section->output_offset; +- break; +- +- case SW_64_R_GPDISP: +- /* This marks the ldah of an ldah/lda pair which loads the +- gp register with the difference of the gp value and the +- current location. The second of the pair is r_size bytes +- ahead; it used to be marked with an SW_64_R_IGNORE reloc, +- but that no longer happens in OSF/1 3.2. */ +- { +- unsigned long insn1, insn2; +- bfd_vma addend; +- +- /* Get the two instructions. */ +- insn1 = bfd_get_32 (input_bfd, data + rel->address); +- insn2 = bfd_get_32 (input_bfd, data + rel->address + rel->addend); +- +- BFD_ASSERT (((insn1 >> 26) & 0x3f) == 0x09); /* ldah */ +- BFD_ASSERT (((insn2 >> 26) & 0x3f) == 0x08); /* lda */ +- +- /* Get the existing addend. We must account for the sign +- extension done by lda and ldah. */ +- addend = ((insn1 & 0xffff) << 16) + (insn2 & 0xffff); +- if (insn1 & 0x8000) +- { +- addend -= 0x80000000; +- addend -= 0x80000000; +- } +- if (insn2 & 0x8000) +- addend -= 0x10000; +- +- /* The existing addend includes the different between the +- gp of the input BFD and the address in the input BFD. +- Subtract this out. */ +- addend -= (ecoff_data (input_bfd)->gp +- - (input_section->vma + rel->address)); +- +- /* Now add in the final gp value, and subtract out the +- final address. */ +- addend += (gp +- - (input_section->output_section->vma +- + input_section->output_offset + rel->address)); +- +- /* Change the instructions, accounting for the sign +- extension, and write them out. */ +- if (addend & 0x8000) +- addend += 0x10000; +- insn1 = (insn1 & 0xffff0000) | ((addend >> 16) & 0xffff); +- insn2 = (insn2 & 0xffff0000) | (addend & 0xffff); +- +- bfd_put_32 (input_bfd, (bfd_vma) insn1, data + rel->address); +- bfd_put_32 (input_bfd, (bfd_vma) insn2, +- data + rel->address + rel->addend); +- +- rel->address += input_section->output_offset; +- } +- break; +- +- case SW_64_R_OP_PUSH: +- /* Push a value on the reloc evaluation stack. */ +- { +- asymbol *symbol; +- bfd_vma relocation; +- +- if (relocatable) +- { +- rel->address += input_section->output_offset; +- break; +- } +- +- /* Figure out the relocation of this symbol. */ +- symbol = *rel->sym_ptr_ptr; +- +- if (bfd_is_und_section (symbol->section)) +- r = bfd_reloc_undefined; +- +- if (bfd_is_com_section (symbol->section)) +- relocation = 0; +- else +- relocation = symbol->value; +- relocation += symbol->section->output_section->vma; +- relocation += symbol->section->output_offset; +- relocation += rel->addend; +- +- if (tos >= RELOC_STACKSIZE) +- abort (); +- +- stack[tos++] = relocation; +- } +- break; +- +- case SW_64_R_OP_STORE: +- /* Store a value from the reloc stack into a bitfield. */ +- { +- bfd_vma val; +- int offset, size; +- +- if (relocatable) +- { +- rel->address += input_section->output_offset; +- break; +- } +- +- if (tos == 0) +- abort (); +- +- /* The offset and size for this reloc are encoded into the +- addend field by sw_64_adjust_reloc_in. */ +- offset = (rel->addend >> 8) & 0xff; +- size = rel->addend & 0xff; +- +- val = bfd_get_64 (abfd, data + rel->address); +- val &= ~(((1 << size) - 1) << offset); +- val |= (stack[--tos] & ((1 << size) - 1)) << offset; +- bfd_put_64 (abfd, val, data + rel->address); +- } +- break; +- +- case SW_64_R_OP_PSUB: +- /* Subtract a value from the top of the stack. */ +- { +- asymbol *symbol; +- bfd_vma relocation; +- +- if (relocatable) +- { +- rel->address += input_section->output_offset; +- break; +- } +- +- /* Figure out the relocation of this symbol. */ +- symbol = *rel->sym_ptr_ptr; +- +- if (bfd_is_und_section (symbol->section)) +- r = bfd_reloc_undefined; +- +- if (bfd_is_com_section (symbol->section)) +- relocation = 0; +- else +- relocation = symbol->value; +- relocation += symbol->section->output_section->vma; +- relocation += symbol->section->output_offset; +- relocation += rel->addend; +- +- if (tos == 0) +- abort (); +- +- stack[tos - 1] -= relocation; +- } +- break; +- +- case SW_64_R_OP_PRSHIFT: +- /* Shift the value on the top of the stack. */ +- { +- asymbol *symbol; +- bfd_vma relocation; +- +- if (relocatable) +- { +- rel->address += input_section->output_offset; +- break; +- } +- +- /* Figure out the relocation of this symbol. */ +- symbol = *rel->sym_ptr_ptr; +- +- if (bfd_is_und_section (symbol->section)) +- r = bfd_reloc_undefined; +- +- if (bfd_is_com_section (symbol->section)) +- relocation = 0; +- else +- relocation = symbol->value; +- relocation += symbol->section->output_section->vma; +- relocation += symbol->section->output_offset; +- relocation += rel->addend; +- +- if (tos == 0) +- abort (); +- +- stack[tos - 1] >>= relocation; +- } +- break; +- +- case SW_64_R_GPVALUE: +- /* I really don't know if this does the right thing. */ +- gp = rel->addend; +- gp_undefined = false; +- break; +- +- default: +- abort (); +- } +- +- if (relocatable) +- { +- asection *os = input_section->output_section; +- +- /* A partial link, so keep the relocs. */ +- os->orelocation[os->reloc_count] = rel; +- os->reloc_count++; +- } +- +- if (r != bfd_reloc_ok) +- { +- switch (r) +- { +- case bfd_reloc_undefined: +- (*link_info->callbacks->undefined_symbol) ( +- link_info, bfd_asymbol_name (*rel->sym_ptr_ptr), input_bfd, +- input_section, rel->address, true); +- break; +- case bfd_reloc_dangerous: +- (*link_info->callbacks->reloc_dangerous) (link_info, err, +- input_bfd, +- input_section, +- rel->address); +- break; +- case bfd_reloc_overflow: +- (*link_info->callbacks->reloc_overflow) ( +- link_info, NULL, bfd_asymbol_name (*rel->sym_ptr_ptr), +- rel->howto->name, rel->addend, input_bfd, input_section, +- rel->address); +- break; +- case bfd_reloc_outofrange: +- default: +- abort (); +- break; +- } +- } +- } +- +- if (tos != 0) +- abort (); +- +-successful_return: +- free (reloc_vector); +- return data; +- +-error_return: +- free (reloc_vector); +- return NULL; +-} +- +-/* Get the howto structure for a generic reloc type. */ +- +-static reloc_howto_type * +-sw_64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, +- bfd_reloc_code_real_type code) +-{ +- int sw_64_type; +- +- switch (code) +- { +- case BFD_RELOC_32: +- sw_64_type = SW_64_R_REFLONG; +- break; +- case BFD_RELOC_64: +- case BFD_RELOC_CTOR: +- sw_64_type = SW_64_R_REFQUAD; +- break; +- case BFD_RELOC_GPREL32: +- sw_64_type = SW_64_R_GPREL32; +- break; +- case BFD_RELOC_SW_64_LITERAL: +- sw_64_type = SW_64_R_LITERAL; +- break; +- case BFD_RELOC_SW_64_LITUSE: +- sw_64_type = SW_64_R_LITUSE; +- break; +- case BFD_RELOC_SW_64_GPDISP_HI16: +- sw_64_type = SW_64_R_GPDISP; +- break; +- case BFD_RELOC_SW_64_GPDISP_LO16: +- sw_64_type = SW_64_R_IGNORE; +- break; +- case BFD_RELOC_23_PCREL_S2: +- sw_64_type = SW_64_R_BRADDR; +- break; +- case BFD_RELOC_SW_64_BR26: +- sw_64_type = SW_64_R_BR26ADDR; +- break; +- case BFD_RELOC_SW_64_HINT: +- sw_64_type = SW_64_R_HINT; +- break; +- case BFD_RELOC_16_PCREL: +- sw_64_type = SW_64_R_SREL16; +- break; +- case BFD_RELOC_32_PCREL: +- sw_64_type = SW_64_R_SREL32; +- break; +- case BFD_RELOC_64_PCREL: +- sw_64_type = SW_64_R_SREL64; +- break; +- default: +- return (reloc_howto_type *) NULL; +- } +- +- return &sw_64_howto_table[sw_64_type]; +-} +- +-static reloc_howto_type * +-sw_64_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name) +-{ +- unsigned int i; ++#include "libiberty.h" ++#endif + +- for (i = 0; i < sizeof (sw_64_howto_table) / sizeof (sw_64_howto_table[0]); +- i++) +- if (sw_64_howto_table[i].name != NULL +- && strcasecmp (sw_64_howto_table[i].name, r_name) == 0) +- return &sw_64_howto_table[i]; +- +- return NULL; +-} +- +-/* A helper routine for sw_64_relocate_section which converts an +- external reloc when generating relocatable output. Returns the +- relocation amount. */ +- +-static bfd_vma +-sw_64_convert_external_reloc (bfd *output_bfd ATTRIBUTE_UNUSED, +- struct bfd_link_info *info, bfd *input_bfd, +- struct external_reloc *ext_rel, +- struct ecoff_link_hash_entry *h) +-{ +- unsigned long r_symndx; +- bfd_vma relocation; +- +- BFD_ASSERT (bfd_link_relocatable (info)); +- +- if (h->root.type == bfd_link_hash_defined +- || h->root.type == bfd_link_hash_defweak) +- { +- asection *hsec; +- const char *name; +- +- /* This symbol is defined in the output. Convert the reloc from +- being against the symbol to being against the section. */ +- +- /* Clear the r_extern bit. */ +- ext_rel->r_bits[1] &= ~RELOC_BITS1_EXTERN_LITTLE; +- +- /* Compute a new r_symndx value. */ +- hsec = h->root.u.def.section; +- name = bfd_section_name (hsec->output_section); +- +- r_symndx = (unsigned long) -1; +- switch (name[1]) +- { +- case 'A': +- if (strcmp (name, "*ABS*") == 0) +- r_symndx = RELOC_SECTION_ABS; +- break; +- case 'b': +- if (strcmp (name, ".bss") == 0) +- r_symndx = RELOC_SECTION_BSS; +- break; +- case 'd': +- if (strcmp (name, ".data") == 0) +- r_symndx = RELOC_SECTION_DATA; +- break; +- case 'f': +- if (strcmp (name, ".fini") == 0) +- r_symndx = RELOC_SECTION_FINI; +- break; +- case 'i': +- if (strcmp (name, ".init") == 0) +- r_symndx = RELOC_SECTION_INIT; +- break; +- case 'l': +- if (strcmp (name, ".lita") == 0) +- r_symndx = RELOC_SECTION_LITA; +- else if (strcmp (name, ".lit8") == 0) +- r_symndx = RELOC_SECTION_LIT8; +- else if (strcmp (name, ".lit4") == 0) +- r_symndx = RELOC_SECTION_LIT4; +- break; +- case 'p': +- if (strcmp (name, ".pdata") == 0) +- r_symndx = RELOC_SECTION_PDATA; +- break; +- case 'r': +- if (strcmp (name, ".rdata") == 0) +- r_symndx = RELOC_SECTION_RDATA; +- else if (strcmp (name, ".rconst") == 0) +- r_symndx = RELOC_SECTION_RCONST; +- break; +- case 's': +- if (strcmp (name, ".sdata") == 0) +- r_symndx = RELOC_SECTION_SDATA; +- else if (strcmp (name, ".sbss") == 0) +- r_symndx = RELOC_SECTION_SBSS; +- break; +- case 't': +- if (strcmp (name, ".text") == 0) +- r_symndx = RELOC_SECTION_TEXT; +- break; +- case 'x': +- if (strcmp (name, ".xdata") == 0) +- r_symndx = RELOC_SECTION_XDATA; +- break; +- } +- +- if (r_symndx == (unsigned long) -1) +- abort (); +- +- /* Add the section VMA and the symbol value. */ +- relocation = (h->root.u.def.value + hsec->output_section->vma +- + hsec->output_offset); +- } +- else +- { +- /* Change the symndx value to the right one for +- the output BFD. */ +- r_symndx = h->indx; +- if (r_symndx == (unsigned long) -1) +- { +- /* Caller must give an error. */ +- r_symndx = 0; +- } +- relocation = 0; +- } +- +- /* Write out the new r_symndx value. */ +- H_PUT_32 (input_bfd, r_symndx, ext_rel->r_symndx); +- +- return relocation; +-} +- +-/* Relocate a section while linking an SW_64 ECOFF file. This is +- quite similar to get_relocated_section_contents. Perhaps they +- could be combined somehow. */ +- +-static bool +-sw_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info, +- bfd *input_bfd, asection *input_section, +- bfd_byte *contents, void *external_relocs) +-{ +- asection **symndx_to_section, *lita_sec; +- struct ecoff_link_hash_entry **sym_hashes; +- bfd_vma gp; +- bool gp_undefined; +- bfd_vma stack[RELOC_STACKSIZE]; +- int tos = 0; +- struct external_reloc *ext_rel; +- struct external_reloc *ext_rel_end; +- bfd_size_type amt; +- +- /* We keep a table mapping the symndx found in an internal reloc to +- the appropriate section. This is faster than looking up the +- section by name each time. */ +- symndx_to_section = ecoff_data (input_bfd)->symndx_to_section; +- if (symndx_to_section == (asection **) NULL) +- { +- amt = NUM_RELOC_SECTIONS * sizeof (asection *); +- symndx_to_section = (asection **) bfd_alloc (input_bfd, amt); +- if (!symndx_to_section) +- return false; +- +- symndx_to_section[RELOC_SECTION_NONE] = NULL; +- symndx_to_section[RELOC_SECTION_TEXT] +- = bfd_get_section_by_name (input_bfd, ".text"); +- symndx_to_section[RELOC_SECTION_RDATA] +- = bfd_get_section_by_name (input_bfd, ".rdata"); +- symndx_to_section[RELOC_SECTION_DATA] +- = bfd_get_section_by_name (input_bfd, ".data"); +- symndx_to_section[RELOC_SECTION_SDATA] +- = bfd_get_section_by_name (input_bfd, ".sdata"); +- symndx_to_section[RELOC_SECTION_SBSS] +- = bfd_get_section_by_name (input_bfd, ".sbss"); +- symndx_to_section[RELOC_SECTION_BSS] +- = bfd_get_section_by_name (input_bfd, ".bss"); +- symndx_to_section[RELOC_SECTION_INIT] +- = bfd_get_section_by_name (input_bfd, ".init"); +- symndx_to_section[RELOC_SECTION_LIT8] +- = bfd_get_section_by_name (input_bfd, ".lit8"); +- symndx_to_section[RELOC_SECTION_LIT4] +- = bfd_get_section_by_name (input_bfd, ".lit4"); +- symndx_to_section[RELOC_SECTION_XDATA] +- = bfd_get_section_by_name (input_bfd, ".xdata"); +- symndx_to_section[RELOC_SECTION_PDATA] +- = bfd_get_section_by_name (input_bfd, ".pdata"); +- symndx_to_section[RELOC_SECTION_FINI] +- = bfd_get_section_by_name (input_bfd, ".fini"); +- symndx_to_section[RELOC_SECTION_LITA] +- = bfd_get_section_by_name (input_bfd, ".lita"); +- symndx_to_section[RELOC_SECTION_ABS] = bfd_abs_section_ptr; +- symndx_to_section[RELOC_SECTION_RCONST] +- = bfd_get_section_by_name (input_bfd, ".rconst"); +- +- ecoff_data (input_bfd)->symndx_to_section = symndx_to_section; +- } +- +- sym_hashes = ecoff_data (input_bfd)->sym_hashes; +- +- /* On the SW_64, the .lita section must be addressable by the global +- pointer. To support large programs, we need to allow multiple +- global pointers. This works as long as each input .lita section +- is <64KB big. This implies that when producing relocatable +- output, the .lita section is limited to 64KB. . */ +- +- lita_sec = symndx_to_section[RELOC_SECTION_LITA]; +- gp = _bfd_get_gp_value (output_bfd); +- if (!bfd_link_relocatable (info) && lita_sec != NULL) +- { +- struct ecoff_section_tdata *lita_sec_data; +- +- /* Make sure we have a section data structure to which we can +- hang on to the gp value we pick for the section. */ +- lita_sec_data = ecoff_section_data (input_bfd, lita_sec); +- if (lita_sec_data == NULL) +- { +- amt = sizeof (struct ecoff_section_tdata); +- lita_sec_data +- = ((struct ecoff_section_tdata *) bfd_zalloc (input_bfd, amt)); +- lita_sec->used_by_bfd = lita_sec_data; +- } +- +- if (lita_sec_data->gp != 0) +- { +- /* If we already assigned a gp to this section, we better +- stick with that value. */ +- gp = lita_sec_data->gp; +- } +- else +- { +- bfd_vma lita_vma; +- bfd_size_type lita_size; +- +- lita_vma = lita_sec->output_offset + lita_sec->output_section->vma; +- lita_size = lita_sec->size; +- +- if (gp == 0 || lita_vma < gp - 0x8000 +- || lita_vma + lita_size >= gp + 0x8000) +- { +- /* Either gp hasn't been set at all or the current gp +- cannot address this .lita section. In both cases we +- reset the gp to point into the "middle" of the +- current input .lita section. */ +- if (gp && !ecoff_data (output_bfd)->issued_multiple_gp_warning) +- { +- (*info->callbacks->warning) (info, +- _ ("using multiple gp values"), +- (char *) NULL, output_bfd, +- (asection *) NULL, (bfd_vma) 0); +- ecoff_data (output_bfd)->issued_multiple_gp_warning = true; +- } +- if (lita_vma < gp - 0x8000) +- gp = lita_vma + lita_size - 0x8000; +- else +- gp = lita_vma + 0x8000; +- } +- +- lita_sec_data->gp = gp; +- } +- +- _bfd_set_gp_value (output_bfd, gp); +- } +- +- gp_undefined = (gp == 0); +- +- BFD_ASSERT (bfd_header_little_endian (output_bfd)); +- BFD_ASSERT (bfd_header_little_endian (input_bfd)); +- +- ext_rel = (struct external_reloc *) external_relocs; +- ext_rel_end = ext_rel + input_section->reloc_count; +- for (; ext_rel < ext_rel_end; ext_rel++) +- { +- bfd_vma r_vaddr; +- unsigned long r_symndx; +- int r_type; +- int r_extern; +- int r_offset; +- int r_size; +- bool relocatep; +- bool adjust_addrp; +- bool gp_usedp; +- bfd_vma addend; +- +- r_vaddr = H_GET_64 (input_bfd, ext_rel->r_vaddr); +- r_symndx = H_GET_32 (input_bfd, ext_rel->r_symndx); +- +- r_type = ((ext_rel->r_bits[0] & RELOC_BITS0_TYPE_LITTLE) +- >> RELOC_BITS0_TYPE_SH_LITTLE); +- r_extern = (ext_rel->r_bits[1] & RELOC_BITS1_EXTERN_LITTLE) != 0; +- r_offset = ((ext_rel->r_bits[1] & RELOC_BITS1_OFFSET_LITTLE) +- >> RELOC_BITS1_OFFSET_SH_LITTLE); +- /* Ignored the reserved bits. */ +- r_size = ((ext_rel->r_bits[3] & RELOC_BITS3_SIZE_LITTLE) +- >> RELOC_BITS3_SIZE_SH_LITTLE); +- +- relocatep = false; +- adjust_addrp = true; +- gp_usedp = false; +- addend = 0; +- +- switch (r_type) +- { +- case SW_64_R_GPRELHIGH: +- _bfd_error_handler (_ ("%pB: %s unsupported"), input_bfd, +- "SW_64_R_GPRELHIGH"); +- bfd_set_error (bfd_error_bad_value); +- continue; +- +- case SW_64_R_GPRELLOW: +- _bfd_error_handler (_ ("%pB: %s unsupported"), input_bfd, +- "SW_64_R_GPRELLOW"); +- bfd_set_error (bfd_error_bad_value); +- continue; +- +- default: +- /* xgettext:c-format */ +- _bfd_error_handler (_ ("%pB: unsupported relocation type %#x"), +- input_bfd, (int) r_type); +- bfd_set_error (bfd_error_bad_value); +- continue; +- +- case SW_64_R_IGNORE: +- /* This reloc appears after a GPDISP reloc. On earlier +- versions of OSF/1, It marked the position of the second +- instruction to be altered by the GPDISP reloc, but it is +- not otherwise used for anything. For some reason, the +- address of the relocation does not appear to include the +- section VMA, unlike the other relocation types. */ +- if (bfd_link_relocatable (info)) +- H_PUT_64 (input_bfd, input_section->output_offset + r_vaddr, +- ext_rel->r_vaddr); +- adjust_addrp = false; +- break; +- +- case SW_64_R_REFLONG: +- case SW_64_R_REFQUAD: +- case SW_64_R_HINT: +- relocatep = true; +- break; +- +- case SW_64_R_BRADDR: +- case SW_64_R_BR26ADDR: +- case SW_64_R_SREL16: +- case SW_64_R_SREL32: +- case SW_64_R_SREL64: +- if (r_extern) +- addend += -(r_vaddr + 4); +- relocatep = true; +- break; +- +- case SW_64_R_GPREL32: +- /* This relocation is used in a switch table. It is a 32 +- bit offset from the current GP value. We must adjust it +- by the different between the original GP value and the +- current GP value. */ +- relocatep = true; +- addend = ecoff_data (input_bfd)->gp - gp; +- gp_usedp = true; +- break; +- +- case SW_64_R_LITERAL: +- /* This is a reference to a literal value, generally +- (always?) in the .lita section. This is a 16 bit GP +- relative relocation. Sometimes the subsequent reloc is a +- LITUSE reloc, which indicates how this reloc is used. +- This sometimes permits rewriting the two instructions +- referred to by the LITERAL and the LITUSE into different +- instructions which do not refer to .lita. This can save +- a memory reference, and permits removing a value from +- .lita thus saving GP relative space. +- +- We do not these optimizations. To do them we would need +- to arrange to link the .lita section first, so that by +- the time we got here we would know the final values to +- use. This would not be particularly difficult, but it is +- not currently implemented. */ +- +- /* I believe that the LITERAL reloc will only apply to a ldq +- or ldl instruction, so check my assumption. */ +- { +- unsigned long insn; +- +- insn +- = bfd_get_32 (input_bfd, contents + r_vaddr - input_section->vma); +- BFD_ASSERT (((insn >> 26) & 0x3f) == 0x29 +- || ((insn >> 26) & 0x3f) == 0x28); +- } +- +- relocatep = true; +- addend = ecoff_data (input_bfd)->gp - gp; +- gp_usedp = true; +- break; +- +- case SW_64_R_LITUSE: +- /* See SW_64_R_LITERAL above for the uses of this reloc. It +- does not cause anything to happen, itself. */ +- break; +- +- case SW_64_R_GPDISP: +- /* This marks the ldah of an ldah/lda pair which loads the +- gp register with the difference of the gp value and the +- current location. The second of the pair is r_symndx +- bytes ahead. It used to be marked with an SW_64_R_IGNORE +- reloc, but OSF/1 3.2 no longer does that. */ +- { +- unsigned long insn1, insn2; +- +- /* Get the two instructions. */ +- insn1 +- = bfd_get_32 (input_bfd, contents + r_vaddr - input_section->vma); +- insn2 = bfd_get_32 (input_bfd, (contents + r_vaddr +- - input_section->vma + r_symndx)); +- +- BFD_ASSERT (((insn1 >> 26) & 0x3f) == 0x09); /* ldah */ +- BFD_ASSERT (((insn2 >> 26) & 0x3f) == 0x08); /* lda */ +- +- /* Get the existing addend. We must account for the sign +- extension done by lda and ldah. */ +- addend = ((insn1 & 0xffff) << 16) + (insn2 & 0xffff); +- if (insn1 & 0x8000) +- { +- /* This is addend -= 0x100000000 without causing an +- integer overflow on a 32 bit host. */ +- addend -= 0x80000000; +- addend -= 0x80000000; +- } +- if (insn2 & 0x8000) +- addend -= 0x10000; +- +- /* The existing addend includes the difference between the +- gp of the input BFD and the address in the input BFD. +- We want to change this to the difference between the +- final GP and the final address. */ +- addend += (gp - ecoff_data (input_bfd)->gp + input_section->vma +- - (input_section->output_section->vma +- + input_section->output_offset)); +- +- /* Change the instructions, accounting for the sign +- extension, and write them out. */ +- if (addend & 0x8000) +- addend += 0x10000; +- insn1 = (insn1 & 0xffff0000) | ((addend >> 16) & 0xffff); +- insn2 = (insn2 & 0xffff0000) | (addend & 0xffff); +- +- bfd_put_32 (input_bfd, (bfd_vma) insn1, +- contents + r_vaddr - input_section->vma); +- bfd_put_32 (input_bfd, (bfd_vma) insn2, +- contents + r_vaddr - input_section->vma + r_symndx); +- +- gp_usedp = true; +- } +- break; +- +- case SW_64_R_OP_PUSH: +- case SW_64_R_OP_PSUB: +- case SW_64_R_OP_PRSHIFT: +- /* Manipulate values on the reloc evaluation stack. The +- r_vaddr field is not an address in input_section, it is +- the current value (including any addend) of the object +- being used. */ +- if (!r_extern) +- { +- asection *s; +- +- s = symndx_to_section[r_symndx]; +- if (s == (asection *) NULL) +- abort (); +- addend = s->output_section->vma + s->output_offset - s->vma; +- } +- else +- { +- struct ecoff_link_hash_entry *h; +- +- h = sym_hashes[r_symndx]; +- if (h == (struct ecoff_link_hash_entry *) NULL) +- abort (); +- +- if (!bfd_link_relocatable (info)) +- { +- if (h->root.type == bfd_link_hash_defined +- || h->root.type == bfd_link_hash_defweak) +- addend = (h->root.u.def.value +- + h->root.u.def.section->output_section->vma +- + h->root.u.def.section->output_offset); +- else +- { +- /* Note that we pass the address as 0, since we +- do not have a meaningful number for the +- location within the section that is being +- relocated. */ +- (*info->callbacks->undefined_symbol) (info, +- h->root.root.string, +- input_bfd, +- input_section, +- (bfd_vma) 0, true); +- addend = 0; +- } +- } +- else +- { +- if (h->root.type != bfd_link_hash_defined +- && h->root.type != bfd_link_hash_defweak && h->indx == -1) +- { +- /* This symbol is not being written out. Pass +- the address as 0, as with undefined_symbol, +- above. */ +- (*info->callbacks->unattached_reloc) (info, +- h->root.root.string, +- input_bfd, +- input_section, +- (bfd_vma) 0); +- } +- +- addend = sw_64_convert_external_reloc (output_bfd, info, +- input_bfd, ext_rel, h); +- } +- } +- +- addend += r_vaddr; +- +- if (bfd_link_relocatable (info)) +- { +- /* Adjust r_vaddr by the addend. */ +- H_PUT_64 (input_bfd, addend, ext_rel->r_vaddr); +- } +- else +- { +- switch (r_type) +- { +- case SW_64_R_OP_PUSH: +- if (tos >= RELOC_STACKSIZE) +- abort (); +- stack[tos++] = addend; +- break; +- +- case SW_64_R_OP_PSUB: +- if (tos == 0) +- abort (); +- stack[tos - 1] -= addend; +- break; +- +- case SW_64_R_OP_PRSHIFT: +- if (tos == 0) +- abort (); +- stack[tos - 1] >>= addend; +- break; +- } +- } +- +- adjust_addrp = false; +- break; +- +- case SW_64_R_OP_STORE: +- /* Store a value from the reloc stack into a bitfield. If +- we are generating relocatable output, all we do is +- adjust the address of the reloc. */ +- if (!bfd_link_relocatable (info)) +- { +- bfd_vma mask; +- bfd_vma val; +- +- if (tos == 0) +- abort (); +- +- /* Get the relocation mask. The separate steps and the +- casts to bfd_vma are attempts to avoid a bug in the +- SW_64 OSF 1.3 C compiler. See reloc.c for more +- details. */ +- mask = 1; +- mask <<= (bfd_vma) r_size; +- mask -= 1; +- +- /* FIXME: I don't know what kind of overflow checking, +- if any, should be done here. */ +- val = bfd_get_64 (input_bfd, +- contents + r_vaddr - input_section->vma); +- val &= ~mask << (bfd_vma) r_offset; +- val |= (stack[--tos] & mask) << (bfd_vma) r_offset; +- bfd_put_64 (input_bfd, val, +- contents + r_vaddr - input_section->vma); +- } +- break; +- +- case SW_64_R_GPVALUE: +- /* I really don't know if this does the right thing. */ +- gp = ecoff_data (input_bfd)->gp + r_symndx; +- gp_undefined = false; +- break; +- } +- +- if (relocatep) +- { +- reloc_howto_type *howto; +- struct ecoff_link_hash_entry *h = NULL; +- asection *s = NULL; +- bfd_vma relocation; +- bfd_reloc_status_type r; +- +- /* Perform a relocation. */ +- +- howto = &sw_64_howto_table[r_type]; +- +- if (r_extern) +- { +- h = sym_hashes[r_symndx]; +- /* If h is NULL, that means that there is a reloc +- against an external symbol which we thought was just +- a debugging symbol. This should not happen. */ +- if (h == (struct ecoff_link_hash_entry *) NULL) +- abort (); +- } +- else +- { +- if (r_symndx >= NUM_RELOC_SECTIONS) +- s = NULL; +- else +- s = symndx_to_section[r_symndx]; +- +- if (s == (asection *) NULL) +- abort (); +- } +- +- if (bfd_link_relocatable (info)) +- { +- /* We are generating relocatable output, and must +- convert the existing reloc. */ +- if (r_extern) +- { +- if (h->root.type != bfd_link_hash_defined +- && h->root.type != bfd_link_hash_defweak && h->indx == -1) +- { +- /* This symbol is not being written out. */ +- (*info->callbacks->unattached_reloc) ( +- info, h->root.root.string, input_bfd, input_section, +- r_vaddr - input_section->vma); +- } +- +- relocation +- = sw_64_convert_external_reloc (output_bfd, info, input_bfd, +- ext_rel, h); +- } +- else +- { +- /* This is a relocation against a section. Adjust +- the value by the amount the section moved. */ +- relocation +- = (s->output_section->vma + s->output_offset - s->vma); +- } ++#include "libcoff.h" + +- /* If this is PC relative, the existing object file +- appears to already have the reloc worked out. We +- must subtract out the old value and add in the new +- one. */ +- if (howto->pc_relative) +- relocation +- -= (input_section->output_section->vma +- + input_section->output_offset - input_section->vma); ++/* The page size is a guess based on ELF. */ + +- /* Put in any addend. */ +- relocation += addend; ++#define COFF_PAGE_SIZE 0x2000 + +- /* Adjust the contents. */ +- r = _bfd_relocate_contents (howto, input_bfd, relocation, +- (contents + r_vaddr +- - input_section->vma)); +- } +- else +- { +- /* We are producing a final executable. */ +- if (r_extern) +- { +- /* This is a reloc against a symbol. */ +- if (h->root.type == bfd_link_hash_defined +- || h->root.type == bfd_link_hash_defweak) +- { +- asection *hsec; ++/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */ ++#define OCTETS_PER_BYTE(ABFD, SEC) 1 + +- hsec = h->root.u.def.section; +- relocation +- = (h->root.u.def.value + hsec->output_section->vma +- + hsec->output_offset); +- } +- else +- { +- (*info->callbacks->undefined_symbol) ( +- info, h->root.root.string, input_bfd, input_section, +- r_vaddr - input_section->vma, true); +- relocation = 0; +- } +- } +- else +- { +- /* This is a reloc against a section. */ +- relocation +- = (s->output_section->vma + s->output_offset - s->vma); ++#ifndef PCRELOFFSET ++#define PCRELOFFSET false ++#endif + +- /* Adjust a PC relative relocation by removing the +- reference to the original source section. */ +- if (howto->pc_relative) +- relocation += input_section->vma; +- } ++/* Currently we don't handle any relocations. */ ++static reloc_howto_type pe_sw_64_std_reloc_howto[] = ++ { + +- r = _bfd_final_link_relocate (howto, input_bfd, input_section, +- contents, +- r_vaddr - input_section->vma, +- relocation, addend); +- } ++ }; + +- if (r != bfd_reloc_ok) +- { +- switch (r) +- { +- default: +- case bfd_reloc_outofrange: +- abort (); +- case bfd_reloc_overflow: { +- const char *name; ++#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 2 + +- if (r_extern) +- name = sym_hashes[r_symndx]->root.root.string; +- else +- name = bfd_section_name (symndx_to_section[r_symndx]); +- (*info->callbacks->reloc_overflow) ( +- info, NULL, name, sw_64_howto_table[r_type].name, +- (bfd_vma) 0, input_bfd, input_section, +- r_vaddr - input_section->vma); +- } +- break; +- } +- } +- } ++#ifndef NUM_ELEM ++#define NUM_ELEM(a) ((sizeof (a)) / sizeof ((a)[0])) ++#endif + +- if (bfd_link_relocatable (info) && adjust_addrp) +- { +- /* Change the address of the relocation. */ +- H_PUT_64 (input_bfd, +- (input_section->output_section->vma +- + input_section->output_offset - input_section->vma +- + r_vaddr), +- ext_rel->r_vaddr); +- } ++#define NUM_RELOCS NUM_ELEM (pe_sw_64_std_reloc_howto) + +- if (gp_usedp && gp_undefined) +- { +- (*info->callbacks->reloc_dangerous) ( +- info, _ ("GP relative relocation used when GP not defined"), +- input_bfd, input_section, r_vaddr - input_section->vma); +- /* Only give the error once per link. */ +- gp = 4; +- _bfd_set_gp_value (output_bfd, gp); +- gp_undefined = false; +- } +- } ++#define RTYPE2HOWTO(cache_ptr, dst) \ ++ (cache_ptr)->howto = NULL + +- if (tos != 0) +- abort (); ++#ifndef bfd_pe_print_pdata ++#define bfd_pe_print_pdata NULL ++#endif + +- return true; +-} ++/* Handle include/coff/sw_64.h external_reloc. */ ++#define SWAP_IN_RELOC_OFFSET H_GET_32 ++#define SWAP_OUT_RELOC_OFFSET H_PUT_32 + +-/* Do final adjustments to the filehdr and the aouthdr. This routine +- sets the dynamic bits in the file header. */ ++/* Return TRUE if this relocation should ++ appear in the output .reloc section. */ + + static bool +-sw_64_adjust_headers (bfd *abfd, struct internal_filehdr *fhdr, +- struct internal_aouthdr *ahdr ATTRIBUTE_UNUSED) +-{ +- if ((abfd->flags & (DYNAMIC | EXEC_P)) == (DYNAMIC | EXEC_P)) +- fhdr->f_flags |= F_SW_64_CALL_SHARED; +- else if ((abfd->flags & DYNAMIC) != 0) +- fhdr->f_flags |= F_SW_64_SHARABLE; +- return true; +-} +- +-/* Archive handling. In OSF/1 (or Digital Unix) v3.2, Digital +- introduced archive packing, in which the elements in an archive are +- optionally compressed using a simple dictionary scheme. We know +- how to read such archives, but we don't write them. */ +- +-#define sw_64_ecoff_slurp_armap _bfd_ecoff_slurp_armap +-#define sw_64_ecoff_slurp_extended_name_table \ +- _bfd_ecoff_slurp_extended_name_table +-#define sw_64_ecoff_construct_extended_name_table \ +- _bfd_ecoff_construct_extended_name_table +-#define sw_64_ecoff_truncate_arname _bfd_ecoff_truncate_arname +-#define sw_64_ecoff_write_armap _bfd_ecoff_write_armap +-#define sw_64_ecoff_write_ar_hdr _bfd_generic_write_ar_hdr +-#define sw_64_ecoff_generic_stat_arch_elt _bfd_ecoff_generic_stat_arch_elt +-#define sw_64_ecoff_update_armap_timestamp _bfd_ecoff_update_armap_timestamp +- +-/* A compressed file uses this instead of ARFMAG. */ +- +-#define ARFZMAG "Z\012" +- +-/* Read an archive header. This is like the standard routine, but it +- also accepts ARFZMAG. */ +- +-static void * +-sw_64_ecoff_read_ar_hdr (bfd *abfd) +-{ +- struct areltdata *ret; +- struct ar_hdr *h; +- +- ret = (struct areltdata *) _bfd_generic_read_ar_hdr_mag (abfd, ARFZMAG); +- if (ret == NULL) +- return NULL; +- +- h = (struct ar_hdr *) ret->arch_header; +- if (strncmp (h->ar_fmag, ARFZMAG, 2) == 0) +- { +- bfd_byte ab[8]; +- +- /* This is a compressed file. We must set the size correctly. +- The size is the eight bytes after the dummy file header. */ +- if (bfd_seek (abfd, (file_ptr) FILHSZ, SEEK_CUR) != 0 +- || bfd_bread (ab, (bfd_size_type) 8, abfd) != 8 +- || bfd_seek (abfd, (file_ptr) (-(FILHSZ + 8)), SEEK_CUR) != 0) +- { +- free (ret); +- return NULL; +- } +- +- ret->parsed_size = H_GET_64 (abfd, ab); +- } +- +- return ret; +-} +- +-/* Get an archive element at a specified file position. This is where +- we uncompress the archive element if necessary. */ +- +-static bfd * +-sw_64_ecoff_get_elt_at_filepos (bfd *archive, file_ptr filepos, +- struct bfd_link_info *info) +-{ +- bfd *nbfd = NULL; +- struct areltdata *tdata; +- struct ar_hdr *hdr; +- bfd_byte ab[8]; +- bfd_size_type size; +- bfd_byte *buf, *p; +- struct bfd_in_memory *bim; +- ufile_ptr filesize; +- +- buf = NULL; +- nbfd = _bfd_get_elt_at_filepos (archive, filepos, info); +- if (nbfd == NULL) +- goto error_return; +- +- if ((nbfd->flags & BFD_IN_MEMORY) != 0) +- { +- /* We have already expanded this BFD. */ +- return nbfd; +- } +- +- tdata = (struct areltdata *) nbfd->arelt_data; +- hdr = (struct ar_hdr *) tdata->arch_header; +- if (strncmp (hdr->ar_fmag, ARFZMAG, 2) != 0) +- return nbfd; +- +- /* We must uncompress this element. We do this by copying it into a +- memory buffer, and making bfd_bread and bfd_seek use that buffer. +- This can use a lot of memory, but it's simpler than getting a +- temporary file, making that work with the file descriptor caching +- code, and making sure that it is deleted at all appropriate +- times. It can be changed if it ever becomes important. */ +- +- /* The compressed file starts with a dummy ECOFF file header. */ +- if (bfd_seek (nbfd, (file_ptr) FILHSZ, SEEK_SET) != 0) +- goto error_return; +- +- /* The next eight bytes are the real file size. */ +- if (bfd_bread (ab, (bfd_size_type) 8, nbfd) != 8) +- goto error_return; +- size = H_GET_64 (nbfd, ab); +- +- /* The decompression algorithm will at most expand by eight times. */ +- filesize = bfd_get_file_size (archive); +- if (filesize != 0 && size / 8 > filesize) +- { +- bfd_set_error (bfd_error_malformed_archive); +- goto error_return; +- } +- +- if (size != 0) +- { +- bfd_size_type left; +- bfd_byte dict[4096]; +- unsigned int h; +- bfd_byte b; +- +- buf = (bfd_byte *) bfd_malloc (size); +- if (buf == NULL) +- goto error_return; +- p = buf; +- +- left = size; +- +- /* I don't know what the next eight bytes are for. */ +- if (bfd_bread (ab, (bfd_size_type) 8, nbfd) != 8) +- goto error_return; +- +- /* This is the uncompression algorithm. It's a simple +- dictionary based scheme in which each character is predicted +- by a hash of the previous three characters. A control byte +- indicates whether the character is predicted or whether it +- appears in the input stream; each control byte manages the +- next eight bytes in the output stream. */ +- memset (dict, 0, sizeof dict); +- h = 0; +- while (bfd_bread (&b, (bfd_size_type) 1, nbfd) == 1) +- { +- unsigned int i; +- +- for (i = 0; i < 8; i++, b >>= 1) +- { +- bfd_byte n; +- +- if ((b & 1) == 0) +- n = dict[h]; +- else +- { +- if (bfd_bread (&n, 1, nbfd) != 1) +- goto error_return; +- dict[h] = n; +- } +- +- *p++ = n; +- +- --left; +- if (left == 0) +- break; +- +- h <<= 4; +- h ^= n; +- h &= sizeof dict - 1; +- } +- +- if (left == 0) +- break; +- } +- } +- +- /* Now the uncompressed file contents are in buf. */ +- bim = ((struct bfd_in_memory *) bfd_malloc ( +- (bfd_size_type) sizeof (struct bfd_in_memory))); +- if (bim == NULL) +- goto error_return; +- bim->size = size; +- bim->buffer = buf; +- +- nbfd->mtime_set = true; +- nbfd->mtime = strtol (hdr->ar_date, (char **) NULL, 10); +- +- nbfd->flags |= BFD_IN_MEMORY; +- nbfd->iostream = bim; +- nbfd->iovec = &_bfd_memory_iovec; +- nbfd->origin = 0; +- BFD_ASSERT (!nbfd->cacheable); +- +- return nbfd; +- +-error_return: +- free (buf); +- if (nbfd != NULL) +- bfd_close (nbfd); +- return NULL; +-} +- +-/* Open the next archived file. */ +- +-static bfd * +-sw_64_ecoff_openr_next_archived_file (bfd *archive, bfd *last_file) +-{ +- ufile_ptr filestart; +- +- if (last_file == NULL) +- filestart = bfd_ardata (archive)->first_file_filepos; +- else +- { +- struct areltdata *t; +- struct ar_hdr *h; +- bfd_size_type size; +- +- /* We can't use arelt_size here, because that uses parsed_size, +- which is the uncompressed size. We need the compressed size. */ +- t = (struct areltdata *) last_file->arelt_data; +- h = (struct ar_hdr *) t->arch_header; +- size = strtol (h->ar_size, (char **) NULL, 10); +- +- /* Pad to an even boundary... +- Note that last_file->origin can be odd in the case of +- BSD-4.4-style element with a long odd size. */ +- filestart = last_file->proxy_origin + size; +- filestart += filestart % 2; +- if (filestart < last_file->proxy_origin) +- { +- /* Prevent looping. See PR19256. */ +- bfd_set_error (bfd_error_malformed_archive); +- return NULL; +- } +- } +- +- return sw_64_ecoff_get_elt_at_filepos (archive, filestart, NULL); +-} +- +-/* Open the archive file given an index into the armap. */ +- +-static bfd * +-sw_64_ecoff_get_elt_at_index (bfd *abfd, symindex sym_index) +-{ +- carsym *entry; +- +- entry = bfd_ardata (abfd)->symdefs + sym_index; +- return sw_64_ecoff_get_elt_at_filepos (abfd, entry->file_offset, NULL); +-} +- +-static void +-sw_64_ecoff_swap_coff_aux_in (bfd *abfd ATTRIBUTE_UNUSED, +- void *ext1 ATTRIBUTE_UNUSED, +- int type ATTRIBUTE_UNUSED, +- int in_class ATTRIBUTE_UNUSED, +- int indx ATTRIBUTE_UNUSED, +- int numaux ATTRIBUTE_UNUSED, +- void *in1 ATTRIBUTE_UNUSED) +-{} +- +-static void +-sw_64_ecoff_swap_coff_sym_in (bfd *abfd ATTRIBUTE_UNUSED, +- void *ext1 ATTRIBUTE_UNUSED, +- void *in1 ATTRIBUTE_UNUSED) +-{} +- +-static void +-sw_64_ecoff_swap_coff_lineno_in (bfd *abfd ATTRIBUTE_UNUSED, +- void *ext1 ATTRIBUTE_UNUSED, +- void *in1 ATTRIBUTE_UNUSED) +-{} +- +-static unsigned int +-sw_64_ecoff_swap_coff_aux_out (bfd *abfd ATTRIBUTE_UNUSED, +- void *inp ATTRIBUTE_UNUSED, +- int type ATTRIBUTE_UNUSED, +- int in_class ATTRIBUTE_UNUSED, +- int indx ATTRIBUTE_UNUSED, +- int numaux ATTRIBUTE_UNUSED, +- void *extp ATTRIBUTE_UNUSED) +-{ +- return 0; +-} +- +-static unsigned int +-sw_64_ecoff_swap_coff_sym_out (bfd *abfd ATTRIBUTE_UNUSED, +- void *inp ATTRIBUTE_UNUSED, +- void *extp ATTRIBUTE_UNUSED) +-{ +- return 0; +-} +- +-static unsigned int +-sw_64_ecoff_swap_coff_lineno_out (bfd *abfd ATTRIBUTE_UNUSED, +- void *inp ATTRIBUTE_UNUSED, +- void *extp ATTRIBUTE_UNUSED) +-{ +- return 0; +-} +- +-static unsigned int +-sw_64_ecoff_swap_coff_reloc_out (bfd *abfd ATTRIBUTE_UNUSED, +- void *inp ATTRIBUTE_UNUSED, +- void *extp ATTRIBUTE_UNUSED) +-{ +- return 0; +-} +- +-/* This is the ECOFF backend structure. The backend field of the +- target vector points to this. */ +- +-static const struct ecoff_backend_data sw_64_ecoff_backend_data = { +- /* COFF backend structure. */ +- {sw_64_ecoff_swap_coff_aux_in, +- sw_64_ecoff_swap_coff_sym_in, +- sw_64_ecoff_swap_coff_lineno_in, +- sw_64_ecoff_swap_coff_aux_out, +- sw_64_ecoff_swap_coff_sym_out, +- sw_64_ecoff_swap_coff_lineno_out, +- sw_64_ecoff_swap_coff_reloc_out, +- sw_64_ecoff_swap_filehdr_out, +- sw_64_ecoff_swap_aouthdr_out, +- sw_64_ecoff_swap_scnhdr_out, +- FILHSZ, +- AOUTSZ, +- SCNHSZ, +- 0, +- 0, +- 0, +- 0, +- FILNMLEN, +- true, +- ECOFF_NO_LONG_SECTION_NAMES, +- 4, +- false, +- 2, +- 32768, +- sw_64_ecoff_swap_filehdr_in, +- sw_64_ecoff_swap_aouthdr_in, +- sw_64_ecoff_swap_scnhdr_in, +- NULL, +- sw_64_ecoff_bad_format_hook, +- _bfd_ecoff_set_arch_mach_hook, +- sw_64_ecoff_mkobject_hook, +- _bfd_ecoff_styp_to_sec_flags, +- _bfd_ecoff_set_alignment_hook, +- _bfd_ecoff_slurp_symbol_table, +- NULL, +- NULL, +- NULL, +- NULL, +- NULL, +- NULL, +- NULL, +- NULL, +- NULL, +- NULL, +- NULL, +- NULL, +- NULL, +- NULL, +- NULL}, +- /* Supported architecture. */ +- bfd_arch_sw_64, +- /* Initial portion of armap string. */ +- "________64", +- /* The page boundary used to align sections in a demand-paged +- executable file. E.g., 0x1000. */ +- 0x2000, +- /* true if the .rdata section is part of the text segment, as on the +- SW_64. false if .rdata is part of the data segment, as on the +- MIPS. */ +- true, +- /* Bitsize of constructor entries. */ +- 64, +- /* Reloc to use for constructor entries. */ +- &sw_64_howto_table[SW_64_R_REFQUAD], +- {/* Symbol table magic number. */ +- magicSym2, +- /* Alignment of debugging information. E.g., 4. */ +- 8, +- /* Sizes of external symbolic information. */ +- sizeof (struct hdr_ext), sizeof (struct dnr_ext), sizeof (struct pdr_ext), +- sizeof (struct sym_ext), sizeof (struct opt_ext), sizeof (struct fdr_ext), +- sizeof (struct rfd_ext), sizeof (struct ext_ext), +- /* Functions to swap in external symbolic data. */ +- ecoff_swap_hdr_in, ecoff_swap_dnr_in, ecoff_swap_pdr_in, ecoff_swap_sym_in, +- ecoff_swap_opt_in, ecoff_swap_fdr_in, ecoff_swap_rfd_in, ecoff_swap_ext_in, +- _bfd_ecoff_swap_tir_in, _bfd_ecoff_swap_rndx_in, +- /* Functions to swap out external symbolic data. */ +- ecoff_swap_hdr_out, ecoff_swap_dnr_out, ecoff_swap_pdr_out, +- ecoff_swap_sym_out, ecoff_swap_opt_out, ecoff_swap_fdr_out, +- ecoff_swap_rfd_out, ecoff_swap_ext_out, _bfd_ecoff_swap_tir_out, +- _bfd_ecoff_swap_rndx_out, +- /* Function to read in symbolic data. */ +- _bfd_ecoff_slurp_symbolic_info}, +- /* External reloc size. */ +- RELSZ, +- /* Reloc swapping functions. */ +- sw_64_ecoff_swap_reloc_in, +- sw_64_ecoff_swap_reloc_out, +- /* Backend reloc tweaking. */ +- sw_64_adjust_reloc_in, +- sw_64_adjust_reloc_out, +- /* Relocate section contents while linking. */ +- sw_64_relocate_section, +- /* Do final adjustments to filehdr and aouthdr. */ +- sw_64_adjust_headers, +- /* Read an element from an archive at a given file position. */ +- sw_64_ecoff_get_elt_at_filepos}; +- +-/* Looking up a reloc type is SW_64 specific. */ +-#define _bfd_ecoff_bfd_reloc_type_lookup sw_64_bfd_reloc_type_lookup +-#define _bfd_ecoff_bfd_reloc_name_lookup sw_64_bfd_reloc_name_lookup +- +-/* So is getting relocated section contents. */ +-#define _bfd_ecoff_bfd_get_relocated_section_contents \ +- sw_64_ecoff_get_relocated_section_contents +- +-/* Handling file windows is generic. */ +-#define _bfd_ecoff_get_section_contents_in_window \ +- _bfd_generic_get_section_contents_in_window +- +-/* Input section flag lookup is generic. */ +-#define _bfd_ecoff_bfd_lookup_section_flags bfd_generic_lookup_section_flags +- +-/* Relaxing sections is generic. */ +-#define _bfd_ecoff_bfd_relax_section bfd_generic_relax_section +-#define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_sections +-#define _bfd_ecoff_bfd_merge_sections bfd_generic_merge_sections +-#define _bfd_ecoff_bfd_is_group_section bfd_generic_is_group_section +-#define _bfd_ecoff_bfd_group_name bfd_generic_group_name +-#define _bfd_ecoff_bfd_discard_group bfd_generic_discard_group +-#define _bfd_ecoff_section_already_linked _bfd_coff_section_already_linked +-#define _bfd_ecoff_bfd_define_common_symbol bfd_generic_define_common_symbol +-#define _bfd_ecoff_bfd_link_hide_symbol _bfd_generic_link_hide_symbol +-#define _bfd_ecoff_bfd_define_start_stop bfd_generic_define_start_stop +-#define _bfd_ecoff_bfd_link_check_relocs _bfd_generic_link_check_relocs +- +-/* Installing internal relocations in a section is also generic. */ +-#define _bfd_ecoff_set_reloc _bfd_generic_set_reloc +- +-const bfd_target sw_64_ecoff_le_vec +- = {"ecoff-littlesw_64", /* name */ +- bfd_target_ecoff_flavour, +- BFD_ENDIAN_LITTLE, /* data byte order is little */ +- BFD_ENDIAN_LITTLE, /* header byte order is little */ +- +- (HAS_RELOC | EXEC_P /* object flags */ +- | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT +- | D_PAGED), +- +- (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA +- | SEC_SMALL_DATA), +- 0, /* leading underscore */ +- ' ', /* ar_pad_char */ +- 15, /* ar_max_namelen */ +- 0, /* match priority. */ +- TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols. */ +- bfd_getl64, +- bfd_getl_signed_64, +- bfd_putl64, +- bfd_getl32, +- bfd_getl_signed_32, +- bfd_putl32, +- bfd_getl16, +- bfd_getl_signed_16, +- bfd_putl16, /* data */ +- bfd_getl64, +- bfd_getl_signed_64, +- bfd_putl64, +- bfd_getl32, +- bfd_getl_signed_32, +- bfd_putl32, +- bfd_getl16, +- bfd_getl_signed_16, +- bfd_putl16, /* hdrs */ +- +- {/* bfd_check_format */ +- _bfd_dummy_target, sw_64_ecoff_object_p, bfd_generic_archive_p, +- _bfd_dummy_target}, +- {/* bfd_set_format */ +- _bfd_bool_bfd_false_error, _bfd_ecoff_mkobject, _bfd_generic_mkarchive, +- _bfd_bool_bfd_false_error}, +- {/* bfd_write_contents */ +- _bfd_bool_bfd_false_error, _bfd_ecoff_write_object_contents, +- _bfd_write_archive_contents, _bfd_bool_bfd_false_error}, +- +- BFD_JUMP_TABLE_GENERIC (_bfd_ecoff), +- BFD_JUMP_TABLE_COPY (_bfd_ecoff), +- BFD_JUMP_TABLE_CORE (_bfd_nocore), +- BFD_JUMP_TABLE_ARCHIVE (sw_64_ecoff), +- BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff), +- BFD_JUMP_TABLE_RELOCS (_bfd_ecoff), +- BFD_JUMP_TABLE_WRITE (_bfd_ecoff), +- BFD_JUMP_TABLE_LINK (_bfd_ecoff), +- BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), +- +- NULL, ++in_reloc_p (bfd * abfd ATTRIBUTE_UNUSED, ++ reloc_howto_type * howto) ++{ ++ return !howto->pc_relative; ++} ++ ++#include "coffcode.h" ++ ++/* Target vectors. */ ++const bfd_target ++#ifdef TARGET_SYM ++ TARGET_SYM = ++#else ++ sw_64_pei_vec = ++#endif ++{ ++#ifdef TARGET_NAME ++ TARGET_NAME, ++#else ++ "pei-sw_64", /* Name. */ ++#endif ++ bfd_target_coff_flavour, ++ BFD_ENDIAN_LITTLE, /* Data byte order is little. */ ++ BFD_ENDIAN_LITTLE, /* Header byte order is little. */ ++ ++ (HAS_RELOC | EXEC_P /* Object flags. */ ++ | HAS_LINENO | HAS_DEBUG ++ | HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS), ++ ++ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section flags. */ ++#if defined(COFF_WITH_PE) ++ | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY | SEC_DEBUGGING ++#endif ++ | SEC_CODE | SEC_DATA | SEC_EXCLUDE ), ++ ++#ifdef TARGET_UNDERSCORE ++ TARGET_UNDERSCORE, /* Leading underscore. */ ++#else ++ 0, /* Leading underscore. */ ++#endif ++ '/', /* Ar_pad_char. */ ++ 15, /* Ar_max_namelen. */ ++ 0, /* match priority. */ ++ TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols. */ ++ ++ /* Data conversion functions. */ ++ bfd_getl64, bfd_getl_signed_64, bfd_putl64, ++ bfd_getl32, bfd_getl_signed_32, bfd_putl32, ++ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data. */ ++ /* Header conversion functions. */ ++ bfd_getl64, bfd_getl_signed_64, bfd_putl64, ++ bfd_getl32, bfd_getl_signed_32, bfd_putl32, ++ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Hdrs. */ ++ ++ /* Note that we allow an object file to be treated as a core file as well. */ ++ { /* bfd_check_format. */ ++ _bfd_dummy_target, ++ coff_object_p, ++ bfd_generic_archive_p, ++ coff_object_p ++ }, ++ { /* bfd_set_format. */ ++ _bfd_bool_bfd_false_error, ++ coff_mkobject, ++ _bfd_generic_mkarchive, ++ _bfd_bool_bfd_false_error ++ }, ++ { /* bfd_write_contents. */ ++ _bfd_bool_bfd_false_error, ++ coff_write_object_contents, ++ _bfd_write_archive_contents, ++ _bfd_bool_bfd_false_error ++ }, ++ ++ BFD_JUMP_TABLE_GENERIC (coff), ++ BFD_JUMP_TABLE_COPY (coff), ++ BFD_JUMP_TABLE_CORE (_bfd_nocore), ++ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), ++ BFD_JUMP_TABLE_SYMBOLS (coff), ++ BFD_JUMP_TABLE_RELOCS (coff), ++ BFD_JUMP_TABLE_WRITE (coff), ++ BFD_JUMP_TABLE_LINK (coff), ++ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), ++ ++ NULL, ++ ++ COFF_SWAP_TABLE ++}; + +- &sw_64_ecoff_backend_data}; ++const bfd_target sw_64_ecoff_le_vec = ++{ ++ "ecoff-littlesw_64", /* name */ ++ bfd_target_ecoff_flavour, ++ BFD_ENDIAN_LITTLE, /* data byte order is little */ ++ BFD_ENDIAN_LITTLE, /* header byte order is little */ ++ ++ (HAS_RELOC | EXEC_P /* object flags */ ++ | HAS_LINENO | HAS_DEBUG ++ | HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED), ++ ++ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE ++ | SEC_DATA | SEC_SMALL_DATA), ++ 0, /* leading underscore */ ++ ' ', /* ar_pad_char */ ++ 15, /* ar_max_namelen */ ++ 0, /* match priority. */ ++ TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols. */ ++ bfd_getl64, bfd_getl_signed_64, bfd_putl64, ++ bfd_getl32, bfd_getl_signed_32, bfd_putl32, ++ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ ++ bfd_getl64, bfd_getl_signed_64, bfd_putl64, ++ bfd_getl32, bfd_getl_signed_32, bfd_putl32, ++ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ ++ ++/* Note that we allow an object file to be treated as a core file as well. */ ++ { /* bfd_check_format. */ ++ _bfd_dummy_target, ++ coff_object_p, ++ bfd_generic_archive_p, ++ coff_object_p ++ }, ++ { /* bfd_set_format. */ ++ _bfd_bool_bfd_false_error, ++ coff_mkobject, ++ _bfd_generic_mkarchive, ++ _bfd_bool_bfd_false_error ++ }, ++ { /* bfd_write_contents. */ ++ _bfd_bool_bfd_false_error, ++ coff_write_object_contents, ++ _bfd_write_archive_contents, ++ _bfd_bool_bfd_false_error ++ }, ++ ++ BFD_JUMP_TABLE_GENERIC (coff), ++ BFD_JUMP_TABLE_COPY (coff), ++ BFD_JUMP_TABLE_CORE (_bfd_nocore), ++ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), ++ BFD_JUMP_TABLE_SYMBOLS (coff), ++ BFD_JUMP_TABLE_RELOCS (coff), ++ BFD_JUMP_TABLE_WRITE (coff), ++ BFD_JUMP_TABLE_LINK (coff), ++ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), ++ ++ NULL, ++ ++ //&sw_64_ecoff_backend_data ++ COFF_SWAP_TABLE ++}; +diff --git a/bfd/coffcode.h b/bfd/coffcode.h +index 62720255..6bc33ad6 100644 +--- a/bfd/coffcode.h ++++ b/bfd/coffcode.h +@@ -2182,6 +2182,12 @@ coff_set_arch_mach_hook (bfd *abfd, void * filehdr) + machine = internal_f->f_flags & F_LOONGARCH64_ARCHITECTURE_MASK; + break; + #endif ++#ifdef SW_64MAGIC ++ case SW_64MAGIC: ++ arch = bfd_arch_sw_64; ++ machine = internal_f->f_flags & F_SW_64_ARCHITECTURE_MASK; ++ break; ++#endif + #ifdef Z80MAGIC + case Z80MAGIC: + arch = bfd_arch_z80; +@@ -2752,7 +2758,11 @@ coff_set_flags (bfd * abfd, + * magicp = LOONGARCH64MAGIC; + return true; + #endif +- ++#ifdef SW_64MAGIC ++ case bfd_arch_sw_64: ++ * magicp = SW_64MAGIC; ++ return true; ++#endif + #ifdef ARMMAGIC + case bfd_arch_arm: + #ifdef ARM_WINCE +@@ -3936,7 +3946,7 @@ coff_write_object_contents (bfd * abfd) + internal_f.f_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE; + #endif + +-#if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) ++#if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) &&!defined(COFF_WITH_peSW_64) + #ifdef COFF_WITH_PE + internal_f.f_flags |= IMAGE_FILE_32BIT_MACHINE; + #else +@@ -3995,6 +4005,11 @@ coff_write_object_contents (bfd * abfd) + internal_a.magic = ZMAGIC; + #endif + ++#if defined(SW_64) ++#define __A_MAGIC_SET__ ++ internal_a.magic = ZMAGIC; ++#endif ++ + #if defined MCORE_PE + #define __A_MAGIC_SET__ + internal_a.magic = IMAGE_NT_OPTIONAL_HDR_MAGIC; +diff --git a/bfd/config.bfd b/bfd/config.bfd +index 85434116..37e1f3e6 100644 +--- a/bfd/config.bfd ++++ b/bfd/config.bfd +@@ -338,43 +338,9 @@ case "${targ}" in + targ_cflags=-DOLD_FREEBSD_ABI_LABEL ;; + esac + ;; +- sw_64*-*-netbsd* | sw_64*-*-openbsd*) +- targ_defvec=sw_64_elf64_vec +- targ_selvecs=sw_64_ecoff_le_vec +- want64=true +- ;; +- sw_64*-*-netware*) +- targ_defvec=sw_64_ecoff_le_vec +- targ_selvecs=sw_64_nlm32_vec +- want64=true +- ;; +- sw_64*-*-linux*ecoff*) +- targ_defvec=sw_64_ecoff_le_vec +- targ_selvecs=sw_64_elf64_vec +- want64=true +- ;; + sw_64-*-linux-* | sw_64-*-elf*) + targ_defvec=sw_64_elf64_vec +- targ_selvecs=sw_64_ecoff_le_vec +- want64=true +- ;; +- sw_64sw6a-*-linux-* | sw_64sw6a-*-elf*) +- targ_defvec=sw_64_elf64_vec +- targ_selvecs=sw_64_ecoff_le_vec +- want64=true +- ;; +- sw_64sw6b-*-linux-* | sw_64sw6b-*-elf*) +- targ_defvec=sw_64_elf64_vec +- targ_selvecs=sw_64_ecoff_le_vec +- want64=true +- ;; +- sw_64sw8a-*-linux-* | sw_64sw8a-*-elf*) +- targ_defvec=sw_64_elf64_vec +- targ_selvecs=sw_64_ecoff_le_vec +- want64=true +- ;; +- sw_64*-*-*) +- targ_defvec=sw_64_ecoff_le_vec ++ targ_selvecs="sw_64_elf64_vec sw_64_ecoff_le_vec sw_64_pei_vec" + want64=true + ;; + amdgcn-*-*) +diff --git a/bfd/configure b/bfd/configure +index 493bac83..3124da20 100755 +--- a/bfd/configure ++++ b/bfd/configure +@@ -13852,10 +13852,11 @@ do + alpha_elf64_fbsd_vec) tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;; + alpha_vms_vec) tb="$tb vms-alpha.lo vms-misc.lo vms-lib.lo"; target_size=64 ;; + alpha_vms_lib_txt_vec) tb="$tb vms-lib.lo vms-misc.lo" ;; +- sw_64_ecoff_le_vec) tb="$tb coff-sw_64.lo ecoff.lo $ecoff"; target_size=64 ;; ++ sw_64_ecoff_le_vec) tb="$tb ecoff.lo $ecoff"; target_size=64 ;; + sw_64_elf64_vec) tb="$tb elf64-sw_64.lo elf64.lo $elf"; target_size=64 ;; + sw_64_elf64_fbsd_vec) tb="$tb elf64-sw_64.lo elf64.lo $elf"; target_size=64 ;; + sw_64_nlm32_vec) tb="$tb nlm32-sw_64.lo nlm32.lo nlm.lo"; target_size=64 ;; ++ sw_64_pei_vec) tb="$tb pei-sw_64.lo pe-sw_64igen.lo $coff"; target_size=64 ;; + am33_elf32_linux_vec) tb="$tb elf32-am33lin.lo elf32.lo $elf" ;; + amdgcn_elf64_le_vec) tb="$tb elf64-amdgcn.lo elf64.lo $elf"; target_size=64 ;; + aout0_be_vec) tb="$tb aout0.lo aout32.lo" ;; +diff --git a/bfd/configure.ac b/bfd/configure.ac +index 160b1351..77793e31 100644 +--- a/bfd/configure.ac ++++ b/bfd/configure.ac +@@ -414,10 +414,11 @@ do + alpha_elf64_fbsd_vec) tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;; + alpha_vms_vec) tb="$tb vms-alpha.lo vms-misc.lo vms-lib.lo"; target_size=64 ;; + alpha_vms_lib_txt_vec) tb="$tb vms-lib.lo vms-misc.lo" ;; +- sw_64_ecoff_le_vec) tb="$tb coff-sw_64.lo ecoff.lo $ecoff"; target_size=64 ;; ++ sw_64_ecoff_le_vec) tb="$tb ecoff.lo $ecoff"; target_size=64 ;; + sw_64_elf64_vec) tb="$tb elf64-sw_64.lo elf64.lo $elf"; target_size=64 ;; + sw_64_elf64_fbsd_vec) tb="$tb elf64-sw_64.lo elf64.lo $elf"; target_size=64 ;; + sw_64_nlm32_vec) tb="$tb nlm32-sw_64.lo nlm32.lo nlm.lo"; target_size=64 ;; ++ sw_64_pei_vec) tb="$tb pei-sw_64.lo pe-sw_64igen.lo $coff"; target_size=64 ;; + am33_elf32_linux_vec) tb="$tb elf32-am33lin.lo elf32.lo $elf" ;; + amdgcn_elf64_le_vec) tb="$tb elf64-amdgcn.lo elf64.lo $elf"; target_size=64 ;; + aout0_be_vec) tb="$tb aout0.lo aout32.lo" ;; +diff --git a/bfd/libpei.h b/bfd/libpei.h +index eafb9cf9..592f1b3d 100644 +--- a/bfd/libpei.h ++++ b/bfd/libpei.h +@@ -240,6 +240,41 @@ + #define _bfd_XXi_write_codeview_record _bfd_pex64i_write_codeview_record + #define _bfd_XXi_slurp_codeview_record _bfd_pex64i_slurp_codeview_record + ++#elif defined COFF_WITH_peSW_64 ++ ++#define GET_OPTHDR_IMAGE_BASE H_GET_64 ++#define PUT_OPTHDR_IMAGE_BASE H_PUT_64 ++#define GET_OPTHDR_SIZE_OF_STACK_RESERVE H_GET_64 ++#define PUT_OPTHDR_SIZE_OF_STACK_RESERVE H_PUT_64 ++#define GET_OPTHDR_SIZE_OF_STACK_COMMIT H_GET_64 ++#define PUT_OPTHDR_SIZE_OF_STACK_COMMIT H_PUT_64 ++#define GET_OPTHDR_SIZE_OF_HEAP_RESERVE H_GET_64 ++#define PUT_OPTHDR_SIZE_OF_HEAP_RESERVE H_PUT_64 ++#define GET_OPTHDR_SIZE_OF_HEAP_COMMIT H_GET_64 ++#define PUT_OPTHDR_SIZE_OF_HEAP_COMMIT H_PUT_64 ++#define GET_PDATA_ENTRY bfd_get_32 ++ ++#define _bfd_XX_bfd_copy_private_bfd_data_common _bfd_peSW_64_bfd_copy_private_bfd_data_common ++#define _bfd_XX_bfd_copy_private_section_data _bfd_peSW_64_bfd_copy_private_section_data ++#define _bfd_XX_get_symbol_info _bfd_peSW_64_get_symbol_info ++#define _bfd_XX_only_swap_filehdr_out _bfd_peSW_64_only_swap_filehdr_out ++#define _bfd_XX_print_private_bfd_data_common _bfd_peSW_64_print_private_bfd_data_common ++#define _bfd_XXi_final_link_postscript _bfd_peSW_64i_final_link_postscript ++#define _bfd_XXi_only_swap_filehdr_out _bfd_peSW_64i_only_swap_filehdr_out ++#define _bfd_XXi_swap_aouthdr_in _bfd_peSW_64i_swap_aouthdr_in ++#define _bfd_XXi_swap_aouthdr_out _bfd_peSW_64i_swap_aouthdr_out ++#define _bfd_XXi_swap_aux_in _bfd_peSW_64i_swap_aux_in ++#define _bfd_XXi_swap_aux_out _bfd_peSW_64i_swap_aux_out ++#define _bfd_XXi_swap_lineno_in _bfd_peSW_64i_swap_lineno_in ++#define _bfd_XXi_swap_lineno_out _bfd_peSW_64i_swap_lineno_out ++#define _bfd_XXi_swap_scnhdr_out _bfd_peSW_64i_swap_scnhdr_out ++#define _bfd_XXi_swap_sym_in _bfd_peSW_64i_swap_sym_in ++#define _bfd_XXi_swap_sym_out _bfd_peSW_64i_swap_sym_out ++#define _bfd_XXi_swap_debugdir_in _bfd_peSW_64i_swap_debugdir_in ++#define _bfd_XXi_swap_debugdir_out _bfd_peSW_64i_swap_debugdir_out ++#define _bfd_XXi_write_codeview_record _bfd_peSW_64i_write_codeview_record ++#define _bfd_XXi_slurp_codeview_record _bfd_peSW_64i_slurp_codeview_record ++ + #elif defined COFF_WITH_pep + + #define GET_OPTHDR_IMAGE_BASE H_GET_64 +@@ -443,5 +478,6 @@ bool _bfd_pe64_print_ce_compressed_pdata (bfd *, void *); + bool _bfd_pex64_print_ce_compressed_pdata (bfd *, void *); + bool _bfd_peAArch64_print_ce_compressed_pdata (bfd *, void *); + bool _bfd_peLoongArch64_print_ce_compressed_pdata (bfd *, void *); ++bool _bfd_peSW_64_print_ce_compressed_pdata (bfd *, void *); + bool _bfd_pep_print_ce_compressed_pdata (bfd *, void *); + +diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c +index da53f349..91aa1078 100644 +--- a/bfd/peXXigen.c ++++ b/bfd/peXXigen.c +@@ -88,6 +88,9 @@ + # include "coff/aarch64.h" + #elif defined COFF_WITH_peLoongArch64 + # include "coff/loongarch64.h" ++#elif defined COFF_WITH_peSW_64 ++# include "coff/sw_64.h" ++# include "coff/external.h" + #else + # include "coff/i386.h" + #endif +@@ -97,7 +100,7 @@ + #include "libpei.h" + #include "safe-ctype.h" + +-#if defined COFF_WITH_pep || defined COFF_WITH_pex64 || defined COFF_WITH_peAArch64 || defined COFF_WITH_peLoongArch64 ++#if defined COFF_WITH_pep || defined COFF_WITH_pex64 || defined COFF_WITH_peAArch64 || defined COFF_WITH_peLoongArch64 || defined COFF_WITH_peSW_64 + # undef AOUTSZ + # define AOUTSZ PEPAOUTSZ + # define PEAOUTHDR PEPAOUTHDR +@@ -464,7 +467,7 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd, + aouthdr_int->text_start = + GET_AOUTHDR_TEXT_START (abfd, aouthdr_ext->text_start); + +-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) ++#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined(COFF_WITH_peSW_64) + /* PE32+ does not have data_start member! */ + aouthdr_int->data_start = + GET_AOUTHDR_DATA_START (abfd, aouthdr_ext->data_start); +@@ -531,7 +534,7 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd, + if (aouthdr_int->entry) + { + aouthdr_int->entry += a->ImageBase; +-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) ++#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined(COFF_WITH_peSW_64) + aouthdr_int->entry &= 0xffffffff; + #endif + } +@@ -539,12 +542,12 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd, + if (aouthdr_int->tsize) + { + aouthdr_int->text_start += a->ImageBase; +-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) ++#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined(COFF_WITH_peSW_64) + aouthdr_int->text_start &= 0xffffffff; + #endif + } + +-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) ++#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined(COFF_WITH_peSW_64) + /* PE32+ does not have data_start member! */ + if (aouthdr_int->dsize) + { +@@ -604,7 +607,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out) + if (aouthdr_in->tsize) + { + aouthdr_in->text_start -= ib; +-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) ++#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined(COFF_WITH_peSW_64) + aouthdr_in->text_start &= 0xffffffff; + #endif + } +@@ -612,7 +615,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out) + if (aouthdr_in->dsize) + { + aouthdr_in->data_start -= ib; +-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) ++#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined(COFF_WITH_peSW_64) + aouthdr_in->data_start &= 0xffffffff; + #endif + } +@@ -620,7 +623,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out) + if (aouthdr_in->entry) + { + aouthdr_in->entry -= ib; +-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) ++#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined(COFF_WITH_peSW_64) + aouthdr_in->entry &= 0xffffffff; + #endif + } +@@ -734,7 +737,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out) + PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start, + aouthdr_out->standard.text_start); + +-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) ++#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined(COFF_WITH_peSW_64) + /* PE32+ does not have data_start member! */ + PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start, + aouthdr_out->standard.data_start); +@@ -920,7 +923,7 @@ _bfd_XXi_swap_scnhdr_out (bfd * abfd, void * in, void * out) + _bfd_error_handler (_("%pB:%.8s: section below image base"), + abfd, scnhdr_int->s_name); + /* Do not compare lower 32-bits for 64-bit vma. */ +-#if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) ++#if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined(COFF_WITH_peSW_64) + else if(ss != (ss & 0xffffffff)) + _bfd_error_handler (_("%pB:%.8s: RVA truncated"), abfd, scnhdr_int->s_name); + PUT_SCNHDR_VADDR (abfd, ss & 0xffffffff, scnhdr_ext->s_vaddr); +@@ -1821,7 +1824,7 @@ pe_print_edata (bfd * abfd, void * vfile) + static bool + pe_print_pdata (bfd * abfd, void * vfile) + { +-#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) ++#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined(COFF_WITH_peSW_64) + # define PDATA_ROW_SIZE (3 * 8) + #else + # define PDATA_ROW_SIZE (5 * 4) +@@ -1849,7 +1852,7 @@ pe_print_pdata (bfd * abfd, void * vfile) + + fprintf (file, + _("\nThe Function Table (interpreted .pdata section contents)\n")); +-#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) ++#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined(COFF_WITH_peSW_64) + fprintf (file, + _(" vma:\t\t\tBegin Address End Address Unwind Info\n")); + #else +@@ -1886,7 +1889,7 @@ pe_print_pdata (bfd * abfd, void * vfile) + bfd_vma eh_handler; + bfd_vma eh_data; + bfd_vma prolog_end_addr; +-#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64) ++#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64) || defined COFF_WITH_peSW_64 + int em_data; + #endif + +@@ -1904,7 +1907,7 @@ pe_print_pdata (bfd * abfd, void * vfile) + /* We are probably into the padding of the section now. */ + break; + +-#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64) ++#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64) || defined COFF_WITH_peSW_64 + em_data = ((eh_handler & 0x1) << 2) | (prolog_end_addr & 0x3); + #endif + eh_handler &= ~(bfd_vma) 0x3; +@@ -1915,7 +1918,7 @@ pe_print_pdata (bfd * abfd, void * vfile) + bfd_fprintf_vma (abfd, file, begin_addr); fputc (' ', file); + bfd_fprintf_vma (abfd, file, end_addr); fputc (' ', file); + bfd_fprintf_vma (abfd, file, eh_handler); +-#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64) ++#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64) || defined COFF_WITH_peSW_64 + fputc (' ', file); + bfd_fprintf_vma (abfd, file, eh_data); fputc (' ', file); + bfd_fprintf_vma (abfd, file, prolog_end_addr); +@@ -2814,7 +2817,7 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile) + bfd_fprintf_vma (abfd, file, i->AddressOfEntryPoint); + fprintf (file, "\nBaseOfCode\t\t"); + bfd_fprintf_vma (abfd, file, i->BaseOfCode); +-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) ++#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined(COFF_WITH_peSW_64) + /* PE32+ does not have BaseOfData member! */ + fprintf (file, "\nBaseOfData\t\t"); + bfd_fprintf_vma (abfd, file, i->BaseOfData); +@@ -3130,7 +3133,7 @@ _bfd_XX_get_symbol_info (bfd * abfd, asymbol *symbol, symbol_info *ret) + coff_get_symbol_info (abfd, symbol, ret); + } + +-#if !defined(COFF_WITH_pep) && (defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64)) ++#if !defined(COFF_WITH_pep) && (defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64)) || defined COFF_WITH_peSW_64 + static int + sort_x64_pdata (const void *l, const void *r) + { +@@ -4546,7 +4549,7 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo) + the TLS data directory consists of 4 pointers, followed + by two 4-byte integer. This implies that the total size + is different for 32-bit and 64-bit executables. */ +-#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) ++#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined(COFF_WITH_peSW_64) + pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size = 0x18; + #else + pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size = 0x28; +@@ -4555,7 +4558,7 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo) + + /* If there is a .pdata section and we have linked pdata finally, we + need to sort the entries ascending. */ +-#if !defined(COFF_WITH_pep) && (defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64)) ++#if !defined(COFF_WITH_pep) && (defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64)) || defined COFF_WITH_peSW_64 + { + asection *sec = bfd_get_section_by_name (abfd, ".pdata"); + +diff --git a/bfd/pei-sw_64.c b/bfd/pei-sw_64.c +new file mode 100644 +index 00000000..ce9a9d26 +--- /dev/null ++++ b/bfd/pei-sw_64.c +@@ -0,0 +1,74 @@ ++/* BFD back-end for SW_64 PECOFF files. ++ Copyright (C) 1995-2021 Free Software Foundation, Inc. ++ ++ This file is part of BFD, the Binary File Descriptor library. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++#include "sysdep.h" ++#include "bfd.h" ++ ++#define TARGET_SYM sw_64_pei_vec ++#define TARGET_NAME "pei-sw_64" ++#define TARGET_ARCHITECTURE bfd_arch_sw_64 ++#define TARGET_PAGESIZE 4096 ++#define TARGET_BIG_ENDIAN 0 ++#define TARGET_ARCHIVE 0 ++#define TARGET_PRIORITY 0 ++ ++#define COFF_IMAGE_WITH_PE ++/* Rename the above into... */ ++#define COFF_WITH_peSW_64 ++#define COFF_WITH_PE ++#define PCRELOFFSET false ++#define COFF_LONG_SECTION_NAMES ++ ++#define COFF_SECTION_ALIGNMENT_ENTRIES \ ++{ COFF_SECTION_NAME_EXACT_MATCH (".bss"), \ ++ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ ++{ COFF_SECTION_NAME_EXACT_MATCH (".data"), \ ++ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ ++{ COFF_SECTION_NAME_EXACT_MATCH (".rdata"), \ ++ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ ++{ COFF_SECTION_NAME_EXACT_MATCH (".text"), \ ++ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ ++{ COFF_SECTION_NAME_PARTIAL_MATCH (".idata"), \ ++ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ ++{ COFF_SECTION_NAME_EXACT_MATCH (".pdata"), \ ++ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ ++{ COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \ ++ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \ ++{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi."), \ ++ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 } ++ ++#define PEI_HEADERS ++#include "sysdep.h" ++#include "bfd.h" ++#include "libbfd.h" ++#include "coff/sw_64.h" ++#include "coff/internal.h" ++#include "coff/external.h" ++#include "coff/pe.h" ++#include "libcoff.h" ++#include "libpei.h" ++#include "libiberty.h" ++ ++/* Make sure we're setting a 64-bit format. */ ++#undef AOUTSZ ++#define AOUTSZ PEPAOUTSZ ++#define PEAOUTHDR PEPAOUTHDR ++ ++#include "coff-sw_64.c" +diff --git a/bfd/peicode.h b/bfd/peicode.h +index 7f5f196d..85ef2754 100644 +--- a/bfd/peicode.h ++++ b/bfd/peicode.h +@@ -233,7 +233,7 @@ coff_swap_scnhdr_in (bfd * abfd, void * ext, void * in) + { + scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase; + /* Do not cut upper 32-bits for 64-bit vma. */ +-#if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) ++#if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined(COFF_WITH_peSW_64) + scnhdr_int->s_vaddr &= 0xffffffff; + #endif + } +@@ -777,6 +777,16 @@ static const jump_table jtab[] = + 4, 0 + }, + ++#endif ++ ++#ifdef SW_64MAGIC ++/* We don't currently support jumping to DLLs, so if ++ someone does try emit a runtime trap. Through BREAK 0. */ ++ { SW_64MAGIC, ++ { 0x00, 0x00, 0x2a, 0x00 }, ++ 4, 0 ++ }, ++ + #endif + + { 0, { 0 }, 0, 0 } +@@ -936,7 +946,7 @@ pe_ILF_build_a_bfd (bfd * abfd, + /* See PR 20907 for a reproducer. */ + goto error_return; + +-#if defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64) ++#if defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64) || defined(COFF_WITH_peSW_64) + ((unsigned int *) id4->contents)[0] = ordinal; + ((unsigned int *) id4->contents)[1] = 0x80000000; + ((unsigned int *) id5->contents)[0] = ordinal; +@@ -1203,10 +1213,6 @@ pe_ILF_object_p (bfd * abfd) + case IMAGE_FILE_MACHINE_UNKNOWN: + case IMAGE_FILE_MACHINE_ALPHA: + case IMAGE_FILE_MACHINE_ALPHA64: +-#ifdef TARGET_SW_64 +- case IMAGE_FILE_MACHINE_SW_64: +- case IMAGE_FILE_MACHINE_SW_6464: +-#endif + case IMAGE_FILE_MACHINE_IA64: + break; + +@@ -1258,6 +1264,13 @@ pe_ILF_object_p (bfd * abfd) + magic = LOONGARCH64MAGIC; + #endif + break; ++#ifdef TARGET_SW_64 ++ case IMAGE_FILE_MACHINE_SW_64: ++#ifdef SW_64MAGIC ++ magic = SW_64MAGIC; ++#endif ++ break; ++#endif + + case IMAGE_FILE_MACHINE_THUMB: + #ifdef THUMBPEMAGIC +diff --git a/bfd/targets.c b/bfd/targets.c +index 02ca240d..0b6acf50 100644 +--- a/bfd/targets.c ++++ b/bfd/targets.c +@@ -697,6 +697,7 @@ extern const bfd_target sw_64_elf64_fbsd_vec; + extern const bfd_target sw_64_nlm32_vec; + extern const bfd_target sw_64_vms_vec; + extern const bfd_target sw_64_vms_lib_txt_vec; ++extern const bfd_target sw_64_pei_vec; + #endif + extern const bfd_target am33_elf32_linux_vec; + extern const bfd_target amdgcn_elf64_le_vec; +@@ -1025,6 +1026,7 @@ static const bfd_target * const _bfd_target_vector[] = + &sw_64_elf64_fbsd_vec, + &sw_64_nlm32_vec, + &sw_64_vms_vec, ++ &sw_64_pei_vec, + #endif + &sw_64_vms_lib_txt_vec, + +diff --git a/binutils/od-pe.c b/binutils/od-pe.c +index be9d4eb2..dbb47719 100644 +--- a/binutils/od-pe.c ++++ b/binutils/od-pe.c +@@ -179,6 +179,9 @@ const struct target_specific_info targ_info[] = + { IMAGE_FILE_MACHINE_SH3E, "SH3E", AOUTHDRSZ }, + { IMAGE_FILE_MACHINE_SH4, "SH4", AOUTHDRSZ }, + { IMAGE_FILE_MACHINE_SH5, "SH5", AOUTHDRSZ }, ++#ifdef TARGET_SW_64 ++ { IMAGE_FILE_MACHINE_SW_64, "SW_64", AOUTHDRSZ }, ++#endif + { IMAGE_FILE_MACHINE_THUMB, "THUMB", AOUTHDRSZ }, + { IMAGE_FILE_MACHINE_TRICORE, "TRICORE", AOUTHDRSZ }, + { IMAGE_FILE_MACHINE_WCEMIPSV2, "WCEMIPSV2", AOUTHDRSZ }, +diff --git a/include/coff/pe.h b/include/coff/pe.h +index 79e349a5..3943be76 100644 +--- a/include/coff/pe.h ++++ b/include/coff/pe.h +@@ -135,8 +135,7 @@ + #define IMAGE_FILE_MACHINE_ALPHA 0x0184 + #define IMAGE_FILE_MACHINE_ALPHA64 0x0284 + #ifdef TARGET_SW_64 +-#define IMAGE_FILE_MACHINE_SW_64 0x0184 +-#define IMAGE_FILE_MACHINE_SW_6464 0x0284 ++#define IMAGE_FILE_MACHINE_SW_64 0x9916 + #endif + #define IMAGE_FILE_MACHINE_AM33 0x01d3 + #define IMAGE_FILE_MACHINE_AMD64 0x8664 +diff --git a/include/coff/sw_64.h b/include/coff/sw_64.h +index 3476e45b..cf69b93c 100644 +--- a/include/coff/sw_64.h ++++ b/include/coff/sw_64.h +@@ -19,7 +19,8 @@ + MA 02110-1301, USA. */ + + /********************** FILE HEADER **********************/ +- ++#ifndef PEI_HEADERS ++#ifndef COFF_WITH_peSW_64 + struct external_filehdr + { + unsigned char f_magic[2]; /* magic number */ +@@ -30,13 +31,41 @@ struct external_filehdr + unsigned char f_opthdr[2]; /* sizeof (optional hdr) */ + unsigned char f_flags[2]; /* flags */ + }; +- ++#endif ++#endif + /* Magic numbers are defined in coff/ecoff.h. */ + #define SW_64_ECOFF_BADMAG(x) \ + ((x).f_magic != SW_64_MAGIC && (x).f_magic != SW_64_MAGIC_BSD) + + #define SW_64_ECOFF_COMPRESSEDMAG(x) ((x).f_magic == SW_64_MAGIC_COMPRESSED) +- ++#define L_LNNO_SIZE 2 ++#define F_SW_64_ARCHITECTURE_MASK (0x4000) ++ ++#define SW_64MAGIC 0x284 /* From Microsoft specification. */ ++ ++#undef BADMAG ++#define BADMAG(x) ((x).f_magic != SW_64MAGIC) ++#define SW_64 1 /* Customize coffcode.h. */ ++//#include "coff/external.h" ++#define INCLUDE_COMDAT_FIELDS_IN_AUXENT ++#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b ++ ++#define OMAGIC 0404 /* Object files, eg as output. */ ++#define ZMAGIC IMAGE_NT_OPTIONAL_HDR64_MAGIC /* Demand load format, eg normal ld output 0x10b. */ ++#define STMAGIC 0401 /* Target shlib. */ ++#define SHMAGIC 0443 /* Host shlib. */ ++ ++/* define some NT default values */ ++/* #define NT_IMAGE_BASE 0x400000 moved to internal.h */ ++#define NT_SECTION_ALIGNMENT 0x1000 ++#define NT_FILE_ALIGNMENT 0x200 ++#define NT_DEF_RESERVE 0x100000 ++#define NT_DEF_COMMIT 0x1000 ++ ++/* We use the .rdata section to hold read only data. */ ++#define _LIT ".rdata" ++ ++#define E_SYMNMLEN 8 /* # characters in a symbol name */ + /* The object type is encoded in the f_flags. */ + #define F_SW_64_OBJECT_TYPE_MASK 0x3000 + #define F_SW_64_NO_SHARED 0x1000 +@@ -47,7 +76,8 @@ struct external_filehdr + #define FILHSZ 24 + + /********************** AOUT "OPTIONAL HEADER" **********************/ +- ++#ifndef PEI_HEADERS ++#ifndef COFF_WITH_peSW_64 + typedef struct external_aouthdr + { + unsigned char magic[2]; /* type of file. */ +@@ -65,14 +95,16 @@ typedef struct external_aouthdr + unsigned char fprmask[4]; /* bitmask of floating point registers used. */ + unsigned char gp_value[8]; /* value for gp register. */ + } AOUTHDR; +- ++#endif ++#endif + /* compute size of a header */ + + #define AOUTSZ 80 + #define AOUTHDRSZ 80 + + /********************** SECTION HEADER **********************/ +- ++#ifndef PEI_HEADERS ++#ifndef COFF_WITH_peSW_64 + struct external_scnhdr + { + unsigned char s_name[8]; /* section name */ +@@ -86,19 +118,28 @@ struct external_scnhdr + unsigned char s_nlnno[2]; /* number of line number entries*/ + unsigned char s_flags[4]; /* flags */ + }; +- ++#endif ++#endif + #define SCNHDR struct external_scnhdr + #define SCNHSZ 64 + + /********************** RELOCATION DIRECTIVES **********************/ +- ++#ifndef PEI_HEADERS + struct external_reloc + { + unsigned char r_vaddr[8]; + unsigned char r_symndx[4]; + unsigned char r_bits[4]; + }; +- ++#else ++struct external_reloc ++{ ++ char r_vaddr[4]; ++ char r_symndx[4]; ++ char r_type[2]; ++ char r_offset[4]; ++}; ++#endif + #define RELOC struct external_reloc + #define RELSZ 16 + +@@ -377,7 +418,7 @@ struct opt_ext + unsigned char o_bits2[1]; + unsigned char o_bits3[1]; + unsigned char o_bits4[1]; +- struct rndx_ext o_rndx; ++ struct rndx_ext *o_rndx; + unsigned char o_offset[4]; + }; + diff --git a/backport-CVE-2025-7546.patch b/backport-CVE-2025-7546.patch new file mode 100644 index 0000000000000000000000000000000000000000..2402f5df164363bfc05f7d6baa81b3e8de6b1d61 --- /dev/null +++ b/backport-CVE-2025-7546.patch @@ -0,0 +1,53 @@ +From 41461010eb7c79fee7a9d5f6209accdaac66cc6b Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Sat, 21 Jun 2025 06:52:00 +0800 +Subject: [PATCH 1/1] elf: Report corrupted group section + +Report corrupted group section instead of trying to recover. + + PR binutils/33050 + * elf.c (bfd_elf_set_group_contents): Report corrupted group + section. + +Signed-off-by: H.J. Lu +--- + bfd/elf.c | 23 ++++++++++------------- + 1 file changed, 10 insertions(+), 13 deletions(-) + +diff --git a/bfd/elf.c b/bfd/elf.c +index 14ce15c7254..ee894eb05f2 100644 +--- a/bfd/elf.c ++++ b/bfd/elf.c +@@ -3971,20 +3971,17 @@ bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg) + break; + } + +- /* We should always get here with loc == sec->contents + 4, but it is +- possible to craft bogus SHT_GROUP sections that will cause segfaults +- in objcopy without checking loc here and in the loop above. */ +- if (loc == sec->contents) +- BFD_ASSERT (0); +- else ++ /* We should always get here with loc == sec->contents + 4. Return ++ an error for bogus SHT_GROUP sections. */ ++ loc -= 4; ++ if (loc != sec->contents) + { +- loc -= 4; +- if (loc != sec->contents) +- { +- BFD_ASSERT (0); +- memset (sec->contents + 4, 0, loc - sec->contents); +- loc = sec->contents; +- } ++ /* xgettext:c-format */ ++ _bfd_error_handler (_("%pB: corrupted group section: `%pA'"), ++ abfd, sec); ++ bfd_set_error (bfd_error_bad_value); ++ *failedptr = true; ++ return; + } + + H_PUT_32 (abfd, sec->flags & SEC_LINK_ONCE ? GRP_COMDAT : 0, loc); +-- +2.43.7 diff --git a/Fix-slowdown-about-partial-linking.patch b/backport-Fix-slowdown-about-partial-linking.patch similarity index 100% rename from Fix-slowdown-about-partial-linking.patch rename to backport-Fix-slowdown-about-partial-linking.patch diff --git a/binutils.spec b/binutils.spec index 0d34413ced4bf07a16a2c5bc1e6c22fba18d4c28..a7ea6a711e354282e35c4b429c9e71bde4b6af13 100644 --- a/binutils.spec +++ b/binutils.spec @@ -2,7 +2,7 @@ Summary: A GNU collection of binary utilities Name: binutils%{?_with_debug:-debug} Version: 2.41 -Release: 21 +Release: 22 License: GPL-3.0-or-later AND (GPL-3.0-or-later WITH Bison-exception-2.2) AND (LGPL-2.0-or-later WITH GCC-exception-2.0) AND BSD-3-Clause AND GFDL-1.3-or-later AND GPL-2.0-or-later AND LGPL-2.1-or-later AND LGPL-2.0-or-later URL: https://sourceware.org/binutils @@ -164,6 +164,7 @@ Source2: binutils-2.19.50.0.1-output-format.sed Patch1001: X86-Change-fpic-to-fPIC-in-PICFLAG.patch Patch1002: PPC-gas-supported-c2000.patch Patch1003: Sw64-binutils-Add-Sw64-support.patch +Patch1004: Sw64-Add-support-for-EFI.patch # Part 3000 - 4999 Patch3001: LoongArch-Fix-ld-no-relax-bug.patch @@ -367,9 +368,10 @@ Patch5010: binutils-BPF-reloc-4.patch # Lifetime: Permanent. Patch5011: binutils-gold-warn-unsupported.patch -# Purpose: Fix slowdown about partial linking. +# Purpose: Fix slowdown about partial linking +# PR 32238, ld -r slowdown since 21401fc7bf # Lifetime: Fixed in 2.44 -Patch5012: Fix-slowdown-about-partial-linking.patch +Patch5012: backport-Fix-slowdown-about-partial-linking.patch # Purpose: nm: Avoid potential segmentation fault when displaying # symbols without version info. @@ -389,18 +391,30 @@ Patch5015: backport-CVE-2025-3198.patch Patch5016: backport-PR32399-buffer-overflow-printing-core_file_failing_c.patch Patch5017: backport-Re-PR32399-buffer-overflow-printing-core_file_failin.patch -#---------------------------------------------------------------------------- +# Purpose: Add prefetch L4 instruction support +# Lifetime: Permanent +Patch5018: aarch64-add-l4-instruction.patch + +# Purpose: PR binutils/33049 +# Lifetime: Fixed in 2.45 +Patch5019: backport-CVE-2025-7545.patch + +# Purpose: PR binutils/33050 +# Lifetime: Fixed in 2.45 +Patch5020: backport-CVE-2025-7546.patch + +# Purpose: See https://gitee.com/src-openeuler/binutils/pulls/361 +# Lifetime: +Patch5021: backport-bfd-aarch64-Fix-BTI-stub-optimization-PR30957.patch +Patch5022: backport-bfd-aarch64-Fix-broken-BTI-stub-PR30930.patch +Patch5023: backport-bfd-aarch64-Avoid-BTI-stub-for-a-PLT-that-has-BTI.patch +Patch5024: backport-bfd-aarch64-Fix-leaks-in-case-of-BTI-stub-reuse.patch +Patch5025: backport-libctf-fix-ref-leak-of-names-of-newly-inserted-non-r.patch +Patch5026: backport-x86-64-fix-suffix-less-PUSH-of-symbol-address.patch +Patch5027: backport-x86-Check-MODRM-for-call-and-jmp-in-binutils-older-t.patch +Patch5028: backport-x86-restrict-prefix-use-with-.insn-VEX-XOP-EVEX.patch -Patch6001: aarch64-add-l4-instruction.patch -Patch6002: backport-bfd-aarch64-Fix-BTI-stub-optimization-PR30957.patch -Patch6003: backport-bfd-aarch64-Fix-broken-BTI-stub-PR30930.patch -Patch6004: backport-bfd-aarch64-Avoid-BTI-stub-for-a-PLT-that-has-BTI.patch -Patch6005: backport-bfd-aarch64-Fix-leaks-in-case-of-BTI-stub-reuse.patch -Patch6006: backport-libctf-fix-ref-leak-of-names-of-newly-inserted-non-r.patch -Patch6007: backport-x86-64-fix-suffix-less-PUSH-of-symbol-address.patch -Patch6008: backport-x86-Check-MODRM-for-call-and-jmp-in-binutils-older-t.patch -Patch6009: backport-x86-restrict-prefix-use-with-.insn-VEX-XOP-EVEX.patch -Patch6010: backport-CVE-2025-7545.patch +#---------------------------------------------------------------------------- Provides: bundled(libiberty) @@ -1416,6 +1430,10 @@ exit 0 #---------------------------------------------------------------------------- %changelog +* Tue Aug 19 2025 eastb233 -2.41-22 +- Format patch names +- Sync openEuler 24.03 series and master branch's CVE and bugfix patches + * Tue Aug 19 2025 Yu Peng - 2.41-21 - Fix CVE-2025-7545: objcopy: Don't extend the output section size