1 /* BFD back-end for Intel 386 COFF files (DJGPP variant). 2 Copyright (C) 1990-2022 Free Software Foundation, Inc. 3 Written by DJ Delorie. 4 5 This file is part of BFD, the Binary File Descriptor library. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 20 MA 02110-1301, USA. */ 21 22 #define TARGET_SYM i386_coff_go32_vec 23 #define TARGET_NAME "coff-go32" 24 #define TARGET_UNDERSCORE '_' 25 #define COFF_GO32 26 #define COFF_LONG_SECTION_NAMES 27 #define COFF_SUPPORT_GNU_LINKONCE 28 #define COFF_LONG_FILENAMES 29 30 #define COFF_SECTION_ALIGNMENT_ENTRIES \ 31 { COFF_SECTION_NAME_PARTIAL_MATCH (".data"), \ 32 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \ 33 { COFF_SECTION_NAME_PARTIAL_MATCH (".text"), \ 34 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \ 35 { COFF_SECTION_NAME_PARTIAL_MATCH (".const"), \ 36 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \ 37 { COFF_SECTION_NAME_PARTIAL_MATCH (".rodata"), \ 38 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \ 39 { COFF_SECTION_NAME_PARTIAL_MATCH (".bss"), \ 40 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \ 41 { COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.d"), \ 42 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \ 43 { COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.t"), \ 44 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \ 45 { COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.r"), \ 46 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \ 47 { COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.b"), \ 48 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \ 49 { COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \ 50 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \ 51 { COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi"), \ 52 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 } 53 54 /* Section contains extended relocations. */ 55 #define IMAGE_SCN_LNK_NRELOC_OVFL (0x01000000) 56 57 #include "sysdep.h" 58 #include "bfd.h" 59 60 /* The following functions are not static, because they are also 61 used for coff-go32-exe (coff-stgo32.c). */ 62 bool _bfd_go32_mkobject (bfd *); 63 void _bfd_go32_swap_scnhdr_in (bfd *, void *, void *); 64 unsigned int _bfd_go32_swap_scnhdr_out (bfd *, void *, void *); 65 66 #define coff_mkobject _bfd_go32_mkobject 67 #define coff_SWAP_scnhdr_in _bfd_go32_swap_scnhdr_in 68 #define coff_SWAP_scnhdr_out _bfd_go32_swap_scnhdr_out 69 70 #include "coff-i386.c" 71 72 bool 73 _bfd_go32_mkobject (bfd * abfd) 74 { 75 const bfd_size_type amt = sizeof (coff_data_type); 76 77 abfd->tdata.coff_obj_data = bfd_zalloc (abfd, amt); 78 if (abfd->tdata.coff_obj_data == NULL) 79 return false; 80 81 coff_data (abfd)->go32 = true; 82 83 return true; 84 } 85 86 void 87 _bfd_go32_swap_scnhdr_in (bfd * abfd, void * ext, void * in) 88 { 89 SCNHDR *scnhdr_ext = (SCNHDR *) ext; 90 struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in; 91 92 memcpy (scnhdr_int->s_name, scnhdr_ext->s_name, sizeof (scnhdr_int->s_name)); 93 94 scnhdr_int->s_vaddr = GET_SCNHDR_VADDR (abfd, scnhdr_ext->s_vaddr); 95 scnhdr_int->s_paddr = GET_SCNHDR_PADDR (abfd, scnhdr_ext->s_paddr); 96 scnhdr_int->s_size = GET_SCNHDR_SIZE (abfd, scnhdr_ext->s_size); 97 98 scnhdr_int->s_scnptr = GET_SCNHDR_SCNPTR (abfd, scnhdr_ext->s_scnptr); 99 scnhdr_int->s_relptr = GET_SCNHDR_RELPTR (abfd, scnhdr_ext->s_relptr); 100 scnhdr_int->s_lnnoptr = GET_SCNHDR_LNNOPTR (abfd, scnhdr_ext->s_lnnoptr); 101 scnhdr_int->s_flags = GET_SCNHDR_FLAGS (abfd, scnhdr_ext->s_flags); 102 scnhdr_int->s_nreloc = GET_SCNHDR_NRELOC (abfd, scnhdr_ext->s_nreloc); 103 scnhdr_int->s_nlnno = GET_SCNHDR_NLNNO (abfd, scnhdr_ext->s_nlnno); 104 105 /* DJGPP follows the same strategy as PE COFF. 106 Iff the file is an executable then the higher 16 bits 107 of the line number have been stored in the relocation 108 counter field. */ 109 if (abfd->flags & EXEC_P && (strcmp (scnhdr_ext->s_name, ".text") == 0)) 110 { 111 scnhdr_int->s_nlnno 112 = (GET_SCNHDR_NRELOC (abfd, scnhdr_ext->s_nreloc) << 16) 113 + GET_SCNHDR_NLNNO (abfd, scnhdr_ext->s_nlnno); 114 scnhdr_int->s_nreloc = 0; 115 } 116 } 117 118 unsigned int 119 _bfd_go32_swap_scnhdr_out (bfd * abfd, void * in, void * out) 120 { 121 struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in; 122 SCNHDR *scnhdr_ext = (SCNHDR *) out; 123 unsigned int ret = bfd_coff_scnhsz (abfd); 124 125 memcpy (scnhdr_ext->s_name, scnhdr_int->s_name, sizeof (scnhdr_int->s_name)); 126 127 PUT_SCNHDR_VADDR (abfd, scnhdr_int->s_vaddr, scnhdr_ext->s_vaddr); 128 PUT_SCNHDR_PADDR (abfd, scnhdr_int->s_paddr, scnhdr_ext->s_paddr); 129 PUT_SCNHDR_SIZE (abfd, scnhdr_int->s_size, scnhdr_ext->s_size); 130 PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr, scnhdr_ext->s_scnptr); 131 PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr, scnhdr_ext->s_relptr); 132 PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr, scnhdr_ext->s_lnnoptr); 133 PUT_SCNHDR_FLAGS (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags); 134 135 if (abfd->flags & EXEC_P && (strcmp (scnhdr_int->s_name, ".text") == 0)) 136 { 137 /* DJGPP follows the same strategy as PE COFF. 138 By inference from looking at MS output, the 32 bit field 139 which is the combination of the number_of_relocs and 140 number_of_linenos is used for the line number count in 141 executables. A 16-bit field won't do for cc1. The MS 142 document says that the number of relocs is zero for 143 executables, but the 17-th bit has been observed to be there. 144 Overflow is not an issue: a 4G-line program will overflow a 145 bunch of other fields long before this! */ 146 PUT_SCNHDR_NLNNO (abfd, (scnhdr_int->s_nlnno & 0xffff), 147 scnhdr_ext->s_nlnno); 148 PUT_SCNHDR_NRELOC (abfd, (scnhdr_int->s_nlnno >> 16), 149 scnhdr_ext->s_nreloc); 150 } 151 else 152 { 153 /* DJGPP follows the same strategy as PE COFF. */ 154 if (scnhdr_int->s_nlnno <= MAX_SCNHDR_NLNNO) 155 PUT_SCNHDR_NLNNO (abfd, scnhdr_int->s_nlnno, scnhdr_ext->s_nlnno); 156 else 157 { 158 char buf[sizeof (scnhdr_int->s_name) + 1]; 159 160 memcpy (buf, scnhdr_int->s_name, sizeof (scnhdr_int->s_name)); 161 buf[sizeof (scnhdr_int->s_name)] = '\0'; 162 _bfd_error_handler 163 /* xgettext:c-format */ 164 (_("%pB: warning: %s: line number overflow: 0x%lx > 0xffff"), 165 abfd, buf, scnhdr_int->s_nlnno); 166 bfd_set_error (bfd_error_file_truncated); 167 PUT_SCNHDR_NLNNO (abfd, 0xffff, scnhdr_ext->s_nlnno); 168 ret = 0; 169 } 170 171 /* Although we could encode 0xffff relocs here, we do not, to be 172 consistent with other parts of bfd. Also it lets us warn, as 173 we should never see 0xffff here w/o having the overflow flag 174 set. */ 175 if (scnhdr_int->s_nreloc < MAX_SCNHDR_NRELOC) 176 PUT_SCNHDR_NRELOC (abfd, scnhdr_int->s_nreloc, scnhdr_ext->s_nreloc); 177 else 178 { 179 /* DJGPP can deal with large #s of relocs, but not here. */ 180 PUT_SCNHDR_NRELOC (abfd, 0xffff, scnhdr_ext->s_nreloc); 181 scnhdr_int->s_flags |= IMAGE_SCN_LNK_NRELOC_OVFL; 182 PUT_SCNHDR_FLAGS (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags); 183 } 184 } 185 186 return ret; 187 } 188