00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "bfd.h"
00026 #include "sysdep.h"
00027 #include "libbfd.h"
00028
00029
00030
00031
00032 #define ARCH_SIZE 32
00033
00034 #include "nlm/ppc-ext.h"
00035 #define Nlm_External_Fixed_Header Nlm32_powerpc_External_Fixed_Header
00036
00037 #include "libnlm.h"
00038
00039 #ifdef OLDFORMAT
00040 static bfd_boolean nlm_powerpc_backend_object_p
00041 PARAMS ((bfd *));
00042 static bfd_boolean nlm_powerpc_write_prefix
00043 PARAMS ((bfd *));
00044 #endif
00045
00046 static bfd_boolean nlm_powerpc_read_reloc
00047 PARAMS ((bfd *, nlmNAME(symbol_type) *, asection **, arelent *));
00048 static bfd_boolean nlm_powerpc_mangle_relocs
00049 PARAMS ((bfd *, asection *, const PTR, bfd_vma, bfd_size_type));
00050 static bfd_boolean nlm_powerpc_read_import
00051 PARAMS ((bfd *, nlmNAME(symbol_type) *));
00052
00053 #ifdef OLDFORMAT
00054 static bfd_boolean nlm_powerpc_write_reloc
00055 PARAMS ((bfd *, asection *, arelent *, int));
00056 #endif
00057
00058 static bfd_boolean nlm_powerpc_write_import
00059 PARAMS ((bfd *, asection *, arelent *));
00060 static bfd_boolean nlm_powerpc_write_external
00061 PARAMS ((bfd *, bfd_size_type, asymbol *, struct reloc_and_sec *));
00062
00063 #ifndef OLDFORMAT
00064 static bfd_boolean nlm_powerpc_set_public_section
00065 PARAMS ((bfd *, nlmNAME(symbol_type) *));
00066 static bfd_vma nlm_powerpc_get_public_offset
00067 PARAMS ((bfd *, asymbol *));
00068 #endif
00069
00070 #ifdef OLDFORMAT
00071
00072
00073
00074
00075
00076
00077
00078 static bfd_boolean
00079 nlm_powerpc_backend_object_p (abfd)
00080 bfd *abfd;
00081 {
00082 struct nlm32_powerpc_external_prefix_header s;
00083
00084 if (bfd_bread ((PTR) &s, (bfd_size_type) sizeof s, abfd) != sizeof s)
00085 return FALSE;
00086
00087 if (memcmp (s.signature, NLM32_POWERPC_SIGNATURE, sizeof s.signature) != 0
00088 || H_GET_32 (abfd, s.headerVersion) != NLM32_POWERPC_HEADER_VERSION)
00089 return FALSE;
00090
00091 return TRUE;
00092 }
00093
00094
00095
00096 static bfd_boolean
00097 nlm_powerpc_write_prefix (abfd)
00098 bfd *abfd;
00099 {
00100 struct nlm32_powerpc_external_prefix_header s;
00101
00102 memset (&s, 0, sizeof s);
00103 memcpy (s.signature, NLM32_POWERPC_SIGNATURE, sizeof s.signature);
00104 H_PUT_32 (abfd, NLM32_POWERPC_HEADER_VERSION, s.headerVersion);
00105 H_PUT_32 (abfd, 0, s.origins);
00106
00107
00108
00109 if (bfd_bwrite ((PTR) &s, (bfd_size_type) sizeof s, abfd) != sizeof s)
00110 return FALSE;
00111
00112 return TRUE;
00113 }
00114
00115 #endif
00116
00117 #ifndef OLDFORMAT
00118
00119
00120
00121 static reloc_howto_type nlm_powerpc_howto =
00122 HOWTO (0,
00123 0,
00124 2,
00125 32,
00126 FALSE,
00127 0,
00128 complain_overflow_bitfield,
00129 0,
00130 "32",
00131 TRUE,
00132 0xffffffff,
00133 0xffffffff,
00134 FALSE);
00135
00136
00137
00138 static bfd_boolean
00139 nlm_powerpc_read_reloc (abfd, sym, secp, rel)
00140 bfd *abfd;
00141 nlmNAME(symbol_type) *sym;
00142 asection **secp;
00143 arelent *rel;
00144 {
00145 bfd_byte temp[4];
00146 bfd_vma val;
00147 const char *name;
00148
00149 if (bfd_bread (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
00150 return FALSE;
00151
00152 val = bfd_get_32 (abfd, temp);
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 if ((val & NLM_HIBIT) == 0)
00170 name = NLM_INITIALIZED_DATA_NAME;
00171 else
00172 {
00173 name = NLM_CODE_NAME;
00174 val &=~ NLM_HIBIT;
00175 }
00176 *secp = bfd_get_section_by_name (abfd, name);
00177
00178 if (sym == NULL)
00179 {
00180 if ((val & (NLM_HIBIT >> 1)) == 0)
00181 name = NLM_INITIALIZED_DATA_NAME;
00182 else
00183 {
00184 name = NLM_CODE_NAME;
00185 val &=~ (NLM_HIBIT >> 1);
00186 }
00187 rel->sym_ptr_ptr = bfd_get_section_by_name (abfd, name)->symbol_ptr_ptr;
00188 }
00189
00190 rel->howto = &nlm_powerpc_howto;
00191
00192 rel->address = val << 2;
00193 rel->addend = 0;
00194
00195 return TRUE;
00196 }
00197
00198 #else
00199
00200
00201
00202
00203
00204
00205 static reloc_howto_type nlm_powerpc_howto_table[] =
00206 {
00207
00208 HOWTO (0,
00209 0,
00210 2,
00211 32,
00212 FALSE,
00213 0,
00214 complain_overflow_bitfield,
00215 0,
00216 "R_POS",
00217 TRUE,
00218 0xffffffff,
00219 0xffffffff,
00220 FALSE),
00221
00222
00223 HOWTO (1,
00224 0,
00225 -2,
00226 32,
00227 FALSE,
00228 0,
00229 complain_overflow_bitfield,
00230 0,
00231 "R_NEG",
00232 TRUE,
00233 0xffffffff,
00234 0xffffffff,
00235 FALSE),
00236
00237
00238 HOWTO (2,
00239 0,
00240 2,
00241 32,
00242 TRUE,
00243 0,
00244 complain_overflow_signed,
00245 0,
00246 "R_REL",
00247 TRUE,
00248 0xffffffff,
00249 0xffffffff,
00250 FALSE),
00251
00252
00253 HOWTO (3,
00254 0,
00255 1,
00256 16,
00257 FALSE,
00258 0,
00259 complain_overflow_signed,
00260 0,
00261 "R_TOC",
00262 TRUE,
00263 0xffff,
00264 0xffff,
00265 FALSE),
00266
00267
00268 HOWTO (4,
00269 1,
00270 2,
00271 32,
00272 FALSE,
00273 0,
00274 complain_overflow_bitfield,
00275 0,
00276 "R_RTB",
00277 TRUE,
00278 0xffffffff,
00279 0xffffffff,
00280 FALSE),
00281
00282
00283 HOWTO (5,
00284 0,
00285 2,
00286 16,
00287 FALSE,
00288 0,
00289 complain_overflow_bitfield,
00290 0,
00291 "R_GL",
00292 TRUE,
00293 0xffff,
00294 0xffff,
00295 FALSE),
00296
00297
00298 HOWTO (6,
00299 0,
00300 2,
00301 16,
00302 FALSE,
00303 0,
00304 complain_overflow_bitfield,
00305 0,
00306 "R_TCL",
00307 TRUE,
00308 0xffff,
00309 0xffff,
00310 FALSE),
00311
00312 { 7 },
00313
00314
00315 HOWTO (8,
00316 0,
00317 2,
00318 26,
00319 FALSE,
00320 0,
00321 complain_overflow_bitfield,
00322 0,
00323 "R_BA",
00324 TRUE,
00325 0x3fffffc,
00326 0x3fffffc,
00327 FALSE),
00328
00329 { 9 },
00330
00331
00332 HOWTO (0xa,
00333 0,
00334 2,
00335 26,
00336 TRUE,
00337 0,
00338 complain_overflow_signed,
00339 0,
00340 "R_BR",
00341 TRUE,
00342 0x3fffffc,
00343 0x3fffffc,
00344 FALSE),
00345
00346 { 0xb },
00347
00348
00349 HOWTO (0xc,
00350 0,
00351 2,
00352 16,
00353 FALSE,
00354 0,
00355 complain_overflow_bitfield,
00356 0,
00357 "R_RL",
00358 TRUE,
00359 0xffff,
00360 0xffff,
00361 FALSE),
00362
00363
00364 HOWTO (0xd,
00365 0,
00366 2,
00367 16,
00368 FALSE,
00369 0,
00370 complain_overflow_bitfield,
00371 0,
00372 "R_RLA",
00373 TRUE,
00374 0xffff,
00375 0xffff,
00376 FALSE),
00377
00378 { 0xe },
00379
00380
00381 HOWTO (0xf,
00382 0,
00383 2,
00384 32,
00385 FALSE,
00386 0,
00387 complain_overflow_bitfield,
00388 0,
00389 "R_REF",
00390 FALSE,
00391 0,
00392 0,
00393 FALSE),
00394
00395 { 0x10 },
00396 { 0x11 },
00397
00398
00399 HOWTO (0x12,
00400 0,
00401 2,
00402 16,
00403 FALSE,
00404 0,
00405 complain_overflow_bitfield,
00406 0,
00407 "R_TRL",
00408 TRUE,
00409 0xffff,
00410 0xffff,
00411 FALSE),
00412
00413
00414 HOWTO (0x13,
00415 0,
00416 2,
00417 16,
00418 FALSE,
00419 0,
00420 complain_overflow_bitfield,
00421 0,
00422 "R_TRLA",
00423 TRUE,
00424 0xffff,
00425 0xffff,
00426 FALSE),
00427
00428
00429 HOWTO (0x14,
00430 1,
00431 2,
00432 32,
00433 FALSE,
00434 0,
00435 complain_overflow_bitfield,
00436 0,
00437 "R_RRTBI",
00438 TRUE,
00439 0xffffffff,
00440 0xffffffff,
00441 FALSE),
00442
00443
00444 HOWTO (0x15,
00445 1,
00446 2,
00447 32,
00448 FALSE,
00449 0,
00450 complain_overflow_bitfield,
00451 0,
00452 "R_RRTBA",
00453 TRUE,
00454 0xffffffff,
00455 0xffffffff,
00456 FALSE),
00457
00458
00459 HOWTO (0x16,
00460 0,
00461 2,
00462 16,
00463 FALSE,
00464 0,
00465 complain_overflow_bitfield,
00466 0,
00467 "R_CAI",
00468 TRUE,
00469 0xffff,
00470 0xffff,
00471 FALSE),
00472
00473
00474 HOWTO (0x17,
00475 0,
00476 2,
00477 16,
00478 FALSE,
00479 0,
00480 complain_overflow_bitfield,
00481 0,
00482 "R_REL",
00483 TRUE,
00484 0xffff,
00485 0xffff,
00486 FALSE),
00487
00488
00489 HOWTO (0x18,
00490 0,
00491 2,
00492 16,
00493 FALSE,
00494 0,
00495 complain_overflow_bitfield,
00496 0,
00497 "R_RBA",
00498 TRUE,
00499 0xffff,
00500 0xffff,
00501 FALSE),
00502
00503
00504 HOWTO (0x19,
00505 0,
00506 2,
00507 16,
00508 FALSE,
00509 0,
00510 complain_overflow_bitfield,
00511 0,
00512 "R_RBAC",
00513 TRUE,
00514 0xffff,
00515 0xffff,
00516 FALSE),
00517
00518
00519 HOWTO (0x1a,
00520 0,
00521 2,
00522 26,
00523 FALSE,
00524 0,
00525 complain_overflow_signed,
00526 0,
00527 "R_REL",
00528 TRUE,
00529 0xffff,
00530 0xffff,
00531 FALSE),
00532
00533
00534 HOWTO (0x1b,
00535 0,
00536 2,
00537 16,
00538 FALSE,
00539 0,
00540 complain_overflow_bitfield,
00541 0,
00542 "R_REL",
00543 TRUE,
00544 0xffff,
00545 0xffff,
00546 FALSE)
00547 };
00548
00549 #define HOWTO_COUNT (sizeof nlm_powerpc_howto_table \
00550 / sizeof nlm_powerpc_howto_table[0])
00551
00552
00553
00554 static bfd_boolean
00555 nlm_powerpc_read_reloc (abfd, sym, secp, rel)
00556 bfd *abfd;
00557 nlmNAME(symbol_type) *sym;
00558 asection **secp;
00559 arelent *rel;
00560 {
00561 struct nlm32_powerpc_external_reloc ext;
00562 bfd_vma l_vaddr;
00563 unsigned long l_symndx;
00564 int l_rtype;
00565 int l_rsecnm;
00566 asection *code_sec, *data_sec, *bss_sec;
00567
00568
00569 if (bfd_bread (&ext, (bfd_size_type) sizeof ext, abfd) != sizeof ext)
00570 return FALSE;
00571
00572
00573 l_vaddr = H_GET_32 (abfd, ext.l_vaddr);
00574 l_symndx = H_GET_32 (abfd, ext.l_symndx);
00575 l_rtype = H_GET_16 (abfd, ext.l_rtype);
00576 l_rsecnm = H_GET_16 (abfd, ext.l_rsecnm);
00577
00578
00579 code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
00580 data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
00581 bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
00582
00583
00584 if (sym != NULL)
00585 {
00586
00587
00588 rel->sym_ptr_ptr = NULL;
00589 }
00590 else
00591 {
00592 asection *sec;
00593
00594 if (l_symndx == 0)
00595 sec = code_sec;
00596 else if (l_symndx == 1)
00597 sec = data_sec;
00598 else if (l_symndx == 2)
00599 sec = bss_sec;
00600 else
00601 {
00602 bfd_set_error (bfd_error_bad_value);
00603 return FALSE;
00604 }
00605
00606 rel->sym_ptr_ptr = sec->symbol_ptr_ptr;
00607 }
00608
00609 rel->addend = 0;
00610
00611 BFD_ASSERT ((l_rtype & 0xff) < HOWTO_COUNT);
00612
00613 rel->howto = nlm_powerpc_howto_table + (l_rtype & 0xff);
00614
00615 BFD_ASSERT (rel->howto->name != NULL
00616 && ((l_rtype & 0x8000) != 0
00617 ? (rel->howto->complain_on_overflow
00618 == complain_overflow_signed)
00619 : (rel->howto->complain_on_overflow
00620 == complain_overflow_bitfield))
00621 && ((l_rtype >> 8) & 0x1f) == rel->howto->bitsize - 1);
00622
00623 if (l_rsecnm == 0)
00624 *secp = code_sec;
00625 else if (l_rsecnm == 1)
00626 {
00627 *secp = data_sec;
00628 l_vaddr -= code_sec->size;
00629 }
00630 else
00631 {
00632 bfd_set_error (bfd_error_bad_value);
00633 return FALSE;
00634 }
00635
00636 rel->address = l_vaddr;
00637
00638 return TRUE;
00639 }
00640
00641 #endif
00642
00643
00644
00645 static bfd_boolean
00646 nlm_powerpc_mangle_relocs (abfd, sec, data, offset, count)
00647 bfd *abfd ATTRIBUTE_UNUSED;
00648 asection *sec ATTRIBUTE_UNUSED;
00649 const PTR data ATTRIBUTE_UNUSED;
00650 bfd_vma offset ATTRIBUTE_UNUSED;
00651 bfd_size_type count ATTRIBUTE_UNUSED;
00652 {
00653 return TRUE;
00654 }
00655
00656
00657
00658 static bfd_boolean
00659 nlm_powerpc_read_import (abfd, sym)
00660 bfd *abfd;
00661 nlmNAME(symbol_type) *sym;
00662 {
00663 struct nlm_relent *nlm_relocs;
00664 bfd_size_type rcount;
00665 bfd_byte temp[NLM_TARGET_LONG_SIZE];
00666 unsigned char symlength;
00667 char *name;
00668
00669 if (bfd_bread ((PTR) &symlength, (bfd_size_type) sizeof (symlength), abfd)
00670 != sizeof (symlength))
00671 return FALSE;
00672 sym -> symbol.the_bfd = abfd;
00673 name = bfd_alloc (abfd, (bfd_size_type) symlength + 1);
00674 if (name == NULL)
00675 return FALSE;
00676 if (bfd_bread (name, (bfd_size_type) symlength, abfd) != symlength)
00677 return FALSE;
00678 name[symlength] = '\0';
00679 sym -> symbol.name = name;
00680 sym -> symbol.flags = 0;
00681 sym -> symbol.value = 0;
00682 sym -> symbol.section = bfd_und_section_ptr;
00683 if (bfd_bread ((PTR) temp, (bfd_size_type) sizeof (temp), abfd)
00684 != sizeof (temp))
00685 return FALSE;
00686 rcount = H_GET_32 (abfd, temp);
00687 nlm_relocs = ((struct nlm_relent *)
00688 bfd_alloc (abfd, rcount * sizeof (struct nlm_relent)));
00689 if (nlm_relocs == (struct nlm_relent *) NULL)
00690 return FALSE;
00691 sym -> relocs = nlm_relocs;
00692 sym -> rcnt = 0;
00693 while (sym -> rcnt < rcount)
00694 {
00695 asection *section;
00696
00697 if (! nlm_powerpc_read_reloc (abfd, sym, §ion, &nlm_relocs -> reloc))
00698 return FALSE;
00699 nlm_relocs -> section = section;
00700 nlm_relocs++;
00701 sym -> rcnt++;
00702 }
00703 return TRUE;
00704 }
00705
00706 #ifndef OLDFORMAT
00707
00708
00709
00710 static bfd_boolean
00711 nlm_powerpc_write_import (abfd, sec, rel)
00712 bfd *abfd;
00713 asection *sec;
00714 arelent *rel;
00715 {
00716 asymbol *sym;
00717 bfd_vma val;
00718 bfd_byte temp[4];
00719
00720
00721 if (rel->addend != 0
00722 || rel->howto == NULL
00723 || rel->howto->rightshift != 0
00724 || rel->howto->size != 2
00725 || rel->howto->bitsize != 32
00726 || rel->howto->bitpos != 0
00727 || rel->howto->pc_relative
00728 || (rel->howto->src_mask != 0xffffffff && rel->addend != 0)
00729 || rel->howto->dst_mask != 0xffffffff)
00730 {
00731 bfd_set_error (bfd_error_invalid_operation);
00732 return FALSE;
00733 }
00734
00735 sym = *rel->sym_ptr_ptr;
00736
00737
00738
00739
00740
00741 val = bfd_get_section_vma (abfd, sec) + rel->address;
00742 if ((val & 3) != 0)
00743 {
00744 bfd_set_error (bfd_error_bad_value);
00745 return FALSE;
00746 }
00747 val >>= 2;
00748
00749
00750
00751 if (bfd_get_section_flags (abfd, sec) & SEC_DATA)
00752 val -= nlm_get_data_low (abfd);
00753 else
00754 {
00755 val -= nlm_get_text_low (abfd);
00756 val |= NLM_HIBIT;
00757 }
00758
00759 if (! bfd_is_und_section (bfd_get_section (sym)))
00760 {
00761
00762
00763
00764 if (bfd_get_section_flags (abfd, bfd_get_section (sym)) & SEC_CODE)
00765 val |= NLM_HIBIT >> 1;
00766 }
00767
00768 bfd_put_32 (abfd, val, temp);
00769 if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
00770 return FALSE;
00771
00772 return TRUE;
00773 }
00774
00775 #else
00776
00777
00778
00779
00780
00781 static bfd_boolean
00782 nlm_powerpc_write_reloc (abfd, sec, rel, indx)
00783 bfd *abfd;
00784 asection *sec;
00785 arelent *rel;
00786 int indx;
00787 {
00788 struct nlm32_powerpc_external_reloc ext;
00789 asection *code_sec, *data_sec, *bss_sec;
00790 asymbol *sym;
00791 asection *symsec;
00792 unsigned long l_symndx;
00793 int l_rtype;
00794 int l_rsecnm;
00795 reloc_howto_type *howto;
00796 bfd_size_type address;
00797
00798
00799 code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
00800 data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
00801 bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
00802
00803 sym = *rel->sym_ptr_ptr;
00804 symsec = bfd_get_section (sym);
00805 if (indx != -1)
00806 {
00807 BFD_ASSERT (bfd_is_und_section (symsec));
00808 l_symndx = indx + 3;
00809 }
00810 else
00811 {
00812 if (symsec == code_sec)
00813 l_symndx = 0;
00814 else if (symsec == data_sec)
00815 l_symndx = 1;
00816 else if (symsec == bss_sec)
00817 l_symndx = 2;
00818 else
00819 {
00820 bfd_set_error (bfd_error_bad_value);
00821 return FALSE;
00822 }
00823 }
00824
00825 H_PUT_32 (abfd, l_symndx, ext.l_symndx);
00826
00827 for (howto = nlm_powerpc_howto_table;
00828 howto < nlm_powerpc_howto_table + HOWTO_COUNT;
00829 howto++)
00830 {
00831 if (howto->rightshift == rel->howto->rightshift
00832 && howto->size == rel->howto->size
00833 && howto->bitsize == rel->howto->bitsize
00834 && howto->pc_relative == rel->howto->pc_relative
00835 && howto->bitpos == rel->howto->bitpos
00836 && (howto->partial_inplace == rel->howto->partial_inplace
00837 || (! rel->howto->partial_inplace
00838 && rel->addend == 0))
00839 && (howto->src_mask == rel->howto->src_mask
00840 || (rel->howto->src_mask == 0
00841 && rel->addend == 0))
00842 && howto->dst_mask == rel->howto->dst_mask
00843 && howto->pcrel_offset == rel->howto->pcrel_offset)
00844 break;
00845 }
00846 if (howto >= nlm_powerpc_howto_table + HOWTO_COUNT)
00847 {
00848 bfd_set_error (bfd_error_bad_value);
00849 return FALSE;
00850 }
00851
00852 l_rtype = howto->type;
00853 if (howto->complain_on_overflow == complain_overflow_signed)
00854 l_rtype |= 0x8000;
00855 l_rtype |= (howto->bitsize - 1) << 8;
00856 H_PUT_16 (abfd, l_rtype, ext.l_rtype);
00857
00858 address = rel->address;
00859
00860 if (sec == code_sec)
00861 l_rsecnm = 0;
00862 else if (sec == data_sec)
00863 {
00864 l_rsecnm = 1;
00865 address += code_sec->size;
00866 }
00867 else
00868 {
00869 bfd_set_error (bfd_error_bad_value);
00870 return FALSE;
00871 }
00872
00873 H_PUT_16 (abfd, l_rsecnm, ext.l_rsecnm);
00874 H_PUT_32 (abfd, address, ext.l_vaddr);
00875
00876 if (bfd_bwrite (&ext, (bfd_size_type) sizeof ext, abfd) != sizeof ext)
00877 return FALSE;
00878
00879 return TRUE;
00880 }
00881
00882
00883
00884 static bfd_boolean
00885 nlm_powerpc_write_import (abfd, sec, rel)
00886 bfd *abfd;
00887 asection *sec;
00888 arelent *rel;
00889 {
00890 return nlm_powerpc_write_reloc (abfd, sec, rel, -1);
00891 }
00892
00893 #endif
00894
00895
00896
00897
00898
00899 static bfd_boolean
00900 nlm_powerpc_write_external (abfd, count, sym, relocs)
00901 bfd *abfd;
00902 bfd_size_type count;
00903 asymbol *sym;
00904 struct reloc_and_sec *relocs;
00905 {
00906 unsigned int i;
00907 bfd_byte len;
00908 unsigned char temp[NLM_TARGET_LONG_SIZE];
00909 #ifdef OLDFORMAT
00910 static int indx;
00911 #endif
00912
00913 len = strlen (sym->name);
00914 if ((bfd_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
00915 != sizeof (bfd_byte))
00916 || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
00917 return FALSE;
00918
00919 bfd_put_32 (abfd, count, temp);
00920 if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
00921 return FALSE;
00922
00923 for (i = 0; i < count; i++)
00924 {
00925 #ifndef OLDFORMAT
00926 if (! nlm_powerpc_write_import (abfd, relocs[i].sec, relocs[i].rel))
00927 return FALSE;
00928 #else
00929 if (! nlm_powerpc_write_reloc (abfd, relocs[i].sec,
00930 relocs[i].rel, indx))
00931 return FALSE;
00932 #endif
00933 }
00934
00935 #ifdef OLDFORMAT
00936 ++indx;
00937 #endif
00938
00939 return TRUE;
00940 }
00941
00942 #ifndef OLDFORMAT
00943
00944
00945
00946
00947
00948
00949 static bfd_boolean
00950 nlm_powerpc_set_public_section (abfd, sym)
00951 bfd *abfd;
00952 nlmNAME(symbol_type) *sym;
00953 {
00954 if (sym->symbol.value & NLM_HIBIT)
00955 {
00956 sym->symbol.value &= ~NLM_HIBIT;
00957 sym->symbol.flags |= BSF_FUNCTION;
00958 sym->symbol.section =
00959 bfd_get_section_by_name (abfd, NLM_CODE_NAME);
00960 }
00961 else
00962 {
00963 sym->symbol.section =
00964 bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
00965 }
00966
00967 sym->symbol.value <<= 2;
00968
00969 return TRUE;
00970 }
00971
00972
00973
00974 static bfd_vma
00975 nlm_powerpc_get_public_offset (abfd, sym)
00976 bfd *abfd;
00977 asymbol *sym;
00978 {
00979 bfd_vma offset;
00980 asection *sec;
00981
00982 offset = bfd_asymbol_value (sym);
00983 sec = bfd_get_section (sym);
00984 if (sec->flags & SEC_CODE)
00985 {
00986 offset -= nlm_get_text_low (abfd);
00987 offset |= NLM_HIBIT;
00988 }
00989 else if (sec->flags & (SEC_DATA | SEC_ALLOC))
00990 {
00991
00992 offset -= nlm_get_data_low (abfd);
00993 }
00994 else
00995 {
00996
00997
00998 bfd_set_error (bfd_error_invalid_operation);
00999
01000 abort ();
01001 }
01002
01003 return offset;
01004 }
01005
01006 #endif
01007
01008 #include "nlmswap.h"
01009
01010 static const struct nlm_backend_data nlm32_powerpc_backend =
01011 {
01012 "NetWare PowerPC Module \032",
01013 sizeof (Nlm32_powerpc_External_Fixed_Header),
01014 #ifndef OLDFORMAT
01015 0,
01016 #else
01017 sizeof (struct nlm32_powerpc_external_prefix_header),
01018 #endif
01019 bfd_arch_powerpc,
01020 0,
01021 FALSE,
01022 #ifndef OLDFORMAT
01023 0,
01024 0,
01025 #else
01026 nlm_powerpc_backend_object_p,
01027 nlm_powerpc_write_prefix,
01028 #endif
01029 nlm_powerpc_read_reloc,
01030 nlm_powerpc_mangle_relocs,
01031 nlm_powerpc_read_import,
01032 nlm_powerpc_write_import,
01033 #ifndef OLDFORMAT
01034 nlm_powerpc_set_public_section,
01035 nlm_powerpc_get_public_offset,
01036 #else
01037 0,
01038 0,
01039 #endif
01040 nlm_swap_fixed_header_in,
01041 nlm_swap_fixed_header_out,
01042 nlm_powerpc_write_external,
01043 0,
01044 };
01045
01046 #define TARGET_BIG_NAME "nlm32-powerpc"
01047 #define TARGET_BIG_SYM nlmNAME(powerpc_vec)
01048 #define TARGET_BACKEND_DATA &nlm32_powerpc_backend
01049
01050 #include "nlm-target.h"