]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
elf: Add PT_GNU_MUTABLE azanella/pt_gnu_mutable
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Tue, 4 Mar 2025 14:39:30 +0000 (11:39 -0300)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Fri, 7 Mar 2025 11:48:50 +0000 (08:48 -0300)
The section mark a memory region that should not be sealed if
GNU_PROPERTY_MEMORY_SEAL attribute is present.  PT_GNU_MUTABLE
section names start with ".gnu.mutable" and are maximum page
aligned and have a size of maximum page size.

For instance the code:

unsigned char mutable_array1[64]
__attribute__ ((section (GNU_MUTABLE_SECTION_NAME)))
   = { 0 };
unsigned char mutable_array2[32]
__attribute__ ((section (GNU_MUTABLE_SECTION_NAME)))
   = { 0 };

places both 'mutable_array1' and 'mutable_array2' on a page
aligned memory region in a size of a page (the alignment and size
can be change with -Wl,-z,max-page-size= linker option).

The linker sets the alignment and size to make it easier to
loader to avoid sealing the area (since mseal only work on
multiple of page size areas), and to simplify the userland
process to change protection of either seal the area after
initialization.

Change-Id: I1304af9ec6b5b2682a1416b2b3d8d5b2c65b9f1c
TODO: add tests.

bfd/elf.c
binutils/readelf.c
include/elf/common.h
ld/ldgram.y
ld/scripttempl/elf.sc
ld/testsuite/ld-aarch64/variant_pcs-r.d
ld/testsuite/ld-x86-64/pr27590.rd
ld/testsuite/ld-x86-64/split-by-file.rd

index 3f8bc838bfb34b367c500b916046a090b4015143..d3ef9ddd17f5d38a408ddbea202cc5ff9412c95b 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1434,6 +1434,7 @@ get_segment_type (unsigned int p_type)
     case PT_GNU_STACK: pt = "STACK"; break;
     case PT_GNU_RELRO: pt = "RELRO"; break;
     case PT_GNU_SFRAME: pt = "SFRAME"; break;
+    case PT_GNU_MUTABLE: pt = "MUTABLE"; break;
     default: pt = NULL; break;
     }
   return pt;
@@ -3416,6 +3417,9 @@ bfd_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int hdr_index)
       return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index,
                                              "sframe");
 
+    case PT_GNU_MUTABLE:
+      return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "mutable");
+
     default:
       /* Check for any processor-specific program segment types.  */
       bed = get_elf_backend_data (abfd);
@@ -4766,6 +4770,13 @@ get_program_header_size (bfd *abfd, struct bfd_link_info *info)
       ++segs;
     }
 
+  s = bfd_get_section_by_name (abfd, GNU_MUTABLE_SECTION_NAME);
+  if (s != NULL)
+    {
+      /* We need a PT_GNU_MUTABLE segment.  */
+      ++segs;
+    }
+
   s = bfd_get_section_by_name (abfd,
                               NOTE_GNU_PROPERTY_SECTION_NAME);
   if (s != NULL && s->size != 0)
@@ -5032,6 +5043,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd,
       asection *first_mbind = NULL;
       asection *dynsec, *eh_frame_hdr;
       asection *sframe;
+      asection *mutabledata;
       size_t amt;
       bfd_vma addr_mask, wrap_to = 0;  /* Bytes.  */
       bfd_size_type phdr_size;  /* Octets/bytes.  */
@@ -5571,6 +5583,23 @@ _bfd_elf_map_sections_to_segments (bfd *abfd,
          pm = &m->next;
        }
 
+      mutabledata = bfd_get_section_by_name (abfd,
+                                            GNU_MUTABLE_SECTION_NAME);
+      if (mutabledata != NULL && (mutabledata->flags & SEC_LOAD) != 0)
+       {
+         amt = sizeof (struct elf_segment_map);
+         m = bfd_zalloc (abfd, amt);
+         if (m == NULL)
+           goto error_return;
+         m->next = NULL;
+         m->p_type = PT_GNU_MUTABLE;
+         m->count = 1;
+         m->sections[0] = mutabledata->output_section;
+
+         *pm = m;
+         pm = &m->next;
+       }
+
       if (info != NULL && info->relro)
        {
          for (m = mfirst; m != NULL; m = m->next)
index dd1871d8c75a72bd0ea1ad2b5e5a3bbfd987ef98..b1f4d5c1b468700241569965deb81e0b7c3d7b9c 100644 (file)
@@ -5483,6 +5483,7 @@ get_os_specific_segment_type (Filedata * filedata, unsigned long p_type)
     case PT_GNU_RELRO:         return "GNU_RELRO";
     case PT_GNU_PROPERTY:      return "GNU_PROPERTY";
     case PT_GNU_SFRAME:        return "GNU_SFRAME";
+    case PT_GNU_MUTABLE:       return "GNU_MUTABLE";
 
     case PT_OPENBSD_MUTABLE:   return "OPENBSD_MUTABLE";
     case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
index fd032d1e03ed5b19f84fda4a8f1a9ecb14867de3..4e68f2ca9611e483c5f3cee4cb11ccdacd7baa8a 100644 (file)
 #define PT_GNU_MBIND_LO (PT_LOOS + 0x474e555)
 #define PT_GNU_MBIND_HI (PT_GNU_MBIND_LO + PT_GNU_MBIND_NUM - 1)
 
+/* Memory sealing mutable section */
+#define PT_GNU_MUTABLE (PT_GNU_MBIND_HI + 1) /* Mutable section.  */
+
 #define PT_LOPROC      0x70000000      /* Processor-specific */
 #define PT_HIPROC      0x7FFFFFFF      /* Processor-specific */
 
 
 #define NOTE_GNU_PROPERTY_SECTION_NAME ".note.gnu.property"
 #define GNU_BUILD_ATTRS_SECTION_NAME   ".gnu.build.attributes"
+#define GNU_MUTABLE_SECTION_NAME       ".gnu.mutable"
 
 /* Values used in GNU .note.gnu.property notes (NT_GNU_PROPERTY_TYPE_0).  */
 #define GNU_PROPERTY_STACK_SIZE                        1
index 6635e598562e79b6c1bcd946f93f7087dac9f761..cbeff7fb0dbb213a08f0fba5436961ef88082508 100644 (file)
@@ -1312,6 +1312,8 @@ phdr_type:
                            $$ = exp_intop (0x6474e552);
                          else if (strcmp (s, "PT_GNU_PROPERTY") == 0)
                            $$ = exp_intop (0x6474e553);
+                         else if (strcmp (s, "PT_GNU_MUTABLE") == 0)
+                           $$ = exp_intop (0x6474f555);
                          else
                            {
                              einfo (_("\
index be8d19fcf1112bc42741d102c3f292dd0cc4512a..5eadc18aa98e0b21078f7a39218f2ce6960745ff 100644 (file)
@@ -244,7 +244,7 @@ RELA_IPLT=".rela.iplt    ${RELOCATING-0} :
 DYNAMIC=".dynamic      ${RELOCATING-0} : { *(.dynamic) }"
 RODATA=".${RODATA_NAME}       ${RELOCATING-0} : { *(.${RODATA_NAME}${RELOCATING+ .${RODATA_NAME}.* .gnu.linkonce.r.*}) }"
 DATARELRO=".data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }"
-DISCARDED="/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.gnu_object_only) }"
+DISCARDED="/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.gnu_object_only) *(.gnu.mutable) }"
 if test -z "${NO_SMALL_DATA}"; then
   SBSS=".${SBSS_NAME}         ${RELOCATING-0} :
   {
@@ -855,6 +855,12 @@ cat <<EOF
   ${DATA_SDATA-${SDATA}}
   ${DATA_SDATA-${OTHER_SDATA_SECTIONS}}
 
+  .gnu.mutable ${RELOCATING-0} : ${RELOCATING+ALIGN(${MAXPAGESIZE})}
+  {
+    *(.gnu.mutable)
+    . = ALIGN(. != 0 ? CONSTANT (MAXPAGESIZE): 1);
+  }
+
   ${RELOCATING+${SYMBOL_ABI_ALIGNMENT+. = ALIGN(${SYMBOL_ABI_ALIGNMENT});}}
   ${RELOCATING+${DATA_END_SYMBOLS-${CREATE_SHLIB+PROVIDE (}$(def_symbol "_edata")${CREATE_SHLIB+)};
   PROVIDE ($(def_symbol "edata"));}}
index 2651a68c935fb6ebf72725bae70e1d3953c90c20..25b800080be585229da672466d17acf9397a2ec6 100644 (file)
@@ -5,56 +5,57 @@
 
 Relocation section '\.rela\.text' at offset .* contains 24 entries:
     Offset             Info             Type               Symbol's Value  Symbol's Name \+ Addend
-0000000000000000  000000180000011b R_AARCH64_CALL26       0000000000000000 f_spec_global_default_def \+ 0
-0000000000000004  000000110000011b R_AARCH64_CALL26       0000000000000000 f_spec_global_default_undef \+ 0
-0000000000000008  000000120000011b R_AARCH64_CALL26       0000000000000000 f_spec_global_hidden_def \+ 0
-0000000000000010  000000170000011b R_AARCH64_CALL26       0000000000000000 f_base_global_default_def \+ 0
-0000000000000014  000000100000011b R_AARCH64_CALL26       0000000000000000 f_base_global_default_undef \+ 0
-0000000000000018  000000150000011b R_AARCH64_CALL26       0000000000000000 f_base_global_hidden_def \+ 0
-0000000000000020  000000140000011b R_AARCH64_CALL26       f_spec_global_default_ifunc\(\) f_spec_global_default_ifunc \+ 0
-0000000000000024  000000160000011b R_AARCH64_CALL26       f_spec_global_hidden_ifunc\(\) f_spec_global_hidden_ifunc \+ 0
-0000000000000028  000000060000011b R_AARCH64_CALL26       f_spec_local_ifunc\(\) f_spec_local_ifunc \+ 0
-000000000000002c  000000190000011b R_AARCH64_CALL26       f_base_global_default_ifunc\(\) f_base_global_default_ifunc \+ 0
-0000000000000030  000000130000011b R_AARCH64_CALL26       f_base_global_hidden_ifunc\(\) f_base_global_hidden_ifunc \+ 0
-0000000000000034  000000070000011b R_AARCH64_CALL26       f_base_local_ifunc\(\) f_base_local_ifunc \+ 0
-0000000000000038  000000180000011b R_AARCH64_CALL26       0000000000000000 f_spec_global_default_def \+ 0
-000000000000003c  000000110000011b R_AARCH64_CALL26       0000000000000000 f_spec_global_default_undef \+ 0
-0000000000000040  000000120000011b R_AARCH64_CALL26       0000000000000000 f_spec_global_hidden_def \+ 0
-0000000000000048  000000170000011b R_AARCH64_CALL26       0000000000000000 f_base_global_default_def \+ 0
-000000000000004c  000000100000011b R_AARCH64_CALL26       0000000000000000 f_base_global_default_undef \+ 0
-0000000000000050  000000150000011b R_AARCH64_CALL26       0000000000000000 f_base_global_hidden_def \+ 0
-0000000000000058  000000140000011b R_AARCH64_CALL26       f_spec_global_default_ifunc\(\) f_spec_global_default_ifunc \+ 0
-000000000000005c  000000160000011b R_AARCH64_CALL26       f_spec_global_hidden_ifunc\(\) f_spec_global_hidden_ifunc \+ 0
-0000000000000060  0000000c0000011b R_AARCH64_CALL26       f_spec_local2_ifunc\(\) f_spec_local2_ifunc \+ 0
-0000000000000064  000000190000011b R_AARCH64_CALL26       f_base_global_default_ifunc\(\) f_base_global_default_ifunc \+ 0
-0000000000000068  000000130000011b R_AARCH64_CALL26       f_base_global_hidden_ifunc\(\) f_base_global_hidden_ifunc \+ 0
-000000000000006c  0000000d0000011b R_AARCH64_CALL26       f_base_local2_ifunc\(\) f_base_local2_ifunc \+ 0
+0000000000000000  000000190000011b R_AARCH64_CALL26       0000000000000000 f_spec_global_default_def \+ 0
+0000000000000004  000000120000011b R_AARCH64_CALL26       0000000000000000 f_spec_global_default_undef \+ 0
+0000000000000008  000000130000011b R_AARCH64_CALL26       0000000000000000 f_spec_global_hidden_def \+ 0
+0000000000000010  000000180000011b R_AARCH64_CALL26       0000000000000000 f_base_global_default_def \+ 0
+0000000000000014  000000110000011b R_AARCH64_CALL26       0000000000000000 f_base_global_default_undef \+ 0
+0000000000000018  000000160000011b R_AARCH64_CALL26       0000000000000000 f_base_global_hidden_def \+ 0
+0000000000000020  000000150000011b R_AARCH64_CALL26       f_spec_global_default_ifunc\(\) f_spec_global_default_ifunc \+ 0
+0000000000000024  000000170000011b R_AARCH64_CALL26       f_spec_global_hidden_ifunc\(\) f_spec_global_hidden_ifunc \+ 0
+0000000000000028  000000070000011b R_AARCH64_CALL26       f_spec_local_ifunc\(\) f_spec_local_ifunc \+ 0
+000000000000002c  0000001a0000011b R_AARCH64_CALL26       f_base_global_default_ifunc\(\) f_base_global_default_ifunc \+ 0
+0000000000000030  000000140000011b R_AARCH64_CALL26       f_base_global_hidden_ifunc\(\) f_base_global_hidden_ifunc \+ 0
+0000000000000034  000000080000011b R_AARCH64_CALL26       f_base_local_ifunc\(\) f_base_local_ifunc \+ 0
+0000000000000038  000000190000011b R_AARCH64_CALL26       0000000000000000 f_spec_global_default_def \+ 0
+000000000000003c  000000120000011b R_AARCH64_CALL26       0000000000000000 f_spec_global_default_undef \+ 0
+0000000000000040  000000130000011b R_AARCH64_CALL26       0000000000000000 f_spec_global_hidden_def \+ 0
+0000000000000048  000000180000011b R_AARCH64_CALL26       0000000000000000 f_base_global_default_def \+ 0
+000000000000004c  000000110000011b R_AARCH64_CALL26       0000000000000000 f_base_global_default_undef \+ 0
+0000000000000050  000000160000011b R_AARCH64_CALL26       0000000000000000 f_base_global_hidden_def \+ 0
+0000000000000058  000000150000011b R_AARCH64_CALL26       f_spec_global_default_ifunc\(\) f_spec_global_default_ifunc \+ 0
+000000000000005c  000000170000011b R_AARCH64_CALL26       f_spec_global_hidden_ifunc\(\) f_spec_global_hidden_ifunc \+ 0
+0000000000000060  0000000d0000011b R_AARCH64_CALL26       f_spec_local2_ifunc\(\) f_spec_local2_ifunc \+ 0
+0000000000000064  0000001a0000011b R_AARCH64_CALL26       f_base_global_default_ifunc\(\) f_base_global_default_ifunc \+ 0
+0000000000000068  000000140000011b R_AARCH64_CALL26       f_base_global_hidden_ifunc\(\) f_base_global_hidden_ifunc \+ 0
+000000000000006c  0000000e0000011b R_AARCH64_CALL26       f_base_local2_ifunc\(\) f_base_local2_ifunc \+ 0
 
-Symbol table '\.symtab' contains 26 entries:
+Symbol table '\.symtab' contains 27 entries:
    Num:    Value          Size Type    Bind   Vis      Ndx Name
      0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
      1: 0000000000000000     0 SECTION LOCAL  DEFAULT    1.*
      2: 0000000000000000     0 SECTION LOCAL  DEFAULT    3.*
      3: 0000000000000000     0 SECTION LOCAL  DEFAULT    4.*
-     4: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS .*variant_pcs-1\.o
-     5: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local
-     6: 0000000000000000     0 IFUNC   LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local_ifunc
-     7: 0000000000000000     0 IFUNC   LOCAL  DEFAULT    1 f_base_local_ifunc
-     8: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT    1 f_base_local
-     9: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT    1 \$x
-    10: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS .*variant_pcs-2\.o
-    11: 0000000000000038     0 NOTYPE  LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local2
-    12: 0000000000000038     0 IFUNC   LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local2_ifunc
-    13: 0000000000000038     0 IFUNC   LOCAL  DEFAULT    1 f_base_local2_ifunc
-    14: 0000000000000038     0 NOTYPE  LOCAL  DEFAULT    1 f_base_local2
-    15: 0000000000000038     0 NOTYPE  LOCAL  DEFAULT    1 \$x
-    16: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND f_base_global_default_undef
-    17: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT \[VARIANT_PCS\]   UND f_spec_global_default_undef
-    18: 0000000000000000     0 NOTYPE  GLOBAL HIDDEN  \[VARIANT_PCS\]     1 f_spec_global_hidden_def
-    19: 0000000000000000     0 IFUNC   GLOBAL HIDDEN     1 f_base_global_hidden_ifunc
-    20: 0000000000000000     0 IFUNC   GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_ifunc
-    21: 0000000000000000     0 NOTYPE  GLOBAL HIDDEN     1 f_base_global_hidden_def
-    22: 0000000000000000     0 IFUNC   GLOBAL HIDDEN  \[VARIANT_PCS\]     1 f_spec_global_hidden_ifunc
-    23: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT    1 f_base_global_default_def
-    24: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_def
-    25: 0000000000000000     0 IFUNC   GLOBAL DEFAULT    1 f_base_global_default_ifunc
+     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    5.*
+     5: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS .*variant_pcs-1\.o
+     6: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local
+     7: 0000000000000000     0 IFUNC   LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local_ifunc
+     8: 0000000000000000     0 IFUNC   LOCAL  DEFAULT    1 f_base_local_ifunc
+     9: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT    1 f_base_local
+    10: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT    1 \$x
+    11: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS .*variant_pcs-2\.o
+    12: 0000000000000038     0 NOTYPE  LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local2
+    13: 0000000000000038     0 IFUNC   LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local2_ifunc
+    14: 0000000000000038     0 IFUNC   LOCAL  DEFAULT    1 f_base_local2_ifunc
+    15: 0000000000000038     0 NOTYPE  LOCAL  DEFAULT    1 f_base_local2
+    16: 0000000000000038     0 NOTYPE  LOCAL  DEFAULT    1 \$x
+    17: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND f_base_global_default_undef
+    18: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT \[VARIANT_PCS\]   UND f_spec_global_default_undef
+    19: 0000000000000000     0 NOTYPE  GLOBAL HIDDEN  \[VARIANT_PCS\]     1 f_spec_global_hidden_def
+    20: 0000000000000000     0 IFUNC   GLOBAL HIDDEN     1 f_base_global_hidden_ifunc
+    21: 0000000000000000     0 IFUNC   GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_ifunc
+    22: 0000000000000000     0 NOTYPE  GLOBAL HIDDEN     1 f_base_global_hidden_def
+    23: 0000000000000000     0 IFUNC   GLOBAL HIDDEN  \[VARIANT_PCS\]     1 f_spec_global_hidden_ifunc
+    24: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT    1 f_base_global_default_def
+    25: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_def
+    26: 0000000000000000     0 IFUNC   GLOBAL DEFAULT    1 f_base_global_default_ifunc
index 55ed17d6f7e46031eb01318c916d8b034bc9f814..5c5710d7d73f3c1ab5fc190f8faa56ecd8a138dc 100644 (file)
@@ -1,11 +1,11 @@
 #...
   \[[ 0-9]+\] .gnu.debuglto_.debug_info PROGBITS +0+ [0-9a-f]+ 0+42 00 +E  0 +0  1
-  \[[ 0-9]+\] .rela.gnu.debuglto_.debug_info RELA +0+ [0-9a-f]+ 0+f0 18 +I 26  17  8
+  \[[ 0-9]+\] .rela.gnu.debuglto_.debug_info RELA +0+ [0-9a-f]+ 0+f0 18 +I 27  18  8
   \[[ 0-9]+\] .gnu.debuglto_.debug_abbrev PROGBITS +0+ [0-9a-f]+ 0+26 00 +E  0 +0  1
   \[[ 0-9]+\] .gnu.debuglto_.debug_macro PROGBITS +0+ [0-9a-f]+ 0+2a 00 +E  0 +0  1
-  \[[ 0-9]+\] .rela.gnu.debuglto_.debug_macro RELA +0+ [0-9a-f]+ 0+60 18 +I 26  20  8
+  \[[ 0-9]+\] .rela.gnu.debuglto_.debug_macro RELA +0+ [0-9a-f]+ 0+60 18 +I 27  21  8
   \[[ 0-9]+\] .gnu.debuglto_.debug_macro PROGBITS +0+ [0-9a-f]+ 0+10 00  GE  0 +0  1
-  \[[ 0-9]+\] .rela.gnu.debuglto_.debug_macro RELA +0+ [0-9a-f]+ 0+30 18  IG 26  22  8
+  \[[ 0-9]+\] .rela.gnu.debuglto_.debug_macro RELA +0+ [0-9a-f]+ 0+30 18  IG 27  23  8
   \[[ 0-9]+\] .gnu.debuglto_.debug_line PROGBITS +0+ [0-9a-f]+ 0+8a 00 +E  0 +0  1
   \[[ 0-9]+\] .gnu.debuglto_.debug_str PROGBITS +0+ [0-9a-f]+ 0+15c 01 MSE  0 +0  1
 #pass
index 4e3e74a2e759dc2d0739b2253b6a5564e1159b24..7f9b732541828f2b23718ef6f882e18a4c4bbcfd 100644 (file)
@@ -1,4 +1,4 @@
-There are 9 section headers, starting at offset .*:
+There are 10 section headers, starting at offset .*:
 
 Section Headers:
   \[Nr\] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
@@ -6,10 +6,11 @@ Section Headers:
   \[ 1\] .text             PROGBITS        0000000000000000 000040 000000 00  AX  0   0  1
   \[ 2\] .foo              PROGBITS        0000000000000000 000040 000003 00 AXl  0   0  1
   \[ 3\] .data             PROGBITS        0000000000000000 000043 000000 00  WA  0   0  1
-  \[ 4\] .bss              NOBITS          0000000000000000 000043 000000 00  WA  0   0  1
-  \[ 5\] .foo.0            PROGBITS        0000000000000003 000043 000003 00 AXl  0   0  1
-  \[ 6\] .symtab           SYMTAB          0000000000000000 [0-9a-f]+ [0-9a-f]+ 18      7   [0-9]  8
-  \[ 7\] .strtab           STRTAB          0000000000000000 [0-9a-f]+ [0-9a-f]+ 00      0   0  1
-  \[ 8\] .shstrtab         STRTAB          0000000000000000 [0-9a-f]+ 000038 00      0   0  1
+  \[ 4\] .gnu.mutable      PROGBITS        0000000000000000 000043 000000 00   W  0   0  1
+  \[ 5\] .bss              NOBITS          0000000000000000 000043 000000 00  WA  0   0  1
+  \[ 6\] .foo.0            PROGBITS        0000000000000003 000043 000003 00 AXl  0   0  1
+  \[ 7\] .symtab           SYMTAB          0000000000000000 [0-9a-f]+ [0-9a-f]+ 18      7   [0-9]  8
+  \[ 8\] .strtab           STRTAB          0000000000000000 [0-9a-f]+ [0-9a-f]+ 00      0   0  1
+  \[ 9\] .shstrtab         STRTAB          0000000000000000 [0-9a-f]+ 000045 00      0   0  1
 Key to Flags:
 #pass