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