ld: add READONLY attribute for SECTIONS

Message ID 20210510144739.569421-1-luca.boccassi@gmail.com
State Superseded
Headers show
Series
  • ld: add READONLY attribute for SECTIONS
Related show

Commit Message

Nick Alcock via Binutils May 10, 2021, 2:47 p.m.
From: Luca Boccassi <luca.boccassi@microsoft.com>


Allows linker scripts to set the SEC_READONLY flag.

Before:

  3 .note.package 0000004c  0000000000000308  0000000000000308  00000308  2**2
                  CONTENTS, ALLOC, LOAD, DATA

After:

  3 .note.package 0000004c  0000000000000308  0000000000000308  00000308  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA

Linker script:

SECTIONS
{
    .note.package (READONLY) : ALIGN(4) {
        BYTE(0x04) BYTE(0x00) BYTE(0x00) BYTE(0x00) /* Length of Owner including NUL */
        BYTE(0x39) BYTE(0x00) BYTE(0x00) BYTE(0x00) /* Length of Value including NUL */
        BYTE(0x7e) BYTE(0x1a) BYTE(0xfe) BYTE(0xca) /* Note ID */
        BYTE(0x46) BYTE(0x44) BYTE(0x4f) BYTE(0x00) /* Owner: 'FDO\x00' */
        BYTE(0x7b) BYTE(0x22) BYTE(0x74) BYTE(0x79)
        BYTE(0x70) BYTE(0x65) BYTE(0x22) BYTE(0x3a)
        BYTE(0x22) BYTE(0x64) BYTE(0x65) BYTE(0x62)
        BYTE(0x22) BYTE(0x2c) BYTE(0x22) BYTE(0x6e)
        BYTE(0x61) BYTE(0x6d) BYTE(0x65) BYTE(0x22)
        BYTE(0x3a) BYTE(0x22) BYTE(0x66) BYTE(0x73)
        BYTE(0x76) BYTE(0x65) BYTE(0x72) BYTE(0x69)
        BYTE(0x74) BYTE(0x79) BYTE(0x2d) BYTE(0x75)
        BYTE(0x74) BYTE(0x69) BYTE(0x6c) BYTE(0x73)
        BYTE(0x22) BYTE(0x2c) BYTE(0x22) BYTE(0x76)
        BYTE(0x65) BYTE(0x72) BYTE(0x73) BYTE(0x69)
        BYTE(0x6f) BYTE(0x6e) BYTE(0x22) BYTE(0x3a)
        BYTE(0x22) BYTE(0x31) BYTE(0x2e) BYTE(0x33)
        BYTE(0x2d) BYTE(0x31) BYTE(0x22) BYTE(0x7d)
        BYTE(0x00) BYTE(0x00) BYTE(0x00) BYTE(0x00)
    }
}
INSERT AFTER .note.gnu.build-id;

---
 ld/ld.texi  | 2 ++
 ld/ldgram.y | 2 ++
 ld/ldlang.c | 6 ++++++
 ld/ldlang.h | 3 ++-
 ld/ldlex.l  | 1 +
 5 files changed, 13 insertions(+), 1 deletion(-)

-- 
2.29.2

Comments

Fangrui Song May 12, 2021, 5:05 a.m. | #1
On Mon, May 10, 2021 at 7:47 AM luca.boccassi--- via Binutils
<binutils@sourceware.org> wrote:
>

> From: Luca Boccassi <luca.boccassi@microsoft.com>

>

> Allows linker scripts to set the SEC_READONLY flag.

>

> Before:

>

>   3 .note.package 0000004c  0000000000000308  0000000000000308  00000308  2**2

>                   CONTENTS, ALLOC, LOAD, DATA

>

> After:

>

>   3 .note.package 0000004c  0000000000000308  0000000000000308  00000308  2**2

>                   CONTENTS, ALLOC, LOAD, READONLY, DATA

>

> Linker script:

>

> SECTIONS

> {

>     .note.package (READONLY) : ALIGN(4) {

>         BYTE(0x04) BYTE(0x00) BYTE(0x00) BYTE(0x00) /* Length of Owner including NUL */

>         BYTE(0x39) BYTE(0x00) BYTE(0x00) BYTE(0x00) /* Length of Value including NUL */

>         BYTE(0x7e) BYTE(0x1a) BYTE(0xfe) BYTE(0xca) /* Note ID */

>         BYTE(0x46) BYTE(0x44) BYTE(0x4f) BYTE(0x00) /* Owner: 'FDO\x00' */

>         BYTE(0x7b) BYTE(0x22) BYTE(0x74) BYTE(0x79)

>         BYTE(0x70) BYTE(0x65) BYTE(0x22) BYTE(0x3a)

>         BYTE(0x22) BYTE(0x64) BYTE(0x65) BYTE(0x62)

>         BYTE(0x22) BYTE(0x2c) BYTE(0x22) BYTE(0x6e)

>         BYTE(0x61) BYTE(0x6d) BYTE(0x65) BYTE(0x22)

>         BYTE(0x3a) BYTE(0x22) BYTE(0x66) BYTE(0x73)

>         BYTE(0x76) BYTE(0x65) BYTE(0x72) BYTE(0x69)

>         BYTE(0x74) BYTE(0x79) BYTE(0x2d) BYTE(0x75)

>         BYTE(0x74) BYTE(0x69) BYTE(0x6c) BYTE(0x73)

>         BYTE(0x22) BYTE(0x2c) BYTE(0x22) BYTE(0x76)

>         BYTE(0x65) BYTE(0x72) BYTE(0x73) BYTE(0x69)

>         BYTE(0x6f) BYTE(0x6e) BYTE(0x22) BYTE(0x3a)

>         BYTE(0x22) BYTE(0x31) BYTE(0x2e) BYTE(0x33)

>         BYTE(0x2d) BYTE(0x31) BYTE(0x22) BYTE(0x7d)

>         BYTE(0x00) BYTE(0x00) BYTE(0x00) BYTE(0x00)

>     }

> }

> INSERT AFTER .note.gnu.build-id;

>

> ---

>  ld/ld.texi  | 2 ++

>  ld/ldgram.y | 2 ++

>  ld/ldlang.c | 6 ++++++

>  ld/ldlang.h | 3 ++-

>  ld/ldlex.l  | 1 +

>  5 files changed, 13 insertions(+), 1 deletion(-)

>

> diff --git a/ld/ld.texi b/ld/ld.texi

> index fe653daacd7..a7f2267308d 100644

> --- a/ld/ld.texi

> +++ b/ld/ld.texi

> @@ -5440,6 +5440,8 @@ parentheses.  The following types are defined:

>  @item NOLOAD

>  The section should be marked as not loadable, so that it will not be

>  loaded into memory when the program is run.

> +@item READONLY

> +The section should be marked as read-only.

>  @item DSECT

>  @itemx COPY

>  @itemx INFO

> diff --git a/ld/ldgram.y b/ld/ldgram.y

> index dd911f46169..31e0071c6fc 100644

> --- a/ld/ldgram.y

> +++ b/ld/ldgram.y

> @@ -139,6 +139,7 @@ static int error_index;

>  %token REGION_ALIAS

>  %token LD_FEATURE

>  %token NOLOAD DSECT COPY INFO OVERLAY

> +%token READONLY

>  %token DEFINED TARGET_K SEARCH_DIR MAP ENTRY

>  %token <integer> NEXT

>  %token SIZEOF ALIGNOF ADDR LOADADDR MAX_K MIN_K

> @@ -1123,6 +1124,7 @@ type:

>         |  COPY    { sectype = noalloc_section; }

>         |  INFO    { sectype = noalloc_section; }

>         |  OVERLAY { sectype = noalloc_section; }

> +       |  READONLY { sectype = readonly_section; }

>         ;

>

>  atype:

> diff --git a/ld/ldlang.c b/ld/ldlang.c

> index 37b64c89ee1..2610be995ca 100644

> --- a/ld/ldlang.c

> +++ b/ld/ldlang.c

> @@ -2639,6 +2639,9 @@ lang_add_section (lang_statement_list_type *ptr,

>      case noalloc_section:

>        flags &= ~SEC_ALLOC;

>        break;

> +    case readonly_section:

> +      flags |= SEC_READONLY;

> +      break;

>      case noload_section:

>        flags &= ~SEC_LOAD;

>        flags |= SEC_NEVER_LOAD;

> @@ -4232,6 +4235,9 @@ map_input_to_output_sections

>             case noalloc_section:

>               flags = SEC_HAS_CONTENTS;

>               break;

> +           case readonly_section:

> +             flags |= SEC_READONLY;

> +             break;

>             case noload_section:

>               if (bfd_get_flavour (link_info.output_bfd)

>                   == bfd_target_elf_flavour)

> diff --git a/ld/ldlang.h b/ld/ldlang.h

> index 6fbe16d97d9..f68ae27b409 100644

> --- a/ld/ldlang.h

> +++ b/ld/ldlang.h

> @@ -121,7 +121,8 @@ enum section_type

>    first_overlay_section,

>    overlay_section,

>    noload_section,

> -  noalloc_section

> +  noalloc_section,

> +  readonly_section

>  };

>

>  /* This structure holds a list of program headers describing

> diff --git a/ld/ldlex.l b/ld/ldlex.l

> index c1b15263587..25b4bcaae01 100644

> --- a/ld/ldlex.l

> +++ b/ld/ldlex.l

> @@ -294,6 +294,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*

>  <BOTH,SCRIPT>"SORT_BY_INIT_PRIORITY"   { RTOKEN(SORT_BY_INIT_PRIORITY); }

>  <BOTH,SCRIPT>"SORT_NONE"               { RTOKEN(SORT_NONE); }

>  <EXPRESSION,BOTH,SCRIPT>"NOLOAD"       { RTOKEN(NOLOAD);}

> +<EXPRESSION,BOTH,SCRIPT>"READONLY"     { RTOKEN(READONLY);}

>  <EXPRESSION,BOTH,SCRIPT>"DSECT"                { RTOKEN(DSECT);}

>  <EXPRESSION,BOTH,SCRIPT>"COPY"         { RTOKEN(COPY);}

>  <EXPRESSION,BOTH,SCRIPT>"INFO"         { RTOKEN(INFO);}

> --

> 2.29.2

>


Do we need this? .note.package does not have the SHF_WRITE flag even
without the new keyword
https://sourceware.org/bugzilla/show_bug.cgi?id=26378

It is also odd to introduce a "readonly" concept instead of a "write".

Patch

diff --git a/ld/ld.texi b/ld/ld.texi
index fe653daacd7..a7f2267308d 100644
--- a/ld/ld.texi
+++ b/ld/ld.texi
@@ -5440,6 +5440,8 @@  parentheses.  The following types are defined:
 @item NOLOAD
 The section should be marked as not loadable, so that it will not be
 loaded into memory when the program is run.
+@item READONLY
+The section should be marked as read-only.
 @item DSECT
 @itemx COPY
 @itemx INFO
diff --git a/ld/ldgram.y b/ld/ldgram.y
index dd911f46169..31e0071c6fc 100644
--- a/ld/ldgram.y
+++ b/ld/ldgram.y
@@ -139,6 +139,7 @@  static int error_index;
 %token REGION_ALIAS
 %token LD_FEATURE
 %token NOLOAD DSECT COPY INFO OVERLAY
+%token READONLY
 %token DEFINED TARGET_K SEARCH_DIR MAP ENTRY
 %token <integer> NEXT
 %token SIZEOF ALIGNOF ADDR LOADADDR MAX_K MIN_K
@@ -1123,6 +1124,7 @@  type:
 	|  COPY    { sectype = noalloc_section; }
 	|  INFO    { sectype = noalloc_section; }
 	|  OVERLAY { sectype = noalloc_section; }
+	|  READONLY { sectype = readonly_section; }
 	;
 
 atype:
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 37b64c89ee1..2610be995ca 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -2639,6 +2639,9 @@  lang_add_section (lang_statement_list_type *ptr,
     case noalloc_section:
       flags &= ~SEC_ALLOC;
       break;
+    case readonly_section:
+      flags |= SEC_READONLY;
+      break;
     case noload_section:
       flags &= ~SEC_LOAD;
       flags |= SEC_NEVER_LOAD;
@@ -4232,6 +4235,9 @@  map_input_to_output_sections
 	    case noalloc_section:
 	      flags = SEC_HAS_CONTENTS;
 	      break;
+	    case readonly_section:
+	      flags |= SEC_READONLY;
+	      break;
 	    case noload_section:
 	      if (bfd_get_flavour (link_info.output_bfd)
 		  == bfd_target_elf_flavour)
diff --git a/ld/ldlang.h b/ld/ldlang.h
index 6fbe16d97d9..f68ae27b409 100644
--- a/ld/ldlang.h
+++ b/ld/ldlang.h
@@ -121,7 +121,8 @@  enum section_type
   first_overlay_section,
   overlay_section,
   noload_section,
-  noalloc_section
+  noalloc_section,
+  readonly_section
 };
 
 /* This structure holds a list of program headers describing
diff --git a/ld/ldlex.l b/ld/ldlex.l
index c1b15263587..25b4bcaae01 100644
--- a/ld/ldlex.l
+++ b/ld/ldlex.l
@@ -294,6 +294,7 @@  V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*
 <BOTH,SCRIPT>"SORT_BY_INIT_PRIORITY"	{ RTOKEN(SORT_BY_INIT_PRIORITY); }
 <BOTH,SCRIPT>"SORT_NONE"		{ RTOKEN(SORT_NONE); }
 <EXPRESSION,BOTH,SCRIPT>"NOLOAD"	{ RTOKEN(NOLOAD);}
+<EXPRESSION,BOTH,SCRIPT>"READONLY"	{ RTOKEN(READONLY);}
 <EXPRESSION,BOTH,SCRIPT>"DSECT"		{ RTOKEN(DSECT);}
 <EXPRESSION,BOTH,SCRIPT>"COPY"		{ RTOKEN(COPY);}
 <EXPRESSION,BOTH,SCRIPT>"INFO"		{ RTOKEN(INFO);}