From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 96338 invoked by alias); 30 Mar 2016 07:34:01 -0000 Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org Received: (qmail 96307 invoked by uid 89); 30 Mar 2016 07:34:00 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.5 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 spammy=einfo, sk:link_in, UD:output_bfd, UD:link_info.output_bfd X-HELO: mail-pf0-f179.google.com Received: from mail-pf0-f179.google.com (HELO mail-pf0-f179.google.com) (209.85.192.179) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Wed, 30 Mar 2016 07:33:58 +0000 Received: by mail-pf0-f179.google.com with SMTP id x3so35317372pfb.1 for ; Wed, 30 Mar 2016 00:33:58 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:date:from:to:subject:message-id:mime-version :content-disposition:user-agent; bh=KN1DRfhQ7OfBSFYm/GbNzEYJkaZ0rVLSbK71DGQF0Fc=; b=Nu/RH8q//Mcx64aEK+Pd/tNP7p9zMu0+TgdNJMHRmzcP1CQoA+EQkerEgyQ4eAHXsM MpUYdOawCXd9wCq4ICq+9e7Jfu/U5maYTxFONcT0PTTbHztwxa2/cLbRmRftac04Qhtn OqJEKUUF3eUSIOJxTd5ua7DkFf6OYLwiHB+m9hbWs06b+w9BO7IdRH7C+NSL2MaJLtw8 wfAP6FFkG5QqWWVVOoDSPz9w5m76DggyufHaKARZH+bDYdK+BGlA/rllPqfyOtIAwZ5q VM9iIm6Ike8pYhBEUG4ik8nOMwu3KCzRXt+tDdQXu/h6kYUOygpEQ3GxpPDRwj0hvHT1 rh7w== X-Gm-Message-State: AD7BkJKMRe0VbZgZM3d4xzw2qlekX0qhKWC38Nw8Zdrxs9kHoH5lFPpZd7MELXmmWAqc5A== X-Received: by 10.98.73.88 with SMTP id w85mr10752993pfa.82.1459323236815; Wed, 30 Mar 2016 00:33:56 -0700 (PDT) Received: from bubble.grove.modra.org (CPE-58-160-146-233.sa.bigpond.net.au. [58.160.146.233]) by smtp.gmail.com with ESMTPSA id b74sm3337329pfd.24.2016.03.30.00.33.56 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 30 Mar 2016 00:33:56 -0700 (PDT) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id ADEC3EA0157; Wed, 30 Mar 2016 18:03:52 +1030 (ACDT) Date: Wed, 30 Mar 2016 07:34:00 -0000 From: Alan Modra To: binutils@sourceware.org Subject: PR18452, ld allows overlapping sections Message-ID: <20160330073352.GL15812@bubble.grove.modra.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-IsSubscribed: yes X-SW-Source: 2016-03/txt/msg00412.txt.bz2 PR 18452 * ldlang.c (maybe_overlays): New static var. (lang_size_sections_1): Set it here. (struct check_sec): New. (sort_sections_by_lma): Adjust for array of structs. (sort_sections_by_vma): New function. (lang_check_section_addresses): Check both LMA and VMA for overlap. * testsuite/ld-scripts/rgn-over7.d: Adjust. diff --git a/ld/ldlang.c b/ld/ldlang.c index b369f99..cb6aab6 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -68,6 +68,7 @@ static lang_statement_list_type *stat_save[10]; static lang_statement_list_type **stat_save_ptr = &stat_save[0]; static struct unique_sections *unique_section_list; static struct asneeded_minfo *asneeded_list_head; +static bfd_boolean maybe_overlays = FALSE; /* Forward declarations. */ static void exp_init_os (etree_type *); @@ -4677,17 +4678,39 @@ size_input_section return dot; } +struct check_sec +{ + asection *sec; + bfd_boolean warned; +}; + static int sort_sections_by_lma (const void *arg1, const void *arg2) { - const asection *sec1 = *(const asection **) arg1; - const asection *sec2 = *(const asection **) arg2; + const asection *sec1 = ((const struct check_sec *) arg1)->sec; + const asection *sec2 = ((const struct check_sec *) arg2)->sec; - if (bfd_section_lma (sec1->owner, sec1) - < bfd_section_lma (sec2->owner, sec2)) + if (sec1->lma < sec2->lma) return -1; - else if (bfd_section_lma (sec1->owner, sec1) - > bfd_section_lma (sec2->owner, sec2)) + else if (sec1->lma > sec2->lma) + return 1; + else if (sec1->id < sec2->id) + return -1; + else if (sec1->id > sec2->id) + return 1; + + return 0; +} + +static int +sort_sections_by_vma (const void *arg1, const void *arg2) +{ + const asection *sec1 = ((const struct check_sec *) arg1)->sec; + const asection *sec2 = ((const struct check_sec *) arg2)->sec; + + if (sec1->vma < sec2->vma) + return -1; + else if (sec1->vma > sec2->vma) return 1; else if (sec1->id < sec2->id) return -1; @@ -4712,66 +4735,90 @@ static void lang_check_section_addresses (void) { asection *s, *p; - asection **sections, **spp; - unsigned int count; + struct check_sec *sections; + size_t i, count; bfd_vma s_start; bfd_vma s_end; - bfd_vma p_start; - bfd_vma p_end; - bfd_size_type amt; + bfd_vma p_start = 0; + bfd_vma p_end = 0; lang_memory_region_type *m; if (bfd_count_sections (link_info.output_bfd) <= 1) return; - amt = bfd_count_sections (link_info.output_bfd) * sizeof (asection *); - sections = (asection **) xmalloc (amt); + count = bfd_count_sections (link_info.output_bfd); + sections = XNEWVEC (struct check_sec, count); /* Scan all sections in the output list. */ count = 0; for (s = link_info.output_bfd->sections; s != NULL; s = s->next) { - /* Only consider loadable sections with real contents. */ - if (!(s->flags & SEC_LOAD) - || !(s->flags & SEC_ALLOC) + if (IGNORE_SECTION (s) || s->size == 0) continue; - sections[count] = s; + sections[count].sec = s; + sections[count].warned = FALSE; count++; } if (count <= 1) return; - qsort (sections, (size_t) count, sizeof (asection *), - sort_sections_by_lma); - - spp = sections; - s = *spp++; - s_start = s->lma; - s_end = s_start + TO_ADDR (s->size) - 1; - for (count--; count; count--) - { - /* We must check the sections' LMA addresses not their VMA - addresses because overlay sections can have overlapping VMAs - but they must have distinct LMAs. */ - p = s; - p_start = s_start; - p_end = s_end; - s = *spp++; - s_start = s->lma; - s_end = s_start + TO_ADDR (s->size) - 1; - - /* Look for an overlap. We have sorted sections by lma, so we - know that s_start >= p_start. Besides the obvious case of - overlap when the current section starts before the previous - one ends, we also must have overlap if the previous section - wraps around the address space. */ - if (s_start <= p_end - || p_end < p_start) - einfo (_("%X%P: section %s loaded at [%V,%V] overlaps section %s loaded at [%V,%V]\n"), - s->name, s_start, s_end, p->name, p_start, p_end); + qsort (sections, count, sizeof (*sections), sort_sections_by_lma); + + /* First check sections LMAs. There should be no overlap of LMAs on + loadable sections, even with overlays. */ + for (p = NULL, i = 0; i < count; i++) + { + s = sections[i].sec; + if ((s->flags & SEC_LOAD) != 0) + { + s_start = s->lma; + s_end = s_start + TO_ADDR (s->size) - 1; + + /* Look for an overlap. We have sorted sections by lma, so + we know that s_start >= p_start. Besides the obvious + case of overlap when the current section starts before + the previous one ends, we also must have overlap if the + previous section wraps around the address space. */ + if (p != NULL + && (s_start <= p_end + || p_end < p_start)) + { + einfo (_("%X%P: section %s LMA [%V,%V]" + " overlaps section %s LMA [%V,%V]\n"), + s->name, s_start, s_end, p->name, p_start, p_end); + sections[i].warned = TRUE; + } + p = s; + p_start = s_start; + p_end = s_end; + } + } + + /* Now check sections VMAs if no overlays were detected. */ + if (!maybe_overlays) + { + qsort (sections, count, sizeof (*sections), sort_sections_by_vma); + + for (p = NULL, i = 0; i < count; i++) + { + s = sections[i].sec; + s_start = s->vma; + s_end = s_start + TO_ADDR (s->size) - 1; + + if (p != NULL + && !sections[i].warned + && (s_start <= p_end + || p_end < p_start)) + einfo (_("%X%P: section %s VMA [%V,%V]" + " overlaps section %s VMA [%V,%V]\n"), + s->name, s_start, s_end, p->name, p_start, p_end); + p = s; + p_start = s_start; + p_end = s_end; + } } free (sections); @@ -5102,6 +5149,18 @@ lang_size_sections_1 if (bfd_is_abs_section (os->bfd_section) || os->ignored) break; + if (r->last_os != NULL + && !IGNORE_SECTION (os->bfd_section) + && os->bfd_section->size != 0) + { + asection *last; + + last = r->last_os->output_section_statement.bfd_section; + if (dot + TO_ADDR (os->bfd_section->size) > last->vma + && dot < last->vma + TO_ADDR (last->size)) + maybe_overlays = TRUE; + } + /* Keep track of normal sections using the default lma region. We use this to set the lma for following sections. Overlays or other linker diff --git a/ld/testsuite/ld-scripts/rgn-over7.d b/ld/testsuite/ld-scripts/rgn-over7.d index 50bd6af..74abb5c 100644 --- a/ld/testsuite/ld-scripts/rgn-over7.d +++ b/ld/testsuite/ld-scripts/rgn-over7.d @@ -1,7 +1,7 @@ # name: rgn-over7 # source: rgn-over.s # ld: -T rgn-over7.t -Map tmpdir/rgn-over7.map -# error: \A[^ \n]*?ld[^:\n]*?: [^\n]*?section `\.text' will not fit in region `r1'\n[^ \n]*?ld[^:\n]*?: section \.data loaded at \[0+1008,0+1013\] overlaps section \.text loaded at \[0+1000,0+100b\]\n[^ \n]*?ld[^:\n]*?: region `r1' overflowed by 4 bytes\Z +# error: \A[^ \n]*?ld[^:\n]*?: [^\n]*?section `\.text' will not fit in region `r1'\n[^ \n]*?ld[^:\n]*?: section \.data LMA \[0+1008,0+1013\] overlaps section \.text LMA \[0+1000,0+100b\]\n[^ \n]*?ld[^:\n]*?: region `r1' overflowed by 4 bytes\Z Discarded input sections #... -- Alan Modra Australia Development Lab, IBM