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