00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #define TARGET_SYM go32stubbedcoff_vec
00038 #define TARGET_NAME "coff-go32-exe"
00039 #define TARGET_UNDERSCORE '_'
00040 #define COFF_GO32_EXE
00041 #define COFF_LONG_SECTION_NAMES
00042 #define COFF_SUPPORT_GNU_LINKONCE
00043 #define COFF_LONG_FILENAMES
00044
00045 #define COFF_SECTION_ALIGNMENT_ENTRIES \
00046 { COFF_SECTION_NAME_EXACT_MATCH (".data"), \
00047 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
00048 { COFF_SECTION_NAME_EXACT_MATCH (".text"), \
00049 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
00050 { COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \
00051 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
00052 { COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi"), \
00053 COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }
00054
00055 #include "bfd.h"
00056
00057
00058
00059 static void
00060 adjust_filehdr_in_post PARAMS ((bfd *, PTR, PTR));
00061 static void
00062 adjust_filehdr_out_pre PARAMS ((bfd *, PTR, PTR));
00063 static void
00064 adjust_filehdr_out_post PARAMS ((bfd *, PTR, PTR));
00065 static void
00066 adjust_scnhdr_in_post PARAMS ((bfd *, PTR, PTR));
00067 static void
00068 adjust_scnhdr_out_pre PARAMS ((bfd *, PTR, PTR));
00069 static void
00070 adjust_scnhdr_out_post PARAMS ((bfd *, PTR, PTR));
00071 static void
00072 adjust_aux_in_post PARAMS ((bfd *, PTR, int, int, int, int, PTR));
00073 static void
00074 adjust_aux_out_pre PARAMS ((bfd *, PTR, int, int, int, int, PTR));
00075 static void
00076 adjust_aux_out_post PARAMS ((bfd *, PTR, int, int, int, int, PTR));
00077 static void
00078 create_go32_stub PARAMS ((bfd *));
00079
00080
00081
00082
00083
00084 #define COFF_ADJUST_FILEHDR_IN_POST adjust_filehdr_in_post
00085 #define COFF_ADJUST_FILEHDR_OUT_PRE adjust_filehdr_out_pre
00086 #define COFF_ADJUST_FILEHDR_OUT_POST adjust_filehdr_out_post
00087
00088 #define COFF_ADJUST_SCNHDR_IN_POST adjust_scnhdr_in_post
00089 #define COFF_ADJUST_SCNHDR_OUT_PRE adjust_scnhdr_out_pre
00090 #define COFF_ADJUST_SCNHDR_OUT_POST adjust_scnhdr_out_post
00091
00092 #define COFF_ADJUST_AUX_IN_POST adjust_aux_in_post
00093 #define COFF_ADJUST_AUX_OUT_PRE adjust_aux_out_pre
00094 #define COFF_ADJUST_AUX_OUT_POST adjust_aux_out_post
00095
00096 static bfd_boolean
00097 go32_stubbed_coff_bfd_copy_private_bfd_data PARAMS ((bfd *, bfd *));
00098
00099 #define coff_bfd_copy_private_bfd_data go32_stubbed_coff_bfd_copy_private_bfd_data
00100
00101 #include "coff-i386.c"
00102
00103
00104 #define bfd_coff_go32stub bfd_usrdata
00105
00106
00107
00108 #define _H(index) (H_GET_16 (abfd, (header+index*2)))
00109
00110
00111
00112
00113 static const unsigned char stub_bytes[STUBSIZE] =
00114 {
00115 #include "go32stub.h"
00116 };
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 #define ADJUST_VAL(val,diff) \
00129 if (val != 0) val += diff
00130
00131 static void
00132 adjust_filehdr_in_post (abfd, src, dst)
00133 bfd *abfd;
00134 PTR src;
00135 PTR dst;
00136 {
00137 FILHDR *filehdr_src = (FILHDR *) src;
00138 struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
00139
00140 ADJUST_VAL (filehdr_dst->f_symptr, STUBSIZE);
00141
00142
00143 bfd_coff_go32stub (abfd) = (PTR) bfd_alloc (abfd, (bfd_size_type) STUBSIZE);
00144
00145
00146
00147
00148
00149 if (bfd_coff_go32stub (abfd) == NULL)
00150 return;
00151 memcpy (bfd_coff_go32stub (abfd), filehdr_src->stub, STUBSIZE);
00152 }
00153
00154 static void
00155 adjust_filehdr_out_pre (abfd, in, out)
00156 bfd *abfd;
00157 PTR in;
00158 PTR out;
00159 {
00160 struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
00161 FILHDR *filehdr_out = (FILHDR *) out;
00162
00163
00164 create_go32_stub (abfd);
00165
00166
00167 if (bfd_coff_go32stub (abfd) != NULL)
00168 memcpy (filehdr_out->stub, bfd_coff_go32stub (abfd), STUBSIZE);
00169 else
00170
00171 memcpy (filehdr_out->stub, stub_bytes, STUBSIZE);
00172
00173 ADJUST_VAL (filehdr_in->f_symptr, -STUBSIZE);
00174 }
00175
00176 static void
00177 adjust_filehdr_out_post (abfd, in, out)
00178 bfd *abfd ATTRIBUTE_UNUSED;
00179 PTR in;
00180 PTR out ATTRIBUTE_UNUSED;
00181 {
00182 struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
00183
00184 ADJUST_VAL (filehdr_in->f_symptr, STUBSIZE);
00185 }
00186
00187 static void
00188 adjust_scnhdr_in_post (abfd, ext, in)
00189 bfd *abfd ATTRIBUTE_UNUSED;
00190 PTR ext ATTRIBUTE_UNUSED;
00191 PTR in;
00192 {
00193 struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
00194
00195 ADJUST_VAL (scnhdr_int->s_scnptr, STUBSIZE);
00196 ADJUST_VAL (scnhdr_int->s_relptr, STUBSIZE);
00197 ADJUST_VAL (scnhdr_int->s_lnnoptr, STUBSIZE);
00198 }
00199
00200 static void
00201 adjust_scnhdr_out_pre (abfd, in, out)
00202 bfd *abfd ATTRIBUTE_UNUSED;
00203 PTR in;
00204 PTR out ATTRIBUTE_UNUSED;
00205 {
00206 struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
00207
00208 ADJUST_VAL (scnhdr_int->s_scnptr, -STUBSIZE);
00209 ADJUST_VAL (scnhdr_int->s_relptr, -STUBSIZE);
00210 ADJUST_VAL (scnhdr_int->s_lnnoptr, -STUBSIZE);
00211 }
00212
00213 static void
00214 adjust_scnhdr_out_post (abfd, in, out)
00215 bfd *abfd ATTRIBUTE_UNUSED;
00216 PTR in;
00217 PTR out ATTRIBUTE_UNUSED;
00218 {
00219 struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
00220
00221 ADJUST_VAL (scnhdr_int->s_scnptr, STUBSIZE);
00222 ADJUST_VAL (scnhdr_int->s_relptr, STUBSIZE);
00223 ADJUST_VAL (scnhdr_int->s_lnnoptr, STUBSIZE);
00224 }
00225
00226 static void
00227 adjust_aux_in_post (abfd, ext1, type, class, indx, numaux, in1)
00228 bfd *abfd ATTRIBUTE_UNUSED;
00229 PTR ext1 ATTRIBUTE_UNUSED;
00230 int type;
00231 int class;
00232 int indx ATTRIBUTE_UNUSED;
00233 int numaux ATTRIBUTE_UNUSED;
00234 PTR in1;
00235 {
00236 union internal_auxent *in = (union internal_auxent *) in1;
00237
00238 if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
00239 {
00240 ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, STUBSIZE);
00241 }
00242 }
00243
00244 static void
00245 adjust_aux_out_pre (abfd, inp, type, class, indx, numaux, extp)
00246 bfd *abfd ATTRIBUTE_UNUSED;
00247 PTR inp;
00248 int type;
00249 int class;
00250 int indx ATTRIBUTE_UNUSED;
00251 int numaux ATTRIBUTE_UNUSED;
00252 PTR extp ATTRIBUTE_UNUSED;
00253 {
00254 union internal_auxent *in = (union internal_auxent *) inp;
00255
00256 if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
00257 {
00258 ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, -STUBSIZE);
00259 }
00260 }
00261
00262 static void
00263 adjust_aux_out_post (abfd, inp, type, class, indx, numaux, extp)
00264 bfd *abfd ATTRIBUTE_UNUSED;
00265 PTR inp;
00266 int type;
00267 int class;
00268 int indx ATTRIBUTE_UNUSED;
00269 int numaux ATTRIBUTE_UNUSED;
00270 PTR extp ATTRIBUTE_UNUSED;
00271 {
00272 union internal_auxent *in = (union internal_auxent *) inp;
00273
00274 if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
00275 {
00276 ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, STUBSIZE);
00277 }
00278 }
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292 static void
00293 create_go32_stub (abfd)
00294 bfd *abfd;
00295 {
00296
00297 if (bfd_coff_go32stub (abfd) == NULL)
00298 {
00299 char *stub;
00300 struct stat st;
00301 int f;
00302 unsigned char header[10];
00303 char magic[8];
00304 unsigned long coff_start;
00305 long exe_start;
00306
00307
00308 stub = getenv ("GO32STUB");
00309
00310 if (stub == NULL)
00311 stub = getenv ("STUB");
00312 if (stub == NULL)
00313 goto stub_end;
00314 if (stat (stub, &st) != 0)
00315 goto stub_end;
00316 #ifdef O_BINARY
00317 f = open (stub, O_RDONLY | O_BINARY);
00318 #else
00319 f = open (stub, O_RDONLY);
00320 #endif
00321 if (f < 0)
00322 goto stub_end;
00323 if (read (f, &header, sizeof (header)) < 0)
00324 {
00325 close (f);
00326 goto stub_end;
00327 }
00328 if (_H (0) != 0x5a4d)
00329 {
00330 close (f);
00331 goto stub_end;
00332 }
00333
00334
00335 coff_start = (long) _H (2) * 512L;
00336 if (_H (1))
00337 coff_start += (long) _H (1) - 512L;
00338
00339
00340
00341 if (coff_start != 2048)
00342 {
00343 close (f);
00344 goto stub_end;
00345 }
00346 exe_start = _H (4) * 16;
00347 if ((long) lseek (f, exe_start, SEEK_SET) != exe_start)
00348 {
00349 close (f);
00350 goto stub_end;
00351 }
00352 if (read (f, &magic, 8) != 8)
00353 {
00354 close (f);
00355 goto stub_end;
00356 }
00357 if (memcmp (magic, "go32stub", 8) != 0)
00358 {
00359 close (f);
00360 goto stub_end;
00361 }
00362
00363 bfd_coff_go32stub (abfd)
00364 = (PTR) bfd_alloc (abfd, (bfd_size_type) coff_start);
00365 if (bfd_coff_go32stub (abfd) == NULL)
00366 {
00367 close (f);
00368 return;
00369 }
00370 lseek (f, 0L, SEEK_SET);
00371 if ((unsigned long) read (f, bfd_coff_go32stub (abfd), coff_start)
00372 != coff_start)
00373 {
00374 bfd_release (abfd, bfd_coff_go32stub (abfd));
00375 bfd_coff_go32stub (abfd) = NULL;
00376 }
00377 close (f);
00378 }
00379 stub_end:
00380
00381
00382 if (bfd_coff_go32stub (abfd) == NULL)
00383 {
00384 bfd_coff_go32stub (abfd)
00385 = (PTR) bfd_alloc (abfd, (bfd_size_type) STUBSIZE);
00386 if (bfd_coff_go32stub (abfd) == NULL)
00387 return;
00388 memcpy (bfd_coff_go32stub (abfd), stub_bytes, STUBSIZE);
00389 }
00390 }
00391
00392
00393
00394
00395 static bfd_boolean
00396 go32_stubbed_coff_bfd_copy_private_bfd_data (ibfd, obfd)
00397 bfd *ibfd;
00398 bfd *obfd;
00399 {
00400
00401 if (ibfd->xvec != obfd->xvec)
00402 return TRUE;
00403
00404
00405 if (bfd_coff_go32stub (ibfd) == NULL
00406 || bfd_coff_go32stub (obfd) == NULL)
00407 return TRUE;
00408
00409
00410 memcpy (bfd_coff_go32stub (obfd), bfd_coff_go32stub (ibfd), STUBSIZE);
00411
00412 return TRUE;
00413 }