mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-08 20:28:30 +00:00
Get codebase completely working with LLVM
You can now build Cosmopolitan with Clang: make -j8 MODE=llvm o/llvm/examples/hello.com The assembler and linker code is now friendly to LLVM too. So it's not needed to configure Clang to use binutils under the hood. If you love LLVM then you can now use pure LLVM.
This commit is contained in:
parent
0e36cb3ac4
commit
e75ffde09e
4528 changed files with 7776 additions and 11640 deletions
323
ape/ape.lds
323
ape/ape.lds
|
@ -36,7 +36,7 @@
|
|||
entails two steps: (1) create a .com.dbg binary w/ Linux toolchain and
|
||||
then (2) unwrap the .com binary embedded within:
|
||||
|
||||
objcopy -SO binary input.com.dbg output.com
|
||||
objcopy -S -O binary input.com.dbg output.com
|
||||
|
||||
Both executables will work fine, but only the .com format is portable.
|
||||
|
||||
|
@ -182,21 +182,6 @@
|
|||
|
||||
ENTRY(_start)
|
||||
|
||||
/* Plans real memory solution at linktime. */
|
||||
MEMORY {
|
||||
PageZero : org = 0x0000000000000000, len = 0x0000000000001000
|
||||
RealBss : org = XLM_BASE_REAL, len = XLM_SIZE
|
||||
RealProgram : org = IMAGE_BASE_REAL, len = 0x0000000000010000 - IMAGE_BASE_REAL
|
||||
RealScratch : org = REAL_SCRATCH_AREA, len = REAL_STACK_FRAME - REAL_SCRATCH_AREA
|
||||
RealStack : org = REAL_STACK_FRAME, len = 0x0000000000010000
|
||||
EbdaMemory : org = 0x0000000000080000, len = 0x0000000000020000
|
||||
VideoMemory : org = 0x00000000000a0000, len = 0x0000000000020000
|
||||
Romz : org = 0x00000000000c0000, len = 0x0000000000030000
|
||||
BiosMemory : org = 0x00000000000f0000, len = 0x0000000000010000
|
||||
SmallCode : org = IMAGE_BASE_PHYSICAL, len = 0x0000000040000000 - IMAGE_BASE_PHYSICAL
|
||||
ZipData : org = 0x0000000040000000, len = 0x0000000040000000
|
||||
}
|
||||
|
||||
PHDRS {
|
||||
Head PT_LOAD FLAGS(5);
|
||||
Rom PT_LOAD FLAGS(5);
|
||||
|
@ -221,34 +206,34 @@ SECTIONS {
|
|||
/* Executable & Linkable Format */
|
||||
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 1);
|
||||
KEEP(*(.elf.phdrs))
|
||||
HIDDEN(.Lape.phdrs.end = .);
|
||||
HIDDEN(ape_phdrs_end = .);
|
||||
. += 1;
|
||||
|
||||
/* OpenBSD */
|
||||
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 1);
|
||||
HIDDEN(.Lape.note = .);
|
||||
HIDDEN(ape_note = .);
|
||||
KEEP(*(.note.openbsd.ident))
|
||||
KEEP(*(.note.netbsd.ident))
|
||||
HIDDEN(.Lape.note.end = .);
|
||||
HIDDEN(ape_note_end = .);
|
||||
. += 1;
|
||||
|
||||
/* Portable Executable */
|
||||
KEEP(*(.pe.header))
|
||||
HIDDEN(.Lape.pe.sections = .);
|
||||
HIDDEN(ape_pe_sections = .);
|
||||
KEEP(*(.pe.sections))
|
||||
HIDDEN(.Lape.pe.sections_end = .);
|
||||
HIDDEN(ape_pe_sections_end = .);
|
||||
. += 1;
|
||||
|
||||
/* Mach-O */
|
||||
KEEP(*(.macho))
|
||||
. = ALIGN(__SIZEOF_POINTER__);
|
||||
HIDDEN(.Lape.macho.end = .);
|
||||
HIDDEN(ape_macho_end = .);
|
||||
. += 1;
|
||||
|
||||
KEEP(*(.ape.pad.head))
|
||||
. = ALIGN(SupportsWindows() ? PAGESIZE : 16);
|
||||
HIDDEN(_ehead = .);
|
||||
} AT>SmallCode :Head
|
||||
} :Head
|
||||
|
||||
/*BEGIN: nt addressability guarantee */
|
||||
|
||||
|
@ -266,7 +251,7 @@ SECTIONS {
|
|||
*(.start)
|
||||
KEEP(*(.initprologue))
|
||||
KEEP(*(SORT_BY_NAME(.init.*)))
|
||||
KEEP(*(SORT_NONE(.init)))
|
||||
KEEP(*(.init))
|
||||
KEEP(*(.initepilogue))
|
||||
KEEP(*(.pltprologue))
|
||||
*(.plt)
|
||||
|
@ -290,19 +275,13 @@ SECTIONS {
|
|||
*(.text .stub .text.*)
|
||||
KEEP(*(SORT_BY_NAME(.sort.text.*)))
|
||||
|
||||
/* Won't support NX bit DRM for tiny executables */
|
||||
HIDDEN(.Lape.piro.align = ABSOLUTE(. > APE_PIRO_THRESHOLD ? 0x1000 : 8));
|
||||
|
||||
/* Code that musn't be mapped in production */
|
||||
KEEP(*(.ape.pad.test));
|
||||
. = ALIGN(.Lape.piro.align);
|
||||
HIDDEN(__test_start = .);
|
||||
*(.test.unlikely)
|
||||
*(.test .test.*)
|
||||
|
||||
/* Privileged code invulnerable to magic */
|
||||
KEEP(*(.ape.pad.privileged));
|
||||
. = ALIGN(.Lape.piro.align);
|
||||
HIDDEN(__privileged_start = .);
|
||||
HIDDEN(__test_end = .);
|
||||
. += 1;
|
||||
|
@ -312,23 +291,10 @@ SECTIONS {
|
|||
/*BEGIN: Read Only Data */
|
||||
|
||||
KEEP(*(.ape.pad.rodata));
|
||||
. = ALIGN(.Lape.piro.align);
|
||||
. += 1;
|
||||
|
||||
/* Nonspecific Read-Only Data */
|
||||
*(.rodata .rodata.*)
|
||||
. += 1;
|
||||
|
||||
/* Undefined Behavior Sanitizer Types */
|
||||
HIDDEN(__ubsan_types_start = .);
|
||||
*(.ubsan.types)
|
||||
HIDDEN(__ubsan_types_end = .);
|
||||
. += 1;
|
||||
|
||||
/* Undefined Behavior Sanitizer Data */
|
||||
HIDDEN(__ubsan_data_start = .);
|
||||
*(.ubsan.data)
|
||||
HIDDEN(__ubsan_data_end = .);
|
||||
|
||||
/* Unit Test & Fixture Registry */
|
||||
|
||||
|
@ -340,7 +306,7 @@ SECTIONS {
|
|||
KEEP(*(.comment))
|
||||
KEEP(*(.commentepilogue))
|
||||
#endif
|
||||
|
||||
|
||||
/* Windows DLL Import Directory */
|
||||
KEEP(*(.idata.ro));
|
||||
KEEP(*(SORT_BY_NAME(.idata.ro.*)))
|
||||
|
@ -350,16 +316,16 @@ SECTIONS {
|
|||
PROVIDE_HIDDEN(__init_array_start = .);
|
||||
KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*)
|
||||
SORT_BY_INIT_PRIORITY(.ctors.*)))
|
||||
KEEP(*(SORT_NONE(.ctors)))
|
||||
KEEP(*(SORT_NONE(.init_array)))
|
||||
KEEP(*(SORT_NONE(.preinit_array)))
|
||||
KEEP(*(.ctors))
|
||||
KEEP(*(.init_array))
|
||||
KEEP(*(.preinit_array))
|
||||
PROVIDE_HIDDEN(__init_array_end = .);
|
||||
|
||||
. = ALIGN(__SIZEOF_POINTER__);
|
||||
PROVIDE_HIDDEN(__fini_array_start = .);
|
||||
KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*)
|
||||
SORT_BY_INIT_PRIORITY(.dtors.*)))
|
||||
KEEP(*(SORT_NONE(.dtors)))
|
||||
KEEP(*(.dtors))
|
||||
PROVIDE_HIDDEN(__fini_array_end = .);
|
||||
|
||||
/* Encoded Data Structures w/ Linear Initialization Order */
|
||||
|
@ -369,13 +335,12 @@ SECTIONS {
|
|||
KEEP(*(SORT_BY_NAME(.sort.rodata.*)))
|
||||
|
||||
KEEP(*(.ape.pad.text))
|
||||
HIDDEN(.Lape.data.align = ABSOLUTE(PAGESIZE));
|
||||
. = ALIGN(.Lape.data.align);
|
||||
. = ALIGN(PAGESIZE);
|
||||
HIDDEN(_etext = .);
|
||||
PROVIDE_HIDDEN(etext = .);
|
||||
/*END: Read Only Data (only needed for initialization) */
|
||||
/*END: Read Only Data */
|
||||
} AT>SmallCode :Rom
|
||||
} :Rom
|
||||
|
||||
.data . : {
|
||||
/*BEGIN: Read/Write Data */
|
||||
|
@ -393,24 +358,21 @@ SECTIONS {
|
|||
KEEP(*(.gotpltepilogue))
|
||||
|
||||
/*BEGIN: Post-Initialization Read-Only */
|
||||
. = ALIGN(.Lape.piro.align);
|
||||
HIDDEN(__piro_start = .);
|
||||
|
||||
. = ALIGN(__SIZEOF_POINTER__);
|
||||
KEEP(*(SORT_BY_NAME(.piro.relo.sort.*)))
|
||||
PROVIDE_HIDDEN(__relo_end = .);
|
||||
. = ALIGN(__SIZEOF_POINTER__);
|
||||
KEEP(*(SORT_BY_NAME(.piro.data.sort.*)))
|
||||
KEEP(*(.piro.pad.data))
|
||||
. = ALIGN(.Lape.data.align);
|
||||
. = ALIGN(PAGESIZE);
|
||||
HIDDEN(_edata = .);
|
||||
PROVIDE_HIDDEN(edata = .);
|
||||
} AT>SmallCode :Ram
|
||||
} :Ram
|
||||
|
||||
.bss . : {
|
||||
KEEP(*(SORT_BY_NAME(.piro.bss.init.*)))
|
||||
*(.piro.bss)
|
||||
KEEP(*(SORT_BY_NAME(.piro.bss.sort.*)))
|
||||
. += 1;
|
||||
. = ALIGN(.Lape.piro.align);
|
||||
HIDDEN(__piro_end = .);
|
||||
/*END: Post-Initialization Read-Only */
|
||||
|
||||
|
@ -429,13 +391,16 @@ SECTIONS {
|
|||
. = ALIGN(0x10000); /* for brk()/sbrk() allocation */
|
||||
HIDDEN(_end = .);
|
||||
PROVIDE_HIDDEN(end = .);
|
||||
} AT>SmallCode :Ram
|
||||
} :Ram
|
||||
|
||||
/*END: nt addressability guarantee */
|
||||
/*END: bsd addressability guarantee */
|
||||
/*END: linux addressability guarantee */
|
||||
/*END: xnu addressability guarantee */
|
||||
|
||||
.shstrtab : { *(.shstrtab) }
|
||||
.strtab : { *(.strtab) }
|
||||
.symtab : { *(.symtab) }
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
|
@ -468,80 +433,81 @@ SECTIONS {
|
|||
.GCC.command.line 0 : { *(.GCC.command.line) }
|
||||
|
||||
/DISCARD/ : {
|
||||
*(__mcount_loc)
|
||||
*(.discard)
|
||||
*(.yoink)
|
||||
*(.*)
|
||||
}
|
||||
}
|
||||
|
||||
PFSTUB8(.Lape.elf.entry, _start);
|
||||
PFSTUB8(.Lape.elf.phoff, RVA(ape.phdrs));
|
||||
PFSTUB8(.Lape.elf.shoff, 0);
|
||||
PFSTUB4(.Lape.elf.phnum, (.Lape.phdrs.end - ape.phdrs) / 56);
|
||||
PFSTUB4(.Lape.elf.shnum, 0);
|
||||
PFSTUB4(.Lape.elf.shstrndx, 0);
|
||||
PFSTUB8(ape_elf_entry, _start);
|
||||
PFSTUB8(ape_elf_phoff, RVA(ape_phdrs));
|
||||
PFSTUB8(ape_elf_shoff, 0);
|
||||
PFSTUB4(ape_elf_phnum, (ape_phdrs_end - ape_phdrs) / 56);
|
||||
PFSTUB4(ape_elf_shnum, 0);
|
||||
PFSTUB4(ape_elf_shstrndx, 0);
|
||||
|
||||
HIDDEN(__privileged_addr = ROUNDDOWN(__privileged_start, PAGESIZE));
|
||||
HIDDEN(__privileged_size = (ROUNDUP(__privileged_end, PAGESIZE) -
|
||||
ROUNDDOWN(__privileged_start, PAGESIZE)));
|
||||
|
||||
HIDDEN(.Lape.rom.offset = 0);
|
||||
HIDDEN(.Lape.rom.vaddr = ADDR(.head));
|
||||
HIDDEN(.Lape.rom.paddr = LOADADDR(.head));
|
||||
HIDDEN(.Lape.rom.filesz = LOADADDR(.data) - .Lape.rom.paddr);
|
||||
HIDDEN(.Lape.rom.memsz = ADDR(.data) - ADDR(.head));
|
||||
HIDDEN(.Lape.rom.align = .Lape.data.align);
|
||||
HIDDEN(.Lape.rom.rva = RVA(.Lape.rom.vaddr));
|
||||
HIDDEN(ape_rom_offset = 0);
|
||||
HIDDEN(ape_rom_vaddr = ADDR(.head));
|
||||
HIDDEN(ape_rom_paddr = LOADADDR(.head));
|
||||
HIDDEN(ape_rom_filesz = LOADADDR(.data) - ape_rom_paddr);
|
||||
HIDDEN(ape_rom_memsz = ADDR(.data) - ADDR(.head));
|
||||
HIDDEN(ape_rom_align = PAGESIZE);
|
||||
HIDDEN(ape_rom_rva = RVA(ape_rom_vaddr));
|
||||
|
||||
HIDDEN(.Lape.ram.offset = .Lape.rom.offset + .Lape.rom.filesz);
|
||||
HIDDEN(.Lape.ram.vaddr = ADDR(.data));
|
||||
HIDDEN(.Lape.ram.paddr = LOADADDR(.data));
|
||||
HIDDEN(.Lape.ram.filesz = LOADADDR(.bss) - LOADADDR(.data));
|
||||
HIDDEN(.Lape.ram.memsz = ADDR(.bss) + SIZEOF(.bss) - .Lape.ram.vaddr);
|
||||
HIDDEN(.Lape.ram.align = .Lape.data.align);
|
||||
HIDDEN(.Lape.ram.rva = RVA(.Lape.ram.vaddr));
|
||||
HIDDEN(ape_ram_offset = ape_rom_offset + ape_rom_filesz);
|
||||
HIDDEN(ape_ram_vaddr = ADDR(.data));
|
||||
HIDDEN(ape_ram_paddr = LOADADDR(.data));
|
||||
HIDDEN(ape_ram_filesz = LOADADDR(.bss) - LOADADDR(.data));
|
||||
HIDDEN(ape_ram_memsz = ADDR(.bss) + SIZEOF(.bss) - ape_ram_vaddr);
|
||||
HIDDEN(ape_ram_align = PAGESIZE);
|
||||
HIDDEN(ape_ram_rva = RVA(ape_ram_vaddr));
|
||||
|
||||
HIDDEN(.Lape.note.offset = .Lape.rom.offset + (.Lape.note - .Lape.rom.vaddr));
|
||||
HIDDEN(.Lape.note.vaddr = .Lape.note);
|
||||
HIDDEN(.Lape.note.paddr = .Lape.rom.paddr + .Lape.note.offset);
|
||||
HIDDEN(.Lape.note.filesz = .Lape.note.end - .Lape.note);
|
||||
HIDDEN(.Lape.note.memsz = .Lape.note.filesz);
|
||||
HIDDEN(.Lape.note.align = __SIZEOF_POINTER__);
|
||||
HIDDEN(ape_note_offset = ape_rom_offset + (ape_note - ape_rom_vaddr));
|
||||
HIDDEN(ape_note_vaddr = ape_note);
|
||||
HIDDEN(ape_note_paddr = ape_rom_paddr + ape_note_offset);
|
||||
HIDDEN(ape_note_filesz = ape_note_end - ape_note);
|
||||
HIDDEN(ape_note_memsz = ape_note_filesz);
|
||||
HIDDEN(ape_note_align = __SIZEOF_POINTER__);
|
||||
|
||||
HIDDEN(.Lape.text.offset = .Lape.rom.offset + LOADADDR(.text) - .Lape.rom.paddr);
|
||||
HIDDEN(.Lape.text.paddr = LOADADDR(.text));
|
||||
HIDDEN(.Lape.text.vaddr = ADDR(.text));
|
||||
HIDDEN(.Lape.text.filesz = SIZEOF(.text));
|
||||
HIDDEN(.Lape.text.memsz = SIZEOF(.text));
|
||||
HIDDEN(.Lape.text.align = 4096);
|
||||
HIDDEN(.Lape.text.rva = RVA(.Lape.text.vaddr));
|
||||
HIDDEN(ape_text_offset = ape_rom_offset + LOADADDR(.text) - ape_rom_paddr);
|
||||
HIDDEN(ape_text_paddr = LOADADDR(.text));
|
||||
HIDDEN(ape_text_vaddr = ADDR(.text));
|
||||
HIDDEN(ape_text_filesz = SIZEOF(.text));
|
||||
HIDDEN(ape_text_memsz = SIZEOF(.text));
|
||||
HIDDEN(ape_text_align = PAGESIZE);
|
||||
HIDDEN(ape_text_rva = RVA(ape_text_vaddr));
|
||||
|
||||
HIDDEN(.Lape.data.offset = .Lape.ram.offset + LOADADDR(.data) - .Lape.ram.paddr);
|
||||
HIDDEN(.Lape.data.paddr = LOADADDR(.data));
|
||||
HIDDEN(.Lape.data.vaddr = ADDR(.data));
|
||||
HIDDEN(.Lape.data.filesz = SIZEOF(.data));
|
||||
HIDDEN(.Lape.data.memsz = SIZEOF(.data));
|
||||
HIDDEN(.Lape.data.align = .Lape.data.align);
|
||||
HIDDEN(.Lape.data.rva = RVA(.Lape.data.vaddr));
|
||||
HIDDEN(ape_data_offset = ape_ram_offset + LOADADDR(.data) - ape_ram_paddr);
|
||||
HIDDEN(ape_data_paddr = LOADADDR(.data));
|
||||
HIDDEN(ape_data_vaddr = ADDR(.data));
|
||||
HIDDEN(ape_data_filesz = SIZEOF(.data));
|
||||
HIDDEN(ape_data_memsz = SIZEOF(.data));
|
||||
HIDDEN(ape_data_align = PAGESIZE);
|
||||
HIDDEN(ape_data_rva = RVA(ape_data_vaddr));
|
||||
|
||||
HIDDEN(.Lape.bss.offset = .Lape.ram.offset + LOADADDR(.bss) - .Lape.ram.paddr);
|
||||
HIDDEN(.Lape.bss.paddr = LOADADDR(.bss));
|
||||
HIDDEN(.Lape.bss.vaddr = ADDR(.bss));
|
||||
HIDDEN(.Lape.bss.filesz = 0);
|
||||
HIDDEN(.Lape.bss.memsz = SIZEOF(.bss));
|
||||
HIDDEN(.Lape.bss.align = .Lape.data.align);
|
||||
HIDDEN(ape_bss_offset = ape_ram_offset + LOADADDR(.bss) - ape_ram_paddr);
|
||||
HIDDEN(ape_bss_paddr = LOADADDR(.bss));
|
||||
HIDDEN(ape_bss_vaddr = ADDR(.bss));
|
||||
HIDDEN(ape_bss_filesz = 0);
|
||||
HIDDEN(ape_bss_memsz = SIZEOF(.bss));
|
||||
HIDDEN(ape_bss_align = PAGESIZE);
|
||||
|
||||
#if SupportsXnu()
|
||||
SHSTUB2(.Lape.macho.dd.skip, RVA(ape.macho) / 8);
|
||||
SHSTUB2(.Lape.macho.dd.count, (.Lape.macho.end - ape.macho) / 8);
|
||||
SHSTUB2(ape_macho_dd_skip, RVA(ape_macho) / 8);
|
||||
SHSTUB2(ape_macho_dd_count, (ape_macho_end - ape_macho) / 8);
|
||||
#endif
|
||||
|
||||
#if SupportsWindows()
|
||||
PFSTUB4(.Lape.pe.offset, ape.pe - ape.mz);
|
||||
HIDDEN(.Lape.pe.optsz = .Lape.pe.sections - (ape.pe + 24));
|
||||
HIDDEN(.Lape.pe.shnum = (.Lape.pe.sections_end - .Lape.pe.sections) / 40);
|
||||
HIDDEN(.Lidata.idtsize = idata.idtend - idata.idt);
|
||||
HIDDEN(.Lidata.iatsize = idata.iatend - idata.iat);
|
||||
PFSTUB4(ape_pe_offset, ape_pe - ape_mz);
|
||||
HIDDEN(ape_pe_optsz = ape_pe_sections - (ape_pe + 24));
|
||||
HIDDEN(ape_pe_shnum = (ape_pe_sections_end - ape_pe_sections) / 40);
|
||||
HIDDEN(ape_idata_idtsize = ape_idata_idtend - ape_idata_idt);
|
||||
HIDDEN(ape_idata_iatsize = ape_idata_iatend - ape_idata_iat);
|
||||
HIDDEN(v_ntsubsystem = (DEFINED(GetMessage)
|
||||
? kNtImageSubsystemWindowsGui
|
||||
: kNtImageSubsystemWindowsCui));
|
||||
|
@ -577,90 +543,89 @@ ZIPCONST(v_zip_commentsize, _edata - __zip_end - kZipCdirHdrMinSize);
|
|||
X = (X + (Y >> 020) & 0xFF) * PHI; \
|
||||
X = (X + (Y >> 030) & 0xFF) * PHI
|
||||
#define CHURN(X) \
|
||||
XORSHIFT(.Lape.uuid1, X); \
|
||||
KMH(.Lape.uuid1, X); \
|
||||
XORSHIFT(.Lape.uuid2, X); \
|
||||
KMH(.Lape.uuid2, X)
|
||||
HIDDEN(.Lape.uuid1 = 88172645463325252);
|
||||
HIDDEN(.Lape.uuid2 = 88172645463325252);
|
||||
CHURN(.Lape.bss.align);
|
||||
CHURN(.Lape.bss.filesz);
|
||||
CHURN(.Lape.bss.memsz);
|
||||
CHURN(.Lape.bss.offset);
|
||||
CHURN(.Lape.bss.paddr);
|
||||
CHURN(.Lape.data.align);
|
||||
CHURN(.Lape.data.filesz);
|
||||
CHURN(.Lape.data.memsz);
|
||||
CHURN(.Lape.data.offset);
|
||||
CHURN(.Lape.data.paddr);
|
||||
CHURN(.Lape.data.rva);
|
||||
CHURN(.Lape.data.vaddr);
|
||||
CHURN(.Lape.elf.entry);
|
||||
CHURN(.Lape.elf.phnum);
|
||||
CHURN(.Lape.elf.phoff);
|
||||
CHURN(.Lape.elf.shnum);
|
||||
CHURN(.Lape.elf.shoff);
|
||||
CHURN(.Lape.elf.shstrndx);
|
||||
CHURN(.Lape.macho.end);
|
||||
CHURN(.Lape.note);
|
||||
CHURN(.Lape.note.align);
|
||||
CHURN(.Lape.note.end);
|
||||
CHURN(.Lape.note.filesz);
|
||||
CHURN(.Lape.note.memsz);
|
||||
CHURN(.Lape.note.offset);
|
||||
CHURN(.Lape.note.paddr);
|
||||
CHURN(.Lape.note.vaddr);
|
||||
CHURN(.Lape.ram.align);
|
||||
CHURN(.Lape.ram.filesz);
|
||||
CHURN(.Lape.ram.memsz);
|
||||
CHURN(.Lape.ram.offset);
|
||||
CHURN(.Lape.ram.paddr);
|
||||
CHURN(.Lape.ram.rva);
|
||||
CHURN(.Lape.ram.vaddr);
|
||||
CHURN(.Lape.rom.align);
|
||||
CHURN(.Lape.rom.filesz);
|
||||
CHURN(.Lape.rom.memsz);
|
||||
CHURN(.Lape.rom.offset);
|
||||
CHURN(.Lape.rom.paddr);
|
||||
CHURN(.Lape.rom.rva);
|
||||
CHURN(.Lape.rom.vaddr);
|
||||
CHURN(.Lape.text.align);
|
||||
CHURN(.Lape.text.filesz);
|
||||
CHURN(.Lape.text.memsz);
|
||||
CHURN(.Lape.text.offset);
|
||||
CHURN(.Lape.text.paddr);
|
||||
CHURN(.Lape.text.rva);
|
||||
CHURN(.Lape.text.vaddr);
|
||||
XORSHIFT(ape_uuid1, X); \
|
||||
KMH(ape_uuid1, X); \
|
||||
XORSHIFT(ape_uuid2, X); \
|
||||
KMH(ape_uuid2, X)
|
||||
HIDDEN(ape_uuid1 = 88172645463325252);
|
||||
HIDDEN(ape_uuid2 = 88172645463325252);
|
||||
CHURN(ape_bss_align);
|
||||
CHURN(ape_bss_filesz);
|
||||
CHURN(ape_bss_memsz);
|
||||
CHURN(ape_bss_offset);
|
||||
CHURN(ape_bss_paddr);
|
||||
CHURN(ape_data_filesz);
|
||||
CHURN(ape_data_memsz);
|
||||
CHURN(ape_data_offset);
|
||||
CHURN(ape_data_paddr);
|
||||
CHURN(ape_data_rva);
|
||||
CHURN(ape_data_vaddr);
|
||||
CHURN(ape_elf_entry);
|
||||
CHURN(ape_elf_phnum);
|
||||
CHURN(ape_elf_phoff);
|
||||
CHURN(ape_elf_shnum);
|
||||
CHURN(ape_elf_shoff);
|
||||
CHURN(ape_elf_shstrndx);
|
||||
CHURN(ape_macho_end);
|
||||
CHURN(ape_note);
|
||||
CHURN(ape_note_align);
|
||||
CHURN(ape_note_end);
|
||||
CHURN(ape_note_filesz);
|
||||
CHURN(ape_note_memsz);
|
||||
CHURN(ape_note_offset);
|
||||
CHURN(ape_note_paddr);
|
||||
CHURN(ape_note_vaddr);
|
||||
CHURN(ape_ram_align);
|
||||
CHURN(ape_ram_filesz);
|
||||
CHURN(ape_ram_memsz);
|
||||
CHURN(ape_ram_offset);
|
||||
CHURN(ape_ram_paddr);
|
||||
CHURN(ape_ram_rva);
|
||||
CHURN(ape_ram_vaddr);
|
||||
CHURN(ape_rom_align);
|
||||
CHURN(ape_rom_filesz);
|
||||
CHURN(ape_rom_memsz);
|
||||
CHURN(ape_rom_offset);
|
||||
CHURN(ape_rom_paddr);
|
||||
CHURN(ape_rom_rva);
|
||||
CHURN(ape_rom_vaddr);
|
||||
CHURN(ape_text_align);
|
||||
CHURN(ape_text_filesz);
|
||||
CHURN(ape_text_memsz);
|
||||
CHURN(ape_text_offset);
|
||||
CHURN(ape_text_paddr);
|
||||
CHURN(ape_text_rva);
|
||||
CHURN(ape_text_vaddr);
|
||||
CHURN(ADDR(.bss));
|
||||
CHURN(_start);
|
||||
CHURN(ape.phdrs);
|
||||
CHURN(ape_phdrs);
|
||||
#if SupportsMetal()
|
||||
CHURN(v_ape_realsectors);
|
||||
#endif
|
||||
#if SupportsXnu()
|
||||
CHURN(ape.macho);
|
||||
CHURN(ape_macho);
|
||||
#endif
|
||||
#if SupportsWindows()
|
||||
CHURN(ape.mz);
|
||||
CHURN(ape.pe);
|
||||
CHURN(.Lape.pe.offset);
|
||||
CHURN(.Lape.pe.optsz);
|
||||
CHURN(.Lape.pe.sections);
|
||||
CHURN(.Lape.pe.sections_end);
|
||||
CHURN(.Lape.pe.shnum);
|
||||
CHURN(.Lape.phdrs.end);
|
||||
CHURN(ape_mz);
|
||||
CHURN(ape_pe);
|
||||
CHURN(ape_pe_offset);
|
||||
CHURN(ape_pe_optsz);
|
||||
CHURN(ape_pe_sections);
|
||||
CHURN(ape_pe_sections_end);
|
||||
CHURN(ape_pe_shnum);
|
||||
CHURN(ape_phdrs_end);
|
||||
CHURN(WinMain);
|
||||
#endif /* SupportsWindows() */
|
||||
#endif /* SupportsXnu() */
|
||||
|
||||
ASSERT(DEFINED(ape.mz) ? ape.mz == IMAGE_BASE_VIRTUAL : 1, "linker panic");
|
||||
ASSERT(DEFINED(ape_mz) ? ape_mz == IMAGE_BASE_VIRTUAL : 1, "linker panic");
|
||||
ASSERT((DEFINED(__init_bss_end) ? __init_bss_end : 0) % __SIZEOF_POINTER__ == 0,
|
||||
"__init_bss misalign");
|
||||
ASSERT(((DEFINED(__init_rodata_end) ? __init_rodata_end : 0) %
|
||||
__SIZEOF_POINTER__ == 0),
|
||||
"__init_rodata misalign");
|
||||
|
||||
ASSERT((!DEFINED(ape.grub) ? 1 : RVA(ape.grub) < 8192),
|
||||
ASSERT((!DEFINED(ape_grub) ? 1 : RVA(ape_grub) < 8192),
|
||||
"grub stub needs to be in first 8kb of image");
|
||||
|
||||
ASSERT(DEFINED(_start) || DEFINED(_start16),
|
||||
|
@ -672,7 +637,7 @@ ASSERT(!DEFINED(_start16) || REAL(_end) < 65536,
|
|||
/* Let's not be like Knight Capital. */
|
||||
/* NOCROSSREFS_TO(.test .text) */
|
||||
|
||||
/* ASSERT(ape_sysv_start == .Lape.text.vaddr, */
|
||||
/* ASSERT(ape_sysv_start == ape_text_vaddr, */
|
||||
/* "ape_sysv_start() must be first in .text"); */
|
||||
|
||||
#endif /* __LINKER__ */
|
||||
|
|
|
@ -24,12 +24,7 @@ APELINK = \
|
|||
$(COMPILE) \
|
||||
$(LINK) \
|
||||
$(LINKARGS) \
|
||||
$(OUTPUT_OPTION) && \
|
||||
$(STRIP) \
|
||||
-X $@ && \
|
||||
$(GZ) \
|
||||
$(ZFLAGS) \
|
||||
-f $@.map
|
||||
$(OUTPUT_OPTION)
|
||||
|
||||
APE_FILES := $(wildcard ape/*.*)
|
||||
APE_HDRS = $(filter %.h,$(APE_FILES))
|
||||
|
|
|
@ -22,15 +22,15 @@
|
|||
#include "ape/relocations.h"
|
||||
/* clang-format off */
|
||||
|
||||
/ Links function from external DLL.
|
||||
/
|
||||
/ This embeds a function pointer in the binary. The NT Executive
|
||||
/ fills its value before control is handed off to the program.
|
||||
/
|
||||
/ @note only ELF toolchains are powerful enough to use this
|
||||
/ @see libc/nt/master.sh
|
||||
/ @see ape/ape.lds
|
||||
/ @see winimp
|
||||
// Links function from external DLL.
|
||||
//
|
||||
// This embeds a function pointer in the binary. The NT Executive
|
||||
// fills its value before control is handed off to the program.
|
||||
//
|
||||
// @note only ELF toolchains are powerful enough to use this
|
||||
// @see libc/nt/master.sh
|
||||
// @see ape/ape.lds
|
||||
// @see winimp
|
||||
.macro .imp dll:req fn:req actual:req hint
|
||||
.dll \dll
|
||||
.section .piro.data.sort.iat.2.\dll\().2.\actual,"aw",@progbits
|
||||
|
@ -63,10 +63,10 @@
|
|||
.previous
|
||||
.endm
|
||||
|
||||
/ Defines DLL import.
|
||||
/ @note this is an implementation detail of .imp
|
||||
// Defines DLL import.
|
||||
// @note this is an implementation detail of .imp
|
||||
.macro .dll name:req
|
||||
.section .idata.ro.idt.2.\name,"aG",\name,comdat
|
||||
.section .idata.ro.idt.2.\name,"aG",@progbits,\name,comdat
|
||||
.equ .Lidata.idt.\name,.
|
||||
.long RVA(idata.ilt.\name) # ImportLookupTable
|
||||
.long 0 # TimeDateStamp
|
||||
|
@ -76,7 +76,7 @@
|
|||
.type .Lidata.idt.\name,@object
|
||||
.size .Lidata.idt.\name,.-.Lidata.idt.\name
|
||||
.previous
|
||||
.section .idata.ro.ilt.\name\().1,"aG",\name,comdat
|
||||
.section .idata.ro.ilt.\name\().1,"aG",@progbits,\name,comdat
|
||||
.align __SIZEOF_POINTER__
|
||||
.type idata.ilt.\name,@object
|
||||
idata.ilt.\name:
|
||||
|
@ -84,15 +84,15 @@ idata.ilt.\name:
|
|||
...
|
||||
decentralized content
|
||||
...
|
||||
*/.section .idata.ro.ilt.\name\().3,"aG",\name,comdat
|
||||
*/.section .idata.ro.ilt.\name\().3,"aG",@progbits,\name,comdat
|
||||
.quad 0
|
||||
.previous
|
||||
.section .idata.ro.hnt.\name\().1,"aG",\name,comdat
|
||||
.section .idata.ro.hnt.\name\().1,"aG",@progbits,\name,comdat
|
||||
.align __SIZEOF_POINTER__
|
||||
.type idata.hnt.\name,@object
|
||||
.equ idata.hnt.\name,.
|
||||
.previous
|
||||
.section .piro.data.sort.iat.2.\name\().1,"awG",\name,comdat
|
||||
.section .piro.data.sort.iat.2.\name\().1,"awG",@progbits,\name,comdat
|
||||
.align __SIZEOF_POINTER__
|
||||
.type idata.iat.\name,@object
|
||||
idata.iat.\name:
|
||||
|
@ -100,7 +100,7 @@ idata.iat.\name:
|
|||
...
|
||||
decentralized content
|
||||
...
|
||||
*/.section .piro.data.sort.iat.2.\name\().3,"awG",\name,comdat
|
||||
*/.section .piro.data.sort.iat.2.\name\().3,"awG",@progbits,\name,comdat
|
||||
.quad 0
|
||||
.previous
|
||||
.section .rodata.str1.1,"aSM",@progbits,1
|
||||
|
|
|
@ -22,11 +22,11 @@
|
|||
.source __FILE__
|
||||
.code16
|
||||
|
||||
/ Resets personal computer.
|
||||
/
|
||||
/ @param di drive number, e.g. A:\ is 0x00, C:\ is 0x80
|
||||
/ @mode real
|
||||
/ @noreturn
|
||||
// Resets personal computer.
|
||||
//
|
||||
// @param di drive number, e.g. A:\ is 0x00, C:\ is 0x80
|
||||
// @mode real
|
||||
// @noreturn
|
||||
bootdr: push %bp
|
||||
mov %sp,%bp
|
||||
mov %di,%dx
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
.hidden e820map
|
||||
.type e820map,@object
|
||||
.size e820map,XLM_E820_SIZE
|
||||
e820map = ape.xlm + XLM_E820
|
||||
e820map = ape_xlm + XLM_E820
|
||||
|
||||
.globl e820map_xlm
|
||||
.hidden e820map_xlm
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
.hidden g_ptsp
|
||||
.type g_ptsp,@object
|
||||
.size g_ptsp,XLM_PAGE_TABLE_STACK_POINTER_SIZE
|
||||
g_ptsp = ape.xlm + XLM_PAGE_TABLE_STACK_POINTER
|
||||
g_ptsp = ape_xlm + XLM_PAGE_TABLE_STACK_POINTER
|
||||
|
||||
.globl g_ptsp_xlm
|
||||
.hidden g_ptsp_xlm
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
.hidden kBiosDataArea
|
||||
.type kBiosDataArea,@object
|
||||
.size kBiosDataArea,XLM_BIOS_DATA_AREA_SIZE
|
||||
kBiosDataArea = ape.xlm + XLM_BIOS_DATA_AREA
|
||||
kBiosDataArea = ape_xlm + XLM_BIOS_DATA_AREA
|
||||
|
||||
.globl kBiosDataAreaXlm
|
||||
.hidden kBiosDataAreaXlm
|
||||
|
|
80
ape/lib/pc.h
80
ape/lib/pc.h
|
@ -63,49 +63,49 @@
|
|||
#define FPU_C2 0b0000000000000010000000000
|
||||
#define FPU_C3 0b0000000000100000000000000
|
||||
|
||||
#define CR0_PE (1u << 0) /* protected mode enabled */
|
||||
#define CR0_MP (1u << 1) /* monitor coprocessor */
|
||||
#define CR0_EM (1u << 2) /* no x87 fpu present if set */
|
||||
#define CR0_TS (1u << 3) /* task switched x87 */
|
||||
#define CR0_ET (1u << 4) /* extension type 287 or 387 */
|
||||
#define CR0_NE (1u << 5) /* enable x87 error reporting */
|
||||
#define CR0_WP (1u << 16) /* write protect read-only pages @pl0 */
|
||||
#define CR0_AM (1u << 18) /* alignment mask */
|
||||
#define CR0_NW (1u << 29) /* global write-through cache disable */
|
||||
#define CR0_CD (1u << 30) /* global cache disable */
|
||||
#define CR0_PG (1u << 31) /* paging enabled */
|
||||
#define CR0_PE 0x01 /* protected mode enabled */
|
||||
#define CR0_MP 0x02 /* monitor coprocessor */
|
||||
#define CR0_EM 0x04 /* no x87 fpu present if set */
|
||||
#define CR0_TS 0x08 /* task switched x87 */
|
||||
#define CR0_ET 0x10 /* extension type 287 or 387 */
|
||||
#define CR0_NE 0x20 /* enable x87 error reporting */
|
||||
#define CR0_WP 0x00010000 /* write protect read-only pages @pl0 */
|
||||
#define CR0_AM 0x00040000 /* alignment mask */
|
||||
#define CR0_NW 0x20000000 /* global write-through cache disable */
|
||||
#define CR0_CD 0x40000000 /* global cache disable */
|
||||
#define CR0_PG 0x80000000 /* paging enabled */
|
||||
|
||||
#define CR4_VME (1u << 0) /* virtual 8086 mode extension */
|
||||
#define CR4_PVI (1u << 1) /* protected mode virtual interrupts */
|
||||
#define CR4_TSD (1u << 2) /* time stamp disable (rdtsc) */
|
||||
#define CR4_DE (1u << 3) /* debugging extensions */
|
||||
#define CR4_PSE (1u << 4) /* page size extension */
|
||||
#define CR4_PAE (1u << 5) /* physical address extension */
|
||||
#define CR4_MCE (1u << 6) /* machine check exception */
|
||||
#define CR4_PGE (1u << 7) /* page global enabled */
|
||||
#define CR4_OSFXSR (1u << 9) /* enable SSE and fxsave/fxrestor */
|
||||
#define CR4_OSXMMEXCPT (1u << 10) /* enable unmasked SSE exceptions */
|
||||
#define CR4_LA57 (1u << 12) /* enable level-5 paging */
|
||||
#define CR4_VMXE (1u << 13) /* enable VMX operations */
|
||||
#define CR4_SMXE (1u << 14) /* enable SMX operations */
|
||||
#define CR4_FSGSBASE (1u << 16) /* enable *FSBASE and *GSBASE instructions */
|
||||
#define CR4_PCIDE (1u << 17) /* enable process-context identifiers */
|
||||
#define CR4_OSXSAVE (1u << 18) /* enable XSAVE */
|
||||
#define CR4_VME 0x01 /* virtual 8086 mode extension */
|
||||
#define CR4_PVI 0x02 /* protected mode virtual interrupts */
|
||||
#define CR4_TSD 0x04 /* time stamp disable (rdtsc) */
|
||||
#define CR4_DE 0x08 /* debugging extensions */
|
||||
#define CR4_PSE 0x10 /* page size extension */
|
||||
#define CR4_PAE 0x20 /* physical address extension */
|
||||
#define CR4_MCE 0x40 /* machine check exception */
|
||||
#define CR4_PGE 0x80 /* page global enabled */
|
||||
#define CR4_OSFXSR 0x0200 /* enable SSE and fxsave/fxrestor */
|
||||
#define CR4_OSXMMEXCPT 0x0400 /* enable unmasked SSE exceptions */
|
||||
#define CR4_LA57 0x1000 /* enable level-5 paging */
|
||||
#define CR4_VMXE 0x2000 /* enable VMX operations */
|
||||
#define CR4_SMXE 0x4000 /* enable SMX operations */
|
||||
#define CR4_FSGSBASE 0x00010000 /* enable *FSBASE and *GSBASE instructions */
|
||||
#define CR4_PCIDE 0x00020000 /* enable process-context identifiers */
|
||||
#define CR4_OSXSAVE 0x00040000 /* enable XSAVE */
|
||||
|
||||
#define XCR0_X87 (1u << 0)
|
||||
#define XCR0_SSE (1u << 1)
|
||||
#define XCR0_AVX (1u << 2)
|
||||
#define XCR0_BNDREG (1u << 3)
|
||||
#define XCR0_BNDCSR (1u << 4)
|
||||
#define XCR0_OPMASK (1u << 5)
|
||||
#define XCR0_ZMM_HI256 (1u << 6)
|
||||
#define XCR0_HI16_ZMM (1u << 7)
|
||||
#define XCR0_X87 0x01
|
||||
#define XCR0_SSE 0x02
|
||||
#define XCR0_AVX 0x04
|
||||
#define XCR0_BNDREG 0x08
|
||||
#define XCR0_BNDCSR 0x10
|
||||
#define XCR0_OPMASK 0x20
|
||||
#define XCR0_ZMM_HI256 0x40
|
||||
#define XCR0_HI16_ZMM 0x80
|
||||
|
||||
#define EFER 0xC0000080 /* extended feature enable register */
|
||||
#define EFER_SCE (1u << 0) /* system call extensions */
|
||||
#define EFER_LME (1u << 8) /* long mode enable */
|
||||
#define EFER_LMA (1u << 10) /* long mode active */
|
||||
#define EFER_NXE (1u << 11) /* no-execute enable */
|
||||
#define EFER 0xc0000080 /* extended feature enable register */
|
||||
#define EFER_SCE 0x01 /* system call extensions */
|
||||
#define EFER_LME 0x0100 /* long mode enable */
|
||||
#define EFER_LMA 0x0400 /* long mode active */
|
||||
#define EFER_NXE 0x0800 /* no-execute enable */
|
||||
|
||||
#define GDT_REAL_CODE 8
|
||||
#define GDT_REAL_DATA 16
|
||||
|
|
|
@ -1,3 +1,21 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#ifndef APE_MACROS_H_
|
||||
#define APE_MACROS_H_
|
||||
#include "libc/macros.h"
|
||||
|
@ -8,9 +26,16 @@
|
|||
* @fileoverview Macros relevant to αcτµαlly pδrταblε εxεcµταblε.
|
||||
*/
|
||||
|
||||
/ Calls near (i.e. pc+pcrel<64kB) FUNCTION.
|
||||
/ @mode long,legacy,real
|
||||
/ @cost 9 bytes overhead
|
||||
// Calls function in real mode.
|
||||
// It's needed because LLVM 8 LLD doesn't support R_X86_64_PC16.
|
||||
.macro call16 name:req
|
||||
mov $REAL(\name),%ax
|
||||
call *%ax
|
||||
.endm
|
||||
|
||||
// Calls near (i.e. pc+pcrel<64kB) FUNCTION.
|
||||
// @mode long,legacy,real
|
||||
// @cost 9 bytes overhead
|
||||
.macro rlcall function:req
|
||||
.byte 0x50 # push %[er]ax
|
||||
.byte 0xb8,0,0 # mov $?,%[e]ax
|
||||
|
@ -25,8 +50,8 @@
|
|||
912:
|
||||
.endm
|
||||
|
||||
/ Loads far (i.e. <1mb) abs constexpr ADDRESS into ES:DI+EDX+RDX.
|
||||
/ @mode long,legacy,real
|
||||
// Loads far (i.e. <1mb) abs constexpr ADDRESS into ES:DI+EDX+RDX.
|
||||
// @mode long,legacy,real
|
||||
.macro movesdi address:req
|
||||
.byte 0xbf # mov $0x????xxxx,%[e]di
|
||||
.short \address>>4
|
||||
|
@ -39,8 +64,8 @@
|
|||
297:
|
||||
.endm
|
||||
|
||||
/ Loads 16-bit CONSTEXPR into Qw-register w/ optional zero-extend.
|
||||
/ @mode long,legacy,real
|
||||
// Loads 16-bit CONSTEXPR into Qw-register w/ optional zero-extend.
|
||||
// @mode long,legacy,real
|
||||
.macro bbmov constexpr:req abcd abcd.hi:req abcd.lo:req
|
||||
.ifnb \abcd
|
||||
.if (\constexpr)<128 && (\constexpr)>=0
|
||||
|
@ -52,8 +77,8 @@
|
|||
movb $(\constexpr)&0xff,\abcd.lo
|
||||
.endm
|
||||
|
||||
/ Compares 16-bit CONSTEXPR with Qw-register.
|
||||
/ @mode long,legacy,real
|
||||
// Compares 16-bit CONSTEXPR with Qw-register.
|
||||
// @mode long,legacy,real
|
||||
.macro bbcmp constexpr:req abcd.hi:req abcd.lo:req
|
||||
cmpb $(\constexpr)>>8&0xff,\abcd.hi
|
||||
jnz 387f
|
||||
|
@ -61,8 +86,8 @@
|
|||
387:
|
||||
.endm
|
||||
|
||||
/ Adds 16-bit CONSTEXPR to Qw-register.
|
||||
/ @mode long,legacy,real
|
||||
// Adds 16-bit CONSTEXPR to Qw-register.
|
||||
// @mode long,legacy,real
|
||||
.macro bbadd constexpr:req abcd.hi:req abcd.lo:req
|
||||
addb $(\constexpr)&0xff,\abcd.lo
|
||||
.if (\constexpr) != 0
|
||||
|
@ -70,8 +95,8 @@
|
|||
.endif
|
||||
.endm
|
||||
|
||||
/ Subtracts 16-bit CONSTEXPR from Qw-register.
|
||||
/ @mode long,legacy,real
|
||||
// Subtracts 16-bit CONSTEXPR from Qw-register.
|
||||
// @mode long,legacy,real
|
||||
.macro bbsub constexpr:req abcd.hi:req abcd.lo:req
|
||||
subb $(\constexpr)&0xff,\abcd.lo
|
||||
.if (\constexpr) != 0
|
||||
|
@ -79,8 +104,8 @@
|
|||
.endif
|
||||
.endm
|
||||
|
||||
/ Ands Qw-register with 16-bit CONSTEXPR.
|
||||
/ @mode long,legacy,real
|
||||
// Ands Qw-register with 16-bit CONSTEXPR.
|
||||
// @mode long,legacy,real
|
||||
.macro bband constexpr:req abcd.hi:req abcd.lo:req
|
||||
.if ((\constexpr)&0xff) != 0xff || ((\constexpr)>>8&0xff) == 0xff
|
||||
andb $(\constexpr)&0xff,\abcd.lo
|
||||
|
@ -90,8 +115,8 @@
|
|||
.endif
|
||||
.endm
|
||||
|
||||
/ Ors Qw-register with 16-bit CONSTEXPR.
|
||||
/ @mode long,legacy,real
|
||||
// Ors Qw-register with 16-bit CONSTEXPR.
|
||||
// @mode long,legacy,real
|
||||
.macro bbor constexpr:req abcd.hi:req abcd.lo:req
|
||||
.if ((\constexpr)&0xff) != 0 || ((\constexpr)>>8&0xff) != 0
|
||||
orb $(\constexpr)&0xff,\abcd.lo
|
||||
|
@ -101,8 +126,8 @@
|
|||
.endif
|
||||
.endm
|
||||
|
||||
/ Performs ACTION only if in real mode.
|
||||
/ @mode long,legacy,real
|
||||
// Performs ACTION only if in real mode.
|
||||
// @mode long,legacy,real
|
||||
.macro rlo clobber:req action:vararg
|
||||
990: mov $0,\clobber
|
||||
.if .-990b!=3
|
||||
|
@ -117,10 +142,10 @@
|
|||
.endif
|
||||
.endm
|
||||
|
||||
/ Initializes real mode stack.
|
||||
/ The most holiest of holy code.
|
||||
/ @mode real
|
||||
/ @see www.pcjs.org/pubs/pc/reference/intel/8086/
|
||||
// Initializes real mode stack.
|
||||
// The most holiest of holy code.
|
||||
// @mode real
|
||||
// @see www.pcjs.org/pubs/pc/reference/intel/8086/
|
||||
.macro rlstack seg:req addr:req
|
||||
cli
|
||||
mov \seg,%ss
|
||||
|
@ -128,7 +153,7 @@
|
|||
sti
|
||||
.endm
|
||||
|
||||
/ Symbolic Linker-Defined Binary Content.
|
||||
// Symbolic Linker-Defined Binary Content.
|
||||
.macro .stub name:req kind:req default type=@object
|
||||
.ifnb \default
|
||||
.equ \name,\default
|
||||
|
@ -139,17 +164,17 @@
|
|||
.hidden \name
|
||||
.endm
|
||||
|
||||
/ Symbolic Linker-Defined Binary-Encoded-Bourne Content.
|
||||
/ @param units is the number of encoded 32-bit values to insert,
|
||||
/ e.g. \000 can be encoded as 0x3030305c.
|
||||
.macro .shstub name:req units:req
|
||||
// Symbolic Linker-Defined Binary-Encoded-Bourne Content.
|
||||
// @param units is the number of encoded 32-bit values to insert,
|
||||
// e.g. \000 can be encoded as 0x3030305c.
|
||||
.macro .shstub name:req num:req
|
||||
ss \name,0
|
||||
.if \units>1
|
||||
.if \num>1
|
||||
ss \name,1
|
||||
.if \units>2
|
||||
.if \num>2
|
||||
ss \name,2
|
||||
ss \name,3
|
||||
.if \units>4
|
||||
.if \num>4
|
||||
ss \name,4
|
||||
ss \name,5
|
||||
ss \name,6
|
||||
|
@ -166,8 +191,8 @@
|
|||
#elif defined(__LINKER__)
|
||||
|
||||
#define BCX_NIBBLE(X) ((((X)&0xf) > 0x9) ? ((X)&0xf) + 0x37 : ((X)&0xf) + 0x30)
|
||||
#define BCX_OCTET(X) ((BCX_NIBBLE((X) >> 4) << 8) | (BCX_NIBBLE((X) >> 0) << 0))
|
||||
#define BCX_INT16(X) ((BCX_OCTET((X) >> 8) << 16) | (BCX_OCTET((X) >> 0) << 0))
|
||||
#define BCX_OCTET(X) ((BCX_NIBBLE((X) >> 4) << 8) | (BCX_NIBBLE((X) >> 0) << 0))
|
||||
#define BCX_INT16(X) ((BCX_OCTET((X) >> 8) << 16) | (BCX_OCTET((X) >> 0) << 0))
|
||||
#define BCXSTUB(SYM, X) \
|
||||
HIDDEN(SYM##_bcx0 = BCX_INT16((X) >> 48)); \
|
||||
HIDDEN(SYM##_bcx1 = BCX_INT16((X) >> 32)); \
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue