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

Subversion Repositories or1k

[/] [or1k/] [tags/] [VER_5_3/] [gdb-5.3/] [bfd/] [mmo.c] - Blame information for rev 1783

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

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

powered by: WebSVN 2.1.0

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