[haiku-commits] haiku: hrev53247 - headers/build/os/kernel src/tools

  • From: waddlesplash <waddlesplash@xxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 12 Jul 2019 21:29:11 -0400 (EDT)

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)



Other related posts:

  • » [haiku-commits] haiku: hrev53247 - headers/build/os/kernel src/tools - waddlesplash