~terry.guo/+junk/xbinutils

« back to all changes in this revision

Viewing changes to src/binutils/gas/config/obj-ecoff.c

  • Committer: Terry Guo
  • Date: 2012-09-05 06:50:40 UTC
  • Revision ID: terry.guo@arm.com-20120905065040-430c6mhm9b11a6r6
Tags: upstream-1.0
ImportĀ upstreamĀ versionĀ 1.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ECOFF object file format.
 
2
   Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002,
 
3
   2005, 2007, 2009, 2010  Free Software Foundation, Inc.
 
4
   Contributed by Cygnus Support.
 
5
   This file was put together by Ian Lance Taylor <ian@cygnus.com>.
 
6
 
 
7
   This file is part of GAS.
 
8
 
 
9
   GAS is free software; you can redistribute it and/or modify
 
10
   it under the terms of the GNU General Public License as published by
 
11
   the Free Software Foundation; either version 3, or (at your option)
 
12
   any later version.
 
13
 
 
14
   GAS is distributed in the hope that it will be useful,
 
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
   GNU General Public License for more details.
 
18
 
 
19
   You should have received a copy of the GNU General Public License
 
20
   along with GAS; see the file COPYING.  If not, write to the Free
 
21
   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
 
22
   02110-1301, USA.  */
 
23
 
 
24
#define OBJ_HEADER "obj-ecoff.h"
 
25
#include "as.h"
 
26
#include "coff/internal.h"
 
27
#include "bfd/libcoff.h"
 
28
#include "bfd/libecoff.h"
 
29
 
 
30
/* Almost all of the ECOFF support is actually in ecoff.c in the main
 
31
   gas directory.  This file mostly just arranges to call that one at
 
32
   the right times.  */
 
33
 
 
34
/* Set section VMAs and GP values before reloc processing.  */
 
35
 
 
36
void
 
37
ecoff_frob_file_before_fix (void)
 
38
{
 
39
  bfd_vma addr;
 
40
  asection *sec;
 
41
 
 
42
  /* Set the section VMA values.  We force the .sdata and .sbss
 
43
     sections to the end to ensure that their VMA addresses are close
 
44
     together so that the GP register can address both of them.  We
 
45
     put the .bss section after the .sbss section.
 
46
 
 
47
     Also, for the Alpha, we must sort the sections, to make sure they
 
48
     appear in the output file in the correct order.  (Actually, maybe
 
49
     this is a job for BFD.  But the VMAs computed would be out of
 
50
     whack if we computed them given our initial, random ordering.
 
51
     It's possible that that wouldn't break things; I could do some
 
52
     experimenting sometime and find out.
 
53
 
 
54
     This output ordering of sections is magic, on the Alpha, at
 
55
     least.  The .lita section must come before .lit8 and .lit4,
 
56
     otherwise the OSF/1 linker may silently trash the .lit{4,8}
 
57
     section contents.  Also, .text must preceed .rdata.  These differ
 
58
     from the order described in some parts of the DEC OSF/1 Assembly
 
59
     Language Programmer's Guide, but that order doesn't seem to work
 
60
     with their linker.
 
61
 
 
62
     I don't know if section ordering on the MIPS is important.  */
 
63
 
 
64
  static const char *const names[] =
 
65
  {
 
66
    /* text segment */
 
67
    ".text", ".rdata", ".init", ".fini",
 
68
    /* data segment */
 
69
    ".data", ".lita", ".lit8", ".lit4", ".sdata", ".got",
 
70
    /* bss segment */
 
71
    ".sbss", ".bss",
 
72
  };
 
73
#define n_names ((int) (sizeof (names) / sizeof (names[0])))
 
74
 
 
75
  /* Sections that match names, order to be straightened out later.  */
 
76
  asection *secs[n_names];
 
77
  int i;
 
78
 
 
79
  addr = 0;
 
80
  for (i = 0; i < n_names; i++)
 
81
    secs[i] = NULL;
 
82
 
 
83
  for (sec = stdoutput->sections; sec != NULL; sec = sec->next)
 
84
    {
 
85
      for (i = 0; i < n_names; i++)
 
86
        if (!strcmp (sec->name, names[i]))
 
87
          {
 
88
            secs[i] = sec;
 
89
            bfd_section_list_remove (stdoutput, sec);
 
90
            break;
 
91
          }
 
92
      if (i == n_names)
 
93
        {
 
94
          bfd_set_section_vma (stdoutput, sec, addr);
 
95
          addr += bfd_section_size (stdoutput, sec);
 
96
        }
 
97
    }
 
98
  for (i = 0; i < n_names; i++)
 
99
    if (secs[i])
 
100
      {
 
101
        bfd_set_section_vma (stdoutput, secs[i], addr);
 
102
        addr += bfd_section_size (stdoutput, secs[i]);
 
103
      }
 
104
  for (i = n_names - 1; i >= 0; i--)
 
105
    if (secs[i])
 
106
      bfd_section_list_prepend (stdoutput, secs[i]);
 
107
 
 
108
  /* Fill in the register masks.  */
 
109
  {
 
110
    unsigned long gprmask = 0;
 
111
    unsigned long fprmask = 0;
 
112
    unsigned long *cprmask = NULL;
 
113
 
 
114
#ifdef TC_MIPS
 
115
    /* Fill in the MIPS register masks.  It's probably not worth
 
116
       setting up a generic interface for this.  */
 
117
    gprmask = mips_gprmask;
 
118
    cprmask = mips_cprmask;
 
119
#endif
 
120
 
 
121
#ifdef TC_ALPHA
 
122
    alpha_frob_ecoff_data ();
 
123
 
 
124
    if (! bfd_ecoff_set_gp_value (stdoutput, alpha_gp_value))
 
125
      as_fatal (_("Can't set GP value"));
 
126
 
 
127
    gprmask = alpha_gprmask;
 
128
    fprmask = alpha_fprmask;
 
129
#endif
 
130
 
 
131
    if (! bfd_ecoff_set_regmasks (stdoutput, gprmask, fprmask, cprmask))
 
132
      as_fatal (_("Can't set register masks"));
 
133
  }
 
134
}
 
135
 
 
136
/* Swap out the symbols and debugging information for BFD.  */
 
137
 
 
138
void
 
139
ecoff_frob_file (void)
 
140
{
 
141
  const struct ecoff_debug_swap * const debug_swap
 
142
    = &ecoff_backend (stdoutput)->debug_swap;
 
143
  bfd_vma addr ATTRIBUTE_UNUSED;
 
144
  HDRR *hdr;
 
145
  char *buf;
 
146
  char *set;
 
147
 
 
148
  /* Build the ECOFF debugging information.  */
 
149
  gas_assert (ecoff_data (stdoutput) != 0);
 
150
  hdr = &ecoff_data (stdoutput)->debug_info.symbolic_header;
 
151
  ecoff_build_debug (hdr, &buf, debug_swap);
 
152
 
 
153
  /* Finish up the ecoff_tdata structure.  */
 
154
  set = buf;
 
155
#define SET(ptr, count, type, size) \
 
156
  if (hdr->count == 0) \
 
157
    ecoff_data (stdoutput)->debug_info.ptr = NULL; \
 
158
  else \
 
159
    { \
 
160
      ecoff_data (stdoutput)->debug_info.ptr = (type) set; \
 
161
      set += hdr->count * size; \
 
162
    }
 
163
 
 
164
  SET (line, cbLine, unsigned char *, sizeof (unsigned char));
 
165
  SET (external_dnr, idnMax, void *, debug_swap->external_dnr_size);
 
166
  SET (external_pdr, ipdMax, void *, debug_swap->external_pdr_size);
 
167
  SET (external_sym, isymMax, void *, debug_swap->external_sym_size);
 
168
  SET (external_opt, ioptMax, void *, debug_swap->external_opt_size);
 
169
  SET (external_aux, iauxMax, union aux_ext *, sizeof (union aux_ext));
 
170
  SET (ss, issMax, char *, sizeof (char));
 
171
  SET (ssext, issExtMax, char *, sizeof (char));
 
172
  SET (external_rfd, crfd, void *, debug_swap->external_rfd_size);
 
173
  SET (external_fdr, ifdMax, void *, debug_swap->external_fdr_size);
 
174
  SET (external_ext, iextMax, void *, debug_swap->external_ext_size);
 
175
#undef SET
 
176
}
 
177
 
 
178
/* This is called by the ECOFF code to set the external information
 
179
   for a symbol.  We just pass it on to BFD, which expects the swapped
 
180
   information to be stored in the native field of the symbol.  */
 
181
 
 
182
void
 
183
obj_ecoff_set_ext (symbolS *sym, EXTR *ext)
 
184
{
 
185
  const struct ecoff_debug_swap * const debug_swap
 
186
    = &ecoff_backend (stdoutput)->debug_swap;
 
187
  ecoff_symbol_type *esym;
 
188
 
 
189
  know (bfd_asymbol_flavour (symbol_get_bfdsym (sym))
 
190
        == bfd_target_ecoff_flavour);
 
191
  esym = ecoffsymbol (symbol_get_bfdsym (sym));
 
192
  esym->local = FALSE;
 
193
  esym->native = xmalloc (debug_swap->external_ext_size);
 
194
  (*debug_swap->swap_ext_out) (stdoutput, ext, esym->native);
 
195
}
 
196
 
 
197
static int
 
198
ecoff_sec_sym_ok_for_reloc (asection *sec ATTRIBUTE_UNUSED)
 
199
{
 
200
  return 1;
 
201
}
 
202
 
 
203
static void
 
204
obj_ecoff_frob_symbol (symbolS *sym, int *puntp ATTRIBUTE_UNUSED)
 
205
{
 
206
  ecoff_frob_symbol (sym);
 
207
}
 
208
 
 
209
static void
 
210
ecoff_pop_insert (void)
 
211
{
 
212
  pop_insert (obj_pseudo_table);
 
213
}
 
214
 
 
215
static int
 
216
ecoff_separate_stab_sections (void)
 
217
{
 
218
  return 0;
 
219
}
 
220
 
 
221
/* These are the pseudo-ops we support in this file.  Only those
 
222
   relating to debugging information are supported here.
 
223
 
 
224
   The following pseudo-ops from the Kane and Heinrich MIPS book
 
225
   should be defined here, but are currently unsupported: .aent,
 
226
   .bgnb, .endb, .verstamp, .vreg.
 
227
 
 
228
   The following pseudo-ops from the Kane and Heinrich MIPS book are
 
229
   MIPS CPU specific, and should be defined by tc-mips.c: .alias,
 
230
   .extern, .galive, .gjaldef, .gjrlive, .livereg, .noalias, .option,
 
231
   .rdata, .sdata, .set.
 
232
 
 
233
   The following pseudo-ops from the Kane and Heinrich MIPS book are
 
234
   not MIPS CPU specific, but are also not ECOFF specific.  I have
 
235
   only listed the ones which are not already in read.c.  It's not
 
236
   completely clear where these should be defined, but tc-mips.c is
 
237
   probably the most reasonable place: .asciiz, .asm0, .endr, .err,
 
238
   .half, .lab, .repeat, .struct, .weakext.  */
 
239
 
 
240
const pseudo_typeS obj_pseudo_table[] =
 
241
{
 
242
  /* COFF style debugging information. .ln is not used; .loc is used
 
243
     instead.  */
 
244
  { "def",      ecoff_directive_def,    0 },
 
245
  { "dim",      ecoff_directive_dim,    0 },
 
246
  { "endef",    ecoff_directive_endef,  0 },
 
247
  { "file",     ecoff_directive_file,   0 },
 
248
  { "scl",      ecoff_directive_scl,    0 },
 
249
  { "size",     ecoff_directive_size,   0 },
 
250
  { "esize",    ecoff_directive_size,   0 },
 
251
  { "tag",      ecoff_directive_tag,    0 },
 
252
  { "type",     ecoff_directive_type,   0 },
 
253
  { "etype",    ecoff_directive_type,   0 },
 
254
  { "val",      ecoff_directive_val,    0 },
 
255
 
 
256
  /* ECOFF specific debugging information.  */
 
257
  { "begin",    ecoff_directive_begin,  0 },
 
258
  { "bend",     ecoff_directive_bend,   0 },
 
259
  { "end",      ecoff_directive_end,    0 },
 
260
  { "ent",      ecoff_directive_ent,    0 },
 
261
  { "fmask",    ecoff_directive_fmask,  0 },
 
262
  { "frame",    ecoff_directive_frame,  0 },
 
263
  { "loc",      ecoff_directive_loc,    0 },
 
264
  { "mask",     ecoff_directive_mask,   0 },
 
265
 
 
266
  /* Other ECOFF directives.  */
 
267
  { "extern",   ecoff_directive_extern, 0 },
 
268
 
 
269
#ifndef TC_MIPS
 
270
  /* For TC_MIPS, tc-mips.c adds this.  */
 
271
  { "weakext",  ecoff_directive_weakext, 0 },
 
272
#endif
 
273
 
 
274
  /* These are used on Irix.  I don't know how to implement them.  */
 
275
  { "bgnb",     s_ignore,               0 },
 
276
  { "endb",     s_ignore,               0 },
 
277
  { "verstamp", s_ignore,               0 },
 
278
 
 
279
  /* Sentinel.  */
 
280
  { NULL,       s_ignore,               0 }
 
281
};
 
282
 
 
283
const struct format_ops ecoff_format_ops =
 
284
{
 
285
  bfd_target_ecoff_flavour,
 
286
  0,    /* dfl_leading_underscore.  */
 
287
 
 
288
  /* FIXME: A comment why emit_section_symbols is different here (1) from
 
289
     the single-format definition (0) would be in order.  */
 
290
  1,    /* emit_section_symbols.  */
 
291
  0,    /* begin.  */
 
292
  ecoff_new_file,
 
293
  obj_ecoff_frob_symbol,
 
294
  ecoff_frob_file,
 
295
  0,    /* frob_file_before_adjust.  */
 
296
  ecoff_frob_file_before_fix,
 
297
  0,    /* frob_file_after_relocs.  */
 
298
  0,    /* s_get_size.  */
 
299
  0,    /* s_set_size.  */
 
300
  0,    /* s_get_align.  */
 
301
  0,    /* s_set_align.  */
 
302
  0,    /* s_get_other.  */
 
303
  0,    /* s_set_other.  */
 
304
  0,    /* s_get_desc.  */
 
305
  0,    /* s_set_desc.  */
 
306
  0,    /* s_get_type.  */
 
307
  0,    /* s_set_type.  */
 
308
  0,    /* copy_symbol_attributes.  */
 
309
  ecoff_generate_asm_lineno,
 
310
  ecoff_stab,
 
311
  ecoff_separate_stab_sections,
 
312
  0,    /* init_stab_section.  */
 
313
  ecoff_sec_sym_ok_for_reloc,
 
314
  ecoff_pop_insert,
 
315
  ecoff_set_ext,
 
316
  ecoff_read_begin_hook,
 
317
  ecoff_symbol_new_hook,
 
318
  ecoff_symbol_clone_hook,
 
319
  0     /* adjust_symtab.  */
 
320
};