Coverage Report

Created: 2025-06-24 06:45

/src/binutils-gdb/bfd/coff-go32.c
Line
Count
Source (jump to first uncovered line)
1
/* BFD back-end for Intel 386 COFF files (DJGPP variant).
2
   Copyright (C) 1990-2025 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
5.17M
#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
68.9k
#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
72.3k
{
75
72.3k
  const bfd_size_type amt = sizeof (coff_data_type);
76
77
72.3k
  abfd->tdata.coff_obj_data = bfd_zalloc (abfd, amt);
78
72.3k
  if (abfd->tdata.coff_obj_data == NULL)
79
0
    return false;
80
81
72.3k
  coff_data (abfd)->go32 = true;
82
83
72.3k
  bfd_coff_long_section_names (abfd)
84
72.3k
    = coff_backend_info (abfd)->_bfd_coff_long_section_names;
85
86
72.3k
  return true;
87
72.3k
}
88
89
void
90
_bfd_go32_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
91
6.37M
{
92
6.37M
  SCNHDR *scnhdr_ext = (SCNHDR *) ext;
93
6.37M
  struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
94
95
6.37M
  memcpy (scnhdr_int->s_name, scnhdr_ext->s_name, sizeof (scnhdr_int->s_name));
96
97
6.37M
  scnhdr_int->s_vaddr = GET_SCNHDR_VADDR (abfd, scnhdr_ext->s_vaddr);
98
6.37M
  scnhdr_int->s_paddr = GET_SCNHDR_PADDR (abfd, scnhdr_ext->s_paddr);
99
6.37M
  scnhdr_int->s_size = GET_SCNHDR_SIZE (abfd, scnhdr_ext->s_size);
100
101
6.37M
  scnhdr_int->s_scnptr = GET_SCNHDR_SCNPTR (abfd, scnhdr_ext->s_scnptr);
102
6.37M
  scnhdr_int->s_relptr = GET_SCNHDR_RELPTR (abfd, scnhdr_ext->s_relptr);
103
6.37M
  scnhdr_int->s_lnnoptr = GET_SCNHDR_LNNOPTR (abfd, scnhdr_ext->s_lnnoptr);
104
6.37M
  scnhdr_int->s_flags = GET_SCNHDR_FLAGS (abfd, scnhdr_ext->s_flags);
105
6.37M
  scnhdr_int->s_nreloc = GET_SCNHDR_NRELOC (abfd, scnhdr_ext->s_nreloc);
106
6.37M
  scnhdr_int->s_nlnno = GET_SCNHDR_NLNNO (abfd, scnhdr_ext->s_nlnno);
107
108
  /* DJGPP follows the same strategy as PE COFF.
109
     Iff the file is an executable then the higher 16 bits
110
     of the line number have been stored in the relocation
111
     counter field.  */
112
6.37M
  if (abfd->flags & EXEC_P && (strcmp (scnhdr_ext->s_name, ".text") == 0))
113
4.28k
    {
114
4.28k
      scnhdr_int->s_nlnno
115
4.28k
  = (GET_SCNHDR_NRELOC (abfd, scnhdr_ext->s_nreloc) << 16)
116
4.28k
    + GET_SCNHDR_NLNNO (abfd, scnhdr_ext->s_nlnno);
117
4.28k
      scnhdr_int->s_nreloc = 0;
118
4.28k
    }
119
6.37M
}
120
121
unsigned int
122
_bfd_go32_swap_scnhdr_out (bfd * abfd, void * in, void * out)
123
0
{
124
0
  struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
125
0
  SCNHDR *scnhdr_ext = (SCNHDR *) out;
126
0
  unsigned int ret = bfd_coff_scnhsz (abfd);
127
128
0
  memcpy (scnhdr_ext->s_name, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
129
130
0
  PUT_SCNHDR_VADDR (abfd, scnhdr_int->s_vaddr, scnhdr_ext->s_vaddr);
131
0
  PUT_SCNHDR_PADDR (abfd, scnhdr_int->s_paddr, scnhdr_ext->s_paddr);
132
0
  PUT_SCNHDR_SIZE (abfd, scnhdr_int->s_size, scnhdr_ext->s_size);
133
0
  PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr, scnhdr_ext->s_scnptr);
134
0
  PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr, scnhdr_ext->s_relptr);
135
0
  PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr, scnhdr_ext->s_lnnoptr);
136
0
  PUT_SCNHDR_FLAGS (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
137
138
0
  if (abfd->flags & EXEC_P && (strcmp (scnhdr_int->s_name, ".text") == 0))
139
0
    {
140
      /* DJGPP follows the same strategy as PE COFF.
141
   By inference from looking at MS output, the 32 bit field
142
   which is the combination of the number_of_relocs and
143
   number_of_linenos is used for the line number count in
144
   executables.  A 16-bit field won't do for cc1.  The MS
145
   document says that the number of relocs is zero for
146
   executables, but the 17-th bit has been observed to be there.
147
   Overflow is not an issue: a 4G-line program will overflow a
148
   bunch of other fields long before this!  */
149
0
      PUT_SCNHDR_NLNNO (abfd, (scnhdr_int->s_nlnno & 0xffff),
150
0
      scnhdr_ext->s_nlnno);
151
0
      PUT_SCNHDR_NRELOC (abfd, (scnhdr_int->s_nlnno >> 16),
152
0
       scnhdr_ext->s_nreloc);
153
0
    }
154
0
  else
155
0
    {
156
      /* DJGPP follows the same strategy as PE COFF.  */
157
0
      if (scnhdr_int->s_nlnno <= MAX_SCNHDR_NLNNO)
158
0
  PUT_SCNHDR_NLNNO (abfd, scnhdr_int->s_nlnno, scnhdr_ext->s_nlnno);
159
0
      else
160
0
  {
161
0
    char buf[sizeof (scnhdr_int->s_name) + 1];
162
163
0
    memcpy (buf, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
164
0
    buf[sizeof (scnhdr_int->s_name)] = '\0';
165
0
    _bfd_error_handler
166
      /* xgettext:c-format */
167
0
      (_("%pB: warning: %s: line number overflow: 0x%lx > 0xffff"),
168
0
       abfd, buf, scnhdr_int->s_nlnno);
169
0
    bfd_set_error (bfd_error_file_truncated);
170
0
    PUT_SCNHDR_NLNNO (abfd, 0xffff, scnhdr_ext->s_nlnno);
171
0
    ret = 0;
172
0
  }
173
174
      /* Although we could encode 0xffff relocs here, we do not, to be
175
   consistent with other parts of bfd.  Also it lets us warn, as
176
   we should never see 0xffff here w/o having the overflow flag
177
   set.  */
178
0
      if (scnhdr_int->s_nreloc < MAX_SCNHDR_NRELOC)
179
0
  PUT_SCNHDR_NRELOC (abfd, scnhdr_int->s_nreloc, scnhdr_ext->s_nreloc);
180
0
      else
181
0
  {
182
    /* DJGPP can deal with large #s of relocs, but not here.  */
183
0
    PUT_SCNHDR_NRELOC (abfd, 0xffff, scnhdr_ext->s_nreloc);
184
0
    scnhdr_int->s_flags |= IMAGE_SCN_LNK_NRELOC_OVFL;
185
0
    PUT_SCNHDR_FLAGS (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
186
0
  }
187
0
    }
188
189
0
  return ret;
190
0
}