aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2024-03-11 09:51:06 -0700
committerH.J. Lu <hjl.tools@gmail.com>2024-04-03 09:11:03 -0700
commita9505c74206cfb797d3baac526b19ba7055675dc (patch)
tree77573e019945fcc8f64c3b884cdc42a9d0d6193b /bfd
parent3428c771aef0cebe229ac0f02a654d2ef78f2427 (diff)
downloadgdb-a9505c74206cfb797d3baac526b19ba7055675dc.zip
gdb-a9505c74206cfb797d3baac526b19ba7055675dc.tar.gz
gdb-a9505c74206cfb797d3baac526b19ba7055675dc.tar.bz2
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.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/elf-bfd.h4
-rw-r--r--bfd/elf.c57
-rw-r--r--bfd/elflink.c33
3 files changed, 82 insertions, 12 deletions
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 01e0da1..f31244f 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 868abec..9b98d3b 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 a7b50bf..2a05299 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)