diff options
-rw-r--r-- | bfd/ChangeLog | 9 | ||||
-rw-r--r-- | bfd/coff-rs6000.c | 77 | ||||
-rw-r--r-- | bfd/xcofflink.c | 5 |
3 files changed, 64 insertions, 27 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index f58853d..c25b139 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,12 @@ +2000-08-15 Geoffrey Keating <geoffk@cygnus.com> + + * xcofflink.c (_bfd_ppc_xcoff_relocate_section): Add ori r0,r0,0 + to the list of NOPs we recognize after a branch-and-link. + Use the ori NOP when one is needed. + + * coff-rs6000.c (_bfd_xcoff_slurp_armap): Finish implementation + for large archives. + 2000-08-14 Jim Wilson <wilson@cygnus.com> * elf64-ia64.c (elf64_ia64_merge_private_bfd_data): Handle diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c index d3332d2d..dec690c 100644 --- a/bfd/coff-rs6000.c +++ b/bfd/coff-rs6000.c @@ -1098,7 +1098,7 @@ _bfd_xcoff_slurp_armap (abfd) size_t namlen; bfd_size_type sz; bfd_byte *contents, *cend; - unsigned int c, i; + bfd_vma c, i; carsym *arsym; bfd_byte *p; @@ -1133,6 +1133,33 @@ _bfd_xcoff_slurp_armap (abfd) return false; sz = strtol (hdr.size, (char **) NULL, 10); + + /* Read in the entire symbol table. */ + contents = (bfd_byte *) bfd_alloc (abfd, sz); + if (contents == NULL) + return false; + if (bfd_read ((PTR) contents, 1, sz, abfd) != sz) + return false; + + /* The symbol table starts with a four byte count. */ + c = bfd_h_get_32 (abfd, contents); + + if (c * 4 >= sz) + { + bfd_set_error (bfd_error_bad_value); + return false; + } + + bfd_ardata (abfd)->symdefs = ((carsym *) + bfd_alloc (abfd, c * sizeof (carsym))); + if (bfd_ardata (abfd)->symdefs == NULL) + return false; + + /* After the count comes a list of four byte file offsets. */ + for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 4; + i < c; + ++i, ++arsym, p += 4) + arsym->file_offset = bfd_h_get_32 (abfd, p); } else { @@ -1163,35 +1190,35 @@ _bfd_xcoff_slurp_armap (abfd) machines) since the field width is 20 and there numbers with more than 32 bits can be represented. */ sz = strtol (hdr.size, (char **) NULL, 10); - } - /* Read in the entire symbol table. */ - contents = (bfd_byte *) bfd_alloc (abfd, sz); - if (contents == NULL) - return false; - if (bfd_read ((PTR) contents, 1, sz, abfd) != sz) - return false; + /* Read in the entire symbol table. */ + contents = (bfd_byte *) bfd_alloc (abfd, sz); + if (contents == NULL) + return false; + if (bfd_read ((PTR) contents, 1, sz, abfd) != sz) + return false; - /* The symbol table starts with a four byte count. */ - c = bfd_h_get_32 (abfd, contents); + /* The symbol table starts with an eight byte count. */ + c = bfd_h_get_64 (abfd, contents); - if (c * 4 >= sz) - { - bfd_set_error (bfd_error_bad_value); - return false; + if (c * 8 >= sz) + { + bfd_set_error (bfd_error_bad_value); + return false; + } + + bfd_ardata (abfd)->symdefs = ((carsym *) + bfd_alloc (abfd, c * sizeof (carsym))); + if (bfd_ardata (abfd)->symdefs == NULL) + return false; + + /* After the count comes a list of eight byte file offsets. */ + for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 8; + i < c; + ++i, ++arsym, p += 8) + arsym->file_offset = bfd_h_get_64 (abfd, p); } - bfd_ardata (abfd)->symdefs = ((carsym *) - bfd_alloc (abfd, c * sizeof (carsym))); - if (bfd_ardata (abfd)->symdefs == NULL) - return false; - - /* After the count comes a list of four byte file offsets. */ - for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 4; - i < c; - ++i, ++arsym, p += 4) - arsym->file_offset = bfd_h_get_32 (abfd, p); - /* After the file offsets come null terminated symbol names. */ cend = contents + sz; for (i = 0, arsym = bfd_ardata (abfd)->symdefs; diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c index 2d03fa4..f518fdf 100644 --- a/bfd/xcofflink.c +++ b/bfd/xcofflink.c @@ -6577,13 +6577,14 @@ _bfd_ppc_xcoff_relocate_section (output_bfd, info, input_bfd, || strcmp (h->root.root.string, "._ptrgl") == 0) { if (next == 0x4def7b82 /* cror 15,15,15 */ - || next == 0x4ffffb82) /* cror 31,31,31 */ + || next == 0x4ffffb82 /* cror 31,31,31 */ + || next == 0x60000000) /* ori r0,r0,0 */ bfd_put_32 (input_bfd, 0x80410014, pnext); /* lwz r1,20(r1) */ } else { if (next == 0x80410014) /* lwz r1,20(r1) */ - bfd_put_32 (input_bfd, 0x4ffffb82, pnext); /* cror 31,31,31 */ + bfd_put_32 (input_bfd, 0x60000000, pnext); /* ori r0,r0,0 */ } } |