Coverage Report

Created: 2026-09-14 08:07

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