Quellcode durchsuchen

riscv64: 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

Builds correctly but untested

Signed-off-by: Callum Farmer <gmbr3@opensuse.org>
Callum Farmer vor 1 Jahr
Ursprung
Commit
58dce6991b
2 geänderte Dateien mit 187 neuen und 121 gelöschten Zeilen
  1. 66 30
      gnuefi/crt0-efi-riscv64.S
  2. 121 91
      gnuefi/elf_riscv64_efi.lds

+ 66 - 30
gnuefi/crt0-efi-riscv64.S

@@ -35,7 +35,7 @@ pe_header:
 	.2byte 	0
 coff_header:
 	.2byte	0x5064				// riscv64
-	.2byte	2				// nr_sections
+	.2byte	4				// nr_sections
 	.4byte	0 				// TimeDateStamp
 	.4byte	0				// PointerToSymbolTable
 	.4byte	0				// NumberOfSymbols
@@ -48,16 +48,16 @@ optional_header:
 	.2byte	0x20b				// PE32+ format
 	.byte	0x02				// MajorLinkerVersion
 	.byte	0x14				// MinorLinkerVersion
-	.4byte	_data - _start			// SizeOfCode
-	.4byte	_edata - _data			// SizeOfInitializedData
+	.4byte	_text_size - ImageBase		// SizeOfCode
+	.4byte	_alldata_size - ImageBase		// SizeOfInitializedData
 	.4byte	0				// SizeOfUninitializedData
 	.4byte	_start - ImageBase		// AddressOfEntryPoint
-	.4byte	_start - ImageBase		// BaseOfCode
+	.4byte	_text - ImageBase		// BaseOfCode
 
 extra_header_fields:
 	.8byte	0				// ImageBase
 	.4byte	0x1000				// SectionAlignment
-	.4byte	0x200				// FileAlignment
+	.4byte	0x1000				// FileAlignment
 	.2byte	0				// MajorOperatingSystemVersion
 	.2byte	0				// MinorOperatingSystemVersion
 	.2byte	0				// MajorImageVersion
@@ -66,10 +66,10 @@ 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
+	.4byte	_text - ImageBase		// SizeOfHeaders
 	.4byte	0				// CheckSum
 	.2byte	EFI_SUBSYSTEM			// Subsystem
 	.2byte	0				// DllCharacteristics
@@ -85,7 +85,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
@@ -99,35 +100,57 @@ extra_header_fields:
 
 	// Section table
 section_table:
+
+	.ascii	".text\0\0\0"
+	.4byte	_text_vsize - ImageBase		// VirtualSize
+	.4byte	_text - ImageBase	// VirtualAddress
+	.4byte	_text_size - ImageBase		// SizeOfRawData
+	.4byte	_text - 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\0\0"
-	.4byte	0
-	.4byte	0
-	.4byte	0				// SizeOfRawData
-	.4byte	0				// PointerToRawData
-	.4byte	0				// PointerToRelocations
-	.4byte	0				// PointerToLineNumbers
-	.2byte	0				// NumberOfRelocations
-	.2byte	0				// NumberOfLineNumbers
-	.4byte	0x42100040			// Characteristics (section flags)
+	.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	0x42000040		// Characteristics (section flags)
 
-	.ascii	".text\0\0\0"
-	.4byte	_edata - _start			// VirtualSize
-	.4byte	_start - ImageBase		// VirtualAddress
-	.4byte	_edata - _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	0xe0500020			// Characteristics (section flags)
-
-	.align	12
+	.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)
+
+	.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)
+
+	.text
 	.globl _start
 	.type _start,%function
 _start:
@@ -146,6 +169,19 @@ _start:
 0:	addi		sp, sp, 24
 	ret
 
+// hand-craft a dummy .reloc section so EFI knows it's a relocatable executable:
+ 
+ 	.data
+dummy:	.4byte	0
+
+#define IMAGE_REL_ABSOLUTE	0
+ 	.section .reloc, "a"
+label1:
+	.4byte	dummy-label1				// 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

+ 121 - 91
gnuefi/elf_riscv64_efi.lds

@@ -3,76 +3,95 @@
 OUTPUT_FORMAT("elf64-littleriscv", "elf64-littleriscv", "elf64-littleriscv")
 OUTPUT_ARCH(riscv)
 ENTRY(_start)
-SECTIONS {
-.text 0x0 :
-	{
-		_text = .;
-		*(.text.head)
-		*(.text)
-		*(.text.*)
-		*(.gnu.linkonce.t.*)
-                *(.plt)
-		. = ALIGN(16);
-	}
-	_etext = .;
-	_text_size = _etext - _text;
-. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
-.dynamic  :
-	{ *(.dynamic) }
-.data :
-	ALIGN(4096)
-	{
-		_data = .;
-		*(.sdata)
-		*(.data)
-		*(.data1)
-		*(.data.*)
-		*(.got.plt)
-		*(.got)
-
-		/*
-		* Note that these aren't the using the GNU "CONSTRUCTOR" output section
-		* command, so they don't start with a size.  Because of p2align and the
-		* end/END definitions, and the fact that they're mergeable, they can also
-		* have NULLs which aren't guaranteed to be at the end.
-		*/
-		. = ALIGN(16);
-		__init_array_start = .;
-		*(SORT(.init_array.*))
-		*(.init_array)
-		__init_array_end = .;
-		. = ALIGN(16);
-		__CTOR_LIST__ = .;
-		*(SORT(.ctors.*))
-		*(.ctors)
-		__CTOR_END__ = .;
-		. = ALIGN(16);
-		__DTOR_LIST__ = .;
-		*(SORT(.dtors.*))
-		*(.dtors)
-		__DTOR_END__ = .;
-		. = ALIGN(16);
-		__fini_array_start = .;
-		*(SORT(.fini_array.*))
-		*(.fini_array)
-		__fini_array_end = .;
+SECTIONS
+{
+  .text 0 : {
+    *(.text.head)
+    . = ALIGN(4096);
+    _text = .;
+    *(.text)
+    *(.text.*)
+    *(.gnu.linkonce.t.*)
+    *(.plt)
+    . = ALIGN(16);
+    _evtext = .;
+    . = ALIGN(4096);
+    _etext = .;
+  } =0
+  _text_vsize = _evtext - _text;
+  _text_size = _etext - _text;
+  . = ALIGN(4096);
+  _reloc = .;
+  .reloc : {
+    *(.reloc)
+    _evreloc = .;
+    . = ALIGN(4096);
+    _ereloc = .;
+  } =0
+  _reloc_vsize = _evreloc - _reloc;
+  _reloc_size = _ereloc - _reloc;
+  . = ALIGN(4096);
+  _data = .;
+  .dynamic  : { *(.dynamic) }
+  . = ALIGN(4096);
+  .data :
+  {
+   *(.sdata)
+   *(.data)
+   *(.data1)
+   *(.data.*)
+   *(.got.plt)
+   *(.got)
 
+   /*
+    * Note that these aren't the using the GNU "CONSTRUCTOR" output section
+    * command, so they don't start with a size.  Because of p2align and the
+    * end/END definitions, and the fact that they're mergeable, they can also
+    * have NULLs which aren't guaranteed to be at the end.
+    */
+   . = ALIGN(16);
+   __init_array_start = .;
+   *(SORT(.init_array.*))
+   *(.init_array)
+   __init_array_end = .;
+  . = ALIGN(16);
+   __CTOR_LIST__ = .;
+   *(SORT(.ctors.*))
+   *(.ctors)
+   __CTOR_END__ = .;
+  . = ALIGN(16);
+   __DTOR_LIST__ = .;
+   *(SORT(.dtors.*))
+   *(.dtors)
+   __DTOR_END__ = .;
+   . = ALIGN(16);
+   __fini_array_start = .;
+   *(SORT(.fini_array.*))
+   *(.fini_array)
+   __fini_array_end = .;
 
-		/* the EFI loader doesn't seem to like a .bss section, so we stick
-		   it all into .data: */
-		. = ALIGN(16);
-		_bss = .;
-		*(.sbss)
-		*(.scommon)
-		*(.dynbss)
-		*(.bss*)
-		*(COMMON)
-		. = ALIGN(16);
-		_bss_end = .;
-	}
+   /* the EFI loader doesn't seem to like a .bss section, so we stick
+      it all into .data: */
+   . = ALIGN(16);
+   _bss = .;
+   *(.sbss)
+   *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(.bss.*)
+   *(COMMON)
+   . = ALIGN(16);
+   _bss_end = .;
+   _evdata = .;
+   . = ALIGN(4096);
+   _edata = .;
+  } =0
+  _data_vsize = _evdata - _data;
+  _data_size = _edata - _data;
 
-. = ALIGN(4096);
-.rela :
+  . = ALIGN(4096);
+  _rodata = .;
+  .rela :
   {
     *(.rela.text*)
     *(.rela.data*)
@@ -83,30 +102,41 @@ SECTIONS {
     *(.rela.fini_array*)
     *(.rela.ctors*)
     *(.rela.dtors*)
+
   }
-. = ALIGN(4096);
-.rela.plt : { *(.rela.plt) }
-. = ALIGN(4096);
-.rodata : { *(.rodata*) }
-	_edata = .;
-	_data_size = _edata - _data;
+  . = ALIGN(4096);
+  .rela.plt : { *(.rela.plt) }
+  . = ALIGN(4096);
+  .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) }
-	. = ALIGN(4096);
-.dynstr   :
-	{ *(.dynstr) }
-	. = ALIGN(4096);
-.note.gnu.build-id :
-	{ *(.note.gnu.build-id) }
-. = DATA_SEGMENT_END (.);
-/DISCARD/ :
-	{
-		*(.rel.reloc)
-		*(.eh_frame)
-		*(.note.GNU-stack)
-	}
-.comment 0 :
-	{ *(.comment) }
+  . = ALIGN(4096);
+  .dynsym   : { *(.dynsym) }
+  . = ALIGN(4096);
+  .dynstr   : { *(.dynstr) }
+  . = ALIGN(4096);
+  .note.gnu.build-id : { *(.note.gnu.build-id) }
+  . = ALIGN(4096);
+  .hash : { *(.hash) }
+  . = ALIGN(4096);
+  .gnu.hash : { *(.gnu.hash) }
+  . = ALIGN(4096);
+  .eh_frame : { *(.eh_frame) }
+  . = ALIGN(4096);
+  .gcc_except_table : { *(.gcc_except_table*) }
+  /DISCARD/ :
+  {
+    *(.rela.reloc)
+    *(.note.GNU-stack)
+  }
+  .comment 0 : { *(.comment) }
 }
+