From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1757 invoked by alias); 2 Mar 2020 20:11:31 -0000 Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org Received: (qmail 1739 invoked by uid 89); 2 Mar 2020 20:11:30 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.5 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.1 spammy=H*Ad:U*amodra, H*MI:sk:1b83498, sk:link_in, intentional X-HELO: mout.gmx.net Received: from mout.gmx.net (HELO mout.gmx.net) (212.227.17.21) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 02 Mar 2020 20:11:27 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1583179880; bh=x+PlDSsm1Gk71YlK61cAkdpggQAYOI1X8arQlomiSL4=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=hP8OKa+KOhLR3St8jF4lUkd71Ii7RoM/652baQVxCiR2y0zVjoZw4qj2c+cmnl6Y2 pAI07igbGalbMlFDEoViYV7opjTF9yeR0zU9iNfHMdlKV2+FxEHUxgWy5QzT9Q25An W6jsA612XTD2HMtmO8l7qbcmnije8PuABeevpwsk= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from zbook-opensuse.wgnetz.xx ([95.114.58.91]) by mail.gmx.com (mrgmx105 [212.227.17.168]) with ESMTPSA (Nemesis) id 1MEm27-1jBJRk39sR-00GI12; Mon, 02 Mar 2020 21:11:19 +0100 From: Christian Eggers To: binutils@sourceware.org, Nick Clifton Cc: amodra@gmail.com, Christian Eggers Subject: [PATCH v4] Fix several mix up between octets and bytes in ELF program headers Date: Mon, 02 Mar 2020 20:11:00 -0000 Message-Id: <20200302201111.6771-1-ceggers@gmx.de> In-Reply-To: <1b834989-fc85-17ed-310c-10563a6ea07e@redhat.com> References: <1b834989-fc85-17ed-310c-10563a6ea07e@redhat.com> Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes X-SW-Source: 2020-03/txt/msg00027.txt On Monday, March 2nd 2020, Nick Clifton wrote: > Approved - please apply - but with one change: > > + bfd_vma p_start =3D p->p_paddr; /* octets */ > > Please could yoy change the format of these comments so that they follow > the GNU Coding Standard guidelines ? Ie, please start with a capital > letter and end with a period: > > /* Octets. */ > > And similarly for you /* bytes */ comments - they should be /* Bytes. */ Changed all occurrences in the patch. Thanks Christian --- When converting between addresses in ELF headers [octets] and bfd LMA/VMA [bytes], the number of octets per byte needs to be incorperated. In ld, the SIZEOF_HEADERS linker script statement must be resolved to bytes instead of octets. Patch changelog: v2: - Keep ELF header entries as octets. v3: - Revert changes to elf32-rx.c and elf64-ia64-vmx.c - Revert change of "break" statement in the patch for elf.c, elf_link_add_object_symbols() - Fix change of IS_CONTAINED_BY_LMA() v4: - GNU coding style for comments. include/ * elf/internal.h (struct elf_internal_phdr): Add unit (octets) to several member field comments. (Elf_Internal_Shdr): likewise. bfd/ * elf.c (_bfd_elf_make_section_from_shdr): Introduce new temp opb. Divide Elf_Internal_Shdr::sh_addr by opb when setting section LMA/VMA. (_bfd_elf_make_section_from_phdr): Similarly. (elf_fake_sections): Fix calculation of Elf_Internal_shdr::sh_addr from section VMA. (_bfd_elf_map_sections_to_segments): Fix mixup between octets and bytes. (assign_file_positions_for_load_sections): Fix calculations of Elf_Internal_shdr::p_vaddr and p_paddr from section LMA/VMA. Fix comparison between program header address and section LMA. (assign_file_positions_for_non_load_sections): Likewise. (rewrite_elf_program_header): Likewise. Introduce new temp opb. (IS_CONTAINED_BY_VMA): Add parameter opb. (IS_CONTAINED_BY_LMA,IS_SECTION_IN_INPUT_SEGMENT, INCLUDE_SECTION_IN_SEGMENT): Likewise. (copy_elf_program_header): Update call to ELF_SECTION_IN_SEGMENT(). Fix calculations of p_addr_valid and p_vaddr_offset. * elflink.c (elf_link_add_object_symbols): Multiply section VMA with octets per byte when comparing against p_vaddr. ld/ * ldexp.c (fold_name): Return SIZEOF_HEADERS in bytes. Signed-off-by: Christian Eggers --- bfd/elf.c | 131 ++++++++++++++++++++++++++++-----------------= ---- bfd/elflink.c | 12 +++-- include/elf/internal.h | 25 +++++----- ld/ldexp.c | 3 +- 4 files changed, 98 insertions(+), 73 deletions(-) diff --git a/bfd/elf.c b/bfd/elf.c index fcd84d2d17b..a329e239828 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -1016,6 +1016,7 @@ _bfd_elf_make_section_from_shdr (bfd *abfd, asection *newsect; flagword flags; const struct elf_backend_data *bed; + unsigned int opb =3D bfd_octets_per_byte (abfd, NULL); if (hdr->bfd_section !=3D NULL) return TRUE; @@ -1034,11 +1035,6 @@ _bfd_elf_make_section_from_shdr (bfd *abfd, newsect->filepos =3D hdr->sh_offset; - if (!bfd_set_section_vma (newsect, hdr->sh_addr) - || !bfd_set_section_size (newsect, hdr->sh_size) - || !bfd_set_section_alignment (newsect, bfd_log2 (hdr->sh_addralign)= )) - return FALSE; - flags =3D SEC_NO_FLAGS; if (hdr->sh_type !=3D SHT_NOBITS) flags |=3D SEC_HAS_CONTENTS; @@ -1096,7 +1092,10 @@ _bfd_elf_make_section_from_shdr (bfd *abfd, flags |=3D SEC_DEBUGGING | SEC_ELF_OCTETS; else if (strncmp (name, GNU_BUILD_ATTRS_SECTION_NAME, 21) =3D=3D 0 || strncmp (name, ".note.gnu", 9) =3D=3D 0) - flags |=3D SEC_ELF_OCTETS; + { + flags |=3D SEC_ELF_OCTETS; + opb =3D 1; + } else if (strncmp (name, ".line", 5) =3D=3D 0 || strncmp (name, ".stab", 5) =3D=3D 0 || strcmp (name, ".gdb_index") =3D=3D 0) @@ -1104,6 +1103,11 @@ _bfd_elf_make_section_from_shdr (bfd *abfd, } } + if (!bfd_set_section_vma (newsect, hdr->sh_addr / opb) + || !bfd_set_section_size (newsect, hdr->sh_size) + || !bfd_set_section_alignment (newsect, bfd_log2 (hdr->sh_addralign)= )) + return FALSE; + /* As a GNU extension, if the name begins with .gnu.linkonce, we only link a single copy of the section. This is used to support g++. g++ will emit each template expansion in its own section. @@ -1165,7 +1169,7 @@ _bfd_elf_make_section_from_shdr (bfd *abfd, { if ((newsect->flags & SEC_LOAD) =3D=3D 0) newsect->lma =3D (phdr->p_paddr - + hdr->sh_addr - phdr->p_vaddr); + + hdr->sh_addr - phdr->p_vaddr) / opb; else /* We used to use the same adjustment for SEC_LOAD sections, but that doesn't work if the segment @@ -1175,7 +1179,7 @@ _bfd_elf_make_section_from_shdr (bfd *abfd, segment will contain sections with contiguous LMAs, even if the VMAs are not. */ newsect->lma =3D (phdr->p_paddr - + hdr->sh_offset - phdr->p_offset); + + hdr->sh_offset - phdr->p_offset) / opb; /* With contiguous segments, we can't tell from file offsets whether a section with zero size should @@ -2945,6 +2949,7 @@ _bfd_elf_make_section_from_phdr (bfd *abfd, char namebuf[64]; size_t len; int split; + unsigned int opb =3D bfd_octets_per_byte (abfd, NULL); split =3D ((hdr->p_memsz > 0) && (hdr->p_filesz > 0) @@ -2961,8 +2966,8 @@ _bfd_elf_make_section_from_phdr (bfd *abfd, newsect =3D bfd_make_section (abfd, name); if (newsect =3D=3D NULL) return FALSE; - newsect->vma =3D hdr->p_vaddr; - newsect->lma =3D hdr->p_paddr; + newsect->vma =3D hdr->p_vaddr / opb; + newsect->lma =3D hdr->p_paddr / opb; newsect->size =3D hdr->p_filesz; newsect->filepos =3D hdr->p_offset; newsect->flags |=3D SEC_HAS_CONTENTS; @@ -2997,8 +3002,8 @@ _bfd_elf_make_section_from_phdr (bfd *abfd, newsect =3D bfd_make_section (abfd, name); if (newsect =3D=3D NULL) return FALSE; - newsect->vma =3D hdr->p_vaddr + hdr->p_filesz; - newsect->lma =3D hdr->p_paddr + hdr->p_filesz; + newsect->vma =3D (hdr->p_vaddr + hdr->p_filesz) / opb; + newsect->lma =3D (hdr->p_paddr + hdr->p_filesz) / opb; newsect->size =3D hdr->p_memsz - hdr->p_filesz; newsect->filepos =3D hdr->p_offset + hdr->p_filesz; align =3D newsect->vma & -newsect->vma; @@ -3274,7 +3279,7 @@ elf_fake_sections (bfd *abfd, asection *asect, void *= fsarg) if ((asect->flags & SEC_ALLOC) !=3D 0 || asect->user_set_vma) - this_hdr->sh_addr =3D asect->vma; + this_hdr->sh_addr =3D asect->vma * bfd_octets_per_byte (abfd, asect); else this_hdr->sh_addr =3D 0; @@ -4662,6 +4667,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct = bfd_link_info *info) size_t amt; bfd_vma addr_mask, wrap_to =3D 0; bfd_size_type phdr_size; + unsigned int opb =3D bfd_octets_per_byte (abfd, NULL); /* Select the allocated sections, and sort them. */ @@ -4701,6 +4707,8 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct = bfd_link_info *info) if (phdr_size =3D=3D (bfd_size_type) -1) phdr_size =3D get_program_header_size (abfd, info); phdr_size +=3D bed->s->sizeof_ehdr; + /* phdr_size is compared to LMA values which are in bytes. */ + phdr_size /=3D opb; maxpagesize =3D bed->maxpagesize; if (maxpagesize =3D=3D 0) maxpagesize =3D 1; @@ -4925,7 +4933,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct = bfd_link_info *info) executable =3D TRUE; last_hdr =3D hdr; /* .tbss sections effectively have zero size. */ - last_size =3D !IS_TBSS (hdr) ? hdr->size : 0; + last_size =3D (!IS_TBSS (hdr) ? hdr->size : 0) / opb; continue; } @@ -4951,7 +4959,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct = bfd_link_info *info) last_hdr =3D hdr; /* .tbss sections effectively have zero size. */ - last_size =3D !IS_TBSS (hdr) ? hdr->size : 0; + last_size =3D (!IS_TBSS (hdr) ? hdr->size : 0) / opb; hdr_index =3D i; phdr_in_segment =3D FALSE; } @@ -5405,11 +5413,12 @@ assign_file_positions_for_load_sections (bfd *abfd, struct elf_segment_map *phdr_load_seg; Elf_Internal_Phdr *phdrs; Elf_Internal_Phdr *p; - file_ptr off; + file_ptr off; /* Octets. */ bfd_size_type maxpagesize; unsigned int alloc, actual; unsigned int i, j; struct elf_segment_map **sorted_seg_map; + unsigned int opb =3D bfd_octets_per_byte (abfd, NULL); if (link_info =3D=3D NULL && !_bfd_elf_map_sections_to_segments (abfd, link_info)) @@ -5517,7 +5526,7 @@ assign_file_positions_for_load_sections (bfd *abfd, for (j =3D 0; j < alloc; j++) { asection **secpp; - bfd_vma off_adjust; + bfd_vma off_adjust; /* Octets. */ bfd_boolean no_contents; /* An ELF segment (described by Elf_Internal_Phdr) may contain a @@ -5531,16 +5540,16 @@ assign_file_positions_for_load_sections (bfd *abfd, p->p_flags =3D m->p_flags; if (m->count =3D=3D 0) - p->p_vaddr =3D m->p_vaddr_offset; + p->p_vaddr =3D m->p_vaddr_offset * opb; else - p->p_vaddr =3D m->sections[0]->vma + m->p_vaddr_offset; + p->p_vaddr =3D (m->sections[0]->vma + m->p_vaddr_offset) * opb; if (m->p_paddr_valid) p->p_paddr =3D m->p_paddr; else if (m->count =3D=3D 0) p->p_paddr =3D 0; else - p->p_paddr =3D m->sections[0]->lma + m->p_vaddr_offset; + p->p_paddr =3D (m->sections[0]->lma + m->p_vaddr_offset) * opb; if (p->p_type =3D=3D PT_LOAD && (abfd->flags & D_PAGED) !=3D 0) @@ -5621,7 +5630,8 @@ assign_file_positions_for_load_sections (bfd *abfd, && (abfd->flags & D_PAGED) !=3D 0 && bed->no_page_alias && (off & (maxpagesize - 1)) !=3D 0 - && (off & -maxpagesize) =3D=3D ((off + off_adjust) & -maxpagesize)) + && ((off & -maxpagesize) + =3D=3D ((off + off_adjust) & -maxpagesize))) off_adjust +=3D maxpagesize; off +=3D off_adjust; if (no_contents) @@ -5712,7 +5722,7 @@ assign_file_positions_for_load_sections (bfd *abfd, else if (phdr_load_seg !=3D NULL) { Elf_Internal_Phdr *phdr =3D phdrs + phdr_load_seg->idx; - bfd_vma phdr_off =3D 0; + bfd_vma phdr_off =3D 0; /* Octets. */ if (phdr_load_seg->includes_filehdr) phdr_off =3D bed->s->sizeof_ehdr; p->p_vaddr =3D phdr->p_vaddr + phdr_off; @@ -5746,7 +5756,7 @@ assign_file_positions_for_load_sections (bfd *abfd, } else { - file_ptr adjust; + file_ptr adjust; /* Octets. */ adjust =3D off - (p->p_offset + p->p_filesz); if (!no_contents) @@ -5777,10 +5787,10 @@ assign_file_positions_for_load_sections (bfd *abfd, && ((this_hdr->sh_flags & SHF_TLS) =3D=3D 0 || p->p_type =3D=3D PT_TLS)))) { - bfd_vma p_start =3D p->p_paddr; - bfd_vma p_end =3D p_start + p->p_memsz; - bfd_vma s_start =3D sec->lma; - bfd_vma adjust =3D s_start - p_end; + bfd_vma p_start =3D p->p_paddr; /* Octets. */ + bfd_vma p_end =3D p_start + p->p_memsz; /* Octets. */ + bfd_vma s_start =3D sec->lma * opb; /* Octets. */ + bfd_vma adjust =3D s_start - p_end; /* Octets. */ if (adjust !=3D 0 && (s_start < p_end @@ -5789,9 +5799,10 @@ assign_file_positions_for_load_sections (bfd *abfd, _bfd_error_handler /* xgettext:c-format */ (_("%pB: section %pA lma %#" PRIx64 " adjusted to %#" PRIx64), - abfd, sec, (uint64_t) s_start, (uint64_t) p_end); + abfd, sec, (uint64_t) s_start / opb, + (uint64_t) p_end / opb); adjust =3D 0; - sec->lma =3D p_end; + sec->lma =3D p_end / opb; } p->p_memsz +=3D adjust; @@ -6181,8 +6192,11 @@ assign_file_positions_for_non_load_sections (bfd *ab= fd, if (i < lm->count) { - p->p_vaddr =3D lm->sections[i]->vma; - p->p_paddr =3D lm->sections[i]->lma; + unsigned int opb =3D bfd_octets_per_byte (abfd, + lm->sections[i]); + + p->p_vaddr =3D lm->sections[i]->vma * opb; + p->p_paddr =3D lm->sections[i]->lma * opb; p->p_offset =3D lm->sections[i]->filepos; p->p_memsz =3D end - p->p_vaddr; p->p_filesz =3D p->p_memsz; @@ -6781,6 +6795,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd) struct elf_segment_map *phdr_adjust_seg =3D NULL; unsigned int phdr_adjust_num =3D 0; const struct elf_backend_data *bed; + unsigned int opb =3D bfd_octets_per_byte (ibfd, NULL); bed =3D get_elf_backend_data (ibfd); iehdr =3D elf_elfheader (ibfd); @@ -6803,17 +6818,17 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd) /* Returns TRUE if the given section is contained within the given segment. VMA addresses are compared. */ -#define IS_CONTAINED_BY_VMA(section, segment) \ - (section->vma >=3D segment->p_vaddr \ - && (section->vma + SECTION_SIZE (section, segment) \ +#define IS_CONTAINED_BY_VMA(section, segment, opb) \ + (section->vma * (opb) >=3D segment->p_vaddr \ + && (section->vma * (opb) + SECTION_SIZE (section, segment) \ <=3D (SEGMENT_END (segment, segment->p_vaddr)))) /* Returns TRUE if the given section is contained within the given segment. LMA addresses are compared. */ -#define IS_CONTAINED_BY_LMA(section, segment, base) \ - (section->lma >=3D base \ - && (section->lma + SECTION_SIZE (section, segment) >=3D section->lma) \ - && (section->lma + SECTION_SIZE (section, segment) \ +#define IS_CONTAINED_BY_LMA(section, segment, base, opb) \ + (section->lma * (opb) >=3D base \ + && (section->lma + SECTION_SIZE (section, segment) / (opb) >=3D section= ->lma) \ + && (section->lma * (opb) + SECTION_SIZE (section, segment) \ <=3D SEGMENT_END (segment, base))) /* Handle PT_NOTE segment. */ @@ -6859,10 +6874,10 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd) 7. SHF_TLS sections are only in PT_TLS or PT_LOAD segments. 8. PT_DYNAMIC should not contain empty sections at the beginning (with the possible exception of .dynamic). */ -#define IS_SECTION_IN_INPUT_SEGMENT(section, segment, bed) \ +#define IS_SECTION_IN_INPUT_SEGMENT(section, segment, bed, opb) \ ((((segment->p_paddr \ - ? IS_CONTAINED_BY_LMA (section, segment, segment->p_paddr) \ - : IS_CONTAINED_BY_VMA (section, segment)) \ + ? IS_CONTAINED_BY_LMA (section, segment, segment->p_paddr, opb) \ + : IS_CONTAINED_BY_VMA (section, segment, opb)) \ && (section->flags & SEC_ALLOC) !=3D 0) \ || IS_NOTE (segment, section)) \ && segment->p_type !=3D PT_GNU_STACK \ @@ -6874,15 +6889,15 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd) && (segment->p_type !=3D PT_DYNAMIC \ || SECTION_SIZE (section, segment) > 0 \ || (segment->p_paddr \ - ? segment->p_paddr !=3D section->lma \ - : segment->p_vaddr !=3D section->vma) \ + ? segment->p_paddr !=3D section->lma * (opb) \ + : segment->p_vaddr !=3D section->vma * (opb)) \ || (strcmp (bfd_section_name (section), ".dynamic") =3D=3D 0)) \ && (segment->p_type !=3D PT_LOAD || !section->segment_mark)) /* If the output section of a section in the input segment is NULL, it is removed from the corresponding output segment. */ -#define INCLUDE_SECTION_IN_SEGMENT(section, segment, bed) \ - (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed) \ +#define INCLUDE_SECTION_IN_SEGMENT(section, segment, bed, opb) \ + (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed, opb) \ && section->output_section !=3D NULL) /* Returns TRUE iff seg1 starts after the end of seg2. */ @@ -6936,7 +6951,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd) { /* Mininal change so that the normal section to segment assignment code will work. */ - segment->p_vaddr =3D section->vma; + segment->p_vaddr =3D section->vma * opb; break; } @@ -7022,7 +7037,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd) { /* Find the first section in the input segment, which may be removed from the corresponding output segment. */ - if (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed)) + if (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed, opb)) { if (first_section =3D=3D NULL) first_section =3D section; @@ -7090,7 +7105,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd) " at vaddr=3D%#" PRIx64 ", is this intentional?"), ibfd, (uint64_t) segment->p_vaddr); - map->p_vaddr_offset =3D segment->p_vaddr; + map->p_vaddr_offset =3D segment->p_vaddr / opb; map->count =3D 0; *pointer_to_map =3D map; pointer_to_map =3D &map->next; @@ -7145,7 +7160,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd) section !=3D NULL; section =3D section->next) { - if (INCLUDE_SECTION_IN_SEGMENT (section, segment, bed)) + if (INCLUDE_SECTION_IN_SEGMENT (section, segment, bed, opb)) { output_section =3D section->output_section; @@ -7172,10 +7187,11 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd) /* Match up the physical address of the segment with the LMA address of the output section. */ - if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr) + if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr, + opb) || IS_COREFILE_NOTE (segment, section) || (bed->want_p_paddr_set_to_zero - && IS_CONTAINED_BY_VMA (output_section, segment))) + && IS_CONTAINED_BY_VMA (output_section, segment, opb))) { if (matching_lma =3D=3D NULL || output_section->lma < matching_lma->lma) @@ -7219,7 +7235,8 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd) /* Account for padding before the first section in the segment. */ - map->p_vaddr_offset =3D map->p_paddr + hdr_size - matching_lma->lma; + map->p_vaddr_offset =3D ((map->p_paddr + hdr_size) / opb + - matching_lma->lma); } free (sections); @@ -7290,7 +7307,8 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd) BFD_ASSERT (output_section !=3D NULL); - if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr) + if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr, + opb) || IS_COREFILE_NOTE (segment, section)) { if (map->count =3D=3D 0) @@ -7442,6 +7460,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd) unsigned int num_segments; bfd_boolean phdr_included =3D FALSE; bfd_boolean p_paddr_valid; + unsigned int opb =3D bfd_octets_per_byte (ibfd, NULL); iehdr =3D elf_elfheader (ibfd); @@ -7567,7 +7586,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd) seg_off =3D this_hdr->sh_offset - segment->p_offset; else seg_off =3D this_hdr->sh_addr - segment->p_vaddr; - if (section->lma - segment->p_paddr !=3D seg_off) + if (section->lma * opb - segment->p_paddr !=3D seg_off) map->p_paddr_valid =3D FALSE; } if (isec =3D=3D section_count) @@ -7577,7 +7596,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd) } if (section_count =3D=3D 0) - map->p_vaddr_offset =3D segment->p_vaddr; + map->p_vaddr_offset =3D segment->p_vaddr / opb; else if (map->p_paddr_valid) { /* Account for padding before the first section in the segment. */ @@ -7587,7 +7606,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd) if (map->includes_phdrs) hdr_size +=3D iehdr->e_phnum * iehdr->e_phentsize; - map->p_vaddr_offset =3D (map->p_paddr + hdr_size + map->p_vaddr_offset =3D ((map->p_paddr + hdr_size) / opb - (lowest_section ? lowest_section->lma : 0)); } diff --git a/bfd/elflink.c b/bfd/elflink.c index c04712a10f6..369f3cb3e7b 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -4218,10 +4218,14 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_= link_info *info) if (phdr->p_type =3D=3D PT_GNU_RELRO) { for (s =3D abfd->sections; s !=3D NULL; s =3D s->next) - if ((s->flags & SEC_ALLOC) !=3D 0 - && s->vma >=3D phdr->p_vaddr - && s->vma + s->size <=3D phdr->p_vaddr + phdr->p_memsz) - s->flags |=3D SEC_READONLY; + { + unsigned int opb =3D bfd_octets_per_byte (abfd, s); + + if ((s->flags & SEC_ALLOC) !=3D 0 + && s->vma * opb >=3D phdr->p_vaddr + && s->vma * opb + s->size <=3D phdr->p_vaddr + phdr->p_memsz) + s->flags |=3D SEC_READONLY; + } break; } diff --git a/include/elf/internal.h b/include/elf/internal.h index 844675c30f3..d626adece5b 100644 --- a/include/elf/internal.h +++ b/include/elf/internal.h @@ -84,14 +84,14 @@ typedef struct elf_internal_ehdr { /* Program header */ struct elf_internal_phdr { - unsigned long p_type; /* Identifies program segment type */ - unsigned long p_flags; /* Segment flags */ - bfd_vma p_offset; /* Segment file offset */ - bfd_vma p_vaddr; /* Segment virtual address */ - bfd_vma p_paddr; /* Segment physical address */ - bfd_vma p_filesz; /* Segment size in file */ - bfd_vma p_memsz; /* Segment size in memory */ - bfd_vma p_align; /* Segment alignment, file & memory */ + unsigned long p_type; /* Identifies program segment type. */ + unsigned long p_flags; /* Segment flags. */ + bfd_vma p_offset; /* Segment file offset in octets. */ + bfd_vma p_vaddr; /* Segment virtual address in octets. */ + bfd_vma p_paddr; /* Segment physical address in octets. */ + bfd_vma p_filesz; /* Segment size in file in octets. */ + bfd_vma p_memsz; /* Segment size in memory in octets. */ + bfd_vma p_align; /* Segment alignment, file & memory. */ }; typedef struct elf_internal_phdr Elf_Internal_Phdr; @@ -102,9 +102,10 @@ typedef struct elf_internal_shdr { unsigned int sh_name; /* Section name, index in string tbl */ unsigned int sh_type; /* Type of section */ bfd_vma sh_flags; /* Miscellaneous section attributes */ - bfd_vma sh_addr; /* Section virtual addr at execution */ - file_ptr sh_offset; /* Section file offset */ - bfd_size_type sh_size; /* Size of section in bytes */ + bfd_vma sh_addr; /* Section virtual addr at execution in + octets. */ + file_ptr sh_offset; /* Section file offset in octets. */ + bfd_size_type sh_size; /* Size of section in octets. */ unsigned int sh_link; /* Index of another section */ unsigned int sh_info; /* Additional section information */ bfd_vma sh_addralign; /* Section alignment */ @@ -267,7 +268,7 @@ struct elf_segment_map unsigned long p_flags; /* Program segment physical address. */ bfd_vma p_paddr; - /* Program segment virtual address offset from section vma. */ + /* Program segment virtual address offset from section vma in bytes. */ bfd_vma p_vaddr_offset; /* Program segment alignment. */ bfd_vma p_align; diff --git a/ld/ldexp.c b/ld/ldexp.c index 6d1457b929a..3ffabb8c1da 100644 --- a/ld/ldexp.c +++ b/ld/ldexp.c @@ -700,7 +700,8 @@ fold_name (etree_type *tree) /* Don't find the real header size if only marking sections; The bfd function may cache incorrect data. */ if (expld.phase !=3D lang_mark_phase_enum) - hdr_size =3D bfd_sizeof_headers (link_info.output_bfd, &link_info); + hdr_size =3D (bfd_sizeof_headers (link_info.output_bfd, &link_info) + / bfd_octets_per_byte (link_info.output_bfd, NULL)); new_number (hdr_size); } break; -- 2.16.4