From 3ff9eb92d37e73a409f4c77f503a7f45998ed12d Mon Sep 17 00:00:00 2001 From: thorpej Date: Mon, 25 Nov 2002 23:15:15 +0000 Subject: [PATCH] Make it possible for the a.out BFD back-end to merge read-only sections with .text if the following 3 conditions are true: 1. Section has file contents and is read-only. 2. The VMA of the section is after the end of .text and before the start of .data. 3. The image is demand-pageable (otherwise, a_text in the header will not reflect the gap between .text and .data). Fixes PR 19164. --- gnu/dist/toolchain/bfd/aoutnbsd.h | 31 +++++++++++++++++++++---------- gnu/dist/toolchain/bfd/aoutx.h | 31 +++++++++++++++++++++---------- gnu/dist/toolchain/bfd/libaout.h | 19 +++++++++++++++++++ gnu/dist/toolchain/bfd/netbsd.h | 15 ++++++++++----- 4 files changed, 71 insertions(+), 25 deletions(-) diff --git a/gnu/dist/toolchain/bfd/aoutnbsd.h b/gnu/dist/toolchain/bfd/aoutnbsd.h index 2bf99de8f985..010116347b8f 100644 --- a/gnu/dist/toolchain/bfd/aoutnbsd.h +++ b/gnu/dist/toolchain/bfd/aoutnbsd.h @@ -1222,11 +1222,17 @@ NAME(aout,set_section_contents) (abfd, section, location, offset, count) if (section != obj_textsec (abfd) && section != obj_datasec (abfd)) { - (*_bfd_error_handler) - ("%s: can not represent section `%s' in a.out object file format", - bfd_get_filename (abfd), bfd_get_section_name (abfd, section)); - bfd_set_error (bfd_error_nonrepresentable_section); - return false; + if (aout_section_merge_with_text_p (abfd, section)) + section->filepos = obj_textsec (abfd)->filepos + + (section->vma - obj_textsec (abfd)->vma); + else + { + (*_bfd_error_handler) + ("%s: can not represent section `%s' in a.out object file format", + bfd_get_filename (abfd), bfd_get_section_name (abfd, section)); + bfd_set_error (bfd_error_nonrepresentable_section); + return false; + } } if (count != 0) @@ -1540,11 +1546,16 @@ translate_to_native_sym_flags (abfd, cache_ptr, sym_pointer) sym_pointer->e_type[0] = N_UNDF | N_EXT; else { - (*_bfd_error_handler) - ("%s: can not represent section `%s' in a.out object file format", - bfd_get_filename (abfd), bfd_get_section_name (abfd, sec)); - bfd_set_error (bfd_error_nonrepresentable_section); - return false; + if (aout_section_merge_with_text_p (abfd, sec)) + sym_pointer->e_type[0] |= N_TEXT; + else + { + (*_bfd_error_handler) + ("%s: can not represent section `%s' in a.out object file format", + bfd_get_filename (abfd), bfd_get_section_name (abfd, sec)); + bfd_set_error (bfd_error_nonrepresentable_section); + return false; + } } /* Turn the symbol from section relative to absolute again */ diff --git a/gnu/dist/toolchain/bfd/aoutx.h b/gnu/dist/toolchain/bfd/aoutx.h index a8012953fc4c..8042c2f1339a 100644 --- a/gnu/dist/toolchain/bfd/aoutx.h +++ b/gnu/dist/toolchain/bfd/aoutx.h @@ -1266,11 +1266,17 @@ NAME(aout,set_section_contents) (abfd, section, location, offset, count) if (section != obj_textsec (abfd) && section != obj_datasec (abfd)) { - (*_bfd_error_handler) - (_("%s: can not represent section `%s' in a.out object file format"), - bfd_get_filename (abfd), bfd_get_section_name (abfd, section)); - bfd_set_error (bfd_error_nonrepresentable_section); - return false; + if (aout_section_merge_with_text_p (abfd, section)) + section->filepos = obj_textsec (abfd)->filepos + + (section->vma - obj_textsec (abfd)->vma); + else + { + (*_bfd_error_handler) + (_("%s: can not represent section `%s' in a.out object file format"), + bfd_get_filename (abfd), bfd_get_section_name (abfd, section)); + bfd_set_error (bfd_error_nonrepresentable_section); + return false; + } } if (count != 0) @@ -1694,11 +1700,16 @@ translate_to_native_sym_flags (abfd, cache_ptr, sym_pointer) sym_pointer->e_type[0] = N_UNDF | N_EXT; else { - (*_bfd_error_handler) - (_("%s: can not represent section `%s' in a.out object file format"), - bfd_get_filename (abfd), bfd_get_section_name (abfd, sec)); - bfd_set_error (bfd_error_nonrepresentable_section); - return false; + if (aout_section_merge_with_text_p (abfd, sec)) + sym_pointer->e_type[0] |= N_TEXT; + else + { + (*_bfd_error_handler) + (_("%s: can not represent section `%s' in a.out object file format"), + bfd_get_filename (abfd), bfd_get_section_name (abfd, sec)); + bfd_set_error (bfd_error_nonrepresentable_section); + return false; + } } /* Turn the symbol from section relative to absolute again */ diff --git a/gnu/dist/toolchain/bfd/libaout.h b/gnu/dist/toolchain/bfd/libaout.h index d3cce56e8633..578603f2719a 100644 --- a/gnu/dist/toolchain/bfd/libaout.h +++ b/gnu/dist/toolchain/bfd/libaout.h @@ -649,4 +649,23 @@ NAME(aout,bfd_free_cached_info) PARAMS ((bfd *)); } #endif +/* Test if a read-only section can be merged with .text. This is + possible if: + + 1. Section has file contents and is read-only. + 2. The VMA of the section is after the end of .text and before + the start of .data. + 3. The image is demand-pageable (otherwise, a_text in the header + will not reflect the gap between .text and .data). */ + +#define aout_section_merge_with_text_p(abfd, sec) \ + (((sec)->flags & (SEC_HAS_CONTENTS|SEC_READONLY)) == \ + (SEC_HAS_CONTENTS|SEC_READONLY) \ + && obj_textsec (abfd) != NULL \ + && obj_datasec (abfd) != NULL \ + && (sec)->vma >= (obj_textsec (abfd)->vma + \ + obj_textsec (abfd)->_cooked_size) \ + && ((sec)->vma + (sec)->_cooked_size) <= obj_datasec (abfd)->vma \ + && ((abfd)->flags & D_PAGED) != 0) + #endif /* ! defined (LIBAOUT_H) */ diff --git a/gnu/dist/toolchain/bfd/netbsd.h b/gnu/dist/toolchain/bfd/netbsd.h index 44b9f6214aed..ce06892899d3 100644 --- a/gnu/dist/toolchain/bfd/netbsd.h +++ b/gnu/dist/toolchain/bfd/netbsd.h @@ -391,11 +391,16 @@ netbsd_translate_to_native_sym_flags (abfd, cache_ptr, sym_pointer) sym_pointer->e_type[0] = N_UNDF | N_EXT; else { - (*_bfd_error_handler) - ("%s: can not represent section `%s' in a.out object file format", - bfd_get_filename (abfd), bfd_get_section_name (abfd, sec)); - bfd_set_error (bfd_error_nonrepresentable_section); - return false; + if (aout_section_merge_with_text_p (abfd, sec)) + sym_pointer->e_type[0] |= N_TEXT; + else + { + (*_bfd_error_handler) + ("%s: n2 can not represent section `%s' in a.out object file format", + bfd_get_filename (abfd), bfd_get_section_name (abfd, sec)); + bfd_set_error (bfd_error_nonrepresentable_section); + return false; + } } /* Turn the symbol from section relative to absolute again */