New x86 linker testsuite failure

Alan Hayward Alan.Hayward@arm.com
Wed Jun 27 13:36:00 GMT 2018



> On 27 Jun 2018, at 02:38, Alan Modra <amodra@gmail.com> wrote:
> 
> On Tue, Jun 26, 2018 at 04:08:40PM +0000, Alan Hayward wrote:
>> I would suggest then that the test is no longer valid?
>> 
>> Looking back at the history
>> https://sourceware.org/ml/binutils/2007-02/msg00375.html
>> https://sourceware.org/bugzilla/show_bug.cgi?id=4007
>> The test only existed as a check against invalid files.
> 
> To expand on what I said earlier:
> 
>>>>> Yeah, and the test really does want to error out as the vma/lma given
>>>>> for .foo isn't possible within the text segment.
> 
> The ld-i386/alloc test script is asking ld to create a file with
> sections where the VMA and LMA is specified, packed into a segment.
> LMA is not directly recorded in an ELF file, we calculate it from
> segment p_paddr plus section sh_offset.  VMA is recorded directly as
> section sh_addr.
> 
> But there's a problem.  VMA can also be calculated from segment
> p_vaddr plus section sh_offset, and that VMA doesn't match sh_addr.  I
> realize you want to allow that mismatch, but the ELF specification
> also talks about the "linking view" and "execution view" of a file.
> The linking view is given by the section headers, while the execution
> view is given by the program headers, and the implication is that only
> the program headers are needed for execution of a binary.  I believe
> that is true on linux kernels with glibc ld.so, and likely on other
> unix systems.  You can strip out section headers from an executable
> and still have it execute properly.
> 
> From what you've said it seems like the armlinker and related runtime
> require executable section headers to be present.  Well OK, the ELF
> standard doesn't prohibit that so I'm fine with objcopy / objdump / nm
> / readelf etc. being modified to handle such binaries, but I think
> ld.bfd should continue to error out on an attempt to *create*
> executables where the execution view VMAs no longer match linking view
> VMAs.
> 
> 

Ok, agreed with that. Looking at the code, ld ends up going through
assign_file_positions_for_load_sections(), which uses ELF_SECTION_IN_SEGMENT_1.
Whereas every other place in binutils uses either ELF_SECTION_IN_SEGMENT
or ELF_SECTION_IN_SEGMENT_STRICT.

Given check_vma is already used to block out the whole address checking,
it’s simple enough to move SHT_NOBITS check into the outer two macros.
This restores the functionality for ld, and allows everything else to
avoid checking for addresses.


Is the following patch ok? This both restores my previous code and fixes
up the macros. Ensured the ld alloc test now passes and the gdb works with
armlinker binaries.

Alan.


Use offsets in ELF_SECTION_IN_SEGMENT for SHT_NOBITS in outer macro

Move the "only check virtual addresses for SHT_NOBITS" check from
the ELF_SECTION_IN_SEGMENT_1 macro into the ELF_SECTION_IN_SEGMENT
and ELF_SECTION_IN_SEGMENT_STRICT macros.

This ensures when using ELF_SECTION_IN_SEGMENT_1 setting check_vma
will always check addresses.

The only direct use of ELF_SECTION_IN_SEGMENT_1 is via
assign_file_positions_for_load_sections () which is used for
creating elf files. This ensures creating elf files will always
have valid addresses, but reading in elf files will allow a more
relaxed layout.

2018-06-27  Alan Hayward  <alan.hayward@arm.com>

	* elf/internal.h (ELF_SECTION_IN_SEGMENT_1): Remove SHT_NOBITS check.
	(ELF_SECTION_IN_SEGMENT): Don’t check addresses for non SHT_NOBITS.
	(ELF_SECTION_IN_SEGMENT_STRICT): Likewise


diff --git a/include/elf/internal.h b/include/elf/internal.h
index b012820f6cf9c7e6b5879748b0b05685594987bb..d311b9d9c53278a21bd1942dec8b18163d9f5b28 100644
--- a/include/elf/internal.h
+++ b/include/elf/internal.h
@@ -342,10 +342,8 @@ struct elf_segment_map
 	   && (((sec_hdr)->sh_offset - (segment)->p_offset		\
 		+ ELF_SECTION_SIZE(sec_hdr, segment))			\
 	       <= (segment)->p_filesz)))				\
-   /* SHT_NOBITS sections with SHF_ALLOC must have VMAs within the	\
-      segment.  */							\
+   /* SHF_ALLOC sections must have VMAs within the segment.  */		\
    && (!(check_vma)							\
-       || (sec_hdr)->sh_type != SHT_NOBITS				\
        || ((sec_hdr)->sh_flags & SHF_ALLOC) == 0			\
        || ((sec_hdr)->sh_addr >= (segment)->p_vaddr			\
 	   && (!(strict)						\
@@ -367,10 +365,16 @@ struct elf_segment_map
 		   && ((sec_hdr)->sh_addr - (segment)->p_vaddr		\
 		       < (segment)->p_memsz))))))

+/* Only check VMA if section is SHT_NOBITS.  */
+
 #define ELF_SECTION_IN_SEGMENT(sec_hdr, segment)			\
-  (ELF_SECTION_IN_SEGMENT_1 (sec_hdr, segment, 1, 0))
+  (ELF_SECTION_IN_SEGMENT_1 (sec_hdr, segment,				\
+			     ((sec_hdr)->sh_type == SHT_NOBITS ? 1 : 0),\
+			     0))

 #define ELF_SECTION_IN_SEGMENT_STRICT(sec_hdr, segment)			\
-  (ELF_SECTION_IN_SEGMENT_1 (sec_hdr, segment, 1, 1))
+  (ELF_SECTION_IN_SEGMENT_1 (sec_hdr, segment,				\
+			     ((sec_hdr)->sh_type == SHT_NOBITS ? 1 : 0),\
+			     1))

 #endif /* _ELF_INTERNAL_H */



More information about the Binutils mailing list