ELF SEC_SMALL_DATA

Message ID 20200302010354.GF5384@bubble.grove.modra.org
State New
Headers show
Series
  • ELF SEC_SMALL_DATA
Related show

Commit Message

Alan Modra March 2, 2020, 1:03 a.m.
For those ELF targets that have .sdata or .sbss sections, or similar
sections, arrange to mark the sections with the SEC_SMALL_DATA flag.
This fixes regressions in nm symbol type caused by removing .sdata
and .sbss from coff_section_type with commit 49d9fd42ac.

	* elf32-m32r.c (m32r_elf_section_flags): New function.
	(elf_backend_section_flags): Define.
	* elf32-nds32.c (nds32_elf_section_flags): New function.
	(elf_backend_section_flags): Define.
	* elf32-ppc.c (ppc_elf_section_from_shdr): Set SEC_SMALL_DATA for
	.sbss and .sdata sections.
	* elf32-v850.c (v850_elf_section_from_shdr): Set SEC_SMALL_DATA
	for SHF_V850_GPREL sections.
	* elf64-alpha.c (elf64_alpha_section_from_shdr): Delete outdated
	FIXME.
	* elf64-hppa.c (elf64_hppa_section_from_shdr): Set SEC_SMALL_DATA
	for SHF_PARISC_SHORT sections.
	* elf64-ppc.c (ppc64_elf_section_flags): New function.
	(elf_backend_section_flags): Define.
	* elfxx-mips.c (_bfd_mips_elf_section_from_shdr): Set SEC_SMALL_DATA
	for SHF_MIPS_GPREL sections.  Delete FIXME.


-- 
Alan Modra
Australia Development Lab, IBM

Patch

diff --git a/bfd/elf32-m32r.c b/bfd/elf32-m32r.c
index edc95b5d63..2a4b0b2ebe 100644
--- a/bfd/elf32-m32r.c
+++ b/bfd/elf32-m32r.c
@@ -3827,6 +3827,18 @@  static const struct bfd_elf_special_section m32r_elf_special_sections[] =
   { NULL,		      0,  0, 0,		   0 }
 };
 
+static bfd_boolean
+m32r_elf_section_flags (const Elf_Internal_Shdr *hdr)
+{
+  const char *name = hdr->bfd_section->name;
+
+  if (strncmp (name, ".sbss", 5) == 0
+      || strncmp (name, ".sdata", 6) == 0)
+    hdr->bfd_section->flags |= SEC_SMALL_DATA;
+
+  return TRUE;
+}
+
 static enum elf_reloc_type_class
 m32r_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
 			   const asection *rel_sec ATTRIBUTE_UNUSED,
@@ -3897,6 +3909,7 @@  m32r_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
 #define bfd_elf32_bfd_set_private_flags		m32r_elf_set_private_flags
 #define bfd_elf32_bfd_print_private_bfd_data	m32r_elf_print_private_bfd_data
 #define elf_backend_special_sections		m32r_elf_special_sections
+#define elf_backend_section_flags		m32r_elf_section_flags
 
 #define elf_backend_linux_prpsinfo32_ugid16	TRUE
 
diff --git a/bfd/elf32-nds32.c b/bfd/elf32-nds32.c
index 6d3c1c360f..fc4d002f0d 100644
--- a/bfd/elf32-nds32.c
+++ b/bfd/elf32-nds32.c
@@ -12593,6 +12593,18 @@  static struct bfd_elf_special_section const nds32_elf_special_sections[] =
   {NULL, 0, 0, 0, 0}
 };
 
+static bfd_boolean
+nds32_elf_section_flags (const Elf_Internal_Shdr *hdr)
+{
+  const char *name = hdr->bfd_section->name;
+
+  if (strncmp (name, ".sbss", 5) == 0
+      || strncmp (name, ".sdata", 6) == 0)
+    hdr->bfd_section->flags |= SEC_SMALL_DATA;
+
+  return TRUE;
+}
+
 static bfd_boolean
 nds32_elf_output_arch_syms (bfd *output_bfd ATTRIBUTE_UNUSED,
 			    struct bfd_link_info *info,
@@ -14093,6 +14105,7 @@  nds32_elf_unify_tls_model (bfd *inbfd, asection *insec, bfd_byte *incontents,
 #define elf_backend_object_p			nds32_elf_object_p
 #define elf_backend_final_write_processing	nds32_elf_final_write_processing
 #define elf_backend_special_sections		nds32_elf_special_sections
+#define elf_backend_section_flags		nds32_elf_section_flags
 #define bfd_elf32_bfd_get_relocated_section_contents \
 				nds32_elf_get_relocated_section_contents
 #define bfd_elf32_bfd_is_target_special_symbol	nds32_elf_is_target_special_symbol
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 3a42a4e105..68b02205aa 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -1332,15 +1332,21 @@  ppc_elf_section_from_shdr (bfd *abfd,
     return FALSE;
 
   newsect = hdr->bfd_section;
-  flags = bfd_section_flags (newsect);
+  flags = 0;
   if (hdr->sh_flags & SHF_EXCLUDE)
     flags |= SEC_EXCLUDE;
 
   if (hdr->sh_type == SHT_ORDERED)
     flags |= SEC_SORT_ENTRIES;
 
-  bfd_set_section_flags (newsect, flags);
-  return TRUE;
+  if (strncmp (name, ".PPC.EMB", 8) == 0)
+    name += 8;
+  if (strncmp (name, ".sbss", 5) == 0
+      || strncmp (name, ".sdata", 6) == 0)
+    flags |= SEC_SMALL_DATA;
+
+  return (flags == 0
+	  || bfd_set_section_flags (newsect, newsect->flags | flags));
 }
 
 /* Set up any other section flags and such that may be necessary.  */
diff --git a/bfd/elf32-v850.c b/bfd/elf32-v850.c
index afebb2ab86..bf37a93662 100644
--- a/bfd/elf32-v850.c
+++ b/bfd/elf32-v850.c
@@ -3151,6 +3151,8 @@  v850_elf_section_from_shdr (bfd *abfd,
 			    const char *name,
 			    int shindex)
 {
+  flagword flags;
+
   /* There ought to be a place to keep ELF backend specific flags, but
      at the moment there isn't one.  We just keep track of the
      sections by their name, instead.  */
@@ -3158,18 +3160,21 @@  v850_elf_section_from_shdr (bfd *abfd,
   if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
     return FALSE;
 
+  flags = 0;
   switch (hdr->sh_type)
     {
     case SHT_V850_SCOMMON:
     case SHT_V850_TCOMMON:
     case SHT_V850_ZCOMMON:
-      if (!bfd_set_section_flags (hdr->bfd_section,
-				  (bfd_section_flags (hdr->bfd_section)
-				   | SEC_IS_COMMON)))
-	return FALSE;
+      flags = SEC_IS_COMMON;
     }
 
-  return TRUE;
+  if ((hdr->sh_flags & SHF_V850_GPREL) != 0)
+    flags |= SEC_SMALL_DATA;
+
+  return (flags == 0
+	  || bfd_set_section_flags (hdr->bfd_section,
+				    hdr->bfd_section->flags | flags));
 }
 
 /* Set the correct type for a V850 ELF section.  We do this
diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c
index 9d2d7f1d4d..ca15944e60 100644
--- a/bfd/elf64-alpha.c
+++ b/bfd/elf64-alpha.c
@@ -1136,9 +1136,7 @@  elf64_alpha_info_to_howto (bfd *abfd, arelent *cache_ptr,
 
 /* Handle an Alpha specific section when reading an object file.  This
    is called when bfd_section_from_shdr finds a section with an unknown
-   type.
-   FIXME: We need to handle the SHF_ALPHA_GPREL flag, but I'm not sure
-   how to.  */
+   type.  */
 
 static bfd_boolean
 elf64_alpha_section_from_shdr (bfd *abfd,
diff --git a/bfd/elf64-hppa.c b/bfd/elf64-hppa.c
index f035443894..a2602daf2b 100644
--- a/bfd/elf64-hppa.c
+++ b/bfd/elf64-hppa.c
@@ -383,7 +383,9 @@  elf64_hppa_section_from_shdr (bfd *abfd,
   if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
     return FALSE;
 
-  return TRUE;
+  return ((hdr->sh_flags & SHF_PARISC_SHORT) == 0
+	  || bfd_set_section_flags (hdr->bfd_section,
+				    hdr->bfd_section->flags | SEC_SMALL_DATA));
 }
 
 /* SEC is a section containing relocs for an input BFD when linking; return
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 1ea4c402e0..05ef34b030 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -125,6 +125,7 @@  static bfd_vma opd_entry_value
 #define elf_backend_finish_dynamic_sections   ppc64_elf_finish_dynamic_sections
 #define elf_backend_link_output_symbol_hook   ppc64_elf_output_symbol_hook
 #define elf_backend_special_sections	      ppc64_elf_special_sections
+#define elf_backend_section_flags	      ppc64_elf_section_flags
 #define elf_backend_merge_symbol_attribute    ppc64_elf_merge_symbol_attribute
 #define elf_backend_merge_symbol	      ppc64_elf_merge_symbol
 #define elf_backend_get_reloc_section	      bfd_get_section_by_name
@@ -2011,6 +2012,18 @@  ppc64_elf_new_section_hook (bfd *abfd, asection *sec)
   return _bfd_elf_new_section_hook (abfd, sec);
 }
 
+static bfd_boolean
+ppc64_elf_section_flags (const Elf_Internal_Shdr *hdr)
+{
+  const char *name = hdr->bfd_section->name;
+
+  if (strncmp (name, ".sbss", 5) == 0
+      || strncmp (name, ".sdata", 6) == 0)
+    hdr->bfd_section->flags |= SEC_SMALL_DATA;
+
+  return TRUE;
+}
+
 static struct _opd_sec_data *
 get_opd_info (asection * sec)
 {
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index ae33acb8d5..4671b50449 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -7425,10 +7425,7 @@  _bfd_mips_elf_section_processing (bfd *abfd, Elf_Internal_Shdr *hdr)
 
 /* Handle a MIPS specific section when reading an object file.  This
    is called when elfcode.h finds a section with an unknown type.
-   This routine supports both the 32-bit and 64-bit ELF ABI.
-
-   FIXME: We need to handle the SHF_MIPS_GPREL flag, but I'm not sure
-   how to.  */
+   This routine supports both the 32-bit and 64-bit ELF ABI.  */
 
 bfd_boolean
 _bfd_mips_elf_section_from_shdr (bfd *abfd,
@@ -7517,6 +7514,9 @@  _bfd_mips_elf_section_from_shdr (bfd *abfd,
   if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
     return FALSE;
 
+  if (hdr->sh_flags & SHF_MIPS_GPREL)
+    flags |= SEC_SMALL_DATA;
+
   if (flags)
     {
       if (!bfd_set_section_flags (hdr->bfd_section,