2020-06-15 14:18:57 +00:00
|
|
|
|
/*-*- mode: ld-script; indent-tabs-mode: nil; tab-width: 2; coding: utf-8 -*-│
|
|
|
|
|
│ vi: set et sts=2 sw=2 fenc=utf-8 :vi │
|
|
|
|
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
|
|
|
|
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
|
|
|
|
│ │
|
2020-12-28 01:18:44 +00:00
|
|
|
|
│ 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. │
|
2020-06-15 14:18:57 +00:00
|
|
|
|
│ │
|
2020-12-28 01:18:44 +00:00
|
|
|
|
│ 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. │
|
2020-06-15 14:18:57 +00:00
|
|
|
|
╠──────────────────────────────────────────────────────────────────────────────╣
|
|
|
|
|
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
|
|
|
|
│░░░░░░░█▀█░█▀█░▀█▀░█░█░█▀█░█░░░█░░░█░█░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
|
|
|
|
│░░░░░░░█▀█░█░▄░░█░░█░█░█▀█░█░░░█░░░▀█▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
|
|
|
|
│░░░░░░░▀░▀░▀▀▀░░▀░░▀▀▀░▀░▀░▀▀▀░▀▀▀░░▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
|
|
|
|
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
|
|
|
|
│░░░░░░░█▀█░█▀█░█▀█░▀█▀░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
|
|
|
|
│░░░░░░░█▀▀░█ █░██▀░░█░░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
|
|
|
|
│░░░░░░░▀░░░▀▀▀░▀░▀░░▀░░▀░▀░▀▀▀░▀▀▀░▀▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
|
|
|
|
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
|
|
|
|
│░░░░░░░█▀▀░█░█░█▀▀░█▀█░█░█░▀█▀░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░▄▄░░░▐█░░│
|
|
|
|
|
│░░░░░░░█▀▀░▄▀▄░█▀▀░█░▄░█░█░░█░░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░▄▄▄░░░▄██▄░░█▀░░░█░▄░│
|
|
|
|
|
│░░░░░░░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀▀▀░░▀░░▀░▀░▀▀▀░▀▀░▀▀▀░░░░░░░░░░▄██▀█▌░██▄▄░░▐█▀▄░▐█▀░░│
|
|
|
|
|
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▐█▀▀▌░░░▄▀▌░▌░█░▌░░▌░▌░░│
|
|
|
|
|
╠──────────────────────────────────────────────────────▌▀▄─▐──▀▄─▐▄─▐▄▐▄─▐▄─▐▄─│
|
|
|
|
|
│ αcτµαlly pδrταblε εxεcµταblε § linker │
|
|
|
|
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
|
|
|
|
Having an executable run natively on stock Windows / Mac / Linux / BSD
|
|
|
|
|
entails two steps: (1) create a .com.dbg binary w/ Linux toolchain and
|
|
|
|
|
then (2) unwrap the .com binary embedded within:
|
|
|
|
|
|
2021-02-08 17:19:00 +00:00
|
|
|
|
objcopy -S -O binary input.com.dbg output.com
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
|
|
|
|
Both executables will work fine, but only the .com format is portable.
|
|
|
|
|
|
|
|
|
|
───BUILDING─────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
LC_ALL=C ld -T ape/ape.lds ...
|
|
|
|
|
|
|
|
|
|
───RUNNING──────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
./foo.com.dbg # works on host machine
|
|
|
|
|
./foo.com # works on any os / arch
|
|
|
|
|
qemu-system-x86_64 -s foo.com # works on any os / arch
|
|
|
|
|
|
|
|
|
|
───BACKGROUND───────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
The purpose of this software is to help native programs have the same
|
|
|
|
|
level of consistency, in terms of user experience, that we enjoy with
|
|
|
|
|
web applications. It's basically like MeteorJS, except primarily CLI,
|
|
|
|
|
bootable, and more on the order of a few kilobytes than hundred megs.
|
|
|
|
|
|
|
|
|
|
Rather than Isomorphic JavaScript it's built using Isomorphic Binary,
|
|
|
|
|
since it grants the fastest possible performance and can be trivially
|
|
|
|
|
emulated in the browser. System resource utilization is also a few kb
|
|
|
|
|
and GUIs are possible too since Cosmopolitan exports the Windows API,
|
|
|
|
|
but we recommend doing it with a CLI web server instead and embedding
|
|
|
|
|
files in your αcτµαlly pδrταblε εxεcµταblε as it's isomorphic to zip.
|
|
|
|
|
|
|
|
|
|
Isomorphic Binary principles state that most platform differences are
|
|
|
|
|
just numbers, which we integrate easily into a unified business logic
|
|
|
|
|
through the use of a sufficiently powerful linker. System numbers are
|
|
|
|
|
otherwise known as ABIs and they're usually the most stable canonical
|
|
|
|
|
interfaces that platforms provide. This is how we are able to support
|
|
|
|
|
more versions of Linux than most Linux-only software, e.g. glibc FTMP
|
|
|
|
|
|
|
|
|
|
───DEBUGGING────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
Can be done in a few ways:
|
|
|
|
|
|
|
|
|
|
gdb --tui foo.com.dbg
|
|
|
|
|
gdb --tui foo.com -ex 'add-symbol-file foo.com.dbg 0x200000'
|
|
|
|
|
gdb --tui -ex 'add-symbol-file foo.com.dbg 0x7c00' \
|
|
|
|
|
-ex 'add-symbol-file foo.com.dbg 0x200000' \
|
|
|
|
|
-ex -target remote localhost:1234'
|
|
|
|
|
|
|
|
|
|
───TRANSPARENCY─────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
αcτµαlly pδrταblε εxεcµταblε is designed to facilitate maximum
|
|
|
|
|
transparency to engender trust in this linker process.
|
|
|
|
|
|
|
|
|
|
The headers and symbols can be viewed using readelf or objdump:
|
|
|
|
|
|
|
|
|
|
readelf -Wa input.com.dbg # maximum transparency
|
|
|
|
|
objdump -wxd input.com.dbg # maximum transparency
|
|
|
|
|
|
|
|
|
|
The disassembly can be viewed using objdump:
|
|
|
|
|
|
|
|
|
|
readelf -Wa input.com.dbg # maximum transparency
|
|
|
|
|
objdump -d input.com.dbg # maximum transparency
|
|
|
|
|
objdump -dj.text input.com.dbg # skip αpε boilerplate
|
|
|
|
|
objdump -j.load -dMi8086 input.com.dbg # fixes real mode code
|
|
|
|
|
|
|
|
|
|
Some commands for controlling the verbosity of binaries:
|
|
|
|
|
|
|
|
|
|
strip -X input.com.dbg # remove ".L" symbols
|
|
|
|
|
strip input.com.dbg # remove all symbols
|
|
|
|
|
strip -S input.com.dbg # remove debug info only
|
|
|
|
|
make CPPFLAGS=-DNDEBUG # remove asserts (prod)
|
2020-06-16 02:01:28 +00:00
|
|
|
|
make CPPFLAGS=-DIM_FEELING_NAUGHTY # remove legal embeddings
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
|
|
|
|
The Makefile build is also configured to always produce a .map file
|
|
|
|
|
when building each program, which provides further details.
|
|
|
|
|
|
|
|
|
|
───HACKABILITY──────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
Your linker and assemblies were designed provide extensibility through
|
|
|
|
|
the use of link-time data structures we call "decentralized sections".
|
|
|
|
|
They allow functions like _init() to be comprised of many small pieces
|
|
|
|
|
defined throughout the codebase. The same applies to ELF / PE headers.
|
|
|
|
|
|
|
|
|
|
Extending that content usually entails writing a .S file. The process
|
|
|
|
|
has more in common with JavaScript programming than contemporary C++
|
|
|
|
|
development practices. It's the reason Cosmopolitan is able to build
|
|
|
|
|
the fast tiny multiplatform autonomous binaries that indie developers
|
|
|
|
|
love using a scalable development model that big businesses respect.
|
|
|
|
|
|
|
|
|
|
───SECURITY─────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
αcτµαlly pδrταblε εxεcµταblε is designed to be secure in untrustworthy
|
|
|
|
|
computing environments. Code and data are separated. Data structures
|
|
|
|
|
initialized at startup are automatically memory protected afterwards.
|
|
|
|
|
Code intended for platforms you don't use is automatically unmapped
|
|
|
|
|
too, minimizing any possible chance of impacting your system, while
|
|
|
|
|
still being there in case you ever need it.
|
|
|
|
|
|
|
|
|
|
───CONFIDENTIALITY──────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
αcτµαlly pδrταblε εxεcµταblε is also designed to not leak confidential
|
|
|
|
|
information by default. Details relating to the host build environment
|
|
|
|
|
such as system/library versions, user ids, home folder locations, etc.
|
|
|
|
|
are not taken into consideration at build time since it's hermetic. We
|
|
|
|
|
can't make speak for debug information, which is why it's put in other
|
|
|
|
|
files. We also provide the bing and fold programs for auditing binary.
|
|
|
|
|
|
|
|
|
|
───DESIGN─DETAILS───────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
αcτµαlly pδrταblε εxεcµταblε is a non-reflective (a.k.a. flat) binary
|
|
|
|
|
format that includes ELF, PE, and Macho-O headers only to respect the
|
|
|
|
|
initialization rituals that supported platforms require.
|
|
|
|
|
|
|
|
|
|
Binaries are sparse because Intel's six thousand page manual says:
|
|
|
|
|
|
|
|
|
|
“Always put code and data on separate pages. [...] If code is
|
|
|
|
|
to be modified, try to do it all at once and make sure the
|
|
|
|
|
code that performs the modifications and the code being
|
|
|
|
|
modified are on separate 4KByte pages or on separate aligned
|
|
|
|
|
1-KByte subpages. [...] If (hopefully read-only) data must
|
|
|
|
|
occur on the same page as code, avoid placing it immediately
|
|
|
|
|
after an indirect jump [...] or inserting an illegal opcode
|
|
|
|
|
[...] after the indirect branch [which] may degrade perf in
|
|
|
|
|
some circumstances.” ──Intel V.O §3.6.9
|
|
|
|
|
|
|
|
|
|
Support for linking dynamic shared objects is only implemented on
|
|
|
|
|
Windows NT for the reasons described by Ulrich Drepper in his DSO
|
|
|
|
|
tutorial. We've implemented this independently of the ld codebase
|
|
|
|
|
because authentic GNU tooling is powerful enough to generalize to
|
|
|
|
|
arbitrary formats without needing to add features to its codebase.
|
|
|
|
|
|
|
|
|
|
Cosmopolitan core library functions may be converted to the COFF or
|
|
|
|
|
Mach-O object formats using objconv. That gives you some freedom to
|
|
|
|
|
choose to use the Microsoft or Apple linker instead of this one. We
|
|
|
|
|
otherwise can't use those formats, due to how they heavily restrict
|
|
|
|
|
naming, which basically makes everything we're doing impossible. In
|
|
|
|
|
the future an authentic GNU toolchain will be made available on the
|
|
|
|
|
Windows and Apple platforms, using canonical formats and behaviors.
|
|
|
|
|
Until then, we can build for those platforms using Linux or WSL. */
|
|
|
|
|
|
|
|
|
|
#ifdef __LINKER__
|
2020-12-01 11:43:40 +00:00
|
|
|
|
#include "ape/macros.internal.h"
|
2021-02-24 04:23:19 +00:00
|
|
|
|
#include "ape/relocations.h"
|
2021-02-08 12:04:42 +00:00
|
|
|
|
#include "libc/dce.h"
|
2022-04-13 05:11:00 +00:00
|
|
|
|
#include "libc/elf/def.h"
|
|
|
|
|
#include "libc/elf/pf2prot.internal.h"
|
2020-11-25 16:19:00 +00:00
|
|
|
|
#include "libc/nt/pedef.internal.h"
|
2022-09-10 18:49:13 +00:00
|
|
|
|
#include "libc/thread/tls.h"
|
2023-05-09 09:35:05 +00:00
|
|
|
|
#include "ape/ape.internal.h"
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
2023-05-12 04:53:15 +00:00
|
|
|
|
/* uncomment if .com.dbg won't execute on your kernel (will break .com file) */
|
|
|
|
|
/* #define APE_FIX_COM_DBG */
|
|
|
|
|
|
2023-05-09 09:35:05 +00:00
|
|
|
|
#ifdef __x86__
|
|
|
|
|
#define CODE_GRANULE 1
|
|
|
|
|
#else
|
|
|
|
|
#define CODE_GRANULE 4
|
|
|
|
|
#endif
|
|
|
|
|
|
2023-05-12 04:53:15 +00:00
|
|
|
|
#ifdef APE_FIX_COM_DBG
|
|
|
|
|
#define SKEW SIZEOF_HEADERS
|
|
|
|
|
#else
|
|
|
|
|
#define SKEW 0
|
|
|
|
|
#endif
|
|
|
|
|
|
2023-09-12 08:21:36 +00:00
|
|
|
|
#ifndef IMAGE_BASE_VIRTUAL
|
|
|
|
|
#define IMAGE_BASE_VIRTUAL 0x400000
|
|
|
|
|
#endif
|
|
|
|
|
|
2023-05-19 02:05:08 +00:00
|
|
|
|
#if IMAGE_BASE_VIRTUAL > 0xffffffff
|
|
|
|
|
#error "please use 32-bit addresses for image data"
|
2023-05-17 09:29:30 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
2020-06-15 14:18:57 +00:00
|
|
|
|
ENTRY(_start)
|
|
|
|
|
|
|
|
|
|
PHDRS {
|
2022-05-27 20:25:46 +00:00
|
|
|
|
Head PT_LOAD FLAGS(PF_X|PF_R);
|
2023-07-01 12:10:12 +00:00
|
|
|
|
Cod PT_LOAD FLAGS(PF_X|PF_R);
|
|
|
|
|
Rom PT_LOAD FLAGS(PF_R);
|
2022-05-27 20:25:46 +00:00
|
|
|
|
Tls PT_TLS FLAGS(PF_W|PF_R);
|
2023-07-01 12:10:12 +00:00
|
|
|
|
Ram PT_LOAD FLAGS(PF_W|PF_R);
|
2022-05-27 20:25:46 +00:00
|
|
|
|
stack PT_GNU_STACK FLAGS(PF_W|PF_R);
|
2020-06-15 14:18:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SECTIONS {
|
|
|
|
|
|
|
|
|
|
/*BEGIN: realmode addressability guarantee */
|
|
|
|
|
/*BEGIN: xnu addressability guarantee */
|
|
|
|
|
/*BEGIN: linux addressability guarantee */
|
|
|
|
|
/*BEGIN: bsd addressability guarantee */
|
|
|
|
|
|
2023-05-12 04:53:15 +00:00
|
|
|
|
.head SEGMENT_START("text-segment", IMAGE_BASE_VIRTUAL) + SKEW : AT(IMAGE_BASE_REAL) {
|
2023-07-01 12:10:12 +00:00
|
|
|
|
__executable_start = .;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
|
|
|
|
/* Real Mode */
|
|
|
|
|
KEEP(*(.head))
|
2021-02-24 04:23:19 +00:00
|
|
|
|
KEEP(*(.text.head))
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
|
|
|
|
/* Executable & Linkable Format */
|
2023-08-11 11:37:23 +00:00
|
|
|
|
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
|
2023-07-01 12:10:12 +00:00
|
|
|
|
ape_phdrs = .;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
KEEP(*(.elf.phdrs))
|
2023-07-01 12:10:12 +00:00
|
|
|
|
ape_phdrs_end = .;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
|
|
|
|
/* OpenBSD */
|
2023-08-11 11:37:23 +00:00
|
|
|
|
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
|
2023-07-01 12:10:12 +00:00
|
|
|
|
ape_note = .;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
KEEP(*(.note.openbsd.ident))
|
2021-02-05 14:16:20 +00:00
|
|
|
|
KEEP(*(.note.netbsd.ident))
|
2023-07-01 12:10:12 +00:00
|
|
|
|
ape_note_end = .;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
|
|
|
|
/* Portable Executable */
|
|
|
|
|
KEEP(*(.pe.header))
|
2023-07-01 12:10:12 +00:00
|
|
|
|
ape_pe_sections = .;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
KEEP(*(.pe.sections))
|
2023-07-01 12:10:12 +00:00
|
|
|
|
ape_pe_sections_end = .;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
|
|
|
|
/* Mach-O */
|
|
|
|
|
KEEP(*(.macho))
|
2023-08-11 11:37:23 +00:00
|
|
|
|
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
|
2023-07-01 12:10:12 +00:00
|
|
|
|
ape_macho_end = .;
|
|
|
|
|
|
|
|
|
|
/* APE loader */
|
|
|
|
|
KEEP(*(.ape.loader))
|
2023-08-11 11:37:23 +00:00
|
|
|
|
. = ALIGN(. != 0 ? CODE_GRANULE : 0);
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
|
|
|
|
KEEP(*(.ape.pad.head))
|
2023-08-17 18:12:10 +00:00
|
|
|
|
. = ALIGN(. != 0 ? (SupportsWindows() || SupportsMetal() ? CONSTANT(COMMONPAGESIZE) : 16) : 0);
|
2023-07-01 12:10:12 +00:00
|
|
|
|
_ehead = .;
|
2021-02-08 17:19:00 +00:00
|
|
|
|
} :Head
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
|
|
|
|
/*BEGIN: nt addressability guarantee */
|
|
|
|
|
|
|
|
|
|
.text . : {
|
2021-09-28 05:58:51 +00:00
|
|
|
|
BYTE(0x90) /* TODO: fix blinkenlights symbol __map_phdrs */
|
2020-06-15 14:18:57 +00:00
|
|
|
|
/* Code that needs to be addressable in Real Mode */
|
|
|
|
|
*(.text.real)
|
|
|
|
|
KEEP(*(SORT_BY_NAME(.sort.text.real.*)))
|
2023-07-01 12:10:12 +00:00
|
|
|
|
_ereal = .;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
/*END: realmode addressability guarantee */
|
2022-05-22 11:51:02 +00:00
|
|
|
|
/*BEGIN: morphable code */
|
2023-05-09 09:35:05 +00:00
|
|
|
|
. += CODE_GRANULE;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
|
|
|
|
/* Normal Code */
|
|
|
|
|
*(.start)
|
|
|
|
|
KEEP(*(.initprologue))
|
|
|
|
|
KEEP(*(SORT_BY_NAME(.init.*)))
|
2021-02-08 17:19:00 +00:00
|
|
|
|
KEEP(*(.init))
|
2020-06-15 14:18:57 +00:00
|
|
|
|
KEEP(*(.initepilogue))
|
|
|
|
|
*(.plt)
|
|
|
|
|
*(.plt.got)
|
2024-02-01 11:39:46 +00:00
|
|
|
|
*(.iplt)
|
2020-06-15 14:18:57 +00:00
|
|
|
|
*(.text.startup .text.startup.*)
|
|
|
|
|
*(.text.exit .text.exit.*)
|
|
|
|
|
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
|
|
|
|
|
*(SORT_BY_ALIGNMENT(.text.antiquity))
|
|
|
|
|
*(SORT_BY_ALIGNMENT(.text.antiquity.*))
|
|
|
|
|
KEEP(*(.textwindowsprologue))
|
|
|
|
|
*(.text.windows)
|
|
|
|
|
KEEP(*(.textwindowsepilogue))
|
|
|
|
|
*(SORT_BY_ALIGNMENT(.text.modernity))
|
|
|
|
|
*(SORT_BY_ALIGNMENT(.text.modernity.*))
|
|
|
|
|
*(SORT_BY_ALIGNMENT(.text.hot))
|
|
|
|
|
*(SORT_BY_ALIGNMENT(.text.hot.*))
|
|
|
|
|
KEEP(*(.keep.text))
|
|
|
|
|
*(.text .stub .text.*)
|
|
|
|
|
KEEP(*(SORT_BY_NAME(.sort.text.*)))
|
|
|
|
|
|
|
|
|
|
KEEP(*(.ape.pad.test));
|
|
|
|
|
*(.test.unlikely)
|
|
|
|
|
*(.test .test.*)
|
|
|
|
|
|
|
|
|
|
/* Privileged code invulnerable to magic */
|
|
|
|
|
KEEP(*(.ape.pad.privileged));
|
2023-08-17 18:12:10 +00:00
|
|
|
|
. = ALIGN(__privileged_end > __privileged_start ? CONSTANT(COMMONPAGESIZE) : 0);
|
2022-05-22 11:51:02 +00:00
|
|
|
|
/*END: morphable code */
|
2023-06-09 06:44:03 +00:00
|
|
|
|
__privileged_start = .;
|
2024-08-16 18:05:37 +00:00
|
|
|
|
*(.privileged .privileged.*)
|
2023-06-09 06:44:03 +00:00
|
|
|
|
__privileged_end = .;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
2023-07-01 12:10:12 +00:00
|
|
|
|
KEEP(*(.ape.pad.text))
|
2023-08-17 18:12:10 +00:00
|
|
|
|
. = ALIGN(. != 0 ? CONSTANT(COMMONPAGESIZE) : 0);
|
2023-07-01 12:10:12 +00:00
|
|
|
|
/*END: Read Only Data (only needed for initialization) */
|
|
|
|
|
} :Cod
|
|
|
|
|
|
2020-06-15 14:18:57 +00:00
|
|
|
|
/*BEGIN: Read Only Data */
|
|
|
|
|
|
2024-02-01 11:39:46 +00:00
|
|
|
|
.rodata ALIGN(CONSTANT(COMMONPAGESIZE)) : {
|
2021-09-07 18:40:11 +00:00
|
|
|
|
KEEP(*(.rodata.pytab.0));
|
|
|
|
|
KEEP(*(.rodata.pytab.1));
|
|
|
|
|
KEEP(*(.rodata.pytab.2));
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
|
|
|
|
*(.rodata .rodata.*)
|
|
|
|
|
*(.ubsan.types)
|
|
|
|
|
*(.ubsan.data)
|
|
|
|
|
|
|
|
|
|
/* Legal Notices */
|
Release Cosmopolitan v3.3
This change upgrades to GCC 12.3 and GNU binutils 2.42. The GNU linker
appears to have changed things so that only a single de-duplicated str
table is present in the binary, and it gets placed wherever the linker
wants, regardless of what the linker script says. To cope with that we
need to stop using .ident to embed licenses. As such, this change does
significant work to revamp how third party licenses are defined in the
codebase, using `.section .notice,"aR",@progbits`.
This new GCC 12.3 toolchain has support for GNU indirect functions. It
lets us support __target_clones__ for the first time. This is used for
optimizing the performance of libc string functions such as strlen and
friends so far on x86, by ensuring AVX systems favor a second codepath
that uses VEX encoding. It shaves some latency off certain operations.
It's a useful feature to have for scientific computing for the reasons
explained by the test/libcxx/openmp_test.cc example which compiles for
fifteen different microarchitectures. Thanks to the upgrades, it's now
also possible to use newer instruction sets, such as AVX512FP16, VNNI.
Cosmo now uses the %gs register on x86 by default for TLS. Doing it is
helpful for any program that links `cosmo_dlopen()`. Such programs had
to recompile their binaries at startup to change the TLS instructions.
That's not great, since it means every page in the executable needs to
be faulted. The work of rewriting TLS-related x86 opcodes, is moved to
fixupobj.com instead. This is great news for MacOS x86 users, since we
previously needed to morph the binary every time for that platform but
now that's no longer necessary. The only platforms where we need fixup
of TLS x86 opcodes at runtime are now Windows, OpenBSD, and NetBSD. On
Windows we morph TLS to point deeper into the TIB, based on a TlsAlloc
assignment, and on OpenBSD/NetBSD we morph %gs back into %fs since the
kernels do not allow us to specify a value for the %gs register.
OpenBSD users are now required to use APE Loader to run Cosmo binaries
and assimilation is no longer possible. OpenBSD kernel needs to change
to allow programs to specify a value for the %gs register, or it needs
to stop marking executable pages loaded by the kernel as mimmutable().
This release fixes __constructor__, .ctor, .init_array, and lastly the
.preinit_array so they behave the exact same way as glibc.
We no longer use hex constants to define math.h symbols like M_PI.
2024-02-20 19:12:09 +00:00
|
|
|
|
__notices = .;
|
|
|
|
|
KEEP(*(.notice))
|
|
|
|
|
BYTE(0);
|
|
|
|
|
BYTE(10);
|
|
|
|
|
BYTE(10);
|
2021-02-27 18:33:32 +00:00
|
|
|
|
|
2023-07-01 12:10:12 +00:00
|
|
|
|
/*BEGIN: read-only data that's only needed for initialization */
|
|
|
|
|
|
2023-07-10 02:47:46 +00:00
|
|
|
|
#if SupportsWindows()
|
2020-06-15 14:18:57 +00:00
|
|
|
|
/* Windows DLL Import Directory */
|
|
|
|
|
KEEP(*(.idata.ro));
|
|
|
|
|
KEEP(*(SORT_BY_NAME(.idata.ro.*)))
|
2023-07-10 02:47:46 +00:00
|
|
|
|
#endif
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
|
|
|
|
/* Encoded Data Structures w/ Linear Initialization Order */
|
|
|
|
|
KEEP(*(.initroprologue))
|
|
|
|
|
KEEP(*(SORT_BY_NAME(.initro.*)))
|
|
|
|
|
KEEP(*(.initroepilogue))
|
|
|
|
|
KEEP(*(SORT_BY_NAME(.sort.rodata.*)))
|
2023-08-17 18:12:10 +00:00
|
|
|
|
. = ALIGN(. != 0 ? CONSTANT(COMMONPAGESIZE) : 0); /* don't delete this line :o */
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
2023-07-01 12:10:12 +00:00
|
|
|
|
/*END: read-only data that's only needed for initialization */
|
2022-03-20 15:01:14 +00:00
|
|
|
|
|
2023-07-01 12:10:12 +00:00
|
|
|
|
} :Rom
|
2023-06-10 16:15:19 +00:00
|
|
|
|
|
2022-12-18 01:51:20 +00:00
|
|
|
|
/* initialization image for thread-local storage, this is copied */
|
|
|
|
|
/* out to actual TLS areas at runtime, so just make it read-only */
|
2023-07-01 12:10:12 +00:00
|
|
|
|
.tdata . : {
|
2022-12-18 01:51:20 +00:00
|
|
|
|
_tdata_start = .;
|
|
|
|
|
*(SORT_BY_ALIGNMENT(.tdata))
|
|
|
|
|
*(SORT_BY_ALIGNMENT(.tdata.*))
|
|
|
|
|
_tdata_end = .;
|
2023-07-01 12:10:12 +00:00
|
|
|
|
KEEP(*(.ape.pad.rodata))
|
2023-08-17 18:12:10 +00:00
|
|
|
|
. = ALIGN(. != 0 ? CONSTANT(COMMONPAGESIZE) : 0);
|
2023-07-01 12:10:12 +00:00
|
|
|
|
_etext = .;
|
|
|
|
|
PROVIDE(etext = .);
|
2022-12-18 01:51:20 +00:00
|
|
|
|
} :Tls :Rom
|
|
|
|
|
/*END: Read Only Data */
|
|
|
|
|
|
2023-08-17 18:12:10 +00:00
|
|
|
|
. = ALIGN(CONSTANT(COMMONPAGESIZE));
|
2023-07-01 12:10:12 +00:00
|
|
|
|
|
2022-12-18 01:51:20 +00:00
|
|
|
|
/* this only tells the linker about the layout of uninitialized */
|
|
|
|
|
/* TLS data, and does not advance the linker's location counter */
|
2023-06-15 00:02:57 +00:00
|
|
|
|
.tbss : {
|
2022-12-18 01:51:20 +00:00
|
|
|
|
_tbss_start = .;
|
|
|
|
|
*(SORT_BY_ALIGNMENT(.tbss))
|
|
|
|
|
*(SORT_BY_ALIGNMENT(.tbss.*))
|
2023-07-01 12:10:12 +00:00
|
|
|
|
KEEP(*(.fstls))
|
2022-12-18 01:51:20 +00:00
|
|
|
|
/* the %fs register is based on this location */
|
|
|
|
|
_tbss_end = .;
|
|
|
|
|
} :Tls
|
|
|
|
|
|
2023-07-01 12:10:12 +00:00
|
|
|
|
.data . : {
|
2020-06-15 14:18:57 +00:00
|
|
|
|
/*BEGIN: Read/Write Data */
|
2023-07-10 02:47:46 +00:00
|
|
|
|
#if SupportsWindows()
|
2022-03-20 15:01:14 +00:00
|
|
|
|
KEEP(*(SORT_BY_NAME(.piro.data.sort.iat.*)))
|
2023-07-10 02:47:46 +00:00
|
|
|
|
#endif
|
2022-03-20 15:01:14 +00:00
|
|
|
|
/*BEGIN: NT FORK COPYING */
|
2020-06-15 14:18:57 +00:00
|
|
|
|
KEEP(*(.dataprologue))
|
|
|
|
|
*(.data .data.*)
|
Release Cosmopolitan v3.3
This change upgrades to GCC 12.3 and GNU binutils 2.42. The GNU linker
appears to have changed things so that only a single de-duplicated str
table is present in the binary, and it gets placed wherever the linker
wants, regardless of what the linker script says. To cope with that we
need to stop using .ident to embed licenses. As such, this change does
significant work to revamp how third party licenses are defined in the
codebase, using `.section .notice,"aR",@progbits`.
This new GCC 12.3 toolchain has support for GNU indirect functions. It
lets us support __target_clones__ for the first time. This is used for
optimizing the performance of libc string functions such as strlen and
friends so far on x86, by ensuring AVX systems favor a second codepath
that uses VEX encoding. It shaves some latency off certain operations.
It's a useful feature to have for scientific computing for the reasons
explained by the test/libcxx/openmp_test.cc example which compiles for
fifteen different microarchitectures. Thanks to the upgrades, it's now
also possible to use newer instruction sets, such as AVX512FP16, VNNI.
Cosmo now uses the %gs register on x86 by default for TLS. Doing it is
helpful for any program that links `cosmo_dlopen()`. Such programs had
to recompile their binaries at startup to change the TLS instructions.
That's not great, since it means every page in the executable needs to
be faulted. The work of rewriting TLS-related x86 opcodes, is moved to
fixupobj.com instead. This is great news for MacOS x86 users, since we
previously needed to morph the binary every time for that platform but
now that's no longer necessary. The only platforms where we need fixup
of TLS x86 opcodes at runtime are now Windows, OpenBSD, and NetBSD. On
Windows we morph TLS to point deeper into the TIB, based on a TlsAlloc
assignment, and on OpenBSD/NetBSD we morph %gs back into %fs since the
kernels do not allow us to specify a value for the %gs register.
OpenBSD users are now required to use APE Loader to run Cosmo binaries
and assimilation is no longer possible. OpenBSD kernel needs to change
to allow programs to specify a value for the %gs register, or it needs
to stop marking executable pages loaded by the kernel as mimmutable().
This release fixes __constructor__, .ctor, .init_array, and lastly the
.preinit_array so they behave the exact same way as glibc.
We no longer use hex constants to define math.h symbols like M_PI.
2024-02-20 19:12:09 +00:00
|
|
|
|
*(.gnu_extab)
|
|
|
|
|
*(.gcc_except_table .gcc_except_table.*)
|
|
|
|
|
*(.exception_ranges*)
|
2023-06-09 12:18:38 +00:00
|
|
|
|
*(.PyRuntime) /* for python */
|
2023-06-05 11:16:15 +00:00
|
|
|
|
*(.subrs) /* for emacs */
|
2020-06-15 14:18:57 +00:00
|
|
|
|
KEEP(*(SORT_BY_NAME(.sort.data.*)))
|
2023-05-09 09:35:05 +00:00
|
|
|
|
. += . > 0 ? CODE_GRANULE : 0;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
2024-02-01 11:39:46 +00:00
|
|
|
|
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
|
|
|
|
|
__got_start = .;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
*(.got)
|
2024-02-01 11:39:46 +00:00
|
|
|
|
__got_end = .;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
|
|
|
|
*(.got.plt)
|
|
|
|
|
|
2023-08-11 11:37:23 +00:00
|
|
|
|
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
|
2023-08-10 01:36:38 +00:00
|
|
|
|
__init_array_start = .;
|
Release Cosmopolitan v3.3
This change upgrades to GCC 12.3 and GNU binutils 2.42. The GNU linker
appears to have changed things so that only a single de-duplicated str
table is present in the binary, and it gets placed wherever the linker
wants, regardless of what the linker script says. To cope with that we
need to stop using .ident to embed licenses. As such, this change does
significant work to revamp how third party licenses are defined in the
codebase, using `.section .notice,"aR",@progbits`.
This new GCC 12.3 toolchain has support for GNU indirect functions. It
lets us support __target_clones__ for the first time. This is used for
optimizing the performance of libc string functions such as strlen and
friends so far on x86, by ensuring AVX systems favor a second codepath
that uses VEX encoding. It shaves some latency off certain operations.
It's a useful feature to have for scientific computing for the reasons
explained by the test/libcxx/openmp_test.cc example which compiles for
fifteen different microarchitectures. Thanks to the upgrades, it's now
also possible to use newer instruction sets, such as AVX512FP16, VNNI.
Cosmo now uses the %gs register on x86 by default for TLS. Doing it is
helpful for any program that links `cosmo_dlopen()`. Such programs had
to recompile their binaries at startup to change the TLS instructions.
That's not great, since it means every page in the executable needs to
be faulted. The work of rewriting TLS-related x86 opcodes, is moved to
fixupobj.com instead. This is great news for MacOS x86 users, since we
previously needed to morph the binary every time for that platform but
now that's no longer necessary. The only platforms where we need fixup
of TLS x86 opcodes at runtime are now Windows, OpenBSD, and NetBSD. On
Windows we morph TLS to point deeper into the TIB, based on a TlsAlloc
assignment, and on OpenBSD/NetBSD we morph %gs back into %fs since the
kernels do not allow us to specify a value for the %gs register.
OpenBSD users are now required to use APE Loader to run Cosmo binaries
and assimilation is no longer possible. OpenBSD kernel needs to change
to allow programs to specify a value for the %gs register, or it needs
to stop marking executable pages loaded by the kernel as mimmutable().
This release fixes __constructor__, .ctor, .init_array, and lastly the
.preinit_array so they behave the exact same way as glibc.
We no longer use hex constants to define math.h symbols like M_PI.
2024-02-20 19:12:09 +00:00
|
|
|
|
KEEP(*(.preinit_array))
|
2023-08-10 01:36:38 +00:00
|
|
|
|
KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*)
|
|
|
|
|
SORT_BY_INIT_PRIORITY(.ctors.*)))
|
|
|
|
|
KEEP(*(.init_array))
|
Release Cosmopolitan v3.3
This change upgrades to GCC 12.3 and GNU binutils 2.42. The GNU linker
appears to have changed things so that only a single de-duplicated str
table is present in the binary, and it gets placed wherever the linker
wants, regardless of what the linker script says. To cope with that we
need to stop using .ident to embed licenses. As such, this change does
significant work to revamp how third party licenses are defined in the
codebase, using `.section .notice,"aR",@progbits`.
This new GCC 12.3 toolchain has support for GNU indirect functions. It
lets us support __target_clones__ for the first time. This is used for
optimizing the performance of libc string functions such as strlen and
friends so far on x86, by ensuring AVX systems favor a second codepath
that uses VEX encoding. It shaves some latency off certain operations.
It's a useful feature to have for scientific computing for the reasons
explained by the test/libcxx/openmp_test.cc example which compiles for
fifteen different microarchitectures. Thanks to the upgrades, it's now
also possible to use newer instruction sets, such as AVX512FP16, VNNI.
Cosmo now uses the %gs register on x86 by default for TLS. Doing it is
helpful for any program that links `cosmo_dlopen()`. Such programs had
to recompile their binaries at startup to change the TLS instructions.
That's not great, since it means every page in the executable needs to
be faulted. The work of rewriting TLS-related x86 opcodes, is moved to
fixupobj.com instead. This is great news for MacOS x86 users, since we
previously needed to morph the binary every time for that platform but
now that's no longer necessary. The only platforms where we need fixup
of TLS x86 opcodes at runtime are now Windows, OpenBSD, and NetBSD. On
Windows we morph TLS to point deeper into the TIB, based on a TlsAlloc
assignment, and on OpenBSD/NetBSD we morph %gs back into %fs since the
kernels do not allow us to specify a value for the %gs register.
OpenBSD users are now required to use APE Loader to run Cosmo binaries
and assimilation is no longer possible. OpenBSD kernel needs to change
to allow programs to specify a value for the %gs register, or it needs
to stop marking executable pages loaded by the kernel as mimmutable().
This release fixes __constructor__, .ctor, .init_array, and lastly the
.preinit_array so they behave the exact same way as glibc.
We no longer use hex constants to define math.h symbols like M_PI.
2024-02-20 19:12:09 +00:00
|
|
|
|
KEEP(*(.ctors))
|
2023-08-10 01:36:38 +00:00
|
|
|
|
__init_array_end = .;
|
|
|
|
|
|
2023-08-11 11:37:23 +00:00
|
|
|
|
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
|
2023-08-10 01:36:38 +00:00
|
|
|
|
__fini_array_start = .;
|
|
|
|
|
KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*)
|
|
|
|
|
SORT_BY_INIT_PRIORITY(.dtors.*)))
|
|
|
|
|
KEEP(*(.fini_array))
|
|
|
|
|
KEEP(*(.dtors))
|
|
|
|
|
__fini_array_end = .;
|
|
|
|
|
|
2020-06-15 14:18:57 +00:00
|
|
|
|
/*BEGIN: Post-Initialization Read-Only */
|
2023-08-11 11:37:23 +00:00
|
|
|
|
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
|
2020-06-15 14:18:57 +00:00
|
|
|
|
KEEP(*(SORT_BY_NAME(.piro.relo.sort.*)))
|
2023-08-11 11:37:23 +00:00
|
|
|
|
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
|
2020-06-15 14:18:57 +00:00
|
|
|
|
KEEP(*(SORT_BY_NAME(.piro.data.sort.*)))
|
|
|
|
|
KEEP(*(.piro.pad.data))
|
2024-02-01 11:39:46 +00:00
|
|
|
|
*(.igot.plt)
|
Release Cosmopolitan v3.3
This change upgrades to GCC 12.3 and GNU binutils 2.42. The GNU linker
appears to have changed things so that only a single de-duplicated str
table is present in the binary, and it gets placed wherever the linker
wants, regardless of what the linker script says. To cope with that we
need to stop using .ident to embed licenses. As such, this change does
significant work to revamp how third party licenses are defined in the
codebase, using `.section .notice,"aR",@progbits`.
This new GCC 12.3 toolchain has support for GNU indirect functions. It
lets us support __target_clones__ for the first time. This is used for
optimizing the performance of libc string functions such as strlen and
friends so far on x86, by ensuring AVX systems favor a second codepath
that uses VEX encoding. It shaves some latency off certain operations.
It's a useful feature to have for scientific computing for the reasons
explained by the test/libcxx/openmp_test.cc example which compiles for
fifteen different microarchitectures. Thanks to the upgrades, it's now
also possible to use newer instruction sets, such as AVX512FP16, VNNI.
Cosmo now uses the %gs register on x86 by default for TLS. Doing it is
helpful for any program that links `cosmo_dlopen()`. Such programs had
to recompile their binaries at startup to change the TLS instructions.
That's not great, since it means every page in the executable needs to
be faulted. The work of rewriting TLS-related x86 opcodes, is moved to
fixupobj.com instead. This is great news for MacOS x86 users, since we
previously needed to morph the binary every time for that platform but
now that's no longer necessary. The only platforms where we need fixup
of TLS x86 opcodes at runtime are now Windows, OpenBSD, and NetBSD. On
Windows we morph TLS to point deeper into the TIB, based on a TlsAlloc
assignment, and on OpenBSD/NetBSD we morph %gs back into %fs since the
kernels do not allow us to specify a value for the %gs register.
OpenBSD users are now required to use APE Loader to run Cosmo binaries
and assimilation is no longer possible. OpenBSD kernel needs to change
to allow programs to specify a value for the %gs register, or it needs
to stop marking executable pages loaded by the kernel as mimmutable().
This release fixes __constructor__, .ctor, .init_array, and lastly the
.preinit_array so they behave the exact same way as glibc.
We no longer use hex constants to define math.h symbols like M_PI.
2024-02-20 19:12:09 +00:00
|
|
|
|
KEEP(*(.dataepilogue))
|
2024-02-01 11:39:46 +00:00
|
|
|
|
|
2023-08-17 18:12:10 +00:00
|
|
|
|
. = ALIGN(. != 0 ? CONSTANT(COMMONPAGESIZE) : 0);
|
2022-03-20 15:01:14 +00:00
|
|
|
|
/*END: NT FORK COPYING */
|
2023-07-01 12:10:12 +00:00
|
|
|
|
_edata = .;
|
|
|
|
|
PROVIDE(edata = .);
|
|
|
|
|
_ezip = .; /* <-- very deprecated */
|
2021-02-08 17:19:00 +00:00
|
|
|
|
} :Ram
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
2023-08-17 18:12:10 +00:00
|
|
|
|
. = ALIGN(CONSTANT(COMMONPAGESIZE));
|
2023-08-11 11:37:23 +00:00
|
|
|
|
|
2021-03-01 14:24:11 +00:00
|
|
|
|
/*END: file content that's loaded by o/s */
|
|
|
|
|
/*END: file content */
|
|
|
|
|
/*BEGIN: bss memory that's addressable */
|
|
|
|
|
|
2023-07-01 12:10:12 +00:00
|
|
|
|
.bss : {
|
2022-03-20 15:01:14 +00:00
|
|
|
|
/*BEGIN: NT FORK COPYING */
|
|
|
|
|
KEEP(*(.bssprologue))
|
2020-06-15 14:18:57 +00:00
|
|
|
|
KEEP(*(SORT_BY_NAME(.piro.bss.init.*)))
|
|
|
|
|
*(.piro.bss)
|
|
|
|
|
KEEP(*(SORT_BY_NAME(.piro.bss.sort.*)))
|
2023-07-01 12:10:12 +00:00
|
|
|
|
__piro_end = .;
|
2023-05-09 09:35:05 +00:00
|
|
|
|
. += . > 0 ? CODE_GRANULE : 0;
|
2020-06-15 14:18:57 +00:00
|
|
|
|
/*END: Post-Initialization Read-Only */
|
|
|
|
|
|
|
|
|
|
/* Statically Allocated Empty Space */
|
|
|
|
|
*(SORT_BY_ALIGNMENT(.bss))
|
|
|
|
|
*(SORT_BY_ALIGNMENT(.bss.*))
|
|
|
|
|
*(COMMON)
|
|
|
|
|
|
|
|
|
|
KEEP(*(SORT_BY_NAME(.sort.bss.*)))
|
|
|
|
|
|
2022-03-20 15:01:14 +00:00
|
|
|
|
KEEP(*(.bssepilogue))
|
2023-07-01 12:10:12 +00:00
|
|
|
|
|
2023-08-17 18:12:10 +00:00
|
|
|
|
. = ALIGN(. != 0 ? CONSTANT(COMMONPAGESIZE) : 0);
|
2023-07-01 12:10:12 +00:00
|
|
|
|
|
2022-03-20 15:01:14 +00:00
|
|
|
|
/*END: NT FORK COPYING */
|
2023-07-01 12:10:12 +00:00
|
|
|
|
} :Ram
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
2023-08-17 18:12:10 +00:00
|
|
|
|
. = ALIGN(CONSTANT(COMMONPAGESIZE));
|
2023-08-11 11:37:23 +00:00
|
|
|
|
_end = .;
|
|
|
|
|
PROVIDE(end = .);
|
2023-06-10 16:15:19 +00:00
|
|
|
|
|
2020-06-15 14:18:57 +00:00
|
|
|
|
/*END: nt addressability guarantee */
|
|
|
|
|
/*END: bsd addressability guarantee */
|
|
|
|
|
/*END: linux addressability guarantee */
|
|
|
|
|
/*END: xnu addressability guarantee */
|
|
|
|
|
|
2021-02-08 17:19:00 +00:00
|
|
|
|
.shstrtab : { *(.shstrtab) }
|
|
|
|
|
.strtab : { *(.strtab) }
|
|
|
|
|
.symtab : { *(.symtab) }
|
2020-08-25 11:23:25 +00:00
|
|
|
|
.stab 0 : { *(.stab) }
|
|
|
|
|
.stabstr 0 : { *(.stabstr) }
|
|
|
|
|
.stab.excl 0 : { *(.stab.excl) }
|
|
|
|
|
.stab.exclstr 0 : { *(.stab.exclstr) }
|
|
|
|
|
.stab.index 0 : { *(.stab.index) }
|
|
|
|
|
.stab.indexstr 0 : { *(.stab.indexstr) }
|
|
|
|
|
.comment 0 : { *(.comment) }
|
|
|
|
|
.debug 0 : { *(.debug) }
|
|
|
|
|
.line 0 : { *(.line) }
|
|
|
|
|
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
|
|
|
|
.debug_sfnames 0 : { *(.debug_sfnames) }
|
|
|
|
|
.debug_aranges 0 : { *(.debug_aranges) }
|
|
|
|
|
.debug_pubnames 0 : { *(.debug_pubnames) }
|
|
|
|
|
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
|
|
|
|
.debug_abbrev 0 : { *(.debug_abbrev) }
|
|
|
|
|
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) }
|
|
|
|
|
.debug_frame 0 : { *(.debug_frame) }
|
|
|
|
|
.debug_str 0 : { *(.debug_str) }
|
2022-09-15 06:03:49 +00:00
|
|
|
|
.debug_line_str 0 : { *(.debug_line_str) }
|
2020-08-25 11:23:25 +00:00
|
|
|
|
.debug_loc 0 : { *(.debug_loc) }
|
|
|
|
|
.debug_macinfo 0 : { *(.debug_macinfo) }
|
|
|
|
|
.debug_weaknames 0 : { *(.debug_weaknames) }
|
|
|
|
|
.debug_funcnames 0 : { *(.debug_funcnames) }
|
|
|
|
|
.debug_typenames 0 : { *(.debug_typenames) }
|
|
|
|
|
.debug_varnames 0 : { *(.debug_varnames) }
|
|
|
|
|
.debug_pubtypes 0 : { *(.debug_pubtypes) }
|
|
|
|
|
.debug_ranges 0 : { *(.debug_ranges) }
|
2022-09-15 06:03:49 +00:00
|
|
|
|
.debug_rnglists 0 : { *(.debug_rnglists) }
|
2020-08-25 11:23:25 +00:00
|
|
|
|
.debug_macro 0 : { *(.debug_macro) }
|
|
|
|
|
.debug_addr 0 : { *(.debug_addr) }
|
|
|
|
|
.gnu.attributes 0 : { KEEP(*(.gnu.attributes)) }
|
|
|
|
|
.GCC.command.line 0 : { *(.GCC.command.line) }
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
2023-06-10 16:15:19 +00:00
|
|
|
|
.zip 0 : {
|
|
|
|
|
KEEP(*(.zip.file))
|
|
|
|
|
__zip_cdir_start = .;
|
|
|
|
|
KEEP(*(.zip.cdir))
|
|
|
|
|
__zip_cdir_size = . - __zip_cdir_start;
|
|
|
|
|
KEEP(*(.zip.eocd))
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-15 14:18:57 +00:00
|
|
|
|
/DISCARD/ : {
|
2023-07-10 02:47:46 +00:00
|
|
|
|
#if !SupportsWindows()
|
|
|
|
|
*(.idata.ro);
|
|
|
|
|
*(.idata.ro.*)
|
|
|
|
|
*(.piro.data.sort.iat.*)
|
|
|
|
|
#endif
|
2023-06-08 11:37:05 +00:00
|
|
|
|
*(__patchable_function_entries)
|
2024-02-25 19:11:34 +00:00
|
|
|
|
*(.note.gnu.property)
|
2021-02-08 17:19:00 +00:00
|
|
|
|
*(__mcount_loc)
|
2024-02-01 11:39:46 +00:00
|
|
|
|
*(.rela.dyn)
|
2020-06-15 14:18:57 +00:00
|
|
|
|
*(.discard)
|
|
|
|
|
*(.yoink)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-25 12:43:04 +00:00
|
|
|
|
ape_pe_filealignment = 512;
|
|
|
|
|
ape_pe_sectionalignment = 4096;
|
|
|
|
|
ape_pe_sizeofheaders = SIZEOF(.head);
|
|
|
|
|
ape_pe_sizeofimage = ROUNDUP(_end - __executable_start, ape_pe_sectionalignment);
|
|
|
|
|
|
2021-02-08 17:19:00 +00:00
|
|
|
|
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);
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
2023-07-01 12:10:12 +00:00
|
|
|
|
_tls_size = _tbss_end - _tdata_start;
|
|
|
|
|
_tdata_size = _tdata_end - _tdata_start;
|
|
|
|
|
_tbss_size = _tbss_end - _tbss_start;
|
|
|
|
|
_tbss_offset = _tbss_start - _tdata_start;
|
|
|
|
|
_tls_content = (_tdata_end - _tdata_start) + (_tbss_end - _tbss_start);
|
2024-05-08 11:03:51 +00:00
|
|
|
|
_tdata_align = ALIGNOF(.tdata);
|
|
|
|
|
_tbss_align = ALIGNOF(.tbss);
|
|
|
|
|
_tls_align = MAX(TLS_ALIGNMENT, MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)));
|
2023-07-01 12:10:12 +00:00
|
|
|
|
|
|
|
|
|
ape_cod_offset = 0;
|
|
|
|
|
ape_cod_vaddr = ADDR(.head);
|
|
|
|
|
ape_cod_paddr = LOADADDR(.head);
|
2023-08-11 11:37:23 +00:00
|
|
|
|
ape_cod_filesz = ADDR(.rodata) - ADDR(.head);
|
2023-07-01 12:10:12 +00:00
|
|
|
|
ape_cod_memsz = ape_cod_filesz;
|
2023-08-17 18:12:10 +00:00
|
|
|
|
ape_cod_align = CONSTANT(COMMONPAGESIZE);
|
2023-07-01 12:10:12 +00:00
|
|
|
|
ape_cod_rva = RVA(ape_cod_vaddr);
|
|
|
|
|
|
|
|
|
|
ape_rom_vaddr = ADDR(.rodata);
|
2023-08-11 11:37:23 +00:00
|
|
|
|
ape_rom_offset = ape_rom_vaddr - __executable_start;
|
2023-07-01 12:10:12 +00:00
|
|
|
|
ape_rom_paddr = LOADADDR(.rodata);
|
2023-08-11 11:37:23 +00:00
|
|
|
|
ape_rom_filesz = ADDR(.tbss) - ADDR(.rodata);
|
2023-07-01 12:10:12 +00:00
|
|
|
|
ape_rom_memsz = ape_rom_filesz;
|
2023-08-17 18:12:10 +00:00
|
|
|
|
ape_rom_align = CONSTANT(COMMONPAGESIZE);
|
2023-07-01 12:10:12 +00:00
|
|
|
|
ape_rom_rva = RVA(ape_rom_vaddr);
|
|
|
|
|
|
|
|
|
|
ape_ram_vaddr = ADDR(.data);
|
2023-08-11 11:37:23 +00:00
|
|
|
|
ape_ram_offset = ape_ram_vaddr - __executable_start;
|
2023-07-01 12:10:12 +00:00
|
|
|
|
ape_ram_paddr = LOADADDR(.data);
|
2023-08-11 11:37:23 +00:00
|
|
|
|
ape_ram_filesz = ADDR(.bss) - ADDR(.data);
|
|
|
|
|
ape_ram_memsz = _end - ADDR(.data);
|
2023-08-17 18:12:10 +00:00
|
|
|
|
ape_ram_align = CONSTANT(COMMONPAGESIZE);
|
2023-07-01 12:10:12 +00:00
|
|
|
|
ape_ram_rva = RVA(ape_ram_vaddr);
|
|
|
|
|
|
|
|
|
|
ape_stack_pf = DEFINED(ape_stack_pf) ? ape_stack_pf : PF_R | PF_W;
|
|
|
|
|
ape_stack_prot = _PF2PROT(ape_stack_pf);
|
|
|
|
|
ape_stack_offset = 0;
|
|
|
|
|
ape_stack_vaddr = DEFINED(ape_stack_vaddr) ? ape_stack_vaddr : 0x700000000000;
|
|
|
|
|
ape_stack_paddr = ape_ram_paddr + ape_ram_filesz;
|
|
|
|
|
ape_stack_filesz = 0;
|
2023-08-16 14:54:40 +00:00
|
|
|
|
ape_stack_memsz = DEFINED(ape_stack_memsz) ? ape_stack_memsz : 8 * 1024 * 1024;
|
2024-06-21 03:46:42 +00:00
|
|
|
|
|
2023-07-01 12:10:12 +00:00
|
|
|
|
ape_note_offset = ape_cod_offset + (ape_note - ape_cod_vaddr);
|
|
|
|
|
ape_note_filesz = ape_note_end - ape_note;
|
|
|
|
|
ape_note_memsz = ape_note_filesz;
|
|
|
|
|
|
|
|
|
|
ape_text_vaddr = ADDR(.text);
|
2023-08-11 11:37:23 +00:00
|
|
|
|
ape_text_offset = ape_text_vaddr - __executable_start;
|
|
|
|
|
ape_text_paddr = LOADADDR(.text);
|
|
|
|
|
ape_text_filesz = ADDR(.rodata) - ADDR(.text);
|
2023-07-01 12:10:12 +00:00
|
|
|
|
ape_text_memsz = ape_text_filesz;
|
2023-08-17 18:12:10 +00:00
|
|
|
|
ape_text_align = CONSTANT(COMMONPAGESIZE);
|
2023-07-01 12:10:12 +00:00
|
|
|
|
ape_text_rva = RVA(ape_text_vaddr);
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
2022-05-22 11:51:02 +00:00
|
|
|
|
/* we roundup here because xnu wants the file load segments page-aligned */
|
|
|
|
|
/* but we don't want to add the nop padding to the ape program, so we'll */
|
|
|
|
|
/* let ape.S dd read past the end of the file into the wrapping binaries */
|
|
|
|
|
SHSTUB2(ape_loader_dd_skip, DEFINED(ape_loader) ? RVA(ape_loader) / 64 : 0);
|
|
|
|
|
SHSTUB2(ape_loader_dd_count,
|
|
|
|
|
DEFINED(ape_loader_end)
|
2023-08-17 18:12:10 +00:00
|
|
|
|
? ROUNDUP(ape_loader_end - ape_loader, CONSTANT(COMMONPAGESIZE)) / 64
|
2022-05-22 11:51:02 +00:00
|
|
|
|
: 0);
|
2022-05-21 14:52:58 +00:00
|
|
|
|
|
2021-02-08 12:04:42 +00:00
|
|
|
|
#if SupportsMetal()
|
2023-07-01 12:10:12 +00:00
|
|
|
|
v_ape_realsectors = MIN(0x70000 - IMAGE_BASE_REAL, ROUNDUP(RVA(_ezip), 512)) / 512;
|
|
|
|
|
v_ape_realbytes = v_ape_realsectors * 512;
|
|
|
|
|
v_ape_realdwords = v_ape_realsectors * (512 / 4);
|
|
|
|
|
v_ape_allsectors = ROUNDUP(RVA(_ezip), 512) / 512;
|
|
|
|
|
v_ape_allbytes = v_ape_allsectors * 512;
|
|
|
|
|
v_ape_highsectors = MIN(0xffff, v_ape_allsectors - v_ape_realsectors);
|
2022-09-29 21:43:08 +00:00
|
|
|
|
TSSDESCSTUB2(_tss, _tss, _tss_end ? _tss_end - _tss - 1 : 0);
|
2021-02-08 12:04:42 +00:00
|
|
|
|
#endif
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
2021-02-08 12:04:42 +00:00
|
|
|
|
#if SupportsXnu()
|
|
|
|
|
/* Generates deterministic ID. */
|
2020-06-15 14:18:57 +00:00
|
|
|
|
#define PHI 0x9e3779b9925d4c17
|
|
|
|
|
#define XOR(X,Y) ((X | Y) - (X & Y))
|
|
|
|
|
#define XORSHIFT(X,Y) \
|
|
|
|
|
X = XOR(X, (Y >> 12)); \
|
|
|
|
|
X = XOR(X, (Y << 25)); \
|
|
|
|
|
X = XOR(X, (Y >> 27))
|
|
|
|
|
#define KMH(X,Y) \
|
|
|
|
|
X = (X + (Y >> 000) & 0xFF) * PHI; \
|
|
|
|
|
X = (X + (Y >> 010) & 0xFF) * PHI; \
|
|
|
|
|
X = (X + (Y >> 020) & 0xFF) * PHI; \
|
|
|
|
|
X = (X + (Y >> 030) & 0xFF) * PHI
|
2020-06-16 02:01:28 +00:00
|
|
|
|
#define CHURN(X) \
|
2021-02-08 17:19:00 +00:00
|
|
|
|
XORSHIFT(ape_uuid1, X); \
|
|
|
|
|
KMH(ape_uuid1, X); \
|
|
|
|
|
XORSHIFT(ape_uuid2, X); \
|
|
|
|
|
KMH(ape_uuid2, X)
|
2023-07-01 12:10:12 +00:00
|
|
|
|
ape_uuid1 = 88172645463325252;
|
|
|
|
|
ape_uuid2 = 88172645463325252;
|
2021-02-08 17:19:00 +00:00
|
|
|
|
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_end);
|
|
|
|
|
CHURN(ape_note_filesz);
|
|
|
|
|
CHURN(ape_note_memsz);
|
|
|
|
|
CHURN(ape_note_offset);
|
|
|
|
|
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);
|
2023-07-01 12:10:12 +00:00
|
|
|
|
CHURN(ape_cod_vaddr);
|
|
|
|
|
CHURN(ape_cod_align);
|
|
|
|
|
CHURN(ape_cod_filesz);
|
|
|
|
|
CHURN(ape_cod_memsz);
|
|
|
|
|
CHURN(ape_cod_offset);
|
|
|
|
|
CHURN(ape_cod_paddr);
|
|
|
|
|
CHURN(ape_cod_rva);
|
|
|
|
|
CHURN(ape_cod_vaddr);
|
2021-02-08 17:19:00 +00:00
|
|
|
|
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);
|
2020-06-16 02:01:28 +00:00
|
|
|
|
CHURN(ADDR(.bss));
|
|
|
|
|
CHURN(_start);
|
2021-02-08 17:19:00 +00:00
|
|
|
|
CHURN(ape_phdrs);
|
2021-02-08 12:04:42 +00:00
|
|
|
|
#if SupportsMetal()
|
2022-12-18 01:51:20 +00:00
|
|
|
|
CHURN(v_ape_allsectors);
|
2021-02-08 12:04:42 +00:00
|
|
|
|
#endif
|
|
|
|
|
#if SupportsXnu()
|
2021-02-08 17:19:00 +00:00
|
|
|
|
CHURN(ape_macho);
|
2021-02-08 12:04:42 +00:00
|
|
|
|
#endif
|
2021-02-24 04:23:19 +00:00
|
|
|
|
#if SupportsWindows() || SupportsMetal()
|
2021-02-08 17:19:00 +00:00
|
|
|
|
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);
|
2021-02-08 12:04:42 +00:00
|
|
|
|
CHURN(WinMain);
|
|
|
|
|
#endif /* SupportsWindows() */
|
|
|
|
|
#endif /* SupportsXnu() */
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
2022-06-20 11:32:25 +00:00
|
|
|
|
#if SupportsWindows() || SupportsMetal()
|
|
|
|
|
#define LINK_WINDOWS (SupportsWindows() && !DEFINED(EfiMain))
|
|
|
|
|
PFSTUB4(ape_pe_offset, ape_pe - ape_mz);
|
2023-07-01 12:10:12 +00:00
|
|
|
|
ape_pe_optsz = ape_pe_sections - (ape_pe + 24);
|
2023-07-25 12:43:04 +00:00
|
|
|
|
ASSERT(ape_pe_optsz % 8 == 0, "SizeOfOptionalHeader must be multiple of 8");
|
2023-07-01 12:10:12 +00:00
|
|
|
|
ape_pe_shnum = (ape_pe_sections_end - ape_pe_sections) / 40;
|
|
|
|
|
ape_pe_base = IMAGE_BASE_VIRTUAL;
|
2023-07-24 07:49:06 +00:00
|
|
|
|
ape_idataz = LINK_WINDOWS ? RVA(ape_idata_iat) : 0;
|
2023-07-01 12:10:12 +00:00
|
|
|
|
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;
|
|
|
|
|
v_ntdllchar = LINK_WINDOWS ? 288 : 0;
|
|
|
|
|
v_ntsubversion = LINK_WINDOWS ? 6 : 5;
|
|
|
|
|
v_ntsubsystem = (LINK_WINDOWS
|
|
|
|
|
? (DEFINED(GetMessage)
|
|
|
|
|
? kNtImageSubsystemWindowsGui
|
|
|
|
|
: kNtImageSubsystemWindowsCui)
|
|
|
|
|
: kNtImageSubsystemEfiApplication);
|
|
|
|
|
ape_pe_entry = LINK_WINDOWS ? WinMain : EfiMain;
|
2022-06-20 11:32:25 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if SupportsXnu()
|
|
|
|
|
SHSTUB2(ape_macho_dd_skip, RVA(ape_macho) / 8);
|
|
|
|
|
SHSTUB2(ape_macho_dd_count, (ape_macho_end - ape_macho) / 8);
|
|
|
|
|
#endif
|
|
|
|
|
|
2021-02-08 17:19:00 +00:00
|
|
|
|
ASSERT(DEFINED(ape_mz) ? ape_mz == IMAGE_BASE_VIRTUAL : 1, "linker panic");
|
2020-06-15 14:18:57 +00:00
|
|
|
|
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");
|
|
|
|
|
|
2021-02-08 17:19:00 +00:00
|
|
|
|
ASSERT((!DEFINED(ape_grub) ? 1 : RVA(ape_grub) < 8192),
|
2020-06-15 14:18:57 +00:00
|
|
|
|
"grub stub needs to be in first 8kb of image");
|
|
|
|
|
|
2022-05-19 23:57:49 +00:00
|
|
|
|
ASSERT(IS2POW(ape_stack_memsz),
|
|
|
|
|
"ape_stack_memsz must be a two power");
|
|
|
|
|
|
2022-09-12 11:19:32 +00:00
|
|
|
|
ASSERT(ape_stack_vaddr % ape_stack_memsz == 0,
|
2022-11-11 05:52:47 +00:00
|
|
|
|
"ape_stack_vaddr must have ape_stack_memsz alignment; try using STATIC_STACK_ADDR(0x700000040000 & -ape_stack_memsz);");
|
2022-05-19 23:57:49 +00:00
|
|
|
|
|
2022-09-10 18:49:13 +00:00
|
|
|
|
ASSERT(ALIGNOF(.tdata) <= TLS_ALIGNMENT && ALIGNOF(.tbss) <= TLS_ALIGNMENT,
|
|
|
|
|
"_Thread_local _Alignof can't exceed TLS_ALIGNMENT");
|
|
|
|
|
|
2023-08-12 23:44:04 +00:00
|
|
|
|
ASSERT(DEFINED(main), "main() function not defined");
|
|
|
|
|
|
2020-06-15 14:18:57 +00:00
|
|
|
|
/* Let's not be like Knight Capital. */
|
|
|
|
|
/* NOCROSSREFS_TO(.test .text) */
|
|
|
|
|
|
2021-02-08 17:19:00 +00:00
|
|
|
|
/* ASSERT(ape_sysv_start == ape_text_vaddr, */
|
2020-06-15 14:18:57 +00:00
|
|
|
|
/* "ape_sysv_start() must be first in .text"); */
|
|
|
|
|
|
|
|
|
|
#endif /* __LINKER__ */
|