1 /* obj-format for ieee-695 records. 2 Copyright 1991, 1992, 1993, 1994, 1997, 2000, 2001, 2002, 2003, 2005 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, 51 Franklin Street - Fifth Floor, Boston, MA 20 02110-1301, 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 s = &(from->fx_addsy->sy_symbol.sy); 213 to->address = ((char *) (from->fx_frag->fr_address + 214 from->fx_where)) 215 - ((char *) (&(from->fx_frag->fr_literal))); 216 to->addend = from->fx_offset; 217 /* If we know the symbol which we want to relocate to, turn 218 this reloaction into a section relative. 219 220 If this relocation is pcrelative, and we know the 221 destination, we still want to keep the relocation - since 222 the linker might relax some of the bytes, but it stops 223 being pc relative and turns into an absolute relocation. */ 224 if (s) 225 { 226 if ((s->flags & BSF_UNDEFINED) == 0) 227 { 228 to->section = s->section; 229 230 /* We can refer directly to the value field here, 231 rather than using S_GET_VALUE, because this is 232 only called after do_symbols, which sets up the 233 value field. */ 234 to->addend += s->value; 235 236 to->sym_ptr_ptr = 0; 237 if (to->howto->pcrel_offset) 238 /* This is a pcrel relocation, the addend should 239 be adjusted. */ 240 to->addend -= to->address + 1; 241 } 242 else 243 { 244 to->section = 0; 245 *ptrs = &(from->fx_addsy->sy_symbol.sy); 246 to->sym_ptr_ptr = ptrs; 247 248 if (to->howto->pcrel_offset) 249 /* This is a pcrel relocation, the addend should 250 be adjusted. */ 251 to->addend -= to->address - 1; 252 } 253 } 254 else 255 to->section = 0; 256 257 ptrs++; 258 from = from->fx_next; 259 } 260 261 /* Attach to the section. */ 262 section->orelocation = reloc_ptr_vector; 263 section->reloc_count = nrelocs; 264 section->flags |= SEC_LOAD; 265 } 266 } 267 268 /* Do the symbols. */ 269 270 static void 271 do_symbols (abfd) 272 bfd *abfd; 273 { 274 extern symbolS *symbol_rootP; 275 symbolS *ptr; 276 asymbol **symbol_ptr_vec; 277 asymbol *symbol_vec; 278 unsigned int count = 0; 279 unsigned int index; 280 281 for (ptr = symbol_rootP; 282 ptr != (symbolS *) NULL; 283 ptr = ptr->sy_next) 284 { 285 if (SEG_NORMAL (ptr->sy_symbol.seg)) 286 { 287 ptr->sy_symbol.sy.section = 288 (asection *) (segment_info[ptr->sy_symbol.seg].user_stuff); 289 S_SET_VALUE (ptr, S_GET_VALUE (ptr)); 290 if (ptr->sy_symbol.sy.flags == 0) 291 ptr->sy_symbol.sy.flags = BSF_LOCAL; 292 } 293 else 294 { 295 switch (ptr->sy_symbol.seg) 296 { 297 case SEG_ABSOLUTE: 298 ptr->sy_symbol.sy.flags |= BSF_ABSOLUTE; 299 ptr->sy_symbol.sy.section = 0; 300 break; 301 case SEG_UNKNOWN: 302 ptr->sy_symbol.sy.flags = BSF_UNDEFINED; 303 ptr->sy_symbol.sy.section = 0; 304 break; 305 default: 306 abort (); 307 } 308 } 309 ptr->sy_symbol.sy.value = S_GET_VALUE (ptr); 310 count++; 311 } 312 symbol_ptr_vec = (asymbol **) malloc ((count + 1) * sizeof (asymbol *)); 313 314 index = 0; 315 for (ptr = symbol_rootP; 316 ptr != (symbolS *) NULL; 317 ptr = ptr->sy_next) 318 { 319 symbol_ptr_vec[index] = &(ptr->sy_symbol.sy); 320 index++; 321 } 322 symbol_ptr_vec[index] = 0; 323 abfd->outsymbols = symbol_ptr_vec; 324 abfd->symcount = count; 325 } 326 327 /* The generic as->bfd converter. Other backends may have special case 328 code. */ 329 330 void 331 bfd_as_write_hook () 332 { 333 int i; 334 335 for (i = SEG_E0; i < SEG_UNKNOWN; i++) 336 size_section (abfd, i); 337 338 for (i = SEG_E0; i < SEG_UNKNOWN; i++) 339 fill_section (abfd, i); 340 341 do_symbols (abfd); 342 343 for (i = SEG_E0; i < SEG_UNKNOWN; i++) 344 do_relocs_for (i); 345 } 346 347 S_SET_SEGMENT (x, y) 348 symbolS *x; 349 int y; 350 { 351 x->sy_symbol.seg = y; 352 } 353 354 S_IS_DEFINED (x) 355 symbolS *x; 356 { 357 if (SEG_NORMAL (x->sy_symbol.seg)) 358 { 359 return 1; 360 } 361 switch (x->sy_symbol.seg) 362 { 363 case SEG_UNKNOWN: 364 return 0; 365 default: 366 abort (); 367 } 368 } 369 370 S_IS_EXTERNAL (x) 371 { 372 abort (); 373 } 374 375 S_GET_DESC (x) 376 { 377 abort (); 378 } 379 380 S_GET_SEGMENT (x) 381 symbolS *x; 382 { 383 return x->sy_symbol.seg; 384 } 385 386 S_SET_EXTERNAL (x) 387 symbolS *x; 388 { 389 x->sy_symbol.sy.flags |= BSF_GLOBAL | BSF_EXPORT; 390 } 391 392 S_SET_NAME (x, y) 393 symbolS *x; 394 char *y; 395 { 396 x->sy_symbol.sy.name = y; 397 } 398 399 S_GET_OTHER (x) 400 { 401 abort (); 402 } 403 404 S_IS_DEBUG (x) 405 { 406 abort (); 407 } 408 409 #ifndef segment_name 410 char * 411 segment_name () 412 { 413 abort (); 414 } 415 #endif 416 417 void 418 obj_read_begin_hook () 419 { 420 } 421 422 static void 423 obj_ieee_section (ignore) 424 int ignore; 425 { 426 extern char *input_line_pointer; 427 extern char is_end_of_line[]; 428 char *p = input_line_pointer; 429 char *s = p; 430 int i; 431 432 /* Look up the name, if it doesn't exist, make it. */ 433 while (*p && *p != ' ' && *p != ',' && !is_end_of_line[*p]) 434 { 435 p++; 436 } 437 for (i = SEG_E0; i < SEG_UNKNOWN; i++) 438 { 439 if (segment_info[i].hadone) 440 { 441 if (strncmp (segment_info[i].name, s, p - s) == 0) 442 goto ok; 443 } 444 else 445 break; 446 } 447 if (i == SEG_UNKNOWN) 448 { 449 as_bad (_("too many sections")); 450 return; 451 } 452 453 segment_info[i].hadone = 1; 454 segment_info[i].name = malloc (p - s + 1); 455 memcpy (segment_info[i].name, s, p - s); 456 segment_info[i].name[p - s] = 0; 457 ok: 458 subseg_set (i, 0); 459 while (!is_end_of_line[*p]) 460 p++; 461 input_line_pointer = p; 462 } 463 464 const pseudo_typeS obj_pseudo_table[] = 465 { 466 {"section", obj_ieee_section, 0}, 467 {"data.b" , cons , 1}, 468 {"data.w" , cons , 2}, 469 {"data.l" , cons , 4}, 470 {"export" , s_globl , 0}, 471 {"option" , s_ignore , 0}, 472 {"end" , s_ignore , 0}, 473 {"import" , s_ignore , 0}, 474 {"sdata" , stringer , 0}, 475 0, 476 }; 477 478 void 479 obj_symbol_new_hook (symbolP) 480 symbolS *symbolP; 481 { 482 symbolP->sy_symbol.sy.the_bfd = abfd; 483 } 484 485 #if 1 486 487 #ifndef SUB_SEGMENT_ALIGN 488 #ifdef HANDLE_ALIGN 489 /* The last subsegment gets an alignment corresponding to the alignment 490 of the section. This allows proper nop-filling at the end of 491 code-bearing sections. */ 492 #define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) \ 493 (!(FRCHAIN)->frch_next || (FRCHAIN)->frch_next->frch_seg != (SEG) \ 494 ? get_recorded_alignment (SEG) : 0) 495 #else 496 #define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 2 497 #endif 498 #endif 499 500 extern void 501 write_object_file () 502 { 503 int i; 504 struct frchain *frchain_ptr; 505 struct frag *frag_ptr; 506 507 abfd = bfd_openw (out_file_name, "ieee"); 508 509 if (abfd == 0) 510 { 511 as_perror (_("FATAL: Can't create %s"), out_file_name); 512 exit (EXIT_FAILURE); 513 } 514 bfd_set_format (abfd, bfd_object); 515 bfd_set_arch_mach (abfd, bfd_arch_h8300, 0); 516 subseg_set (1, 0); 517 subseg_set (2, 0); 518 subseg_set (3, 0); 519 520 /* Run through all the sub-segments and align them up. Also 521 close any open frags. We tack a .fill onto the end of the 522 frag chain so that any .align's size can be worked by looking 523 at the next frag. */ 524 for (frchain_ptr = frchain_root; 525 frchain_ptr != (struct frchain *) NULL; 526 frchain_ptr = frchain_ptr->frch_next) 527 { 528 int alignment; 529 530 subseg_set (frchain_ptr->frch_seg, frchain_ptr->frch_subseg); 531 532 alignment = SUB_SEGMENT_ALIGN (now_seg, frchain_ptr) 533 534 #ifdef md_do_align 535 md_do_align (alignment, (char *) NULL, 0, 0, alignment_done); 536 #endif 537 if (subseg_text_p (now_seg)) 538 frag_align_code (alignment, 0); 539 else 540 frag_align (alignment, 0, 0); 541 542 #ifdef md_do_align 543 alignment_done: 544 #endif 545 546 frag_wane (frag_now); 547 frag_now->fr_fix = 0; 548 know (frag_now->fr_next == NULL); 549 } 550 551 /* Now build one big frag chain for each segment, linked through 552 fr_next. */ 553 for (i = SEG_E0; i < SEG_UNKNOWN; i++) 554 { 555 fragS **prev_frag_ptr_ptr; 556 struct frchain *next_frchain_ptr; 557 558 segment_info[i].frag_root = segment_info[i].frchainP->frch_root; 559 } 560 561 for (i = SEG_E0; i < SEG_UNKNOWN; i++) 562 relax_segment (segment_info[i].frag_root, i); 563 564 /* Relaxation has completed. Freeze all syms. */ 565 finalize_syms = 1; 566 567 /* Now the addresses of the frags are correct within the segment. */ 568 569 bfd_as_write_hook (); 570 bfd_close (abfd); 571 } 572 573 #endif 574 575 H_SET_TEXT_SIZE (a, b) 576 { 577 abort (); 578 } 579 580 H_GET_TEXT_SIZE () 581 { 582 abort (); 583 } 584 585 H_SET_BSS_SIZE () 586 { 587 abort (); 588 } 589 590 H_SET_STRING_SIZE () 591 { 592 abort (); 593 } 594 595 H_SET_RELOCATION_SIZE () 596 { 597 abort (); 598 } 599 600 H_SET_MAGIC_NUMBER () 601 { 602 abort (); 603 } 604 605 H_GET_FILE_SIZE () 606 { 607 abort (); 608 } 609 610 H_GET_TEXT_RELOCATION_SIZE () 611 { 612 abort (); 613 } 614