OSDN Git Service

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