binutils-gdb/bfd/coff-go32.c

180 lines
6.9 KiB
C
Raw Normal View History

/* BFD back-end for Intel 386 COFF files (DJGPP variant).
Copyright (C) 1990-2020 Free Software Foundation, Inc.
1999-05-03 09:29:11 +02:00
Written by DJ Delorie.
This file is part of BFD, the Binary File Descriptor library.
1999-05-03 09:29:11 +02:00
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.
1999-05-03 09:29:11 +02:00
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.
1999-05-03 09:29:11 +02:00
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. */
1999-05-03 09:29:11 +02:00
bfd target vector rationalisation This renames the bfd targets to <cpu>_<format>_<other>_<endian>_vec. So for example, bfd_elf32_ntradlittlemips_vec becomes mips_elf32_ntrad_le_vec and hp300bsd_vec becomes m68k_aout_hp300bsd_vec. bfd/ * aix386-core.c, * aout-adobe.c, * aout-arm.c, * aout-ns32k.c, * aout-sparcle.c, * aout0.c, * aoutx.h, * armnetbsd.c, * bout.c, * cf-i386lynx.c, * cf-sparclynx.c, * cisco-core.c, * coff-alpha.c, * coff-apollo.c, * coff-arm.c, * coff-aux.c, * coff-go32.c, * coff-h8300.c, * coff-h8500.c, * coff-i386.c, * coff-i860.c, * coff-i960.c, * coff-m68k.c, * coff-m88k.c, * coff-mips.c, * coff-rs6000.c, * coff-sh.c, * coff-sparc.c, * coff-stgo32.c, * coff-svm68k.c, * coff-tic80.c, * coff-u68k.c, * coff-w65.c, * coff-we32k.c, * coff-x86_64.c, * coff-z80.c, * coff-z8k.c, * coff64-rs6000.c, * config.bfd, * configure.com, * configure.in, * demo64.c, * elf-m10200.c, * elf-m10300.c, * elf32-am33lin.c, * elf32-arc.c, * elf32-arm.c, * elf32-avr.c, * elf32-bfin.c, * elf32-cr16.c, * elf32-cr16c.c, * elf32-cris.c, * elf32-crx.c, * elf32-d10v.c, * elf32-d30v.c, * elf32-dlx.c, * elf32-epiphany.c, * elf32-fr30.c, * elf32-frv.c, * elf32-gen.c, * elf32-h8300.c, * elf32-hppa.c, * elf32-i370.c, * elf32-i386.c, * elf32-i860.c, * elf32-i960.c, * elf32-ip2k.c, * elf32-iq2000.c, * elf32-lm32.c, * elf32-m32c.c, * elf32-m32r.c, * elf32-m68hc11.c, * elf32-m68hc12.c, * elf32-m68k.c, * elf32-m88k.c, * elf32-mcore.c, * elf32-mep.c, * elf32-metag.c, * elf32-microblaze.c, * elf32-mips.c, * elf32-moxie.c, * elf32-msp430.c, * elf32-mt.c, * elf32-nds32.c, * elf32-nios2.c, * elf32-or1k.c, * elf32-pj.c, * elf32-ppc.c, * elf32-rl78.c, * elf32-rx.c, * elf32-s390.c, * elf32-score.c, * elf32-sh-symbian.c, * elf32-sh.c, * elf32-sh64.c, * elf32-sparc.c, * elf32-spu.c, * elf32-tic6x.c, * elf32-tilegx.c, * elf32-tilepro.c, * elf32-v850.c, * elf32-vax.c, * elf32-xc16x.c, * elf32-xgate.c, * elf32-xstormy16.c, * elf32-xtensa.c, * elf64-alpha.c, * elf64-gen.c, * elf64-hppa.c, * elf64-ia64-vms.c, * elf64-mips.c, * elf64-mmix.c, * elf64-ppc.c, * elf64-s390.c, * elf64-sh64.c, * elf64-sparc.c, * elf64-tilegx.c, * elf64-x86-64.c, * elfn32-mips.c, * elfnn-aarch64.c, * elfnn-ia64.c, * epoc-pe-arm.c, * epoc-pei-arm.c, * hp300bsd.c, * hp300hpux.c, * hppabsd-core.c, * hpux-core.c, * i386aout.c, * i386bsd.c, * i386dynix.c, * i386freebsd.c, * i386linux.c, * i386lynx.c, * i386mach3.c, * i386msdos.c, * i386netbsd.c, * i386os9k.c, * irix-core.c, * m68k4knetbsd.c, * m68klinux.c, * m68knetbsd.c, * m88kmach3.c, * m88kopenbsd.c, * mach-o-i386.c, * mach-o-x86-64.c, * makefile.vms, * mipsbsd.c, * mmo.c, * netbsd-core.c, * newsos3.c, * nlm32-alpha.c, * nlm32-i386.c, * nlm32-ppc.c, * nlm32-sparc.c, * ns32knetbsd.c, * osf-core.c, * pc532-mach.c, * pe-arm-wince.c, * pe-arm.c, * pe-i386.c, * pe-mcore.c, * pe-mips.c, * pe-ppc.c, * pe-sh.c, * pe-x86_64.c, * pei-arm-wince.c, * pei-arm.c, * pei-i386.c, * pei-ia64.c, * pei-mcore.c, * pei-mips.c, * pei-ppc.c, * pei-sh.c, * pei-x86_64.c, * ppcboot.c, * ptrace-core.c, * riscix.c, * sco5-core.c, * som.c, * sparclinux.c, * sparclynx.c, * sparcnetbsd.c, * sunos.c, * targets.c, * trad-core.c, * vax1knetbsd.c, * vaxbsd.c, * vaxnetbsd.c, * versados.c, * vms-alpha.c, * vms-lib.c: Rename bfd targets to <cpu>_<format>_<other>_<endian>_vec. Adjust associated MY macros on aout targets. * configure: Regenerate. binutils/ * emul_aix.c: Update bfd target vector naming. * testsuite/binutils-all/objcopy.exp: Likewise. ld/ * emultempl/metagelf.em: Update bfd target vector naming. * emultempl/nios2elf.em: Likewise. * emultempl/spuelf.em: Likewise. * emultempl/tic6xdsbt.em: Likewise.
2014-05-02 12:39:40 +02:00
#define TARGET_SYM i386_coff_go32_vec
1999-05-03 09:29:11 +02:00
#define TARGET_NAME "coff-go32"
#define TARGET_UNDERSCORE '_'
[PATCH v2 2/2] coff-go32: support extended relocations This patch extends the relocation and line number counters for coff-go32 and coff-go32-exe to 32 bits. As I understand it works the same as for PE-COFF: If the number of relocations in an object file exceeds 65534, the NRELOC field is set to 65535 and the actual number of relocations is stored in the VADDR field of the first relocation entry. Executable files have no relocations, and thus the NRELOC field is repurposed to extend NLNNO to 32-bits. bfd * coff-go32.c (COFF_GO32, IMAGE_SCN_LNK_NRELOC_OVFL) (coff_SWAP_scnhdr_in, coff_SWAP_scnhdr_out): Define. (_bfd_go32_swap_scnhdr_in, _bfd_go32_swap_scnhdr_out) (_bfd_go32_mkobject): New functions. * coff-stgo32.c (IMAGE_SCN_LNK_NRELOC_OVFL) (coff_SWAP_scnhdr_in, coff_SWAP_scnhdr_out): Define. (go32exe_mkobject): Call _bfd_go32_mkobject. * coffcode.h (COFF_WITH_EXTENDED_RELOC_COUNTER): Define. (coff_set_alignment_hook): Define function for COFF_GO32_EXE and COFF_GO32. (coff_write_relocs): Enable extended reloc counter code if COFF_WITH_EXTENDED_RELOC_COUNTER is defined. Test for obj_go32. (coff_write_object_contents): Likewise. Pad section headers for COFF_GO32 and COFF_GO32EXE. Use bfd_coff_swap_scnhdr_out instead of coff_swap_scnhdr_out. * cofflink.c (_bfd_coff_final_link): Test also for obj_go32 to enable extended reloc counter. * coffswap.h: (coff_swap_scnhdr_in, coff_swap_scnhdr_out): Declare with ATTRIBUTE_UNUSED. * libcoff-in.h: (struct coff_tdata): New field go32. (obj_go32): Define. * libcoff.h: Regenerate.
2020-04-14 18:30:01 +02:00
#define COFF_GO32
#define COFF_LONG_SECTION_NAMES
#define COFF_SUPPORT_GNU_LINKONCE
2001-01-25 22:08:10 +01:00
#define COFF_LONG_FILENAMES
1999-05-03 09:29:11 +02:00
#define COFF_SECTION_ALIGNMENT_ENTRIES \
{ COFF_SECTION_NAME_EXACT_MATCH (".data"), \
COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
{ COFF_SECTION_NAME_EXACT_MATCH (".text"), \
COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.d"), \
COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.t"), \
COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.r"), \
COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
{ 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 }
[PATCH v2 2/2] coff-go32: support extended relocations This patch extends the relocation and line number counters for coff-go32 and coff-go32-exe to 32 bits. As I understand it works the same as for PE-COFF: If the number of relocations in an object file exceeds 65534, the NRELOC field is set to 65535 and the actual number of relocations is stored in the VADDR field of the first relocation entry. Executable files have no relocations, and thus the NRELOC field is repurposed to extend NLNNO to 32-bits. bfd * coff-go32.c (COFF_GO32, IMAGE_SCN_LNK_NRELOC_OVFL) (coff_SWAP_scnhdr_in, coff_SWAP_scnhdr_out): Define. (_bfd_go32_swap_scnhdr_in, _bfd_go32_swap_scnhdr_out) (_bfd_go32_mkobject): New functions. * coff-stgo32.c (IMAGE_SCN_LNK_NRELOC_OVFL) (coff_SWAP_scnhdr_in, coff_SWAP_scnhdr_out): Define. (go32exe_mkobject): Call _bfd_go32_mkobject. * coffcode.h (COFF_WITH_EXTENDED_RELOC_COUNTER): Define. (coff_set_alignment_hook): Define function for COFF_GO32_EXE and COFF_GO32. (coff_write_relocs): Enable extended reloc counter code if COFF_WITH_EXTENDED_RELOC_COUNTER is defined. Test for obj_go32. (coff_write_object_contents): Likewise. Pad section headers for COFF_GO32 and COFF_GO32EXE. Use bfd_coff_swap_scnhdr_out instead of coff_swap_scnhdr_out. * cofflink.c (_bfd_coff_final_link): Test also for obj_go32 to enable extended reloc counter. * coffswap.h: (coff_swap_scnhdr_in, coff_swap_scnhdr_out): Declare with ATTRIBUTE_UNUSED. * libcoff-in.h: (struct coff_tdata): New field go32. (obj_go32): Define. * libcoff.h: Regenerate.
2020-04-14 18:30:01 +02:00
/* Section contains extended relocations. */
#define IMAGE_SCN_LNK_NRELOC_OVFL (0x01000000)
#include "sysdep.h"
#include "bfd.h"
/* The following functions are not static, because they are also
used for coff-go32-exe (coff-stgo32.c). */
bfd_boolean _bfd_go32_mkobject (bfd *);
void _bfd_go32_swap_scnhdr_in (bfd *, void *, void *);
unsigned int _bfd_go32_swap_scnhdr_out (bfd *, void *, void *);
#define coff_mkobject _bfd_go32_mkobject
#define coff_SWAP_scnhdr_in _bfd_go32_swap_scnhdr_in
#define coff_SWAP_scnhdr_out _bfd_go32_swap_scnhdr_out
1999-05-03 09:29:11 +02:00
#include "coff-i386.c"
[PATCH v2 2/2] coff-go32: support extended relocations This patch extends the relocation and line number counters for coff-go32 and coff-go32-exe to 32 bits. As I understand it works the same as for PE-COFF: If the number of relocations in an object file exceeds 65534, the NRELOC field is set to 65535 and the actual number of relocations is stored in the VADDR field of the first relocation entry. Executable files have no relocations, and thus the NRELOC field is repurposed to extend NLNNO to 32-bits. bfd * coff-go32.c (COFF_GO32, IMAGE_SCN_LNK_NRELOC_OVFL) (coff_SWAP_scnhdr_in, coff_SWAP_scnhdr_out): Define. (_bfd_go32_swap_scnhdr_in, _bfd_go32_swap_scnhdr_out) (_bfd_go32_mkobject): New functions. * coff-stgo32.c (IMAGE_SCN_LNK_NRELOC_OVFL) (coff_SWAP_scnhdr_in, coff_SWAP_scnhdr_out): Define. (go32exe_mkobject): Call _bfd_go32_mkobject. * coffcode.h (COFF_WITH_EXTENDED_RELOC_COUNTER): Define. (coff_set_alignment_hook): Define function for COFF_GO32_EXE and COFF_GO32. (coff_write_relocs): Enable extended reloc counter code if COFF_WITH_EXTENDED_RELOC_COUNTER is defined. Test for obj_go32. (coff_write_object_contents): Likewise. Pad section headers for COFF_GO32 and COFF_GO32EXE. Use bfd_coff_swap_scnhdr_out instead of coff_swap_scnhdr_out. * cofflink.c (_bfd_coff_final_link): Test also for obj_go32 to enable extended reloc counter. * coffswap.h: (coff_swap_scnhdr_in, coff_swap_scnhdr_out): Declare with ATTRIBUTE_UNUSED. * libcoff-in.h: (struct coff_tdata): New field go32. (obj_go32): Define. * libcoff.h: Regenerate.
2020-04-14 18:30:01 +02:00
bfd_boolean
_bfd_go32_mkobject (bfd * abfd)
{
const bfd_size_type amt = sizeof (coff_data_type);
abfd->tdata.coff_obj_data = bfd_zalloc (abfd, amt);
if (abfd->tdata.coff_obj_data == NULL)
return FALSE;
coff_data (abfd)->go32 = TRUE;
return TRUE;
}
void
_bfd_go32_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
{
SCNHDR *scnhdr_ext = (SCNHDR *) ext;
struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
memcpy (scnhdr_int->s_name, scnhdr_ext->s_name, sizeof (scnhdr_int->s_name));
scnhdr_int->s_vaddr = GET_SCNHDR_VADDR (abfd, scnhdr_ext->s_vaddr);
scnhdr_int->s_paddr = GET_SCNHDR_PADDR (abfd, scnhdr_ext->s_paddr);
scnhdr_int->s_size = GET_SCNHDR_SIZE (abfd, scnhdr_ext->s_size);
scnhdr_int->s_scnptr = GET_SCNHDR_SCNPTR (abfd, scnhdr_ext->s_scnptr);
scnhdr_int->s_relptr = GET_SCNHDR_RELPTR (abfd, scnhdr_ext->s_relptr);
scnhdr_int->s_lnnoptr = GET_SCNHDR_LNNOPTR (abfd, scnhdr_ext->s_lnnoptr);
scnhdr_int->s_flags = GET_SCNHDR_FLAGS (abfd, scnhdr_ext->s_flags);
scnhdr_int->s_nreloc = GET_SCNHDR_NRELOC (abfd, scnhdr_ext->s_nreloc);
scnhdr_int->s_nlnno = GET_SCNHDR_NLNNO (abfd, scnhdr_ext->s_nlnno);
/* DJGPP follows the same strategy as PE COFF.
Iff the file is an executable then the higher 16 bits
of the line number have been stored in the relocation
counter field. */
if (abfd->flags & EXEC_P && (strcmp (scnhdr_ext->s_name, ".text") == 0))
{
scnhdr_int->s_nlnno
= (GET_SCNHDR_NRELOC (abfd, scnhdr_ext->s_nreloc) << 16)
+ GET_SCNHDR_NLNNO (abfd, scnhdr_ext->s_nlnno);
scnhdr_int->s_nreloc = 0;
}
}
unsigned int
_bfd_go32_swap_scnhdr_out (bfd * abfd, void * in, void * out)
{
struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
SCNHDR *scnhdr_ext = (SCNHDR *) out;
unsigned int ret = bfd_coff_scnhsz (abfd);
memcpy (scnhdr_ext->s_name, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
PUT_SCNHDR_VADDR (abfd, scnhdr_int->s_vaddr, scnhdr_ext->s_vaddr);
PUT_SCNHDR_PADDR (abfd, scnhdr_int->s_paddr, scnhdr_ext->s_paddr);
PUT_SCNHDR_SIZE (abfd, scnhdr_int->s_size, scnhdr_ext->s_size);
PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr, scnhdr_ext->s_scnptr);
PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr, scnhdr_ext->s_relptr);
PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr, scnhdr_ext->s_lnnoptr);
PUT_SCNHDR_FLAGS (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
if (abfd->flags & EXEC_P && (strcmp (scnhdr_int->s_name, ".text") == 0))
{
/* DJGPP follows the same strategy as PE COFF.
By inference from looking at MS output, the 32 bit field
which is the combination of the number_of_relocs and
number_of_linenos is used for the line number count in
executables. A 16-bit field won't do for cc1. The MS
document says that the number of relocs is zero for
executables, but the 17-th bit has been observed to be there.
Overflow is not an issue: a 4G-line program will overflow a
bunch of other fields long before this! */
PUT_SCNHDR_NLNNO (abfd, (scnhdr_int->s_nlnno & 0xffff),
scnhdr_ext->s_nlnno);
PUT_SCNHDR_NRELOC (abfd, (scnhdr_int->s_nlnno >> 16),
scnhdr_ext->s_nreloc);
}
else
{
/* DJGPP follows the same strategy as PE COFF. */
if (scnhdr_int->s_nlnno <= MAX_SCNHDR_NLNNO)
PUT_SCNHDR_NLNNO (abfd, scnhdr_int->s_nlnno, scnhdr_ext->s_nlnno);
else
{
char buf[sizeof (scnhdr_int->s_name) + 1];
memcpy (buf, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
buf[sizeof (scnhdr_int->s_name)] = '\0';
_bfd_error_handler
/* xgettext:c-format */
(_("%pB: warning: %s: line number overflow: 0x%lx > 0xffff"),
abfd, buf, scnhdr_int->s_nlnno);
bfd_set_error (bfd_error_file_truncated);
PUT_SCNHDR_NLNNO (abfd, 0xffff, scnhdr_ext->s_nlnno);
ret = 0;
}
/* Although we could encode 0xffff relocs here, we do not, to be
consistent with other parts of bfd. Also it lets us warn, as
we should never see 0xffff here w/o having the overflow flag
set. */
if (scnhdr_int->s_nreloc < MAX_SCNHDR_NRELOC)
PUT_SCNHDR_NRELOC (abfd, scnhdr_int->s_nreloc, scnhdr_ext->s_nreloc);
else
{
/* DJGPP can deal with large #s of relocs, but not here. */
PUT_SCNHDR_NRELOC (abfd, 0xffff, scnhdr_ext->s_nreloc);
scnhdr_int->s_flags |= IMAGE_SCN_LNK_NRELOC_OVFL;
PUT_SCNHDR_FLAGS (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
}
}
return ret;
}