Commit | Line | Data |
---|---|---|
3d3c5039 | 1 | /* ECOFF object file format. |
5a051773 | 2 | Copyright (C) 1993, 1994 Free Software Foundation, Inc. |
3d3c5039 | 3 | Contributed by Cygnus Support. |
c5953036 | 4 | This file was put together by Ian Lance Taylor <ian@cygnus.com>. |
3d3c5039 ILT |
5 | |
6 | This file is part of GAS. | |
7 | ||
8 | GAS is free software; you can redistribute it and/or modify | |
9 | it under the terms of the GNU General Public License as published by | |
10 | the Free Software Foundation; either version 2, or (at your option) | |
11 | any later version. | |
12 | ||
13 | GAS is distributed in the hope that it will be useful, | |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | GNU General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
19 | along with GAS; see the file COPYING. If not, write to | |
20 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
21 | ||
22 | #include "as.h" | |
23 | #include "coff/internal.h" | |
5a051773 SS |
24 | #include "bfd/libcoff.h" |
25 | #include "bfd/libecoff.h" | |
3d3c5039 | 26 | |
c5953036 ILT |
27 | /* Almost all of the ECOFF support is actually in ecoff.c in the main |
28 | gas directory. This file mostly just arranges to call that one at | |
29 | the right times. */ | |
670a50eb | 30 | |
c5953036 ILT |
31 | /* These are the pseudo-ops we support in this file. Only those |
32 | relating to debugging information are supported here. | |
3d3c5039 | 33 | |
c5953036 ILT |
34 | The following pseudo-ops from the Kane and Heinrich MIPS book |
35 | should be defined here, but are currently unsupported: .aent, | |
36 | .bgnb, .endb, .verstamp, .vreg. | |
3d3c5039 | 37 | |
c5953036 ILT |
38 | The following pseudo-ops from the Kane and Heinrich MIPS book are |
39 | MIPS CPU specific, and should be defined by tc-mips.c: .alias, | |
40 | .extern, .galive, .gjaldef, .gjrlive, .livereg, .noalias, .option, | |
41 | .rdata, .sdata, .set. | |
3d3c5039 | 42 | |
c5953036 ILT |
43 | The following pseudo-ops from the Kane and Heinrich MIPS book are |
44 | not MIPS CPU specific, but are also not ECOFF specific. I have | |
45 | only listed the ones which are not already in read.c. It's not | |
46 | completely clear where these should be defined, but tc-mips.c is | |
47 | probably the most reasonable place: .asciiz, .asm0, .endr, .err, | |
48 | .half, .lab, .repeat, .struct, .weakext. */ | |
3d3c5039 | 49 | |
c5953036 | 50 | const pseudo_typeS obj_pseudo_table[] = |
3d3c5039 | 51 | { |
c5953036 ILT |
52 | /* COFF style debugging information. .ln is not used; .loc is used |
53 | instead. */ | |
54 | { "def", ecoff_directive_def, 0 }, | |
55 | { "dim", ecoff_directive_dim, 0 }, | |
56 | { "endef", ecoff_directive_endef, 0 }, | |
57 | { "file", ecoff_directive_file, 0 }, | |
58 | { "scl", ecoff_directive_scl, 0 }, | |
59 | { "size", ecoff_directive_size, 0 }, | |
60 | { "tag", ecoff_directive_tag, 0 }, | |
61 | { "type", ecoff_directive_type, 0 }, | |
62 | { "val", ecoff_directive_val, 0 }, | |
3d3c5039 | 63 | |
c5953036 ILT |
64 | /* ECOFF specific debugging information. */ |
65 | { "begin", ecoff_directive_begin, 0 }, | |
66 | { "bend", ecoff_directive_bend, 0 }, | |
67 | { "end", ecoff_directive_end, 0 }, | |
68 | { "ent", ecoff_directive_ent, 0 }, | |
69 | { "fmask", ecoff_directive_fmask, 0 }, | |
70 | { "frame", ecoff_directive_frame, 0 }, | |
71 | { "loc", ecoff_directive_loc, 0 }, | |
72 | { "mask", ecoff_directive_mask, 0 }, | |
73 | ||
74 | /* These are used on Irix. I don't know how to implement them. */ | |
75 | { "bgnb", s_ignore, 0 }, | |
76 | { "endb", s_ignore, 0 }, | |
77 | { "verstamp", s_ignore, 0 }, | |
3d3c5039 | 78 | |
c5953036 ILT |
79 | /* Sentinel. */ |
80 | { NULL } | |
81 | }; | |
3d3c5039 | 82 | |
3d3c5039 ILT |
83 | /* Swap out the symbols and debugging information for BFD. */ |
84 | ||
85 | void | |
86 | ecoff_frob_file () | |
87 | { | |
c5953036 ILT |
88 | const struct ecoff_debug_swap * const debug_swap |
89 | = &ecoff_backend (stdoutput)->debug_swap; | |
918692a5 ILT |
90 | bfd_vma addr; |
91 | asection *sec; | |
3d3c5039 ILT |
92 | HDRR *hdr; |
93 | char *buf; | |
3d3c5039 ILT |
94 | char *set; |
95 | ||
918692a5 ILT |
96 | /* Set the section VMA values. */ |
97 | addr = 0; | |
98 | for (sec = stdoutput->sections; sec != (asection *) NULL; sec = sec->next) | |
99 | { | |
100 | bfd_set_section_vma (stdoutput, sec, addr); | |
101 | addr += bfd_section_size (stdoutput, sec); | |
102 | } | |
103 | ||
c5953036 ILT |
104 | /* Build the ECOFF debugging information. */ |
105 | hdr = &ecoff_data (stdoutput)->debug_info.symbolic_header; | |
106 | ecoff_build_debug (hdr, &buf, debug_swap); | |
3d3c5039 | 107 | |
c5953036 | 108 | /* Finish up the ecoff_tdata structure. */ |
3d3c5039 | 109 | set = buf; |
4573d186 | 110 | #define SET(ptr, count, type, size) \ |
c5953036 ILT |
111 | if (hdr->count == 0) \ |
112 | ecoff_data (stdoutput)->debug_info.ptr = (type) NULL; \ | |
113 | else \ | |
114 | { \ | |
115 | ecoff_data (stdoutput)->debug_info.ptr = (type) set; \ | |
116 | set += hdr->count * size; \ | |
117 | } | |
4573d186 ILT |
118 | |
119 | SET (line, cbLine, unsigned char *, sizeof (unsigned char)); | |
c5953036 ILT |
120 | SET (external_dnr, idnMax, PTR, debug_swap->external_dnr_size); |
121 | SET (external_pdr, ipdMax, PTR, debug_swap->external_pdr_size); | |
122 | SET (external_sym, isymMax, PTR, debug_swap->external_sym_size); | |
123 | SET (external_opt, ioptMax, PTR, debug_swap->external_opt_size); | |
4573d186 ILT |
124 | SET (external_aux, iauxMax, union aux_ext *, sizeof (union aux_ext)); |
125 | SET (ss, issMax, char *, sizeof (char)); | |
126 | SET (ssext, issExtMax, char *, sizeof (char)); | |
c5953036 ILT |
127 | SET (external_rfd, crfd, PTR, debug_swap->external_rfd_size); |
128 | SET (external_fdr, ifdMax, PTR, debug_swap->external_fdr_size); | |
129 | SET (external_ext, iextMax, PTR, debug_swap->external_ext_size); | |
3d3c5039 ILT |
130 | |
131 | #undef SET | |
132 | ||
f37449aa ILT |
133 | /* Fill in the register masks. */ |
134 | { | |
135 | asection *regsec; | |
136 | struct ecoff_reginfo s; | |
137 | ||
138 | regsec = bfd_make_section (stdoutput, REGINFO); | |
139 | know (regsec != NULL); | |
140 | ||
141 | if (bfd_get_section_contents (stdoutput, regsec, (PTR) &s, | |
142 | (file_ptr) 0, sizeof s) == false) | |
143 | as_fatal ("Can't read REGINFO section"); | |
144 | ||
1aa6938e | 145 | #ifdef TC_MIPS |
f37449aa ILT |
146 | /* Fill in the MIPS register masks. It's probably not worth |
147 | setting up a generic interface for this. */ | |
148 | s.gprmask = mips_gprmask; | |
149 | s.cprmask[0] = mips_cprmask[0]; | |
150 | s.cprmask[1] = mips_cprmask[1]; | |
151 | s.cprmask[2] = mips_cprmask[2]; | |
152 | s.cprmask[3] = mips_cprmask[3]; | |
1aa6938e | 153 | #endif |
3d3c5039 | 154 | |
f37449aa ILT |
155 | if (bfd_set_section_contents (stdoutput, regsec, (PTR) &s, |
156 | (file_ptr) 0, sizeof s) == false) | |
157 | as_fatal ("Can't write REGINFO section"); | |
158 | } | |
3d3c5039 | 159 | } |
3d3c5039 | 160 | |
c5953036 ILT |
161 | /* This is called by the ECOFF code to set the external information |
162 | for a symbol. We just pass it on to BFD, which expects the swapped | |
163 | information to be stored in the native field of the symbol. */ | |
3d3c5039 | 164 | |
c5953036 ILT |
165 | void |
166 | obj_ecoff_set_ext (sym, ext) | |
167 | symbolS *sym; | |
168 | EXTR *ext; | |
169 | { | |
170 | const struct ecoff_debug_swap * const debug_swap | |
171 | = &ecoff_backend (stdoutput)->debug_swap; | |
172 | ecoff_symbol_type *esym; | |
173 | ||
174 | know (bfd_asymbol_flavour (sym->bsym) == bfd_target_ecoff_flavour); | |
175 | esym = ecoffsymbol (sym->bsym); | |
176 | esym->local = false; | |
177 | esym->native = xmalloc (debug_swap->external_ext_size); | |
178 | (*debug_swap->swap_ext_out) (stdoutput, ext, esym->native); | |
3d3c5039 | 179 | } |