Переглянути джерело

ARM32: fix image

- Make it actually work
- Split text/data/reloc/rodata sections
- Move hash sections to past end of image
  (un-needed in PE)
- Correct section & file alignment
- Correct image size
- rename .reloc to .areloc within ELF
  as only on ARM32 does this name cause
  it to be marked as REL and subsequently
  mistakenly added to RELSZ

Builds correctly & tested working in QEMU

Signed-off-by: Callum Farmer <gmbr3@opensuse.org>
Callum Farmer 11 місяців тому
батько
коміт
50b27a854c
3 змінених файлів з 103 додано та 42 видалено
  1. 1 1
      Make.rules
  2. 59 30
      gnuefi/crt0-efi-arm.S
  3. 43 11
      gnuefi/elf_arm_efi.lds

+ 1 - 1
Make.rules

@@ -39,7 +39,7 @@
 %.efi: %.so
 	$(OBJCOPY) -j .text -j .sdata -j .data -j .dynamic -j .rodata -j .rel \
 		    -j .rela -j .rel.* -j .rela.* -j .rel* -j .rela* \
-		    -j .reloc $(FORMAT) $*.so $@
+		    -j .areloc -j .reloc $(FORMAT) $*.so $@
 
 %.efi.debug: %.so
 	$(OBJCOPY) -j .debug_info -j .debug_abbrev -j .debug_aranges \

+ 59 - 30
gnuefi/crt0-efi-arm.S

@@ -31,7 +31,7 @@ pe_header:
 	.2byte 	0
 coff_header:
 	.2byte	0x1c2				// Mixed ARM/Thumb
-	.2byte	2				// nr_sections
+	.2byte	4				// nr_sections
 	.4byte	0 				// TimeDateStamp
 	.4byte	0				// PointerToSymbolTable
 	.4byte	0				// NumberOfSymbols
@@ -45,17 +45,17 @@ optional_header:
 	.2byte	0x10b				// PE32+ format
 	.byte	0x02				// MajorLinkerVersion
 	.byte	0x14				// MinorLinkerVersion
-	.4byte	_edata - _start			// SizeOfCode
-	.4byte	0				// SizeOfInitializedData
+	.4byte	_etext - _start		// SizeOfCode
+	.4byte	_alldata_size - ImageBase		// SizeOfInitializedData
 	.4byte	0				// SizeOfUninitializedData
 	.4byte	_start - ImageBase		// AddressOfEntryPoint
 	.4byte	_start - ImageBase		// BaseOfCode
-	.4byte	0				// BaseOfData
+	.4byte	_reloc - ImageBase		// BaseOfData
 
 extra_header_fields:
 	.4byte	0				// ImageBase
-	.4byte	0x20				// SectionAlignment
-	.4byte	0x8				// FileAlignment
+	.4byte	0x1000				// SectionAlignment
+	.4byte	0x1000				// FileAlignment
 	.2byte	0				// MajorOperatingSystemVersion
 	.2byte	0				// MinorOperatingSystemVersion
 	.2byte	0				// MajorImageVersion
@@ -64,7 +64,7 @@ extra_header_fields:
 	.2byte	0				// MinorSubsystemVersion
 	.4byte	0				// Win32VersionValue
 
-	.4byte	_edata - ImageBase		// SizeOfImage
+	.4byte	_image_end - ImageBase		// SizeOfImage
 
 	// Everything before the kernel image is considered part of the header
 	.4byte	_start - ImageBase		// SizeOfHeaders
@@ -83,7 +83,8 @@ extra_header_fields:
 	.8byte	0				// ResourceTable
 	.8byte	0				// ExceptionTable
 	.8byte	0				// CertificationTable
-	.8byte	0				// BaseRelocationTable
+	.4byte	_reloc - ImageBase				// BaseRelocationTable (VirtualAddress)
+	.4byte	_reloc_vsize - ImageBase				// BaseRelocationTable (Size)
 	.8byte	0				// Debug
 	.8byte	0				// Architecture
 	.8byte	0				// Global Ptr
@@ -98,40 +99,56 @@ extra_header_fields:
 	// Section table
 section_table:
 
+	.ascii	".text\0\0\0"
+	.4byte	_evtext - _start // VirtualSize
+	.4byte	_start - ImageBase	// VirtualAddress
+	.4byte	_etext - _start		// SizeOfRawData
+	.4byte	_start - ImageBase	// PointerToRawData
+	.4byte	0		// PointerToRelocations (0 for executables)
+	.4byte	0		// PointerToLineNumbers (0 for executables)
+	.2byte	0		// NumberOfRelocations  (0 for executables)
+	.2byte	0		// NumberOfLineNumbers  (0 for executables)
+	.4byte	0x60000020	// Characteristics (section flags)
+
 	/*
 	 * The EFI application loader requires a relocation section
 	 * because EFI applications must be relocatable.  This is a
 	 * dummy section as far as we are concerned.
 	 */
-	.ascii	".reloc"
-	.byte	0
-	.byte	0			// end of 0 padding of section name
-	.4byte	0
-	.4byte	0
-	.4byte	0			// SizeOfRawData
-	.4byte	0			// PointerToRawData
+	.ascii	".reloc\0\0"
+	.4byte	_reloc_vsize - ImageBase			// VirtualSize
+	.4byte	_reloc - ImageBase			// VirtualAddress
+	.4byte	_reloc_size - ImageBase			// SizeOfRawData
+	.4byte	_reloc - ImageBase			// PointerToRawData
 	.4byte	0			// PointerToRelocations
 	.4byte	0			// PointerToLineNumbers
 	.2byte	0			// NumberOfRelocations
 	.2byte	0			// NumberOfLineNumbers
-	.4byte	0x42100040		// Characteristics (section flags)
-
+	.4byte	0x42000040		// Characteristics (section flags)
 
-	.ascii	".text"
-	.byte	0
-	.byte	0
-	.byte	0        		// end of 0 padding of section name
-	.4byte	_edata - _start		// VirtualSize
-	.4byte	_start - ImageBase	// VirtualAddress
-	.4byte	_edata - _start		// SizeOfRawData
-	.4byte	_start - ImageBase	// PointerToRawData
+	.ascii	".data\0\0\0"
+	.4byte	_data_vsize - ImageBase			// VirtualSize
+	.4byte	_data - ImageBase			// VirtualAddress
+	.4byte	_data_size - ImageBase			// SizeOfRawData
+	.4byte	_data - ImageBase			// PointerToRawData
+	.4byte	0			// PointerToRelocations
+	.4byte	0			// PointerToLineNumbers
+	.2byte	0			// NumberOfRelocations
+	.2byte	0			// NumberOfLineNumbers
+	.4byte	0xC0000040		// Characteristics (section flags)
 
-	.4byte	0		// PointerToRelocations (0 for executables)
-	.4byte	0		// PointerToLineNumbers (0 for executables)
-	.2byte	0		// NumberOfRelocations  (0 for executables)
-	.2byte	0		// NumberOfLineNumbers  (0 for executables)
-	.4byte	0xe0500020	// Characteristics (section flags)
+	.ascii	".rodata\0"
+	.4byte	_rodata_vsize - ImageBase			// VirtualSize
+	.4byte	_rodata - ImageBase			// VirtualAddress
+	.4byte	_rodata_size - ImageBase			// SizeOfRawData
+	.4byte	_rodata - ImageBase			// PointerToRawData
+	.4byte	0			// PointerToRelocations
+	.4byte	0			// PointerToLineNumbers
+	.2byte	0			// NumberOfRelocations
+	.2byte	0			// NumberOfLineNumbers
+	.4byte	0x40000040		// Characteristics (section flags)
 
+.balign 256
 .globl	_start
 .type _start,%function
 _start:
@@ -156,6 +173,18 @@ _start:
 .L_DYNAMIC:
 	.4byte		_DYNAMIC - .
 
+// hand-craft a dummy .reloc section so EFI knows it's a relocatable executable:
+ 
+ 	.data
+dummy:	.4byte	0
+
+#define IMAGE_REL_ABSOLUTE	0
+ 	.section .areloc
+ 	.4byte	dummy					// Page RVA
+	.4byte	12					// Block Size (2*4+2*2), must be aligned by 32 Bits
+	.2byte	(IMAGE_REL_ABSOLUTE<<12) +  0		// reloc for dummy
+	.2byte	(IMAGE_REL_ABSOLUTE<<12) +  0		// reloc for dummy
+
 #if defined(__ELF__) && defined(__linux__)
 	.section .note.GNU-stack,"",%progbits
 #endif

+ 43 - 11
gnuefi/elf_arm_efi.lds

@@ -3,23 +3,36 @@ OUTPUT_ARCH(arm)
 ENTRY(_start)
 SECTIONS
 {
-  .text 0x0 : {
-    _text = .;
+  .text 0 : {
     *(.text.head)
+    _text = .;
     *(.text)
     *(.text.*)
     *(.gnu.linkonce.t.*)
     *(.plt)
     . = ALIGN(16);
-  }
-  _etext = .;
+    _evtext = .;
+    . = ALIGN(4096);
+    _etext = .;
+  } =0
+  _text_vsize = _evtext - _text;
   _text_size = _etext - _text;
   . = ALIGN(4096);
+  _reloc = .;
+  .areloc : {
+    *(.areloc)
+    _evreloc = .;
+    . = ALIGN(4096);
+    _ereloc = .;
+  } =0
+  _reloc_vsize = _evreloc - _reloc;
+  _reloc_size = _ereloc - _reloc;
+  . = ALIGN(4096);
+  _data = .;
   .dynamic  : { *(.dynamic) }
   . = ALIGN(4096);
   .data :
   {
-   _data = .;
    *(.sdata)
    *(.data)
    *(.data1)
@@ -66,9 +79,15 @@ SECTIONS
    *(COMMON)
    . = ALIGN(16);
    _bss_end = .;
-  }
+   _evdata = .;
+   . = ALIGN(4096);
+   _edata = .;
+  } =0
+  _data_vsize = _evdata - _data;
+  _data_size = _edata - _data;
 
   . = ALIGN(4096);
+  _rodata = .;
   .rel :
   {
     *(.rel.text*)
@@ -85,9 +104,16 @@ SECTIONS
   . = ALIGN(4096);
   .rel.plt : { *(.rel.plt) }
   . = ALIGN(4096);
-  .rodata : { *(.rodata*) }
-  _edata = .;
-  _data_size = _edata - _etext;
+  .rodata : {
+    *(.rodata*)
+    _evrodata = .;
+    . = ALIGN(4096);
+    _erodata = .;
+  } =0
+  _rodata_vsize = _evrodata - _rodata;
+  _rodata_size = _erodata - _rodata;
+  _image_end = .;
+  _alldata_size = _image_end - _reloc;
 
   . = ALIGN(4096);
   .dynsym   : { *(.dynsym) }
@@ -95,10 +121,16 @@ SECTIONS
   .dynstr   : { *(.dynstr) }
   . = ALIGN(4096);
   .note.gnu.build-id : { *(.note.gnu.build-id) }
+  . = ALIGN(4096);
+  .hash : { *(.hash) }
+  . = ALIGN(4096);
+  .gnu.hash : { *(.gnu.hash) }
+  . = ALIGN(4096);
+  .ARM.exidx : { *(.ARM.exidx*) }
+  .ARM.extab : { *(.ARM.extab*) }
   /DISCARD/ :
   {
-    *(.rel.reloc)
-    *(.eh_frame)
+    *(.rel.areloc)
     *(.note.GNU-stack)
   }
   .comment 0 : { *(.comment) }