LD: Support fixed-size sections some psABIs may require
authorMaciej W. Rozycki <macro@mips.com>
Mon, 19 Feb 2018 18:38:41 +0000 (18:38 +0000)
committerMaciej W. Rozycki <macro@mips.com>
Mon, 19 Feb 2018 18:38:41 +0000 (18:38 +0000)
Define a SEC_FIXED_SIZE section flag for target backends to use for
output sections whose size has been fixed in the psABI.  The size of
such sections will not be changed anyhow by the generic linker and it is
up to the target backend to get their size right.

bfd/
* section.c (SEC_FIXED_SIZE): New macro.
* bfd-in2.h: Regenerate.

ld/
* ldlang.c (insert_pad): Do not change output section's size if
SEC_FIXED_SIZE is set in the flags.
(size_input_section): Likewise.
(lang_size_sections_1): Likewise.
(lang_reset_memory_regions): Likewise.

bfd/ChangeLog
bfd/bfd-in2.h
bfd/section.c
ld/ChangeLog
ld/ldlang.c

index e4c33c76d55055ec5ff97c3bb0e52bcb9738d0ad..b84a3d15972cf0a152117d67eb75530625be6128 100644 (file)
@@ -1,3 +1,8 @@
+2018-02-19  Maciej W. Rozycki  <macro@mips.com>
+
+       * section.c (SEC_FIXED_SIZE): New macro.
+       * bfd-in2.h: Regenerate.
+
 2018-02-19  Maciej W. Rozycki  <macro@mips.com>
 
        * section.c (SEC_HAS_GOT_REF): Remove macro.
index 2901488ef1dabbdd9e45bc5f439e8f7663c4d572..9742c1ac7fe1c0077b4cb8066d83c9d3c1d9feac 100644 (file)
@@ -1342,6 +1342,11 @@ typedef struct bfd_section
   /* The section contains thread local data.  */
 #define SEC_THREAD_LOCAL                0x400
 
+  /* The section's size is fixed.  Generic linker code will not
+     recalculate it and it is up to whoever has set this flag to
+     get the size right.  */
+#define SEC_FIXED_SIZE                  0x800
+
   /* The section contains common symbols (symbols may be defined
      multiple times, the value of a symbol is the amount of
      space it requires, and the largest symbol value is the one
index de4ca3ad9e87aea05560ebd44f692294bd918145..6aa18d5db3c6c984bc8bf793d7f41425da5b1655 100644 (file)
@@ -221,6 +221,11 @@ CODE_FRAGMENT
 .  {* The section contains thread local data.  *}
 .#define SEC_THREAD_LOCAL                0x400
 .
+.  {* The section's size is fixed.  Generic linker code will not
+.     recalculate it and it is up to whoever has set this flag to
+.     get the size right.  *}
+.#define SEC_FIXED_SIZE                  0x800
+.
 .  {* The section contains common symbols (symbols may be defined
 .     multiple times, the value of a symbol is the amount of
 .     space it requires, and the largest symbol value is the one
index 84c6d3e9dd50bbdc3b642298c8db157c91b5efe5..4f5cd5fe00140a6bc7511842dca401de9c49231f 100644 (file)
@@ -1,3 +1,11 @@
+2018-02-19  Maciej W. Rozycki  <macro@mips.com>
+
+       * ldlang.c (insert_pad): Do not change output section's size if
+       SEC_FIXED_SIZE is set in the flags.
+       (size_input_section): Likewise.
+       (lang_size_sections_1): Likewise.
+       (lang_reset_memory_regions): Likewise.
+
 2018-02-19  Alan Modra  <amodra@gmail.com>
 
        * ldmisc.c (vfinfo) Handle %pI, %pR, %pS and %pT in place of
index 1a6f2cf6c1fb519bb20a47fd8eeda296c293f8d9..54019826f60b758c94e1209e6eccc0a5b79bd74d 100644 (file)
@@ -4675,8 +4675,9 @@ insert_pad (lang_statement_union_type **ptr,
     }
   pad->padding_statement.output_offset = dot - output_section->vma;
   pad->padding_statement.size = alignment_needed;
-  output_section->size = TO_SIZE (dot + TO_ADDR (alignment_needed)
-                                 - output_section->vma);
+  if (!(output_section->flags & SEC_FIXED_SIZE))
+    output_section->size = TO_SIZE (dot + TO_ADDR (alignment_needed)
+                                   - output_section->vma);
 }
 
 /* Work out how much this section will move the dot point.  */
@@ -4725,7 +4726,8 @@ size_input_section
 
       /* Mark how big the output section must be to contain this now.  */
       dot += TO_ADDR (i->size);
-      o->size = TO_SIZE (dot - o->vma);
+      if (!(o->flags & SEC_FIXED_SIZE))
+       o->size = TO_SIZE (dot - o->vma);
     }
 
   return dot;
@@ -5079,7 +5081,8 @@ lang_size_sections_1
                bfd_set_section_vma (os->bfd_section->owner,
                                     os->bfd_section,
                                     bfd_section_vma (input->owner, input));
-               os->bfd_section->size = input->size;
+               if (!(os->bfd_section->flags & SEC_FIXED_SIZE))
+                 os->bfd_section->size = input->size;
                break;
              }
 
@@ -5194,7 +5197,9 @@ lang_size_sections_1
                          + os->block_value - 1)
                         & - (bfd_vma) os->block_value);
 
-               os->bfd_section->size = TO_SIZE (after - os->bfd_section->vma);
+               if (!(os->bfd_section->flags & SEC_FIXED_SIZE))
+                 os->bfd_section->size = TO_SIZE (after
+                                                  - os->bfd_section->vma);
              }
 
            /* Set section lma.  */
@@ -5379,8 +5384,10 @@ lang_size_sections_1
            if (size < TO_SIZE ((unsigned) 1))
              size = TO_SIZE ((unsigned) 1);
            dot += TO_ADDR (size);
-           output_section_statement->bfd_section->size
-             = TO_SIZE (dot - output_section_statement->bfd_section->vma);
+           if (!(output_section_statement->bfd_section->flags
+                 & SEC_FIXED_SIZE))
+             output_section_statement->bfd_section->size
+               = TO_SIZE (dot - output_section_statement->bfd_section->vma);
 
          }
          break;
@@ -5395,8 +5402,10 @@ lang_size_sections_1
              output_section_statement->bfd_section;
            size = bfd_get_reloc_size (s->reloc_statement.howto);
            dot += TO_ADDR (size);
-           output_section_statement->bfd_section->size
-             = TO_SIZE (dot - output_section_statement->bfd_section->vma);
+           if (!(output_section_statement->bfd_section->flags
+                 & SEC_FIXED_SIZE))
+             output_section_statement->bfd_section->size
+               = TO_SIZE (dot - output_section_statement->bfd_section->vma);
          }
          break;
 
@@ -6764,7 +6773,8 @@ lang_reset_memory_regions (void)
     {
       /* Save the last size for possible use by bfd_relax_section.  */
       o->rawsize = o->size;
-      o->size = 0;
+      if (!(o->flags & SEC_FIXED_SIZE))
+       o->size = 0;
     }
 }