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