OSDN Git Service

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