-/* Get the size of the program header.
-
- If this is called by the linker before any of the section VMA's are set, it
- can't calculate the correct value for a strange memory layout. This only
- happens when SIZEOF_HEADERS is used in a linker script. In this case,
- SORTED_HDRS is NULL and we assume the normal scenario of one text and one
- data segment (exclusive of .interp and .dynamic).
-
- ??? User written scripts must either not use SIZEOF_HEADERS, or assume there
- will be two segments. */
-
-static bfd_size_type
-get_program_header_size (bfd *abfd)
-{
- size_t segs;
- asection *s;
- const struct elf_backend_data *bed = get_elf_backend_data (abfd);
-
- /* We can't return a different result each time we're called. */
- if (elf_tdata (abfd)->program_header_size != 0)
- return elf_tdata (abfd)->program_header_size;
-
- if (elf_tdata (abfd)->segment_map != NULL)
- {
- struct elf_segment_map *m;
-
- segs = 0;
- for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
- ++segs;
- elf_tdata (abfd)->program_header_size = segs * bed->s->sizeof_phdr;
- return elf_tdata (abfd)->program_header_size;
- }
-
- /* Assume we will need exactly two PT_LOAD segments: one for text
- and one for data. */
- segs = 2;
-
- s = bfd_get_section_by_name (abfd, ".interp");
- if (s != NULL && (s->flags & SEC_LOAD) != 0)
- {
- /* If we have a loadable interpreter section, we need a
- PT_INTERP segment. In this case, assume we also need a
- PT_PHDR segment, although that may not be true for all
- targets. */
- segs += 2;
- }
-
- if (bfd_get_section_by_name (abfd, ".dynamic") != NULL)
- {
- /* We need a PT_DYNAMIC segment. */
- ++segs;
- }
-
- if (elf_tdata (abfd)->eh_frame_hdr)
- {
- /* We need a PT_GNU_EH_FRAME segment. */
- ++segs;
- }
-
- if (elf_tdata (abfd)->stack_flags)
- {
- /* We need a PT_GNU_STACK segment. */
- ++segs;
- }
-
- if (elf_tdata (abfd)->relro)
- {
- /* We need a PT_GNU_RELRO segment. */
- ++segs;
- }
-
- for (s = abfd->sections; s != NULL; s = s->next)
- {
- if ((s->flags & SEC_LOAD) != 0
- && strncmp (s->name, ".note", 5) == 0)
- {
- /* We need a PT_NOTE segment. */
- ++segs;
- }
- }
-
- for (s = abfd->sections; s != NULL; s = s->next)
- {
- if (s->flags & SEC_THREAD_LOCAL)
- {
- /* We need a PT_TLS segment. */
- ++segs;
- break;
- }
- }
-
- /* Let the backend count up any program headers it might need. */
- if (bed->elf_backend_additional_program_headers)
- {
- int a;
-
- a = (*bed->elf_backend_additional_program_headers) (abfd);
- if (a == -1)
- abort ();
- segs += a;
- }
-
- elf_tdata (abfd)->program_header_size = segs * bed->s->sizeof_phdr;
- return elf_tdata (abfd)->program_header_size;
-}
-