From 191d910cb94db8426d5d309d68a28eeb25d5268b Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 5 Aug 1996 17:45:58 +0000 Subject: [PATCH] * elf.c (map_sections_to_segments): Rewrite tests for starting a new segment to make them more comprehensible. If the relationship between the LMA and the VMA changed, start a new segment. Don't check dynsec when deciding whether to start a new segment for a writeable section; -N will now handle this. --- bfd/ChangeLog | 8 +++++ bfd/elf.c | 83 +++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 69 insertions(+), 22 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index da041906261..c3a057811de 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +Mon Aug 5 13:42:41 1996 Ian Lance Taylor + + * elf.c (map_sections_to_segments): Rewrite tests for starting a + new segment to make them more comprehensible. If the relationship + between the LMA and the VMA changed, start a new segment. Don't + check dynsec when deciding whether to start a new segment for a + writeable section; -N will now handle this. + Thu Aug 1 22:43:08 1996 Jeffrey A Law (law@cygnus.com) * libhppa.h: Remove "esel" changes. Not the right approach. diff --git a/bfd/elf.c b/bfd/elf.c index 6a27ba56dd7..7eb5540fcf5 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -40,6 +40,7 @@ SECTION static INLINE struct elf_segment_map *make_mapping PARAMS ((bfd *, asection **, unsigned int, unsigned int, boolean)); +static boolean map_sections_to_segments PARAMS ((bfd *)); static int elf_sort_sections PARAMS ((const PTR, const PTR)); static boolean assign_file_positions_for_segments PARAMS ((bfd *)); static boolean assign_file_positions_except_relocs PARAMS ((bfd *)); @@ -1754,29 +1755,68 @@ map_sections_to_segments (abfd) for (i = 0, hdrpp = sections; i < count; i++, hdrpp++) { asection *hdr; + boolean new_segment; hdr = *hdrpp; /* See if this section and the last one will fit in the same - segment. Don't put a loadable section after a non-loadable - section. If we are building a dynamic executable, don't put - a writable section in a read only segment, unless they're on - the same page anyhow (we don't do this for a non-dynamic - executable because some people prefer to have only one - program segment; anybody can use PHDRS in their linker script - to control what happens anyhow). */ - if (last_hdr == NULL - || (abfd->flags & D_PAGED) == 0 - || ((BFD_ALIGN (last_hdr->lma + last_hdr->_raw_size, maxpagesize) - >= hdr->lma) - && ((last_hdr->flags & SEC_LOAD) != 0 - || (hdr->flags & SEC_LOAD) == 0) - && (dynsec == NULL - || writable - || (hdr->flags & SEC_READONLY) != 0 - || (BFD_ALIGN (last_hdr->lma + last_hdr->_raw_size, - maxpagesize) - > hdr->lma)))) + segment. */ + + if (last_hdr == NULL) + { + /* If we don't have a segment yet, then we don't need a new + one (we build the last one after this loop). */ + new_segment = false; + } + else if (last_hdr->lma - last_hdr->vma != hdr->lma - hdr->vma) + { + /* If this section has a different relation between the + virtual address and the load address, then we need a new + segment. */ + new_segment = true; + } + else if ((abfd->flags & D_PAGED) == 0) + { + /* If the file is not demand paged, which means that we + don't require the sections to be correctly aligned in the + file, then there is no other reason for a new segment. */ + new_segment = false; + } + else if (BFD_ALIGN (last_hdr->lma + last_hdr->_raw_size, maxpagesize) + < hdr->lma) + { + /* If putting this section in this segment would force us to + skip a page in the segment, then we need a new segment. */ + new_segment = true; + } + else if ((last_hdr->flags & SEC_LOAD) == 0 + && (hdr->flags & SEC_LOAD) != 0) + { + /* We don't want to put a loadable section after a + nonloadable section in the same segment. */ + new_segment = true; + } + else if (! writable + && (hdr->flags & SEC_READONLY) == 0 + && (BFD_ALIGN (last_hdr->lma + last_hdr->_raw_size, maxpagesize) + == hdr->lma)) + { + /* We don't want to put a writable section in a read only + segment, unless they are on the same page in memory + anyhow. We already know that the last section does not + bring us past the current section on the page, so the + only case in which the new section is not on the same + page as the previous section is when the previous section + ends precisely on a page boundary. */ + new_segment = true; + } + else + { + /* Otherwise, we can use the same segment. */ + new_segment = false; + } + + if (! new_segment) { if ((hdr->flags & SEC_READONLY) == 0) writable = true; @@ -1784,9 +1824,8 @@ map_sections_to_segments (abfd) continue; } - /* This section won't fit in the program segment. We must - create a new program header holding all the sections from - phdr_index until hdr. */ + /* We need a new program segment. We must create a new program + header holding all the sections from phdr_index until hdr. */ m = make_mapping (abfd, sections, phdr_index, i, phdr_in_section); if (m == NULL) -- 2.30.2