Coverage Report

Created: 2025-06-24 06:45

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