mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +00:00
Tune the page sizes
This commit is contained in:
parent
ff198e7577
commit
94ea34367a
12 changed files with 56 additions and 178 deletions
|
@ -72,7 +72,7 @@ SECTIONS {
|
|||
KEEP(*(SORT_NONE(.fini)))
|
||||
} =0x1f2003d5
|
||||
|
||||
.privileged ALIGN(CONSTANT(MAXPAGESIZE)) : {
|
||||
.privileged ALIGN(CONSTANT(COMMONPAGESIZE)) : {
|
||||
__privileged_start = .;
|
||||
*(.privileged*)
|
||||
} =0x1f2003d6
|
||||
|
@ -119,8 +119,8 @@ SECTIONS {
|
|||
_etext = .;
|
||||
PROVIDE(etext = .);
|
||||
|
||||
. = ALIGN(CONSTANT(MAXPAGESIZE));
|
||||
. = DATA_SEGMENT_ALIGN(CONSTANT(MAXPAGESIZE), CONSTANT(COMMONPAGESIZE));
|
||||
. = ALIGN(CONSTANT(COMMONPAGESIZE));
|
||||
. = DATA_SEGMENT_ALIGN(CONSTANT(COMMONPAGESIZE), CONSTANT(COMMONPAGESIZE));
|
||||
|
||||
.eh_frame : ONLY_IF_RW {
|
||||
KEEP(*(.eh_frame))
|
||||
|
@ -209,6 +209,7 @@ SECTIONS {
|
|||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
KEEP(*(SORT_BY_NAME(.piro.bss.sort.*)))
|
||||
*(COMMON)
|
||||
. = ALIGN(CONSTANT(COMMONPAGESIZE));
|
||||
}
|
||||
|
||||
_bss_end__ = .;
|
||||
|
|
19
ape/ape.S
19
ape/ape.S
|
@ -224,7 +224,7 @@ stub: mov $0x40,%dl // *literally* dos
|
|||
3: .byte 0xbd,0,0 // a.k.a. mov imm,%bp
|
||||
jmp pc // real mode, is real
|
||||
jmp _start // surprise it's unix
|
||||
.endfn stub
|
||||
.endfn stub,globl
|
||||
|
||||
/*─────────────────────────────────────────────────────────────────────────────╗
|
||||
│ αcτµαlly pδrταblε εxεcµταblε § ibm personal computer │
|
||||
|
@ -1073,25 +1073,10 @@ ape_pe: .ascin "PE",4
|
|||
.quad 0 // HeapReserve
|
||||
.quad 0 // HeapCommit
|
||||
.long 0 // LoaderFlags
|
||||
.long 16 // NumberOfDirectoryEntries
|
||||
.long 2 // NumberOfDirectoryEntries
|
||||
.long 0,0 // ExportsDirectory
|
||||
.stub ape_idata,long // ImportsDirectory
|
||||
.stub ape_idata_idtsize,long // ImportsDirectorySize
|
||||
.long 0,0 // ResourcesDirectory
|
||||
.long 0,0 // ExceptionsDirectory
|
||||
.long 0,0 // SecurityDirectory
|
||||
.long 0,0 // BaseRelocationTable
|
||||
.long 0,0 // DebugDirectory
|
||||
.long 0,0 // DescriptionString
|
||||
.long 0,0 // MachineSpecific
|
||||
.long 0,0 // ThreadLocalStorage
|
||||
.long 0,0 // LoadConfigurationDirectory
|
||||
.long 0,0 // BoundImportDirectory
|
||||
.stub ape_idata,long // ImportAddressDirectory
|
||||
.stub ape_idata_iatsize,long // ImportAddressDirectorySize
|
||||
.long 0,0 // DelayImportDescriptor
|
||||
.long 0,0 // ComPlusRuntimeHeader
|
||||
.long 0,0 // Reserved
|
||||
.endobj ape_pe,globl
|
||||
.previous
|
||||
|
||||
|
|
|
@ -390,7 +390,7 @@ SECTIONS {
|
|||
} :Tls :Rom
|
||||
/*END: Read Only Data */
|
||||
|
||||
. = DATA_SEGMENT_ALIGN(CONSTANT(MAXPAGESIZE), CONSTANT(COMMONPAGESIZE));
|
||||
. = DATA_SEGMENT_ALIGN(CONSTANT(COMMONPAGESIZE), CONSTANT(COMMONPAGESIZE));
|
||||
. = DATA_SEGMENT_RELRO_END(0, .);
|
||||
|
||||
/* this only tells the linker about the layout of uninitialized */
|
||||
|
@ -461,7 +461,7 @@ SECTIONS {
|
|||
|
||||
KEEP(*(.bssepilogue))
|
||||
|
||||
. = ALIGN(64);
|
||||
. = ALIGN(CONSTANT(COMMONPAGESIZE));
|
||||
|
||||
/*END: NT FORK COPYING */
|
||||
_end = .;
|
||||
|
@ -722,7 +722,7 @@ PFSTUB4(ape_pe_offset, ape_pe - ape_mz);
|
|||
ape_pe_optsz = ape_pe_sections - (ape_pe + 24);
|
||||
ape_pe_shnum = (ape_pe_sections_end - ape_pe_sections) / 40;
|
||||
ape_pe_base = IMAGE_BASE_VIRTUAL;
|
||||
ape_idata = LINK_WINDOWS ? RVA(ape_idata_iat) : 0;
|
||||
ape_idataz = LINK_WINDOWS ? RVA(ape_idata_iat) : 0;
|
||||
ape_idata_iatsize = LINK_WINDOWS ? ape_idata_iatend - ape_idata_iat : 0;
|
||||
ape_idata = LINK_WINDOWS ? RVA(ape_idata_idt) : 0;
|
||||
ape_idata_idtsize = LINK_WINDOWS ? ape_idata_idtend - ape_idata_idt : 0;
|
||||
|
|
|
@ -215,7 +215,7 @@ o/$(MODE)/ape/ape.elf.dbg: \
|
|||
o/$(MODE)/ape/launch.o \
|
||||
o/$(MODE)/ape/systemcall.o \
|
||||
ape/loader.lds
|
||||
@$(COMPILE) -ALINK.elf $(LINK) $(APE_LOADER_LDFLAGS) -o $@ $(patsubst %.lds,-T %.lds,$^)
|
||||
@$(COMPILE) -ALINK.elf $(LD) $(APE_LOADER_LDFLAGS) -o $@ $(patsubst %.lds,-T %.lds,$^)
|
||||
|
||||
.PHONY: o/$(MODE)/ape
|
||||
o/$(MODE)/ape: $(APE_CHECKS) \
|
||||
|
|
|
@ -888,7 +888,8 @@ __attribute__((__noreturn__)) void ApeLoader(long di, long *sp, char dl) {
|
|||
}
|
||||
}
|
||||
if (READ64(M->ehdr.buf) == READ64("MZqFpD='") ||
|
||||
READ64(M->ehdr.buf) == READ64("jartsr='")) {
|
||||
READ64(M->ehdr.buf) == READ64("jartsr='") ||
|
||||
READ64(M->ehdr.buf) == READ64("APEDBG='")) {
|
||||
for (p = M->ehdr.buf; p < pe; ++p) {
|
||||
if (READ64(p) != READ64("printf '")) {
|
||||
continue;
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -252,7 +252,7 @@ DEFAULT_LDFLAGS += \
|
|||
-znorelro
|
||||
else
|
||||
DEFAULT_LDFLAGS += \
|
||||
-zmax-page-size=0x1000 \
|
||||
-zmax-page-size=0x10000 \
|
||||
-zcommon-page-size=0x1000
|
||||
endif
|
||||
|
||||
|
|
|
@ -3,14 +3,11 @@
|
|||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
struct NtImageImportDescriptor {
|
||||
union {
|
||||
uint32_t Characteristics;
|
||||
uint32_t OriginalFirstThunk;
|
||||
};
|
||||
uint32_t ImportLookupTable;
|
||||
uint32_t TimeDateStamp;
|
||||
uint32_t ForwarderChain;
|
||||
uint32_t Name;
|
||||
uint32_t FirstThunk;
|
||||
uint32_t DllNameRva;
|
||||
uint32_t ImportAddressTable;
|
||||
};
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -11,11 +11,43 @@ struct NtImageOptionalHeader {
|
|||
uint32_t SizeOfCode;
|
||||
uint32_t SizeOfInitializedData;
|
||||
uint32_t SizeOfUninitializedData;
|
||||
|
||||
/*
|
||||
* The address of the entry point relative to the image base when the
|
||||
* executable file is loaded into memory. For program images, this is
|
||||
* the starting address. For device drivers, this is the address of
|
||||
* the initialization function. An entry point is optional for DLLs.
|
||||
* When no entry point is present, this field must be zero.
|
||||
*/
|
||||
uint32_t AddressOfEntryPoint;
|
||||
|
||||
uint32_t BaseOfCode;
|
||||
|
||||
/*
|
||||
* The preferred address of the first byte of image when loaded into
|
||||
* memory; must be a multiple of 64 K. The default for DLLs is
|
||||
* 0x10000000. The default for Windows CE EXEs is 0x00010000. The
|
||||
* default for Windows NT, Windows 2000, Windows XP, Windows 95,
|
||||
* Windows 98, and Windows Me is 0x00400000.
|
||||
*/
|
||||
uint64_t ImageBase;
|
||||
|
||||
/*
|
||||
* The alignment (in bytes) of sections when they are loaded into
|
||||
* memory. It must be greater than or equal to FileAlignment. The
|
||||
* default is the page size for the architecture.
|
||||
*/
|
||||
uint32_t SectionAlignment;
|
||||
|
||||
/*
|
||||
* The alignment factor (in bytes) that is used to align the raw data
|
||||
* of sections in the image file. The value should be a power of 2
|
||||
* between 512 and 64 K, inclusive. The default is 512. If the
|
||||
* SectionAlignment is less than the architecture's page size, then
|
||||
* FileAlignment must match SectionAlignment.
|
||||
*/
|
||||
uint32_t FileAlignment;
|
||||
|
||||
uint16_t MajorOperatingSystemVersion;
|
||||
uint16_t MinorOperatingSystemVersion;
|
||||
uint16_t MajorImageVersion;
|
||||
|
@ -34,7 +66,7 @@ struct NtImageOptionalHeader {
|
|||
uint64_t SizeOfHeapCommit;
|
||||
uint32_t LoaderFlags;
|
||||
uint32_t NumberOfRvaAndSizes;
|
||||
struct NtImageDataDirectory DataDirectory[kNtImageNumberofDirectoryEntries];
|
||||
struct NtImageDataDirectory DataDirectory[];
|
||||
};
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -1,139 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2023 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. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/elf/elf.h"
|
||||
#include "libc/elf/struct/ehdr.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
#include "third_party/getopt/getopt.internal.h"
|
||||
|
||||
#define VERSION \
|
||||
"apelink v1.0\n" \
|
||||
"copyright 2023 justine tunney\n" \
|
||||
"https://github.com/jart/cosmopolitan\n"
|
||||
|
||||
#define MANUAL \
|
||||
" -o OUTPUT INPUT...\n" \
|
||||
"\n" \
|
||||
"DESCRIPTION\n" \
|
||||
"\n" \
|
||||
" Actually Portable Executable Linker\n" \
|
||||
"\n" \
|
||||
" This program may be used to turn ELF executables into\n" \
|
||||
" APE executables. It's useful for creating fat binaries\n" \
|
||||
" that run on multiple architectures.\n" \
|
||||
"\n" \
|
||||
"FLAGS\n" \
|
||||
"\n" \
|
||||
" -h show usage\n" \
|
||||
" -o OUTPUT set output path\n" \
|
||||
"\n" \
|
||||
"ARGUMENTS\n" \
|
||||
"\n" \
|
||||
" OUTPUT is your ape executable\n" \
|
||||
" INPUT may specify multiple APE or ELF builds of the\n" \
|
||||
" same program for different architectures that\n" \
|
||||
" shall be merged into a single output file\n" \
|
||||
"\n"
|
||||
|
||||
static const char *prog;
|
||||
static const char *outpath;
|
||||
|
||||
static wontreturn void Die(const char *reason) {
|
||||
tinyprint(2, prog, ": ", reason, "\n", NULL);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static wontreturn void DieSys(const char *thing) {
|
||||
perror(thing);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static wontreturn void ShowUsage(int rc, int fd) {
|
||||
tinyprint(fd, VERSION, "\nUSAGE\n\n ", prog, MANUAL, NULL);
|
||||
exit(rc);
|
||||
}
|
||||
|
||||
static void GetOpts(int argc, char *argv[]) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "ho:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'o':
|
||||
outpath = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
ShowUsage(0, 1);
|
||||
default:
|
||||
ShowUsage(1, 2);
|
||||
}
|
||||
}
|
||||
if (!outpath) {
|
||||
Die("need output path");
|
||||
}
|
||||
if (optind == argc) {
|
||||
Die("missing input argument");
|
||||
}
|
||||
}
|
||||
|
||||
static void HandleInput(const char *inpath) {
|
||||
int fildes;
|
||||
ssize_t esize;
|
||||
Elf64_Ehdr *elf;
|
||||
if ((fildes = open(inpath, O_RDONLY)) == -1) {
|
||||
DieSys("open");
|
||||
}
|
||||
if ((esize = lseek(fildes, 0, SEEK_END)) == -1) {
|
||||
DieSys("lseek");
|
||||
}
|
||||
if (esize) {
|
||||
if ((elf = mmap(0, esize, PROT_READ | PROT_WRITE, MAP_SHARED, fildes, 0)) ==
|
||||
MAP_FAILED) {
|
||||
DieSys("mmap");
|
||||
}
|
||||
if (IsElf64Binary(elf, esize)) {
|
||||
}
|
||||
if (munmap(elf, esize)) {
|
||||
DieSys("munmap");
|
||||
}
|
||||
}
|
||||
if (close(fildes)) {
|
||||
DieSys("close");
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int i, opt;
|
||||
|
||||
// get program name
|
||||
prog = argv[0];
|
||||
if (!prog) prog = "apelink";
|
||||
|
||||
// read flags
|
||||
GetOpts(argc, argv);
|
||||
|
||||
// read args
|
||||
for (i = optind; i < argc; ++i) {
|
||||
HandleInput(argv[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -24,6 +24,7 @@
|
|||
#include "libc/intrin/bits.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdckdint.h"
|
||||
#include "libc/str/str.h"
|
||||
|
@ -107,12 +108,12 @@ void GetOpts(int argc, char *argv[]) {
|
|||
}
|
||||
}
|
||||
|
||||
void GetElfHeader(char ehdr[hasatleast 64], const char *image) {
|
||||
void GetElfHeader(char ehdr[hasatleast 64], const char *image, size_t n) {
|
||||
char *p;
|
||||
int c, i;
|
||||
for (p = image; p < image + 4096; ++p) {
|
||||
for (p = image; p < image + MIN(n, 4096); ++p) {
|
||||
if (READ64LE(p) != READ64LE("printf '")) continue;
|
||||
for (i = 0, p += 8; p + 3 < image + 4096 && (c = *p++) != '\'';) {
|
||||
for (i = 0, p += 8; p + 3 < image + MIN(n, 4096) && (c = *p++) != '\'';) {
|
||||
if (c == '\\') {
|
||||
if ('0' <= *p && *p <= '7') {
|
||||
c = *p++ - '0';
|
||||
|
@ -208,7 +209,7 @@ void GetMachoPayload(const char *image, size_t imagesize, int *out_offset,
|
|||
|
||||
void AssimilateElf(char *p, size_t n) {
|
||||
char ehdr[64];
|
||||
GetElfHeader(ehdr, p);
|
||||
GetElfHeader(ehdr, p, n);
|
||||
memcpy(p, ehdr, 64);
|
||||
msync(p, 4096, MS_SYNC);
|
||||
}
|
||||
|
@ -232,8 +233,8 @@ void Assimilate(void) {
|
|||
kprintf("%s: fstat() failed: %m\n", prog);
|
||||
exit(14);
|
||||
}
|
||||
if (st.st_size < 4096) {
|
||||
kprintf("%s: ape binaries must be at least 4096 bytes\n", prog);
|
||||
if (st.st_size < 64) {
|
||||
kprintf("%s: ape binaries must be at least 64 bytes\n", prog);
|
||||
exit(15);
|
||||
}
|
||||
if ((p = mmap(0, st.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) ==
|
||||
|
|
Loading…
Reference in a new issue