public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: "H.J. Lu" <hjl.tools@gmail.com>
To: binutils@sourceware.org
Cc: goldstein.w.n@gmail.com, sam@gentoo.org, amodra@gmail.com
Subject: [PATCH v12 6/6] elf: Add _bfd_elf_link_m[un]map_section_contents
Date: Sun, 17 Mar 2024 05:19:12 -0700	[thread overview]
Message-ID: <20240317121912.799372-7-hjl.tools@gmail.com> (raw)
In-Reply-To: <20240317121912.799372-1-hjl.tools@gmail.com>

To copy input section contents, add _bfd_elf_link_mmap_section_contents
and _bfd_elf_link_munmap_section_contents to mmap in the input sections.

	* elf-bfd.h (_bfd_elf_link_mmap_section_contents): New.
	(_bfd_elf_link_munmap_section_contents): Likewise.
	* elf.c (elf_mmap_section_contents): New.
	(_bfd_elf_mmap_section_contents): Use it.
	(_bfd_elf_link_mmap_section_contents): New.
	(_bfd_elf_link_munmap_section_contents): Likewise.
	* elflink.c (elf_link_input_bfd): Call
	_bfd_elf_link_mmap_section_contents instead of
	bfd_get_full_section_contents.  Call
	_bfd_elf_link_munmap_section_contents to munmap the section
	contents.
	(bfd_elf_final_link): When mmap is used, initialize
	max_contents_size to _bfd_minimum_mmap_size and increase it
	for compressed or linker created sections or sections whose
	rawsize != size.
---
 bfd/elf-bfd.h |  4 ++++
 bfd/elf.c     | 57 +++++++++++++++++++++++++++++++++++++++++++++++----
 bfd/elflink.c | 33 +++++++++++++++++++++--------
 3 files changed, 82 insertions(+), 12 deletions(-)

diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index e7c2cd19bed..0fcef04af36 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -3143,6 +3143,10 @@ extern bool _bfd_elf_mmap_section_contents
   (bfd *abfd, asection *section, bfd_byte **buf);
 extern void _bfd_elf_munmap_section_contents
   (asection *, void *);
+extern bool _bfd_elf_link_mmap_section_contents
+  (bfd *abfd, asection *section, bfd_byte **buf);
+extern void _bfd_elf_link_munmap_section_contents
+  (asection *);
 
 /* Large common section.  */
 extern asection _bfd_elf_large_com_section;
diff --git a/bfd/elf.c b/bfd/elf.c
index cb47c499704..f66ac9289df 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -14388,10 +14388,12 @@ _bfd_elf_write_secondary_reloc_section (bfd *abfd, asection *sec)
   return result;
 }
 
-/* Mmap in section contents.  */
+/* Mmap in section contents.  If FINAL_LINK is false, set *BUF to NULL
+   before calling bfd_get_full_section_contents.  */
 
-bool
-_bfd_elf_mmap_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **buf)
+static bool
+elf_mmap_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **buf,
+			   bool final_link)
 {
 #ifdef USE_MMAP
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
@@ -14415,16 +14417,41 @@ _bfd_elf_mmap_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **buf)
 	  if (sec->mmapped_p)
 	    abort ();
 	  sec->mmapped_p = 1;
+
+	  /* Never use the preallocated buffer if mmapp is used.  */
+	  *buf = NULL;
 	}
     }
 #endif
-  *buf = NULL;
+  /* NB: When this is called from elf_link_input_bfd, FINAL_LINK is
+     true.  If FINAL_LINK is false, *BUF is set to the preallocated
+     buffer if USE_MMAP is undefined and *BUF is set to NULL if
+     USE_MMAP is defined.  */
+  if (!final_link)
+    *buf = NULL;
   bool ret = bfd_get_full_section_contents (abfd, sec, buf);
   if (ret && sec->mmapped_p)
     *buf = sec->contents;
   return ret;
 }
 
+/* Mmap in section contents.  */
+
+bool
+_bfd_elf_mmap_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **buf)
+{
+  return elf_mmap_section_contents (abfd, sec, buf, false);
+}
+
+/* Mmap in the full section contents for the final link.  */
+
+bool
+_bfd_elf_link_mmap_section_contents (bfd *abfd, sec_ptr sec,
+				     bfd_byte **buf)
+{
+  return elf_mmap_section_contents (abfd, sec, buf, true);
+}
+
 /* Munmap section contents.  */
 
 void
@@ -14464,3 +14491,25 @@ _bfd_elf_munmap_section_contents (asection *sec ATTRIBUTE_UNUSED,
 
   free (contents);
 }
+
+/* Munmap the full section contents for the final link.  */
+
+void
+_bfd_elf_link_munmap_section_contents (asection *sec ATTRIBUTE_UNUSED)
+{
+#ifdef USE_MMAP
+  if (sec->mmapped_p && elf_section_data (sec)->contents_addr != NULL)
+    {
+      /* When _bfd_elf_link_mmap_section_contents returns CONTENTS as
+	 malloced, CONTENTS_ADDR is set to NULL.  */
+      /* NB: CONTENTS_ADDR and CONTENTS_SIZE must be valid.  */
+      if (munmap (elf_section_data (sec)->contents_addr,
+		  elf_section_data (sec)->contents_size) != 0)
+	abort ();
+      sec->mmapped_p = 0;
+      sec->contents = NULL;
+      elf_section_data (sec)->contents_addr = NULL;
+      elf_section_data (sec)->contents_size = 0;
+    }
+#endif
+}
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 601d15e9cef..ab3fa308d44 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -11487,7 +11487,8 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
       else
 	{
 	  contents = flinfo->contents;
-	  if (! bfd_get_full_section_contents (input_bfd, o, &contents))
+	  if (! _bfd_elf_link_mmap_section_contents (input_bfd, o,
+						     &contents))
 	    return false;
 	}
 
@@ -12045,6 +12046,9 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
 	  }
 	  break;
 	}
+
+      /* Munmap the section contents for each input section.  */
+      _bfd_elf_link_munmap_section_contents (o);
     }
 
   return true;
@@ -12483,13 +12487,17 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
   /* Count up the number of relocations we will output for each output
      section, so that we know the sizes of the reloc sections.  We
      also figure out some maximum sizes.  */
-  max_contents_size = 0;
 #ifdef USE_MMAP
   /* Mmap is used only if section size >= the minimum mmap section
-     size.  max_external_reloc_size covers all relocation sections
-     smaller than the minimum mmap section size.   */
+     size.  The initial max_contents_size value covers all sections
+     smaller than the minimum mmap section size.  It may be increased
+     for compressed or linker created sections or sections whose
+     rawsize != size.  max_external_reloc_size covers all relocation
+     sections smaller than the minimum mmap section size.  */
+  max_contents_size = _bfd_minimum_mmap_size;
   max_external_reloc_size = _bfd_minimum_mmap_size;
 #else
+  max_contents_size = 0;
   max_external_reloc_size = 0;
 #endif
   max_internal_reloc_count = 0;
@@ -12525,10 +12533,19 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
 	      if (sec->flags & SEC_MERGE)
 		merged = true;
 
-	      if (sec->rawsize > max_contents_size)
-		max_contents_size = sec->rawsize;
-	      if (sec->size > max_contents_size)
-		max_contents_size = sec->size;
+#ifdef USE_MMAP
+	      /* Mmap is used only on non-compressed, non-linker created
+		 sections whose rawsize == size.  */
+	      if (sec->compress_status != COMPRESS_SECTION_NONE
+		 || (sec->flags & SEC_LINKER_CREATED) != 0
+		 || sec->rawsize != sec->size)
+#endif
+		{
+		  if (sec->rawsize > max_contents_size)
+		    max_contents_size = sec->rawsize;
+		  if (sec->size > max_contents_size)
+		    max_contents_size = sec->size;
+		}
 
 	      if (bfd_get_flavour (sec->owner) == bfd_target_elf_flavour
 		  && (sec->owner->flags & DYNAMIC) == 0)
-- 
2.44.0


  parent reply	other threads:[~2024-03-17 12:19 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-17 12:19 [PATCH v12 0/6] elf: Use mmap to map in section contents H.J. Lu
2024-03-17 12:19 ` [PATCH v12 1/6] elf: Use mmap to map in read-only sections H.J. Lu
2024-04-08  3:57   ` Simon Marchi
2024-04-08 14:26     ` [PATCH] bfd: Define pagesize variables only for mmap H.J. Lu
2024-04-08 22:55       ` Alan Modra
2024-04-09  2:49         ` H.J. Lu
2024-04-09  5:47           ` Alan Modra
2024-04-09 14:25             ` H.J. Lu
2024-03-17 12:19 ` [PATCH v12 2/6] elf: Add _bfd_elf_m[un]map_section_contents H.J. Lu
2024-03-17 12:19 ` [PATCH v12 3/6] elf: Use mmap to map in symbol and relocation tables H.J. Lu
2024-03-17 12:19 ` [PATCH v12 4/6] elf: Don't cache symbol nor relocation tables with mmap H.J. Lu
2024-03-17 12:19 ` [PATCH v12 5/6] elf: Always keep symbol table and relocation info for eh_frame H.J. Lu
2024-03-17 12:19 ` H.J. Lu [this message]
2024-03-28 13:29 ` PING: [PATCH v12 0/6] elf: Use mmap to map in section contents H.J. Lu
2024-04-03 16:03   ` Nick Clifton
2024-04-04 13:12 ` Luis Machado
2024-04-04 13:53   ` H.J. Lu
2024-04-04 20:27   ` Joseph Myers
2024-04-04 22:22     ` Alan Modra
2024-04-04 22:43       ` Joseph Myers
2024-04-04 22:46         ` H.J. Lu
2024-04-04 23:20           ` H.J. Lu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240317121912.799372-7-hjl.tools@gmail.com \
    --to=hjl.tools@gmail.com \
    --cc=amodra@gmail.com \
    --cc=binutils@sourceware.org \
    --cc=goldstein.w.n@gmail.com \
    --cc=sam@gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).