OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [mmo.c] - Blame information for rev 303

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 khays
/* BFD back-end for mmo objects (MMIX-specific object-format).
2 148 khays
   Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011
3 14 khays
   Free Software Foundation, Inc.
4
   Written by Hans-Peter Nilsson (hp@bitrange.com).
5
   Infrastructure and other bits originally copied from srec.c and
6
   binary.c.
7
 
8
   This file is part of BFD, the Binary File Descriptor library.
9
 
10
   This program is free software; you can redistribute it and/or modify
11
   it under the terms of the GNU General Public License as published by
12
   the Free Software Foundation; either version 3 of the License, or
13
   (at your option) any later version.
14
 
15
   This program is distributed in the hope that it will be useful,
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
   GNU General Public License for more details.
19
 
20
   You should have received a copy of the GNU General Public License
21
   along with this program; if not, write to the Free Software
22
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
23
   MA 02110-1301, USA.  */
24
 
25
 
26
/*
27
SECTION
28
        mmo backend
29
 
30
        The mmo object format is used exclusively together with Professor
31
        Donald E.@: Knuth's educational 64-bit processor MMIX.  The simulator
32
        @command{mmix} which is available at
33
        @url{http://www-cs-faculty.stanford.edu/~knuth/programs/mmix.tar.gz}
34
        understands this format.  That package also includes a combined
35
        assembler and linker called @command{mmixal}.  The mmo format has
36
        no advantages feature-wise compared to e.g. ELF.  It is a simple
37
        non-relocatable object format with no support for archives or
38
        debugging information, except for symbol value information and
39
        line numbers (which is not yet implemented in BFD).  See
40
        @url{http://www-cs-faculty.stanford.edu/~knuth/mmix.html} for more
41
        information about MMIX.  The ELF format is used for intermediate
42
        object files in the BFD implementation.
43
 
44
@c We want to xref the symbol table node.  A feature in "chew"
45
@c requires that "commands" do not contain spaces in the
46
@c arguments.  Hence the hyphen in "Symbol-table".
47
@menu
48
@* File layout::
49
@* Symbol-table::
50
@* mmo section mapping::
51
@end menu
52
 
53
INODE
54
File layout, Symbol-table, mmo, mmo
55
SUBSECTION
56
        File layout
57
 
58
        The mmo file contents is not partitioned into named sections as
59
        with e.g.@: ELF.  Memory areas is formed by specifying the
60
        location of the data that follows.  Only the memory area
61
        @samp{0x0000@dots{}00} to @samp{0x01ff@dots{}ff} is executable, so
62
        it is used for code (and constants) and the area
63
        @samp{0x2000@dots{}00} to @samp{0x20ff@dots{}ff} is used for
64
        writable data.  @xref{mmo section mapping}.
65
 
66
        There is provision for specifying ``special data'' of 65536
67
        different types.  We use type 80 (decimal), arbitrarily chosen the
68
        same as the ELF <<e_machine>> number for MMIX, filling it with
69
        section information normally found in ELF objects. @xref{mmo
70
        section mapping}.
71
 
72
        Contents is entered as 32-bit words, xor:ed over previous
73
        contents, always zero-initialized.  A word that starts with the
74
        byte @samp{0x98} forms a command called a @samp{lopcode}, where
75
        the next byte distinguished between the thirteen lopcodes.  The
76
        two remaining bytes, called the @samp{Y} and @samp{Z} fields, or
77
        the @samp{YZ} field (a 16-bit big-endian number), are used for
78
        various purposes different for each lopcode.  As documented in
79
        @url{http://www-cs-faculty.stanford.edu/~knuth/mmixal-intro.ps.gz},
80
        the lopcodes are:
81
 
82
        @table @code
83
        @item lop_quote
84
        0x98000001.  The next word is contents, regardless of whether it
85
        starts with 0x98 or not.
86
 
87
        @item lop_loc
88
        0x9801YYZZ, where @samp{Z} is 1 or 2.  This is a location
89
        directive, setting the location for the next data to the next
90
        32-bit word (for @math{Z = 1}) or 64-bit word (for @math{Z = 2}),
91
        plus @math{Y * 2^56}.  Normally @samp{Y} is 0 for the text segment
92
        and 2 for the data segment.
93
 
94
        @item lop_skip
95
        0x9802YYZZ.  Increase the current location by @samp{YZ} bytes.
96
 
97
        @item lop_fixo
98
        0x9803YYZZ, where @samp{Z} is 1 or 2.  Store the current location
99
        as 64 bits into the location pointed to by the next 32-bit
100
        (@math{Z = 1}) or 64-bit (@math{Z = 2}) word, plus @math{Y *
101
        2^56}.
102
 
103
        @item lop_fixr
104
        0x9804YYZZ.  @samp{YZ} is stored into the current location plus
105
        @math{2 - 4 * YZ}.
106
 
107
        @item lop_fixrx
108
        0x980500ZZ.  @samp{Z} is 16 or 24.  A value @samp{L} derived from
109
        the following 32-bit word are used in a manner similar to
110
        @samp{YZ} in lop_fixr: it is xor:ed into the current location
111
        minus @math{4 * L}.  The first byte of the word is 0 or 1.  If it
112
        is 1, then @math{L = (@var{lowest 24 bits of word}) - 2^Z}, if 0,
113
        then @math{L = (@var{lowest 24 bits of word})}.
114
 
115
        @item lop_file
116
        0x9806YYZZ.  @samp{Y} is the file number, @samp{Z} is count of
117
        32-bit words.  Set the file number to @samp{Y} and the line
118
        counter to 0.  The next @math{Z * 4} bytes contain the file name,
119
        padded with zeros if the count is not a multiple of four.  The
120
        same @samp{Y} may occur multiple times, but @samp{Z} must be 0 for
121
        all but the first occurrence.
122
 
123
        @item lop_line
124
        0x9807YYZZ.  @samp{YZ} is the line number.  Together with
125
        lop_file, it forms the source location for the next 32-bit word.
126
        Note that for each non-lopcode 32-bit word, line numbers are
127
        assumed incremented by one.
128
 
129
        @item lop_spec
130
        0x9808YYZZ.  @samp{YZ} is the type number.  Data until the next
131
        lopcode other than lop_quote forms special data of type @samp{YZ}.
132
        @xref{mmo section mapping}.
133
 
134
        Other types than 80, (or type 80 with a content that does not
135
        parse) is stored in sections named <<.MMIX.spec_data.@var{n}>>
136
        where @var{n} is the @samp{YZ}-type.  The flags for such a
137
        sections say not to allocate or load the data.  The vma is 0.
138
        Contents of multiple occurrences of special data @var{n} is
139
        concatenated to the data of the previous lop_spec @var{n}s.  The
140
        location in data or code at which the lop_spec occurred is lost.
141
 
142
        @item lop_pre
143
        0x980901ZZ.  The first lopcode in a file.  The @samp{Z} field forms the
144
        length of header information in 32-bit words, where the first word
145
        tells the time in seconds since @samp{00:00:00 GMT Jan 1 1970}.
146
 
147
        @item lop_post
148
        0x980a00ZZ.  @math{Z > 32}.  This lopcode follows after all
149
        content-generating lopcodes in a program.  The @samp{Z} field
150
        denotes the value of @samp{rG} at the beginning of the program.
151
        The following @math{256 - Z} big-endian 64-bit words are loaded
152
        into global registers @samp{$G} @dots{} @samp{$255}.
153
 
154
        @item lop_stab
155
        0x980b0000.  The next-to-last lopcode in a program.  Must follow
156
        immediately after the lop_post lopcode and its data.  After this
157
        lopcode follows all symbols in a compressed format
158
        (@pxref{Symbol-table}).
159
 
160
        @item lop_end
161
        0x980cYYZZ.  The last lopcode in a program.  It must follow the
162
        lop_stab lopcode and its data.  The @samp{YZ} field contains the
163
        number of 32-bit words of symbol table information after the
164
        preceding lop_stab lopcode.
165
        @end table
166
 
167
        Note that the lopcode "fixups"; <<lop_fixr>>, <<lop_fixrx>> and
168
        <<lop_fixo>> are not generated by BFD, but are handled.  They are
169
        generated by <<mmixal>>.
170
 
171
EXAMPLE
172
        This trivial one-label, one-instruction file:
173
 
174
| :Main TRAP 1,2,3
175
 
176
        can be represented this way in mmo:
177
 
178
| 0x98090101 - lop_pre, one 32-bit word with timestamp.
179
| <timestamp>
180
| 0x98010002 - lop_loc, text segment, using a 64-bit address.
181
|              Note that mmixal does not emit this for the file above.
182
| 0x00000000 - Address, high 32 bits.
183
| 0x00000000 - Address, low 32 bits.
184
| 0x98060002 - lop_file, 2 32-bit words for file-name.
185
| 0x74657374 - "test"
186
| 0x2e730000 - ".s\0\0"
187
| 0x98070001 - lop_line, line 1.
188
| 0x00010203 - TRAP 1,2,3
189
| 0x980a00ff - lop_post, setting $255 to 0.
190
| 0x00000000
191
| 0x00000000
192
| 0x980b0000 - lop_stab for ":Main" = 0, serial 1.
193
| 0x203a4040   @xref{Symbol-table}.
194
| 0x10404020
195
| 0x4d206120
196
| 0x69016e00
197
| 0x81000000
198
| 0x980c0005 - lop_end; symbol table contained five 32-bit words.  */
199
 
200
#include "sysdep.h"
201
#include "bfd.h"
202
#include "libbfd.h"
203
#include "libiberty.h"
204
#include "elf/mmix.h"
205
#include "opcode/mmix.h"
206
 
207
#define LOP 0x98
208
#define LOP_QUOTE 0
209
#define LOP_LOC 1
210
#define LOP_SKIP 2
211
#define LOP_FIXO 3
212
#define LOP_FIXR 4
213
#define LOP_FIXRX 5
214
#define LOP_FILE 6
215
#define LOP_LINE 7
216
#define LOP_SPEC 8
217
#define LOP_PRE 9
218
#define LOP_POST 10
219
#define LOP_STAB 11
220
#define LOP_END 12
221
 
222
#define LOP_QUOTE_NEXT ((LOP << 24) | (LOP_QUOTE << 16) | 1)
223
#define SPEC_DATA_SECTION 80
224
#define LOP_SPEC_SECTION \
225
 ((LOP << 24) | (LOP_SPEC << 16) | SPEC_DATA_SECTION)
226
 
227
/* Must be a power of two.  If you change this to be >= 64k, you need a
228
   new test-case; the ld test b-loc64k.d touches chunk-size problem areas.  */
229
#define MMO_SEC_CONTENTS_CHUNK_SIZE (1 << 15)
230
 
231
/* An arbitrary number for the maximum length section name size.  */
232
#define MAX_SECTION_NAME_SIZE (1024 * 1024)
233
 
234
/* A quite arbitrary number for the maximum length section size.  */
235
#define MAX_ARTIFICIAL_SECTION_SIZE (1024 * 1024 * 1024)
236
 
237
#define MMO3_WCHAR 0x80
238
#define MMO3_LEFT 0x40
239
#define MMO3_MIDDLE 0x20
240
#define MMO3_RIGHT 0x10
241
#define MMO3_TYPEBITS 0xf
242
#define MMO3_REGQUAL_BITS 0xf
243
#define MMO3_UNDEF 2
244
#define MMO3_DATA 8
245
#define MMO3_SYMBITS 0x2f
246
 
247
/* Put these everywhere in new code.  */
248
#define FATAL_DEBUG                                             \
249
 _bfd_abort (__FILE__, __LINE__,                                \
250
             "Internal: Non-debugged code (test-case missing)")
251
 
252
#define BAD_CASE(x)                             \
253
 _bfd_abort (__FILE__, __LINE__,                \
254
             "bad case for " #x)
255
 
256
enum mmo_sym_type { mmo_reg_sym, mmo_undef_sym, mmo_data_sym, mmo_abs_sym};
257
 
258
/* When scanning the mmo file, a linked list of mmo_symbol
259
   structures is built to represent the symbol table (if there is
260
   one).  */
261
 
262
struct mmo_symbol
263
  {
264
    struct mmo_symbol *next;
265
    char *name;
266
    bfd_vma value;
267
    enum mmo_sym_type sym_type;
268
    unsigned int serno;
269
  };
270
 
271
struct mmo_data_list_struct
272
  {
273
    struct mmo_data_list_struct *next;
274
    bfd_vma where;
275
    bfd_size_type size;
276
    bfd_size_type allocated_size;
277
    bfd_byte data[1];
278
  };
279
 
280
typedef struct mmo_data_list_struct mmo_data_list_type;
281
 
282
struct mmo_symbol_trie
283
  {
284
    struct mmo_symbol_trie *left;
285
    struct mmo_symbol_trie *right;
286
    struct mmo_symbol_trie *middle;
287
 
288
    bfd_byte symchar;
289
 
290
    /* A zero name means there's nothing here.  */
291
    struct mmo_symbol sym;
292
  };
293
 
294
/* The mmo tdata information.  */
295
 
296
struct mmo_data_struct
297
  {
298
    struct mmo_symbol *symbols;
299
    struct mmo_symbol *symtail;
300
    asymbol *csymbols;
301
 
302
    /* File representation of time (NULL) when this file was created.  */
303
    bfd_byte created[4];
304
 
305
    /* When we're reading bytes recursively, check this occasionally.
306
       Also holds write errors.  */
307
    bfd_boolean have_error;
308
 
309
    /* Max symbol length that may appear in the lop_stab table.  Note that
310
       this table might just hold a subset of symbols for not-really large
311
       programs, as it can only be 65536 * 4 bytes large.  */
312
    int max_symbol_length;
313
 
314
    /* Here's the symbol we build in lop_stab.  */
315
    char *lop_stab_symbol;
316
 
317
    /* Index into lop_stab_symbol for the next character when parsing the
318
       symbol information.  */
319
    int symbol_position;
320
 
321
    /* When creating arbitrary sections, we need to count section numbers.  */
322
    int sec_no;
323
 
324
    /* When writing or reading byte-wise, we need to count the bytes
325
       within a 32-bit word.  */
326
    int byte_no;
327
 
328
    /* We also need a buffer to hold the bytes we count reading or writing.  */
329
    bfd_byte buf[4];
330
  };
331
 
332
typedef struct mmo_data_struct tdata_type;
333
 
334
struct mmo_section_data_struct
335
  {
336
    mmo_data_list_type *head;
337
    mmo_data_list_type *tail;
338
  };
339
 
340
#define mmo_section_data(sec) \
341
  ((struct mmo_section_data_struct *) (sec)->used_by_bfd)
342
 
343
/* These structures are used in bfd_map_over_sections constructs.  */
344
 
345
/* Used when writing out sections; all but the register contents section
346
   which is stored in reg_section.  */
347
struct mmo_write_sec_info
348
  {
349
    asection *reg_section;
350
    bfd_boolean retval;
351
  };
352
 
353
/* Used when trying to find a section corresponding to addr.  */
354
struct mmo_find_sec_info
355
  {
356
    asection *sec;
357
    bfd_vma addr;
358
  };
359
 
360
static bfd_boolean mmo_bfd_copy_private_bfd_data (bfd *, bfd *);
361
static void mmo_write_section_unless_reg_contents (bfd *, asection *, void *);
362
static void mmo_find_sec_w_addr (bfd *, asection *, void *);
363
static void mmo_find_sec_w_addr_grow (bfd *, asection *, void *);
364
static asection *mmo_make_section (bfd *, const char *);
365
static void mmo_get_symbol_info (bfd *, asymbol *, symbol_info *);
366
static void mmo_print_symbol (bfd *, void *, asymbol *,
367
                              bfd_print_symbol_type);
368
static void mmo_init (void);
369
static bfd_boolean mmo_mkobject (bfd *);
370
static bfd_boolean mmo_scan (bfd *);
371
static asection *mmo_decide_section (bfd *, bfd_vma);
372
static asection *mmo_get_generic_spec_data_section (bfd *, int);
373
static asection *mmo_get_spec_section (bfd *, int);
374
static INLINE bfd_byte *mmo_get_loc (asection *, bfd_vma, int);
375
static void mmo_xore_64 (asection *, bfd_vma vma, bfd_vma value);
376
static void mmo_xore_32 (asection *, bfd_vma vma, unsigned int);
377
static void mmo_xore_16 (asection *, bfd_vma vma, unsigned int);
378
static const bfd_target *mmo_object_p (bfd *);
379
static void mmo_map_set_sizes (bfd *, asection *, void *);
380
static bfd_boolean mmo_get_symbols (bfd *);
381
static bfd_boolean mmo_create_symbol (bfd *, const char *, bfd_vma,
382
                                      enum mmo_sym_type, unsigned int);
383
static bfd_boolean mmo_get_section_contents (bfd *, asection *, void *,
384
                                             file_ptr, bfd_size_type);
385
static long mmo_get_symtab_upper_bound (bfd *);
386
static long mmo_canonicalize_symtab (bfd *, asymbol **);
387
static void mmo_get_symbol_info (bfd *, asymbol *, symbol_info *);
388
static void mmo_print_symbol (bfd *, void *, asymbol *,
389
                              bfd_print_symbol_type);
390
static bfd_boolean mmo_set_section_contents (bfd *, sec_ptr, const void *,
391
                                             file_ptr, bfd_size_type);
392
static int mmo_sizeof_headers (bfd *, struct bfd_link_info *);
393
static bfd_boolean mmo_internal_write_header (bfd *);
394
static bfd_boolean mmo_internal_write_post (bfd *, int, asection *);
395
static bfd_boolean mmo_internal_add_3_sym (bfd *, struct mmo_symbol_trie *,
396
                                           const struct mmo_symbol *);
397
static unsigned int mmo_internal_3_length (bfd *, struct mmo_symbol_trie *);
398
static void mmo_internal_3_dump (bfd *, struct mmo_symbol_trie *);
399
static void mmo_beb128_out (bfd *, int, int);
400
static bfd_boolean mmo_internal_write_section (bfd *, asection *);
401
static void mmo_write_tetra (bfd *, unsigned int);
402
static void mmo_write_tetra_raw (bfd *, unsigned int);
403
static void mmo_write_octa (bfd *, bfd_vma);
404
static void mmo_write_octa_raw (bfd *, bfd_vma);
405
static bfd_boolean mmo_write_chunk (bfd *, const bfd_byte *, unsigned int);
406
static bfd_boolean mmo_flush_chunk (bfd *);
407
static bfd_boolean mmo_write_loc_chunk (bfd *, bfd_vma, const bfd_byte *,
408
                                        unsigned int, bfd_vma *);
409
static bfd_boolean mmo_write_chunk_list (bfd *, mmo_data_list_type *);
410
static bfd_boolean mmo_write_loc_chunk_list (bfd *, mmo_data_list_type *);
411
static bfd_boolean mmo_write_symbols_and_terminator (bfd *);
412
static flagword mmo_sec_flags_from_bfd_flags (flagword);
413
static flagword bfd_sec_flags_from_mmo_flags (flagword);
414
static bfd_byte mmo_get_byte (bfd *);
415
static void mmo_write_byte (bfd *, bfd_byte);
416
static bfd_boolean mmo_new_section_hook (bfd *, asection *);
417
static int mmo_sort_mmo_symbols (const void *, const void *);
418
static bfd_boolean mmo_write_object_contents (bfd *);
419
static bfd_boolean mmo_write_section_description (bfd *, asection *);
420
static bfd_boolean mmo_has_leading_or_trailing_zero_tetra_p (bfd *,
421
                                                             asection *);
422
 
423
/* Global "const" variables initialized once.  Must not depend on
424
   particular input or caller; put such things into the bfd or elsewhere.
425
   Look ma, no static per-invocation data!  */
426
 
427
static
428
char valid_mmo_symbol_character_set[/* A-Z a-z (we assume consecutive
429
                                       codes; sorry EBCDIC:ers!).  */
430
                                    + 'Z' - 'A' + 1 + 'z' - 'a' + 1
431
                                    /* Digits.  */
432
                                    + 10
433
                                    /* ':' and '_'.  */
434
                                    + 1 + 1
435
                                    /* Codes higher than 126.  */
436
                                    + 256 - 126
437
                                    /* Ending zero.  */
438
                                    + 1];
439
 
440
 
441
/* Get section SECNAME or create one if it doesn't exist.  When creating
442
   one, new memory for the name is allocated.  */
443
 
444
static asection *
445
mmo_make_section (bfd *abfd, const char *secname)
446
{
447
  asection *sec = bfd_get_section_by_name (abfd, secname);
448
 
449
  if (sec == NULL)
450
    {
451
      char *newsecname = strdup (secname);
452
 
453
      if (newsecname == NULL)
454
        {
455
          (*_bfd_error_handler)
456
            (_("%s: No core to allocate section name %s\n"),
457
             bfd_get_filename (abfd), secname);
458
          bfd_set_error (bfd_error_system_call);
459
          return NULL;
460
        }
461
      sec = bfd_make_section (abfd, newsecname);
462
    }
463
 
464
  return sec;
465
}
466
 
467
/* Nothing to do, but keep as a placeholder if we need it.
468
   Note that state that might differ between bfd:s must not be initialized
469
   here, nor must it be static.  Add it to tdata information instead.  */
470
 
471
static void
472
mmo_init (void)
473
{
474
  static bfd_boolean inited = FALSE;
475
  int i = 0;
476
  int j = 0;
477
  static const char letters[]
478
    = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789:_";
479
 
480
  if (inited)
481
    return;
482
  inited = TRUE;
483
 
484
  /* Fill in the set of valid symbol characters.  */
485
  strcpy (valid_mmo_symbol_character_set, letters);
486
  i = strlen (letters);
487
 
488
  for (j = 126; j < 256; j++)
489
    valid_mmo_symbol_character_set[i++] = j;
490
}
491
 
492
/* Check whether an existing file is an mmo file.  */
493
 
494
static const bfd_target *
495
mmo_object_p (bfd *abfd)
496
{
497
  struct stat statbuf;
498
  bfd_byte b[4];
499
 
500
  mmo_init ();
501
 
502
  if (bfd_stat (abfd, &statbuf) < 0
503
      || bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
504
      || bfd_bread (b, 4, abfd) != 4)
505
    goto bad_final;
506
 
507
  /* All mmo files are a multiple of four bytes long.
508
     Only recognize version one.  */
509
  if ((statbuf.st_size % 4) != 0
510
      || b[0] != LOP || b[1] != LOP_PRE || b[2] != 1)
511
    goto bad_format;
512
 
513
  /* Get the last 32-bit word.  */
514
  if (bfd_seek (abfd, (file_ptr) statbuf.st_size - 4, SEEK_SET) != 0
515
      || bfd_bread (b, 4, abfd) != 4)
516
    goto bad_final;
517
 
518
  /* Check if the file ends in a lop_end lopcode. */
519
  if (b[0] != LOP || b[1] != LOP_END || ! mmo_mkobject (abfd))
520
    goto bad_format;
521
 
522
  /* Compute an upper bound on the max symbol length.  Not really
523
     important as all of the symbol information can only be 256k.  */
524
  abfd->tdata.mmo_data->max_symbol_length = (b[2] * 256 + b[3]) * 4;
525
  abfd->tdata.mmo_data->lop_stab_symbol
526
    = bfd_malloc (abfd->tdata.mmo_data->max_symbol_length + 1);
527
 
528
  if (abfd->tdata.mmo_data->lop_stab_symbol == NULL)
529
    {
530
      (*_bfd_error_handler)
531
        (_("%s: No core to allocate a symbol %d bytes long\n"),
532
         bfd_get_filename (abfd), abfd->tdata.mmo_data->max_symbol_length);
533
      goto bad_final;
534
    }
535
 
536
  /* Read in everything.  */
537
  if (! mmo_scan (abfd))
538
    goto bad_format_free;
539
 
540
  if (abfd->symcount > 0)
541
    abfd->flags |= HAS_SYMS;
542
 
543
  /* You'll have to tweak this if you want to use this format for other
544
     arches (not recommended due to its small-size limitations).  Look at
545
     the ELF format for how to make it target-generic.  */
546
  if (! bfd_default_set_arch_mach (abfd, bfd_arch_mmix, 0))
547
    goto bad_format_free;
548
 
549
  return abfd->xvec;
550
 
551
 bad_format_free:
552
  free (abfd->tdata.mmo_data->lop_stab_symbol);
553
 bad_format:
554
  bfd_set_error (bfd_error_wrong_format);
555
 bad_final:
556
  return NULL;
557
}
558
 
559
/* Set up the mmo tdata information.  */
560
 
561
static bfd_boolean
562
mmo_mkobject (bfd *abfd)
563
{
564
  mmo_init ();
565
 
566
  if (abfd->tdata.mmo_data == NULL)
567
    {
568
      time_t created;
569
 
570
      /* All fields are zero-initialized, so we don't have to explicitly
571
         initialize most.  */
572
      tdata_type *tdata = (tdata_type *) bfd_zmalloc (sizeof (tdata_type));
573
      if (tdata == NULL)
574
        return FALSE;
575
 
576
      created = time (NULL);
577
      bfd_put_32 (abfd, created, tdata->created);
578
 
579
      abfd->tdata.mmo_data = tdata;
580
    }
581
 
582
  return TRUE;
583
}
584
 
585
static bfd_boolean
586
mmo_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
587
{
588
  if (bfd_get_flavour (ibfd) != bfd_target_mmo_flavour
589
      || bfd_get_flavour (obfd) != bfd_target_mmo_flavour)
590
    return TRUE;
591
 
592
  /* Copy the time the copied-from file was created.  If people want the
593
     time the file was last *modified*, they have that in the normal file
594
     information.  */
595
  memcpy (obfd->tdata.mmo_data->created, ibfd->tdata.mmo_data->created,
596
          sizeof (obfd->tdata.mmo_data->created));
597
  return TRUE;
598
}
599
 
600
/* Helper functions for mmo_decide_section, used through
601
   bfd_map_over_sections.  */
602
 
603
static void
604
mmo_find_sec_w_addr (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *p)
605
{
606
  struct mmo_find_sec_info *infop = (struct mmo_find_sec_info *) p;
607
  bfd_vma vma = bfd_get_section_vma (abfd, sec);
608
 
609
  /* Ignore sections that aren't loaded.  */
610
  if ((bfd_get_section_flags (abfd, sec) & (SEC_LOAD | SEC_ALLOC))
611
      !=  (SEC_LOAD | SEC_ALLOC))
612
    return;
613
 
614
  if (infop->addr >= vma && infop->addr < vma + sec->size)
615
    infop->sec = sec;
616
}
617
 
618
static void
619
mmo_find_sec_w_addr_grow (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *p)
620
{
621
  struct mmo_find_sec_info *infop = (struct mmo_find_sec_info *) p;
622
  bfd_vma vma = bfd_get_section_vma (abfd, sec);
623
 
624
  /* Ignore sections that aren't loaded.  */
625
  if ((bfd_get_section_flags (abfd, sec) & (SEC_LOAD | SEC_ALLOC))
626
      !=  (SEC_LOAD | SEC_ALLOC))
627
    return;
628
 
629
  if (infop->addr >= vma && infop->addr < vma + MAX_ARTIFICIAL_SECTION_SIZE)
630
    infop->sec = sec;
631
}
632
 
633
/* Find a section that corresponds to a VMA.  Automatically create .text
634
   or .data and set current section to it, depending on what vma.  If we
635
   can't deduce a section, make one up as ".MMIX.sec.N", where N is an
636
   increasing number.  */
637
 
638
static asection *
639
mmo_decide_section (bfd *abfd, bfd_vma vma)
640
{
641
  asection *sec = NULL;
642
  char sec_name[sizeof (".MMIX.sec.") + 20];
643
  struct mmo_find_sec_info info;
644
 
645
  info.addr = vma;
646
  info.sec = NULL;
647
 
648
  /* First see if there's a section that would match exactly.  */
649
  bfd_map_over_sections (abfd, mmo_find_sec_w_addr, &info);
650
 
651
  if (info.sec != NULL)
652
    return info.sec;
653
 
654
  /* If there's no such section, try and expand one of the existing ones,
655
     up to a limit.  Make sure we have .text and .data before we try that;
656
     create them corresponding to expected addresses and set flags to make
657
     them match the "loaded and with contents" expectation.  */
658
  if ((vma >> 56) == 0)
659
    {
660
      sec = bfd_make_section_old_way (abfd, MMO_TEXT_SECTION_NAME);
661
 
662
      if (sec == NULL)
663
        return NULL;
664
 
665
      if (! sec->user_set_vma)
666
        bfd_set_section_vma (abfd, sec, vma);
667
      if (! bfd_set_section_flags (abfd, sec,
668
                                   bfd_get_section_flags (abfd, sec)
669
                                   | SEC_CODE | SEC_LOAD | SEC_ALLOC))
670
        return NULL;
671
    }
672
  else if ((vma >> 56) == 0x20)
673
    {
674
      sec = bfd_make_section_old_way (abfd, MMO_DATA_SECTION_NAME);
675
 
676
      if (sec == NULL)
677
        return NULL;
678
 
679
      if (! sec->user_set_vma)
680
        bfd_set_section_vma (abfd, sec, vma);
681
      if (! bfd_set_section_flags (abfd, sec,
682
                                   bfd_get_section_flags (abfd, sec)
683
                                   | SEC_LOAD | SEC_ALLOC))
684
        return NULL;
685
    }
686
 
687
  bfd_map_over_sections (abfd, mmo_find_sec_w_addr_grow, &info);
688
 
689
  if (info.sec != NULL)
690
    return info.sec;
691
 
692
  /* If there's still no suitable section, make a new one.  */
693
  sprintf (sec_name, ".MMIX.sec.%d", abfd->tdata.mmo_data->sec_no++);
694
  sec = mmo_make_section (abfd, sec_name);
695
  if (! sec->user_set_vma)
696
    bfd_set_section_vma (abfd, sec, vma);
697
 
698
  if (! bfd_set_section_flags (abfd, sec,
699
                               bfd_get_section_flags (abfd, sec)
700
                               | SEC_LOAD | SEC_ALLOC))
701
    return NULL;
702
  return sec;
703
}
704
 
705
/* Xor in a 64-bit value VALUE at VMA.  */
706
 
707
static INLINE void
708
mmo_xore_64 (asection *sec, bfd_vma vma, bfd_vma value)
709
{
710
  bfd_byte *loc = mmo_get_loc (sec, vma, 8);
711
  bfd_vma prev = bfd_get_64 (sec->owner, loc);
712
 
713
  value ^= prev;
714
  bfd_put_64 (sec->owner, value, loc);
715
}
716
 
717
/* Xor in a 32-bit value VALUE at VMA.  */
718
 
719
static INLINE void
720
mmo_xore_32 (asection *sec, bfd_vma vma, unsigned int value)
721
{
722
  bfd_byte *loc = mmo_get_loc (sec, vma, 4);
723
  unsigned int prev = bfd_get_32 (sec->owner, loc);
724
 
725
  value ^= prev;
726
  bfd_put_32 (sec->owner, value, loc);
727
}
728
 
729
/* Xor in a 16-bit value VALUE at VMA.  */
730
 
731
static INLINE void
732
mmo_xore_16 (asection *sec, bfd_vma vma, unsigned int value)
733
{
734
  bfd_byte *loc = mmo_get_loc (sec, vma, 2);
735
  unsigned int prev = bfd_get_16 (sec->owner, loc);
736
 
737
  value ^= prev;
738
  bfd_put_16 (sec->owner, value, loc);
739
}
740
 
741
/* Write a 32-bit word to output file, no lop_quote generated.  */
742
 
743
static INLINE void
744
mmo_write_tetra_raw (bfd *abfd, unsigned int value)
745
{
746
  bfd_byte buf[4];
747
 
748
  bfd_put_32 (abfd, value, buf);
749
 
750
  if (bfd_bwrite (buf, 4, abfd) != 4)
751
    abfd->tdata.mmo_data->have_error = TRUE;
752
}
753
 
754
/* Write a 32-bit word to output file; lop_quote if necessary.  */
755
 
756
static INLINE void
757
mmo_write_tetra (bfd *abfd, unsigned int value)
758
{
759
  if (((value >> 24) & 0xff) == LOP)
760
    mmo_write_tetra_raw (abfd, LOP_QUOTE_NEXT);
761
 
762
  mmo_write_tetra_raw (abfd, value);
763
}
764
 
765
/* Write a 64-bit word to output file, perhaps with lop_quoting.  */
766
 
767
static INLINE void
768
mmo_write_octa (bfd *abfd, bfd_vma value)
769
{
770
  mmo_write_tetra (abfd, (unsigned int) (value >> 32));
771
  mmo_write_tetra (abfd, (unsigned int) value);
772
}
773
 
774
/* Write a 64-bit word to output file, without lop_quoting.  */
775
 
776
static INLINE void
777
mmo_write_octa_raw (bfd *abfd, bfd_vma value)
778
{
779
  mmo_write_tetra_raw (abfd, (unsigned int) (value >> 32));
780
  mmo_write_tetra_raw (abfd, (unsigned int) value);
781
}
782
 
783
/* Write quoted contents.  Intended to be called multiple times in
784
   sequence, followed by a call to mmo_flush_chunk.  */
785
 
786
static INLINE bfd_boolean
787
mmo_write_chunk (bfd *abfd, const bfd_byte *loc, unsigned int len)
788
{
789
  bfd_boolean retval = TRUE;
790
 
791
  /* Fill up a tetra from bytes remaining from a previous chunk.  */
792
  if (abfd->tdata.mmo_data->byte_no != 0)
793
    {
794
      while (abfd->tdata.mmo_data->byte_no < 4 && len != 0)
795
        {
796
          abfd->tdata.mmo_data->buf[abfd->tdata.mmo_data->byte_no++] = *loc++;
797
          len--;
798
        }
799
 
800
      if (abfd->tdata.mmo_data->byte_no == 4)
801
        {
802
          mmo_write_tetra (abfd,
803
                           bfd_get_32 (abfd, abfd->tdata.mmo_data->buf));
804
          abfd->tdata.mmo_data->byte_no = 0;
805
        }
806
    }
807
 
808
  while (len >= 4)
809
    {
810
      if (loc[0] == LOP)
811
        mmo_write_tetra_raw (abfd, LOP_QUOTE_NEXT);
812
 
813
      retval = (retval
814
                && ! abfd->tdata.mmo_data->have_error
815
                && 4 == bfd_bwrite (loc, 4, abfd));
816
 
817
      loc += 4;
818
      len -= 4;
819
    }
820
 
821
  if (len)
822
    {
823
      memcpy (abfd->tdata.mmo_data->buf, loc, len);
824
      abfd->tdata.mmo_data->byte_no = len;
825
    }
826
 
827
  if (! retval)
828
    abfd->tdata.mmo_data->have_error = TRUE;
829
  return retval;
830
}
831
 
832
/* Flush remaining bytes, from a previous mmo_write_chunk, zero-padded to
833
   4 bytes.  */
834
 
835
static INLINE bfd_boolean
836
mmo_flush_chunk (bfd *abfd)
837
{
838
  if (abfd->tdata.mmo_data->byte_no != 0)
839
    {
840
      memset (abfd->tdata.mmo_data->buf + abfd->tdata.mmo_data->byte_no,
841
              0, 4 - abfd->tdata.mmo_data->byte_no);
842
      mmo_write_tetra (abfd,
843
                       bfd_get_32 (abfd, abfd->tdata.mmo_data->buf));
844
      abfd->tdata.mmo_data->byte_no = 0;
845
    }
846
 
847
  return ! abfd->tdata.mmo_data->have_error;
848
}
849
 
850
/* Same, but from a list.  */
851
 
852
static INLINE bfd_boolean
853
mmo_write_chunk_list (bfd *abfd, mmo_data_list_type *datap)
854
{
855
  for (; datap != NULL; datap = datap->next)
856
    if (! mmo_write_chunk (abfd, datap->data, datap->size))
857
      return FALSE;
858
 
859
  return mmo_flush_chunk (abfd);
860
}
861
 
862
/* Write a lop_loc and some contents.  A caller needs to call
863
   mmo_flush_chunk after calling this function.  The location is only
864
   output if different than *LAST_VMAP, which is updated after this call.  */
865
 
866
static bfd_boolean
867
mmo_write_loc_chunk (bfd *abfd, bfd_vma vma, const bfd_byte *loc,
868
                     unsigned int len, bfd_vma *last_vmap)
869
{
870
  /* Find an initial and trailing section of zero tetras; we don't need to
871
     write out zeros.  FIXME: When we do this, we should emit section size
872
     and address specifiers, else objcopy can't always perform an identity
873
     translation.  Only do this if we *don't* have left-over data from a
874
     previous write or the vma of this chunk is *not* the next address,
875
     because then data isn't tetrabyte-aligned and we're concatenating to
876
     that left-over data.  */
877
 
878
  if (abfd->tdata.mmo_data->byte_no == 0 || vma != *last_vmap)
879
    {
880
      while (len >= 4 && bfd_get_32 (abfd, loc) == 0)
881
        {
882
          vma += 4;
883
          len -= 4;
884
          loc += 4;
885
        }
886
 
887
      while (len >= 4 && bfd_get_32 (abfd, loc + len - 4) == 0)
888
        len -= 4;
889
    }
890
 
891
  /* Only write out the location if it's different than the one the caller
892
     (supposedly) previously handled, accounting for omitted leading zeros.  */
893
  if (vma != *last_vmap)
894
    {
895
      /* We might be in the middle of a sequence.  */
896
      mmo_flush_chunk (abfd);
897
 
898
      /* We always write the location as 64 bits; no use saving bytes
899
         here.  */
900
      mmo_write_tetra_raw (abfd, (LOP << 24) | (LOP_LOC << 16) | 2);
901
      mmo_write_octa_raw (abfd, vma);
902
    }
903
 
904
  /* Update to reflect end of this chunk, with trailing zeros omitted.  */
905
  *last_vmap = vma + len;
906
 
907
  return (! abfd->tdata.mmo_data->have_error
908
          && mmo_write_chunk (abfd, loc, len));
909
}
910
 
911
/* Same, but from a list.  */
912
 
913
static INLINE bfd_boolean
914
mmo_write_loc_chunk_list (bfd *abfd, mmo_data_list_type *datap)
915
{
916
  /* Get an address different than the address of the first chunk.  */
917
  bfd_vma last_vma = datap ? datap->where - 1 : 0;
918
 
919
  for (; datap != NULL; datap = datap->next)
920
    if (! mmo_write_loc_chunk (abfd, datap->where, datap->data, datap->size,
921
                               &last_vma))
922
      return FALSE;
923
 
924
  return mmo_flush_chunk (abfd);
925
}
926
 
927
/* Make a .MMIX.spec_data.N section.  */
928
 
929
static asection *
930
mmo_get_generic_spec_data_section (bfd *abfd, int spec_data_number)
931
{
932
  asection *sec;
933
  char secname[sizeof (MMIX_OTHER_SPEC_SECTION_PREFIX) + 20]
934
    = MMIX_OTHER_SPEC_SECTION_PREFIX;
935
 
936
  sprintf (secname + strlen (MMIX_OTHER_SPEC_SECTION_PREFIX),
937
           "%d", spec_data_number);
938
 
939
  sec = mmo_make_section (abfd, secname);
940
 
941
  return sec;
942
}
943
 
944
/* Make a special section for SPEC_DATA_NUMBER.  If it is the one we use
945
   ourselves, parse some of its data to get at the section name.  */
946
 
947
static asection *
948
mmo_get_spec_section (bfd *abfd, int spec_data_number)
949
{
950
  char *secname;
951
  asection *sec;
952
  bfd_byte buf[4];
953
  unsigned int secname_length;
954
  unsigned int i;
955
  bfd_vma section_length;
956
  bfd_vma section_vma;
957
  mmo_data_list_type *loc;
958
  flagword flags;
959
  long orig_pos;
960
 
961
  /* If this isn't the "special" special data, then make a placeholder
962
     section.  */
963
  if (spec_data_number != SPEC_DATA_SECTION)
964
    return mmo_get_generic_spec_data_section (abfd, spec_data_number);
965
 
966
  /* Seek back to this position if there was a format error.  */
967
  orig_pos = bfd_tell (abfd);
968
 
969
  /* Read the length (in 32-bit words).  */
970
  if (bfd_bread (buf, 4, abfd) != 4)
971
    goto format_error;
972
 
973
  if (buf[0] == LOP)
974
    {
975
      if (buf[1] != LOP_QUOTE)
976
        goto format_error;
977
 
978
      if (bfd_bread (buf, 4, abfd) != 4)
979
        goto format_error;
980
    }
981
 
982
  /* We don't care to keep the name length accurate.  It's
983
     zero-terminated.  */
984
  secname_length = bfd_get_32 (abfd, buf) * 4;
985
 
986
  /* Check section name length for sanity.  */
987
  if (secname_length > MAX_SECTION_NAME_SIZE)
988
    goto format_error;
989
 
990
  /* This should be free'd regardless if a section is created.  */
991
  secname = bfd_malloc (secname_length + 1);
992
  secname[secname_length] = 0;
993
 
994
  for (i = 0; i < secname_length / 4; i++)
995
    {
996
      if (bfd_bread (secname + i * 4, 4, abfd) != 4)
997
        goto format_error_free;
998
 
999
      if (secname[i * 4] == (char) LOP)
1000
        {
1001
          /* A bit of overkill, but we handle char 0x98 in a section name,
1002
             and recognize misparsing.  */
1003
          if (secname[i * 4 + 1] != LOP_QUOTE
1004
              || bfd_bread (secname + i * 4, 4, abfd) != 4)
1005
            /* Whoops.  We thought this was a name, and now we found a
1006
               non-lop_quote lopcode before we parsed the whole length of
1007
               the name.  Signal end-of-file in the same manner.  */
1008
              goto format_error_free;
1009
        }
1010
    }
1011
 
1012
  /* Get the section flags.  */
1013
  if (bfd_bread (buf, 4, abfd) != 4
1014
      || (buf[0] == LOP
1015
          && (buf[1] != LOP_QUOTE || bfd_bread (buf, 4, abfd) != 4)))
1016
    goto format_error_free;
1017
 
1018
  flags = bfd_get_32 (abfd, buf);
1019
 
1020
  /* Get the section length.  */
1021
  if (bfd_bread (buf, 4, abfd) != 4
1022
      || (buf[0] == LOP
1023
          && (buf[1] != LOP_QUOTE || bfd_bread (buf, 4, abfd) != 4)))
1024
    goto format_error_free;
1025
 
1026
  section_length = (bfd_vma) bfd_get_32 (abfd, buf) << 32;
1027
 
1028
  /* That's the first, high-part.  Now get the low part.  */
1029
 
1030
  if (bfd_bread (buf, 4, abfd) != 4
1031
      || (buf[0] == LOP
1032
          && (buf[1] != LOP_QUOTE || bfd_bread (buf, 4, abfd) != 4)))
1033
    goto format_error_free;
1034
 
1035
  section_length |= (bfd_vma) bfd_get_32 (abfd, buf);
1036
 
1037
  /* Check the section length for sanity.  */
1038
  if (section_length > MAX_ARTIFICIAL_SECTION_SIZE)
1039
    goto format_error_free;
1040
 
1041
  /* Get the section VMA.  */
1042
  if (bfd_bread (buf, 4, abfd) != 4
1043
      || (buf[0] == LOP
1044
          && (buf[1] != LOP_QUOTE || bfd_bread (buf, 4, abfd) != 4)))
1045
    goto format_error_free;
1046
 
1047
  section_vma = (bfd_vma) bfd_get_32 (abfd, buf) << 32;
1048
 
1049
  /* That's the first, high-part.  Now get the low part.  */
1050
  if (bfd_bread (buf, 4, abfd) != 4
1051
      || (buf[0] == LOP
1052
          && (buf[1] != LOP_QUOTE || bfd_bread (buf, 4, abfd) != 4)))
1053
    goto format_error_free;
1054
 
1055
  section_vma |= (bfd_vma) bfd_get_32 (abfd, buf);
1056
 
1057
  sec = mmo_make_section (abfd, secname);
1058
  free (secname);
1059
  if (sec == NULL)
1060
    goto format_error;
1061
 
1062
  /* We allocate a buffer here for the advertised size, with head room for
1063
     tetrabyte alignment.  */
1064
  loc = bfd_zmalloc (section_length + 3
1065
                     + sizeof (struct mmo_data_list_struct));
1066
  if (loc == NULL)
1067
    goto format_error;
1068
 
1069
  /* Use a TETRA-rounded size for the allocated buffer; we set the
1070
     "visible" section size below.  */
1071
  loc->size = (section_length + 3) & ~3;
1072
 
1073
  /* Add in the section flags we found to those bfd entered during this
1074
     process and set the contents.  */
1075
  if (! bfd_set_section_flags (abfd, sec,
1076
                               bfd_sec_flags_from_mmo_flags (flags)
1077
                               | bfd_get_section_flags (abfd, sec)
1078
                               | (section_length != 0 ? SEC_HAS_CONTENTS : 0))
1079
      || ! bfd_set_section_size (abfd, sec, sec->size + section_length)
1080
      /* Set VMA only for the first occurrence.  */
1081
      || (! sec->user_set_vma
1082
          && ! bfd_set_section_vma  (abfd, sec, section_vma)))
1083
    {
1084
      /* If we get an error for any of the calls above, signal more than
1085
         just a format error for the spec section.  */
1086
      return NULL;
1087
    }
1088
 
1089
  loc->next = NULL;
1090
  if (mmo_section_data (sec)->tail != NULL)
1091
    mmo_section_data (sec)->tail->next = loc;
1092
  else
1093
    mmo_section_data (sec)->head = loc;
1094
  mmo_section_data (sec)->tail = loc;
1095
  loc->where = section_vma;
1096
 
1097
  return sec;
1098
 
1099
 format_error_free:
1100
  free (secname);
1101
 format_error:
1102
  if (bfd_seek (abfd, orig_pos, SEEK_SET) != 0)
1103
    return NULL;
1104
 
1105
  return mmo_get_generic_spec_data_section (abfd, spec_data_number);
1106
}
1107
 
1108
/* Read a byte, but read from file in multiples of 32-bit words.  */
1109
 
1110
static bfd_byte
1111
mmo_get_byte (bfd *abfd)
1112
{
1113
  bfd_byte retval;
1114
 
1115
  if (abfd->tdata.mmo_data->byte_no == 0)
1116
    {
1117
      if (! abfd->tdata.mmo_data->have_error
1118
          && bfd_bread (abfd->tdata.mmo_data->buf, 4, abfd) != 4)
1119
        {
1120
          abfd->tdata.mmo_data->have_error = TRUE;
1121
 
1122
          /* A value somewhat safe against tripping on some inconsistency
1123
             when mopping up after this error.  */
1124
          return 128;
1125
        }
1126
    }
1127
 
1128
  retval = abfd->tdata.mmo_data->buf[abfd->tdata.mmo_data->byte_no];
1129
  abfd->tdata.mmo_data->byte_no = (abfd->tdata.mmo_data->byte_no + 1) % 4;
1130
 
1131
  return retval;
1132
}
1133
 
1134
/* Write a byte, in multiples of 32-bit words.  */
1135
 
1136
static void
1137
mmo_write_byte (bfd *abfd, bfd_byte value)
1138
{
1139
  abfd->tdata.mmo_data->buf[(abfd->tdata.mmo_data->byte_no++ % 4)] = value;
1140
  if ((abfd->tdata.mmo_data->byte_no % 4) == 0)
1141
    {
1142
      if (! abfd->tdata.mmo_data->have_error
1143
          && bfd_bwrite (abfd->tdata.mmo_data->buf, 4, abfd) != 4)
1144
        abfd->tdata.mmo_data->have_error = TRUE;
1145
    }
1146
}
1147
 
1148
/* Create a symbol.  */
1149
 
1150
static bfd_boolean
1151
mmo_create_symbol (bfd *abfd, const char *symname, bfd_vma addr, enum
1152
                   mmo_sym_type sym_type, unsigned int serno)
1153
{
1154
  struct mmo_symbol *n;
1155
 
1156
  n = (struct mmo_symbol *) bfd_alloc (abfd, sizeof (struct mmo_symbol));
1157
  if (n == NULL)
1158
    return FALSE;
1159
 
1160
  n->name = bfd_alloc (abfd, strlen (symname) + 1);
1161
  if (n->name == NULL)
1162
    return FALSE;
1163
 
1164
  strcpy (n->name, symname);
1165
 
1166
  n->value = addr;
1167
  n->sym_type = sym_type;
1168
  n->serno = serno;
1169
 
1170
  if (abfd->tdata.mmo_data->symbols == NULL)
1171
    abfd->tdata.mmo_data->symbols = n;
1172
  else
1173
    abfd->tdata.mmo_data->symtail->next = n;
1174
  abfd->tdata.mmo_data->symtail = n;
1175
  n->next = NULL;
1176
 
1177
  ++abfd->symcount;
1178
 
1179
  /* Check that :Main equals the last octa of the .MMIX.reg_contents
1180
     section, as it's the one place we're sure to pass when reading a mmo
1181
     object.  For written objects, we do it while setting the symbol
1182
     table.  */
1183
  if (strcmp (symname, MMIX_START_SYMBOL_NAME) == 0
1184
      && bfd_get_start_address (abfd) != addr)
1185
    {
1186
      (*_bfd_error_handler)
1187
        (_("%s: invalid mmo file: initialization value for $255 is not `Main'\n"),
1188
         bfd_get_filename (abfd));
1189
      bfd_set_error (bfd_error_bad_value);
1190
      return FALSE;
1191
    }
1192
 
1193
  return TRUE;
1194
}
1195
 
1196
/* Read in symbols.  */
1197
 
1198
static bfd_boolean
1199
mmo_get_symbols (bfd *abfd)
1200
{
1201
/*
1202
INODE
1203
Symbol-table, mmo section mapping, File layout, mmo
1204
SUBSECTION
1205
        Symbol table format
1206
 
1207
        From mmixal.w (or really, the generated mmixal.tex) in
1208
        @url{http://www-cs-faculty.stanford.edu/~knuth/programs/mmix.tar.gz}):
1209
        ``Symbols are stored and retrieved by means of a @samp{ternary
1210
        search trie}, following ideas of Bentley and Sedgewick. (See
1211
        ACM--SIAM Symp.@: on Discrete Algorithms @samp{8} (1997), 360--369;
1212
        R.@:Sedgewick, @samp{Algorithms in C} (Reading, Mass.@:
1213
        Addison--Wesley, 1998), @samp{15.4}.)  Each trie node stores a
1214
        character, and there are branches to subtries for the cases where
1215
        a given character is less than, equal to, or greater than the
1216
        character in the trie.  There also is a pointer to a symbol table
1217
        entry if a symbol ends at the current node.''
1218
 
1219
        So it's a tree encoded as a stream of bytes.  The stream of bytes
1220
        acts on a single virtual global symbol, adding and removing
1221
        characters and signalling complete symbol points.  Here, we read
1222
        the stream and create symbols at the completion points.
1223
 
1224
        First, there's a control byte <<m>>.  If any of the listed bits
1225
        in <<m>> is nonzero, we execute what stands at the right, in
1226
        the listed order:
1227
 
1228
| (MMO3_LEFT)
1229
| 0x40 - Traverse left trie.
1230
|        (Read a new command byte and recurse.)
1231
|
1232
| (MMO3_SYMBITS)
1233
| 0x2f - Read the next byte as a character and store it in the
1234
|        current character position; increment character position.
1235
|        Test the bits of <<m>>:
1236
|
1237
|        (MMO3_WCHAR)
1238
|        0x80 - The character is 16-bit (so read another byte,
1239
|               merge into current character.
1240
|
1241
|        (MMO3_TYPEBITS)
1242
|        0xf  - We have a complete symbol; parse the type, value
1243
|               and serial number and do what should be done
1244
|               with a symbol.  The type and length information
1245
|               is in j = (m & 0xf).
1246
|
1247
|               (MMO3_REGQUAL_BITS)
1248
|               j == 0xf: A register variable.  The following
1249
|                         byte tells which register.
1250
|               j <= 8:   An absolute symbol.  Read j bytes as the
1251
|                         big-endian number the symbol equals.
1252
|                         A j = 2 with two zero bytes denotes an
1253
|                         unknown symbol.
1254
|               j > 8:    As with j <= 8, but add (0x20 << 56)
1255
|                         to the value in the following j - 8
1256
|                         bytes.
1257
|
1258
|               Then comes the serial number, as a variant of
1259
|               uleb128, but better named ubeb128:
1260
|               Read bytes and shift the previous value left 7
1261
|               (multiply by 128).  Add in the new byte, repeat
1262
|               until a byte has bit 7 set.  The serial number
1263
|               is the computed value minus 128.
1264
|
1265
|        (MMO3_MIDDLE)
1266
|        0x20 - Traverse middle trie.  (Read a new command byte
1267
|               and recurse.)  Decrement character position.
1268
|
1269
| (MMO3_RIGHT)
1270
| 0x10 - Traverse right trie.  (Read a new command byte and
1271
|        recurse.)
1272
 
1273
        Let's look again at the <<lop_stab>> for the trivial file
1274
        (@pxref{File layout}).
1275
 
1276
| 0x980b0000 - lop_stab for ":Main" = 0, serial 1.
1277
| 0x203a4040
1278
| 0x10404020
1279
| 0x4d206120
1280
| 0x69016e00
1281
| 0x81000000
1282
 
1283
        This forms the trivial trie (note that the path between ``:'' and
1284
        ``M'' is redundant):
1285
 
1286
| 203a     ":"
1287
| 40       /
1288
| 40      /
1289
| 10      \
1290
| 40      /
1291
| 40     /
1292
| 204d  "M"
1293
| 2061  "a"
1294
| 2069  "i"
1295
| 016e  "n" is the last character in a full symbol, and
1296
|       with a value represented in one byte.
1297
| 00    The value is 0.
1298
| 81    The serial number is 1.  */
1299
 
1300
  bfd_byte m = mmo_get_byte (abfd);
1301
 
1302
  /* Check first if we have a bad hair day.  */
1303
  if (abfd->tdata.mmo_data->have_error)
1304
    return FALSE;
1305
 
1306
  if (m & MMO3_LEFT)
1307
    /* Traverse left trie. */
1308
    mmo_get_symbols (abfd);
1309
 
1310
  if (m & MMO3_SYMBITS)
1311
    {
1312
      bfd_byte c = mmo_get_byte (abfd);
1313
      bfd_byte j = m & MMO3_TYPEBITS;
1314
      bfd_vma addr = 0;
1315
      enum mmo_sym_type sym_type;
1316
      unsigned int serno = 0;
1317
      bfd_byte k;
1318
 
1319
      if (m & MMO3_WCHAR)
1320
        {
1321
          bfd_byte c2 = mmo_get_byte (abfd);
1322
 
1323
          /* A two-byte character.  We can't grok this, but neither can
1324
             mmotype, for other cases than the second byte being zero.  */
1325
 
1326
          if (c != 0)
1327
            {
1328
              abfd->tdata.mmo_data->lop_stab_symbol
1329
                [abfd->tdata.mmo_data->symbol_position] = 0;
1330
 
1331
              (*_bfd_error_handler)
1332
                (_("%s: unsupported wide character sequence"
1333
                   " 0x%02X 0x%02X after symbol name starting with `%s'\n"),
1334
                 bfd_get_filename (abfd), c, c2,
1335
                 abfd->tdata.mmo_data->lop_stab_symbol);
1336
              bfd_set_error (bfd_error_bad_value);
1337
              abfd->tdata.mmo_data->have_error = TRUE;
1338
              return FALSE;
1339
            }
1340
          else
1341
            c = c2;
1342
        }
1343
 
1344
      abfd->tdata.mmo_data->lop_stab_symbol[abfd->tdata.mmo_data->symbol_position++] = c;
1345
      abfd->tdata.mmo_data->lop_stab_symbol[abfd->tdata.mmo_data->symbol_position] = 0;
1346
 
1347
      if (j & MMO3_REGQUAL_BITS)
1348
        {
1349
          if (j == MMO3_REGQUAL_BITS)
1350
            {
1351
              sym_type = mmo_reg_sym;
1352
              addr = mmo_get_byte (abfd);
1353
            }
1354
          else if (j <= 8)
1355
            {
1356
              unsigned int i;
1357
 
1358
              for (i = 0; i < j; i++)
1359
                addr = (addr << 8) + mmo_get_byte (abfd);
1360
 
1361
              if (addr == 0 && j == MMO3_UNDEF)
1362
                sym_type = mmo_undef_sym;
1363
              else
1364
                sym_type = mmo_abs_sym;
1365
            }
1366
          else
1367
            {
1368
              unsigned int i;
1369
 
1370
              for (i = MMO3_DATA; i < j; i++)
1371
                addr = (addr << 8) + mmo_get_byte (abfd);
1372
 
1373
              addr += (bfd_vma) 0x20 << 56;
1374
              sym_type = mmo_data_sym;
1375
            }
1376
 
1377
          /* Get the serial number.  */
1378
          do
1379
            {
1380
              k = mmo_get_byte (abfd);
1381
              serno = (serno << 7) + k;
1382
            }
1383
          while (k < 128);
1384
          serno -= 128;
1385
 
1386
          /* Got it.  Now enter it.  Skip a leading ":".  */
1387
          if (! abfd->tdata.mmo_data->have_error
1388
              && ! mmo_create_symbol (abfd,
1389
                                      abfd->tdata.mmo_data->lop_stab_symbol
1390
                                      + 1,
1391
                                      addr, sym_type, serno))
1392
            abfd->tdata.mmo_data->have_error = TRUE;
1393
        }
1394
 
1395
      if (m & MMO3_MIDDLE)
1396
        /* Traverse middle trie. */
1397
        mmo_get_symbols (abfd);
1398
 
1399
      abfd->tdata.mmo_data->symbol_position--;
1400
    }
1401
 
1402
  if (m & MMO3_RIGHT)
1403
    /* Traverse right trie.  */
1404
    mmo_get_symbols (abfd);
1405
 
1406
  return ! abfd->tdata.mmo_data->have_error;
1407
}
1408
 
1409
/* Get the location of memory area [VMA..VMA + SIZE - 1], which we think
1410
   is in section SEC.  Adjust and reallocate zero-initialized contents.
1411
   If there's new contents, allocate to the next multiple of
1412
   MMO_SEC_CONTENTS_CHUNK_SIZE.  */
1413
 
1414
static INLINE bfd_byte *
1415
mmo_get_loc (asection *sec, bfd_vma vma, int size)
1416
{
1417
  bfd_size_type allocated_size;
1418
  struct mmo_section_data_struct *sdatap = mmo_section_data (sec);
1419
  struct mmo_data_list_struct *datap = sdatap->head;
1420
  struct mmo_data_list_struct *entry;
1421
 
1422
  /* First search the list to see if we have the requested chunk in one
1423
     piece, or perhaps if we have a suitable chunk with room to fit.  */
1424
  for (; datap != NULL; datap = datap->next)
1425
    {
1426
      if (datap->where <= vma
1427
          && datap->where + datap->size >= vma + size)
1428
        return datap->data + vma - datap->where;
1429
      else if (datap->where <= vma
1430
               && datap->where + datap->allocated_size >= vma + size
1431
               /* Only munch on the "allocated size" if it does not
1432
                  overlap the next chunk.  */
1433
               && (datap->next == NULL || datap->next->where >= vma + size))
1434
        {
1435
          /* There was room allocated, but the size wasn't set to include
1436
             it.  Do that now.  */
1437
          datap->size += (vma + size) - (datap->where + datap->size);
1438
 
1439
          /* Update the section size.  This happens only if we update the
1440
             32-bit-aligned chunk size.  Callers that have
1441
             non-32-bit-aligned sections should do all allocation and
1442
             size-setting by themselves or at least set the section size
1443
             after the last allocating call to this function.  */
1444
          if (vma + size > sec->vma + sec->size)
1445
            sec->size += (vma + size) - (sec->vma + sec->size);
1446
 
1447
          return datap->data + vma - datap->where;
1448
        }
1449
    }
1450
 
1451
  /* Not found; allocate a new block.  First check in case we get a
1452
     request for a size split up over several blocks; we'll have to return
1453
     NULL for those cases, requesting the caller to split up the request.
1454
     Requests with an address aligned on MMO_SEC_CONTENTS_CHUNK_SIZE bytes and
1455
     for no more than MMO_SEC_CONTENTS_CHUNK_SIZE will always get resolved.  */
1456
 
1457
  for (datap = sdatap->head; datap != NULL; datap = datap->next)
1458
    if ((datap->where <= vma && datap->where + datap->size > vma)
1459
        || (datap->where < vma + size
1460
            && datap->where + datap->size >= vma + size))
1461
      return NULL;
1462
 
1463
  allocated_size
1464
    = (size + MMO_SEC_CONTENTS_CHUNK_SIZE - 1) & ~(MMO_SEC_CONTENTS_CHUNK_SIZE - 1);
1465
  entry = (mmo_data_list_type *)
1466
    bfd_zalloc (sec->owner, sizeof (mmo_data_list_type) + allocated_size);
1467
  if (entry == NULL)
1468
    return NULL;
1469
  entry->where = vma;
1470
  entry->size = size;
1471
  entry->allocated_size = allocated_size;
1472
 
1473
  datap = sdatap->head;
1474
 
1475
  /* Sort the records by address.  Optimize for the common case of adding
1476
     a record to the end of the list.  */
1477
  if (sdatap->tail != NULL && entry->where >= sdatap->tail->where)
1478
    {
1479
      sdatap->tail->next = entry;
1480
      entry->next = NULL;
1481
      sdatap->tail = entry;
1482
    }
1483
  else
1484
    {
1485
      mmo_data_list_type **look;
1486
      for (look = &sdatap->head;
1487
           *look != NULL && (*look)->where < entry->where;
1488
           look = &(*look)->next)
1489
        ;
1490
      entry->next = *look;
1491
      *look = entry;
1492
      if (entry->next == NULL)
1493
        {
1494
          sdatap->tail = entry;
1495
 
1496
          /* We get here for the first time (at other times too) for this
1497
             section.  Say we have contents.  */
1498
          if (! bfd_set_section_flags (sec->owner, sec,
1499
                                       bfd_get_section_flags (sec->owner, sec)
1500
                                       | SEC_HAS_CONTENTS))
1501
            return NULL;
1502
        }
1503
    }
1504
 
1505
  /* Update the section size.  This happens only when we add contents and
1506
     re-size as we go.  The section size will then be aligned to 32 bits.  */
1507
  if (vma + size > sec->vma + sec->size)
1508
    sec->size += (vma + size) - (sec->vma + sec->size);
1509
  return entry->data;
1510
}
1511
 
1512
/* Set sizes once we've read in all sections.  */
1513
 
1514
static void
1515
mmo_map_set_sizes (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
1516
                   void *ignored ATTRIBUTE_UNUSED)
1517
{
1518
  sec->lma = sec->vma;
1519
}
1520
 
1521
/* Read the mmo file and turn it into sections.  */
1522
 
1523
static bfd_boolean
1524
mmo_scan (bfd *abfd)
1525
{
1526
  unsigned int i;
1527
  unsigned int lineno = 1;
1528
  bfd_boolean error = FALSE;
1529
  bfd_vma vma = 0;
1530
  asection *sec = bfd_make_section_old_way (abfd, MMO_TEXT_SECTION_NAME);
1531
  asection *non_spec_sec = NULL;
1532
  bfd_vma non_spec_vma = 0;
1533
  bfd_size_type nbytes_read = 0;
1534
  /* Buffer with room to read a 64-bit value.  */
1535
  bfd_byte buf[8];
1536
  long stab_loc = -1;
1537
  char *file_names[256];
1538
 
1539
  memset (file_names, 0, sizeof (file_names));
1540
 
1541
  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
1542
    goto error_return;
1543
 
1544
  while ((nbytes_read = bfd_bread (buf, 4, abfd)) == 4)
1545
    {
1546
      if (buf[0] == LOP)
1547
        {
1548
          unsigned int y = bfd_get_8 (abfd, buf + 2);
1549
          unsigned int z = bfd_get_8 (abfd, buf + 3);
1550
 
1551
          /* Change back to the original section for lopcodes other
1552
             than LOP_QUOTE that comes after a LOP_SPEC.  */
1553
          if ((buf[1] != LOP_QUOTE || y != 0 || z != 1)
1554
              && non_spec_sec != NULL)
1555
            {
1556
              sec = non_spec_sec;
1557
              vma = non_spec_vma;
1558
              non_spec_sec = NULL;
1559
            }
1560
 
1561
          switch (buf[1])
1562
            {
1563
            default:
1564
              (*_bfd_error_handler)
1565
                (_("%s: invalid mmo file: unsupported lopcode `%d'\n"),
1566
                 bfd_get_filename (abfd), buf[1]);
1567
              bfd_set_error (bfd_error_bad_value);
1568
              goto error_return;
1569
 
1570
            case LOP_QUOTE:
1571
              /* Quote the next 32-bit word.  */
1572
              if (y != 0 || z != 1)
1573
                {
1574
                  (*_bfd_error_handler)
1575
                    (_("%s: invalid mmo file: expected YZ = 1 got YZ = %d for lop_quote\n"),
1576
                     bfd_get_filename (abfd), y*256+z);
1577
                  bfd_set_error (bfd_error_bad_value);
1578
                  goto error_return;
1579
                }
1580
              if (bfd_bread (buf, 4, abfd) != 4)
1581
                goto error_return;
1582
 
1583
              mmo_xore_32 (sec, vma, bfd_get_32 (abfd, buf));
1584
              vma += 4;
1585
              vma &= ~3;
1586
              lineno++;
1587
              break;
1588
 
1589
            case LOP_LOC:
1590
              /* Set vma (and section).  */
1591
              vma = (bfd_vma) y << 56;
1592
              if (z == 1)
1593
                {
1594
                  /* Get a 32-bit value.  */
1595
                  if (bfd_bread (buf, 4, abfd) != 4)
1596
                    goto error_return;
1597
 
1598
                  vma += bfd_get_32 (abfd, buf);
1599
                }
1600
              else if (z == 2)
1601
                {
1602
                  /* Get a 64-bit value.  */
1603
                  if (bfd_bread (buf, 8, abfd) != 8)
1604
                    goto error_return;
1605
 
1606
                  vma += bfd_get_64 (abfd, buf);
1607
                }
1608
              else
1609
                {
1610
                  (*_bfd_error_handler)
1611
                    (_("%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_loc\n"),
1612
                     bfd_get_filename (abfd), z);
1613
                  bfd_set_error (bfd_error_bad_value);
1614
                  goto error_return;
1615
                }
1616
 
1617
              sec = mmo_decide_section (abfd, vma);
1618
              if (sec == NULL)
1619
                goto error_return;
1620
              break;
1621
 
1622
            case LOP_SKIP:
1623
              /* Move forward within the same section.  */
1624
              vma += y * 256 + z;
1625
 
1626
              sec = mmo_decide_section (abfd, vma);
1627
              if (sec == NULL)
1628
                goto error_return;
1629
              break;
1630
 
1631
            case LOP_FIXO:
1632
              /* A fixup: Store the current vma somewhere.  Position using
1633
                 same format as LOP_LOC.  */
1634
              {
1635
                bfd_vma p = (bfd_vma) y << 56;
1636
                asection *fixosec;
1637
 
1638
                if (z == 1)
1639
                  {
1640
                    /* Get a 32-bit value.  */
1641
                    if (bfd_bread (buf, 4, abfd) != 4)
1642
                      goto error_return;
1643
 
1644
                    p += bfd_get_32 (abfd, buf);
1645
                  }
1646
                else if (z == 2)
1647
                  {
1648
                    /* Get a 64-bit value.  */
1649
                    if (bfd_bread (buf, 8, abfd) != 8)
1650
                      goto error_return;
1651
 
1652
                    p += bfd_get_64 (abfd, buf);
1653
                  }
1654
                else
1655
                  {
1656
                    (*_bfd_error_handler)
1657
                      (_("%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_fixo\n"),
1658
                       bfd_get_filename (abfd), z);
1659
                    bfd_set_error (bfd_error_bad_value);
1660
                    goto error_return;
1661
                  }
1662
 
1663
                /* The section where we store this address might be a
1664
                   different one than the current section.  */
1665
                fixosec = mmo_decide_section (abfd, p);
1666
                if (fixosec == NULL)
1667
                  goto error_return;
1668
                mmo_xore_64 (fixosec, p, vma);
1669
              }
1670
            break;
1671
 
1672
            case LOP_FIXR:
1673
              /* A fixup: Store YZ of this lopcode into YZ at vma - 4 * yz.  */
1674
              {
1675
                unsigned int yz = (y * 256 + z);
1676
                bfd_vma p = vma + 2 - 4 * yz;
1677
                asection *fixrsec = mmo_decide_section (abfd, p);
1678
                if (fixrsec == NULL)
1679
                  goto error_return;
1680
                mmo_xore_16 (fixrsec, p, yz);
1681
              }
1682
            break;
1683
 
1684
            case LOP_FIXRX:
1685
              /* A fixup, similar to lop_fixr, but taking larger numbers
1686
                 and can change branches into the opposite direction
1687
                 (gasp!).  */
1688
              {
1689
                bfd_vma delta;
1690
                bfd_vma p;
1691
                asection *fixrsec;
1692
 
1693
                if (y != 0)
1694
                  {
1695
                    (*_bfd_error_handler)
1696
                      (_("%s: invalid mmo file: expected y = 0, got y = %d for lop_fixrx\n"),
1697
                       bfd_get_filename (abfd), y);
1698
                    bfd_set_error (bfd_error_bad_value);
1699
                    goto error_return;
1700
                  }
1701
 
1702
                if (z != 16 && z != 24)
1703
                  {
1704
                    (*_bfd_error_handler)
1705
                      (_("%s: invalid mmo file: expected z = 16 or z = 24, got z = %d for lop_fixrx\n"),
1706
                       bfd_get_filename (abfd), z);
1707
                    bfd_set_error (bfd_error_bad_value);
1708
                    goto error_return;
1709
                  }
1710
 
1711
                /* Get the next 32-bit value.  */
1712
                if (bfd_bread (buf, 4, abfd) != 4)
1713
                  goto error_return;
1714
 
1715
                delta = bfd_get_32 (abfd, buf);
1716
 
1717
                /* Do an, ehm, involved calculation for the location of
1718
                   the fixup.  See mmixal documentation for a verbose
1719
                   explanation.  We follow it verbosely here for the
1720
                   readers delight.  */
1721
                if (buf[0] == 0)
1722
                  p = vma - 4 * delta;
1723
                else if (buf[0] == 1)
1724
                  p = vma - 4 * ((delta & 0xffffff) - (1 << z));
1725
                else
1726
                  {
1727
                    (*_bfd_error_handler)
1728
                      (_("%s: invalid mmo file: leading byte of operand word must be 0 or 1, got %d for lop_fixrx\n"),
1729
                       bfd_get_filename (abfd), buf[0]);
1730
                    bfd_set_error (bfd_error_bad_value);
1731
                    goto error_return;
1732
                  }
1733
 
1734
                fixrsec = mmo_decide_section (abfd, vma);
1735
                if (fixrsec == NULL)
1736
                  goto error_return;
1737
                mmo_xore_32 (fixrsec, p, delta);
1738
              }
1739
            break;
1740
 
1741
            case LOP_FILE:
1742
              /* Set current file and perhaps the file name.  Reset line
1743
                 number.  */
1744
              if (z != 0)
1745
                {
1746
                  char *fname = bfd_malloc (z * 4 + 1);
1747
 
1748
                  if (fname == NULL)
1749
                    {
1750
                      (*_bfd_error_handler)
1751
                        (_("%s: cannot allocate file name for file number %d, %d bytes\n"),
1752
                         bfd_get_filename (abfd), y, z * 4 + 1);
1753
                      bfd_set_error (bfd_error_system_call);
1754
                      goto error_return;
1755
                    }
1756
 
1757
                  fname[z * 4] = 0;
1758
 
1759
                  for (i = 0; i < z; i++)
1760
                    {
1761
                      if (bfd_bread (fname + i * 4, 4, abfd) != 4)
1762
                        {
1763
                          free (fname);
1764
                          goto error_return;
1765
                        }
1766
                    }
1767
 
1768
                  if (file_names[y] != NULL)
1769
                    {
1770
                      (*_bfd_error_handler)
1771
                        (_("%s: invalid mmo file: file number %d `%s',"
1772
                           " was already entered as `%s'\n"),
1773
                         bfd_get_filename (abfd), y, fname, file_names[y]);
1774
                      bfd_set_error (bfd_error_bad_value);
1775
                      goto error_return;
1776
                    }
1777
 
1778
                  file_names[y] = fname;
1779
                }
1780
 
1781
              if (file_names[y] == NULL)
1782
                {
1783
                  (*_bfd_error_handler)
1784
                    (_("%s: invalid mmo file: file name for number %d"
1785
                       " was not specified before use\n"),
1786
                     bfd_get_filename (abfd), y);
1787
                  bfd_set_error (bfd_error_bad_value);
1788
                  goto error_return;
1789
                }
1790
 
1791
              lineno = 0;
1792
              break;
1793
 
1794
            case LOP_LINE:
1795
              /* Set line number.  */
1796
              lineno = y * 256 + z;
1797
              /* FIXME: Create a sequence of mmo-specific line number
1798
                 entries for each section, then translate into canonical
1799
                 format.  */
1800
              break;
1801
 
1802
            case LOP_SPEC:
1803
              /* Special data follows until the next non-lop_quote
1804
                 lopcode.  */
1805
              non_spec_sec = sec;
1806
              non_spec_vma = vma;
1807
              sec = mmo_get_spec_section (abfd, y * 256 + z);
1808
              if (sec == NULL)
1809
                goto error_return;
1810
 
1811
              vma = sec->vma;
1812
              break;
1813
 
1814
            case LOP_PRE:
1815
              {
1816
                /* We ignore header information, except we read in the
1817
                   creation time from the first 32-bit word with the time
1818
                   in seconds since era.  */
1819
                if (z >= 1
1820
                    && bfd_bread (abfd->tdata.mmo_data->created, 4,
1821
                                 abfd) != 4)
1822
                  goto error_return;
1823
 
1824
                for (i = 1; i < z; i++)
1825
                  if (bfd_bread (buf, 4, abfd) != 4)
1826
                    goto error_return;
1827
              }
1828
              break;
1829
 
1830
            case LOP_POST:
1831
              /* This tells of the contents of registers $Z..$255 at
1832
                 startup.  We make a section out of it, with VMA = Z * 8,
1833
                 but only if Z != 255 or the contents is non-zero.  */
1834
              {
1835
                asection *rsec;
1836
                bfd_byte *loc;
1837
                bfd_vma first_octa;
1838
                bfd_vma startaddr_octa;
1839
 
1840
                /* Read first octaword outside loop to simplify logic when
1841
                   excluding the Z == 255, octa == 0 case.  */
1842
                if (bfd_bread (buf, 8, abfd) != 8)
1843
                  goto error_return;
1844
 
1845
                first_octa = bfd_get_64 (abfd, buf);
1846
 
1847
                /* Don't emit contents for the trivial case which is
1848
                   always present; $255 pointing to Main.  */
1849
                if (z != 255)
1850
                  {
1851
                    rsec
1852
                      = bfd_make_section_old_way (abfd,
1853
                                                  MMIX_REG_CONTENTS_SECTION_NAME);
1854
                    rsec->flags |= SEC_LINKER_CREATED;
1855
                    rsec->vma = z * 8;
1856
                    loc = mmo_get_loc (rsec, z * 8, (255 - z) * 8);
1857
                    bfd_put_64 (abfd, first_octa, loc);
1858
 
1859
                    for (i = z + 1; i < 255; i++)
1860
                      {
1861
                        if (bfd_bread (loc + (i - z) * 8, 8, abfd) != 8)
1862
                          goto error_return;
1863
                      }
1864
 
1865
                    /* Read out the last octabyte, and use it to set the
1866
                       start address.  */
1867
                    if (bfd_bread (buf, 8, abfd) != 8)
1868
                      goto error_return;
1869
 
1870
                    startaddr_octa = bfd_get_64 (abfd, buf);
1871
                  }
1872
                else
1873
                  startaddr_octa = first_octa;
1874
 
1875
                if (! bfd_set_start_address (abfd, startaddr_octa))
1876
                  {
1877
                    /* Currently this can't fail, but this should handle
1878
                       future failures.  */
1879
                    bfd_set_error (bfd_error_bad_value);
1880
                    goto error_return;
1881
                  }
1882
              }
1883
              break;
1884
 
1885
            case LOP_STAB:
1886
              /* We read in the symbols now, not later.  */
1887
              if (y != 0 || z != 0)
1888
                {
1889
                  (*_bfd_error_handler)
1890
                    (_("%s: invalid mmo file: fields y and z of lop_stab"
1891
                       " non-zero, y: %d, z: %d\n"),
1892
                     bfd_get_filename (abfd), y, z);
1893
                  bfd_set_error (bfd_error_bad_value);
1894
                  goto error_return;
1895
                }
1896
 
1897
              /* Save the location, so we can check that YZ in the LOP_END
1898
                 is correct.  */
1899
              stab_loc = bfd_tell (abfd);
1900
 
1901
              /* It's not said that an MMO can be without symbols (though
1902
                 mmixal will refuse to assemble files without Main), but
1903
                 it seems it would still be a valid mmo-file, so allow it.
1904
                 We detect the absence of a symbol area in that the upper
1905
                 limit is computed (from the lop_end YZ field) as 0.
1906
                 Don't call mmo_get_symbols; it can only detect the end of
1907
                 a valid symbol trie, not the absence of one.  */
1908
              if (abfd->tdata.mmo_data->max_symbol_length != 0
1909
                  && ! mmo_get_symbols (abfd))
1910
                goto error_return;
1911
              break;
1912
 
1913
            case LOP_END:
1914
              {
1915
                /* This must be the last 32-bit word in an mmo file.
1916
                   Let's find out.  */
1917
                struct stat statbuf;
1918
                file_ptr curpos = bfd_tell (abfd);
1919
 
1920
                if (bfd_stat (abfd, &statbuf) < 0)
1921
                  goto error_return;
1922
 
1923
                if (statbuf.st_size != curpos)
1924
                  {
1925
                    (*_bfd_error_handler)
1926
                      (_("%s: invalid mmo file: lop_end not last item in"
1927
                         " file\n"),
1928
                       bfd_get_filename (abfd));
1929
                    bfd_set_error (bfd_error_bad_value);
1930
                    goto error_return;
1931
                  }
1932
 
1933
                /* Check that the YZ field is right.  Subtract the size of
1934
                   this LOP_END in the calculation; YZ does not include
1935
                   it.  */
1936
                if ((long) (y * 256 + z) * 4 != (curpos - stab_loc) - 4)
1937
                  {
1938
                    (*_bfd_error_handler)
1939
                      (_("%s: invalid mmo file: YZ of lop_end (%ld)"
1940
                         " not equal to the number of tetras to the preceding"
1941
                         " lop_stab (%ld)\n"),
1942
                       bfd_get_filename (abfd), (long) (y * 256 + z),
1943
                       (curpos - stab_loc - 4)/4);
1944
                    bfd_set_error (bfd_error_bad_value);
1945
                    goto error_return;
1946
                  }
1947
 
1948
                bfd_map_over_sections (abfd, mmo_map_set_sizes, NULL);
1949
                goto done;
1950
              }
1951
            }
1952
        }
1953
      else
1954
        {
1955
          /* This wasn't a lopcode, so store it in the current section.  */
1956
          mmo_xore_32 (sec, vma & ~3, bfd_get_32 (abfd, buf));
1957
          vma += 4;
1958
          vma &= ~3;
1959
          lineno++;
1960
        }
1961
    }
1962
 
1963
  /* We know this file is a multiple of four bytes (checked in
1964
     mmo_object_p), so if we got something other than 0, this was a bad
1965
     file (although it's more likely we'll get 0 in that case too).
1966
     If we got end-of-file, then there was no lop_stab, so the file has
1967
     invalid format.  */
1968
 
1969
  if (nbytes_read != 0)
1970
    bfd_set_error (bfd_error_system_call);
1971
  else
1972
    bfd_set_error (bfd_error_bad_value);
1973
 
1974
 error_return:
1975
  error = TRUE;
1976
 done:
1977
  /* Mark the .text and .data section with their normal attribute if they
1978
     contain anything.  This is not redundant wrt. mmo_decide_section,
1979
     since that code might never execute, and conversely the alloc+code
1980
     section flags must be set then.  */
1981
  sec = bfd_get_section_by_name (abfd, MMO_TEXT_SECTION_NAME);
1982
  if (sec != NULL
1983
      && (bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS)
1984
      && ! bfd_set_section_flags (abfd, sec,
1985
                                  bfd_get_section_flags (abfd, sec)
1986
                                  | SEC_ALLOC | SEC_LOAD | SEC_CODE))
1987
    error = TRUE;
1988
 
1989
  sec = bfd_get_section_by_name (abfd, MMO_DATA_SECTION_NAME);
1990
  if (sec != NULL
1991
      && (bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS)
1992
      && ! bfd_set_section_flags (abfd, sec,
1993
                                  bfd_get_section_flags (abfd, sec)
1994
                                  | SEC_ALLOC | SEC_LOAD))
1995
    error = TRUE;
1996
 
1997
  /* Free whatever resources we took.  */
1998
  for (i = 0; i < sizeof (file_names) / sizeof (file_names[0]); i++)
1999
    if (file_names[i])
2000
      free (file_names[i]);
2001
  return ! error;
2002
}
2003
 
2004
/* A hook to set up object file dependent section information.  For mmo,
2005
   we point out the shape of allocated section contents.  */
2006
 
2007
static bfd_boolean
2008
mmo_new_section_hook (bfd *abfd, asection *newsect)
2009
{
2010
  if (!newsect->used_by_bfd)
2011
    {
2012
      /* We zero-fill all fields and assume NULL is represented by an all
2013
         zero-bit pattern.  */
2014
      newsect->used_by_bfd
2015
        = bfd_zalloc (abfd, sizeof (struct mmo_section_data_struct));
2016
      if (!newsect->used_by_bfd)
2017
        return FALSE;
2018
    }
2019
 
2020
  /* Always align to at least 32-bit words.  */
2021
  newsect->alignment_power = 2;
2022
  return _bfd_generic_new_section_hook (abfd, newsect);
2023
}
2024
 
2025
/* We already have section contents loaded for sections that have
2026
   contents.  */
2027
 
2028
static bfd_boolean
2029
mmo_get_section_contents (bfd *abfd ATTRIBUTE_UNUSED,
2030
                          asection *sec,
2031
                          void * location,
2032
                          file_ptr offset,
2033
                          bfd_size_type bytes_to_do)
2034
{
2035
  /* Iterate over diminishing chunk sizes, copying contents, like
2036
     mmo_set_section_contents.  */
2037
  while (bytes_to_do)
2038
    {
2039
      /* A minor song-and-dance to make sure we're not bitten by the
2040
         distant possibility of the cast from bfd_vma to int making the
2041
         chunk zero-sized.  */
2042
      int chunk_size
2043
        = (int) bytes_to_do != 0 ? bytes_to_do : MMO_SEC_CONTENTS_CHUNK_SIZE;
2044
      bfd_byte *loc;
2045
 
2046
      do
2047
        loc = mmo_get_loc (sec, sec->vma + offset, chunk_size);
2048
      while (loc == NULL && (chunk_size /= 2) != 0);
2049
 
2050
      if (chunk_size == 0)
2051
        return FALSE;
2052
 
2053
      memcpy (location, loc, chunk_size);
2054
 
2055
      location += chunk_size;
2056
      bytes_to_do -= chunk_size;
2057
      offset += chunk_size;
2058
    }
2059
  return TRUE;
2060
}
2061
 
2062
/* Return the amount of memory needed to read the symbol table.  */
2063
 
2064
static long
2065
mmo_get_symtab_upper_bound (bfd *abfd)
2066
{
2067
  return (abfd->symcount + 1) * sizeof (asymbol *);
2068
}
2069
 
2070
/* Sort mmo symbols by serial number.  */
2071
 
2072
static int
2073
mmo_sort_mmo_symbols (const void *arg1, const void *arg2)
2074
{
2075
  const struct mmo_symbol *sym1 = *(const struct mmo_symbol **) arg1;
2076
  const struct mmo_symbol *sym2 = *(const struct mmo_symbol **) arg2;
2077
 
2078
  /* Sort by serial number first.  */
2079
  if (sym1->serno < sym2->serno)
2080
    return -1;
2081
  else if (sym1->serno > sym2->serno)
2082
    return 1;
2083
 
2084
  /* Then sort by address of the table entries.  */
2085
  return ((const char *) arg1 - (const char *) arg2);
2086
}
2087
 
2088
/* Translate the symbol table.  */
2089
 
2090
static long
2091
mmo_canonicalize_symtab (bfd *abfd, asymbol **alocation)
2092
{
2093
  unsigned int symcount = bfd_get_symcount (abfd);
2094
  asymbol *csymbols;
2095
  unsigned int i;
2096
 
2097
  csymbols = abfd->tdata.mmo_data->csymbols;
2098
  if (csymbols == NULL && symcount != 0)
2099
    {
2100
      asymbol *c;
2101
      struct mmo_symbol *s;
2102
      struct mmo_symbol **msp;
2103
 
2104
      /* First we store the symbols into the table we'll return, then we
2105
         qsort it on the serial number, with secondary on the address of
2106
         the symbol, to preserve order if there would be non-unique serial
2107
         numbers.  */
2108
      for (s = abfd->tdata.mmo_data->symbols,
2109
             msp = (struct mmo_symbol **) alocation;
2110
           s != NULL;
2111
           s = s->next, ++msp)
2112
        *msp = s;
2113
 
2114
      *msp = NULL;
2115
 
2116
      qsort (alocation, symcount, sizeof (struct mmo_symbol *),
2117
             mmo_sort_mmo_symbols);
2118
 
2119
      csymbols = (asymbol *) bfd_alloc (abfd, symcount * sizeof (asymbol));
2120
      if (csymbols == NULL)
2121
        return -1;
2122
      abfd->tdata.mmo_data->csymbols = csymbols;
2123
 
2124
      for (msp = (struct mmo_symbol **) alocation, c = csymbols;
2125
           *msp != NULL;
2126
           msp++, ++c)
2127
        {
2128
          s = *msp;
2129
          c->the_bfd = abfd;
2130
          c->name = s->name;
2131
          c->value = s->value;
2132
          c->flags = BSF_GLOBAL;
2133
 
2134
          if (s->sym_type == mmo_data_sym)
2135
            {
2136
              c->section
2137
                = bfd_get_section_by_name (abfd, MMO_DATA_SECTION_NAME);
2138
 
2139
              if (c->section == NULL)
2140
                c->section = bfd_abs_section_ptr;
2141
              else
2142
                c->value -= c->section->vma;
2143
            }
2144
          else if (s->sym_type == mmo_undef_sym)
2145
            c->section = bfd_und_section_ptr;
2146
          else if (s->sym_type == mmo_reg_sym)
2147
            {
2148
              c->section
2149
                = bfd_make_section_old_way (abfd, MMIX_REG_SECTION_NAME);
2150
              c->section->flags |= SEC_LINKER_CREATED;
2151
            }
2152
          else
2153
            {
2154
              asection *textsec
2155
                = bfd_get_section_by_name (abfd, MMO_TEXT_SECTION_NAME);
2156
              asection *datasec;
2157
 
2158
              if (textsec != NULL
2159
                  && c->value >= textsec->vma
2160
                  && c->value <= textsec->vma + textsec->size)
2161
                {
2162
                  c->section = textsec;
2163
                  c->value -= c->section->vma;
2164
                }
2165
              /* In mmo, symbol types depend on the VMA.  Therefore, if
2166
                 the data section isn't within the usual bounds, its
2167
                 symbols are marked as absolute.  Correct that.  This
2168
                 means we can't have absolute symbols with values matching
2169
                 data section addresses, but we also can't have with
2170
                 absolute symbols with values matching text section
2171
                 addresses.  For such needs, use the ELF format.  */
2172
              else if ((datasec
2173
                        = bfd_get_section_by_name (abfd,
2174
                                                   MMO_DATA_SECTION_NAME))
2175
                       != NULL
2176
                       && c->value >= datasec->vma
2177
                       && c->value <= datasec->vma + datasec->size)
2178
                {
2179
                  c->section = datasec;
2180
                  c->value -= c->section->vma;
2181
                }
2182
              else
2183
                c->section = bfd_abs_section_ptr;
2184
            }
2185
 
2186
          c->udata.p = NULL;
2187
        }
2188
    }
2189
 
2190
  /* Last, overwrite the incoming table with the right-type entries.  */
2191
  for (i = 0; i < symcount; i++)
2192
    *alocation++ = csymbols++;
2193
  *alocation = NULL;
2194
 
2195
  return symcount;
2196
}
2197
 
2198
/* Get information about a symbol.  */
2199
 
2200
static void
2201
mmo_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED,
2202
                     asymbol *symbol, symbol_info *ret)
2203
{
2204
  bfd_symbol_info (symbol, ret);
2205
}
2206
 
2207
static void
2208
mmo_print_symbol (bfd *abfd, void *afile, asymbol *symbol,
2209
                  bfd_print_symbol_type how)
2210
{
2211
  FILE *file = (FILE *) afile;
2212
 
2213
  switch (how)
2214
    {
2215
    case bfd_print_symbol_name:
2216
      fprintf (file, "%s", symbol->name);
2217
      break;
2218
    default:
2219
      bfd_print_symbol_vandf (abfd, file, symbol);
2220
 
2221
      fprintf (file, " %-5s %s",
2222
               symbol->section->name,
2223
               symbol->name);
2224
    }
2225
}
2226
 
2227
/* We can't map a file directly into executable code, so the
2228
   size of header information is irrelevant.  */
2229
 
2230
static int
2231
mmo_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
2232
                    struct bfd_link_info *info ATTRIBUTE_UNUSED)
2233
{
2234
  return 0;
2235
}
2236
 
2237
/* Write the (section-neutral) file preamble.  */
2238
 
2239
static bfd_boolean
2240
mmo_internal_write_header (bfd *abfd)
2241
{
2242
  const char lop_pre_bfd[] = { LOP, LOP_PRE, 1, 1};
2243
 
2244
  if (bfd_bwrite (lop_pre_bfd, 4, abfd) != 4)
2245
    return FALSE;
2246
 
2247
  /* Copy creation time of original file.  */
2248
  if (bfd_bwrite (abfd->tdata.mmo_data->created, 4, abfd) != 4)
2249
    return FALSE;
2250
 
2251
  return TRUE;
2252
}
2253
 
2254
/* Write the LOP_POST record, with global register initializations.
2255
   Z is the Z field of the LOP_POST, corresponding to 255 - number of
2256
   registers at DATA.  The Z = 255 field is filled in with the
2257
   start-address.  */
2258
 
2259
static bfd_boolean
2260
mmo_internal_write_post (bfd *abfd, int z, asection *sec)
2261
{
2262
  int i;
2263
  bfd_byte buf[8];
2264
  mmo_write_tetra_raw (abfd, (LOP << 24) | (LOP_POST << 16) | z);
2265
 
2266
  for (i = z; i < 255; i++)
2267
    {
2268
      bfd_byte *data = mmo_get_loc (sec, i * 8, 8);
2269
 
2270
      if (bfd_bwrite (data, 8, abfd) != 8)
2271
        return FALSE;
2272
    }
2273
 
2274
  /* For Z == $255, we always emit the start location; supposedly Main,
2275
     but we have it handy at bfd_get_start_address.  If we're called with
2276
     Z == 255, don't assume DATA is valid.  */
2277
  bfd_put_64 (abfd, bfd_get_start_address (abfd), buf);
2278
 
2279
  return ! abfd->tdata.mmo_data->have_error && bfd_bwrite (buf, 8, abfd) == 8;
2280
}
2281
 
2282
/* Translate to and from BFD flags.  This is to make sure that we don't
2283
   get bitten by BFD flag number changes.  */
2284
 
2285
static flagword
2286
mmo_sec_flags_from_bfd_flags (flagword flags)
2287
{
2288
  flagword oflags = 0;
2289
 
2290
  if (flags & SEC_ALLOC)
2291
    oflags |= MMO_SEC_ALLOC;
2292
  if (flags & SEC_LOAD)
2293
    oflags |= MMO_SEC_LOAD;
2294
  if (flags & SEC_RELOC)
2295
    oflags |= MMO_SEC_RELOC;
2296
  if (flags & SEC_READONLY)
2297
    oflags |= MMO_SEC_READONLY;
2298
  if (flags & SEC_CODE)
2299
    oflags |= MMO_SEC_CODE;
2300
  if (flags & SEC_DATA)
2301
    oflags |= MMO_SEC_DATA;
2302
  if (flags & SEC_NEVER_LOAD)
2303
    oflags |= MMO_SEC_NEVER_LOAD;
2304
  if (flags & SEC_IS_COMMON)
2305
    oflags |= MMO_SEC_IS_COMMON;
2306
  if (flags & SEC_DEBUGGING)
2307
    oflags |= MMO_SEC_DEBUGGING;
2308
 
2309
  return oflags;
2310
}
2311
 
2312
static flagword
2313
bfd_sec_flags_from_mmo_flags (flagword flags)
2314
{
2315
  flagword oflags = 0;
2316
 
2317
  if (flags & MMO_SEC_ALLOC)
2318
    oflags |= SEC_ALLOC;
2319
  if (flags & MMO_SEC_LOAD)
2320
    oflags |= SEC_LOAD;
2321
  if (flags & MMO_SEC_RELOC)
2322
    oflags |= SEC_RELOC;
2323
  if (flags & MMO_SEC_READONLY)
2324
    oflags |= SEC_READONLY;
2325
  if (flags & MMO_SEC_CODE)
2326
    oflags |= SEC_CODE;
2327
  if (flags & MMO_SEC_DATA)
2328
    oflags |= SEC_DATA;
2329
  if (flags & MMO_SEC_NEVER_LOAD)
2330
    oflags |= SEC_NEVER_LOAD;
2331
  if (flags & MMO_SEC_IS_COMMON)
2332
    oflags |= SEC_IS_COMMON;
2333
  if (flags & MMO_SEC_DEBUGGING)
2334
    oflags |= SEC_DEBUGGING;
2335
 
2336
  return oflags;
2337
}
2338
 
2339
/* Return TRUE iff the leading or trailing tetrabyte in SEC is defined and
2340
   is 0.  */
2341
 
2342
static bfd_boolean
2343
mmo_has_leading_or_trailing_zero_tetra_p (bfd *abfd, asection *sec)
2344
{
2345
  bfd_vma secaddr = bfd_get_section_vma (abfd, sec);
2346
 
2347
  if (sec->size < 4)
2348
    return FALSE;
2349
 
2350
  if (bfd_get_32 (abfd, mmo_get_loc (sec, secaddr, 4)) == 0
2351
      && bfd_get_32 (abfd,
2352
                     mmo_get_loc (sec, secaddr + sec->size - 4, 4)) == 0)
2353
    return TRUE;
2354
 
2355
  return FALSE;
2356
}
2357
 
2358
/* Write a section.  */
2359
 
2360
static bfd_boolean
2361
mmo_internal_write_section (bfd *abfd, asection *sec)
2362
{
2363
  /* We do it differently depending on what section this is:
2364
 
2365
   ".text": Output, prepended by information about the first source file
2366
   (not yet implemented.)
2367
 
2368
   ".data": Output.
2369
 
2370
   (".MMIX.reg_contents": Not handled here.)
2371
 
2372
   Anything else: Output inside a lop_spec 80, in the format described
2373
   above.  */
2374
 
2375
  if (strcmp (sec->name, MMO_TEXT_SECTION_NAME) == 0)
2376
    {
2377
      bfd_vma secaddr = bfd_get_section_vma (abfd, sec);
2378
 
2379
      /* Because leading and trailing zeros are omitted in output, we need to
2380
         specify the section boundaries so they're correct when the file
2381
         is read in again.  That's also the case if this section is
2382
         specified as not within its usual boundaries or alignments.  */
2383
      if (sec->size != 0
2384
          && (secaddr + sec->size >= (bfd_vma) 1 << 56
2385
              || (secaddr & 3) != 0
2386
              || (sec->size & 3) != 0
2387
              || mmo_has_leading_or_trailing_zero_tetra_p (abfd, sec)))
2388
        {
2389
          if (!mmo_write_section_description (abfd, sec))
2390
            return FALSE;
2391
        }
2392
 
2393
      /* FIXME: Output source file name and line number.  */
2394
      return mmo_write_loc_chunk_list (abfd, mmo_section_data (sec)->head);
2395
    }
2396
  else if (strcmp (sec->name, MMO_DATA_SECTION_NAME) == 0)
2397
    {
2398
      bfd_vma secaddr = bfd_get_section_vma (abfd, sec);
2399
 
2400
      /* Same goes as for MMO_TEXT_SECTION_NAME above.  */
2401
      if (sec->size != 0
2402
          && (secaddr < (bfd_vma) 0x20 << 56
2403
              || secaddr + sec->size >= (bfd_vma) 0x21 << 56
2404
              || (secaddr & 3) != 0
2405
              || (sec->size & 3) != 0
2406
              || mmo_has_leading_or_trailing_zero_tetra_p (abfd, sec)))
2407
        {
2408
          if (!mmo_write_section_description (abfd, sec))
2409
            return FALSE;
2410
        }
2411
 
2412
      return mmo_write_loc_chunk_list (abfd, mmo_section_data (sec)->head);
2413
    }
2414
  else if (strcmp (sec->name, MMIX_REG_CONTENTS_SECTION_NAME) == 0)
2415
    /* Not handled here.  */
2416
    {
2417
      /* This would normally be an abort call since this can't happen, but
2418
         we don't do that.  */
2419
      bfd_set_error (bfd_error_bad_value);
2420
      return FALSE;
2421
    }
2422
  else if (CONST_STRNEQ (sec->name, MMIX_OTHER_SPEC_SECTION_PREFIX))
2423
    {
2424
      int n = atoi (sec->name + strlen (MMIX_OTHER_SPEC_SECTION_PREFIX));
2425
 
2426
      mmo_write_tetra_raw (abfd, (LOP << 24) | (LOP_SPEC << 16) | n);
2427
      return (! abfd->tdata.mmo_data->have_error
2428
              && mmo_write_chunk_list (abfd, mmo_section_data (sec)->head));
2429
    }
2430
  /* Ignore sections that are just allocated or empty; we write out
2431
     _contents_ here.  */
2432
  else if ((bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS) != 0
2433
           && sec->size != 0)
2434
    {
2435
      if (!mmo_write_section_description (abfd, sec))
2436
        return FALSE;
2437
 
2438
      /* Writing a LOP_LOC ends the LOP_SPEC data, and makes data actually
2439
         loaded.  */
2440
      if (bfd_get_section_flags (abfd, sec) & SEC_LOAD)
2441
        return (! abfd->tdata.mmo_data->have_error
2442
                && mmo_write_loc_chunk_list (abfd,
2443
                                         mmo_section_data (sec)->head));
2444
      return (! abfd->tdata.mmo_data->have_error
2445
              && mmo_write_chunk_list (abfd, mmo_section_data (sec)->head));
2446
    }
2447
 
2448
  /* Some section without contents.  */
2449
  return TRUE;
2450
}
2451
 
2452
/* Write the description of a section, extended-mmo-style.  */
2453
 
2454
static bfd_boolean
2455
mmo_write_section_description (bfd *abfd, asection *sec)
2456
{
2457
  /* Keep the following document-comment formatted the way it is.  */
2458
/*
2459
INODE
2460
mmo section mapping, , Symbol-table, mmo
2461
SUBSECTION
2462
        mmo section mapping
2463
 
2464
        The implementation in BFD uses special data type 80 (decimal) to
2465
        encapsulate and describe named sections, containing e.g.@: debug
2466
        information.  If needed, any datum in the encapsulation will be
2467
        quoted using lop_quote.  First comes a 32-bit word holding the
2468
        number of 32-bit words containing the zero-terminated zero-padded
2469
        segment name.  After the name there's a 32-bit word holding flags
2470
        describing the section type.  Then comes a 64-bit big-endian word
2471
        with the section length (in bytes), then another with the section
2472
        start address.  Depending on the type of section, the contents
2473
        might follow, zero-padded to 32-bit boundary.  For a loadable
2474
        section (such as data or code), the contents might follow at some
2475
        later point, not necessarily immediately, as a lop_loc with the
2476
        same start address as in the section description, followed by the
2477
        contents.  This in effect forms a descriptor that must be emitted
2478
        before the actual contents.  Sections described this way must not
2479
        overlap.
2480
 
2481
        For areas that don't have such descriptors, synthetic sections are
2482
        formed by BFD.  Consecutive contents in the two memory areas
2483
        @samp{0x0000@dots{}00} to @samp{0x01ff@dots{}ff} and
2484
        @samp{0x2000@dots{}00} to @samp{0x20ff@dots{}ff} are entered in
2485
        sections named <<.text>> and <<.data>> respectively.  If an area
2486
        is not otherwise described, but would together with a neighboring
2487
        lower area be less than @samp{0x40000000} bytes long, it is joined
2488
        with the lower area and the gap is zero-filled.  For other cases,
2489
        a new section is formed, named <<.MMIX.sec.@var{n}>>.  Here,
2490
        @var{n} is a number, a running count through the mmo file,
2491
        starting at 0.
2492
 
2493
EXAMPLE
2494
        A loadable section specified as:
2495
 
2496
| .section secname,"ax"
2497
| TETRA 1,2,3,4,-1,-2009
2498
| BYTE 80
2499
 
2500
        and linked to address @samp{0x4}, is represented by the sequence:
2501
 
2502
| 0x98080050 - lop_spec 80
2503
| 0x00000002 - two 32-bit words for the section name
2504
| 0x7365636e - "secn"
2505
| 0x616d6500 - "ame\0"
2506
| 0x00000033 - flags CODE, READONLY, LOAD, ALLOC
2507
| 0x00000000 - high 32 bits of section length
2508
| 0x0000001c - section length is 28 bytes; 6 * 4 + 1 + alignment to 32 bits
2509
| 0x00000000 - high 32 bits of section address
2510
| 0x00000004 - section address is 4
2511
| 0x98010002 - 64 bits with address of following data
2512
| 0x00000000 - high 32 bits of address
2513
| 0x00000004 - low 32 bits: data starts at address 4
2514
| 0x00000001 - 1
2515
| 0x00000002 - 2
2516
| 0x00000003 - 3
2517
| 0x00000004 - 4
2518
| 0xffffffff - -1
2519
| 0xfffff827 - -2009
2520
| 0x50000000 - 80 as a byte, padded with zeros.
2521
 
2522
        Note that the lop_spec wrapping does not include the section
2523
        contents.  Compare this to a non-loaded section specified as:
2524
 
2525
| .section thirdsec
2526
| TETRA 200001,100002
2527
| BYTE 38,40
2528
 
2529
        This, when linked to address @samp{0x200000000000001c}, is
2530
        represented by:
2531
 
2532
| 0x98080050 - lop_spec 80
2533
| 0x00000002 - two 32-bit words for the section name
2534
| 0x7365636e - "thir"
2535
| 0x616d6500 - "dsec"
2536
| 0x00000010 - flag READONLY
2537
| 0x00000000 - high 32 bits of section length
2538
| 0x0000000c - section length is 12 bytes; 2 * 4 + 2 + alignment to 32 bits
2539
| 0x20000000 - high 32 bits of address
2540
| 0x0000001c - low 32 bits of address 0x200000000000001c
2541
| 0x00030d41 - 200001
2542
| 0x000186a2 - 100002
2543
| 0x26280000 - 38, 40 as bytes, padded with zeros
2544
 
2545
        For the latter example, the section contents must not be
2546
        loaded in memory, and is therefore specified as part of the
2547
        special data.  The address is usually unimportant but might
2548
        provide information for e.g.@: the DWARF 2 debugging format.  */
2549
 
2550
  mmo_write_tetra_raw (abfd, LOP_SPEC_SECTION);
2551
  mmo_write_tetra (abfd, (strlen (sec->name) + 3) / 4);
2552
  mmo_write_chunk (abfd, (bfd_byte *) sec->name, strlen (sec->name));
2553
  mmo_flush_chunk (abfd);
2554
  /* FIXME: We can get debug sections (.debug_line & Co.) with a section
2555
     flag still having SEC_RELOC set.  Investigate.  This might be true
2556
     for all alien sections; perhaps mmo.em should clear that flag.  Might
2557
     be related to weak references.  */
2558
  mmo_write_tetra (abfd,
2559
                   mmo_sec_flags_from_bfd_flags
2560
                   (bfd_get_section_flags (abfd, sec)));
2561
  mmo_write_octa (abfd, sec->size);
2562
  mmo_write_octa (abfd, bfd_get_section_vma (abfd, sec));
2563
  return TRUE;
2564
}
2565
 
2566
/* We save up all data before output.  */
2567
 
2568
static bfd_boolean
2569
mmo_set_section_contents (bfd *abfd ATTRIBUTE_UNUSED, sec_ptr sec,
2570
                          const void *location, file_ptr offset,
2571
                          bfd_size_type bytes_to_do)
2572
{
2573
  /* Iterate over diminishing chunk sizes, copying contents.  */
2574
  while (bytes_to_do)
2575
    {
2576
      /* A minor song-and-dance to make sure we're not bitten by the
2577
         distant possibility of the cast from bfd_vma to int making the
2578
         chunk zero-sized.  */
2579
      int chunk_size
2580
        = (int) bytes_to_do != 0 ? bytes_to_do : MMO_SEC_CONTENTS_CHUNK_SIZE;
2581
      bfd_byte *loc;
2582
 
2583
      do
2584
        loc = mmo_get_loc (sec, sec->vma + offset, chunk_size);
2585
      while (loc == NULL && (chunk_size /= 2) != 0);
2586
 
2587
      if (chunk_size == 0)
2588
        return FALSE;
2589
 
2590
      memcpy (loc, location, chunk_size);
2591
 
2592
      location += chunk_size;
2593
      bytes_to_do -= chunk_size;
2594
      offset += chunk_size;
2595
    }
2596
  return TRUE;
2597
}
2598
 
2599
/* Add a symbol to a trie-tree.  */
2600
 
2601
static bfd_boolean
2602
mmo_internal_add_3_sym (bfd *abfd, struct mmo_symbol_trie *rootp,
2603
                        const struct mmo_symbol *symp)
2604
{
2605
  const char *name = symp->name;
2606
  struct mmo_symbol_trie *trie = rootp;
2607
  struct mmo_symbol_trie **triep = NULL;
2608
 
2609
  while (*name && trie != NULL)
2610
    {
2611
      if (*name < trie->symchar)
2612
        {
2613
          triep = &trie->left;
2614
          trie = trie->left;
2615
        }
2616
      else if (*name > trie->symchar)
2617
        {
2618
          triep = &trie->right;
2619
          trie = trie->right;
2620
        }
2621
      else if (*name == trie->symchar)
2622
        {
2623
          triep = &trie->middle;
2624
          name++;
2625
 
2626
          /* Make sure "trie" points to where we should fill in the
2627
             current symbol whenever we've iterated through "name".  We
2628
             would lose the right position if we encounter "foobar" then
2629
             "foo".  */
2630
          if (*name)
2631
            trie = trie->middle;
2632
        }
2633
    }
2634
 
2635
  while (*name != 0)
2636
    {
2637
      /* Create middle branches for the rest of the characters.  */
2638
      trie = bfd_zalloc (abfd, sizeof (struct mmo_symbol_trie));
2639
      *triep = trie;
2640
      trie->symchar = *name++;
2641
      triep = &trie->middle;
2642
    }
2643
 
2644
  /* We discover a duplicate symbol rather late in the process, but still;
2645
     we discover it and bail out.  */
2646
  if (trie->sym.name != NULL)
2647
    {
2648
      (*_bfd_error_handler)
2649
        (_("%s: invalid symbol table: duplicate symbol `%s'\n"),
2650
         bfd_get_filename (abfd), trie->sym.name);
2651
      bfd_set_error (bfd_error_bad_value);
2652
      return FALSE;
2653
    }
2654
 
2655
  memcpy (&trie->sym, symp, sizeof *symp);
2656
  return TRUE;
2657
}
2658
 
2659
/* Find out the length of the serialized version of a trie in bytes.  */
2660
 
2661
static unsigned int
2662
mmo_internal_3_length (bfd *abfd, struct mmo_symbol_trie *trie)
2663
{
2664
  /* First, one for the control byte.  */
2665
  unsigned int length = 1;
2666
 
2667
  if (trie == NULL)
2668
    return 0;
2669
 
2670
  /* Add in the recursion to the left.  */
2671
  length += mmo_internal_3_length (abfd, trie->left);
2672
 
2673
  /* Add in the middle trie and the character.  */
2674
  length += 1 + mmo_internal_3_length (abfd, trie->middle);
2675
 
2676
  /* Add in the recursion to the right.  */
2677
  length += mmo_internal_3_length (abfd, trie->right);
2678
 
2679
  /* Add in bytes for the symbol (if this is an endnode). */
2680
  if (trie->sym.name != NULL)
2681
    {
2682
      unsigned int serno = trie->sym.serno;
2683
 
2684
      /* First what it takes to encode the value. */
2685
      if (trie->sym.sym_type == mmo_reg_sym)
2686
        length++;
2687
      else if (trie->sym.sym_type == mmo_undef_sym)
2688
        length += 2;
2689
      else
2690
        {
2691
          bfd_vma value = trie->sym.value;
2692
 
2693
          /* Coded in one to eight following bytes.  */
2694
          if (trie->sym.sym_type == mmo_data_sym)
2695
            value -= (bfd_vma) 0x20 << 56;
2696
 
2697
          do
2698
            {
2699
              value >>= 8;
2700
              length++;
2701
            }
2702
          while (value != 0);
2703
        }
2704
 
2705
      /* Find out what it takes to encode the serial number.  */
2706
      do
2707
        {
2708
          serno >>= 7;
2709
          length++;
2710
        }
2711
      while (serno != 0);
2712
    }
2713
 
2714
  return length;
2715
}
2716
 
2717
/* Helper function for outputting the serial number of a symbol, output as
2718
   a variant of leb128 (see dwarf2 documentation) which could be called
2719
   beb128.  Using a helper function and recursion simplifies debugging.  */
2720
 
2721
static void
2722
mmo_beb128_out (bfd *abfd, int serno, int marker)
2723
{
2724
  if (serno & ~0x7f)
2725
    mmo_beb128_out (abfd, serno >> 7, 0);
2726
  mmo_write_byte (abfd, marker | (serno & 0x7f));
2727
}
2728
 
2729
/* Serialize a trie.  */
2730
 
2731
static void
2732
mmo_internal_3_dump (bfd *abfd, struct mmo_symbol_trie *trie)
2733
{
2734
  bfd_byte control = 0;
2735
 
2736
  if (trie == NULL)
2737
    return;
2738
 
2739
  if (trie->left)
2740
    control |= MMO3_LEFT;
2741
 
2742
  if (trie->middle)
2743
    control |= MMO3_MIDDLE;
2744
 
2745
  if (trie->right)
2746
    control |= MMO3_RIGHT;
2747
 
2748
  if (trie->sym.name != NULL)
2749
    {
2750
      /* Encode the symbol type and length of value bytes.  */
2751
      if (trie->sym.sym_type == mmo_reg_sym)
2752
        control |= MMO3_REGQUAL_BITS;
2753
      else if (trie->sym.sym_type == mmo_undef_sym)
2754
        control |= MMO3_UNDEF;
2755
      else
2756
        {
2757
          bfd_vma value = trie->sym.value;
2758
 
2759
          /* Coded in 1..8 following bytes.  */
2760
          if (trie->sym.sym_type == mmo_data_sym)
2761
            {
2762
              control |= MMO3_DATA;
2763
              value -= (bfd_vma) 0x20 << 56;
2764
            }
2765
 
2766
          do
2767
            {
2768
              value >>= 8;
2769
              control++;
2770
            }
2771
          while (value != 0);
2772
        }
2773
    }
2774
 
2775
  /* The control byte is output before recursing.  */
2776
  mmo_write_byte (abfd, control);
2777
 
2778
  mmo_internal_3_dump (abfd, trie->left);
2779
 
2780
  if (control & MMO3_SYMBITS)
2781
    {
2782
      mmo_write_byte (abfd, trie->symchar);
2783
 
2784
      if (trie->sym.name != NULL)
2785
        {
2786
          if (trie->sym.sym_type == mmo_reg_sym)
2787
            mmo_write_byte (abfd, trie->sym.value);
2788
          else if (trie->sym.sym_type == mmo_undef_sym)
2789
            {
2790
              mmo_write_byte (abfd, 0);
2791
              mmo_write_byte (abfd, 0);
2792
            }
2793
          else
2794
            {
2795
              bfd_vma value = trie->sym.value;
2796
 
2797
              bfd_byte byte_n = control & 15;
2798
 
2799
              /* Coded in 1..8 following bytes.  Note that the value is
2800
                 shifted out big-endian.  */
2801
              if (trie->sym.sym_type == mmo_data_sym)
2802
                {
2803
                  value -= (bfd_vma) 0x20 << 56;
2804
                  byte_n -= 8;
2805
                }
2806
 
2807
              do
2808
                {
2809
                  mmo_write_byte (abfd, (value >> ((byte_n - 1) * 8)) & 0xff);
2810
                  byte_n--;
2811
                }
2812
              while (byte_n != 0);
2813
            }
2814
 
2815
          mmo_beb128_out (abfd, trie->sym.serno, 128);
2816
        }
2817
      mmo_internal_3_dump (abfd, trie->middle);
2818
    }
2819
  mmo_internal_3_dump (abfd, trie->right);
2820
}
2821
 
2822
/* Write symbols in mmo format.  Also write the lop_end terminator.  */
2823
 
2824
static bfd_boolean
2825
mmo_write_symbols_and_terminator (bfd *abfd)
2826
{
2827
  int count = bfd_get_symcount (abfd);
2828
  asymbol **table;
2829
  asymbol **orig_table = bfd_get_outsymbols (abfd);
2830
  int serno;
2831
  struct mmo_symbol_trie root;
2832
  int trie_len;
2833
  int i;
2834
  bfd_byte buf[4];
2835
 
2836
  /* Create a symbol for "Main".  */
2837
  asymbol *fakemain = bfd_make_empty_symbol (abfd);
2838
 
2839
  fakemain->flags = BSF_GLOBAL;
2840
  fakemain->value = bfd_get_start_address (abfd);
2841
  fakemain->name = MMIX_START_SYMBOL_NAME;
2842
  fakemain->section = bfd_abs_section_ptr;
2843
 
2844
  memset (&root, 0, sizeof (root));
2845
 
2846
  /* Make all symbols take a left turn.  */
2847
  root.symchar = 0xff;
2848
 
2849
  /* There must always be a ":Main", so we'll add one if there are no
2850
     symbols.  Make sure we have room for it.  */
2851
  table = bfd_alloc (abfd, (count + 1) * sizeof (asymbol *));
2852
  if (table == NULL)
2853
    return FALSE;
2854
 
2855
  memcpy (table, orig_table, count * sizeof (asymbol *));
2856
 
2857
  /* Move :Main (if there is one) to the first position.  This is
2858
     necessary to get the same layout of the trie-tree when linking as
2859
     when objcopying the result as in the objcopy.exp test "simple objcopy
2860
     of executable".  It also automatically takes care of assigning serial
2861
     number 1 to :Main (as is mandatory).  */
2862
  for (i = 0; i < count; i++)
2863
    if (table[i] != NULL
2864
        && strcmp (table[i]->name, MMIX_START_SYMBOL_NAME) == 0
2865
        && (table[i]->flags & (BSF_DEBUGGING|BSF_GLOBAL)) == BSF_GLOBAL)
2866
      {
2867
        asymbol *mainsym = table[i];
2868
        memcpy (table + 1, orig_table, i * sizeof (asymbol *));
2869
        table[0] = mainsym;
2870
 
2871
        /* Check that the value assigned to :Main is the same as the entry
2872
           address.  The default linker script asserts this.  This is as
2873
           good a place as any to check this consistency. */
2874
        if ((mainsym->value
2875
             + mainsym->section->output_section->vma
2876
             + mainsym->section->output_offset)
2877
            != bfd_get_start_address (abfd))
2878
          {
2879
            /* Arbitrary buffer to hold the printable representation of a
2880
               vma.  */
2881
            char vmas_main[40];
2882
            char vmas_start[40];
2883
            bfd_vma vma_start = bfd_get_start_address (abfd);
2884
 
2885
            sprintf_vma (vmas_main, mainsym->value);
2886
            sprintf_vma (vmas_start, vma_start);
2887
 
2888
            (*_bfd_error_handler)
2889
              (_("%s: Bad symbol definition: `Main' set to %s rather"
2890
                 " than the start address %s\n"),
2891
               bfd_get_filename (abfd), vmas_main, vmas_start);
2892
            bfd_set_error (bfd_error_bad_value);
2893
            return FALSE;
2894
          }
2895
        break;
2896
      }
2897
  if (i == count && count != 0)
2898
    {
2899
      /* When there are symbols, there must be a :Main.  There was no
2900
         :Main, so we need to add it manually.  */
2901
      memcpy (table + 1, orig_table, count * sizeof (asymbol *));
2902
      table[0] = fakemain;
2903
      count++;
2904
    }
2905
 
2906
  for (i = 0, serno = 1; i < count && table[i] != NULL; i++)
2907
    {
2908
      asymbol *s = table[i];
2909
 
2910
      /* It's not enough to consult bfd_is_local_label, since it does not
2911
         mean "local" in the sense of linkable-and-observable-after-link.
2912
         Let's just check the BSF_GLOBAL flag.
2913
 
2914
         Also, don't export symbols with characters not in the allowed set.  */
2915
      if ((s->flags & (BSF_DEBUGGING|BSF_GLOBAL)) == BSF_GLOBAL
2916
          && strspn (s->name,
2917
                     valid_mmo_symbol_character_set) == strlen (s->name))
2918
        {
2919
          struct mmo_symbol sym;
2920
          memset (&sym, 0, sizeof (sym));
2921
 
2922
          /* Need to strip const here; strdup:ing would leak and the
2923
             existing string must be safe to reuse.  */
2924
          sym.name = (char *) s->name;
2925
          sym.value =
2926
            s->value
2927
            + s->section->output_section->vma
2928
            + s->section->output_offset;
2929
 
2930
          if (bfd_is_und_section (s->section))
2931
            sym.sym_type = mmo_undef_sym;
2932
          else if (strcmp (s->section->name, MMO_DATA_SECTION_NAME) == 0
2933
                   /* The encoding of data symbols require that the "rest"
2934
                      of the value fits in 6 bytes, so the upper two bytes
2935
                      must be 0x2000.  All other symbols get to be the
2936
                      absolute type.  */
2937
                   && (sym.value >> 48) == 0x2000)
2938
            sym.sym_type = mmo_data_sym;
2939
          else if (strcmp (s->section->name, MMIX_REG_SECTION_NAME) == 0)
2940
            sym.sym_type = mmo_reg_sym;
2941
          else if (strcmp (s->section->name,
2942
                           MMIX_REG_CONTENTS_SECTION_NAME) == 0)
2943
            {
2944
              sym.sym_type = mmo_reg_sym;
2945
              sym.value /= 8;
2946
            }
2947
          else
2948
            sym.sym_type = mmo_abs_sym;
2949
 
2950
          /* FIXME: We assume the order of the received symbols is an
2951
             ordered mapping of the serial numbers.  This is not
2952
             necessarily true if we e.g. objcopy a mmo file to another and
2953
             there are gaps in the numbering.  Not sure if this can
2954
             happen.  Not sure what to do.  */
2955
          sym.serno = serno++;
2956
 
2957
          if (! mmo_internal_add_3_sym (abfd, &root, &sym))
2958
            return FALSE;
2959
        }
2960
    }
2961
 
2962
  /* Change the root node to be a ":"-prefix.  */
2963
  root.symchar = ':';
2964
  root.middle = root.left;
2965
  root.right = NULL;
2966
  root.left = NULL;
2967
 
2968
  /* We have to find out if we can fit the whole symbol table in the mmo
2969
     symtab.  It would be bad to assume we can always fit it in 262144
2970
     bytes.  If we can't, just leave the Main symbol.  */
2971
  trie_len = (mmo_internal_3_length (abfd, &root) + 3)/4;
2972
 
2973
  if (trie_len > 0xffff)
2974
    {
2975
      /* Test this code by using a lower limit in the test above and check
2976
         that the single "Main" symbol is emitted and handled properly.
2977
         There's no specific test-case.  */
2978
      struct mmo_symbol sym;
2979
 
2980
      (*_bfd_error_handler)
2981
        (_("%s: warning: symbol table too large for mmo, larger than 65535"
2982
           " 32-bit words: %d.  Only `Main' will be emitted.\n"),
2983
         bfd_get_filename (abfd), trie_len);
2984
 
2985
      memset (&sym, 0, sizeof (sym));
2986
      sym.sym_type = mmo_abs_sym;
2987
      sym.name = MMIX_START_SYMBOL_NAME;
2988
      sym.serno = 1;
2989
      sym.value = bfd_get_start_address (abfd);
2990
 
2991
      /* Then patch up a symbol table to be just the ":Main" symbol.  */
2992
      memset (&root, 0, sizeof (root));
2993
      root.left = root.middle;
2994
      root.symchar = 0xff;
2995
      root.middle = NULL;
2996
      root.right = NULL;
2997
 
2998
      if (! mmo_internal_add_3_sym (abfd, &root, &sym))
2999
        return FALSE;
3000
 
3001
      root.symchar = ':';
3002
      root.middle = root.left;
3003
      root.right = NULL;
3004
      root.left = NULL;
3005
 
3006
      trie_len = (mmo_internal_3_length (abfd, &root) + 3)/4;
3007
    }
3008
 
3009
  /* Reset the written-bytes counter.  */
3010
  abfd->tdata.mmo_data->byte_no = 0;
3011
 
3012
  /* Put out the lop_stab mark.  */
3013
  bfd_put_32 (abfd, (LOP << 24) | (LOP_STAB << 16), buf);
3014
  if (bfd_bwrite (buf, 4, abfd) != 4)
3015
    return FALSE;
3016
 
3017
  /* Dump out symbols.  */
3018
  mmo_internal_3_dump (abfd, &root);
3019
 
3020
  if (trie_len != (abfd->tdata.mmo_data->byte_no + 3)/4)
3021
    {
3022
      /* I haven't seen this trig.  It seems no use claiming this case
3023
         isn't debugged and abort if we get here.  Instead emit a
3024
         diagnostic and fail "normally".  */
3025
      (*_bfd_error_handler)
3026
        (_("%s: internal error, symbol table changed size from %d to %d"
3027
           " words\n"),
3028
         bfd_get_filename (abfd), trie_len,
3029
         (abfd->tdata.mmo_data->byte_no + 3)/4);
3030
      bfd_set_error (bfd_error_bad_value);
3031
      return FALSE;
3032
    }
3033
 
3034
  /* Dump out remaining bytes in the buffer and handle I/O errors by
3035
     propagating errors.  */
3036
  if ((abfd->tdata.mmo_data->byte_no % 4) != 0
3037
      || abfd->tdata.mmo_data->have_error)
3038
    {
3039
      memset (abfd->tdata.mmo_data->buf + (abfd->tdata.mmo_data->byte_no % 4),
3040
              0, 4 - (abfd->tdata.mmo_data->byte_no % 4));
3041
 
3042
      if (abfd->tdata.mmo_data->have_error
3043
          || bfd_bwrite (abfd->tdata.mmo_data->buf, 4, abfd) != 4)
3044
        return FALSE;
3045
    }
3046
 
3047
  bfd_put_32 (abfd, (LOP << 24) | (LOP_END << 16) | trie_len, buf);
3048
  return bfd_bwrite (buf, 4, abfd) == 4;
3049
}
3050
 
3051
/* Write section unless it is the register contents section.  For that, we
3052
   instead store the section in the supplied pointer.  This function is
3053
   used through bfd_map_over_sections.  */
3054
 
3055
static void
3056
mmo_write_section_unless_reg_contents (bfd *abfd, asection *sec, void *p)
3057
{
3058
  struct mmo_write_sec_info *infop = (struct mmo_write_sec_info *) p;
3059
 
3060
  if (! infop->retval)
3061
    return;
3062
 
3063
  if (strcmp (sec->name, MMIX_REG_CONTENTS_SECTION_NAME) == 0)
3064
    {
3065
      infop->reg_section = sec;
3066
      return;
3067
    }
3068
 
3069
  /* Exclude the convenience register section.  */
3070
  if (strcmp (sec->name, MMIX_REG_SECTION_NAME) == 0)
3071
    {
3072
      if (bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS)
3073
        {
3074
          /* Make sure it hasn't got contents.  It seems impossible to
3075
             make it carry contents, so we don't have a test-case for
3076
             this.  */
3077
          (*_bfd_error_handler)
3078
            (_("%s: internal error, internal register section %s had"
3079
               " contents\n"),
3080
             bfd_get_filename (abfd), sec->name);
3081
          bfd_set_error (bfd_error_bad_value);
3082
          infop->retval = FALSE;
3083
          return;
3084
        }
3085
 
3086
      return;
3087
    }
3088
 
3089
  infop->retval = mmo_internal_write_section (abfd, sec);
3090
}
3091
 
3092
/* Do the actual output of a file.  Assumes mmo_set_section_contents is
3093
   already called. */
3094
 
3095
static bfd_boolean
3096
mmo_write_object_contents (bfd *abfd)
3097
{
3098
  struct mmo_write_sec_info wsecinfo;
3099
 
3100
  /* First, there are a few words of preamble.  */
3101
  if (! mmo_internal_write_header (abfd))
3102
    return FALSE;
3103
 
3104
  wsecinfo.reg_section = NULL;
3105
  wsecinfo.retval = TRUE;
3106
 
3107
  bfd_map_over_sections (abfd, mmo_write_section_unless_reg_contents,
3108
                         &wsecinfo);
3109
 
3110
  if (! wsecinfo.retval)
3111
    return FALSE;
3112
 
3113
  if (wsecinfo.reg_section != NULL)
3114
    {
3115
      asection *sec = wsecinfo.reg_section;
3116
      unsigned int z = (unsigned int) (sec->vma / 8);
3117
 
3118
      /* Registers 0..31 must not be global.  Do sanity check on the "vma"
3119
         of the register contents section and check that it corresponds to
3120
         the length of the section.  */
3121
      if (z < 32 || z >= 255 || (sec->vma & 7) != 0
3122
          || sec->vma != 256 * 8 - sec->size - 8)
3123
        {
3124
          bfd_set_error (bfd_error_bad_value);
3125
 
3126
          if (sec->size == 0)
3127
            /* There must always be at least one such register.  */
3128
            (*_bfd_error_handler)
3129
              (_("%s: no initialized registers; section length 0\n"),
3130
               bfd_get_filename (abfd));
3131
          else if (sec->vma > (256 - 32) * 8)
3132
            /* Provide better error message for the case of too many
3133
               global registers.  */
3134
            (*_bfd_error_handler)
3135
              (_("%s: too many initialized registers; section length %ld\n"),
3136
               bfd_get_filename (abfd),
3137
               (long) sec->size);
3138
          else
3139
            (*_bfd_error_handler)
3140
              (_("%s: invalid start address for initialized registers of"
3141
                 " length %ld: 0x%lx%08lx\n"),
3142
               bfd_get_filename (abfd),
3143
               (long) sec->size,
3144
               (unsigned long) (sec->vma >> 32), (unsigned long) (sec->vma));
3145
 
3146
          return FALSE;
3147
        }
3148
 
3149
      if (! mmo_internal_write_post (abfd, z, sec))
3150
        return FALSE;
3151
    }
3152
  else
3153
    if (! mmo_internal_write_post (abfd, 255, NULL))
3154
      return FALSE;
3155
 
3156
  return mmo_write_symbols_and_terminator (abfd);
3157
}
3158
 
3159
/* If there's anything in particular in a mmo bfd that we want to free,
3160
   make this a real function.  Only do this if you see major memory
3161
   thrashing; zealous free:ing will cause unwanted behavior, especially if
3162
   you "free" memory allocated with "bfd_alloc", or even "bfd_release" a
3163
   block allocated with "bfd_alloc"; they're really allocated from an
3164
   obstack, and we don't know what was allocated there since this
3165
   particular allocation.  */
3166
 
3167
#define mmo_close_and_cleanup _bfd_generic_close_and_cleanup
3168
#define mmo_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
3169
 
3170
/* Perhaps we need to adjust this one; mmo labels (originally) without a
3171
   leading ':' might more appropriately be called local.  */
3172
#define mmo_bfd_is_local_label_name bfd_generic_is_local_label_name
3173
#define mmo_bfd_is_target_special_symbol  \
3174
  ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
3175
 
3176
/* Is this one really used or defined by anyone?  */
3177
#define mmo_get_lineno _bfd_nosymbols_get_lineno
3178
 
3179
/* FIXME: We can do better on this one, if we have a dwarf2 .debug_line
3180
   section or if MMO line numbers are implemented.  */
3181
#define mmo_find_nearest_line _bfd_nosymbols_find_nearest_line
3182
#define mmo_find_inliner_info _bfd_nosymbols_find_inliner_info
3183
#define mmo_make_empty_symbol _bfd_generic_make_empty_symbol
3184
#define mmo_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
3185
#define mmo_read_minisymbols _bfd_generic_read_minisymbols
3186
#define mmo_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
3187
 
3188
#define mmo_get_section_contents_in_window \
3189
  _bfd_generic_get_section_contents_in_window
3190
#define mmo_bfd_get_relocated_section_contents \
3191
  bfd_generic_get_relocated_section_contents
3192
#define mmo_bfd_gc_sections bfd_generic_gc_sections
3193 161 khays
#define mmo_bfd_lookup_section_flags bfd_generic_lookup_section_flags
3194 14 khays
#define mmo_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
3195
#define mmo_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
3196
#define mmo_bfd_link_add_symbols _bfd_generic_link_add_symbols
3197
#define mmo_bfd_link_just_syms _bfd_generic_link_just_syms
3198
#define mmo_bfd_copy_link_hash_symbol_type \
3199
  _bfd_generic_copy_link_hash_symbol_type
3200
#define mmo_bfd_final_link _bfd_generic_final_link
3201
#define mmo_bfd_link_split_section _bfd_generic_link_split_section
3202
 
3203
/* Strictly speaking, only MMIX uses this restricted format, but let's not
3204
   stop anybody from shooting themselves in the foot.  */
3205
#define mmo_set_arch_mach bfd_default_set_arch_mach
3206
#define mmo_bfd_relax_section bfd_generic_relax_section
3207
#define mmo_bfd_merge_sections bfd_generic_merge_sections
3208
#define mmo_bfd_is_group_section bfd_generic_is_group_section
3209
#define mmo_bfd_discard_group bfd_generic_discard_group
3210
#define mmo_section_already_linked \
3211
  _bfd_generic_section_already_linked
3212
#define mmo_bfd_define_common_symbol bfd_generic_define_common_symbol
3213
 
3214
/* We want to copy time of creation, otherwise we'd use
3215
   BFD_JUMP_TABLE_COPY (_bfd_generic).  */
3216
#define mmo_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
3217
#define mmo_bfd_copy_private_section_data _bfd_generic_bfd_copy_private_section_data
3218
#define mmo_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data
3219
#define mmo_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data
3220
#define mmo_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
3221
#define mmo_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data
3222
 
3223
const bfd_target bfd_mmo_vec =
3224
{
3225
  "mmo",                        /* name */
3226
  bfd_target_mmo_flavour,
3227
  BFD_ENDIAN_BIG,               /* target byte order */
3228
  BFD_ENDIAN_BIG,               /* target headers byte order */
3229
 
3230
  /* FIXME: Might need adjustments.  */
3231
  (HAS_RELOC | EXEC_P |         /* object flags */
3232
   HAS_LINENO | HAS_DEBUG |
3233
   HAS_SYMS | HAS_LOCALS | WP_TEXT),
3234
 
3235
  /* FIXME: Might need adjustments.  */
3236
  (SEC_CODE | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD
3237
   | SEC_READONLY | SEC_EXCLUDE | SEC_DEBUGGING | SEC_IN_MEMORY),
3238
                                /* section flags */
3239
  0,                             /* leading underscore */
3240
  ' ',                          /* ar_pad_char */
3241
  16,                           /* ar_max_namelen */
3242 148 khays
  0,                             /* match priority.  */
3243 14 khays
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
3244
  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
3245
  bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* data */
3246
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
3247
  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
3248
  bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* hdrs */
3249
 
3250
  {
3251
    _bfd_dummy_target,
3252
    mmo_object_p,               /* bfd_check_format */
3253
    _bfd_dummy_target,
3254
    _bfd_dummy_target,
3255
  },
3256
  {
3257
    bfd_false,
3258
    mmo_mkobject,
3259
    bfd_false,
3260
    bfd_false,
3261
  },
3262
  {                             /* bfd_write_contents */
3263
    bfd_false,
3264
    mmo_write_object_contents,
3265
    bfd_false,
3266
    bfd_false,
3267
  },
3268
 
3269
  BFD_JUMP_TABLE_GENERIC (mmo),
3270
  BFD_JUMP_TABLE_COPY (mmo),
3271
  BFD_JUMP_TABLE_CORE (_bfd_nocore),
3272
  BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
3273
  BFD_JUMP_TABLE_SYMBOLS (mmo),
3274
  BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
3275
  BFD_JUMP_TABLE_WRITE (mmo),
3276
  BFD_JUMP_TABLE_LINK (mmo),
3277
  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
3278
 
3279
  NULL,
3280
 
3281
  NULL
3282
};

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.