1 /* Binutils emulation layer.
2    Copyright (C) 2002-2021 Free Software Foundation, Inc.
3    Written by Tom Rix, Red Hat Inc.
4 
5    This file is part of GNU Binutils.
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 #include "binemul.h"
23 #include "bfdlink.h"
24 #include "coff/internal.h"
25 #include "coff/xcoff.h"
26 #include "libcoff.h"
27 #include "libxcoff.h"
28 
29 /* Default to <bigaf>.  */
30 /* FIXME: write only variable.  */
31 static bool big_archive = true;
32 
33 /* Whether to include 32 bit objects.  */
34 static bool X32 = true;
35 
36 /* Whether to include 64 bit objects.  */
37 static bool X64 = false;
38 
39 static void
ar_emul_aix_usage(FILE * fp)40 ar_emul_aix_usage (FILE *fp)
41 {
42   AR_EMUL_USAGE_PRINT_OPTION_HEADER (fp);
43   /* xgettext:c-format */
44   fprintf (fp, _("  [-g]         - 32 bit small archive\n"));
45   fprintf (fp, _("  [-X32]       - ignores 64 bit objects\n"));
46   fprintf (fp, _("  [-X64]       - ignores 32 bit objects\n"));
47   fprintf (fp, _("  [-X32_64]    - accepts 32 and 64 bit objects\n"));
48 }
49 
50 static bool
check_aix(bfd * try_bfd)51 check_aix (bfd *try_bfd)
52 {
53   extern const bfd_target rs6000_xcoff_vec;
54   extern const bfd_target rs6000_xcoff64_vec;
55   extern const bfd_target rs6000_xcoff64_aix_vec;
56 
57   if (bfd_check_format (try_bfd, bfd_object))
58     {
59       if (!X32 && try_bfd->xvec == &rs6000_xcoff_vec)
60 	return false;
61 
62       if (!X64 && (try_bfd->xvec == &rs6000_xcoff64_vec
63 		   || try_bfd->xvec == &rs6000_xcoff64_aix_vec))
64 	return false;
65     }
66   return true;
67 }
68 
69 static bool
ar_emul_aix_append(bfd ** after_bfd,bfd * new_bfd,bool verbose,bool flatten)70 ar_emul_aix_append (bfd **after_bfd, bfd *new_bfd,
71 		    bool verbose, bool flatten)
72 {
73   return do_ar_emul_append (after_bfd, new_bfd, verbose, flatten, check_aix);
74 }
75 
76 static bool
ar_emul_aix_replace(bfd ** after_bfd,bfd * new_bfd,bool verbose)77 ar_emul_aix_replace (bfd **after_bfd, bfd *new_bfd,
78 		     bool verbose)
79 {
80   if (!check_aix (new_bfd))
81     return false;
82 
83   AR_EMUL_REPLACE_PRINT_VERBOSE (verbose, bfd_get_filename (new_bfd));
84 
85   new_bfd->archive_next = *after_bfd;
86   *after_bfd = new_bfd;
87 
88   return true;
89 }
90 
91 static bool
ar_emul_aix_parse_arg(char * arg)92 ar_emul_aix_parse_arg (char *arg)
93 {
94   if (startswith (arg, "-X32_64"))
95     {
96       big_archive = true;
97       X32 = true;
98       X64 = true;
99     }
100   else if (startswith (arg, "-X32"))
101     {
102       big_archive = true;
103       X32 = true;
104       X64 = false;
105     }
106   else if (startswith (arg, "-X64"))
107     {
108       big_archive = true;
109       X32 = false;
110       X64 = true;
111     }
112   else if (startswith (arg, "-g"))
113     {
114       big_archive = false;
115       X32 = true;
116       X64 = false;
117     }
118   else
119     return false;
120 
121   return true;
122 }
123 
124 struct bin_emulation_xfer_struct bin_aix_emulation =
125 {
126   ar_emul_aix_usage,
127   ar_emul_aix_append,
128   ar_emul_aix_replace,
129   ar_emul_aix_parse_arg,
130 };
131