1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
# This shell script emits C code -*- C -*-
# to keep track of the machine type of Z80 object files
# It does some substitutions.
# Copyright (C) 2005-2020 Free Software Foundation, Inc.
# This file is part of the GNU Binutils.
#
# 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.
LDEMUL_BEFORE_PARSE=gldz80_before_parse
LDEMUL_RECOGNIZED_FILE=gldz80_recognized_file
LDEMUL_AFTER_OPEN=gldz80_after_open
fragment <<EOF
/* --- \begin{z80.em} */
/* Codes for machine types, bitwise or gives the code to use for the
output. */
#define M_Z80STRICT 0x01
#define M_Z80 0x03
#define M_Z80FULL 0x07
#define M_R800 0x10
#define M_Z80ANY 0x0f
#define M_GBZ80 0x20
#define M_Z180 0x40
#define M_EZ80_Z80 0x80
#define M_EZ80_ADL 0x100
#define M_ARCH_MASK 0xFF0
/* Bitwise or of the machine types seen so far. */
static int result_mach_type;
static void
${LDEMUL_BEFORE_PARSE} (void)
{
#ifndef TARGET_ /* I.e., if not generic. */
ldfile_set_output_arch ("`echo ${ARCH}`", bfd_arch_unknown);
#endif /* not TARGET_ */
result_mach_type = 0;
}
/* Update result_mach_type. */
static bfd_boolean
${LDEMUL_RECOGNIZED_FILE} (lang_input_statement_type *entry)
{
unsigned long mach_type;
mach_type = bfd_get_mach (entry->the_bfd);
switch (mach_type)
{
case bfd_mach_z80strict:
result_mach_type |= M_Z80STRICT;
break;
case bfd_mach_z80:
result_mach_type |= M_Z80;
break;
case bfd_mach_z80full:
result_mach_type |= M_Z80FULL;
break;
case bfd_mach_r800:
result_mach_type |= M_R800;
break;
case bfd_mach_gbz80:
result_mach_type |= M_GBZ80;
break;
case bfd_mach_z180:
result_mach_type |= M_Z180;
break;
case bfd_mach_ez80_z80:
result_mach_type |= M_EZ80_Z80;
break;
case bfd_mach_ez80_adl:
result_mach_type |= M_EZ80_ADL;
break;
default:
einfo (_("%P: warning: unknown machine type %u"), (unsigned)mach_type);
result_mach_type |= M_Z80ANY;
}
return FALSE;
}
/* Set the machine type of the output file based on result_mach_type. */
static void
gldz80_after_open (void)
{
unsigned long mach_type;
after_open_default ();
switch (result_mach_type & M_ARCH_MASK)
{
case M_Z80 & M_ARCH_MASK:
case M_R800:
case M_Z180:
case M_GBZ80:
case M_EZ80_Z80:
case M_EZ80_ADL:
case M_EZ80_Z80 | M_Z180:
/* valid combination */
break;
case M_EZ80_Z80 | M_EZ80_ADL:
case M_EZ80_Z80 | M_EZ80_ADL | M_Z180:
case M_EZ80_ADL | M_Z180:
/* combination may cause invalid objdump output */
/* but it is possible for mixed ADL/Z80 code */
einfo (_("%P: warning: mixing ADL and Z80 mode binaries, objdump may generate invalid output"));
break;
default:
/* invalid combination: for example Z180 + R800 */
einfo (_("%P: warning: incompatible object files linked, result code might not work"));
}
if ((result_mach_type & M_EZ80_ADL) == M_EZ80_ADL)
mach_type = bfd_mach_ez80_adl;
else if ((result_mach_type & M_EZ80_Z80) == M_EZ80_Z80)
mach_type = bfd_mach_ez80_z80;
else if ((result_mach_type & M_Z180) == M_Z180)
mach_type = bfd_mach_z180;
else if ((result_mach_type & M_R800) == M_R800)
mach_type = bfd_mach_r800;
else if ((result_mach_type & M_GBZ80) == M_GBZ80)
mach_type = bfd_mach_gbz80;
else if ((result_mach_type & M_Z80FULL) == M_Z80FULL)
mach_type = bfd_mach_z80full; /* TODO: remove it */
else if ((result_mach_type & M_Z80) == M_Z80)
mach_type = bfd_mach_z80;
else if ((result_mach_type & M_Z80STRICT) == M_Z80STRICT)
mach_type = bfd_mach_z80strict; /* TODO: remove this */
else
mach_type = bfd_arch_unknown;
bfd_set_arch_mach (link_info.output_bfd, bfd_arch_z80, mach_type);
}
/* --- \end{z80.em} */
EOF
|