hrev53247 adds 2 changesets to branch 'master'
old head: 19d1cffe33373572da33f477596411ce4e0cb965
new head: c90c06ef59d77e980a13b65ac984f40bc2528dc4
overview:
https://git.haiku-os.org/haiku/log/?qt=range&q=c90c06ef59d7+%5E19d1cffe3337
----------------------------------------------------------------------------
076b19023f39: elf2aout: import from FreeBSD
The sparc openboot implementation can run executables in the a.out
format. We used to generate these using objcopy, but this does not work
anymore as binutils is deprecating a.out format support.
- Import elf2aout from FreeBSD
- Add some missing bits to our elf.h and have a copy of it in the build
headers so it can be used to build elf2aout for the host platform
(tested for Linux)
- Use it to generate the sparc haiku_loader
- Adjust the bootloader linker script to have two "program headers": one
that is not loadable and contains the ELF headers, and the second one
that is loadable and contains the actual code and data. Unlike
objcopy, elf2aout relies only on the program headers to know what to
put in its output file (sections are ignored), so this is required
otherwise we end up with the ELF header nested inside the a.out file,
and everything offset from the expected load address as a result.
Confirmed that this allows to build the loader and run it as far as
before, so I'm back to needing to implement some MMU support now.
FreeBSD commit: 7551d83c353e040b32c6ac205e577dbc5f2c8955
Change-Id: I90b48e578fa7f148aeddd8c5998fdddc5cfa73fa
Reviewed-on: https://review.haiku-os.org/c/1557
Reviewed-by: Adrien Destugues <pulkomandy@xxxxxxxxx>
[ Adrien Destugues <pulkomandy@xxxxxxxxxxxxx> ]
c90c06ef59d7: sparc: documentation about the boot process and useful commands
I didn't do anything with sparc for a few weeks (you don't want this
machine running when temperatures already are over 30°...), and I wastd
some time finding back some of the useful information, such as commands
to boot and debug, load and execution address of the bootloader program,
etc. So let's keep these in the documentation directory.
Change-Id: I293e0eea3063d410d66f9b2397c2cf0bdbfc6753
Reviewed-on: https://review.haiku-os.org/c/1581
Reviewed-by: waddlesplash <waddlesplash@xxxxxxxxx>
[ PulkoMandy <pulkomandy@xxxxxxxxxxxxx> ]
----------------------------------------------------------------------------
7 files changed, 1145 insertions(+), 16 deletions(-)
docs/develop/kernel/arch/sparc/openboot.txt | 21 +-
headers/build/os/kernel/elf.h | 934 +++++++++++++++++++
headers/os/kernel/elf.h | 9 +
src/system/boot/Jamfile | 13 +-
.../ldscripts/sparc/boot_loader_openfirmware.ld | 14 +-
src/tools/Jamfile | 7 +-
src/tools/elf2aout.c | 163 ++++
############################################################################
Commit: 076b19023f391d3ebb0015e4524f38b98b2afc2d
URL: https://git.haiku-os.org/haiku/commit/?id=076b19023f39
Author: Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
Date: Mon Jul 1 19:58:20 2019 UTC
Committer: waddlesplash <waddlesplash@xxxxxxxxx>
Commit-Date: Sat Jul 13 01:29:05 2019 UTC
elf2aout: import from FreeBSD
The sparc openboot implementation can run executables in the a.out
format. We used to generate these using objcopy, but this does not work
anymore as binutils is deprecating a.out format support.
- Import elf2aout from FreeBSD
- Add some missing bits to our elf.h and have a copy of it in the build
headers so it can be used to build elf2aout for the host platform
(tested for Linux)
- Use it to generate the sparc haiku_loader
- Adjust the bootloader linker script to have two "program headers": one
that is not loadable and contains the ELF headers, and the second one
that is loadable and contains the actual code and data. Unlike
objcopy, elf2aout relies only on the program headers to know what to
put in its output file (sections are ignored), so this is required
otherwise we end up with the ELF header nested inside the a.out file,
and everything offset from the expected load address as a result.
Confirmed that this allows to build the loader and run it as far as
before, so I'm back to needing to implement some MMU support now.
FreeBSD commit: 7551d83c353e040b32c6ac205e577dbc5f2c8955
Change-Id: I90b48e578fa7f148aeddd8c5998fdddc5cfa73fa
Reviewed-on: https://review.haiku-os.org/c/1557
Reviewed-by: Adrien Destugues <pulkomandy@xxxxxxxxx>
----------------------------------------------------------------------------
diff --git a/headers/build/os/kernel/elf.h b/headers/build/os/kernel/elf.h
new file mode 100644
index 0000000000..c8ab1a87a5
--- /dev/null
+++ b/headers/build/os/kernel/elf.h
@@ -0,0 +1,934 @@
+/*
+ * Copyright 2002-2016 Haiku, Inc. All rights reserved.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef _ELF_H
+#define _ELF_H
+
+
+#include <SupportDefs.h>
+#include <ByteOrder.h>
+
+
+typedef uint32 Elf32_Addr;
+typedef uint16 Elf32_Half;
+typedef uint32 Elf32_Off;
+typedef int32 Elf32_Sword;
+typedef uint32 Elf32_Word;
+
+typedef Elf32_Half Elf32_Versym;
+
+typedef uint64 Elf64_Addr;
+typedef uint64 Elf64_Off;
+typedef uint16 Elf64_Half;
+typedef uint32 Elf64_Word;
+typedef int32 Elf64_Sword;
+typedef uint64 Elf64_Xword;
+typedef int64 Elf64_Sxword;
+
+typedef Elf64_Half Elf64_Versym;
+
+
+/*** ELF header ***/
+
+#define EI_NIDENT 16
+
+typedef struct {
+ uint8 e_ident[EI_NIDENT];
+ Elf32_Half e_type;
+ Elf32_Half e_machine;
+ Elf32_Word e_version;
+ Elf32_Addr e_entry;
+ Elf32_Off e_phoff;
+ Elf32_Off e_shoff;
+ Elf32_Word e_flags;
+ Elf32_Half e_ehsize;
+ Elf32_Half e_phentsize;
+ Elf32_Half e_phnum;
+ Elf32_Half e_shentsize;
+ Elf32_Half e_shnum;
+ Elf32_Half e_shstrndx;
+
+#ifdef __cplusplus
+ bool IsHostEndian() const;
+#endif
+} Elf32_Ehdr;
+
+typedef struct {
+ uint8 e_ident[EI_NIDENT];
+ Elf64_Half e_type;
+ Elf64_Half e_machine;
+ Elf64_Word e_version;
+ Elf64_Addr e_entry;
+ Elf64_Off e_phoff;
+ Elf64_Off e_shoff;
+ Elf64_Word e_flags;
+ Elf64_Half e_ehsize;
+ Elf64_Half e_phentsize;
+ Elf64_Half e_phnum;
+ Elf64_Half e_shentsize;
+ Elf64_Half e_shnum;
+ Elf64_Half e_shstrndx;
+
+#ifdef __cplusplus
+ bool IsHostEndian() const;
+#endif
+} Elf64_Ehdr;
+
+/* e_ident[] indices */
+#define EI_MAG0 0
+#define EI_MAG1 1
+#define EI_MAG2 2
+#define EI_MAG3 3
+#define EI_CLASS 4
+#define EI_DATA 5
+#define EI_VERSION 6
+#define EI_PAD 7
+
+/* Values for the magic number bytes. */
+#define ELFMAG0 0x7f
+#define ELFMAG1 'E'
+#define ELFMAG2 'L'
+#define ELFMAG3 'F'
+#define ELFMAG "\x7f""ELF"
+#define SELFMAG 4
+
+/* e_ident */
+#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
+ (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
+ (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
+ (ehdr).e_ident[EI_MAG3] == ELFMAG3)
+
+/* e_type (Object file type) */
+#define ET_NONE 0 /* No file type */
+#define ET_REL 1 /* Relocatable file */
+#define ET_EXEC 2 /* Executable file */
+#define ET_DYN 3 /* Shared-object file */
+#define ET_CORE 4 /* Core file */
+#define ET_LOOS 0xfe00 /* OS-specific range start */
+#define ET_HIOS 0xfeff /* OS-specific range end */
+#define ET_LOPROC 0xff00 /* Processor-specific range start */
+#define ET_HIPROC 0xffff /* Processor-specific range end */
+
+/* e_machine (Architecture) */
+#define EM_NONE 0 /* No machine */
+#define EM_M32 1 /* AT&T WE 32100 */
+#define EM_SPARC 2 /* Sparc */
+#define EM_386 3 /* Intel 80386 */
+#define EM_68K 4 /* Motorola m68k family */
+#define EM_88K 5 /* Motorola m88k family */
+#define EM_486 6 /* Intel 80486, Reserved for future use */
+#define EM_860 7 /* Intel 80860 */
+#define EM_MIPS 8 /* MIPS R3000 (officially, big-endian
only) */
+#define EM_S370 9 /* IBM System/370 */
+#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian, Deprecated */
+#define EM_PARISC 15 /* HPPA */
+#define EM_VPP550 17 /* Fujitsu VPP500 */
+#define EM_SPARC32PLUS 18 /* Sun "v8plus" */
+#define EM_960 19 /* Intel 80960 */
+#define EM_PPC 20 /* PowerPC */
+#define EM_PPC64 21 /* 64-bit PowerPC */
+#define EM_S390 22 /* IBM S/390 */
+#define EM_V800 36 /* NEC V800 series */
+#define EM_FR20 37 /* Fujitsu FR20 */
+#define EM_RH32 38 /* TRW RH32 */
+#define EM_MCORE 39 /* Motorola M*Core */
+#define EM_RCE 39 /* Old name for MCore */
+#define EM_ARM 40 /* ARM */
+#define EM_OLD_ALPHA 41 /* Digital Alpha */
+#define EM_SH 42 /* Renesas / SuperH SH */
+#define EM_SPARCV9 43 /* SPARC v9 64-bit */
+#define EM_TRICORE 44 /* Siemens Tricore embedded processor */
+#define EM_ARC 45 /* ARC Cores */
+#define EM_H8_300 46 /* Renesas H8/300 */
+#define EM_H8_300H 47 /* Renesas H8/300H */
+#define EM_H8S 48 /* Renesas H8S */
+#define EM_H8_500 49 /* Renesas H8/500 */
+#define EM_IA_64 50 /* Intel IA-64 Processor */
+#define EM_MIPS_X 51 /* Stanford MIPS-X */
+#define EM_COLDFIRE 52 /* Motorola Coldfire */
+#define EM_68HC12 53 /* Motorola M68HC12 */
+#define EM_MMA 54 /* Fujitsu Multimedia Accelerator */
+#define EM_PCP 55 /* Siemens PCP */
+#define EM_NCPU 56 /* Sony nCPU embedded RISC processor
*/
+#define EM_NDR1 57 /* Denso NDR1 microprocesspr */
+#define EM_STARCORE 58 /* Motorola Star*Core processor */
+#define EM_ME16 59 /* Toyota ME16 processor */
+#define EM_ST100 60 /* STMicroelectronics ST100 processor */
+#define EM_TINYJ 61 /* Advanced Logic Corp. TinyJ embedded
processor */
+#define EM_X86_64 62 /* Advanced Micro Devices X86-64 processor */
+#define EM_PDSP 63 /* Sony DSP Processor */
+#define EM_FX66 66 /* Siemens FX66 microcontroller */
+#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */
+#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */
+#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */
+#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */
+#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */
+#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */
+#define EM_SVX 73 /* Silicon Graphics SVx */
+#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc
*/
+#define EM_VAX 75 /* Digital VAX */
+#define EM_CRIS 76 /* Axis Communications 32-bit
embedded processor */
+#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded
processor */
+#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */
+#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */
+#define EM_MMIX 80 /* Donald Knuth's educational 64-bit
processor */
+#define EM_HUANY 81 /* Harvard University machine-independent
object files */
+#define EM_PRISM 82 /* SiTera Prism */
+#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */
+#define EM_FR30 84 /* Fujitsu FR30 */
+#define EM_D10V 85 /* Mitsubishi D10V */
+#define EM_D30V 86 /* Mitsubishi D30V */
+#define EM_V850 87 /* NEC v850 */
+#define EM_M32R 88 /* Mitsubishi M32R */
+#define EM_MN10300 89 /* Matsushita MN10300 */
+#define EM_MN10200 90 /* Matsushita MN10200 */
+#define EM_PJ 91 /* picoJava */
+#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */
+#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */
+#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */
+#define EM_VIDCORE 95 /* Alphamosaic VideoCore */
+#define EM_CR 103 /* Nat. Semi. CompactRISC microprocessor */
+#define EM_BLACKFIN 106 /* Analog Devices Blackfin (DSP) processor
*/
+#define EM_ARCA 109 /* Arca RISC Microprocessor */
+#define EM_VIDCORE3 137 /* Broadcom VideoCore III */
+#define EM_ARM64 183 /* ARM 64 bit */
+#define EM_AARCH64 EM_ARM64
+#define EM_AVR32 185 /* AVR-32 */
+#define EM_STM8 186 /* ST STM8S */
+#define EM_CUDA 190 /* Nvidia CUDA */
+#define EM_VIDCORE5 198 /* Broadcom VideoCore V */
+#define EM_NORC 218 /* Nanoradio Optimized RISC */
+#define EM_AMDGPU 224 /* AMD GPU */
+#define EM_RISCV 243 /* RISC-V */
+#define EM_BPF 247 /* Linux kernel bpf virtual machine */
+
+#define EM_ALPHA 0x9026 /* Digital Alpha (nonstandard, but the value
+ everyone
uses) */
+
+/* architecture class (EI_CLASS) */
+#define ELFCLASSNONE 0
+#define ELFCLASS32 1
+#define ELFCLASS64 2
+
+/* endian (EI_DATA) */
+#define ELFDATANONE 0 /* invalid */
+#define ELFDATA2LSB 1 /* little endian */
+#define ELFDATA2MSB 2 /* big endian */
+
+/* ELF version (EI_VERSION) */
+#define EV_NONE 0 /* invalid */
+#define EV_CURRENT 1 /* current version */
+
+/*** section header ***/
+
+typedef struct {
+ Elf32_Word sh_name;
+ Elf32_Word sh_type;
+ Elf32_Word sh_flags;
+ Elf32_Addr sh_addr;
+ Elf32_Off sh_offset;
+ Elf32_Word sh_size;
+ Elf32_Word sh_link;
+ Elf32_Word sh_info;
+ Elf32_Word sh_addralign;
+ Elf32_Word sh_entsize;
+} Elf32_Shdr;
+
+typedef struct {
+ Elf64_Word sh_name;
+ Elf64_Word sh_type;
+ Elf64_Xword sh_flags;
+ Elf64_Addr sh_addr;
+ Elf64_Off sh_offset;
+ Elf64_Xword sh_size;
+ Elf64_Word sh_link;
+ Elf64_Word sh_info;
+ Elf64_Xword sh_addralign;
+ Elf64_Xword sh_entsize;
+} Elf64_Shdr;
+
+/* special section indices */
+#define SHN_UNDEF 0
+#define SHN_LORESERVE 0xff00
+#define SHN_LOPROC 0xff00
+#define SHN_HIPROC 0xff1f
+#define SHN_ABS 0xfff1
+#define SHN_COMMON 0xfff2
+#define SHN_HIRESERVE 0xffff
+
+/* section header type */
+#define SHT_NULL 0
+#define SHT_PROGBITS 1
+#define SHT_SYMTAB 2
+#define SHT_STRTAB 3
+#define SHT_RELA 4
+#define SHT_HASH 5
+#define SHT_DYNAMIC 6
+#define SHT_NOTE 7
+#define SHT_NOBITS 8
+#define SHT_REL 9
+#define SHT_SHLIB 10
+#define SHT_DYNSYM 11
+
+#define SHT_GNU_verdef 0x6ffffffd /* version definition section */
+#define SHT_GNU_verneed 0x6ffffffe /* version needs section */
+#define SHT_GNU_versym 0x6fffffff /* version symbol table */
+
+#define SHT_LOPROC 0x70000000
+#define SHT_HIPROC 0x7fffffff
+#define SHT_LOUSER 0x80000000
+#define SHT_HIUSER 0xffffffff
+
+/* section header flags */
+#define SHF_WRITE 1
+#define SHF_ALLOC 2
+#define SHF_EXECINSTR 4
+
+#define SHF_MASKPROC 0xf0000000
+
+
+/*** program header ***/
+
+typedef struct {
+ Elf32_Word p_type;
+ Elf32_Off p_offset; /* offset from the beginning of the
file of the segment */
+ Elf32_Addr p_vaddr; /* virtual address for the segment in
memory */
+ Elf32_Addr p_paddr;
+ Elf32_Word p_filesz; /* the size of the segment in the file
*/
+ Elf32_Word p_memsz; /* the size of the segment in memory */
+ Elf32_Word p_flags;
+ Elf32_Word p_align;
+
+#ifdef __cplusplus
+ bool IsReadWrite() const;
+ bool IsExecutable() const;
+#endif
+} Elf32_Phdr;
+
+typedef struct {
+ Elf64_Word p_type;
+ Elf64_Word p_flags;
+ Elf64_Off p_offset; /* offset from the beginning of the
file of the segment */
+ Elf64_Addr p_vaddr; /* virtual address for the segment in
memory */
+ Elf64_Addr p_paddr;
+ Elf64_Xword p_filesz; /* the size of the segment in the file
*/
+ Elf64_Xword p_memsz; /* the size of the segment in memory */
+ Elf64_Xword p_align;
+
+#ifdef __cplusplus
+ bool IsReadWrite() const;
+ bool IsExecutable() const;
+#endif
+} Elf64_Phdr;
+
+/* program header segment types */
+#define PT_NULL 0
+#define PT_LOAD 1
+#define PT_DYNAMIC 2
+#define PT_INTERP 3
+#define PT_NOTE 4
+#define PT_SHLIB 5
+#define PT_PHDR 6
+#define PT_TLS 7
+#define PT_EH_FRAME 0x6474e550
+#define PT_STACK 0x6474e551
+#define PT_RELRO 0x6474e552
+
+#define PT_LOPROC 0x70000000
+#define PT_ARM_UNWIND 0x70000001
+#define PT_HIPROC 0x7fffffff
+
+/* program header segment flags */
+#define PF_EXECUTE 0x1
+#define PF_WRITE 0x2
+#define PF_READ 0x4
+#define PF_PROTECTION_MASK (PF_EXECUTE | PF_WRITE | PF_READ)
+
+#define PF_MASKPROC 0xf0000000
+
+
+/* symbol table entry */
+
+typedef struct {
+ Elf32_Word st_name;
+ Elf32_Addr st_value;
+ Elf32_Word st_size;
+ uint8 st_info;
+ uint8 st_other;
+ Elf32_Half st_shndx;
+
+#ifdef __cplusplus
+ uint8 Bind() const;
+ uint8 Type() const;
+ void SetInfo(uint8 bind, uint8 type);
+#endif
+} Elf32_Sym;
+
+typedef struct {
+ Elf64_Word st_name;
+ uint8 st_info;
+ uint8 st_other;
+ Elf64_Half st_shndx;
+ Elf64_Addr st_value;
+ Elf64_Xword st_size;
+
+#ifdef __cplusplus
+ uint8 Bind() const;
+ uint8 Type() const;
+ void SetInfo(uint8 bind, uint8 type);
+#endif
+} Elf64_Sym;
+
+#define ELF32_ST_BIND(i) ((i) >> 4)
+#define ELF32_ST_TYPE(i) ((i) & 0xf)
+#define ELF32_ST_INFO(b, t) (((b) << 4) + ((t) & 0xf))
+
+#define ELF64_ST_BIND(i) ((i) >> 4)
+#define ELF64_ST_TYPE(i) ((i) & 0xf)
+#define ELF64_ST_INFO(b, t) (((b) << 4) + ((t) & 0xf))
+
+/* symbol types */
+#define STT_NOTYPE 0
+#define STT_OBJECT 1
+#define STT_FUNC 2
+#define STT_SECTION 3
+#define STT_FILE 4
+#define STT_TLS 6
+#define STT_LOPROC 13
+#define STT_HIPROC 15
+
+/* symbol binding */
+#define STB_LOCAL 0
+#define STB_GLOBAL 1
+#define STB_WEAK 2
+#define STB_LOPROC 13
+#define STB_HIPROC 15
+
+/* special symbol indices */
+#define STN_UNDEF 0
+
+
+/* relocation table entry */
+
+typedef struct {
+ Elf32_Addr r_offset;
+ Elf32_Word r_info;
+
+#ifdef __cplusplus
+ uint8 SymbolIndex() const;
+ uint8 Type() const;
+#endif
+} Elf32_Rel;
+
+typedef struct {
+ Elf64_Addr r_offset;
+ Elf64_Xword r_info;
+
+#ifdef __cplusplus
+ uint8 SymbolIndex() const;
+ uint8 Type() const;
+#endif
+} Elf64_Rel;
+
+#ifdef __cplusplus
+typedef struct Elf32_Rela : public Elf32_Rel {
+#else
+typedef struct {
+ Elf32_Addr r_offset;
+ Elf32_Word r_info;
+#endif
+ Elf32_Sword r_addend;
+} Elf32_Rela;
+
+#ifdef __cplusplus
+typedef struct Elf64_Rela : public Elf64_Rel {
+#else
+typedef struct {
+ Elf64_Addr r_offset;
+ Elf64_Xword r_info;
+#endif
+ Elf64_Sxword r_addend;
+} Elf64_Rela;
+
+#define ELF32_R_SYM(i) ((i) >> 8)
+#define ELF32_R_TYPE(i) ((unsigned char)(i))
+#define ELF32_R_INFO(s, t) (((s) << 8) + (unsigned char)(t))
+
+#define ELF64_R_SYM(i) ((i) >> 32)
+#define ELF64_R_TYPE(i) ((i) & 0xffffffffL)
+#define ELF64_R_INFO(s, t) ((((Elf64_Xword)(s)) << 32) + ((t) & 0xffffffffL))
+
+
+/* dynamic section entry */
+
+typedef struct {
+ Elf32_Sword d_tag;
+ union {
+ Elf32_Word d_val;
+ Elf32_Addr d_ptr;
+ } d_un;
+} Elf32_Dyn;
+
+typedef struct {
+ Elf64_Sxword d_tag;
+ union {
+ Elf64_Xword d_val;
+ Elf64_Addr d_ptr;
+ } d_un;
+} Elf64_Dyn;
+
+/* dynamic entry type */
+#define DT_NULL 0
+#define DT_NEEDED 1
+#define DT_PLTRELSZ 2
+#define DT_PLTGOT 3
+#define DT_HASH 4
+#define DT_STRTAB 5
+#define DT_SYMTAB 6
+#define DT_RELA 7
+#define DT_RELASZ 8
+#define DT_RELAENT 9
+#define DT_STRSZ 10
+#define DT_SYMENT 11
+#define DT_INIT 12
+#define DT_FINI 13
+#define DT_SONAME 14
+#define DT_RPATH 15
+#define DT_SYMBOLIC 16
+#define DT_REL 17
+#define DT_RELSZ 18
+#define DT_RELENT 19
+#define DT_PLTREL 20
+#define DT_DEBUG 21
+#define DT_TEXTREL 22
+#define DT_JMPREL 23
+#define DT_BIND_NOW 24 /* no lazy binding */
+#define DT_INIT_ARRAY 25 /* init function array */
+#define DT_FINI_ARRAY 26 /* termination function array */
+#define DT_INIT_ARRAYSZ 27 /* init function array size */
+#define DT_FINI_ARRAYSZ 28 /* termination function array
size */
+#define DT_RUNPATH 29 /* library search path
(supersedes DT_RPATH) */
+#define DT_FLAGS 30 /* flags (see below) */
+#define DT_ENCODING 32
+#define DT_PREINIT_ARRAY 32 /* preinitialization array */
+#define DT_PREINIT_ARRAYSZ 33 /* preinitialization array size */
+
+#define DT_VERSYM 0x6ffffff0 /* symbol version table */
+#define DT_VERDEF 0x6ffffffc /* version definition table */
+#define DT_VERDEFNUM 0x6ffffffd /* number of version definitions */
+#define DT_VERNEED 0x6ffffffe /* table with needed versions */
+#define DT_VERNEEDNUM 0x6fffffff /* number of needed versions */
+
+#define DT_LOPROC 0x70000000
+#define DT_HIPROC 0x7fffffff
+
+/* DT_FLAGS values */
+#define DF_ORIGIN 0x01
+#define DF_SYMBOLIC 0x02
+#define DF_TEXTREL 0x04
+#define DF_BIND_NOW 0x08
+#define DF_STATIC_TLS 0x10
+
+
+/* version definition section */
+
+typedef struct {
+ Elf32_Half vd_version; /* version revision */
+ Elf32_Half vd_flags; /* version information flags */
+ Elf32_Half vd_ndx; /* version index as specified
in the
+ symbol
version table */
+ Elf32_Half vd_cnt; /* number of associated verdaux
entries */
+ Elf32_Word vd_hash; /* version name hash value */
+ Elf32_Word vd_aux; /* byte offset to verdaux array
*/
+ Elf32_Word vd_next; /* byte offset to next verdef
entry */
+} Elf32_Verdef;
+
+typedef struct {
+ Elf64_Half vd_version; /* version revision */
+ Elf64_Half vd_flags; /* version information flags */
+ Elf64_Half vd_ndx; /* version index as specified
in the
+ symbol
version table */
+ Elf64_Half vd_cnt; /* number of associated verdaux
entries */
+ Elf64_Word vd_hash; /* version name hash value */
+ Elf64_Word vd_aux; /* byte offset to verdaux array
*/
+ Elf64_Word vd_next; /* byte offset to next verdef
entry */
+} Elf64_Verdef;
+
+/* values for vd_version (version revision) */
+#define VER_DEF_NONE 0 /* no version */
+#define VER_DEF_CURRENT 1 /* current version */
+#define VER_DEF_NUM 2 /* given version number
*/
+
+/* values for vd_flags (version information flags) */
+#define VER_FLG_BASE 0x1 /* version definition of file
itself */
+#define VER_FLG_WEAK 0x2 /* weak version identifier */
+
+/* values for versym symbol index */
+#define VER_NDX_LOCAL 0 /* symbol is local */
+#define VER_NDX_GLOBAL 1 /* symbol is global/unversioned
*/
+#define VER_NDX_INITIAL 2 /* initial version --
that's the one given
+ to
symbols when a library becomes
+
versioned; handled by the linker (and
+
runtime loader) similar to
+
VER_NDX_GLOBAL */
+#define VER_NDX_LORESERVE 0xff00 /* beginning of reserved entries */
+#define VER_NDX_ELIMINATE 0xff01 /* symbol is to be eliminated */
+
+#define VER_NDX_FLAG_HIDDEN 0x8000 /* flag: version is hidden */
+#define VER_NDX_MASK 0x7fff /* mask to get the actual version index
*/
+#define VER_NDX(x) ((x) & VER_NDX_MASK)
+
+
+/* auxiliary version information */
+
+typedef struct {
+ Elf32_Word vda_name; /* string table offset to
version or dependency
+ name */
+ Elf32_Word vda_next; /* byte offset to next verdaux
entry */
+} Elf32_Verdaux;
+
+typedef struct {
+ Elf64_Word vda_name; /* string table offset to
version or dependency
+ name */
+ Elf64_Word vda_next; /* byte offset to next verdaux
entry */
+} Elf64_Verdaux;
+
+
+/* version dependency section */
+
+typedef struct {
+ Elf32_Half vn_version; /* version of structure */
+ Elf32_Half vn_cnt; /* number of associated vernaux
entries */
+ Elf32_Word vn_file; /* byte offset to file name for
this
+ dependency */
+ Elf32_Word vn_aux; /* byte offset to vernaux array
*/
+ Elf32_Word vn_next; /* byte offset to next verneed
entry */
+} Elf32_Verneed;
+
+typedef struct {
+ Elf64_Half vn_version; /* version of structure */
+ Elf64_Half vn_cnt; /* number of associated vernaux
entries */
+ Elf64_Word vn_file; /* byte offset to file name for
this
+ dependency */
+ Elf64_Word vn_aux; /* byte offset to vernaux array
*/
+ Elf64_Word vn_next; /* byte offset to next verneed
entry */
+} Elf64_Verneed;
+
+/* values for vn_version (version revision) */
+#define VER_NEED_NONE 0 /* no version */
+#define VER_NEED_CURRENT 1 /* current version */
+#define VER_NEED_NUM 2 /* given version number */
+
+
+/* auxiliary needed version information */
+
+typedef struct {
+ Elf32_Word vna_hash; /* dependency name hash value */
+ Elf32_Half vna_flags; /* dependency specific
information flags */
+ Elf32_Half vna_other; /* version index as specified
in the symbol
+ version
table */
+ Elf32_Word vna_name; /* string table offset to
dependency name */
+ Elf32_Word vna_next; /* byte offset to next vernaux
entry */
+} Elf32_Vernaux;
+
+typedef struct {
+ Elf64_Word vna_hash; /* dependency name hash value */
+ Elf64_Half vna_flags; /* dependency specific
information flags */
+ Elf64_Half vna_other; /* version index as specified
in the symbol
+ version
table */
+ Elf64_Word vna_name; /* string table offset to
dependency name */
+ Elf64_Word vna_next; /* byte offset to next vernaux
entry */
+} Elf64_Vernaux;
+
+/* values for vna_flags */
+#define VER_FLG_WEAK 0x2 /* weak version identifier */
+
+
+/*** core files ***/
+
+/* note section header */
+
+typedef struct {
+ Elf32_Word n_namesz; /* length of the note's name */
+ Elf32_Word n_descsz; /* length of the note's descriptor */
+ Elf32_Word n_type; /* note type */
+} Elf32_Nhdr;
+
+typedef struct {
+ Elf64_Word n_namesz; /* length of the note's name */
+ Elf64_Word n_descsz; /* length of the note's descriptor */
+ Elf64_Word n_type; /* note type */
+} Elf64_Nhdr;
+
+/* values for note name */
+#define ELF_NOTE_CORE "CORE"
+#define ELF_NOTE_HAIKU "Haiku"
+
+/* values for note type (n_type) */
+/* ELF_NOTE_CORE/... */
+#define NT_FILE 0x46494c45 /* mapped files */
+
+/* ELF_NOTE_HAIKU/... */
+#define NT_TEAM 0x7465616d /* team */
+#define NT_AREAS 0x61726561 /* areas */
+#define NT_IMAGES 0x696d6167 /* images */
+#define NT_THREADS 0x74687264 /* threads */
+#define NT_SYMBOLS 0x73796d73 /* symbols */
+
+/* NT_TEAM: uint32 entrySize; Elf32_Note_Team; char[] args */
+typedef struct {
+ int32 nt_id; /* team ID */
+ int32 nt_uid; /* team owner ID */
+ int32 nt_gid; /* team group ID */
+} Elf32_Note_Team;
+
+typedef Elf32_Note_Team Elf64_Note_Team;
+
+/* NT_AREAS:
+ * uint32 count;
+ * uint32 entrySize;
+ * Elf32_Note_Area_Entry[count];
+ * char[] names
+ */
+typedef struct {
+ int32 na_id; /* area ID */
+ uint32 na_lock; /* lock type
(B_NO_LOCK, ...) */
+ uint32 na_protection; /* protection (B_READ_AREA |
...) */
+ uint32 na_base; /* area base address */
+ uint32 na_size; /* area size */
+ uint32 na_ram_size; /* physical memory used */
+} Elf32_Note_Area_Entry;
+
+/* NT_AREAS:
+ * uint32 count;
+ * uint32 entrySize;
+ * Elf64_Note_Area_Entry[count];
+ * char[] names
+ */
+typedef struct {
+ int32 na_id; /* area ID */
+ uint32 na_lock; /* lock type
(B_NO_LOCK, ...) */
+ uint32 na_protection; /* protection (B_READ_AREA |
...) */
+ uint32 na_pad1;
+ uint64 na_base; /* area base address */
+ uint64 na_size; /* area size */
+ uint64 na_ram_size; /* physical memory used */
+} Elf64_Note_Area_Entry;
+
+/* NT_IMAGES:
+ * uint32 count;
+ * uint32 entrySize;
+ * Elf32_Note_Image_Entry[count];
+ * char[] names
+ */
+typedef struct {
+ int32 ni_id; /* image ID */
+ int32 ni_type; /* image type
(B_APP_IMAGE, ...) */
+ uint32 ni_init_routine; /* address of init function */
+ uint32 ni_term_routine; /* address of termination
function */
+ int32 ni_device; /* device ID of mapped
file */
+ int64 ni_node; /* node ID of mapped
file */
+ uint32 ni_text_base; /* base address of text segment
*/
+ uint32 ni_text_size; /* size of text segment */
+ int32 ni_text_delta; /* delta of the text segment
relative to
+ load
address specified in the ELF file */
+ uint32 ni_data_base; /* base address of data segment
*/
+ uint32 ni_data_size; /* size of data segment */
+ uint32 ni_symbol_table; /* address of dynamic symbol
table */
+ uint32 ni_symbol_hash; /* address of dynamic symbol
hash */
+ uint32 ni_string_table; /* address of dynamic string
table */
+} Elf32_Note_Image_Entry;
+
+/* NT_IMAGES:
+ * uint32 count;
+ * uint32 entrySize;
+ * Elf64_Note_Image_Entry[count];
+ * char[] names
+ */
+typedef struct {
+ int32 ni_id; /* image ID */
+ int32 ni_type; /* image type
(B_APP_IMAGE, ...) */
+ uint64 ni_init_routine; /* address of init function */
+ uint64 ni_term_routine; /* address of termination
function */
+ uint32 ni_pad1;
+ int32 ni_device; /* device ID of mapped
file */
+ int64 ni_node; /* node ID of mapped
file */
+ uint64 ni_text_base; /* base address of text segment
*/
+ uint64 ni_text_size; /* size of text segment */
+ int64 ni_text_delta; /* delta of the text segment
relative to
+ load
address specified in the ELF file */
+ uint64 ni_data_base; /* base address of data segment
*/
+ uint64 ni_data_size; /* size of data segment */
+ uint64 ni_symbol_table; /* address of dynamic symbol
table */
+ uint64 ni_symbol_hash; /* address of dynamic symbol
hash */
+ uint64 ni_string_table; /* address of dynamic string
table */
+} Elf64_Note_Image_Entry;
+
+/* NT_THREADS:
+ * uint32 count;
+ * uint32 entrySize;
+ * uint32 cpuStateSize;
+ * {Elf32_Note_Thread_Entry, uint8[cpuStateSize] cpuState}[count];
+ * char[] names
+ */
+typedef struct {
+ int32 nth_id; /* thread ID */
+ int32 nth_state; /* thread state
(B_THREAD_RUNNING, ...) */
+ int32 nth_priority; /* thread priority */
+ uint32 nth_stack_base; /* thread stack base address */
+ uint32 nth_stack_end; /* thread stack end address */
+} Elf32_Note_Thread_Entry;
+
+/* NT_THREADS:
+ * uint32 count;
+ * uint32 entrySize;
+ * uint32 cpuStateSize;
+ * {Elf64_Note_Thread_Entry, uint8[cpuStateSize] cpuState}[count];
+ * char[] names
+ */
+typedef struct {
+ int32 nth_id; /* thread ID */
+ int32 nth_state; /* thread state
(B_THREAD_RUNNING, ...) */
+ int32 nth_priority; /* thread priority */
+ uint32 nth_pad1;
+ uint64 nth_stack_base; /* thread stack base address */
+ uint64 nth_stack_end; /* thread stack end address */
+} Elf64_Note_Thread_Entry;
+
+/* NT_SYMBOLS:
+ * int32 imageId;
+ * uint32 symbolCount;
+ * uint32 entrySize;
+ * Elf{32,64}_Sym[count];
+ * char[] strings
+ */
+
+
+/*** inline functions ***/
+
+#ifdef __cplusplus
+
+inline bool
+Elf32_Ehdr::IsHostEndian() const
+{
+#if B_HOST_IS_LENDIAN
+ return e_ident[EI_DATA] == ELFDATA2LSB;
+#elif B_HOST_IS_BENDIAN
+ return e_ident[EI_DATA] == ELFDATA2MSB;
+#endif
+}
+
+
+inline bool
+Elf64_Ehdr::IsHostEndian() const
+{
+#if B_HOST_IS_LENDIAN
+ return e_ident[EI_DATA] == ELFDATA2LSB;
+#elif B_HOST_IS_BENDIAN
+ return e_ident[EI_DATA] == ELFDATA2MSB;
+#endif
+}
+
+
+inline bool
+Elf32_Phdr::IsReadWrite() const
+{
+ return !(~p_flags & (PF_READ | PF_WRITE));
+}
+
+
+inline bool
+Elf32_Phdr::IsExecutable() const
+{
+ return (p_flags & PF_EXECUTE) != 0;
+}
+
+
+inline bool
+Elf64_Phdr::IsReadWrite() const
+{
+ return !(~p_flags & (PF_READ | PF_WRITE));
+}
+
+
+inline bool
+Elf64_Phdr::IsExecutable() const
+{
+ return (p_flags & PF_EXECUTE) != 0;
+}
+
+
+inline uint8
+Elf32_Sym::Bind() const
+{
+ return ELF32_ST_BIND(st_info);
+}
+
+
+inline uint8
+Elf32_Sym::Type() const
+{
+ return ELF32_ST_TYPE(st_info);
+}
+
+
+inline void
+Elf32_Sym::SetInfo(uint8 bind, uint8 type)
+{
+ st_info = ELF32_ST_INFO(bind, type);
+}
+
+
+inline uint8
+Elf64_Sym::Bind() const
+{
+ return ELF64_ST_BIND(st_info);
+}
+
+
+inline uint8
+Elf64_Sym::Type() const
+{
+ return ELF64_ST_TYPE(st_info);
+}
+
+
+inline void
+Elf64_Sym::SetInfo(uint8 bind, uint8 type)
+{
+ st_info = ELF64_ST_INFO(bind, type);
+}
+
+
+inline uint8
+Elf32_Rel::SymbolIndex() const
+{
+ return ELF32_R_SYM(r_info);
+}
+
+
+inline uint8
+Elf32_Rel::Type() const
+{
+ return ELF32_R_TYPE(r_info);
+}
+
+
+inline uint8
+Elf64_Rel::SymbolIndex() const
+{
+ return ELF64_R_SYM(r_info);
+}
+
+
+inline uint8
+Elf64_Rel::Type() const
+{
+ return ELF64_R_TYPE(r_info);
+}
+
+#endif /* __cplusplus */
+
+
+#endif /* _ELF_H */
diff --git a/headers/os/kernel/elf.h b/headers/os/kernel/elf.h
index d4deca9c2e..c8ab1a87a5 100644
--- a/headers/os/kernel/elf.h
+++ b/headers/os/kernel/elf.h
@@ -93,6 +93,12 @@ typedef struct {
#define ELFMAG "\x7f""ELF"
#define SELFMAG 4
+/* e_ident */
+#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
+ (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
+ (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
+ (ehdr).e_ident[EI_MAG3] == ELFMAG3)
+
/* e_type (Object file type) */
#define ET_NONE 0 /* No file type */
#define ET_REL 1 /* Relocatable file */
@@ -197,6 +203,9 @@ typedef struct {
#define EM_RISCV 243 /* RISC-V */
#define EM_BPF 247 /* Linux kernel bpf virtual machine */
+#define EM_ALPHA 0x9026 /* Digital Alpha (nonstandard, but the value
+ everyone
uses) */
+
/* architecture class (EI_CLASS) */
#define ELFCLASSNONE 0
#define ELFCLASS32 1
diff --git a/src/system/boot/Jamfile b/src/system/boot/Jamfile
index b89309dc16..5a25917a61 100644
--- a/src/system/boot/Jamfile
+++ b/src/system/boot/Jamfile
@@ -28,17 +28,14 @@ rule BuildOpenFirmwareLoader {
rule BuildAoutLoader {
local haikuLoader = $(1) ;
local bootLoader = $(2) ;
- switch $(TARGET_ARCH) {
- case sparc :
- AOUT_FORMAT on $(haikuLoader) = a.out-sunos-big ;
- case * :
- Exit "Currently unsupported coff arch:" $(TARGET_ARCH) ;
- }
+ ELF2AOUT on $(haikuLoader) = <build>elf2aout ;
+ Depends $(haikuLoader) : <build>elf2aout ;
}
-actions BuildAoutLoader {
+actions BuildAoutLoader bind ELF2AOUT {
rm -f $(1)
- $(TARGET_OBJCOPY_$(TARGET_PACKAGING_ARCH)) -O $(AOUT_FORMAT) --impure
-S $(2) $(1)
+ $(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR)
+ $(ELF2AOUT) -o $(1) $(2)
}
diff --git a/src/system/ldscripts/sparc/boot_loader_openfirmware.ld
b/src/system/ldscripts/sparc/boot_loader_openfirmware.ld
index 18b9e9b63d..d037f79b1d 100644
--- a/src/system/ldscripts/sparc/boot_loader_openfirmware.ld
+++ b/src/system/ldscripts/sparc/boot_loader_openfirmware.ld
@@ -3,6 +3,14 @@ OUTPUT_ARCH(sparc:v9)
ENTRY(_start)
+PHDRS
+{
+ /* have a non-loadable program chunk with the headers, then a loadable
one
+ * with the actual data. This eases the work of elf2aout. */
+ headers PT_NULL FILEHDR PHDRS ;
+ text PT_LOAD ;
+}
+
SECTIONS
{
/* Execution address. The file is loaded at 0x4000 with its header,
@@ -23,7 +31,7 @@ SECTIONS
*(.text .text.* .gnu.linkonce.t.*)
*(.rodata .rodata.* .gnu.linkonce.r.*)
- *(.sdata2) }
+ *(.sdata2) } :text
.data : {
__ctor_list = .;
@@ -34,7 +42,7 @@ SECTIONS
*(.data .gnu.linkonce.d.*)
*(.data.rel.ro.local .data.rel.ro*)
*(.got .got2)
- *(.sdata .sdata.* .gnu.linkonce.s.* .fixup) }
+ *(.sdata .sdata.* .gnu.linkonce.s.* .fixup) } :text
/* uninitialized data (in same segment as writable data) */
__bss_start = .;
@@ -42,7 +50,7 @@ SECTIONS
*(.bss .bss.* .gnu.linkonce.b.*)
. = ALIGN(0x1000);
- }
+ } :text
_end = . ;
diff --git a/src/tools/Jamfile b/src/tools/Jamfile
index 680646e837..b5227d92a3 100644
--- a/src/tools/Jamfile
+++ b/src/tools/Jamfile
@@ -4,9 +4,10 @@ UsePrivateBuildHeaders app storage ;
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src/bin ] ;
-local tools =
+local beapi_tools =
<build>catattr
<build>copyattr
+ <build>elf2aout
<build>generate_attribute_stores
<build>listattr
<build>mimeset
@@ -19,7 +20,7 @@ local tools =
<build>generate_boot_screen
;
-USES_BE_API on $(tools) = true ;
+USES_BE_API on $(beapi_tools) = true ;
BuildPlatformMain <build>catattr : catattr.cpp : $(HOST_LIBBE) ;
@@ -32,6 +33,8 @@ BuildPlatformMain <build>create_image : create_image.cpp :
$(HOST_LIBSUPC++) ;
BuildPlatformMain <build>data_to_source : data_to_source.cpp
: $(HOST_LIBSUPC++) ;
+BuildPlatformMain <build>elf2aout : elf2aout.c : ;
+
BuildPlatformMain <build>generate_attribute_stores
: generate_attribute_stores.cpp : $(HOST_LIBBE) $(HOST_LIBSUPC++) ;
diff --git a/src/tools/elf2aout.c b/src/tools/elf2aout.c
new file mode 100644
index 0000000000..e5f449ce9f
--- /dev/null
+++ b/src/tools/elf2aout.c
@@ -0,0 +1,163 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2002 Jake Burkholder
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <elf.h>
+
+#define xe16toh(x) ((data == ELFDATA2MSB) ? be16toh(x) :
le16toh(x))
+#define xe32toh(x) ((data == ELFDATA2MSB) ? be32toh(x) :
le32toh(x))
+#define xe64toh(x) ((data == ELFDATA2MSB) ? be64toh(x) :
le64toh(x))
+#define htoxe32(x) ((data == ELFDATA2MSB) ? htobe32(x) :
htole32(x))
+
+struct exec {
+ u_int32_t a_magic;
+ u_int32_t a_text;
+ u_int32_t a_data;
+ u_int32_t a_bss;
+ u_int32_t a_syms;
+ u_int32_t a_entry;
+ u_int32_t a_trsize;
+ u_int32_t a_drsize;
+};
+#define A_MAGIC 0x01030107
+
+static void usage(void);
+
+/*
+ * elf to a.out converter for freebsd/sparc64 bootblocks.
+ */
+int
+main(int ac, char **av)
+{
+ Elf64_Half phentsize;
+ Elf64_Half machine;
+ Elf64_Half phnum;
+ Elf64_Xword filesz;
+ Elf64_Xword memsz;
+ Elf64_Addr entry;
+ Elf64_Off offset;
+ Elf64_Off phoff;
+ Elf64_Word type;
+ unsigned char data;
+ struct stat sb;
+ struct exec a;
+ Elf64_Phdr *p;
+ Elf64_Ehdr *e;
+ void *v;
+ int efd;
+ int fd;
+ int c;
+ int i;
+
+ fd = STDIN_FILENO;
+ while ((c = getopt(ac, av, "o:")) != -1)
+ switch (c) {
+ case 'o':
+ if ((fd = open(optarg, O_CREAT|O_RDWR, 0644)) < 0)
+ err(1, "%s", optarg);
+ break;
+ case '?':
+ default:
+ usage();
+ }
+ ac -= optind;
+ av += optind;
+ if (ac == 0)
+ usage();
+
+ if ((efd = open(*av, O_RDONLY)) < 0 || fstat(efd, &sb) < 0)
+ err(1, NULL);
+ v = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, efd, 0);
+ if ((e = v) == MAP_FAILED)
+ err(1, NULL);
+
+ if (!IS_ELF(*e))
+ errx(1, "not an elf file");
+ if (e->e_ident[EI_CLASS] != ELFCLASS64)
+ errx(1, "wrong class");
+ data = e->e_ident[EI_DATA];
+ if (data != ELFDATA2MSB && data != ELFDATA2LSB)
+ errx(1, "wrong data format");
+ if (e->e_ident[EI_VERSION] != EV_CURRENT)
+ errx(1, "wrong elf version");
+ machine = xe16toh(e->e_machine);
+ if (machine != EM_SPARCV9 && machine != EM_ALPHA)
+ errx(1, "wrong machine type");
+ phentsize = xe16toh(e->e_phentsize);
+ if (phentsize != sizeof(*p))
+ errx(1, "phdr size mismatch");
+
+ entry = xe64toh(e->e_entry);
+ phoff = xe64toh(e->e_phoff);
+ phnum = xe16toh(e->e_phnum);
+ p = (Elf64_Phdr *)((char *)e + phoff);
+ bzero(&a, sizeof(a));
+ for (i = 0; i < phnum; i++) {
+ type = xe32toh(p[i].p_type);
+ switch (type) {
+ case PT_LOAD:
+ if (a.a_magic != 0)
+ errx(1, "too many loadable segments");
+ filesz = xe64toh(p[i].p_filesz);
+ memsz = xe64toh(p[i].p_memsz);
+ offset = xe64toh(p[i].p_offset);
+ a.a_magic = htoxe32(A_MAGIC);
+ a.a_text = htoxe32(filesz);
+ a.a_bss = htoxe32(memsz - filesz);
+ a.a_entry = htoxe32(entry);
+ if (write(fd, &a, sizeof(a)) != sizeof(a) ||
+ write(fd, (char *)e + offset, filesz) !=
(ssize_t)filesz)
+ err(1, NULL);
+ break;
+ default:
+ break;
+ }
+ }
+
+ return (0);
+}
+
+static void
+usage(void)
+{
+
+ fprintf(stderr, "usage: elf2aout [-o outfile] infile\n");
+ exit(1);
+}
############################################################################
Revision: hrev53247
Commit: c90c06ef59d77e980a13b65ac984f40bc2528dc4
URL: https://git.haiku-os.org/haiku/commit/?id=c90c06ef59d7
Author: PulkoMandy <pulkomandy@xxxxxxxxxxxxx>
Date: Thu Jul 11 10:14:19 2019 UTC
Committer: waddlesplash <waddlesplash@xxxxxxxxx>
Commit-Date: Sat Jul 13 01:29:05 2019 UTC
sparc: documentation about the boot process and useful commands
I didn't do anything with sparc for a few weeks (you don't want this
machine running when temperatures already are over 30°...), and I wastd
some time finding back some of the useful information, such as commands
to boot and debug, load and execution address of the bootloader program,
etc. So let's keep these in the documentation directory.
Change-Id: I293e0eea3063d410d66f9b2397c2cf0bdbfc6753
Reviewed-on: https://review.haiku-os.org/c/1581
Reviewed-by: waddlesplash <waddlesplash@xxxxxxxxx>
----------------------------------------------------------------------------
diff --git a/docs/develop/kernel/arch/sparc/openboot.txt
b/docs/develop/kernel/arch/sparc/openboot.txt
index 7a5aab336f..b24068ab4c 100644
--- a/docs/develop/kernel/arch/sparc/openboot.txt
+++ b/docs/develop/kernel/arch/sparc/openboot.txt
@@ -6,8 +6,13 @@ Executable format
PowerPC uses COFF. Sparc uses a.out, which is a lot simpler. According to the
spec, some fields should be zeroed out, but they say implementation may chose
-to allow other values, so it's possible a standard a.out file would work as
-well.
+to allow other values, so a standard a.out file works as well.
+
+It used to be possible to generate one with objcopy, but support was removed,
+so we now use elf2aout (imported from FreeBSD).
+
+The file is first loaded at 4000, then relocated to its load address (we use
+202000 and executed there)
Openfirmware prompt
===================
@@ -47,7 +52,17 @@ Boot from network
-----------------
rarp:
-boot net
+boot net:,somefile
+(net is an alias to the network card and also sets the load address:
/pci@1f,4000/network@1,1)
dhcp:
boot net:dhcp
+
+Debugging
+---------
+
+202000 dis (disassemble starting at 202000 until next return instruction)
+
+4000 1000 dump (dump 1000 bytes from address 4000)
+
+ctrace (backtrace)