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