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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [bfd/] [mmo.c] - Blame information for rev 294

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

Line No. Rev Author Line
1 24 jeremybenn
/* BFD back-end for mmo objects (MMIX-specific object-format).
2 225 jeremybenn
   Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009
3 24 jeremybenn
   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
  char *current_filename = NULL;
1534
  bfd_size_type nbytes_read = 0;
1535
  /* Buffer with room to read a 64-bit value.  */
1536
  bfd_byte buf[8];
1537
  long stab_loc = -1;
1538
  char *file_names[256];
1539
 
1540
  memset (file_names, 0, sizeof (file_names));
1541
 
1542
  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
1543
    goto error_return;
1544
 
1545
  while ((nbytes_read = bfd_bread (buf, 4, abfd)) == 4)
1546
    {
1547
      if (buf[0] == LOP)
1548
        {
1549
          unsigned int y = bfd_get_8 (abfd, buf + 2);
1550
          unsigned int z = bfd_get_8 (abfd, buf + 3);
1551
 
1552
          /* Change back to the original section for lopcodes other
1553
             than LOP_QUOTE that comes after a LOP_SPEC.  */
1554
          if ((buf[1] != LOP_QUOTE || y != 0 || z != 1)
1555
              && non_spec_sec != NULL)
1556
            {
1557
              sec = non_spec_sec;
1558
              vma = non_spec_vma;
1559
              non_spec_sec = NULL;
1560
            }
1561
 
1562
          switch (buf[1])
1563
            {
1564
            default:
1565
              (*_bfd_error_handler)
1566
                (_("%s: invalid mmo file: unsupported lopcode `%d'\n"),
1567
                 bfd_get_filename (abfd), buf[1]);
1568
              bfd_set_error (bfd_error_bad_value);
1569
              goto error_return;
1570
 
1571
            case LOP_QUOTE:
1572
              /* Quote the next 32-bit word.  */
1573
              if (y != 0 || z != 1)
1574
                {
1575
                  (*_bfd_error_handler)
1576
                    (_("%s: invalid mmo file: expected YZ = 1 got YZ = %d for lop_quote\n"),
1577
                     bfd_get_filename (abfd), y*256+z);
1578
                  bfd_set_error (bfd_error_bad_value);
1579
                  goto error_return;
1580
                }
1581
              if (bfd_bread (buf, 4, abfd) != 4)
1582
                goto error_return;
1583
 
1584
              mmo_xore_32 (sec, vma, bfd_get_32 (abfd, buf));
1585
              vma += 4;
1586
              vma &= ~3;
1587
              lineno++;
1588
              break;
1589
 
1590
            case LOP_LOC:
1591
              /* Set vma (and section).  */
1592
              vma = (bfd_vma) y << 56;
1593
              if (z == 1)
1594
                {
1595
                  /* Get a 32-bit value.  */
1596
                  if (bfd_bread (buf, 4, abfd) != 4)
1597
                    goto error_return;
1598
 
1599
                  vma += bfd_get_32 (abfd, buf);
1600
                }
1601
              else if (z == 2)
1602
                {
1603
                  /* Get a 64-bit value.  */
1604
                  if (bfd_bread (buf, 8, abfd) != 8)
1605
                    goto error_return;
1606
 
1607
                  vma += bfd_get_64 (abfd, buf);
1608
                }
1609
              else
1610
                {
1611
                  (*_bfd_error_handler)
1612
                    (_("%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_loc\n"),
1613
                     bfd_get_filename (abfd), z);
1614
                  bfd_set_error (bfd_error_bad_value);
1615
                  goto error_return;
1616
                }
1617
 
1618
              sec = mmo_decide_section (abfd, vma);
1619
              if (sec == NULL)
1620
                goto error_return;
1621
              break;
1622
 
1623
            case LOP_SKIP:
1624
              /* Move forward within the same section.  */
1625
              vma += y * 256 + z;
1626
 
1627
              sec = mmo_decide_section (abfd, vma);
1628
              if (sec == NULL)
1629
                goto error_return;
1630
              break;
1631
 
1632
            case LOP_FIXO:
1633
              /* A fixup: Store the current vma somewhere.  Position using
1634
                 same format as LOP_LOC.  */
1635
              {
1636
                bfd_vma p = (bfd_vma) y << 56;
1637
                asection *fixosec;
1638
 
1639
                if (z == 1)
1640
                  {
1641
                    /* Get a 32-bit value.  */
1642
                    if (bfd_bread (buf, 4, abfd) != 4)
1643
                      goto error_return;
1644
 
1645
                    p += bfd_get_32 (abfd, buf);
1646
                  }
1647
                else if (z == 2)
1648
                  {
1649
                    /* Get a 64-bit value.  */
1650
                    if (bfd_bread (buf, 8, abfd) != 8)
1651
                      goto error_return;
1652
 
1653
                    p += bfd_get_64 (abfd, buf);
1654
                  }
1655
                else
1656
                  {
1657
                    (*_bfd_error_handler)
1658
                      (_("%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_fixo\n"),
1659
                       bfd_get_filename (abfd), z);
1660
                    bfd_set_error (bfd_error_bad_value);
1661
                    goto error_return;
1662
                  }
1663
 
1664
                /* The section where we store this address might be a
1665
                   different one than the current section.  */
1666
                fixosec = mmo_decide_section (abfd, p);
1667
                if (fixosec == NULL)
1668
                  goto error_return;
1669
                mmo_xore_64 (fixosec, p, vma);
1670
              }
1671
            break;
1672
 
1673
            case LOP_FIXR:
1674
              /* A fixup: Store YZ of this lopcode into YZ at vma - 4 * yz.  */
1675
              {
1676
                unsigned int yz = (y * 256 + z);
1677
                bfd_vma p = vma + 2 - 4 * yz;
1678
                asection *fixrsec = mmo_decide_section (abfd, p);
1679
                if (fixrsec == NULL)
1680
                  goto error_return;
1681
                mmo_xore_16 (fixrsec, p, yz);
1682
              }
1683
            break;
1684
 
1685
            case LOP_FIXRX:
1686
              /* A fixup, similar to lop_fixr, but taking larger numbers
1687
                 and can change branches into the opposite direction
1688
                 (gasp!).  */
1689
              {
1690
                bfd_vma delta;
1691
                bfd_vma p;
1692
                asection *fixrsec;
1693
 
1694
                if (y != 0)
1695
                  {
1696
                    (*_bfd_error_handler)
1697
                      (_("%s: invalid mmo file: expected y = 0, got y = %d for lop_fixrx\n"),
1698
                       bfd_get_filename (abfd), y);
1699
                    bfd_set_error (bfd_error_bad_value);
1700
                    goto error_return;
1701
                  }
1702
 
1703
                if (z != 16 && z != 24)
1704
                  {
1705
                    (*_bfd_error_handler)
1706
                      (_("%s: invalid mmo file: expected z = 16 or z = 24, got z = %d for lop_fixrx\n"),
1707
                       bfd_get_filename (abfd), z);
1708
                    bfd_set_error (bfd_error_bad_value);
1709
                    goto error_return;
1710
                  }
1711
 
1712
                /* Get the next 32-bit value.  */
1713
                if (bfd_bread (buf, 4, abfd) != 4)
1714
                  goto error_return;
1715
 
1716
                delta = bfd_get_32 (abfd, buf);
1717
 
1718
                /* Do an, ehm, involved calculation for the location of
1719
                   the fixup.  See mmixal documentation for a verbose
1720
                   explanation.  We follow it verbosely here for the
1721
                   readers delight.  */
1722
                if (buf[0] == 0)
1723
                  p = vma - 4 * delta;
1724
                else if (buf[0] == 1)
1725
                  p = vma - 4 * ((delta & 0xffffff) - (1 << z));
1726
                else
1727
                  {
1728
                    (*_bfd_error_handler)
1729
                      (_("%s: invalid mmo file: leading byte of operand word must be 0 or 1, got %d for lop_fixrx\n"),
1730
                       bfd_get_filename (abfd), buf[0]);
1731
                    bfd_set_error (bfd_error_bad_value);
1732
                    goto error_return;
1733
                  }
1734
 
1735
                fixrsec = mmo_decide_section (abfd, vma);
1736
                if (fixrsec == NULL)
1737
                  goto error_return;
1738
                mmo_xore_32 (fixrsec, p, delta);
1739
              }
1740
            break;
1741
 
1742
            case LOP_FILE:
1743
              /* Set current file and perhaps the file name.  Reset line
1744
                 number.  */
1745
              if (z != 0)
1746
                {
1747
                  char *fname = bfd_malloc (z * 4 + 1);
1748
 
1749
                  if (fname == NULL)
1750
                    {
1751
                      (*_bfd_error_handler)
1752
                        (_("%s: cannot allocate file name for file number %d, %d bytes\n"),
1753
                         bfd_get_filename (abfd), y, z * 4 + 1);
1754
                      bfd_set_error (bfd_error_system_call);
1755
                      goto error_return;
1756
                    }
1757
 
1758
                  fname[z * 4] = 0;
1759
 
1760
                  for (i = 0; i < z; i++)
1761
                    {
1762
                      if (bfd_bread (fname + i * 4, 4, abfd) != 4)
1763
                        {
1764
                          free (fname);
1765
                          goto error_return;
1766
                        }
1767
                    }
1768
 
1769
                  if (file_names[y] != NULL)
1770
                    {
1771
                      (*_bfd_error_handler)
1772
                        (_("%s: invalid mmo file: file number %d `%s',"
1773
                           " was already entered as `%s'\n"),
1774
                         bfd_get_filename (abfd), y, fname, file_names[y]);
1775
                      bfd_set_error (bfd_error_bad_value);
1776
                      goto error_return;
1777
                    }
1778
 
1779
                  file_names[y] = fname;
1780
                }
1781
 
1782
              if (file_names[y] == NULL)
1783
                {
1784
                  (*_bfd_error_handler)
1785
                    (_("%s: invalid mmo file: file name for number %d"
1786
                       " was not specified before use\n"),
1787
                     bfd_get_filename (abfd), y);
1788
                  bfd_set_error (bfd_error_bad_value);
1789
                  goto error_return;
1790
                }
1791
 
1792
              current_filename = file_names[y];
1793
              lineno = 0;
1794
              break;
1795
 
1796
            case LOP_LINE:
1797
              /* Set line number.  */
1798
              lineno = y * 256 + z;
1799
              /* FIXME: Create a sequence of mmo-specific line number
1800
                 entries for each section, then translate into canonical
1801
                 format.  */
1802
              break;
1803
 
1804
            case LOP_SPEC:
1805
              /* Special data follows until the next non-lop_quote
1806
                 lopcode.  */
1807
              non_spec_sec = sec;
1808
              non_spec_vma = vma;
1809
              sec = mmo_get_spec_section (abfd, y * 256 + z);
1810
              if (sec == NULL)
1811
                goto error_return;
1812
 
1813
              vma = sec->vma;
1814
              break;
1815
 
1816
            case LOP_PRE:
1817
              {
1818
                /* We ignore header information, except we read in the
1819
                   creation time from the first 32-bit word with the time
1820
                   in seconds since era.  */
1821
                if (z >= 1
1822
                    && bfd_bread (abfd->tdata.mmo_data->created, 4,
1823
                                 abfd) != 4)
1824
                  goto error_return;
1825
 
1826
                for (i = 1; i < z; i++)
1827
                  if (bfd_bread (buf, 4, abfd) != 4)
1828
                    goto error_return;
1829
              }
1830
              break;
1831
 
1832
            case LOP_POST:
1833
              /* This tells of the contents of registers $Z..$255 at
1834
                 startup.  We make a section out of it, with VMA = Z * 8,
1835
                 but only if Z != 255 or the contents is non-zero.  */
1836
              {
1837
                asection *rsec;
1838
                bfd_byte *loc;
1839
                bfd_vma first_octa;
1840
                bfd_vma startaddr_octa;
1841
 
1842
                /* Read first octaword outside loop to simplify logic when
1843
                   excluding the Z == 255, octa == 0 case.  */
1844
                if (bfd_bread (buf, 8, abfd) != 8)
1845
                  goto error_return;
1846
 
1847
                first_octa = bfd_get_64 (abfd, buf);
1848
 
1849
                /* Don't emit contents for the trivial case which is
1850
                   always present; $255 pointing to Main.  */
1851
                if (z != 255)
1852
                  {
1853
                    rsec
1854
                      = bfd_make_section_old_way (abfd,
1855
                                                  MMIX_REG_CONTENTS_SECTION_NAME);
1856
                    rsec->flags |= SEC_LINKER_CREATED;
1857
                    rsec->vma = z * 8;
1858
                    loc = mmo_get_loc (rsec, z * 8, (255 - z) * 8);
1859
                    bfd_put_64 (abfd, first_octa, loc);
1860
 
1861
                    for (i = z + 1; i < 255; i++)
1862
                      {
1863
                        if (bfd_bread (loc + (i - z) * 8, 8, abfd) != 8)
1864
                          goto error_return;
1865
                      }
1866
 
1867
                    /* Read out the last octabyte, and use it to set the
1868
                       start address.  */
1869
                    if (bfd_bread (buf, 8, abfd) != 8)
1870
                      goto error_return;
1871
 
1872
                    startaddr_octa = bfd_get_64 (abfd, buf);
1873
                  }
1874
                else
1875
                  startaddr_octa = first_octa;
1876
 
1877
                if (! bfd_set_start_address (abfd, startaddr_octa))
1878
                  {
1879
                    /* Currently this can't fail, but this should handle
1880
                       future failures.  */
1881
                    bfd_set_error (bfd_error_bad_value);
1882
                    goto error_return;
1883
                  }
1884
              }
1885
              break;
1886
 
1887
            case LOP_STAB:
1888
              /* We read in the symbols now, not later.  */
1889
              if (y != 0 || z != 0)
1890
                {
1891
                  (*_bfd_error_handler)
1892
                    (_("%s: invalid mmo file: fields y and z of lop_stab"
1893
                       " non-zero, y: %d, z: %d\n"),
1894
                     bfd_get_filename (abfd), y, z);
1895
                  bfd_set_error (bfd_error_bad_value);
1896
                  goto error_return;
1897
                }
1898
 
1899
              /* Save the location, so we can check that YZ in the LOP_END
1900
                 is correct.  */
1901
              stab_loc = bfd_tell (abfd);
1902
 
1903
              /* It's not said that an MMO can be without symbols (though
1904
                 mmixal will refuse to assemble files without Main), but
1905
                 it seems it would still be a valid mmo-file, so allow it.
1906
                 We detect the absence of a symbol area in that the upper
1907
                 limit is computed (from the lop_end YZ field) as 0.
1908
                 Don't call mmo_get_symbols; it can only detect the end of
1909
                 a valid symbol trie, not the absence of one.  */
1910
              if (abfd->tdata.mmo_data->max_symbol_length != 0
1911
                  && ! mmo_get_symbols (abfd))
1912
                goto error_return;
1913
              break;
1914
 
1915
            case LOP_END:
1916
              {
1917
                /* This must be the last 32-bit word in an mmo file.
1918
                   Let's find out.  */
1919
                struct stat statbuf;
1920
                file_ptr curpos = bfd_tell (abfd);
1921
 
1922
                if (bfd_stat (abfd, &statbuf) < 0)
1923
                  goto error_return;
1924
 
1925
                if (statbuf.st_size != curpos)
1926
                  {
1927
                    (*_bfd_error_handler)
1928
                      (_("%s: invalid mmo file: lop_end not last item in"
1929
                         " file\n"),
1930
                       bfd_get_filename (abfd));
1931
                    bfd_set_error (bfd_error_bad_value);
1932
                    goto error_return;
1933
                  }
1934
 
1935
                /* Check that the YZ field is right.  Subtract the size of
1936
                   this LOP_END in the calculation; YZ does not include
1937
                   it.  */
1938
                if ((long) (y * 256 + z) * 4 != (curpos - stab_loc) - 4)
1939
                  {
1940
                    (*_bfd_error_handler)
1941
                      (_("%s: invalid mmo file: YZ of lop_end (%ld)"
1942
                         " not equal to the number of tetras to the preceding"
1943
                         " lop_stab (%ld)\n"),
1944
                       bfd_get_filename (abfd), (long) (y * 256 + z),
1945
                       (curpos - stab_loc - 4)/4);
1946
                    bfd_set_error (bfd_error_bad_value);
1947
                    goto error_return;
1948
                  }
1949
 
1950
                bfd_map_over_sections (abfd, mmo_map_set_sizes, NULL);
1951
                goto done;
1952
              }
1953
            }
1954
        }
1955
      else
1956
        {
1957
          /* This wasn't a lopcode, so store it in the current section.  */
1958
          mmo_xore_32 (sec, vma & ~3, bfd_get_32 (abfd, buf));
1959
          vma += 4;
1960
          vma &= ~3;
1961
          lineno++;
1962
        }
1963
    }
1964
 
1965
  /* We know this file is a multiple of four bytes (checked in
1966
     mmo_object_p), so if we got something other than 0, this was a bad
1967
     file (although it's more likely we'll get 0 in that case too).
1968
     If we got end-of-file, then there was no lop_stab, so the file has
1969
     invalid format.  */
1970
 
1971
  if (nbytes_read != 0)
1972
    bfd_set_error (bfd_error_system_call);
1973
  else
1974
    bfd_set_error (bfd_error_bad_value);
1975
 
1976
 error_return:
1977
  error = TRUE;
1978
 done:
1979
  /* Mark the .text and .data section with their normal attribute if they
1980
     contain anything.  This is not redundant wrt. mmo_decide_section,
1981
     since that code might never execute, and conversely the alloc+code
1982
     section flags must be set then.  */
1983
  sec = bfd_get_section_by_name (abfd, MMO_TEXT_SECTION_NAME);
1984
  if (sec != NULL
1985
      && (bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS)
1986
      && ! bfd_set_section_flags (abfd, sec,
1987
                                  bfd_get_section_flags (abfd, sec)
1988
                                  | SEC_ALLOC | SEC_LOAD | SEC_CODE))
1989
    error = TRUE;
1990
 
1991
  sec = bfd_get_section_by_name (abfd, MMO_DATA_SECTION_NAME);
1992
  if (sec != NULL
1993
      && (bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS)
1994
      && ! bfd_set_section_flags (abfd, sec,
1995
                                  bfd_get_section_flags (abfd, sec)
1996
                                  | SEC_ALLOC | SEC_LOAD))
1997
    error = TRUE;
1998
 
1999
  /* Free whatever resources we took.  */
2000
  for (i = 0; i < sizeof (file_names) / sizeof (file_names[0]); i++)
2001
    if (file_names[i])
2002
      free (file_names[i]);
2003
  return ! error;
2004
}
2005
 
2006
/* A hook to set up object file dependent section information.  For mmo,
2007
   we point out the shape of allocated section contents.  */
2008
 
2009
static bfd_boolean
2010
mmo_new_section_hook (bfd *abfd, asection *newsect)
2011
{
2012
  if (!newsect->used_by_bfd)
2013
    {
2014
      /* We zero-fill all fields and assume NULL is represented by an all
2015
         zero-bit pattern.  */
2016
      newsect->used_by_bfd
2017
        = bfd_zalloc (abfd, sizeof (struct mmo_section_data_struct));
2018
      if (!newsect->used_by_bfd)
2019
        return FALSE;
2020
    }
2021
 
2022
  /* Always align to at least 32-bit words.  */
2023
  newsect->alignment_power = 2;
2024
  return _bfd_generic_new_section_hook (abfd, newsect);
2025
}
2026
 
2027
/* We already have section contents loaded for sections that have
2028
   contents.  */
2029
 
2030
static bfd_boolean
2031
mmo_get_section_contents (bfd *abfd ATTRIBUTE_UNUSED,
2032
                          asection *sec,
2033
                          void * location,
2034
                          file_ptr offset,
2035
                          bfd_size_type bytes_to_do)
2036
{
2037
  /* Iterate over diminishing chunk sizes, copying contents, like
2038
     mmo_set_section_contents.  */
2039
  while (bytes_to_do)
2040
    {
2041
      /* A minor song-and-dance to make sure we're not bitten by the
2042
         distant possibility of the cast from bfd_vma to int making the
2043
         chunk zero-sized.  */
2044
      int chunk_size
2045
        = (int) bytes_to_do != 0 ? bytes_to_do : MMO_SEC_CONTENTS_CHUNK_SIZE;
2046
      bfd_byte *loc;
2047
 
2048
      do
2049
        loc = mmo_get_loc (sec, sec->vma + offset, chunk_size);
2050
      while (loc == NULL && (chunk_size /= 2) != 0);
2051
 
2052
      if (chunk_size == 0)
2053
        return FALSE;
2054
 
2055
      memcpy (location, loc, chunk_size);
2056
 
2057
      location += chunk_size;
2058
      bytes_to_do -= chunk_size;
2059
      offset += chunk_size;
2060
    }
2061
  return TRUE;
2062
}
2063
 
2064
/* Return the amount of memory needed to read the symbol table.  */
2065
 
2066
static long
2067
mmo_get_symtab_upper_bound (bfd *abfd)
2068
{
2069
  return (abfd->symcount + 1) * sizeof (asymbol *);
2070
}
2071
 
2072
/* Sort mmo symbols by serial number.  */
2073
 
2074
static int
2075
mmo_sort_mmo_symbols (const void *arg1, const void *arg2)
2076
{
2077
  const struct mmo_symbol *sym1 = *(const struct mmo_symbol **) arg1;
2078
  const struct mmo_symbol *sym2 = *(const struct mmo_symbol **) arg2;
2079
 
2080
  /* Sort by serial number first.  */
2081
  if (sym1->serno < sym2->serno)
2082
    return -1;
2083
  else if (sym1->serno > sym2->serno)
2084
    return 1;
2085
 
2086
  /* Then sort by address of the table entries.  */
2087
  return ((const char *) arg1 - (const char *) arg2);
2088
}
2089
 
2090
/* Translate the symbol table.  */
2091
 
2092
static long
2093
mmo_canonicalize_symtab (bfd *abfd, asymbol **alocation)
2094
{
2095
  unsigned int symcount = bfd_get_symcount (abfd);
2096
  asymbol *csymbols;
2097
  unsigned int i;
2098
 
2099
  csymbols = abfd->tdata.mmo_data->csymbols;
2100
  if (csymbols == NULL && symcount != 0)
2101
    {
2102
      asymbol *c;
2103
      struct mmo_symbol *s;
2104
      struct mmo_symbol **msp;
2105
 
2106
      /* First we store the symbols into the table we'll return, then we
2107
         qsort it on the serial number, with secondary on the address of
2108
         the symbol, to preserve order if there would be non-unique serial
2109
         numbers.  */
2110
      for (s = abfd->tdata.mmo_data->symbols,
2111
             msp = (struct mmo_symbol **) alocation;
2112
           s != NULL;
2113
           s = s->next, ++msp)
2114
        *msp = s;
2115
 
2116
      *msp = NULL;
2117
 
2118
      qsort (alocation, symcount, sizeof (struct mmo_symbol *),
2119
             mmo_sort_mmo_symbols);
2120
 
2121
      csymbols = (asymbol *) bfd_alloc (abfd, symcount * sizeof (asymbol));
2122
      if (csymbols == NULL)
2123
        return -1;
2124
      abfd->tdata.mmo_data->csymbols = csymbols;
2125
 
2126
      for (msp = (struct mmo_symbol **) alocation, c = csymbols;
2127
           *msp != NULL;
2128
           msp++, ++c)
2129
        {
2130
          s = *msp;
2131
          c->the_bfd = abfd;
2132
          c->name = s->name;
2133
          c->value = s->value;
2134
          c->flags = BSF_GLOBAL;
2135
 
2136
          if (s->sym_type == mmo_data_sym)
2137
            {
2138
              c->section
2139
                = bfd_get_section_by_name (abfd, MMO_DATA_SECTION_NAME);
2140
 
2141
              if (c->section == NULL)
2142
                c->section = bfd_abs_section_ptr;
2143
              else
2144
                c->value -= c->section->vma;
2145
            }
2146
          else if (s->sym_type == mmo_undef_sym)
2147
            c->section = bfd_und_section_ptr;
2148
          else if (s->sym_type == mmo_reg_sym)
2149
            {
2150
              c->section
2151
                = bfd_make_section_old_way (abfd, MMIX_REG_SECTION_NAME);
2152
              c->section->flags |= SEC_LINKER_CREATED;
2153
            }
2154
          else
2155
            {
2156
              asection *textsec
2157
                = bfd_get_section_by_name (abfd, MMO_TEXT_SECTION_NAME);
2158
              asection *datasec;
2159
 
2160
              if (textsec != NULL
2161
                  && c->value >= textsec->vma
2162
                  && c->value <= textsec->vma + textsec->size)
2163
                {
2164
                  c->section = textsec;
2165
                  c->value -= c->section->vma;
2166
                }
2167
              /* In mmo, symbol types depend on the VMA.  Therefore, if
2168
                 the data section isn't within the usual bounds, its
2169
                 symbols are marked as absolute.  Correct that.  This
2170
                 means we can't have absolute symbols with values matching
2171
                 data section addresses, but we also can't have with
2172
                 absolute symbols with values matching text section
2173
                 addresses.  For such needs, use the ELF format.  */
2174
              else if ((datasec
2175
                        = bfd_get_section_by_name (abfd,
2176
                                                   MMO_DATA_SECTION_NAME))
2177
                       != NULL
2178
                       && c->value >= datasec->vma
2179
                       && c->value <= datasec->vma + datasec->size)
2180
                {
2181
                  c->section = datasec;
2182
                  c->value -= c->section->vma;
2183
                }
2184
              else
2185
                c->section = bfd_abs_section_ptr;
2186
            }
2187
 
2188
          c->udata.p = NULL;
2189
        }
2190
    }
2191
 
2192
  /* Last, overwrite the incoming table with the right-type entries.  */
2193
  for (i = 0; i < symcount; i++)
2194
    *alocation++ = csymbols++;
2195
  *alocation = NULL;
2196
 
2197
  return symcount;
2198
}
2199
 
2200
/* Get information about a symbol.  */
2201
 
2202
static void
2203
mmo_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED,
2204
                     asymbol *symbol, symbol_info *ret)
2205
{
2206
  bfd_symbol_info (symbol, ret);
2207
}
2208
 
2209
static void
2210
mmo_print_symbol (bfd *abfd, void *afile, asymbol *symbol,
2211
                  bfd_print_symbol_type how)
2212
{
2213
  FILE *file = (FILE *) afile;
2214
 
2215
  switch (how)
2216
    {
2217
    case bfd_print_symbol_name:
2218
      fprintf (file, "%s", symbol->name);
2219
      break;
2220
    default:
2221
      bfd_print_symbol_vandf (abfd, file, symbol);
2222
 
2223
      fprintf (file, " %-5s %s",
2224
               symbol->section->name,
2225
               symbol->name);
2226
    }
2227
}
2228
 
2229
/* We can't map a file directly into executable code, so the
2230
   size of header information is irrelevant.  */
2231
 
2232
static int
2233
mmo_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
2234
                    struct bfd_link_info *info ATTRIBUTE_UNUSED)
2235
{
2236
  return 0;
2237
}
2238
 
2239
/* Write the (section-neutral) file preamble.  */
2240
 
2241
static bfd_boolean
2242
mmo_internal_write_header (bfd *abfd)
2243
{
2244
  const char lop_pre_bfd[] = { LOP, LOP_PRE, 1, 1};
2245
 
2246
  if (bfd_bwrite (lop_pre_bfd, 4, abfd) != 4)
2247
    return FALSE;
2248
 
2249
  /* Copy creation time of original file.  */
2250
  if (bfd_bwrite (abfd->tdata.mmo_data->created, 4, abfd) != 4)
2251
    return FALSE;
2252
 
2253
  return TRUE;
2254
}
2255
 
2256
/* Write the LOP_POST record, with global register initializations.
2257
   Z is the Z field of the LOP_POST, corresponding to 255 - number of
2258
   registers at DATA.  The Z = 255 field is filled in with the
2259
   start-address.  */
2260
 
2261
static bfd_boolean
2262
mmo_internal_write_post (bfd *abfd, int z, asection *sec)
2263
{
2264
  int i;
2265
  bfd_byte buf[8];
2266
  mmo_write_tetra_raw (abfd, (LOP << 24) | (LOP_POST << 16) | z);
2267
 
2268
  for (i = z; i < 255; i++)
2269
    {
2270
      bfd_byte *data = mmo_get_loc (sec, i * 8, 8);
2271
 
2272
      if (bfd_bwrite (data, 8, abfd) != 8)
2273
        return FALSE;
2274
    }
2275
 
2276
  /* For Z == $255, we always emit the start location; supposedly Main,
2277
     but we have it handy at bfd_get_start_address.  If we're called with
2278
     Z == 255, don't assume DATA is valid.  */
2279
  bfd_put_64 (abfd, bfd_get_start_address (abfd), buf);
2280
 
2281
  return ! abfd->tdata.mmo_data->have_error && bfd_bwrite (buf, 8, abfd) == 8;
2282
}
2283
 
2284
/* Translate to and from BFD flags.  This is to make sure that we don't
2285
   get bitten by BFD flag number changes.  */
2286
 
2287
static flagword
2288
mmo_sec_flags_from_bfd_flags (flagword flags)
2289
{
2290
  flagword oflags = 0;
2291
 
2292
  if (flags & SEC_ALLOC)
2293
    oflags |= MMO_SEC_ALLOC;
2294
  if (flags & SEC_LOAD)
2295
    oflags |= MMO_SEC_LOAD;
2296
  if (flags & SEC_RELOC)
2297
    oflags |= MMO_SEC_RELOC;
2298
  if (flags & SEC_READONLY)
2299
    oflags |= MMO_SEC_READONLY;
2300
  if (flags & SEC_CODE)
2301
    oflags |= MMO_SEC_CODE;
2302
  if (flags & SEC_DATA)
2303
    oflags |= MMO_SEC_DATA;
2304
  if (flags & SEC_NEVER_LOAD)
2305
    oflags |= MMO_SEC_NEVER_LOAD;
2306
  if (flags & SEC_IS_COMMON)
2307
    oflags |= MMO_SEC_IS_COMMON;
2308
  if (flags & SEC_DEBUGGING)
2309
    oflags |= MMO_SEC_DEBUGGING;
2310
 
2311
  return oflags;
2312
}
2313
 
2314
static flagword
2315
bfd_sec_flags_from_mmo_flags (flagword flags)
2316
{
2317
  flagword oflags = 0;
2318
 
2319
  if (flags & MMO_SEC_ALLOC)
2320
    oflags |= SEC_ALLOC;
2321
  if (flags & MMO_SEC_LOAD)
2322
    oflags |= SEC_LOAD;
2323
  if (flags & MMO_SEC_RELOC)
2324
    oflags |= SEC_RELOC;
2325
  if (flags & MMO_SEC_READONLY)
2326
    oflags |= SEC_READONLY;
2327
  if (flags & MMO_SEC_CODE)
2328
    oflags |= SEC_CODE;
2329
  if (flags & MMO_SEC_DATA)
2330
    oflags |= SEC_DATA;
2331
  if (flags & MMO_SEC_NEVER_LOAD)
2332
    oflags |= SEC_NEVER_LOAD;
2333
  if (flags & MMO_SEC_IS_COMMON)
2334
    oflags |= SEC_IS_COMMON;
2335
  if (flags & MMO_SEC_DEBUGGING)
2336
    oflags |= SEC_DEBUGGING;
2337
 
2338
  return oflags;
2339
}
2340
 
2341
/* Return TRUE iff the leading or trailing tetrabyte in SEC is defined and
2342
   is 0.  */
2343
 
2344
static bfd_boolean
2345
mmo_has_leading_or_trailing_zero_tetra_p (bfd *abfd, asection *sec)
2346
{
2347
  bfd_vma secaddr = bfd_get_section_vma (abfd, sec);
2348
 
2349
  if (sec->size < 4)
2350
    return FALSE;
2351
 
2352
  if (bfd_get_32 (abfd, mmo_get_loc (sec, secaddr, 4)) == 0
2353
      && bfd_get_32 (abfd,
2354
                     mmo_get_loc (sec, secaddr + sec->size - 4, 4)) == 0)
2355
    return TRUE;
2356
 
2357
  return FALSE;
2358
}
2359
 
2360
/* Write a section.  */
2361
 
2362
static bfd_boolean
2363
mmo_internal_write_section (bfd *abfd, asection *sec)
2364
{
2365
  /* We do it differently depending on what section this is:
2366
 
2367
   ".text": Output, prepended by information about the first source file
2368
   (not yet implemented.)
2369
 
2370
   ".data": Output.
2371
 
2372
   (".MMIX.reg_contents": Not handled here.)
2373
 
2374
   Anything else: Output inside a lop_spec 80, in the format described
2375
   above.  */
2376
 
2377
  if (strcmp (sec->name, MMO_TEXT_SECTION_NAME) == 0)
2378
    {
2379
      bfd_vma secaddr = bfd_get_section_vma (abfd, sec);
2380
 
2381
      /* Because leading and trailing zeros are omitted in output, we need to
2382
         specify the section boundaries so they're correct when the file
2383
         is read in again.  That's also the case if this section is
2384
         specified as not within its usual boundaries or alignments.  */
2385
      if (sec->size != 0
2386
          && (secaddr + sec->size >= (bfd_vma) 1 << 56
2387
              || (secaddr & 3) != 0
2388
              || (sec->size & 3) != 0
2389
              || mmo_has_leading_or_trailing_zero_tetra_p (abfd, sec)))
2390
        {
2391
          if (!mmo_write_section_description (abfd, sec))
2392
            return FALSE;
2393
        }
2394
 
2395
      /* FIXME: Output source file name and line number.  */
2396
      return mmo_write_loc_chunk_list (abfd, mmo_section_data (sec)->head);
2397
    }
2398
  else if (strcmp (sec->name, MMO_DATA_SECTION_NAME) == 0)
2399
    {
2400
      bfd_vma secaddr = bfd_get_section_vma (abfd, sec);
2401
 
2402
      /* Same goes as for MMO_TEXT_SECTION_NAME above.  */
2403
      if (sec->size != 0
2404
          && (secaddr < (bfd_vma) 0x20 << 56
2405
              || secaddr + sec->size >= (bfd_vma) 0x21 << 56
2406
              || (secaddr & 3) != 0
2407
              || (sec->size & 3) != 0
2408
              || mmo_has_leading_or_trailing_zero_tetra_p (abfd, sec)))
2409
        {
2410
          if (!mmo_write_section_description (abfd, sec))
2411
            return FALSE;
2412
        }
2413
 
2414
      return mmo_write_loc_chunk_list (abfd, mmo_section_data (sec)->head);
2415
    }
2416
  else if (strcmp (sec->name, MMIX_REG_CONTENTS_SECTION_NAME) == 0)
2417
    /* Not handled here.  */
2418
    {
2419
      /* This would normally be an abort call since this can't happen, but
2420
         we don't do that.  */
2421
      bfd_set_error (bfd_error_bad_value);
2422
      return FALSE;
2423
    }
2424
  else if (CONST_STRNEQ (sec->name, MMIX_OTHER_SPEC_SECTION_PREFIX))
2425
    {
2426
      int n = atoi (sec->name + strlen (MMIX_OTHER_SPEC_SECTION_PREFIX));
2427
 
2428
      mmo_write_tetra_raw (abfd, (LOP << 24) | (LOP_SPEC << 16) | n);
2429
      return (! abfd->tdata.mmo_data->have_error
2430
              && mmo_write_chunk_list (abfd, mmo_section_data (sec)->head));
2431
    }
2432
  /* Ignore sections that are just allocated or empty; we write out
2433
     _contents_ here.  */
2434
  else if ((bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS) != 0
2435
           && sec->size != 0)
2436
    {
2437
      if (!mmo_write_section_description (abfd, sec))
2438
        return FALSE;
2439
 
2440
      /* Writing a LOP_LOC ends the LOP_SPEC data, and makes data actually
2441
         loaded.  */
2442
      if (bfd_get_section_flags (abfd, sec) & SEC_LOAD)
2443
        return (! abfd->tdata.mmo_data->have_error
2444
                && mmo_write_loc_chunk_list (abfd,
2445
                                         mmo_section_data (sec)->head));
2446
      return (! abfd->tdata.mmo_data->have_error
2447
              && mmo_write_chunk_list (abfd, mmo_section_data (sec)->head));
2448
    }
2449
 
2450
  /* Some section without contents.  */
2451
  return TRUE;
2452
}
2453
 
2454
/* Write the description of a section, extended-mmo-style.  */
2455
 
2456
static bfd_boolean
2457
mmo_write_section_description (bfd *abfd, asection *sec)
2458
{
2459
  /* Keep the following document-comment formatted the way it is.  */
2460
/*
2461
INODE
2462
mmo section mapping, , Symbol-table, mmo
2463
SUBSECTION
2464
        mmo section mapping
2465
 
2466
        The implementation in BFD uses special data type 80 (decimal) to
2467
        encapsulate and describe named sections, containing e.g.@: debug
2468
        information.  If needed, any datum in the encapsulation will be
2469
        quoted using lop_quote.  First comes a 32-bit word holding the
2470
        number of 32-bit words containing the zero-terminated zero-padded
2471
        segment name.  After the name there's a 32-bit word holding flags
2472
        describing the section type.  Then comes a 64-bit big-endian word
2473
        with the section length (in bytes), then another with the section
2474
        start address.  Depending on the type of section, the contents
2475
        might follow, zero-padded to 32-bit boundary.  For a loadable
2476
        section (such as data or code), the contents might follow at some
2477
        later point, not necessarily immediately, as a lop_loc with the
2478
        same start address as in the section description, followed by the
2479
        contents.  This in effect forms a descriptor that must be emitted
2480
        before the actual contents.  Sections described this way must not
2481
        overlap.
2482
 
2483
        For areas that don't have such descriptors, synthetic sections are
2484
        formed by BFD.  Consecutive contents in the two memory areas
2485
        @samp{0x0000@dots{}00} to @samp{0x01ff@dots{}ff} and
2486
        @samp{0x2000@dots{}00} to @samp{0x20ff@dots{}ff} are entered in
2487
        sections named <<.text>> and <<.data>> respectively.  If an area
2488
        is not otherwise described, but would together with a neighboring
2489
        lower area be less than @samp{0x40000000} bytes long, it is joined
2490
        with the lower area and the gap is zero-filled.  For other cases,
2491
        a new section is formed, named <<.MMIX.sec.@var{n}>>.  Here,
2492
        @var{n} is a number, a running count through the mmo file,
2493
        starting at 0.
2494
 
2495
EXAMPLE
2496
        A loadable section specified as:
2497
 
2498
| .section secname,"ax"
2499
| TETRA 1,2,3,4,-1,-2009
2500
| BYTE 80
2501
 
2502
        and linked to address @samp{0x4}, is represented by the sequence:
2503
 
2504
| 0x98080050 - lop_spec 80
2505
| 0x00000002 - two 32-bit words for the section name
2506
| 0x7365636e - "secn"
2507
| 0x616d6500 - "ame\0"
2508
| 0x00000033 - flags CODE, READONLY, LOAD, ALLOC
2509
| 0x00000000 - high 32 bits of section length
2510
| 0x0000001c - section length is 28 bytes; 6 * 4 + 1 + alignment to 32 bits
2511
| 0x00000000 - high 32 bits of section address
2512
| 0x00000004 - section address is 4
2513
| 0x98010002 - 64 bits with address of following data
2514
| 0x00000000 - high 32 bits of address
2515
| 0x00000004 - low 32 bits: data starts at address 4
2516
| 0x00000001 - 1
2517
| 0x00000002 - 2
2518
| 0x00000003 - 3
2519
| 0x00000004 - 4
2520
| 0xffffffff - -1
2521
| 0xfffff827 - -2009
2522
| 0x50000000 - 80 as a byte, padded with zeros.
2523
 
2524
        Note that the lop_spec wrapping does not include the section
2525
        contents.  Compare this to a non-loaded section specified as:
2526
 
2527
| .section thirdsec
2528
| TETRA 200001,100002
2529
| BYTE 38,40
2530
 
2531
        This, when linked to address @samp{0x200000000000001c}, is
2532
        represented by:
2533
 
2534
| 0x98080050 - lop_spec 80
2535
| 0x00000002 - two 32-bit words for the section name
2536
| 0x7365636e - "thir"
2537
| 0x616d6500 - "dsec"
2538
| 0x00000010 - flag READONLY
2539
| 0x00000000 - high 32 bits of section length
2540
| 0x0000000c - section length is 12 bytes; 2 * 4 + 2 + alignment to 32 bits
2541
| 0x20000000 - high 32 bits of address
2542
| 0x0000001c - low 32 bits of address 0x200000000000001c
2543
| 0x00030d41 - 200001
2544
| 0x000186a2 - 100002
2545
| 0x26280000 - 38, 40 as bytes, padded with zeros
2546
 
2547
        For the latter example, the section contents must not be
2548
        loaded in memory, and is therefore specified as part of the
2549
        special data.  The address is usually unimportant but might
2550
        provide information for e.g.@: the DWARF 2 debugging format.  */
2551
 
2552
  mmo_write_tetra_raw (abfd, LOP_SPEC_SECTION);
2553
  mmo_write_tetra (abfd, (strlen (sec->name) + 3) / 4);
2554
  mmo_write_chunk (abfd, (bfd_byte *) sec->name, strlen (sec->name));
2555
  mmo_flush_chunk (abfd);
2556
  /* FIXME: We can get debug sections (.debug_line & Co.) with a section
2557
     flag still having SEC_RELOC set.  Investigate.  This might be true
2558
     for all alien sections; perhaps mmo.em should clear that flag.  Might
2559
     be related to weak references.  */
2560
  mmo_write_tetra (abfd,
2561
                   mmo_sec_flags_from_bfd_flags
2562
                   (bfd_get_section_flags (abfd, sec)));
2563
  mmo_write_octa (abfd, sec->size);
2564
  mmo_write_octa (abfd, bfd_get_section_vma (abfd, sec));
2565
  return TRUE;
2566
}
2567
 
2568
/* We save up all data before output.  */
2569
 
2570
static bfd_boolean
2571
mmo_set_section_contents (bfd *abfd ATTRIBUTE_UNUSED, sec_ptr sec,
2572
                          const void *location, file_ptr offset,
2573
                          bfd_size_type bytes_to_do)
2574
{
2575
  /* Iterate over diminishing chunk sizes, copying contents.  */
2576
  while (bytes_to_do)
2577
    {
2578
      /* A minor song-and-dance to make sure we're not bitten by the
2579
         distant possibility of the cast from bfd_vma to int making the
2580
         chunk zero-sized.  */
2581
      int chunk_size
2582
        = (int) bytes_to_do != 0 ? bytes_to_do : MMO_SEC_CONTENTS_CHUNK_SIZE;
2583
      bfd_byte *loc;
2584
 
2585
      do
2586
        loc = mmo_get_loc (sec, sec->vma + offset, chunk_size);
2587
      while (loc == NULL && (chunk_size /= 2) != 0);
2588
 
2589
      if (chunk_size == 0)
2590
        return FALSE;
2591
 
2592
      memcpy (loc, location, chunk_size);
2593
 
2594
      location += chunk_size;
2595
      bytes_to_do -= chunk_size;
2596
      offset += chunk_size;
2597
    }
2598
  return TRUE;
2599
}
2600
 
2601
/* Add a symbol to a trie-tree.  */
2602
 
2603
static bfd_boolean
2604
mmo_internal_add_3_sym (bfd *abfd, struct mmo_symbol_trie *rootp,
2605
                        const struct mmo_symbol *symp)
2606
{
2607
  const char *name = symp->name;
2608
  struct mmo_symbol_trie *trie = rootp;
2609
  struct mmo_symbol_trie **triep = NULL;
2610
 
2611
  while (*name && trie != NULL)
2612
    {
2613
      if (*name < trie->symchar)
2614
        {
2615
          triep = &trie->left;
2616
          trie = trie->left;
2617
        }
2618
      else if (*name > trie->symchar)
2619
        {
2620
          triep = &trie->right;
2621
          trie = trie->right;
2622
        }
2623
      else if (*name == trie->symchar)
2624
        {
2625
          triep = &trie->middle;
2626
          name++;
2627
 
2628
          /* Make sure "trie" points to where we should fill in the
2629
             current symbol whenever we've iterated through "name".  We
2630
             would lose the right position if we encounter "foobar" then
2631
             "foo".  */
2632
          if (*name)
2633
            trie = trie->middle;
2634
        }
2635
    }
2636
 
2637
  while (*name != 0)
2638
    {
2639
      /* Create middle branches for the rest of the characters.  */
2640
      trie = bfd_zalloc (abfd, sizeof (struct mmo_symbol_trie));
2641
      *triep = trie;
2642
      trie->symchar = *name++;
2643
      triep = &trie->middle;
2644
    }
2645
 
2646
  /* We discover a duplicate symbol rather late in the process, but still;
2647
     we discover it and bail out.  */
2648
  if (trie->sym.name != NULL)
2649
    {
2650
      (*_bfd_error_handler)
2651
        (_("%s: invalid symbol table: duplicate symbol `%s'\n"),
2652
         bfd_get_filename (abfd), trie->sym.name);
2653
      bfd_set_error (bfd_error_bad_value);
2654
      return FALSE;
2655
    }
2656
 
2657
  memcpy (&trie->sym, symp, sizeof *symp);
2658
  return TRUE;
2659
}
2660
 
2661
/* Find out the length of the serialized version of a trie in bytes.  */
2662
 
2663
static unsigned int
2664
mmo_internal_3_length (bfd *abfd, struct mmo_symbol_trie *trie)
2665
{
2666
  /* First, one for the control byte.  */
2667
  unsigned int length = 1;
2668
 
2669
  if (trie == NULL)
2670
    return 0;
2671
 
2672
  /* Add in the recursion to the left.  */
2673
  length += mmo_internal_3_length (abfd, trie->left);
2674
 
2675
  /* Add in the middle trie and the character.  */
2676
  length += 1 + mmo_internal_3_length (abfd, trie->middle);
2677
 
2678
  /* Add in the recursion to the right.  */
2679
  length += mmo_internal_3_length (abfd, trie->right);
2680
 
2681
  /* Add in bytes for the symbol (if this is an endnode). */
2682
  if (trie->sym.name != NULL)
2683
    {
2684
      unsigned int serno = trie->sym.serno;
2685
 
2686
      /* First what it takes to encode the value. */
2687
      if (trie->sym.sym_type == mmo_reg_sym)
2688
        length++;
2689
      else if (trie->sym.sym_type == mmo_undef_sym)
2690
        length += 2;
2691
      else
2692
        {
2693
          bfd_vma value = trie->sym.value;
2694
 
2695
          /* Coded in one to eight following bytes.  */
2696
          if (trie->sym.sym_type == mmo_data_sym)
2697
            value -= (bfd_vma) 0x20 << 56;
2698
 
2699
          do
2700
            {
2701
              value >>= 8;
2702
              length++;
2703
            }
2704
          while (value != 0);
2705
        }
2706
 
2707
      /* Find out what it takes to encode the serial number.  */
2708
      do
2709
        {
2710
          serno >>= 7;
2711
          length++;
2712
        }
2713
      while (serno != 0);
2714
    }
2715
 
2716
  return length;
2717
}
2718
 
2719
/* Helper function for outputting the serial number of a symbol, output as
2720
   a variant of leb128 (see dwarf2 documentation) which could be called
2721
   beb128.  Using a helper function and recursion simplifies debugging.  */
2722
 
2723
static void
2724
mmo_beb128_out (bfd *abfd, int serno, int marker)
2725
{
2726
  if (serno & ~0x7f)
2727
    mmo_beb128_out (abfd, serno >> 7, 0);
2728
  mmo_write_byte (abfd, marker | (serno & 0x7f));
2729
}
2730
 
2731
/* Serialize a trie.  */
2732
 
2733
static void
2734
mmo_internal_3_dump (bfd *abfd, struct mmo_symbol_trie *trie)
2735
{
2736
  bfd_byte control = 0;
2737
 
2738
  if (trie == NULL)
2739
    return;
2740
 
2741
  if (trie->left)
2742
    control |= MMO3_LEFT;
2743
 
2744
  if (trie->middle)
2745
    control |= MMO3_MIDDLE;
2746
 
2747
  if (trie->right)
2748
    control |= MMO3_RIGHT;
2749
 
2750
  if (trie->sym.name != NULL)
2751
    {
2752
      /* Encode the symbol type and length of value bytes.  */
2753
      if (trie->sym.sym_type == mmo_reg_sym)
2754
        control |= MMO3_REGQUAL_BITS;
2755
      else if (trie->sym.sym_type == mmo_undef_sym)
2756
        control |= MMO3_UNDEF;
2757
      else
2758
        {
2759
          bfd_vma value = trie->sym.value;
2760
 
2761
          /* Coded in 1..8 following bytes.  */
2762
          if (trie->sym.sym_type == mmo_data_sym)
2763
            {
2764
              control |= MMO3_DATA;
2765
              value -= (bfd_vma) 0x20 << 56;
2766
            }
2767
 
2768
          do
2769
            {
2770
              value >>= 8;
2771
              control++;
2772
            }
2773
          while (value != 0);
2774
        }
2775
    }
2776
 
2777
  /* The control byte is output before recursing.  */
2778
  mmo_write_byte (abfd, control);
2779
 
2780
  mmo_internal_3_dump (abfd, trie->left);
2781
 
2782
  if (control & MMO3_SYMBITS)
2783
    {
2784
      mmo_write_byte (abfd, trie->symchar);
2785
 
2786
      if (trie->sym.name != NULL)
2787
        {
2788
          if (trie->sym.sym_type == mmo_reg_sym)
2789
            mmo_write_byte (abfd, trie->sym.value);
2790
          else if (trie->sym.sym_type == mmo_undef_sym)
2791
            {
2792
              mmo_write_byte (abfd, 0);
2793
              mmo_write_byte (abfd, 0);
2794
            }
2795
          else
2796
            {
2797
              bfd_vma value = trie->sym.value;
2798
 
2799
              bfd_byte byte_n = control & 15;
2800
 
2801
              /* Coded in 1..8 following bytes.  Note that the value is
2802
                 shifted out big-endian.  */
2803
              if (trie->sym.sym_type == mmo_data_sym)
2804
                {
2805
                  value -= (bfd_vma) 0x20 << 56;
2806
                  byte_n -= 8;
2807
                }
2808
 
2809
              do
2810
                {
2811
                  mmo_write_byte (abfd, (value >> ((byte_n - 1) * 8)) & 0xff);
2812
                  byte_n--;
2813
                }
2814
              while (byte_n != 0);
2815
            }
2816
 
2817
          mmo_beb128_out (abfd, trie->sym.serno, 128);
2818
        }
2819
      mmo_internal_3_dump (abfd, trie->middle);
2820
    }
2821
  mmo_internal_3_dump (abfd, trie->right);
2822
}
2823
 
2824
/* Write symbols in mmo format.  Also write the lop_end terminator.  */
2825
 
2826
static bfd_boolean
2827
mmo_write_symbols_and_terminator (bfd *abfd)
2828
{
2829
  int count = bfd_get_symcount (abfd);
2830
  asymbol *maintable[2];
2831
  asymbol **table;
2832
  asymbol **orig_table = bfd_get_outsymbols (abfd);
2833
  int serno;
2834
  struct mmo_symbol_trie root;
2835
  int trie_len;
2836
  int i;
2837
  bfd_byte buf[4];
2838
 
2839
  /* Create a symbol for "Main".  */
2840
  asymbol *fakemain = bfd_make_empty_symbol (abfd);
2841
 
2842
  fakemain->flags = BSF_GLOBAL;
2843
  fakemain->value = bfd_get_start_address (abfd);
2844
  fakemain->name = MMIX_START_SYMBOL_NAME;
2845
  fakemain->section = bfd_abs_section_ptr;
2846
  maintable[0] = fakemain;
2847
  maintable[1] = NULL;
2848
 
2849
  memset (&root, 0, sizeof (root));
2850
 
2851
  /* Make all symbols take a left turn.  */
2852
  root.symchar = 0xff;
2853
 
2854
  /* There must always be a ":Main", so we'll add one if there are no
2855
     symbols.  Make sure we have room for it.  */
2856
  table = bfd_alloc (abfd, (count + 1) * sizeof (asymbol *));
2857
  if (table == NULL)
2858
    return FALSE;
2859
 
2860
  memcpy (table, orig_table, count * sizeof (asymbol *));
2861
 
2862
  /* Move :Main (if there is one) to the first position.  This is
2863
     necessary to get the same layout of the trie-tree when linking as
2864
     when objcopying the result as in the objcopy.exp test "simple objcopy
2865
     of executable".  It also automatically takes care of assigning serial
2866
     number 1 to :Main (as is mandatory).  */
2867
  for (i = 0; i < count; i++)
2868
    if (table[i] != NULL
2869
        && strcmp (table[i]->name, MMIX_START_SYMBOL_NAME) == 0
2870
        && (table[i]->flags & (BSF_DEBUGGING|BSF_GLOBAL)) == BSF_GLOBAL)
2871
      {
2872
        asymbol *mainsym = table[i];
2873
        memcpy (table + 1, orig_table, i * sizeof (asymbol *));
2874
        table[0] = mainsym;
2875
 
2876
        /* Check that the value assigned to :Main is the same as the entry
2877
           address.  The default linker script asserts this.  This is as
2878
           good a place as any to check this consistency. */
2879
        if ((mainsym->value
2880
             + mainsym->section->output_section->vma
2881
             + mainsym->section->output_offset)
2882
            != bfd_get_start_address (abfd))
2883
          {
2884
            /* Arbitrary buffer to hold the printable representation of a
2885
               vma.  */
2886
            char vmas_main[40];
2887
            char vmas_start[40];
2888
            bfd_vma vma_start = bfd_get_start_address (abfd);
2889
 
2890
            sprintf_vma (vmas_main, mainsym->value);
2891
            sprintf_vma (vmas_start, vma_start);
2892
 
2893
            (*_bfd_error_handler)
2894
              (_("%s: Bad symbol definition: `Main' set to %s rather"
2895
                 " than the start address %s\n"),
2896
               bfd_get_filename (abfd), vmas_main, vmas_start);
2897
            bfd_set_error (bfd_error_bad_value);
2898
            return FALSE;
2899
          }
2900
        break;
2901
      }
2902
  if (i == count && count != 0)
2903
    {
2904
      /* When there are symbols, there must be a :Main.  There was no
2905
         :Main, so we need to add it manually.  */
2906
      memcpy (table + 1, orig_table, count * sizeof (asymbol *));
2907
      table[0] = fakemain;
2908
      count++;
2909
    }
2910
 
2911
  for (i = 0, serno = 1; i < count && table[i] != NULL; i++)
2912
    {
2913
      asymbol *s = table[i];
2914
 
2915
      /* It's not enough to consult bfd_is_local_label, since it does not
2916
         mean "local" in the sense of linkable-and-observable-after-link.
2917
         Let's just check the BSF_GLOBAL flag.
2918
 
2919
         Also, don't export symbols with characters not in the allowed set.  */
2920
      if ((s->flags & (BSF_DEBUGGING|BSF_GLOBAL)) == BSF_GLOBAL
2921
          && strspn (s->name,
2922
                     valid_mmo_symbol_character_set) == strlen (s->name))
2923
        {
2924
          struct mmo_symbol sym;
2925
          memset (&sym, 0, sizeof (sym));
2926
 
2927
          /* Need to strip const here; strdup:ing would leak and the
2928
             existing string must be safe to reuse.  */
2929
          sym.name = (char *) s->name;
2930
          sym.value =
2931
            s->value
2932
            + s->section->output_section->vma
2933
            + s->section->output_offset;
2934
 
2935
          if (bfd_is_und_section (s->section))
2936
            sym.sym_type = mmo_undef_sym;
2937
          else if (strcmp (s->section->name, MMO_DATA_SECTION_NAME) == 0
2938
                   /* The encoding of data symbols require that the "rest"
2939
                      of the value fits in 6 bytes, so the upper two bytes
2940
                      must be 0x2000.  All other symbols get to be the
2941
                      absolute type.  */
2942
                   && (sym.value >> 48) == 0x2000)
2943
            sym.sym_type = mmo_data_sym;
2944
          else if (strcmp (s->section->name, MMIX_REG_SECTION_NAME) == 0)
2945
            sym.sym_type = mmo_reg_sym;
2946
          else if (strcmp (s->section->name,
2947
                           MMIX_REG_CONTENTS_SECTION_NAME) == 0)
2948
            {
2949
              sym.sym_type = mmo_reg_sym;
2950
              sym.value /= 8;
2951
            }
2952
          else
2953
            sym.sym_type = mmo_abs_sym;
2954
 
2955
          /* FIXME: We assume the order of the received symbols is an
2956
             ordered mapping of the serial numbers.  This is not
2957
             necessarily true if we e.g. objcopy a mmo file to another and
2958
             there are gaps in the numbering.  Not sure if this can
2959
             happen.  Not sure what to do.  */
2960
          sym.serno = serno++;
2961
 
2962
          if (! mmo_internal_add_3_sym (abfd, &root, &sym))
2963
            return FALSE;
2964
        }
2965
    }
2966
 
2967
  /* Change the root node to be a ":"-prefix.  */
2968
  root.symchar = ':';
2969
  root.middle = root.left;
2970
  root.right = NULL;
2971
  root.left = NULL;
2972
 
2973
  /* We have to find out if we can fit the whole symbol table in the mmo
2974
     symtab.  It would be bad to assume we can always fit it in 262144
2975
     bytes.  If we can't, just leave the Main symbol.  */
2976
  trie_len = (mmo_internal_3_length (abfd, &root) + 3)/4;
2977
 
2978
  if (trie_len > 0xffff)
2979
    {
2980
      /* Test this code by using a lower limit in the test above and check
2981
         that the single "Main" symbol is emitted and handled properly.
2982
         There's no specific test-case.  */
2983
      struct mmo_symbol sym;
2984
 
2985
      (*_bfd_error_handler)
2986
        (_("%s: warning: symbol table too large for mmo, larger than 65535"
2987
           " 32-bit words: %d.  Only `Main' will be emitted.\n"),
2988
         bfd_get_filename (abfd), trie_len);
2989
 
2990
      memset (&sym, 0, sizeof (sym));
2991
      sym.sym_type = mmo_abs_sym;
2992
      sym.name = MMIX_START_SYMBOL_NAME;
2993
      sym.serno = 1;
2994
      sym.value = bfd_get_start_address (abfd);
2995
 
2996
      /* Then patch up a symbol table to be just the ":Main" symbol.  */
2997
      memset (&root, 0, sizeof (root));
2998
      root.left = root.middle;
2999
      root.symchar = 0xff;
3000
      root.middle = NULL;
3001
      root.right = NULL;
3002
 
3003
      if (! mmo_internal_add_3_sym (abfd, &root, &sym))
3004
        return FALSE;
3005
 
3006
      root.symchar = ':';
3007
      root.middle = root.left;
3008
      root.right = NULL;
3009
      root.left = NULL;
3010
 
3011
      trie_len = (mmo_internal_3_length (abfd, &root) + 3)/4;
3012
    }
3013
 
3014
  /* Reset the written-bytes counter.  */
3015
  abfd->tdata.mmo_data->byte_no = 0;
3016
 
3017
  /* Put out the lop_stab mark.  */
3018
  bfd_put_32 (abfd, (LOP << 24) | (LOP_STAB << 16), buf);
3019
  if (bfd_bwrite (buf, 4, abfd) != 4)
3020
    return FALSE;
3021
 
3022
  /* Dump out symbols.  */
3023
  mmo_internal_3_dump (abfd, &root);
3024
 
3025
  if (trie_len != (abfd->tdata.mmo_data->byte_no + 3)/4)
3026
    {
3027
      /* I haven't seen this trig.  It seems no use claiming this case
3028
         isn't debugged and abort if we get here.  Instead emit a
3029
         diagnostic and fail "normally".  */
3030
      (*_bfd_error_handler)
3031
        (_("%s: internal error, symbol table changed size from %d to %d"
3032
           " words\n"),
3033
         bfd_get_filename (abfd), trie_len,
3034
         (abfd->tdata.mmo_data->byte_no + 3)/4);
3035
      bfd_set_error (bfd_error_bad_value);
3036
      return FALSE;
3037
    }
3038
 
3039
  /* Dump out remaining bytes in the buffer and handle I/O errors by
3040
     propagating errors.  */
3041
  if ((abfd->tdata.mmo_data->byte_no % 4) != 0
3042
      || abfd->tdata.mmo_data->have_error)
3043
    {
3044
      memset (abfd->tdata.mmo_data->buf + (abfd->tdata.mmo_data->byte_no % 4),
3045
              0, 4 - (abfd->tdata.mmo_data->byte_no % 4));
3046
 
3047
      if (abfd->tdata.mmo_data->have_error
3048
          || bfd_bwrite (abfd->tdata.mmo_data->buf, 4, abfd) != 4)
3049
        return FALSE;
3050
    }
3051
 
3052
  bfd_put_32 (abfd, (LOP << 24) | (LOP_END << 16) | trie_len, buf);
3053
  return bfd_bwrite (buf, 4, abfd) == 4;
3054
}
3055
 
3056
/* Write section unless it is the register contents section.  For that, we
3057
   instead store the section in the supplied pointer.  This function is
3058
   used through bfd_map_over_sections.  */
3059
 
3060
static void
3061
mmo_write_section_unless_reg_contents (bfd *abfd, asection *sec, void *p)
3062
{
3063
  struct mmo_write_sec_info *infop = (struct mmo_write_sec_info *) p;
3064
 
3065
  if (! infop->retval)
3066
    return;
3067
 
3068
  if (strcmp (sec->name, MMIX_REG_CONTENTS_SECTION_NAME) == 0)
3069
    {
3070
      infop->reg_section = sec;
3071
      return;
3072
    }
3073
 
3074
  /* Exclude the convenience register section.  */
3075
  if (strcmp (sec->name, MMIX_REG_SECTION_NAME) == 0)
3076
    {
3077
      if (bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS)
3078
        {
3079
          /* Make sure it hasn't got contents.  It seems impossible to
3080
             make it carry contents, so we don't have a test-case for
3081
             this.  */
3082
          (*_bfd_error_handler)
3083
            (_("%s: internal error, internal register section %s had"
3084
               " contents\n"),
3085
             bfd_get_filename (abfd), sec->name);
3086
          bfd_set_error (bfd_error_bad_value);
3087
          infop->retval = FALSE;
3088
          return;
3089
        }
3090
 
3091
      return;
3092
    }
3093
 
3094
  infop->retval = mmo_internal_write_section (abfd, sec);
3095
}
3096
 
3097
/* Do the actual output of a file.  Assumes mmo_set_section_contents is
3098
   already called. */
3099
 
3100
static bfd_boolean
3101
mmo_write_object_contents (bfd *abfd)
3102
{
3103
  struct mmo_write_sec_info wsecinfo;
3104
 
3105
  /* First, there are a few words of preamble.  */
3106
  if (! mmo_internal_write_header (abfd))
3107
    return FALSE;
3108
 
3109
  wsecinfo.reg_section = NULL;
3110
  wsecinfo.retval = TRUE;
3111
 
3112
  bfd_map_over_sections (abfd, mmo_write_section_unless_reg_contents,
3113
                         &wsecinfo);
3114
 
3115
  if (! wsecinfo.retval)
3116
    return FALSE;
3117
 
3118
  if (wsecinfo.reg_section != NULL)
3119
    {
3120
      asection *sec = wsecinfo.reg_section;
3121
      unsigned int z = (unsigned int) (sec->vma / 8);
3122
 
3123
      /* Registers 0..31 must not be global.  Do sanity check on the "vma"
3124
         of the register contents section and check that it corresponds to
3125
         the length of the section.  */
3126
      if (z < 32 || z >= 255 || (sec->vma & 7) != 0
3127
          || sec->vma != 256 * 8 - sec->size - 8)
3128
        {
3129
          bfd_set_error (bfd_error_bad_value);
3130
 
3131
          if (sec->size == 0)
3132
            /* There must always be at least one such register.  */
3133
            (*_bfd_error_handler)
3134
              (_("%s: no initialized registers; section length 0\n"),
3135
               bfd_get_filename (abfd));
3136
          else if (sec->vma > (256 - 32) * 8)
3137
            /* Provide better error message for the case of too many
3138
               global registers.  */
3139
            (*_bfd_error_handler)
3140
              (_("%s: too many initialized registers; section length %ld\n"),
3141
               bfd_get_filename (abfd),
3142
               (long) sec->size);
3143
          else
3144
            (*_bfd_error_handler)
3145
              (_("%s: invalid start address for initialized registers of"
3146
                 " length %ld: 0x%lx%08lx\n"),
3147
               bfd_get_filename (abfd),
3148
               (long) sec->size,
3149
               (unsigned long) (sec->vma >> 32), (unsigned long) (sec->vma));
3150
 
3151
          return FALSE;
3152
        }
3153
 
3154
      if (! mmo_internal_write_post (abfd, z, sec))
3155
        return FALSE;
3156
    }
3157
  else
3158
    if (! mmo_internal_write_post (abfd, 255, NULL))
3159
      return FALSE;
3160
 
3161
  return mmo_write_symbols_and_terminator (abfd);
3162
}
3163
 
3164
/* If there's anything in particular in a mmo bfd that we want to free,
3165
   make this a real function.  Only do this if you see major memory
3166
   thrashing; zealous free:ing will cause unwanted behavior, especially if
3167
   you "free" memory allocated with "bfd_alloc", or even "bfd_release" a
3168
   block allocated with "bfd_alloc"; they're really allocated from an
3169
   obstack, and we don't know what was allocated there since this
3170
   particular allocation.  */
3171
 
3172
#define mmo_close_and_cleanup _bfd_generic_close_and_cleanup
3173
#define mmo_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
3174
 
3175
/* Perhaps we need to adjust this one; mmo labels (originally) without a
3176
   leading ':' might more appropriately be called local.  */
3177
#define mmo_bfd_is_local_label_name bfd_generic_is_local_label_name
3178
#define mmo_bfd_is_target_special_symbol  \
3179
  ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
3180
 
3181
/* Is this one really used or defined by anyone?  */
3182
#define mmo_get_lineno _bfd_nosymbols_get_lineno
3183
 
3184
/* FIXME: We can do better on this one, if we have a dwarf2 .debug_line
3185
   section or if MMO line numbers are implemented.  */
3186
#define mmo_find_nearest_line _bfd_nosymbols_find_nearest_line
3187
#define mmo_find_inliner_info _bfd_nosymbols_find_inliner_info
3188
#define mmo_make_empty_symbol _bfd_generic_make_empty_symbol
3189
#define mmo_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
3190
#define mmo_read_minisymbols _bfd_generic_read_minisymbols
3191
#define mmo_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
3192
 
3193
#define mmo_get_section_contents_in_window \
3194
  _bfd_generic_get_section_contents_in_window
3195
#define mmo_bfd_get_relocated_section_contents \
3196
  bfd_generic_get_relocated_section_contents
3197
#define mmo_bfd_gc_sections bfd_generic_gc_sections
3198
#define mmo_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
3199
#define mmo_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
3200
#define mmo_bfd_link_add_symbols _bfd_generic_link_add_symbols
3201
#define mmo_bfd_link_just_syms _bfd_generic_link_just_syms
3202
#define mmo_bfd_final_link _bfd_generic_final_link
3203
#define mmo_bfd_link_split_section _bfd_generic_link_split_section
3204
 
3205
/* Strictly speaking, only MMIX uses this restricted format, but let's not
3206
   stop anybody from shooting themselves in the foot.  */
3207
#define mmo_set_arch_mach bfd_default_set_arch_mach
3208
#define mmo_bfd_relax_section bfd_generic_relax_section
3209
#define mmo_bfd_merge_sections bfd_generic_merge_sections
3210
#define mmo_bfd_is_group_section bfd_generic_is_group_section
3211
#define mmo_bfd_discard_group bfd_generic_discard_group
3212
#define mmo_section_already_linked \
3213
  _bfd_generic_section_already_linked
3214 225 jeremybenn
#define mmo_bfd_define_common_symbol bfd_generic_define_common_symbol
3215 24 jeremybenn
 
3216
/* We want to copy time of creation, otherwise we'd use
3217
   BFD_JUMP_TABLE_COPY (_bfd_generic).  */
3218
#define mmo_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
3219
#define mmo_bfd_copy_private_section_data _bfd_generic_bfd_copy_private_section_data
3220
#define mmo_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data
3221
#define mmo_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data
3222
#define mmo_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
3223
#define mmo_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data
3224
 
3225
const bfd_target bfd_mmo_vec =
3226
{
3227
  "mmo",                        /* name */
3228
  bfd_target_mmo_flavour,
3229
  BFD_ENDIAN_BIG,               /* target byte order */
3230
  BFD_ENDIAN_BIG,               /* target headers byte order */
3231
 
3232
  /* FIXME: Might need adjustments.  */
3233
  (HAS_RELOC | EXEC_P |         /* object flags */
3234
   HAS_LINENO | HAS_DEBUG |
3235
   HAS_SYMS | HAS_LOCALS | WP_TEXT),
3236
 
3237
  /* FIXME: Might need adjustments.  */
3238
  (SEC_CODE | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD
3239
   | SEC_READONLY | SEC_EXCLUDE | SEC_DEBUGGING | SEC_IN_MEMORY),
3240
                                /* section flags */
3241
  0,                             /* leading underscore */
3242
  ' ',                          /* ar_pad_char */
3243
  16,                           /* ar_max_namelen */
3244
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
3245
  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
3246
  bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* data */
3247
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
3248
  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
3249
  bfd_getb16, bfd_getb_signed_16, bfd_putb16,   /* hdrs */
3250
 
3251
  {
3252
    _bfd_dummy_target,
3253
    mmo_object_p,               /* bfd_check_format */
3254
    _bfd_dummy_target,
3255
    _bfd_dummy_target,
3256
  },
3257
  {
3258
    bfd_false,
3259
    mmo_mkobject,
3260
    bfd_false,
3261
    bfd_false,
3262
  },
3263
  {                             /* bfd_write_contents */
3264
    bfd_false,
3265
    mmo_write_object_contents,
3266
    bfd_false,
3267
    bfd_false,
3268
  },
3269
 
3270
  BFD_JUMP_TABLE_GENERIC (mmo),
3271
  BFD_JUMP_TABLE_COPY (mmo),
3272
  BFD_JUMP_TABLE_CORE (_bfd_nocore),
3273
  BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
3274
  BFD_JUMP_TABLE_SYMBOLS (mmo),
3275
  BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
3276
  BFD_JUMP_TABLE_WRITE (mmo),
3277
  BFD_JUMP_TABLE_LINK (mmo),
3278
  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
3279
 
3280
  NULL,
3281
 
3282
  NULL
3283
};

powered by: WebSVN 2.1.0

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