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