so, number of segments will be wrong if there is .interp but no .dynamic. why don't we ignore the conventrion set in this file and ++segs when adding those segments?
On Thu, Jul 12, 2018 at 09:38:16PM +0000, Joerg Sonnenberger wrote: > Module Name: src > Committed By: joerg > Date: Thu Jul 12 21:38:16 UTC 2018 > > Modified Files: > src/external/gpl3/binutils.old/dist/bfd: elf.c > src/external/gpl3/binutils/dist/bfd: elf.c > > Log Message: > PT_PHDR is useful without PT_INTERP, i.e. for static PIE. It removes the > need for platform-specific computations of _DYNAMIC and friends. > > > To generate a diff of this commit: > cvs rdiff -u -r1.5 -r1.6 src/external/gpl3/binutils.old/dist/bfd/elf.c > cvs rdiff -u -r1.9 -r1.10 src/external/gpl3/binutils/dist/bfd/elf.c > > Please note that diffs are not public domain; they are subject to the > copyright notices on the relevant files. > > Modified files: > > Index: src/external/gpl3/binutils.old/dist/bfd/elf.c > diff -u src/external/gpl3/binutils.old/dist/bfd/elf.c:1.5 > src/external/gpl3/binutils.old/dist/bfd/elf.c:1.6 > --- src/external/gpl3/binutils.old/dist/bfd/elf.c:1.5 Sat Apr 14 15:49:38 2018 > +++ src/external/gpl3/binutils.old/dist/bfd/elf.c Thu Jul 12 21:38:16 2018 > @@ -4159,7 +4159,7 @@ static bfd_size_type > get_program_header_size (bfd *abfd, struct bfd_link_info *info) > { > size_t segs; > - asection *s; > + asection *s, *s2; > const struct elf_backend_data *bed; > > /* Assume we will need exactly two PT_LOAD segments: one for text > @@ -4167,21 +4167,28 @@ get_program_header_size (bfd *abfd, stru > segs = 2; > > s = bfd_get_section_by_name (abfd, ".interp"); > + s2 = bfd_get_section_by_name (abfd, ".dynamic"); > 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; > + ++segs; > } > > - if (bfd_get_section_by_name (abfd, ".dynamic") != NULL) > + if (s2 != NULL && (s2->flags & SEC_LOAD) != 0) > { > /* We need a PT_DYNAMIC segment. */ > ++segs; > } > > + if ((s != NULL && (s->flags & SEC_LOAD) != 0) || > + (s2 != NULL && (s2->flags & SEC_LOAD) != 0)) > + { > + /* > + * If either a PT_INTERP or PT_DYNAMIC segment is created, > + * also create a PT_PHDR segment. > + */ > + ++segs; > + } > + > if (info != NULL && info->relro) > { > /* We need a PT_GNU_RELRO segment. */ > @@ -4448,6 +4455,13 @@ _bfd_elf_map_sections_to_segments (bfd * > section. */ > s = bfd_get_section_by_name (abfd, ".interp"); > if (s != NULL && (s->flags & SEC_LOAD) != 0) > + s = NULL; > + dynsec = bfd_get_section_by_name (abfd, ".dynamic"); > + if (dynsec != NULL > + && (dynsec->flags & SEC_LOAD) == 0) > + dynsec = NULL; > + > + if (s != NULL || dynsec != NULL) > { > amt = sizeof (struct elf_segment_map); > m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); > @@ -4462,7 +4476,10 @@ _bfd_elf_map_sections_to_segments (bfd * > > *pm = m; > pm = &m->next; > + } > > + if (s != NULL) > + { > amt = sizeof (struct elf_segment_map); > m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); > if (m == NULL) > @@ -4489,10 +4506,6 @@ _bfd_elf_map_sections_to_segments (bfd * > if (maxpagesize == 0) > maxpagesize = 1; > writable = FALSE; > - dynsec = bfd_get_section_by_name (abfd, ".dynamic"); > - if (dynsec != NULL > - && (dynsec->flags & SEC_LOAD) == 0) > - dynsec = NULL; > > /* Deal with -Ttext or something similar such that the first section > is not adjacent to the program headers. This is an > > Index: src/external/gpl3/binutils/dist/bfd/elf.c > diff -u src/external/gpl3/binutils/dist/bfd/elf.c:1.9 > src/external/gpl3/binutils/dist/bfd/elf.c:1.10 > --- src/external/gpl3/binutils/dist/bfd/elf.c:1.9 Sun Apr 15 20:06:01 2018 > +++ src/external/gpl3/binutils/dist/bfd/elf.c Thu Jul 12 21:38:16 2018 > @@ -4301,7 +4301,7 @@ static bfd_size_type > get_program_header_size (bfd *abfd, struct bfd_link_info *info) > { > size_t segs; > - asection *s; > + asection *s, *s2; > const struct elf_backend_data *bed; > > /* Assume we will need exactly two PT_LOAD segments: one for text > @@ -4309,21 +4309,28 @@ get_program_header_size (bfd *abfd, stru > segs = 2; > > s = bfd_get_section_by_name (abfd, ".interp"); > + s2 = bfd_get_section_by_name (abfd, ".dynamic"); > 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; > + ++segs; > } > > - if (bfd_get_section_by_name (abfd, ".dynamic") != NULL) > + if (s2 != NULL && (s2->flags & SEC_LOAD) != 0) > { > /* We need a PT_DYNAMIC segment. */ > ++segs; > } > > + if ((s != NULL && (s->flags & SEC_LOAD) != 0) || > + (s2 != NULL && (s2->flags & SEC_LOAD) != 0)) > + { > + /* > + * If either a PT_INTERP or PT_DYNAMIC segment is created, > + * also create a PT_PHDR segment. > + */ > + ++segs; > + } > + > if (info != NULL && info->relro) > { > /* We need a PT_GNU_RELRO segment. */ > @@ -4620,6 +4627,13 @@ _bfd_elf_map_sections_to_segments (bfd * > section. */ > s = bfd_get_section_by_name (abfd, ".interp"); > if (s != NULL && (s->flags & SEC_LOAD) != 0) > + s = NULL; > + dynsec = bfd_get_section_by_name (abfd, ".dynamic"); > + if (dynsec != NULL > + && (dynsec->flags & SEC_LOAD) == 0) > + dynsec = NULL; > + > + if (s != NULL || dynsec != NULL) > { > amt = sizeof (struct elf_segment_map); > m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); > @@ -4633,7 +4647,10 @@ _bfd_elf_map_sections_to_segments (bfd * > linker_created_pt_phdr_segment = TRUE; > *pm = m; > pm = &m->next; > + } > > + if (s != NULL) > + { > amt = sizeof (struct elf_segment_map); > m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); > if (m == NULL) > @@ -4661,10 +4678,6 @@ _bfd_elf_map_sections_to_segments (bfd * > maxpagesize = 1; > writable = FALSE; > executable = FALSE; > - dynsec = bfd_get_section_by_name (abfd, ".dynamic"); > - if (dynsec != NULL > - && (dynsec->flags & SEC_LOAD) == 0) > - dynsec = NULL; > > /* Deal with -Ttext or something similar such that the first section > is not adjacent to the program headers. This is an >