1 /* obj-format for ieee-695 records. 2 Copyright 1991, 1992, 1993, 1994, 1997, 2000 3 Free Software Foundation, Inc. 4 5 This file is part of GAS, the GNU Assembler. 6 7 GAS is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2, or (at your option) 10 any later version. 11 12 GAS is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GAS; see the file COPYING. If not, write to the Free 19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA 20 02111-1307, USA. */ 21 22 /* Created by Steve Chamberlain <steve@cygnus.com>. */ 23 24 /* This will hopefully become the port through which bfd and gas talk, 25 for the moment, only ieee is known to work well. */ 26 27 #include "bfd.h" 28 #include "as.h" 29 #include "subsegs.h" 30 #include "output-file.h" 31 #include "frags.h" 32 33 bfd *abfd; 34 35 /* How many addresses does the .align take? */ 36 37 static relax_addressT 38 relax_align (address, alignment) 39 /* Address now. */ 40 register relax_addressT address; 41 42 /* Alignment (binary). */ 43 register long alignment; 44 { 45 relax_addressT mask; 46 relax_addressT new_address; 47 48 mask = ~((~0) << alignment); 49 new_address = (address + mask) & (~mask); 50 return (new_address - address); 51 } 52 53 /* Calculate the size of the frag chain 54 and create a bfd section to contain all of it. */ 55 56 static void 57 size_section (abfd, idx) 58 bfd *abfd; 59 unsigned int idx; 60 { 61 asection *sec; 62 unsigned int size = 0; 63 fragS *frag = segment_info[idx].frag_root; 64 65 while (frag) 66 { 67 if (frag->fr_address != size) 68 { 69 printf (_("Out of step\n")); 70 size = frag->fr_address; 71 } 72 size += frag->fr_fix; 73 switch (frag->fr_type) 74 { 75 case rs_fill: 76 case rs_org: 77 size += frag->fr_offset * frag->fr_var; 78 break; 79 case rs_align: 80 case rs_align_code: 81 { 82 addressT off; 83 84 off = relax_align (size, frag->fr_offset); 85 if (frag->fr_subtype != 0 && off > frag->fr_subtype) 86 off = 0; 87 size += off; 88 } 89 } 90 frag = frag->fr_next; 91 } 92 if (size) 93 { 94 char *name = segment_info[idx].name; 95 96 if (name == (char *) NULL) 97 name = ".data"; 98 99 segment_info[idx].user_stuff = 100 (char *) (sec = bfd_make_section (abfd, name)); 101 /* Make it output through itself. */ 102 sec->output_section = sec; 103 sec->flags |= SEC_HAS_CONTENTS; 104 bfd_set_section_size (abfd, sec, size); 105 } 106 } 107 108 /* Run through a frag chain and write out the data to go with it. */ 109 110 static void 111 fill_section (abfd, idx) 112 bfd *abfd; 113 unsigned int idx; 114 { 115 asection *sec = segment_info[idx].user_stuff; 116 117 if (sec) 118 { 119 fragS *frag = segment_info[idx].frag_root; 120 unsigned int offset = 0; 121 while (frag) 122 { 123 unsigned int fill_size; 124 unsigned int count; 125 switch (frag->fr_type) 126 { 127 case rs_fill: 128 case rs_align: 129 case rs_org: 130 if (frag->fr_fix) 131 { 132 bfd_set_section_contents (abfd, 133 sec, 134 frag->fr_literal, 135 frag->fr_address, 136 frag->fr_fix); 137 } 138 offset += frag->fr_fix; 139 fill_size = frag->fr_var; 140 if (fill_size) 141 { 142 unsigned int off = frag->fr_fix; 143 for (count = frag->fr_offset; count; count--) 144 { 145 bfd_set_section_contents (abfd, sec, 146 frag->fr_literal + 147 frag->fr_fix, 148 frag->fr_address + off, 149 fill_size); 150 off += fill_size; 151 } 152 } 153 break; 154 default: 155 abort (); 156 } 157 frag = frag->fr_next; 158 } 159 } 160 } 161 162 /* Count the relocations in a chain. */ 163 164 static unsigned int 165 count_entries_in_chain (idx) 166 unsigned int idx; 167 { 168 unsigned int nrelocs; 169 fixS *fixup_ptr; 170 171 /* Count the relocations. */ 172 fixup_ptr = segment_info[idx].fix_root; 173 nrelocs = 0; 174 while (fixup_ptr != (fixS *) NULL) 175 { 176 fixup_ptr = fixup_ptr->fx_next; 177 nrelocs++; 178 } 179 return nrelocs; 180 } 181 182 /* Output all the relocations for a section. */ 183 184 void 185 do_relocs_for (idx) 186 unsigned int idx; 187 { 188 unsigned int nrelocs; 189 arelent **reloc_ptr_vector; 190 arelent *reloc_vector; 191 asymbol **ptrs; 192 asection *section = (asection *) (segment_info[idx].user_stuff); 193 unsigned int i; 194 fixS *from; 195 196 if (section) 197 { 198 nrelocs = count_entries_in_chain (idx); 199 200 reloc_ptr_vector = 201 (arelent **) malloc ((nrelocs + 1) * sizeof (arelent *)); 202 reloc_vector = (arelent *) malloc (nrelocs * sizeof (arelent)); 203 ptrs = (asymbol **) malloc (nrelocs * sizeof (asymbol *)); 204 from = segment_info[idx].fix_root; 205 for (i = 0; i < nrelocs; i++) 206 { 207 arelent *to = reloc_vector + i; 208 asymbol *s; 209 reloc_ptr_vector[i] = to; 210 to->howto = (reloc_howto_type *) (from->fx_r_type); 211 212 #if 0 213 /* We can't represent complicated things in a reloc yet. */ 214 if (from->fx_addsy == 0 || from->fx_subsy != 0) 215 abort (); 216 #endif 217 218 s = &(from->fx_addsy->sy_symbol.sy); 219 to->address = ((char *) (from->fx_frag->fr_address + 220 from->fx_where)) 221 - ((char *) (&(from->fx_frag->fr_literal))); 222 to->addend = from->fx_offset; 223 /* If we know the symbol which we want to relocate to, turn 224 this reloaction into a section relative. 225 226 If this relocation is pcrelative, and we know the 227 destination, we still want to keep the relocation - since 228 the linker might relax some of the bytes, but it stops 229 being pc relative and turns into an absolute relocation. */ 230 if (s) 231 { 232 if ((s->flags & BSF_UNDEFINED) == 0) 233 { 234 to->section = s->section; 235 236 /* We can refer directly to the value field here, 237 rather than using S_GET_VALUE, because this is 238 only called after do_symbols, which sets up the 239 value field. */ 240 to->addend += s->value; 241 242 to->sym_ptr_ptr = 0; 243 if (to->howto->pcrel_offset) 244 /* This is a pcrel relocation, the addend should 245 be adjusted. */ 246 to->addend -= to->address + 1; 247 } 248 else 249 { 250 to->section = 0; 251 *ptrs = &(from->fx_addsy->sy_symbol.sy); 252 to->sym_ptr_ptr = ptrs; 253 254 if (to->howto->pcrel_offset) 255 /* This is a pcrel relocation, the addend should 256 be adjusted. */ 257 to->addend -= to->address - 1; 258 } 259 } 260 else 261 to->section = 0; 262 263 ptrs++; 264 from = from->fx_next; 265 } 266 267 /* Attach to the section. */ 268 section->orelocation = reloc_ptr_vector; 269 section->reloc_count = nrelocs; 270 section->flags |= SEC_LOAD; 271 } 272 } 273 274 /* Do the symbols. */ 275 276 static void 277 do_symbols (abfd) 278 bfd *abfd; 279 { 280 extern symbolS *symbol_rootP; 281 symbolS *ptr; 282 asymbol **symbol_ptr_vec; 283 asymbol *symbol_vec; 284 unsigned int count = 0; 285 unsigned int index; 286 287 for (ptr = symbol_rootP; 288 ptr != (symbolS *) NULL; 289 ptr = ptr->sy_next) 290 { 291 if (SEG_NORMAL (ptr->sy_symbol.seg)) 292 { 293 ptr->sy_symbol.sy.section = 294 (asection *) (segment_info[ptr->sy_symbol.seg].user_stuff); 295 S_SET_VALUE (ptr, S_GET_VALUE (ptr)); 296 if (ptr->sy_symbol.sy.flags == 0) 297 ptr->sy_symbol.sy.flags = BSF_LOCAL; 298 } 299 else 300 { 301 switch (ptr->sy_symbol.seg) 302 { 303 case SEG_ABSOLUTE: 304 ptr->sy_symbol.sy.flags |= BSF_ABSOLUTE; 305 ptr->sy_symbol.sy.section = 0; 306 break; 307 case SEG_UNKNOWN: 308 ptr->sy_symbol.sy.flags = BSF_UNDEFINED; 309 ptr->sy_symbol.sy.section = 0; 310 break; 311 default: 312 abort (); 313 } 314 } 315 ptr->sy_symbol.sy.value = S_GET_VALUE (ptr); 316 count++; 317 } 318 symbol_ptr_vec = (asymbol **) malloc ((count + 1) * sizeof (asymbol *)); 319 320 index = 0; 321 for (ptr = symbol_rootP; 322 ptr != (symbolS *) NULL; 323 ptr = ptr->sy_next) 324 { 325 symbol_ptr_vec[index] = &(ptr->sy_symbol.sy); 326 index++; 327 } 328 symbol_ptr_vec[index] = 0; 329 abfd->outsymbols = symbol_ptr_vec; 330 abfd->symcount = count; 331 } 332 333 /* The generic as->bfd converter. Other backends may have special case 334 code. */ 335 336 void 337 bfd_as_write_hook () 338 { 339 int i; 340 341 for (i = SEG_E0; i < SEG_UNKNOWN; i++) 342 size_section (abfd, i); 343 344 for (i = SEG_E0; i < SEG_UNKNOWN; i++) 345 fill_section (abfd, i); 346 347 do_symbols (abfd); 348 349 for (i = SEG_E0; i < SEG_UNKNOWN; i++) 350 do_relocs_for (i); 351 } 352 353 S_SET_SEGMENT (x, y) 354 symbolS *x; 355 int y; 356 { 357 x->sy_symbol.seg = y; 358 } 359 360 S_IS_DEFINED (x) 361 symbolS *x; 362 { 363 if (SEG_NORMAL (x->sy_symbol.seg)) 364 { 365 return 1; 366 } 367 switch (x->sy_symbol.seg) 368 { 369 case SEG_UNKNOWN: 370 return 0; 371 default: 372 abort (); 373 } 374 } 375 376 S_IS_EXTERNAL (x) 377 { 378 abort (); 379 } 380 381 S_GET_DESC (x) 382 { 383 abort (); 384 } 385 386 S_GET_SEGMENT (x) 387 symbolS *x; 388 { 389 return x->sy_symbol.seg; 390 } 391 392 S_SET_EXTERNAL (x) 393 symbolS *x; 394 { 395 x->sy_symbol.sy.flags |= BSF_GLOBAL | BSF_EXPORT; 396 } 397 398 S_SET_NAME (x, y) 399 symbolS *x; 400 char *y; 401 { 402 x->sy_symbol.sy.name = y; 403 } 404 405 S_GET_OTHER (x) 406 { 407 abort (); 408 } 409 410 S_IS_DEBUG (x) 411 { 412 abort (); 413 } 414 415 #ifndef segment_name 416 char * 417 segment_name () 418 { 419 abort (); 420 } 421 #endif 422 423 void 424 obj_read_begin_hook () 425 { 426 } 427 428 static void 429 obj_ieee_section (ignore) 430 int ignore; 431 { 432 extern char *input_line_pointer; 433 extern char is_end_of_line[]; 434 char *p = input_line_pointer; 435 char *s = p; 436 int i; 437 438 /* Look up the name, if it doesn't exist, make it. */ 439 while (*p && *p != ' ' && *p != ',' && !is_end_of_line[*p]) 440 { 441 p++; 442 } 443 for (i = SEG_E0; i < SEG_UNKNOWN; i++) 444 { 445 if (segment_info[i].hadone) 446 { 447 if (strncmp (segment_info[i].name, s, p - s) == 0) 448 goto ok; 449 } 450 else 451 break; 452 } 453 if (i == SEG_UNKNOWN) 454 { 455 as_bad (_("too many sections")); 456 return; 457 } 458 459 segment_info[i].hadone = 1; 460 segment_info[i].name = malloc (p - s + 1); 461 memcpy (segment_info[i].name, s, p - s); 462 segment_info[i].name[p - s] = 0; 463 ok: 464 subseg_set (i, 0); 465 while (!is_end_of_line[*p]) 466 p++; 467 input_line_pointer = p; 468 } 469 470 const pseudo_typeS obj_pseudo_table[] = 471 { 472 {"section", obj_ieee_section, 0}, 473 {"data.b" , cons , 1}, 474 {"data.w" , cons , 2}, 475 {"data.l" , cons , 4}, 476 {"export" , s_globl , 0}, 477 {"option" , s_ignore , 0}, 478 {"end" , s_ignore , 0}, 479 {"import" , s_ignore , 0}, 480 {"sdata" , stringer , 0}, 481 0, 482 }; 483 484 void 485 obj_symbol_new_hook (symbolP) 486 symbolS *symbolP; 487 { 488 symbolP->sy_symbol.sy.the_bfd = abfd; 489 } 490 491 #if 1 492 493 #ifndef SUB_SEGMENT_ALIGN 494 #ifdef HANDLE_ALIGN 495 /* The last subsegment gets an alignment corresponding to the alignment 496 of the section. This allows proper nop-filling at the end of 497 code-bearing sections. */ 498 #define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) \ 499 (!(FRCHAIN)->frch_next || (FRCHAIN)->frch_next->frch_seg != (SEG) \ 500 ? get_recorded_alignment (SEG) : 0) 501 #else 502 #define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 2 503 #endif 504 #endif 505 506 extern void 507 write_object_file () 508 { 509 int i; 510 struct frchain *frchain_ptr; 511 struct frag *frag_ptr; 512 513 abfd = bfd_openw (out_file_name, "ieee"); 514 515 if (abfd == 0) 516 { 517 as_perror (_("FATAL: Can't create %s"), out_file_name); 518 exit (EXIT_FAILURE); 519 } 520 bfd_set_format (abfd, bfd_object); 521 bfd_set_arch_mach (abfd, bfd_arch_h8300, 0); 522 subseg_set (1, 0); 523 subseg_set (2, 0); 524 subseg_set (3, 0); 525 526 /* Run through all the sub-segments and align them up. Also 527 close any open frags. We tack a .fill onto the end of the 528 frag chain so that any .align's size can be worked by looking 529 at the next frag. */ 530 for (frchain_ptr = frchain_root; 531 frchain_ptr != (struct frchain *) NULL; 532 frchain_ptr = frchain_ptr->frch_next) 533 { 534 int alignment; 535 536 subseg_set (frchain_ptr->frch_seg, frchain_ptr->frch_subseg); 537 538 alignment = SUB_SEGMENT_ALIGN (now_seg, frchain_ptr) 539 540 #ifdef md_do_align 541 md_do_align (alignment, (char *) NULL, 0, 0, alignment_done); 542 #endif 543 if (subseg_text_p (now_seg)) 544 frag_align_code (alignment, 0); 545 else 546 frag_align (alignment, 0, 0); 547 548 #ifdef md_do_align 549 alignment_done: 550 #endif 551 552 frag_wane (frag_now); 553 frag_now->fr_fix = 0; 554 know (frag_now->fr_next == NULL); 555 } 556 557 /* Now build one big frag chain for each segment, linked through 558 fr_next. */ 559 for (i = SEG_E0; i < SEG_UNKNOWN; i++) 560 { 561 fragS **prev_frag_ptr_ptr; 562 struct frchain *next_frchain_ptr; 563 564 #if 0 565 struct frag **head_ptr = segment_info[i].frag_root; 566 #endif 567 568 segment_info[i].frag_root = segment_info[i].frchainP->frch_root; 569 #if 0 570 /* I'm not sure what this is for. */ 571 for (frchain_ptr = segment_info[i].frchainP->frch_root; 572 frchain_ptr != (struct frchain *) NULL; 573 frchain_ptr = frchain_ptr->frch_next) 574 { 575 *head_ptr = frchain_ptr; 576 head_ptr = &frchain_ptr->next; 577 } 578 #endif 579 } 580 581 for (i = SEG_E0; i < SEG_UNKNOWN; i++) 582 relax_segment (segment_info[i].frag_root, i); 583 584 /* Relaxation has completed. Freeze all syms. */ 585 finalize_syms = 1; 586 587 /* Now the addresses of the frags are correct within the segment. */ 588 589 bfd_as_write_hook (); 590 bfd_close (abfd); 591 } 592 593 #endif 594 595 H_SET_TEXT_SIZE (a, b) 596 { 597 abort (); 598 } 599 600 H_GET_TEXT_SIZE () 601 { 602 abort (); 603 } 604 605 H_SET_BSS_SIZE () 606 { 607 abort (); 608 } 609 610 H_SET_STRING_SIZE () 611 { 612 abort (); 613 } 614 615 H_SET_RELOCATION_SIZE () 616 { 617 abort (); 618 } 619 620 H_SET_MAGIC_NUMBER () 621 { 622 abort (); 623 } 624 625 H_GET_FILE_SIZE () 626 { 627 abort (); 628 } 629 630 H_GET_TEXT_RELOCATION_SIZE () 631 { 632 abort (); 633 } 634