Coverage Report

Created: 2023-08-28 06:31

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