diff options
author | Ian Lance Taylor <ian@airs.com> | 1999-09-12 00:30:27 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 1999-09-12 00:30:27 +0000 |
commit | cb43721da5d2e451a068fc3397b89ec1f47ce2bc (patch) | |
tree | b84634985c22d5e591833c198e072d11ef1d0772 /bfd | |
parent | 5933bdc9a1882e0d81d8da7b869c5339b6bf2fc4 (diff) | |
download | fsf-binutils-gdb-cb43721da5d2e451a068fc3397b89ec1f47ce2bc.zip fsf-binutils-gdb-cb43721da5d2e451a068fc3397b89ec1f47ce2bc.tar.gz fsf-binutils-gdb-cb43721da5d2e451a068fc3397b89ec1f47ce2bc.tar.bz2 |
1999-09-11 Donn Terry <donn@interix.com>
* peicode.h (coff_swap_scnhdr_in): If COFF_IMAGE_WITH_PE, the
get the overflow of the s_nlnno field from the s_nreloc field.
* peigen.c (_bfd_pei_swap_scnhdr_out): If doing a final link, swap
the s_nlnno overflow of the .text section into the s_nreloc
field.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 6 | ||||
-rw-r--r-- | bfd/peicode.h | 16 | ||||
-rw-r--r-- | bfd/peigen.c | 57 |
3 files changed, 60 insertions, 19 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 28d5780..ff1f942 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -7,6 +7,12 @@ 1999-09-11 Donn Terry <donn@interix.com> + * peicode.h (coff_swap_scnhdr_in): If COFF_IMAGE_WITH_PE, the + get the overflow of the s_nlnno field from the s_nreloc field. + * peigen.c (_bfd_pei_swap_scnhdr_out): If doing a final link, swap + the s_nlnno overflow of the .text section into the s_nreloc + field. + * peigen.c (add_data_entry): Declare. (pei_swap_aouthdr_out): Get image size right. Set linker version more intuitively. diff --git a/bfd/peicode.h b/bfd/peicode.h index 605b1c0..0b6bde4 100644 --- a/bfd/peicode.h +++ b/bfd/peicode.h @@ -215,8 +215,20 @@ coff_swap_scnhdr_in (abfd, ext, in) GET_SCNHDR_LNNOPTR (abfd, (bfd_byte *) scnhdr_ext->s_lnnoptr); scnhdr_int->s_flags = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_flags); - scnhdr_int->s_nreloc = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nreloc); - scnhdr_int->s_nlnno = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nlnno); + /* MS handles overflow of line numbers by carrying into the reloc + field (it appears). Since it's supposed to be zero for PE + *IMAGE* format, that's safe. This is still a bit iffy. */ +#ifdef COFF_IMAGE_WITH_PE + scnhdr_int->s_nlnno = + (bfd_h_get_16 (abfd, (bfd_byte *) scnhdr_ext->s_nlnno) + + (bfd_h_get_16 (abfd, (bfd_byte *) scnhdr_ext->s_nreloc) << 16)); + scnhdr_int->s_nreloc = 0; +#else + scnhdr_int->s_nreloc = bfd_h_get_16 (abfd, + (bfd_byte *) scnhdr_ext->s_nreloc); + scnhdr_int->s_nlnno = bfd_h_get_16 (abfd, + (bfd_byte *) scnhdr_ext->s_nlnno); +#endif if (scnhdr_int->s_vaddr != 0) { diff --git a/bfd/peigen.c b/bfd/peigen.c index 24945b4..a79b857 100644 --- a/bfd/peigen.c +++ b/bfd/peigen.c @@ -958,27 +958,50 @@ _bfd_pei_swap_scnhdr_out (abfd, in, out) bfd_h_put_32(abfd, flags, (bfd_byte *) scnhdr_ext->s_flags); } - if (scnhdr_int->s_nlnno <= 0xffff) - bfd_h_put_16(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno); - else + if (coff_data (abfd)->link_info + && ! coff_data (abfd)->link_info->relocateable + && ! coff_data (abfd)->link_info->shared + && strcmp (scnhdr_int->s_name, ".text") == 0) { - (*_bfd_error_handler) (_("%s: line number overflow: 0x%lx > 0xffff"), - bfd_get_filename (abfd), - scnhdr_int->s_nlnno); - bfd_set_error (bfd_error_file_truncated); - bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nlnno); - ret = 0; + /* By inference from looking at MS output, the 32 bit field + which is the combintion of the number_of_relocs and + number_of_linenos is used for the line number count in + executables. A 16-bit field won't do for cc1. The MS + document says that the number of relocs is zero for + executables, but the 17-th bit has been observed to be there. + Overflow is not an issue: a 4G-line program will overflow a + bunch of other fields long before this! */ + bfd_h_put_16 (abfd, scnhdr_int->s_nlnno & 0xffff, + (bfd_byte *) scnhdr_ext->s_nlnno); + bfd_h_put_16 (abfd, scnhdr_int->s_nlnno >> 16, + (bfd_byte *) scnhdr_ext->s_nreloc); } - if (scnhdr_int->s_nreloc <= 0xffff) - bfd_h_put_16(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc); else { - (*_bfd_error_handler) (_("%s: reloc overflow: 0x%lx > 0xffff"), - bfd_get_filename (abfd), - scnhdr_int->s_nreloc); - bfd_set_error (bfd_error_file_truncated); - bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc); - ret = 0; + if (scnhdr_int->s_nlnno <= 0xffff) + bfd_h_put_16 (abfd, scnhdr_int->s_nlnno, + (bfd_byte *) scnhdr_ext->s_nlnno); + else + { + (*_bfd_error_handler) (_("%s: line number overflow: 0x%lx > 0xffff"), + bfd_get_filename (abfd), + scnhdr_int->s_nlnno); + bfd_set_error (bfd_error_file_truncated); + bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nlnno); + ret = 0; + } + if (scnhdr_int->s_nreloc <= 0xffff) + bfd_h_put_16 (abfd, scnhdr_int->s_nreloc, + (bfd_byte *) scnhdr_ext->s_nreloc); + else + { + (*_bfd_error_handler) (_("%s: reloc overflow: 0x%lx > 0xffff"), + bfd_get_filename (abfd), + scnhdr_int->s_nreloc); + bfd_set_error (bfd_error_file_truncated); + bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc); + ret = 0; + } } return ret; } |