public inbox for binutils-cvs@sourceware.org
 help / color / mirror / Atom feed
* [binutils-gdb] elf: Add _bfd_elf_link_m[un]map_section_contents
@ 2024-04-03 16:17 H.J. Lu
  0 siblings, 0 replies; only message in thread
From: H.J. Lu @ 2024-04-03 16:17 UTC (permalink / raw)
  To: binutils-cvs

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=a9505c74206cfb797d3baac526b19ba7055675dc

commit a9505c74206cfb797d3baac526b19ba7055675dc
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Mon Mar 11 09:51:06 2024 -0700

    elf: Add _bfd_elf_link_m[un]map_section_contents
    
    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.

Diff:
---
 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 01e0da135b9..f31244f2227 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -3146,6 +3146,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 868abeccddb..9b98d3b8b2b 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -14366,10 +14366,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);
@@ -14393,16 +14395,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
@@ -14442,3 +14469,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 a7b50bfcaf9..2a05299b24d 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -11486,7 +11486,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;
 	}
 
@@ -12047,6 +12048,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;
@@ -12485,13 +12489,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;
@@ -12527,10 +12535,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)

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-04-03 16:17 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-03 16:17 [binutils-gdb] elf: Add _bfd_elf_link_m[un]map_section_contents H.J. Lu

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).