@@ -2818,6 +2818,8 @@ char *bfd_demangle (bfd *, const char *, int);
asymbol *bfd_group_signature (asection *group, asymbol **isympp);
+bool bfd_is_special_readonly_section (bfd *abfd, const char *name);
+
/* Extracted from bfdio.c. */
bfd_size_type bfd_read (void *, bfd_size_type, bfd *)
ATTRIBUTE_WARN_UNUSED_RESULT;
@@ -3133,3 +3133,27 @@ bfd_group_signature (asection *group, asymbol **isympp)
}
return NULL;
}
+
+/*
+FUNCTION
+ bfd_is_special_readonly_section
+
+SYNOPSIS
+ bool bfd_is_special_readonly_section (bfd *abfd, const char *name);
+
+DESCRIPTION
+ Return true if the BFD section of NAME is a special readonly
+ section.
+*/
+
+bool
+bfd_is_special_readonly_section (bfd *abfd, const char *name)
+{
+ if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
+ {
+ elf_backend_data *bed = get_elf_backend_data (abfd);
+ return bed->is_special_readonly_section (abfd, name);
+ }
+
+ return false;
+}
@@ -1127,6 +1127,11 @@ struct elf_backend_data
const struct bfd_elf_special_section * (*get_sec_type_attr)
(bfd *, asection *);
+ /* A function that returns true if the given BFD section of name
+ is a special readonly section. */
+ bool (*is_special_readonly_section)
+ (bfd *, const char*);
+
/* A function to handle unusual program segment types when creating BFD
sections from ELF program segments. */
bool (*elf_backend_section_from_phdr)
@@ -2542,6 +2547,8 @@ extern const struct bfd_elf_special_section *_bfd_elf_get_special_section
ATTRIBUTE_HIDDEN;
extern const struct bfd_elf_special_section *_bfd_elf_get_sec_type_attr
(bfd *, asection *) ATTRIBUTE_HIDDEN;
+extern bool _bfd_elf_is_special_readonly_section
+ (bfd *, const char *) ATTRIBUTE_HIDDEN;
extern bool _bfd_elf_link_hide_sym_by_version
(struct bfd_link_info *, struct elf_link_hash_entry *) ATTRIBUTE_HIDDEN;
@@ -3275,32 +3275,31 @@ _bfd_elf_get_special_section (const char *name,
return NULL;
}
-const struct bfd_elf_special_section *
-_bfd_elf_get_sec_type_attr (bfd *abfd, asection *sec)
+static const struct bfd_elf_special_section *
+elf_get_special_section (bfd *abfd, const char *name,
+ unsigned int use_rela_p)
{
int i;
const struct bfd_elf_special_section *spec;
elf_backend_data *bed;
/* See if this is one of the special sections. */
- if (sec->name == NULL)
+ if (name == NULL)
return NULL;
bed = get_elf_backend_data (abfd);
spec = bed->special_sections;
if (spec)
{
- spec = _bfd_elf_get_special_section (sec->name,
- bed->special_sections,
- sec->use_rela_p);
+ spec = _bfd_elf_get_special_section (name, spec, use_rela_p);
if (spec != NULL)
return spec;
}
- if (sec->name[0] != '.')
+ if (name[0] != '.')
return NULL;
- i = sec->name[1] - 'b';
+ i = name[1] - 'b';
if (i < 0 || i > 'z' - 'b')
return NULL;
@@ -3309,7 +3308,25 @@ _bfd_elf_get_sec_type_attr (bfd *abfd, asection *sec)
if (spec == NULL)
return NULL;
- return _bfd_elf_get_special_section (sec->name, spec, sec->use_rela_p);
+ return _bfd_elf_get_special_section (name, spec, use_rela_p);
+}
+
+const struct bfd_elf_special_section *
+_bfd_elf_get_sec_type_attr (bfd *abfd, asection *sec)
+{
+ return elf_get_special_section (abfd, sec->name, sec->use_rela_p);
+}
+
+bool
+_bfd_elf_is_special_readonly_section (bfd *abfd, const char *name)
+{
+ elf_backend_data *bed;
+ const struct bfd_elf_special_section *spec;
+ bed = get_elf_backend_data (abfd);
+ spec = elf_get_special_section (abfd, name, bed->default_use_rela_p);
+ if (spec == NULL)
+ return false;
+ return (spec->attr & SHF_WRITE) == 0;
}
bool
@@ -443,6 +443,10 @@
#ifndef elf_backend_get_sec_type_attr
#define elf_backend_get_sec_type_attr _bfd_elf_get_sec_type_attr
#endif
+#ifndef elf_backend_is_special_readonly_section
+#define elf_backend_is_special_readonly_section \
+ _bfd_elf_is_special_readonly_section
+#endif
#ifndef elf_backend_section_from_phdr
#define elf_backend_section_from_phdr _bfd_elf_make_section_from_phdr
#endif
@@ -872,6 +876,7 @@ static const struct elf_backend_data elfNN_bed =
elf_backend_section_from_shdr,
elf_backend_section_flags,
elf_backend_get_sec_type_attr,
+ elf_backend_is_special_readonly_section,
elf_backend_section_from_phdr,
elf_backend_fake_sections,
elf_backend_section_from_bfd_section,
@@ -2604,7 +2604,10 @@ get_os_init_flag (lang_output_section_statement_type * os)
{
case readonly_section: return SEC_READONLY;
case noload_section: return SEC_NEVER_LOAD;
- default: break;
+ default:
+ if (bfd_is_special_readonly_section (link_info.output_bfd,
+ os->name))
+ return SEC_READONLY;
}
return 0;
new file mode 100644
@@ -0,0 +1,9 @@
+#name: .rodata section attributes
+#ld: -Tflags2.ld
+#readelf: -S --wide
+
+#...
+Section Headers:
+#...
+ \[[ 0-9]+\] \.rodata.*[ \t]+PROGBITS[ \t0-9a-f]+ A .*
+#pass
new file mode 100644
@@ -0,0 +1 @@
+SECTIONS { .rodata : ALIGN(4) { __crc_hello = .; LONG(0x05d25769); } }
new file mode 100644
@@ -0,0 +1,6 @@
+ .text
+ .globl start
+ .type start, %function
+start:
+ .byte 0
+ .section .note.GNU-stack, "", %progbits