PHDRS {
  CODE_RO PT_LOAD;
  MTDATA PT_LOAD FLAGS(0x04000004); ​/* Bits 24-26 MANIFEST SEGMENT 0x04 */
  GOT PT_LOAD;
  DATA PT_LOAD;
  DYN PT_DYNAMIC;
  REL PT_LOAD;
#ifdef TA_LINK_RELRO
  RELRO PT_GNU_RELRO;
#endif
}

SECTIONS {
  .plt ALIGN(4096) : {
    text_section_base = .;
    * (.plt*)
  } : CODE_RO

  .text : {
    * (.text*)
    * (EXCLUDE_FILE(*metadata.o) .rodata* .eh_frame*)
    text_section_limit = .;
  } : CODE_RO
  
  .metadata ALIGN(4096) : {
    *metadata.o (.data* .rodata*)
    * (.metadata.sentinel)
    ASSERT(SIZEOF(.metadata) != 0, "No metadata section defined.");
  } : MTDATA

  /*
    Add all data that should be read-only after relocation into GOT segment.
    The loader does not support RELRO of partial segments.
  */
  .got ALIGN(4096) : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) } : GOT
#ifdef TA_LINK_RELRO
    : RELRO
#endif

  /*
    The following data may be made RO after linking and relocation.
    We add it to GOT so that it can be covered by RELRO segment.
    This must come before the data segment, otherwise the .data* below
    would capture it.
  */
  .data.rel.ro.local : {
    *(.data.rel.ro.local*)
  } : GOT
#ifdef TA_LINK_RELRO
    : RELRO
#endif

  .data.rel.ro : {
    *(.data.rel.ro*)
  } : GOT
#ifdef TA_LINK_RELRO
    : RELRO
#endif

  INIT_ARRAY : {
    FILL(0x0)
    __init_array_start = .;
    *(.init_array)
    __init_array_end = .;
  } : GOT
#ifdef TA_LINK_RELRO
    : RELRO
#endif

  FINI_ARRAY : {
    FILL(0x0)
    __fini_array_start = .;
    *(.fini_array)
    __fini_array_end = .;
  } : GOT
#ifdef TA_LINK_RELRO
    : RELRO
#endif

  .data ALIGN(4096) : {
    data_section_base = .;
    * (EXCLUDE_FILE(*metadata.o) .data*)
    * (.bss* COMMON)
    data_section_limit = .;
  } : DATA

  .dynamic ALIGN(4096) : { *(.dynamic) } : DYN : REL

  .rela.dyn : { *(.rela.dyn) } : REL
  .rela.plt : { *(.rela.plt) } : REL
  .hash     : { *(.hash) }     : REL
  .dynsym   : { *(.dynsym) }   : REL
  .dynstr   : { *(.dynstr) }   : REL

  .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
  .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
  /DISCARD/ : { *(.ARM.exidx*) *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.init) *(.fini) }
}
