[v1,10/14] clean-up bfd/elf-attrs.c: move specific-code to parse object attributes v1 into a new function

Message ID 20250227104811.178094-11-matthieu.longo@arm.com
State New
Headers
Series Several clean-ups and refactorings before a long patch series on AArch64 build attributes |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm fail Patch failed to apply
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 fail Patch failed to apply

Commit Message

Matthieu Longo Feb. 27, 2025, 10:47 a.m. UTC
  ---
 bfd/elf-attrs.c | 282 +++++++++++++++++++++++++-----------------------
 1 file changed, 147 insertions(+), 135 deletions(-)
  

Patch

diff --git a/bfd/elf-attrs.c b/bfd/elf-attrs.c
index aa6d6284a3d..a6a72369afd 100644
--- a/bfd/elf-attrs.c
+++ b/bfd/elf-attrs.c
@@ -489,160 +489,172 @@  _bfd_elf_obj_attrs_arg_type (bfd *abfd, int vendor, unsigned int tag)
     }
 }
 
+static void
+bfd_elf_parse_attr_section_v1 (bfd *abfd,
+			       Elf_Internal_Shdr * hdr,
+			       bfd_byte *contents)
+{
+  bfd_byte *p = contents;
+  bfd_byte *p_end = p + hdr->sh_size;
+  const char *std_sec = get_elf_backend_data (abfd)->obj_attrs_vendor;
+
+  while (p_end - p >= 4)
+    {
+      size_t len = p_end - p;
+      size_t namelen;
+      size_t section_len;
+      int vendor;
+
+      section_len = bfd_get_32 (abfd, p);
+      p += 4;
+      if (section_len == 0)
+	break;
+      if (section_len > len)
+	section_len = len;
+      if (section_len <= 4)
+	{
+	  _bfd_error_handler
+		(_("%pB: error: attribute section length too small: %ld"),
+		 abfd, (long) section_len);
+	  break;
+	}
+      section_len -= 4;
+      namelen = strnlen ((char *) p, section_len) + 1;
+      if (namelen >= section_len)
+	break;
+      if (std_sec && strcmp ((char *) p, std_sec) == 0)
+	vendor = OBJ_ATTR_PROC;
+      else if (strcmp ((char *) p, "gnu") == 0)
+	vendor = OBJ_ATTR_GNU;
+      else
+	{
+	  /* Other vendor section.  Ignore it.  */
+	  p += section_len;
+	  continue;
+	}
+
+      p += namelen;
+      section_len -= namelen;
+      while (section_len > 0)
+	{
+	  unsigned int tag;
+	  unsigned int val;
+	  size_t subsection_len;
+	  bfd_byte *end, *orig_p;
+
+	  orig_p = p;
+	  tag = _bfd_safe_read_leb128 (abfd, &p, false, p_end);
+	  if (p_end - p >= 4)
+	  {
+	    subsection_len = bfd_get_32 (abfd, p);
+	    p += 4;
+	  }
+	  else
+	  {
+	    p = p_end;
+	    break;
+	  }
+	  if (subsection_len > section_len)
+	    subsection_len = section_len;
+	  section_len -= subsection_len;
+	  end = orig_p + subsection_len;
+	  if (end < p)
+	    break;
+	  switch (tag)
+	    {
+	    case Tag_File:
+	      while (p < end)
+		{
+		  int type;
+		  bool ok = false;
+
+		  tag = _bfd_safe_read_leb128 (abfd, &p, false, end);
+		  type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
+		  switch (type & (ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL))
+		    {
+		    case ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL:
+		      val = _bfd_safe_read_leb128 (abfd, &p, false, end);
+		      ok = elf_add_obj_attr_int_string (abfd, vendor, tag,
+							val, (char *) p,
+							(char *) end);
+		      p += strnlen ((char *) p, end - p);
+		      if (p < end)
+			p++;
+		      break;
+		    case ATTR_TYPE_FLAG_STR_VAL:
+		      ok = elf_add_obj_attr_string (abfd, vendor, tag,
+						    (char *) p,
+						    (char *) end);
+		      p += strnlen ((char *) p, end - p);
+		      if (p < end)
+			p++;
+		      break;
+		    case ATTR_TYPE_FLAG_INT_VAL:
+		      val = _bfd_safe_read_leb128 (abfd, &p, false, end);
+		      ok = bfd_elf_add_obj_attr_int (abfd, vendor, tag, val);
+		      break;
+		    default:
+		      abort ();
+		    }
+		  if (!ok)
+		    bfd_perror (_("error adding attribute"));
+		}
+	      break;
+	    case Tag_Section:
+	    case Tag_Symbol:
+	      /* Don't have anywhere convenient to attach these.
+		 Fall through for now.  */
+	    default:
+	      /* Ignore things we don't know about.  */
+	      p = end;
+	      break;
+	    }
+	}
+    }
+}
+
 /* Parse an object attributes section.  */
 void
 _bfd_elf_parse_attributes (bfd *abfd, Elf_Internal_Shdr * hdr)
 {
-  bfd_byte *contents;
-  bfd_byte *p;
-  bfd_byte *p_end;
-  const char *std_sec;
-  ufile_ptr filesize;
-
   /* PR 17512: file: 2844a11d.  */
   if (hdr->sh_size == 0)
     return;
 
-  filesize = bfd_get_file_size (abfd);
+  ufile_ptr filesize = bfd_get_file_size (abfd);
   if (filesize != 0 && hdr->sh_size > filesize)
     {
-      /* xgettext:c-format */
       _bfd_error_handler (_("%pB: error: attribute section '%pA' too big: %#llx"),
 			  abfd, hdr->bfd_section, (long long) hdr->sh_size);
       bfd_set_error (bfd_error_invalid_operation);
       return;
     }
 
-  contents = (bfd_byte *) bfd_malloc (hdr->sh_size);
-  if (!contents)
+  bfd_byte *data = (bfd_byte *) bfd_malloc (hdr->sh_size);
+  if (!data)
     return;
-  if (!bfd_get_section_contents (abfd, hdr->bfd_section, contents, 0,
-				 hdr->sh_size))
-    {
-      free (contents);
-      return;
-    }
-  p = contents;
-  p_end = p + hdr->sh_size;
-  std_sec = get_elf_backend_data (abfd)->obj_attrs_vendor;
 
-  if (*p++ == 'A')
-    {
-      while (p_end - p >= 4)
-	{
-	  size_t len = p_end - p;
-	  size_t namelen;
-	  size_t section_len;
-	  int vendor;
-
-	  section_len = bfd_get_32 (abfd, p);
-	  p += 4;
-	  if (section_len == 0)
-	    break;
-	  if (section_len > len)
-	    section_len = len;
-	  if (section_len <= 4)
-	    {
-	      _bfd_error_handler
-		(_("%pB: error: attribute section length too small: %ld"),
-		 abfd, (long) section_len);
-	      break;
-	    }
-	  section_len -= 4;
-	  namelen = strnlen ((char *) p, section_len) + 1;
-	  if (namelen >= section_len)
-	    break;
-	  if (std_sec && strcmp ((char *) p, std_sec) == 0)
-	    vendor = OBJ_ATTR_PROC;
-	  else if (strcmp ((char *) p, "gnu") == 0)
-	    vendor = OBJ_ATTR_GNU;
-	  else
-	    {
-	      /* Other vendor section.  Ignore it.  */
-	      p += section_len;
-	      continue;
-	    }
+  if (!bfd_get_section_contents (abfd, hdr->bfd_section, data, 0, hdr->sh_size))
+    goto free_data;
 
-	  p += namelen;
-	  section_len -= namelen;
-	  while (section_len > 0)
-	    {
-	      unsigned int tag;
-	      unsigned int val;
-	      size_t subsection_len;
-	      bfd_byte *end, *orig_p;
-
-	      orig_p = p;
-	      tag = _bfd_safe_read_leb128 (abfd, &p, false, p_end);
-	      if (p_end - p >= 4)
-		{
-		  subsection_len = bfd_get_32 (abfd, p);
-		  p += 4;
-		}
-	      else
-		{
-		  p = p_end;
-		  break;
-		}
-	      if (subsection_len > section_len)
-		subsection_len = section_len;
-	      section_len -= subsection_len;
-	      end = orig_p + subsection_len;
-	      if (end < p)
-		break;
-	      switch (tag)
-		{
-		case Tag_File:
-		  while (p < end)
-		    {
-		      int type;
-		      bool ok = false;
-
-		      tag = _bfd_safe_read_leb128 (abfd, &p, false, end);
-		      type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
-		      switch (type & (ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL))
-			{
-			case ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL:
-			  val = _bfd_safe_read_leb128 (abfd, &p, false, end);
-			  ok = elf_add_obj_attr_int_string (abfd, vendor, tag,
-							    val, (char *) p,
-							    (char *) end);
-			  p += strnlen ((char *) p, end - p);
-			  if (p < end)
-			    p++;
-			  break;
-			case ATTR_TYPE_FLAG_STR_VAL:
-			  ok = elf_add_obj_attr_string (abfd, vendor, tag,
-							(char *) p,
-							(char *) end);
-			  p += strnlen ((char *) p, end - p);
-			  if (p < end)
-			    p++;
-			  break;
-			case ATTR_TYPE_FLAG_INT_VAL:
-			  val = _bfd_safe_read_leb128 (abfd, &p, false, end);
-			  ok = bfd_elf_add_obj_attr_int (abfd, vendor, tag, val);
-			  break;
-			default:
-			  abort ();
-			}
-		      if (!ok)
-			bfd_perror (_("error adding attribute"));
-		    }
-		  break;
-		case Tag_Section:
-		case Tag_Symbol:
-		  /* Don't have anywhere convenient to attach these.
-		     Fall through for now.  */
-		default:
-		  /* Ignore things we don't know about.  */
-		  p = end;
-		  break;
-		}
-	    }
-	}
-    }
-  free (contents);
+  unsigned char *cursor = data;
+
+  /* The first character is the version of the attributes.
+     Currently only version 'A' is recognised here.  */
+  if (*cursor != 'A')
+  {
+    _bfd_error_handler (_("%pB: error: unknown attributes version '%c'(%d) "
+			  "- expecting 'A'\n"), abfd, *cursor, *cursor);
+    bfd_set_error (bfd_error_wrong_format);
+    goto free_data;
+  }
+
+  ++cursor;
+
+  bfd_elf_parse_attr_section_v1 (abfd, hdr, cursor);
+
+free_data:
+  free (data);
 }
 
 /* Merge common object attributes from IBFD into OBFD.  Raise an error