Changeset 609 for branches/GNU/src/binutils/bfd/sparclinux.c
- Timestamp:
- Aug 16, 2003, 6:59:22 PM (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/GNU/src/binutils/bfd/sparclinux.c
-
Property cvs2svn:cvs-rev
changed from
1.1
to1.1.1.2
r608 r609 1 1 /* BFD back-end for linux flavored sparc a.out binaries. 2 Copyright 1992, 1993, 1994, 1995, 1996, 1997, 2000 2 Copyright 1992, 1993, 1994, 1995, 1996, 1997, 2000, 2001, 2002, 2003 3 3 Free Software Foundation, Inc. 4 4 … … 20 20 USA. */ 21 21 22 #define TARGET_PAGE_SIZE 4096 23 #define ZMAGIC_DISK_BLOCK_SIZE 1024 24 #define SEGMENT_SIZE TARGET_PAGE_SIZE 25 #define TEXT_START_ADDR 0x0 26 #define N_SHARED_LIB(x) 0 27 #define BYTES_IN_WORD 4 22 #define TARGET_PAGE_SIZE 4096 23 #define ZMAGIC_DISK_BLOCK_SIZE 1024 24 #define SEGMENT_SIZE TARGET_PAGE_SIZE 25 #define TEXT_START_ADDR 0x0 26 #define N_SHARED_LIB(x) 0 28 27 29 28 #define MACHTYPE_OK(mtype) ((mtype) == M_SPARC || (mtype) == M_UNKNOWN) … … 38 37 39 38 #define DEFAULT_ARCH bfd_arch_sparc 40 #define MY(OP) CAT(sparclinux_,OP) 39 /* Do not "beautify" the CONCAT* macro args. Traditional C will not 40 remove whitespace added here, and thus will fail to concatenate 41 the tokens. */ 42 #define MY(OP) CONCAT2 (sparclinux_,OP) 41 43 #define TARGETNAME "a.out-sparc-linux" 42 44 … … 50 52 PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *)); 51 53 52 static b oolean sparclinux_bfd_final_link54 static bfd_boolean sparclinux_bfd_final_link 53 55 PARAMS ((bfd *abfd, struct bfd_link_info *info)); 54 56 55 static b oolean57 static bfd_boolean 56 58 sparclinux_bfd_final_link (abfd, info) 57 59 bfd *abfd; … … 66 68 /* Set the machine type correctly. */ 67 69 68 static b oolean sparclinux_write_object_contents PARAMS ((bfd *abfd));69 70 static b oolean70 static bfd_boolean sparclinux_write_object_contents PARAMS ((bfd *abfd)); 71 72 static bfd_boolean 71 73 sparclinux_write_object_contents (abfd) 72 74 bfd *abfd; … … 81 83 WRITE_HEADERS(abfd, execp); 82 84 83 return true;85 return TRUE; 84 86 } 85 87 … … 90 92 91 93 #ifndef GOT_REF_PREFIX 92 #define 94 #define GOT_REF_PREFIX "__GOT_" 93 95 #endif 94 96 … … 99 101 100 102 #ifndef PLT_REF_PREFIX 101 #define 103 #define PLT_REF_PREFIX "__PLT_" 102 104 #endif 103 105 … … 177 179 static struct fixup *new_fixup 178 180 PARAMS ((struct bfd_link_info *, struct linux_link_hash_entry *, 179 180 static b oolean linux_link_create_dynamic_sections181 bfd_vma, int)); 182 static bfd_boolean linux_link_create_dynamic_sections 181 183 PARAMS ((bfd *, struct bfd_link_info *)); 182 static b oolean linux_add_one_symbol184 static bfd_boolean linux_add_one_symbol 183 185 PARAMS ((struct bfd_link_info *, bfd *, const char *, flagword, asection *, 184 bfd_vma, const char *, boolean,boolean,185 186 static b oolean linux_tally_symbols186 bfd_vma, const char *, bfd_boolean, bfd_boolean, 187 struct bfd_link_hash_entry **)); 188 static bfd_boolean linux_tally_symbols 187 189 PARAMS ((struct linux_link_hash_entry *, PTR)); 188 static b oolean linux_finish_dynamic_link190 static bfd_boolean linux_finish_dynamic_link 189 191 PARAMS ((bfd *, struct bfd_link_info *)); 190 192 … … 203 205 if (ret == (struct linux_link_hash_entry *) NULL) 204 206 ret = ((struct linux_link_hash_entry *) 205 207 bfd_hash_allocate (table, sizeof (struct linux_link_hash_entry))); 206 208 if (ret == NULL) 207 209 return (struct bfd_hash_entry *) ret; … … 209 211 /* Call the allocation method of the superclass. */ 210 212 ret = ((struct linux_link_hash_entry *) 211 212 213 NAME(aout,link_hash_newfunc) ((struct bfd_hash_entry *) ret, 214 table, string)); 213 215 if (ret != NULL) 214 216 { … … 226 228 { 227 229 struct linux_link_hash_table *ret; 228 229 ret = ((struct linux_link_hash_table *) 230 bfd_alloc (abfd, sizeof (struct linux_link_hash_table)));230 bfd_size_type amt = sizeof (struct linux_link_hash_table); 231 232 ret = (struct linux_link_hash_table *) bfd_malloc (amt); 231 233 if (ret == (struct linux_link_hash_table *) NULL) 232 234 return (struct bfd_link_hash_table *) NULL; 233 235 if (! NAME(aout,link_hash_table_init) (&ret->root, abfd, 234 236 linux_link_hash_newfunc)) 235 237 { 236 238 free (ret); … … 251 253 ((struct linux_link_hash_entry *) \ 252 254 aout_link_hash_lookup (&(table)->root, (string), (create), (copy),\ 253 255 (follow))) 254 256 255 257 /* Traverse a Linux link hash table. */ 256 258 257 #define linux_link_hash_traverse(table, func, info) 258 (aout_link_hash_traverse 259 (&(table)->root, 260 (b oolean (*) PARAMS ((struct aout_link_hash_entry *, PTR))) (func), \259 #define linux_link_hash_traverse(table, func, info) \ 260 (aout_link_hash_traverse \ 261 (&(table)->root, \ 262 (bfd_boolean (*) PARAMS ((struct aout_link_hash_entry *, PTR))) (func), \ 261 263 (info))) 262 264 … … 278 280 279 281 f = (struct fixup *) bfd_hash_allocate (&info->hash->table, 280 282 sizeof (struct fixup)); 281 283 if (f == NULL) 282 284 return f; … … 298 300 create it for now. */ 299 301 300 static b oolean302 static bfd_boolean 301 303 linux_link_create_dynamic_sections (abfd, info) 302 304 bfd *abfd; … … 310 312 311 313 /* We choose to use the name ".linux-dynamic" for the fixup table. 312 Why not? */314 Why not? */ 313 315 s = bfd_make_section (abfd, ".linux-dynamic"); 314 316 if (s == NULL 315 317 || ! bfd_set_section_flags (abfd, s, flags) 316 318 || ! bfd_set_section_alignment (abfd, s, 2)) 317 return false;319 return FALSE; 318 320 s->_raw_size = 0; 319 321 s->contents = 0; 320 322 321 return true;323 return TRUE; 322 324 } 323 325 … … 326 328 tweaking needed for dynamic linking support. */ 327 329 328 static b oolean330 static bfd_boolean 329 331 linux_add_one_symbol (info, abfd, name, flags, section, value, string, 330 332 copy, collect, hashp) 331 333 struct bfd_link_info *info; 332 334 bfd *abfd; … … 336 338 bfd_vma value; 337 339 const char *string; 338 b oolean copy;339 b oolean collect;340 bfd_boolean copy; 341 bfd_boolean collect; 340 342 struct bfd_link_hash_entry **hashp; 341 343 { 342 344 struct linux_link_hash_entry *h; 343 b oolean insert;345 bfd_boolean insert; 344 346 345 347 /* Look up and see if we already have this symbol in the hash table. … … 351 353 confusion is possible. */ 352 354 353 insert = false;355 insert = FALSE; 354 356 355 357 if (! info->relocateable … … 360 362 { 361 363 if (! linux_link_create_dynamic_sections (abfd, info)) 362 return false;364 return FALSE; 363 365 linux_hash_table (info)->dynobj = abfd; 364 insert = true;366 insert = TRUE; 365 367 } 366 368 … … 368 370 && abfd->xvec == info->hash->creator) 369 371 { 370 h = linux_link_hash_lookup (linux_hash_table (info), name, false,371 false, false);372 h = linux_link_hash_lookup (linux_hash_table (info), name, FALSE, 373 FALSE, FALSE); 372 374 if (h != NULL 373 374 375 376 377 378 379 380 381 382 383 return false;384 385 386 return true;387 375 && (h->root.root.type == bfd_link_hash_defined 376 || h->root.root.type == bfd_link_hash_defweak)) 377 { 378 struct fixup *f; 379 380 if (hashp != NULL) 381 *hashp = (struct bfd_link_hash_entry *) h; 382 383 f = new_fixup (info, h, value, ! IS_PLT_SYM (name)); 384 if (f == NULL) 385 return FALSE; 386 f->jump = IS_PLT_SYM (name); 387 388 return TRUE; 389 } 388 390 } 389 391 390 392 /* Do the usual procedure for adding a symbol. */ 391 393 if (! _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, 392 393 394 return false;394 value, string, copy, collect, 395 hashp)) 396 return FALSE; 395 397 396 398 /* Insert a pointer to our table in the set vector. The dynamic 397 linker requires this information */399 linker requires this information. */ 398 400 if (insert) 399 401 { … … 401 403 402 404 /* Here we do our special thing to add the pointer to the 403 405 dynamic section in the SHARABLE_CONFLICTS set vector. */ 404 406 s = bfd_get_section_by_name (linux_hash_table (info)->dynobj, 405 407 ".linux-dynamic"); 406 408 BFD_ASSERT (s != NULL); 407 409 408 410 if (! (_bfd_generic_link_add_one_symbol 409 (info, linux_hash_table (info)->dynobj, SHARABLE_CONFLICTS, 410 BSF_GLOBAL | BSF_CONSTRUCTOR, s, 0, NULL, false, false, NULL))) 411 return false; 412 } 413 414 return true; 411 (info, linux_hash_table (info)->dynobj, SHARABLE_CONFLICTS, 412 BSF_GLOBAL | BSF_CONSTRUCTOR, s, (bfd_vma) 0, NULL, 413 FALSE, FALSE, NULL))) 414 return FALSE; 415 } 416 417 return TRUE; 415 418 } 416 419 … … 425 428 This function is called via linux_link_hash_traverse. */ 426 429 427 static b oolean430 static bfd_boolean 428 431 linux_tally_symbols (h, data) 429 432 struct linux_link_hash_entry *h; … … 434 437 int is_plt; 435 438 struct linux_link_hash_entry *h1, *h2; 436 boolean exists; 439 bfd_boolean exists; 440 441 if (h->root.root.type == bfd_link_hash_warning) 442 h = (struct linux_link_hash_entry *) h->root.root.u.i.link; 437 443 438 444 if (h->root.root.type == bfd_link_hash_undefined 439 445 && strncmp (h->root.root.root.string, NEEDS_SHRLIB, 440 446 sizeof NEEDS_SHRLIB - 1) == 0) 441 447 { 442 448 const char *name; … … 447 453 p = strrchr (name, '_'); 448 454 if (p != NULL) 449 alloc = (char *) bfd_malloc (strlen (name) + 1);455 alloc = (char *) bfd_malloc ((bfd_size_type) strlen (name) + 1); 450 456 451 457 if (p == NULL || alloc == NULL) 452 453 458 (*_bfd_error_handler) (_("Output file requires shared library `%s'\n"), 459 name); 454 460 else 455 456 457 458 459 460 461 462 463 461 { 462 strcpy (alloc, name); 463 p = strrchr (alloc, '_'); 464 *p++ = '\0'; 465 (*_bfd_error_handler) 466 (_("Output file requires shared library `%s.so.%s'\n"), 467 alloc, p); 468 free (alloc); 469 } 464 470 465 471 abort (); … … 473 479 { 474 480 /* Look up this symbol twice. Once just as a regular lookup, 475 476 481 and then again following all of the indirect links until we 482 reach a real symbol. */ 477 483 h1 = linux_link_hash_lookup (linux_hash_table (info), 478 479 480 false, false, true);484 (h->root.root.root.string 485 + sizeof PLT_REF_PREFIX - 1), 486 FALSE, FALSE, TRUE); 481 487 /* h2 does not follow indirect symbols. */ 482 488 h2 = linux_link_hash_lookup (linux_hash_table (info), 483 484 485 false, false, false);489 (h->root.root.root.string 490 + sizeof PLT_REF_PREFIX - 1), 491 FALSE, FALSE, FALSE); 486 492 487 493 /* The real symbol must exist but if it is also an ABS symbol, 488 489 490 491 492 494 there is no need to have a fixup. This is because they both 495 came from the same library. If on the other hand, we had to 496 use an indirect symbol to get to the real symbol, we add the 497 fixup anyway, since there are cases where these symbols come 498 from different shared libraries */ 493 499 if (h1 != NULL 494 495 496 497 498 499 500 501 502 503 exists = false;504 505 506 507 508 509 510 511 512 exists = true;513 514 515 516 517 518 519 520 521 522 exists = true;523 524 525 526 527 528 529 530 531 532 533 534 535 500 && (((h1->root.root.type == bfd_link_hash_defined 501 || h1->root.root.type == bfd_link_hash_defweak) 502 && ! bfd_is_abs_section (h1->root.root.u.def.section)) 503 || h2->root.root.type == bfd_link_hash_indirect)) 504 { 505 /* See if there is a "builtin" fixup already present 506 involving this symbol. If so, convert it to a regular 507 fixup. In the end, this relaxes some of the requirements 508 about the order of performing fixups. */ 509 exists = FALSE; 510 for (f1 = linux_hash_table (info)->fixup_list; 511 f1 != NULL; 512 f1 = f1->next) 513 { 514 if ((f1->h != h && f1->h != h1) 515 || (! f1->builtin && ! f1->jump)) 516 continue; 517 if (f1->h == h1) 518 exists = TRUE; 519 if (! exists 520 && bfd_is_abs_section (h->root.root.u.def.section)) 521 { 522 f = new_fixup (info, h1, f1->h->root.root.u.def.value, 0); 523 f->jump = is_plt; 524 } 525 f1->h = h1; 526 f1->jump = is_plt; 527 f1->builtin = 0; 528 exists = TRUE; 529 } 530 if (! exists 531 && bfd_is_abs_section (h->root.root.u.def.section)) 532 { 533 f = new_fixup (info, h1, h->root.root.u.def.value, 0); 534 if (f == NULL) 535 { 536 /* FIXME: No way to return error. */ 537 abort (); 538 } 539 f->jump = is_plt; 540 } 541 } 536 542 537 543 /* Quick and dirty way of stripping these symbols from the 538 544 symtab. */ 539 545 if (bfd_is_abs_section (h->root.root.u.def.section)) 540 h->root.written = true;541 } 542 543 return true;546 h->root.written = TRUE; 547 } 548 549 return TRUE; 544 550 } 545 551 … … 550 556 are required. */ 551 557 552 b oolean558 bfd_boolean 553 559 bfd_sparclinux_size_dynamic_sections (output_bfd, info) 554 560 bfd *output_bfd; … … 559 565 560 566 if (output_bfd->xvec != &MY(vec)) 561 return true;567 return TRUE; 562 568 563 569 /* First find the fixups... */ 564 570 linux_link_hash_traverse (linux_hash_table (info), 565 566 571 linux_tally_symbols, 572 (PTR) info); 567 573 568 574 /* If there are builtin fixups, leave room for a marker. This is … … 572 578 { 573 579 if (f->builtin) 574 575 576 577 578 580 { 581 ++linux_hash_table (info)->fixup_count; 582 ++linux_hash_table (info)->local_builtins; 583 break; 584 } 579 585 } 580 586 … … 582 588 { 583 589 if (linux_hash_table (info)->fixup_count > 0) 584 585 return true;590 abort (); 591 return TRUE; 586 592 } 587 593 588 594 /* Allocate memory for our fixup table. We will fill it in later. */ 589 595 s = bfd_get_section_by_name (linux_hash_table (info)->dynobj, 590 596 ".linux-dynamic"); 591 597 if (s != NULL) 592 598 { 593 s->_raw_size = 8 + linux_hash_table (info)->fixup_count * 8; 594 s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size); 599 s->_raw_size = linux_hash_table (info)->fixup_count + 1; 600 s->_raw_size *= 8; 601 s->contents = (bfd_byte *) bfd_zalloc (output_bfd, s->_raw_size); 595 602 if (s->contents == NULL) 596 return false; 597 memset (s->contents, 0, (size_t) s->_raw_size); 598 } 599 600 return true; 603 return FALSE; 604 } 605 606 return TRUE; 601 607 } 602 608 … … 605 611 the stuff we need. */ 606 612 607 static b oolean613 static bfd_boolean 608 614 linux_finish_dynamic_link (output_bfd, info) 609 615 bfd *output_bfd; … … 619 625 620 626 if (linux_hash_table (info)->dynobj == NULL) 621 return true;627 return TRUE; 622 628 623 629 s = bfd_get_section_by_name (linux_hash_table (info)->dynobj, 624 630 ".linux-dynamic"); 625 631 BFD_ASSERT (s != NULL); 626 632 os = s->output_section; … … 629 635 #ifdef LINUX_LINK_DEBUG 630 636 printf ("Fixup table file offset: %x VMA: %x\n", 631 632 637 os->filepos + s->output_offset, 638 os->vma + s->output_offset); 633 639 #endif 634 640 635 641 fixup_table = s->contents; 636 bfd_put_32 (output_bfd, linux_hash_table (info)->fixup_count, fixup_table); 642 bfd_put_32 (output_bfd, 643 (bfd_vma) linux_hash_table (info)->fixup_count, fixup_table); 637 644 fixup_table += 4; 638 645 … … 641 648 { 642 649 if (f->builtin) 643 650 continue; 644 651 645 652 if (f->h->root.root.type != bfd_link_hash_defined 646 647 648 649 650 651 652 653 && f->h->root.root.type != bfd_link_hash_defweak) 654 { 655 (*_bfd_error_handler) 656 (_("Symbol %s not defined for fixups\n"), 657 f->h->root.root.root.string); 658 continue; 659 } 653 660 654 661 is = f->h->root.root.u.def.section; … … 658 665 #ifdef LINUX_LINK_DEBUG 659 666 printf ("Fixup(%d) %s: %x %x\n",f->jump, f->h->root.root.string, 660 667 new_addr, f->value); 661 668 #endif 662 669 663 670 if (f->jump) 664 665 666 667 bfd_put_32 (output_bfd,new_addr, fixup_table);668 669 670 671 671 { 672 /* Relative address */ 673 new_addr = new_addr - (f->value + 5); 674 bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table); 675 fixup_table += 4; 676 bfd_put_32 (output_bfd, f->value + 1, fixup_table); 677 fixup_table += 4; 678 } 672 679 else 673 674 bfd_put_32 (output_bfd,new_addr, fixup_table);675 676 677 678 680 { 681 bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table); 682 fixup_table += 4; 683 bfd_put_32 (output_bfd, f->value, fixup_table); 684 fixup_table += 4; 685 } 679 686 ++fixups_written; 680 687 } … … 683 690 { 684 691 /* Special marker so we know to switch to the other type of fixup */ 685 bfd_put_32 (output_bfd, 0, fixup_table);692 bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table); 686 693 fixup_table += 4; 687 bfd_put_32 (output_bfd, 0, fixup_table);694 bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table); 688 695 fixup_table += 4; 689 696 ++fixups_written; 690 697 for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next) 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 698 { 699 if (! f->builtin) 700 continue; 701 702 if (f->h->root.root.type != bfd_link_hash_defined 703 && f->h->root.root.type != bfd_link_hash_defweak) 704 { 705 (*_bfd_error_handler) 706 (_("Symbol %s not defined for fixups\n"), 707 f->h->root.root.root.string); 708 continue; 709 } 710 711 is = f->h->root.root.u.def.section; 712 section_offset = is->output_section->vma + is->output_offset; 713 new_addr = f->h->root.root.u.def.value + section_offset; 707 714 708 715 #ifdef LINUX_LINK_DEBUG 709 710 716 printf ("Fixup(B) %s: %x %x\n", f->h->root.root.string, 717 new_addr, f->value); 711 718 #endif 712 719 713 bfd_put_32 (output_bfd,new_addr, fixup_table);714 715 716 717 718 719 }720 bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table); 721 fixup_table += 4; 722 bfd_put_32 (output_bfd, f->value, fixup_table); 723 fixup_table += 4; 724 ++fixups_written; 725 } 726 } 720 727 721 728 if (linux_hash_table (info)->fixup_count != fixups_written) … … 723 730 (*_bfd_error_handler) (_("Warning: fixup count mismatch\n")); 724 731 while (linux_hash_table (info)->fixup_count > fixups_written) 725 726 bfd_put_32 (output_bfd,0, fixup_table);727 728 bfd_put_32 (output_bfd,0, fixup_table);729 730 731 732 { 733 bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table); 734 fixup_table += 4; 735 bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table); 736 fixup_table += 4; 737 ++fixups_written; 738 } 732 739 } 733 740 734 741 h = linux_link_hash_lookup (linux_hash_table (info), 735 736 false, false, false);742 "__BUILTIN_FIXUPS__", 743 FALSE, FALSE, FALSE); 737 744 738 745 if (h != NULL 739 746 && (h->root.root.type == bfd_link_hash_defined 740 747 || h->root.root.type == bfd_link_hash_defweak)) 741 748 { 742 749 is = h->root.root.u.def.section; … … 748 755 #endif 749 756 750 bfd_put_32 (output_bfd, new_addr, fixup_table);757 bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table); 751 758 } 752 759 else 753 bfd_put_32 (output_bfd, 0, fixup_table);754 755 if (bfd_seek (output_bfd, os->filepos + s->output_offset, SEEK_SET) != 0)756 return false; 757 758 if (bfd_write ((PTR) s->contents, 1, s->_raw_size, output_bfd) 759 760 return false;761 762 return true;760 bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table); 761 762 if (bfd_seek (output_bfd, (file_ptr) (os->filepos + s->output_offset), 763 SEEK_SET) != 0) 764 return FALSE; 765 766 if (bfd_bwrite ((PTR) s->contents, s->_raw_size, output_bfd) != s->_raw_size) 767 return FALSE; 768 769 return TRUE; 763 770 } 764 771 -
Property cvs2svn:cvs-rev
changed from
Note:
See TracChangeset
for help on using the changeset viewer.