mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-04 00:40:27 +00:00
Compare commits
No commits in common. "master" and "0.2" have entirely different histories.
30233 changed files with 368463 additions and 4380374 deletions
|
@ -6,11 +6,8 @@ AlignConsecutiveMacros: true
|
|||
AlignConsecutiveDeclarations: false
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AllowShortFunctionsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
IncludeBlocks: Merge
|
||||
---
|
||||
Language: Cpp
|
||||
AllowShortFunctionsOnASingleLine: false
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
# Run this command to always ignore formatting commits in git blame
|
||||
# git config blame.ignoreRevsFile .git-blame-ignore-revs
|
||||
|
||||
# Upgraded clang-format to 19.0.0git
|
||||
89fc95fefd40413706ff1bdaac2e8d98b328dbf1
|
||||
# vim c++ filetype in modelines
|
||||
04c6bc478e082263d67c41bedbd033dde2d429eb
|
||||
# Ran clang-format
|
||||
f032b5570b4cd87c6bb4abb54c0b98e69c939955
|
||||
# Applied clang-format update to repo
|
||||
6e6fc38935054db0534d5af4fb99c6193305b946
|
||||
# revert retabbing
|
||||
2b315626f3af765cdfbc61114647412cdb798b3a
|
||||
# more modeline errata
|
||||
3a8e01a77a7c97af0b16fb1651b230cee7f7d4c6
|
||||
# fix more vi modelines
|
||||
2fc507c98f53a76718f61f9a36602f86b5ac0cc9
|
||||
# flip et/noet in modelines
|
||||
e16a7d8f3b8f906c3ef76e79f57f3adfc7f25186
|
||||
# fix vi modelines
|
||||
394d998315f613a888cc6b6c051d4163bdf5cd6f
|
||||
# clang-format
|
||||
c0eacf2eb1e1c0b3bd4f71f12fef258f5b249c3f
|
||||
# ape-m1 formatting cleanup
|
||||
da8baf2aa5ce93b958aca90a0ae69f537806324b
|
||||
# Run clang-format on most sources
|
||||
369f9740de4534c28d0e81ab2afc99decbb9a3e6
|
||||
# Get rid of .internal.h convention in LIBC_INTRIN
|
||||
86d884cce24d773e298a2714c1e3d91ecab9be45
|
||||
# Remove .internal from more header filenames
|
||||
31194165d2afca36c2315a6e7ca2f0797dde09e3
|
10
.gitattributes
vendored
10
.gitattributes
vendored
|
@ -1,10 +0,0 @@
|
|||
# -*- conf -*-
|
||||
*.gz binary
|
||||
*.so binary
|
||||
*.dll binary
|
||||
*.dylib binary
|
||||
/build/bootstrap/* binary
|
||||
/usr/share/terminfo/* binary
|
||||
/usr/share/terminfo/*/* binary
|
||||
/usr/share/zoneinfo/* binary
|
||||
/usr/share/zoneinfo/*/* binary
|
59
.github/ISSUE_TEMPLATE/01-bug-low.yml
vendored
59
.github/ISSUE_TEMPLATE/01-bug-low.yml
vendored
|
@ -1,59 +0,0 @@
|
|||
name: Low Severity Bugs
|
||||
description: Used to report low severity bugs in cosmopolitan (e.g. cosmetic issues, non critical UI glitches)
|
||||
title: "Bug: "
|
||||
labels: ["bug", "low severity"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report!
|
||||
Please include information about your system, the steps to reproduce the bug,
|
||||
and the version of cosmopolitan that you are using.
|
||||
If possible, please provide a minimal code example that reproduces the bug.
|
||||
You may also consider using function call tracing `--ftrace` or the lighter system call tracing `--strace`
|
||||
for additional technical logging that may allow us to narrow down where the fault occurred.
|
||||
- type: input
|
||||
id: contact
|
||||
attributes:
|
||||
label: Contact Details
|
||||
description: How can we get in touch with you if we need more info?
|
||||
placeholder: ex. email@example.com
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: what-happened
|
||||
attributes:
|
||||
label: What happened?
|
||||
description: Also tell us, what did you expect to happen?
|
||||
placeholder: Tell us what you see!
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: What version of our software are you running? (use `--version` to get a version string)
|
||||
placeholder: "cosmocc (GCC) 12.3.0"
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: operating-system
|
||||
attributes:
|
||||
label: What operating system are you seeing the problem on?
|
||||
multiple: true
|
||||
options:
|
||||
- Linux
|
||||
- Mac
|
||||
- Windows
|
||||
- FreeBSD
|
||||
- OpenBSD
|
||||
- NetBSD
|
||||
- BIOS
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
59
.github/ISSUE_TEMPLATE/02-bug-medium.yml
vendored
59
.github/ISSUE_TEMPLATE/02-bug-medium.yml
vendored
|
@ -1,59 +0,0 @@
|
|||
name: Medium Severity Bug
|
||||
description: Used to report medium severity bugs in cosmopolitan (e.g. Malfunctioning Features but generally still useable)
|
||||
title: "Bug: "
|
||||
labels: ["bug", "medium severity"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report!
|
||||
Please include information about your system, the steps to reproduce the bug,
|
||||
and the version of cosmopolitan that you are using.
|
||||
If possible, please provide a minimal code example that reproduces the bug.
|
||||
You may also consider using function call tracing `--ftrace` or the lighter system call tracing `--strace`
|
||||
for additional technical logging that may allow us to narrow down where the fault occurred.
|
||||
- type: input
|
||||
id: contact
|
||||
attributes:
|
||||
label: Contact Details
|
||||
description: How can we get in touch with you if we need more info?
|
||||
placeholder: ex. email@example.com
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: what-happened
|
||||
attributes:
|
||||
label: What happened?
|
||||
description: Also tell us, what did you expect to happen?
|
||||
placeholder: Tell us what you see!
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: What version of our software are you running? (use `--version` to get a version string)
|
||||
placeholder: "cosmocc (GCC) 12.3.0"
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: operating-system
|
||||
attributes:
|
||||
label: What operating system are you seeing the problem on?
|
||||
multiple: true
|
||||
options:
|
||||
- Linux
|
||||
- Mac
|
||||
- Windows
|
||||
- FreeBSD
|
||||
- OpenBSD
|
||||
- NetBSD
|
||||
- BIOS
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
59
.github/ISSUE_TEMPLATE/03-bug-high.yml
vendored
59
.github/ISSUE_TEMPLATE/03-bug-high.yml
vendored
|
@ -1,59 +0,0 @@
|
|||
name: High Severity Bug
|
||||
description: Used to report high severity bugs in cosmopolitan (e.g. Malfunctioning features hindering important common workflow)
|
||||
title: "Bug: "
|
||||
labels: ["bug", "high severity"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report!
|
||||
Please include information about your system, the steps to reproduce the bug,
|
||||
and the version of cosmopolitan that you are using.
|
||||
If possible, please provide a minimal code example that reproduces the bug.
|
||||
You may also consider using function call tracing `--ftrace` or the lighter system call tracing `--strace`
|
||||
for additional technical logging that may allow us to narrow down where the fault occurred.
|
||||
- type: input
|
||||
id: contact
|
||||
attributes:
|
||||
label: Contact Details
|
||||
description: How can we get in touch with you if we need more info?
|
||||
placeholder: ex. email@example.com
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: what-happened
|
||||
attributes:
|
||||
label: What happened?
|
||||
description: Also tell us, what did you expect to happen?
|
||||
placeholder: Tell us what you see!
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: What version of our software are you running? (use `--version` to get a version string)
|
||||
placeholder: "cosmocc (GCC) 12.3.0"
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: operating-system
|
||||
attributes:
|
||||
label: What operating system are you seeing the problem on?
|
||||
multiple: true
|
||||
options:
|
||||
- Linux
|
||||
- Mac
|
||||
- Windows
|
||||
- FreeBSD
|
||||
- OpenBSD
|
||||
- NetBSD
|
||||
- BIOS
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
59
.github/ISSUE_TEMPLATE/04-bug-critical.yml
vendored
59
.github/ISSUE_TEMPLATE/04-bug-critical.yml
vendored
|
@ -1,59 +0,0 @@
|
|||
name: Critical Severity Bug
|
||||
description: Used to report critical severity bugs in cosmopolitan (e.g. Crashing, Corrupted, Dataloss)
|
||||
title: "Bug: "
|
||||
labels: ["bug", "critical severity"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report!
|
||||
Please include information about your system, the steps to reproduce the bug,
|
||||
and the version of cosmopolitan that you are using.
|
||||
If possible, please provide a minimal code example that reproduces the bug.
|
||||
You may also consider using function call tracing `--ftrace` or the lighter system call tracing `--strace`
|
||||
for additional technical logging that may allow us to narrow down where the fault occurred.
|
||||
- type: input
|
||||
id: contact
|
||||
attributes:
|
||||
label: Contact Details
|
||||
description: How can we get in touch with you if we need more info?
|
||||
placeholder: ex. email@example.com
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: what-happened
|
||||
attributes:
|
||||
label: What happened?
|
||||
description: Also tell us, what did you expect to happen?
|
||||
placeholder: Tell us what you see!
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: What version of our software are you running? (use `--version` to get a version string)
|
||||
placeholder: "cosmocc (GCC) 12.3.0"
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: operating-system
|
||||
attributes:
|
||||
label: What operating system are you seeing the problem on?
|
||||
multiple: true
|
||||
options:
|
||||
- Linux
|
||||
- Mac
|
||||
- Windows
|
||||
- FreeBSD
|
||||
- OpenBSD
|
||||
- NetBSD
|
||||
- BIOS
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
51
.github/ISSUE_TEMPLATE/05-enhancement.yml
vendored
51
.github/ISSUE_TEMPLATE/05-enhancement.yml
vendored
|
@ -1,51 +0,0 @@
|
|||
name: Enhancement template
|
||||
description: Used to request enhancements for cosmopolitan
|
||||
title: "Feature Request: "
|
||||
labels: ["enhancement"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
[Please post your idea first in Discussion if there is not yet a consensus for this enhancement request. This will help to keep this issue tracker focused on enhancements that the community has agreed needs to be implemented.](https://github.com/jart/cosmopolitan/discussions/categories/ideas)
|
||||
|
||||
- type: checkboxes
|
||||
id: prerequisites
|
||||
attributes:
|
||||
label: Prerequisites
|
||||
description: Please confirm the following before submitting your enhancement request.
|
||||
options:
|
||||
- label: I am running the latest code. Mention the version if possible as well.
|
||||
required: true
|
||||
- label: I carefully followed the [README.md](https://github.com/jart/cosmopolitan/blob/master/README.md).
|
||||
required: true
|
||||
- label: I searched using keywords relevant to my issue to make sure that I am creating a new issue that is not already open (or closed).
|
||||
required: true
|
||||
- label: I reviewed the [Discussions](https://github.com/jart/cosmopolitan/discussions), and have a new and useful enhancement to share.
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: feature-description
|
||||
attributes:
|
||||
label: Feature Description
|
||||
description: Please provide a detailed written description of what you were trying to do, and what you expected `cosmopolitan` to do as an enhancement.
|
||||
placeholder: Detailed description of the enhancement
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: motivation
|
||||
attributes:
|
||||
label: Motivation
|
||||
description: Please provide a detailed written description of reasons why this feature is necessary and how it is useful to `cosmopolitan` users.
|
||||
placeholder: Explanation of why this feature is needed and its benefits
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: possible-implementation
|
||||
attributes:
|
||||
label: Possible Implementation
|
||||
description: If you have an idea as to how it can be implemented, please write a detailed description. Feel free to give links to external sources or share visuals that might be helpful to understand the details better.
|
||||
placeholder: Detailed description of potential implementation
|
||||
validations:
|
||||
required: false
|
52
.github/ISSUE_TEMPLATE/06-research.yml
vendored
52
.github/ISSUE_TEMPLATE/06-research.yml
vendored
|
@ -1,52 +0,0 @@
|
|||
name: Research
|
||||
description: Track new technical research area
|
||||
title: "Research: "
|
||||
labels: ["research"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Don't forget to check for any [duplicate research issue tickets](https://github.com/jart/cosmopolitan/issues?q=is%3Aopen+is%3Aissue+label%3A%22research+%F0%9F%94%AC%22)
|
||||
|
||||
- type: checkboxes
|
||||
id: research-stage
|
||||
attributes:
|
||||
label: Research Stage
|
||||
description: Track general state of this research ticket
|
||||
options:
|
||||
- label: Background Research (Let's try to avoid reinventing the wheel)
|
||||
- label: Hypothesis Formed (How do you think this will work and it's effect?)
|
||||
- label: Strategy / Implementation Forming
|
||||
- label: Analysis of results
|
||||
- label: Debrief / Documentation (So people in the future can learn from us)
|
||||
|
||||
- type: textarea
|
||||
id: background
|
||||
attributes:
|
||||
label: Previous existing literature and research
|
||||
description: Whats the current state of the art and whats the motivation for this research?
|
||||
|
||||
- type: textarea
|
||||
id: hypothesis
|
||||
attributes:
|
||||
label: Hypothesis
|
||||
description: How do you think this will work and it's effect?
|
||||
|
||||
- type: textarea
|
||||
id: implementation
|
||||
attributes:
|
||||
label: Implementation
|
||||
description: Got an approach? e.g. a PR ready to go?
|
||||
|
||||
- type: textarea
|
||||
id: analysis
|
||||
attributes:
|
||||
label: Analysis
|
||||
description: How does the proposed implementation behave?
|
||||
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
28
.github/ISSUE_TEMPLATE/07-refactor.yml
vendored
28
.github/ISSUE_TEMPLATE/07-refactor.yml
vendored
|
@ -1,28 +0,0 @@
|
|||
name: Refactor (Maintainers)
|
||||
description: Used to track refactoring opportunities
|
||||
title: "Refactor: "
|
||||
labels: ["refactor"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Don't forget to [check for existing refactor issue tickets](https://github.com/jart/cosmopolitan/issues?q=is%3Aopen+is%3Aissue+label%3Arefactoring) in case it's already covered.
|
||||
Also you may want to check [Pull request refactor label as well](https://github.com/jart/cosmopolitan/pulls?q=is%3Aopen+is%3Apr+label%3Arefactoring) for duplicates too.
|
||||
|
||||
- type: textarea
|
||||
id: background-description
|
||||
attributes:
|
||||
label: Background Description
|
||||
description: Please provide a detailed written description of the pain points you are trying to solve.
|
||||
placeholder: Detailed description behind your motivation to request refactor
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: possible-approaches
|
||||
attributes:
|
||||
label: Possible Refactor Approaches
|
||||
description: If you have some idea of possible approaches to solve this problem. You may want to make it a todo list.
|
||||
placeholder: Your idea of possible refactoring opportunity/approaches
|
||||
validations:
|
||||
required: false
|
15
.github/ISSUE_TEMPLATE/config.yml
vendored
15
.github/ISSUE_TEMPLATE/config.yml
vendored
|
@ -1,15 +0,0 @@
|
|||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: FAQ
|
||||
url: https://github.com/jart/cosmopolitan/wiki/FAQ
|
||||
about: Is your question a common one? You may want to check here first.
|
||||
- name: Got an idea?
|
||||
url: https://github.com/jart/cosmopolitan/discussions/categories/ideas
|
||||
about: Pop it there. It may then become an enhancement ticket.
|
||||
- name: Got a question?
|
||||
url: https://github.com/jart/cosmopolitan/discussions/categories/q-a
|
||||
about: Ask a question there!
|
||||
- name: Want to contribute?
|
||||
url: https://github.com/jart/cosmopolitan/wiki/contribute
|
||||
about: Head to the contribution guide page of the wiki for areas you can help with
|
||||
|
49
.github/labeler.yml
vendored
49
.github/labeler.yml
vendored
|
@ -1,49 +0,0 @@
|
|||
# https://github.com/actions/labeler
|
||||
|
||||
documentation:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- README.md
|
||||
- LICENSE
|
||||
- CONTRIBUTING.md
|
||||
- libc/README.md
|
||||
- tool/cosmocc/README.md
|
||||
- third_party/getopt/README.txt
|
||||
build:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- build/**
|
||||
- Makefile
|
||||
- '*/*.mk'
|
||||
examples:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: examples/**
|
||||
devops:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- .github/**
|
||||
- .clang-format
|
||||
dsp:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- dsp/**
|
||||
ape:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ape/**
|
||||
libc:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- libc/**
|
||||
net:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- net/**
|
||||
third_party:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- third_party/**
|
||||
tool:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- tool/**
|
69
.github/workflows/build.yml
vendored
69
.github/workflows/build.yml
vendored
|
@ -1,69 +0,0 @@
|
|||
name: build
|
||||
|
||||
env:
|
||||
COSMOCC_VERSION: 3.9.2
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "master"
|
||||
- "flake"
|
||||
pull_request:
|
||||
branches:
|
||||
- "master"
|
||||
|
||||
# run workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
matrix_on_mode:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
mode: ["", tiny, rel, tinylinux, optlinux]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
# Full checkout needed for git-restore-mtime-bare.
|
||||
fetch-depth: 0
|
||||
|
||||
# TODO(jart): fork this action.
|
||||
- uses: chetan/git-restore-mtime-action@v2
|
||||
|
||||
- uses: actions/cache/restore@v4
|
||||
id: cache
|
||||
with:
|
||||
path: |
|
||||
.cosmocc
|
||||
o
|
||||
key: ${{ env.COSMOCC_VERSION }}-${{ matrix.mode }}-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ env.COSMOCC_VERSION }}-${{ matrix.mode }}-
|
||||
${{ env.COSMOCC_VERSION }}-
|
||||
|
||||
- name: Restore mtimes
|
||||
if: steps.cache.outputs.cache-hit == 'true'
|
||||
run: |
|
||||
while read mtime file; do
|
||||
[ -f "$file" ] && touch -d "@$mtime" "$file"
|
||||
done < o/.mtimes
|
||||
|
||||
- name: support ape bins 1
|
||||
run: sudo cp -a build/bootstrap/ape.elf /usr/bin/ape
|
||||
|
||||
- name: support ape bins 2
|
||||
run: sudo sh -c "echo ':APE:M::MZqFpD::/usr/bin/ape:' >/proc/sys/fs/binfmt_misc/register"
|
||||
|
||||
- name: make matrix
|
||||
run: V=0 make -j2 MODE=${{ matrix.mode }}
|
||||
|
||||
- name: Save mtimes
|
||||
run: |
|
||||
find o -type f -exec stat -c "%Y %n" {} \; > o/.mtimes
|
||||
|
||||
- uses: actions/cache/save@v4
|
||||
with:
|
||||
path: |
|
||||
.cosmocc
|
||||
o
|
||||
key: ${{ env.COSMOCC_VERSION }}-${{ matrix.mode }}-${{ github.sha }}
|
17
.github/workflows/labeler.yml
vendored
17
.github/workflows/labeler.yml
vendored
|
@ -1,17 +0,0 @@
|
|||
name: "Pull Request Labeler"
|
||||
on:
|
||||
- pull_request_target
|
||||
|
||||
jobs:
|
||||
labeler:
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
repository: "jart/cosmopolitan"
|
||||
- uses: actions/labeler@v5
|
||||
with:
|
||||
configuration-path: '.github/labeler.yml'
|
24
.github/workflows/nightly-cosmocc.yml
vendored
24
.github/workflows/nightly-cosmocc.yml
vendored
|
@ -1,24 +0,0 @@
|
|||
name: Nightly cosmocc
|
||||
on:
|
||||
schedule:
|
||||
# https://crontab.guru/#37_4_*_*_*
|
||||
- cron: "37 4 * * *"
|
||||
workflow_dispatch:
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
build-cosmocc:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: |
|
||||
sudo cp build/bootstrap/ape.elf /usr/bin/ape
|
||||
sudo sh -c "echo ':APE:M::MZqFpD::/usr/bin/ape:' >/proc/sys/fs/binfmt_misc/register"
|
||||
- run: tool/cosmocc/package.sh
|
||||
# https://github.com/actions/upload-artifact/issues/590
|
||||
- uses: actions/upload-artifact@v4.3.5
|
||||
with:
|
||||
name: cosmocc
|
||||
path: cosmocc
|
||||
compression-level: 9
|
11
.gitignore
vendored
11
.gitignore
vendored
|
@ -1,11 +1,4 @@
|
|||
# -*- conf -*-
|
||||
|
||||
/o
|
||||
/cosmocc
|
||||
/.cosmocc
|
||||
|
||||
# TODO: Find some way to have Python write to o/
|
||||
__pycache__
|
||||
|
||||
*.tmp
|
||||
/.bochs.log
|
||||
|
@ -13,6 +6,4 @@ __pycache__
|
|||
/TAGS
|
||||
/bx_enh_dbg.ini
|
||||
/tool/emacs/*.elc
|
||||
/perf.data
|
||||
/perf.data.old
|
||||
/qemu*core
|
||||
/usr/share/dict/words
|
||||
|
|
69
.vscode/c_cpp_properties.json
vendored
Normal file
69
.vscode/c_cpp_properties.json
vendored
Normal file
|
@ -0,0 +1,69 @@
|
|||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"${workspaceFolder}"
|
||||
],
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++11",
|
||||
"compilerPath": "${workspaceFolder}/o/third_party/gcc/bin/x86_64-linux-musl-gcc",
|
||||
"forcedInclude": ["${workspaceFolder}/.vscode/vscode.h"],
|
||||
"defines": [
|
||||
"libcesque=",
|
||||
"pureconst=",
|
||||
"paramsnonnull(x)=",
|
||||
"alignas(x)",
|
||||
"alignof(x)",
|
||||
"artificial=",
|
||||
"nodiscard=",
|
||||
"mayalias=",
|
||||
"forceinline=",
|
||||
"forcealign(x)=",
|
||||
"scanfesque(x)=",
|
||||
"strftimeesque(x)=",
|
||||
"wontreturn=",
|
||||
"textreal=",
|
||||
"mallocesque=",
|
||||
"callocesque=",
|
||||
"vallocesque=",
|
||||
"reallocesque=",
|
||||
"strlenesque=",
|
||||
"memcpyesque=",
|
||||
"hasatleast=",
|
||||
"noinline=",
|
||||
"textexit=",
|
||||
"returnstwice=",
|
||||
"textwindows=",
|
||||
"privileged=",
|
||||
"compatfn=",
|
||||
"noinstrument=",
|
||||
"nodebuginfo=",
|
||||
"interruptfn=",
|
||||
"optimizespeed=",
|
||||
"forcealignargpointer=",
|
||||
"noasan=",
|
||||
"noubsan=",
|
||||
"testonly=",
|
||||
"donothing=",
|
||||
"nosideeffect=",
|
||||
"unreachable=",
|
||||
"thatispacked=",
|
||||
"nothrow=",
|
||||
"nocallback=",
|
||||
"relegated=",
|
||||
"hidden=",
|
||||
"textstartup=",
|
||||
"initarray=",
|
||||
"returnsnonnull=",
|
||||
"returnspointerwithnoaliases=",
|
||||
"printfesque(x)=",
|
||||
"attributeallocsize(x)=",
|
||||
"returnsaligned(x)=",
|
||||
"attributeallocalign(x)=",
|
||||
"nullterminated(x)="
|
||||
]
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
36
.vscode/settings.json
vendored
36
.vscode/settings.json
vendored
|
@ -1,36 +0,0 @@
|
|||
{
|
||||
"C_Cpp.default.compilerPath": ".cosmocc/3.9.2/bin/aarch64-linux-cosmo-c++",
|
||||
"C_Cpp.default.compilerArgs": [
|
||||
"-nostdinc",
|
||||
"-nostdlib",
|
||||
"-iquote.",
|
||||
"-isystemlibc/isystem",
|
||||
"-isystemthird_party/libcxx",
|
||||
"-includelibc/integral/normalize.inc",
|
||||
"-D_COSMO_SOURCE",
|
||||
"-D__aarch64__"
|
||||
],
|
||||
"[c]": {
|
||||
"editor.tabSize": 2,
|
||||
"editor.insertSpaces": true
|
||||
},
|
||||
"[cpp]": {
|
||||
"editor.tabSize": 2,
|
||||
"editor.insertSpaces": true
|
||||
},
|
||||
"[makefile]": {
|
||||
"editor.tabSize": 8,
|
||||
"editor.insertSpaces": false
|
||||
},
|
||||
"[make]": {
|
||||
"editor.tabSize": 8,
|
||||
"editor.insertSpaces": false
|
||||
},
|
||||
"[assembly]": {
|
||||
"editor.tabSize": 8,
|
||||
"editor.insertSpaces": true
|
||||
},
|
||||
"files.associations": {
|
||||
"log.h": "c"
|
||||
}
|
||||
}
|
160
.vscode/vscode.h
vendored
Normal file
160
.vscode/vscode.h
vendored
Normal file
|
@ -0,0 +1,160 @@
|
|||
#define __VSCODE_INTELLISENSE__ 1
|
||||
#include "libc/integral/normalize.inc"
|
||||
|
||||
#if 0
|
||||
#define __VSCODE_INTELLISENSE__ 1
|
||||
#define __BIGGEST_ALIGNMENT__ 1
|
||||
#define __CHAR_MAX__ 0x7F
|
||||
#define __SCHAR_MAX__ __CHAR_MAX__
|
||||
#define __SHRT_MAX__ 0x7FFF
|
||||
#define __INT_MAX__ 0x7FFFFFFF
|
||||
#define __LONG_MAX__ 0x7FFFFFFFFFFFFFFF
|
||||
#define __LONG_LONG_MAX__ __LONG_MAX__
|
||||
#define __CHAR_MIN__ -((__CHAR_MAX__) + 1)
|
||||
#define __SHRT_MIN__ -((__SHRT_MAX__) + 1)
|
||||
#define __INT_MIN__ -((__INT_MAX__) + 1)
|
||||
#define __LONG_MIN__ -((__LONG_MAX__) + 1)
|
||||
#define __LONG_LONG_MIN__ -((__LONG_LONG_MAX__) + 1)
|
||||
#define __UCHAR_MAX__ 0xFF
|
||||
#define __USHRT_MAX__ 0xFFFF
|
||||
#define __UINT_MAX__ 0xFFFFFFFF
|
||||
#define __ULONG_MAX__ 0xFFFFFFFFFFFFFFFF
|
||||
#define __SIZE_MAX__ __ULONG_MAX__
|
||||
#define __SSIZE_MAX__ __LONG_MAX__
|
||||
#define __UINTPTR_MAX__ __SIZE_MAX__
|
||||
#define __INTPTR_MAX__ __SSIZE_MAX__
|
||||
#define __WCHAR_MAX__ __UINT_MAX__
|
||||
#define __PTRDIFF_MAX__ __UINTPTR_MAX__
|
||||
#define __INTMAX_MAX__ __ULONG_MAX__
|
||||
#define __SIZEOF_POINTER__ 8
|
||||
#define __SIZEOF_SHORT__ 2
|
||||
#define __SIZEOF_INT__ 4
|
||||
#define __SIZEOF_LONG__ 8
|
||||
#define __SIZEOF_LONG_LONG__ 8
|
||||
#define __SIZEOF_PTRDIFF_T__ 8
|
||||
#define __SIZEOF_SIZE_T__ 8
|
||||
#define __SIZEOF_WCHAR_T__ 4
|
||||
#define __SIZEOF_WINT_T__ 4
|
||||
#define __SIZEOF_FLOAT__ 4
|
||||
#define __SIZEOF_FLOAT128__ 16
|
||||
#define __SIZEOF_DOUBLE__ 8
|
||||
#define __SIZEOF_FLOAT80__ 10
|
||||
#define __SIZEOF_LONG_DOUBLE__ 16
|
||||
#define __FLT_MAX__ 1
|
||||
#define __DBL_MAX__ 1
|
||||
|
||||
#define __INT_LEAST8_TYPE__ signed char
|
||||
#define __INT_LEAST16_TYPE__ signed short
|
||||
#define __INT_LEAST32_TYPE__ signed int
|
||||
#define __INT_LEAST64_TYPE__ signed long long
|
||||
#define __UINT_LEAST8_TYPE__ unsigned char
|
||||
#define __UINT_LEAST16_TYPE__ unsigned short
|
||||
#define __UINT_LEAST32_TYPE__ unsigned int
|
||||
#define __UINT_LEAST64_TYPE__ unsigned long long
|
||||
|
||||
#define __UINT8_MAX__ __UCHAR_MAX__
|
||||
#define __UINT16_MAX__ __USHRT_MAX__
|
||||
#define __UINT32_MAX__ __UINT_MAX__
|
||||
#define __UINT64_MAX__ __ULONG_MAX__
|
||||
|
||||
#define __INT8_MAX__ __CHAR_MAX__
|
||||
#define __INT16_MAX__ __SHRT_MAX__
|
||||
#define __INT32_MAX__ __INT_MAX__
|
||||
#define __INT64_MAX__ __LONG_MAX__
|
||||
|
||||
#define ATEXIT_MAX 1
|
||||
#define STACKSIZE 0x10000
|
||||
#define ARG_MAX 255
|
||||
#define OPEN_MAX 0x7FFF
|
||||
#define CHAR_BIT 7
|
||||
#define NSIG 1
|
||||
#define NULL (0)
|
||||
#define false 0
|
||||
#define true (!(false))
|
||||
#define COSMOPOLITAN_C_START_
|
||||
#define COSMOPOLITAN_C_END_
|
||||
#define PAGESIZE 0x1000
|
||||
#define BIGPAGESIZE 0x10000
|
||||
#define NAME_MAX 255
|
||||
|
||||
#define SWITCHEROO(...) 0
|
||||
|
||||
extern unsigned g_loglevel;
|
||||
|
||||
typedef void * va_list;
|
||||
|
||||
#define va_start(...) 0
|
||||
#define va_end(...) 0
|
||||
#define va_arg(x, y) (y)(0)
|
||||
|
||||
typedef signed char int8_t;
|
||||
typedef signed short int16_t;
|
||||
typedef signed int int32_t;
|
||||
#define int64_t long long
|
||||
#define int128_t int64_t
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
typedef unsigned long long uint128_t;
|
||||
|
||||
typedef int errno_t;
|
||||
typedef uint64_t size_t;
|
||||
typedef unsigned long long ssize_t;
|
||||
typedef uint64_t uintptr_t;
|
||||
typedef long long intptr_t;
|
||||
|
||||
typedef unsigned long long uintmax_t;
|
||||
typedef long long intmax_t;
|
||||
|
||||
typedef uint32_t bool32;
|
||||
|
||||
#ifndef __cplusplus
|
||||
typedef uint8_t bool;
|
||||
typedef uint16_t char16_t;
|
||||
typedef uint32_t char32_t;
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef char32_t wint_t;
|
||||
typedef char32_t wchar_t;
|
||||
typedef struct { int ax, dx; } axdx_t;
|
||||
|
||||
/* duplicate and replace xmmintrin.internal.h to fix it for IntelliSense
|
||||
* SEE: <> */
|
||||
|
||||
#define _Vector_size(x) __attribute__((__vector_size__(x)))
|
||||
|
||||
#define IMAGE_BASE_VIRTUAL 0x400000
|
||||
#define __SIGACTION(...) (0)
|
||||
#define VEIL(x, y) (y)
|
||||
#define STATIC_YOINK(x)
|
||||
#define BUFSIZ 1
|
||||
#define FRAMESIZE 0x10000
|
||||
#define PATH_MAX 252
|
||||
#define concat(x, y, z) 0
|
||||
#define CONCAT(a, b, c, d, e) 0
|
||||
#define shuffle(...) 0
|
||||
#define reverse(x, y) 0
|
||||
#define autotype(x) intptr_t
|
||||
|
||||
#define _Generic_(...) (void*)(0)
|
||||
#define _Generic(...) _Generic_
|
||||
#define _Alignas(...)
|
||||
#define _Section(...)
|
||||
|
||||
#define offsetof(x, y) 0
|
||||
#define INITIALIZER(...) struct _dummy
|
||||
#define __far
|
||||
#define tinystrstr(...) 0
|
||||
#define BENCHLOOP(...) 0
|
||||
|
||||
#ifdef __hook
|
||||
#undef __hook
|
||||
#endif /* __hook */
|
||||
|
||||
#ifdef UriKeyval
|
||||
#undef UriKeyval
|
||||
#endif /* UriKeyval */
|
||||
|
||||
#define _Static_assert(...) 0
|
||||
#endif /* 0 */
|
|
@ -1,86 +0,0 @@
|
|||
# Contributing Guidelines
|
||||
|
||||
We'd love to accept your patches! Please read this guide first.
|
||||
|
||||
## Identity Disclosure
|
||||
|
||||
This project does not accept anonymous contributions. Justine Tunney
|
||||
won't merge pull requests from strangers. In order to change the Cosmo
|
||||
codebase, and have your changes be upstreamed, she has to know who you
|
||||
are. You're encouraged to disclose your full name and email address to
|
||||
the public too, by including them in your git commit messages; however
|
||||
that's not a requirement; as we're happy to respect the wishes of
|
||||
contributors who prefer to remain anonymous to the public.
|
||||
|
||||
## Copyright Assignment
|
||||
|
||||
The first time you send a pull request, you need to send an email to
|
||||
Justine Tunney <jtunney@gmail.com> stating that you intend to assign her
|
||||
the copyright to the changes you contribute to Cosmopolitan. It only
|
||||
needs to happen once. This only applies to the code you *choose* to
|
||||
contribute. The email should be sent from an email address associated
|
||||
with your identity. Your email should link to your pull request.
|
||||
|
||||
To make things easy, here's an example of a good email you can use:
|
||||
|
||||
> **From**: YOUR NAME (yname@gmail.com)
|
||||
> **To**: Justine Tunney (jtunney@gmail.com)
|
||||
> **Subject**: Cosmopolitan Copyright Assignment for YOUR NAME
|
||||
>
|
||||
> Hi Justine,
|
||||
>
|
||||
> I made my first contribution to Cosmopolitan in
|
||||
> https://github.com/jart/cosmopolitan/pull/XXXX could you please take a
|
||||
> look? I intend to assign you the copyright to the changes I contribute
|
||||
> to Cosmopolitan.
|
||||
>
|
||||
> Thanks!
|
||||
|
||||
Please note that in order to give Justine the copyright, it has to be
|
||||
yours to give in the first place. If you're employed, then you should
|
||||
get your employer's approval to do this beforehand. Even with big
|
||||
companies like Google, this process is quick and painless. Usually we
|
||||
see employers granting authorization in less than one day.
|
||||
|
||||
If you live in a country that doesn't recognize one's ability to assign
|
||||
copyright, then you may alternatively consider disclaiming it using the
|
||||
language in [Unlicense](https://unlicense.org) or
|
||||
[CC-0](http://creativecommons.org/share-your-work/public-domain/cc0).
|
||||
|
||||
If you're checking-in third party code, then you need to have headers at
|
||||
the top of each source file (but never header files) documenting its
|
||||
owners and the code should go in the `third_party/` folder. Every third
|
||||
party project should have a `README.cosmo` file that documents its
|
||||
provenance as well as any local changes you've made.
|
||||
|
||||
## Copyright Policy Exceptions
|
||||
|
||||
### Tests
|
||||
|
||||
You're encoraged to claim ownership of your test code. If you add a new
|
||||
file under the `test/` directory, then you should put your name in the
|
||||
ISC license header at the top of the file. If you add new test cases to
|
||||
an existing unit test file, then you're encouraged to append a line with
|
||||
your name to the existing copyright header of that file.
|
||||
|
||||
### Exceptional Features
|
||||
|
||||
Let's say you discovered a faster better way to implement `log10()` and
|
||||
you want to give it to Cosmopolitan. In cases like this, it really isn't
|
||||
appropriate for Justine to own your code. What you could do instead, is
|
||||
write your own new and improved `log10.c` from scratch, put your name on
|
||||
the top with the ISC license, and then add a `__notice()` directive so
|
||||
that your name will be embedded inside every executable that links the
|
||||
`log10()` function. This will help you get your name out there. Please
|
||||
note you need get approval from Justine each time you want to do this.
|
||||
|
||||
## Style Guide
|
||||
|
||||
You can use clang-format to automatically format your files:
|
||||
|
||||
```sh
|
||||
clang-format -i -style=file tool/net/redbean.c
|
||||
```
|
||||
|
||||
If you use Emacs this can be automated on save for Cosmopolitan using
|
||||
[tool/emacs/cosmo-format.el](tool/emacs/cosmo-format.el).
|
16
LICENSE
16
LICENSE
|
@ -1,16 +0,0 @@
|
|||
ISC License
|
||||
|
||||
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.
|
696
Makefile
696
Makefile
|
@ -1,5 +1,5 @@
|
|||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||
#── vi: set et ft=make ts=8 sw=8 fenc=utf-8 :vi ──────────────────────┘
|
||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
|
@ -21,26 +21,27 @@
|
|||
# make -j8 -O MODE=tiny
|
||||
#
|
||||
# # build individual target
|
||||
# make -j8 -O o//examples/hello
|
||||
# o//examples/hello
|
||||
# make -j8 -O o//examples/hello.com
|
||||
# o//examples/hello.com
|
||||
#
|
||||
# # view source
|
||||
# less examples/hello.c
|
||||
#
|
||||
# # view binary
|
||||
# o//tool/viz/bing o//examples/hello |
|
||||
# o//tool/viz/fold
|
||||
# o//tool/viz/bing.com o//examples/hello.com |
|
||||
# o//tool/viz/fold.com
|
||||
#
|
||||
# # view transitive closure of legalese
|
||||
# o//tool/viz/bing -n o//examples/hello |
|
||||
# o//tool/viz/fold
|
||||
# o//tool/viz/bing.com -n o//examples/hello.com |
|
||||
# o//tool/viz/fold.com
|
||||
#
|
||||
# # basic debugging
|
||||
# make -j8 -O MODE=dbg o/dbg/examples/crashreport
|
||||
# o/examples/crashreport
|
||||
# make -j8 -O MODE=dbg o/dbg/examples/crashreport.com
|
||||
# o/dbg/examples/crashreport.com
|
||||
# less examples/crashreport.c
|
||||
#
|
||||
# # extremely tiny binaries
|
||||
# # extremely tiny binaries (scout's honor escape hatch)
|
||||
# # please pay the $1k for commercial license if you can
|
||||
# make -j8 -O MODE=tiny \
|
||||
# LDFLAGS+=-s \
|
||||
# CPPFLAGS+=-DIM_FEELING_NAUGHTY \
|
||||
|
@ -51,7 +52,7 @@
|
|||
#
|
||||
# TROUBLESHOOTING
|
||||
#
|
||||
# make -j8 -O V=1 o//examples/hello
|
||||
# make -j8 -O V=1 o//examples/hello.com
|
||||
# make o//examples/life.elf -pn |& less
|
||||
# etc.
|
||||
#
|
||||
|
@ -59,124 +60,18 @@
|
|||
#
|
||||
# build/config.mk
|
||||
|
||||
SHELL = build/bootstrap/cocmd
|
||||
MAKEFLAGS += --no-builtin-rules
|
||||
SHELL = /bin/sh
|
||||
HOSTS ?= freebsd openbsd netbsd rhel7 rhel5 xnu win7 win10
|
||||
SANITY := $(shell build/sanitycheck $$PPID)
|
||||
GNUMAKEFLAGS += --output-sync
|
||||
|
||||
.SUFFIXES:
|
||||
.DELETE_ON_ERROR:
|
||||
.FEATURES: output-sync
|
||||
.PHONY: all o bins check test depend tags aarch64 clean
|
||||
.PHONY: all o bins check test depend tags
|
||||
|
||||
ifneq ($(m),)
|
||||
ifeq ($(MODE),)
|
||||
MODE := $(m)
|
||||
endif
|
||||
endif
|
||||
|
||||
COMMA := ,
|
||||
PWD := $(shell pwd)
|
||||
|
||||
# detect wsl2 running cosmopolitan binaries on the host by checking whether:
|
||||
# - user ran .cosmocc/current/bin/make, in which case make's working directory
|
||||
# is in wsl
|
||||
# - user ran make, in which case cocmd's working directory is in wsl
|
||||
ifneq ($(findstring //wsl.localhost/,$(CURDIR) $(PWD)),)
|
||||
$(warning wsl2 interop is enabled)
|
||||
$(error you need to run sudo sh -c 'echo -1 > /proc/sys/fs/binfmt_misc/WSLInterop')
|
||||
endif
|
||||
|
||||
UNAME_M := $(shell uname -m)
|
||||
UNAME_S := $(shell uname -s)
|
||||
|
||||
# apple still distributes a 17 year old version of gnu make
|
||||
ifeq ($(MAKE_VERSION), 3.81)
|
||||
$(error please use https://cosmo.zip/pub/cosmos/bin/make)
|
||||
endif
|
||||
|
||||
LC_ALL = C
|
||||
SOURCE_DATE_EPOCH = 0
|
||||
|
||||
ARFLAGS = rcsD
|
||||
ZFLAGS ?=
|
||||
XARGS ?= xargs -P4 -rs8000
|
||||
DOT ?= dot
|
||||
CLANG = clang
|
||||
TMPDIR = o/tmp
|
||||
AR = $(BOOTSTRAP)/ar.ape
|
||||
CP = $(BOOTSTRAP)/cp.ape
|
||||
RM = $(BOOTSTRAP)/rm.ape -f
|
||||
GZIP = $(BOOTSTRAP)/gzip.ape
|
||||
ECHO = $(BOOTSTRAP)/echo.ape
|
||||
CHMOD = $(BOOTSTRAP)/chmod.ape
|
||||
TOUCH = $(BOOTSTRAP)/touch.ape
|
||||
PKG = $(BOOTSTRAP)/package.ape
|
||||
MKDEPS = $(BOOTSTRAP)/mkdeps
|
||||
ZIPOBJ = $(BOOTSTRAP)/zipobj
|
||||
ZIPCOPY = $(BOOTSTRAP)/zipcopy
|
||||
PECHECK = $(BOOTSTRAP)/pecheck
|
||||
FIXUPOBJ = $(BOOTSTRAP)/fixupobj
|
||||
OBJBINCOPY = $(BOOTSTRAP)/objbincopy
|
||||
MKDIR = $(BOOTSTRAP)/mkdir.ape -p
|
||||
COMPILE = $(BOOTSTRAP)/compile.ape -V9 -M2048m -P8192 $(QUOTA)
|
||||
|
||||
# the default build modes is empty string
|
||||
# on x86_64 hosts, MODE= is the same as MODE=x86_64
|
||||
# on aarch64 hosts, MODE= is changed to MODE=aarch64
|
||||
ifeq ($(MODE),)
|
||||
ifeq ($(UNAME_M),arm64)
|
||||
MODE := aarch64
|
||||
endif
|
||||
ifeq ($(UNAME_M),aarch64)
|
||||
MODE := aarch64
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(findstring aarch64,$(MODE)),)
|
||||
ARCH = aarch64
|
||||
HOSTS ?= pi pi5 studio freebsdarm
|
||||
else
|
||||
ARCH = x86_64
|
||||
HOSTS ?= freebsd rhel7 xnu openbsd netbsd win10 luna
|
||||
endif
|
||||
|
||||
ZIPOBJ_FLAGS += -a$(ARCH)
|
||||
|
||||
export ADDR2LINE
|
||||
export LC_ALL
|
||||
export MKDIR
|
||||
export MODE
|
||||
export SOURCE_DATE_EPOCH
|
||||
export TMPDIR
|
||||
|
||||
COSMOCC = .cosmocc/3.9.2
|
||||
BOOTSTRAP = $(COSMOCC)/bin
|
||||
TOOLCHAIN = $(COSMOCC)/bin/$(ARCH)-linux-cosmo-
|
||||
DOWNLOAD := $(shell build/download-cosmocc.sh $(COSMOCC) 3.9.2 f4ff13af65fcd309f3f1cfd04275996fb7f72a4897726628a8c9cf732e850193)
|
||||
|
||||
IGNORE := $(shell $(MKDIR) $(TMPDIR))
|
||||
|
||||
AS = $(TOOLCHAIN)as
|
||||
CC = $(TOOLCHAIN)gcc
|
||||
CXX = $(TOOLCHAIN)g++
|
||||
CXXFILT = $(TOOLCHAIN)c++filt
|
||||
LD = $(TOOLCHAIN)ld.bfd
|
||||
NM = $(TOOLCHAIN)nm
|
||||
GCC = $(TOOLCHAIN)gcc
|
||||
STRIP = $(TOOLCHAIN)strip
|
||||
OBJCOPY = $(TOOLCHAIN)objcopy
|
||||
OBJDUMP = $(TOOLCHAIN)objdump
|
||||
ifneq ($(wildcard $(PWD)/$(TOOLCHAIN)addr2line),)
|
||||
ADDR2LINE = $(PWD)/$(TOOLCHAIN)addr2line
|
||||
else
|
||||
ADDR2LINE = $(TOOLCHAIN)addr2line
|
||||
endif
|
||||
|
||||
# primary build rules
|
||||
all: o
|
||||
o: o/$(MODE)
|
||||
o/$(MODE): \
|
||||
o/$(MODE)/ape \
|
||||
o/$(MODE)/ctl \
|
||||
o: o/$(MODE)/ape \
|
||||
o/$(MODE)/dsp \
|
||||
o/$(MODE)/net \
|
||||
o/$(MODE)/libc \
|
||||
|
@ -185,45 +80,6 @@ o/$(MODE): \
|
|||
o/$(MODE)/examples \
|
||||
o/$(MODE)/third_party
|
||||
|
||||
# TODO(jart): Make Emacs `C-c C-c` shortcut not need this.
|
||||
.PHONY: o/$(MODE)/ o/$(MODE)/.
|
||||
o/$(MODE)/: o/$(MODE)
|
||||
o/$(MODE)/.: o/$(MODE)
|
||||
|
||||
# check if we're using o//third_party/make/make
|
||||
# we added sandboxing to guarantee cosmo's makefile is hermetic
|
||||
# it also shaves away 200ms of startup latency with native $(uniq)
|
||||
ifneq ($(LANDLOCKMAKE_VERSION),)
|
||||
ifeq ($(UNAME_S),Linux)
|
||||
ifeq ($(wildcard /usr/bin/ape),)
|
||||
$(warning please run ape/apeinstall.sh if you intend to use landlock make)
|
||||
$(shell sleep .5)
|
||||
endif
|
||||
endif
|
||||
ifneq ($(TOOLCHAIN),)
|
||||
.STRICT = 1
|
||||
endif
|
||||
endif
|
||||
|
||||
.PLEDGE += stdio rpath wpath cpath fattr proc
|
||||
.UNVEIL += \
|
||||
libc/integral \
|
||||
libc/stdbool.h \
|
||||
rwc:/dev/shm \
|
||||
rx:.cosmocc \
|
||||
rx:build/bootstrap \
|
||||
r:build/portcosmo.h \
|
||||
/proc/stat \
|
||||
rw:/dev/null \
|
||||
rw:/dev/full \
|
||||
w:o/stack.log \
|
||||
/etc/hosts \
|
||||
~/.runit.psk \
|
||||
/proc/self/status \
|
||||
rx:/usr/bin/qemu-aarch64 \
|
||||
rx:o/third_party/qemu/qemu-aarch64 \
|
||||
/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
|
||||
|
||||
PKGS =
|
||||
|
||||
-include ~/.cosmo.mk
|
||||
|
@ -231,168 +87,113 @@ include build/functions.mk #─┐
|
|||
include build/definitions.mk # ├──META
|
||||
include build/config.mk # │ You can build
|
||||
include build/rules.mk # │ You can topologically order
|
||||
include build/online.mk #─┘
|
||||
include libc/nexgen32e/BUILD.mk #─┐
|
||||
include libc/sysv/BUILD.mk # ├──SYSTEM SUPPORT
|
||||
include libc/nt/BUILD.mk # │ You can do math
|
||||
include libc/intrin/BUILD.mk # │ You can use the stack
|
||||
include third_party/compiler_rt/BUILD.mk # │ You can manipulate arrays
|
||||
include libc/tinymath/BUILD.mk # │ You can issue raw system calls
|
||||
include libc/str/BUILD.mk # │
|
||||
include third_party/xed/BUILD.mk # │
|
||||
include third_party/puff/BUILD.mk # │
|
||||
include libc/elf/BUILD.mk # │
|
||||
include ape/BUILD.mk # │
|
||||
include libc/fmt/BUILD.mk # │
|
||||
include libc/vga/BUILD.mk # │
|
||||
include libc/irq/BUILD.mk #─┘
|
||||
include libc/calls/BUILD.mk #─┐
|
||||
include libc/irq/BUILD.mk # ├──SYSTEMS RUNTIME
|
||||
include third_party/nsync/BUILD.mk # │ You can issue system calls
|
||||
include libc/runtime/BUILD.mk # │
|
||||
include libc/crt/BUILD.mk # │
|
||||
include third_party/dlmalloc/BUILD.mk #─┘
|
||||
include libc/mem/BUILD.mk #─┐
|
||||
include third_party/gdtoa/BUILD.mk # ├──DYNAMIC RUNTIME
|
||||
include third_party/nsync/mem/BUILD.mk # │ You can now use stdio
|
||||
include libc/proc/BUILD.mk # │ You can now use threads
|
||||
include libc/dlopen/BUILD.mk # │ You can now use processes
|
||||
include libc/thread/BUILD.mk # │ You can finally call malloc()
|
||||
include third_party/zlib/BUILD.mk # │
|
||||
include libc/stdio/BUILD.mk # │
|
||||
include tool/hello/BUILD.mk # │
|
||||
include third_party/tz/BUILD.mk # │
|
||||
include net/BUILD.mk # │
|
||||
include third_party/vqsort/BUILD.mk # │
|
||||
include libc/log/BUILD.mk # │
|
||||
include third_party/getopt/BUILD.mk # │
|
||||
include third_party/bzip2/BUILD.mk # │
|
||||
include dsp/core/BUILD.mk # │
|
||||
include third_party/zlib/gz/BUILD.mk # │
|
||||
include third_party/intel/BUILD.mk # │
|
||||
include third_party/aarch64/BUILD.mk # │
|
||||
include libc/BUILD.mk #─┘
|
||||
include libc/sock/BUILD.mk #─┐
|
||||
include net/http/BUILD.mk # ├──ONLINE RUNTIME
|
||||
include third_party/musl/BUILD.mk # │ You can communicate with the network
|
||||
include third_party/regex/BUILD.mk # │
|
||||
include third_party/tr/BUILD.mk # │
|
||||
include third_party/sed/BUILD.mk # │
|
||||
include libc/system/BUILD.mk # │
|
||||
include libc/x/BUILD.mk # │
|
||||
include dsp/scale/BUILD.mk # │
|
||||
include dsp/mpeg/BUILD.mk # │
|
||||
include dsp/tty/BUILD.mk # │
|
||||
include dsp/audio/BUILD.mk # │
|
||||
include dsp/prog/BUILD.mk # │
|
||||
include dsp/BUILD.mk # │
|
||||
include third_party/stb/BUILD.mk # │
|
||||
include third_party/mbedtls/BUILD.mk # │
|
||||
include third_party/ncurses/BUILD.mk # │
|
||||
include third_party/readline/BUILD.mk # │
|
||||
include third_party/libunwind/BUILD.mk # |
|
||||
include third_party/libcxxabi/BUILD.mk # |
|
||||
include third_party/double-conversion/BUILD.mk # │
|
||||
include ctl/BUILD.mk # │
|
||||
include third_party/libcxx/BUILD.mk # │
|
||||
include third_party/openmp/BUILD.mk # │
|
||||
include third_party/pcre/BUILD.mk # │
|
||||
include third_party/less/BUILD.mk # │
|
||||
include net/https/BUILD.mk #─┘
|
||||
include third_party/tidy/BUILD.mk
|
||||
include third_party/BUILD.mk
|
||||
include third_party/nsync/testing/BUILD.mk
|
||||
include libc/testlib/BUILD.mk
|
||||
include tool/viz/lib/BUILD.mk
|
||||
include tool/args/BUILD.mk
|
||||
include test/math/BUILD.mk
|
||||
include test/posix/BUILD.mk
|
||||
include test/ctl/BUILD.mk
|
||||
include test/libcxx/BUILD.mk
|
||||
include test/tool/args/BUILD.mk
|
||||
include third_party/linenoise/BUILD.mk
|
||||
include third_party/maxmind/BUILD.mk
|
||||
include net/finger/BUILD.mk
|
||||
include third_party/double-conversion/test/BUILD.mk
|
||||
include third_party/lua/BUILD.mk
|
||||
include third_party/tree/BUILD.mk
|
||||
include third_party/zstd/BUILD.mk
|
||||
include third_party/awk/BUILD.mk
|
||||
include third_party/hiredis/BUILD.mk
|
||||
include third_party/make/BUILD.mk
|
||||
include third_party/ctags/BUILD.mk
|
||||
include third_party/finger/BUILD.mk
|
||||
include third_party/argon2/BUILD.mk
|
||||
include third_party/smallz4/BUILD.mk
|
||||
include third_party/sqlite3/BUILD.mk
|
||||
include third_party/mbedtls/test/BUILD.mk
|
||||
include third_party/lz4cli/BUILD.mk
|
||||
include third_party/zip/BUILD.mk
|
||||
include third_party/xxhash/BUILD.mk
|
||||
include third_party/unzip/BUILD.mk
|
||||
include tool/build/lib/BUILD.mk
|
||||
include third_party/chibicc/BUILD.mk
|
||||
include third_party/chibicc/test/BUILD.mk
|
||||
include third_party/python/BUILD.mk
|
||||
include tool/build/BUILD.mk
|
||||
include tool/curl/BUILD.mk
|
||||
include third_party/qemu/BUILD.mk
|
||||
include third_party/libcxxabi/test/BUILD.mk
|
||||
include examples/BUILD.mk
|
||||
include examples/pyapp/BUILD.mk
|
||||
include examples/pylife/BUILD.mk
|
||||
include tool/decode/lib/BUILD.mk
|
||||
include tool/decode/BUILD.mk
|
||||
include tool/lambda/lib/BUILD.mk
|
||||
include tool/lambda/BUILD.mk
|
||||
include tool/plinko/lib/BUILD.mk
|
||||
include tool/plinko/BUILD.mk
|
||||
include test/tool/plinko/BUILD.mk
|
||||
include tool/net/BUILD.mk
|
||||
include tool/viz/BUILD.mk
|
||||
include tool/BUILD.mk
|
||||
include net/turfwar/BUILD.mk
|
||||
include test/libc/tinymath/BUILD.mk
|
||||
include test/libc/intrin/BUILD.mk
|
||||
include test/libc/mem/BUILD.mk
|
||||
include test/libc/nexgen32e/BUILD.mk
|
||||
include test/libc/runtime/BUILD.mk
|
||||
include test/libc/thread/BUILD.mk
|
||||
include test/libc/sock/BUILD.mk
|
||||
include test/libc/str/BUILD.mk
|
||||
include test/libc/log/BUILD.mk
|
||||
include test/libc/str/BUILD.mk
|
||||
include test/libc/calls/BUILD.mk
|
||||
include test/libc/x/BUILD.mk
|
||||
include test/libc/xed/BUILD.mk
|
||||
include test/libc/fmt/BUILD.mk
|
||||
include test/libc/time/BUILD.mk
|
||||
include test/libc/proc/BUILD.mk
|
||||
include test/libc/stdio/BUILD.mk
|
||||
include test/libc/system/BUILD.mk
|
||||
include test/libc/BUILD.mk
|
||||
include test/net/http/BUILD.mk
|
||||
include test/net/https/BUILD.mk
|
||||
include test/net/finger/BUILD.mk
|
||||
include test/net/BUILD.mk
|
||||
include test/tool/build/lib/BUILD.mk
|
||||
include test/tool/build/BUILD.mk
|
||||
include test/tool/viz/lib/BUILD.mk
|
||||
include test/tool/viz/BUILD.mk
|
||||
include test/tool/net/BUILD.mk
|
||||
include test/tool/BUILD.mk
|
||||
include test/dsp/core/BUILD.mk
|
||||
include test/dsp/scale/BUILD.mk
|
||||
include test/dsp/tty/BUILD.mk
|
||||
include test/dsp/BUILD.mk
|
||||
include examples/package/lib/BUILD.mk
|
||||
include examples/package/BUILD.mk
|
||||
include build/online.mk # │
|
||||
include libc/stubs/stubs.mk #─┘
|
||||
include libc/nexgen32e/nexgen32e.mk #─┐
|
||||
include libc/sysv/sysv.mk # ├──SYSTEM SUPPORT
|
||||
include libc/nt/nt.mk # │ You can do math
|
||||
include libc/intrin/intrin.mk # │ You can use the stack
|
||||
include libc/linux/linux.mk # │ You can manipulate arrays
|
||||
include libc/tinymath/tinymath.mk # │ You can issue raw system calls
|
||||
include third_party/compiler_rt/compiler_rt.mk # │
|
||||
include libc/bits/bits.mk # │
|
||||
include libc/str/str.mk # │
|
||||
include third_party/xed/xed.mk # │
|
||||
include third_party/zlib/zlib.mk # │
|
||||
include libc/elf/elf.mk # │
|
||||
include ape/lib/apelib.mk # │
|
||||
include ape/ape.mk # │
|
||||
include libc/fmt/fmt.mk #─┘
|
||||
include libc/calls/calls.mk #─┐
|
||||
include libc/runtime/runtime.mk # ├──SYSTEMS RUNTIME
|
||||
include libc/crt/crt.mk # │ You can issue system calls
|
||||
include libc/rand/rand.mk # │
|
||||
include libc/unicode/unicode.mk # │
|
||||
include third_party/dlmalloc/dlmalloc.mk #─┘
|
||||
include libc/mem/mem.mk #─┐
|
||||
include libc/ohmyplus/ohmyplus.mk # ├──DYNAMIC RUNTIME
|
||||
include libc/zipos/zipos.mk # │ You can now use stdio
|
||||
include third_party/gdtoa/gdtoa.mk # │ You can finally call malloc()
|
||||
include libc/time/time.mk # │
|
||||
include libc/alg/alg.mk # │
|
||||
include libc/stdio/stdio.mk # │
|
||||
include net/net.mk # │
|
||||
include libc/log/log.mk # │
|
||||
include dsp/core/core.mk # │
|
||||
include libc/x/x.mk # │
|
||||
include third_party/stb/stb.mk # │
|
||||
include dsp/scale/scale.mk # │
|
||||
include dsp/mpeg/mpeg.mk # │
|
||||
include dsp/dsp.mk # │
|
||||
include third_party/musl/musl.mk # │
|
||||
include third_party/getopt/getopt.mk # │
|
||||
include libc/libc.mk #─┘
|
||||
include libc/sock/sock.mk #─┐
|
||||
include dsp/tty/tty.mk # ├──ONLINE RUNTIME
|
||||
include libc/dns/dns.mk # │ You can communicate with the network
|
||||
include libc/crypto/crypto.mk # │
|
||||
include net/http/http.mk #─┘
|
||||
include third_party/duktape/duktape.mk
|
||||
include third_party/regex/regex.mk
|
||||
include third_party/third_party.mk
|
||||
include libc/testlib/testlib.mk
|
||||
include tool/viz/lib/vizlib.mk
|
||||
include examples/examples.mk
|
||||
include third_party/lz4cli/lz4cli.mk
|
||||
include tool/build/lib/buildlib.mk
|
||||
include third_party/chibicc/chibicc.mk
|
||||
include third_party/chibicc/test/test.mk
|
||||
include tool/build/emucrt/emucrt.mk
|
||||
include tool/build/emubin/emubin.mk
|
||||
include tool/build/build.mk
|
||||
include tool/decode/lib/decodelib.mk
|
||||
include tool/decode/decode.mk
|
||||
include tool/hash/hash.mk
|
||||
include tool/net/net.mk
|
||||
include tool/viz/viz.mk
|
||||
include tool/tool.mk
|
||||
include test/libc/alg/test.mk
|
||||
include test/libc/tinymath/test.mk
|
||||
include test/libc/intrin/test.mk
|
||||
include test/libc/mem/test.mk
|
||||
include test/libc/nexgen32e/test.mk
|
||||
include test/libc/runtime/test.mk
|
||||
include test/libc/sock/test.mk
|
||||
include test/libc/bits/test.mk
|
||||
include test/libc/crypto/test.mk
|
||||
include test/libc/str/test.mk
|
||||
include test/libc/unicode/test.mk
|
||||
include test/libc/calls/test.mk
|
||||
include test/libc/x/test.mk
|
||||
include test/libc/xed/test.mk
|
||||
include test/libc/fmt/test.mk
|
||||
include test/libc/dns/test.mk
|
||||
include test/libc/rand/test.mk
|
||||
include test/libc/time/test.mk
|
||||
include test/libc/stdio/test.mk
|
||||
include test/libc/release/test.mk
|
||||
include test/libc/test.mk
|
||||
include test/ape/lib/test.mk
|
||||
include test/ape/test.mk
|
||||
include test/net/http/test.mk
|
||||
include test/net/test.mk
|
||||
include test/tool/build/lib/test.mk
|
||||
include test/tool/build/test.mk
|
||||
include test/tool/viz/lib/test.mk
|
||||
include test/tool/viz/test.mk
|
||||
include test/tool/test.mk
|
||||
include test/dsp/core/test.mk
|
||||
include test/dsp/scale/test.mk
|
||||
include test/dsp/tty/test.mk
|
||||
include test/dsp/test.mk
|
||||
include examples/package/lib/build.mk
|
||||
include examples/package/build.mk
|
||||
#-φ-examples/package/new.sh
|
||||
include test/BUILD.mk
|
||||
include test/test.mk
|
||||
|
||||
OBJS = $(foreach x,$(PKGS),$($(x)_OBJS))
|
||||
SRCS := $(foreach x,$(PKGS),$($(x)_SRCS))
|
||||
HDRS := $(foreach x,$(PKGS),$($(x)_HDRS))
|
||||
SRCS = $(foreach x,$(PKGS),$($(x)_SRCS))
|
||||
HDRS = $(foreach x,$(PKGS),$($(x)_HDRS))
|
||||
INCS = $(foreach x,$(PKGS),$($(x)_INCS))
|
||||
BINS = $(foreach x,$(PKGS),$($(x)_BINS))
|
||||
TESTS = $(foreach x,$(PKGS),$($(x)_TESTS))
|
||||
|
@ -400,171 +201,128 @@ CHECKS = $(foreach x,$(PKGS),$($(x)_CHECKS))
|
|||
|
||||
bins: $(BINS)
|
||||
check: $(CHECKS)
|
||||
test: $(TESTS)
|
||||
test: $(TESTS) all
|
||||
depend: o/$(MODE)/depend
|
||||
tags: TAGS HTAGS
|
||||
|
||||
o/$(MODE)/.x:
|
||||
@$(COMPILE) -AMKDIR -tT$@ $(MKDIR) $(@D)
|
||||
@$(MKDIR) $(@D) && touch $@
|
||||
|
||||
o/$(MODE)/srcs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(SRCS),$(dir $(x)))) $(SRCS)
|
||||
$(file >$@,$(SRCS))
|
||||
o/$(MODE)/hdrs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(HDRS) $(INCS),$(dir $(x)))) $(HDRS) $(INCS)
|
||||
$(file >$@,$(HDRS) $(INCS))
|
||||
o/$(MODE)/incs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(INCS) $(INCS),$(dir $(x)))) $(INCS) $(INCS)
|
||||
$(file >$@,$(INCS))
|
||||
o/$(MODE)/depend: o/$(MODE)/.x o/$(MODE)/srcs.txt o/$(MODE)/hdrs.txt o/$(MODE)/incs.txt $(SRCS) $(HDRS) $(INCS)
|
||||
$(COMPILE) -AMKDEPS -L320 $(MKDEPS) -o $@ -s -r o/$(MODE)/ @o/$(MODE)/srcs.txt @o/$(MODE)/hdrs.txt @o/$(MODE)/incs.txt
|
||||
|
||||
o/$(MODE)/srcs-old.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(SRCS),$(dir $(x))))
|
||||
o/$(MODE)/srcs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(SRCS),$(dir $(x))))
|
||||
$(file >$@) $(foreach x,$(SRCS),$(file >>$@,$(x)))
|
||||
o/$(MODE)/hdrs-old.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(HDRS) $(INCS),$(dir $(x))))
|
||||
|
||||
o/$(MODE)/hdrs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(HDRS) $(INCS),$(dir $(x))))
|
||||
$(file >$@) $(foreach x,$(HDRS) $(INCS),$(file >>$@,$(x)))
|
||||
|
||||
TAGS: private .UNSANDBOXED = 1
|
||||
TAGS: o/$(MODE)/srcs-old.txt $(SRCS) #o/$(MODE)/third_party/ctags/ctags
|
||||
@$(RM) $@
|
||||
@o/$(MODE)/third_party/ctags/ctags $(TAGSFLAGS) -L $< -o $@
|
||||
o/$(MODE)/depend: o/$(MODE)/.x o/$(MODE)/srcs.txt o/$(MODE)/hdrs.txt $(SRCS) $(HDRS) $(INCS)
|
||||
@build/mkdeps -o $@ -r o/$(MODE)/ o/$(MODE)/srcs.txt o/$(MODE)/hdrs.txt
|
||||
|
||||
HTAGS: private .UNSANDBOXED = 1
|
||||
HTAGS: o/$(MODE)/hdrs-old.txt $(filter-out third_party/libcxx/%,$(HDRS)) #o/$(MODE)/third_party/ctags/ctags
|
||||
@$(RM) $@
|
||||
@build/htags o/$(MODE)/third_party/ctags/ctags -L $< -o $@
|
||||
TAGS: o/$(MODE)/srcs.txt $(SRCS)
|
||||
@rm -f $@
|
||||
@ACTION=TAGS TARGET=$@ build/do $(TAGS) $(TAGSFLAGS) -L $< -o $@
|
||||
|
||||
loc: private .UNSANDBOXED = 1
|
||||
loc: o/$(MODE)/tool/build/summy
|
||||
find -name \*.h -or -name \*.hpp -or -name \*.c -or -name \*.cc -or -name \*.cpp -or -name \*.S -or -name \*.mk | \
|
||||
HTAGS: o/$(MODE)/hdrs.txt $(HDRS)
|
||||
@rm -f $@
|
||||
@ACTION=TAGS TARGET=$@ build/do build/htags -L $< -o $@
|
||||
|
||||
loc: o/$(MODE)/tool/build/summy.com
|
||||
find -name \*.h -or -name \*.c -or -name \*.S | \
|
||||
$(XARGS) wc -l | grep total | awk '{print $$1}' | $<
|
||||
|
||||
COSMOPOLITAN = \
|
||||
CTL \
|
||||
DSP_AUDIO \
|
||||
LIBC_CALLS \
|
||||
LIBC_DLOPEN \
|
||||
LIBC_ELF \
|
||||
LIBC_FMT \
|
||||
LIBC_INTRIN \
|
||||
LIBC_IRQ \
|
||||
LIBC_LOG \
|
||||
LIBC_MEM \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_NT_ADVAPI32 \
|
||||
LIBC_NT_BCRYPTPRIMITIVES \
|
||||
LIBC_NT_COMDLG32 \
|
||||
LIBC_NT_GDI32 \
|
||||
LIBC_NT_IPHLPAPI \
|
||||
LIBC_NT_KERNEL32 \
|
||||
LIBC_NT_NTDLL \
|
||||
LIBC_NT_PDH \
|
||||
LIBC_NT_POWRPROF \
|
||||
LIBC_NT_PSAPI \
|
||||
LIBC_NT_REALTIME \
|
||||
LIBC_NT_SHELL32 \
|
||||
LIBC_NT_SYNCHRONIZATION \
|
||||
LIBC_NT_USER32 \
|
||||
LIBC_NT_WS2_32 \
|
||||
LIBC_PROC \
|
||||
LIBC_RUNTIME \
|
||||
COSMOPOLITAN_OBJECTS = \
|
||||
LIBC_CRYPTO \
|
||||
LIBC_DNS \
|
||||
LIBC_SOCK \
|
||||
LIBC_STDIO \
|
||||
LIBC_STR \
|
||||
LIBC_SYSTEM \
|
||||
LIBC_SYSV \
|
||||
LIBC_SYSV_CALLS \
|
||||
LIBC_THREAD \
|
||||
LIBC_TINYMATH \
|
||||
LIBC_VGA \
|
||||
LIBC_NT_WS2_32 \
|
||||
LIBC_NT_MSWSOCK \
|
||||
LIBC_OHMYPLUS \
|
||||
LIBC_X \
|
||||
NET_HTTP \
|
||||
THIRD_PARTY_COMPILER_RT \
|
||||
THIRD_PARTY_DLMALLOC \
|
||||
THIRD_PARTY_DOUBLECONVERSION \
|
||||
THIRD_PARTY_GDTOA \
|
||||
THIRD_PARTY_GETOPT \
|
||||
THIRD_PARTY_LIBCXXABI \
|
||||
THIRD_PARTY_LIBUNWIND \
|
||||
THIRD_PARTY_MUSL \
|
||||
THIRD_PARTY_NSYNC \
|
||||
THIRD_PARTY_NSYNC_MEM \
|
||||
THIRD_PARTY_OPENMP \
|
||||
THIRD_PARTY_PUFF \
|
||||
THIRD_PARTY_REGEX \
|
||||
THIRD_PARTY_TZ \
|
||||
THIRD_PARTY_XED \
|
||||
LIBC_LOG \
|
||||
LIBC_UNICODE \
|
||||
LIBC_TIME \
|
||||
LIBC_ZIPOS \
|
||||
THIRD_PARTY_ZLIB \
|
||||
THIRD_PARTY_ZLIB_GZ \
|
||||
TOOL_ARGS \
|
||||
|
||||
COSMOPOLITAN_H_PKGS = \
|
||||
APE \
|
||||
DSP_AUDIO \
|
||||
LIBC \
|
||||
APE_LIB \
|
||||
THIRD_PARTY_MUSL \
|
||||
LIBC_STDIO \
|
||||
THIRD_PARTY_REGEX \
|
||||
LIBC_ALG \
|
||||
LIBC_MEM \
|
||||
THIRD_PARTY_DLMALLOC \
|
||||
LIBC_BITS \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_ELF \
|
||||
LIBC_CALLS \
|
||||
LIBC_RAND \
|
||||
LIBC_SYSV_CALLS \
|
||||
LIBC_NT_KERNELBASE \
|
||||
LIBC_NT_SHELL32 \
|
||||
LIBC_NT_GDI32 \
|
||||
LIBC_NT_COMDLG32 \
|
||||
LIBC_NT_NETAPI32 \
|
||||
LIBC_NT_URL \
|
||||
LIBC_NT_USER32 \
|
||||
LIBC_NT_NTDLL \
|
||||
LIBC_NT_ADVAPI32 \
|
||||
LIBC_FMT \
|
||||
THIRD_PARTY_COMPILER_RT \
|
||||
LIBC_TINYMATH \
|
||||
LIBC_SYSV \
|
||||
LIBC_STR \
|
||||
LIBC_INTRIN \
|
||||
LIBC_NT_KERNEL32 \
|
||||
LIBC_NEXGEN32E
|
||||
|
||||
COSMOPOLITAN_HEADERS = \
|
||||
LIBC \
|
||||
LIBC_ALG \
|
||||
LIBC_BITS \
|
||||
LIBC_CALLS \
|
||||
LIBC_CRYPTO \
|
||||
LIBC_DNS \
|
||||
LIBC_ELF \
|
||||
LIBC_FMT \
|
||||
LIBC_DLOPEN \
|
||||
LIBC_INTRIN \
|
||||
LIBC_LOG \
|
||||
LIBC_MEM \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_NT \
|
||||
LIBC_OHMYPLUS \
|
||||
LIBC_RAND \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_SOCK \
|
||||
LIBC_STDIO \
|
||||
LIBC_PROC \
|
||||
THIRD_PARTY_NSYNC \
|
||||
THIRD_PARTY_XED \
|
||||
LIBC_STR \
|
||||
LIBC_SYSV \
|
||||
LIBC_THREAD \
|
||||
LIBC_TIME \
|
||||
LIBC_TINYMATH \
|
||||
LIBC_UNICODE \
|
||||
LIBC_X \
|
||||
LIBC_VGA \
|
||||
NET_HTTP \
|
||||
TOOL_ARGS \
|
||||
LIBC_ZIPOS \
|
||||
THIRD_PARTY_DLMALLOC \
|
||||
THIRD_PARTY_GDTOA \
|
||||
THIRD_PARTY_GETOPT \
|
||||
THIRD_PARTY_MUSL \
|
||||
THIRD_PARTY_ZLIB \
|
||||
THIRD_PARTY_ZLIB_GZ \
|
||||
THIRD_PARTY_REGEX
|
||||
|
||||
COSMOCC_PKGS = \
|
||||
$(COSMOPOLITAN_H_PKGS) \
|
||||
CTL \
|
||||
THIRD_PARTY_AARCH64 \
|
||||
THIRD_PARTY_LIBCXX \
|
||||
THIRD_PARTY_LIBCXXABI \
|
||||
THIRD_PARTY_LIBUNWIND \
|
||||
THIRD_PARTY_OPENMP \
|
||||
THIRD_PARTY_INTEL
|
||||
|
||||
o/$(MODE)/cosmopolitan.a: \
|
||||
$(call reverse,$(call uniq,$(foreach x,$(COSMOPOLITAN),$($(x)))))
|
||||
|
||||
COSMOCC_HDRS = \
|
||||
$(wildcard libc/integral/*) \
|
||||
$(foreach x,$(COSMOCC_PKGS),$($(x)_HDRS)) \
|
||||
$(foreach x,$(COSMOCC_PKGS),$($(x)_INCS))
|
||||
|
||||
o/cosmocc.h.txt: Makefile libc $(MAKEFILES) $(call uniq,$(foreach x,$(HDRS) $(INCS),$(dir $(x)))) $(HDRS) $(INCS)
|
||||
$(file >$@, $(call uniq,$(COSMOCC_HDRS)))
|
||||
|
||||
COSMOPOLITAN_H_ROOT_HDRS = \
|
||||
o/$(MODE)/cosmopolitan.a.txt:
|
||||
printf "%s\n" $(call reverse,$(call uniq,$(foreach x,$(COSMOPOLITAN_OBJECTS),$($(x)))))
|
||||
o/$(MODE)/cosmopolitan.a: $(filter-out o/libc/stubs/exit11.o,$(foreach x,$(COSMOPOLITAN_OBJECTS),$($(x)_A_OBJS)))
|
||||
o/cosmopolitan.h: \
|
||||
o/$(MODE)/tool/build/rollup.com \
|
||||
libc/integral/normalize.inc \
|
||||
$(foreach x,$(COSMOPOLITAN_H_PKGS),$($(x)_HDRS))
|
||||
$(foreach x,$(COSMOPOLITAN_HEADERS),$($(x)_HDRS))
|
||||
@ACTION=ROLLUP TARGET=$@ build/do $^ >$@
|
||||
|
||||
o/cosmopolitan.html: private .UNSANDBOXED = 1
|
||||
o/cosmopolitan.html: \
|
||||
o/$(MODE)/third_party/chibicc/chibicc.dbg \
|
||||
$(filter-out %.s,$(foreach x,$(COSMOPOLITAN_OBJECTS),$($(x)_SRCS))) \
|
||||
$(filter-out %.cpp,$(filter-out %.cc,$(SRCS))) \
|
||||
$(HDRS)
|
||||
$(file >$(TMPDIR)/$(subst /,_,$@),$(filter-out %.cpp,$(filter-out %.cc,$(filter-out %.s,$(foreach x,$(COSMOPOLITAN_OBJECTS),$($(x)_SRCS))))))
|
||||
o/$(MODE)/third_party/chibicc/chibicc.dbg -J \
|
||||
o/$(MODE)/third_party/chibicc/chibicc.com.dbg \
|
||||
$(filter-out %.s,$(foreach x,$(COSMOPOLITAN_OBJECTS),$($(x)_SRCS)))
|
||||
o/$(MODE)/third_party/chibicc/chibicc.com.dbg -J \
|
||||
-fno-common -include libc/integral/normalize.inc -o $@ \
|
||||
-DCOSMO @$(TMPDIR)/$(subst /,_,$@)
|
||||
$(filter-out %.s,$(foreach x,$(COSMOPOLITAN_OBJECTS),$($(x)_SRCS)))
|
||||
|
||||
$(SRCS): \
|
||||
libc/integral/normalize.inc \
|
||||
|
@ -574,50 +332,6 @@ $(SRCS): \
|
|||
libc/integral/lp64arg.inc \
|
||||
libc/integral/lp64.inc
|
||||
|
||||
ifeq ($(ARCH), x86_64)
|
||||
TOOLCHAIN_ARTIFACTS = \
|
||||
o/$(MODE)/ape/ape.lds \
|
||||
o/$(MODE)/libc/crt/crt.o \
|
||||
o/$(MODE)/ape/ape.elf \
|
||||
o/$(MODE)/ape/ape.o \
|
||||
o/$(MODE)/ape/ape-copy-self.o \
|
||||
o/$(MODE)/ape/ape-no-modify-self.o \
|
||||
o/$(MODE)/cosmopolitan.a \
|
||||
o/$(MODE)/third_party/libcxx/libcxx.a \
|
||||
o/$(MODE)/tool/build/march-native \
|
||||
o/$(MODE)/tool/build/ar \
|
||||
o/$(MODE)/tool/build/mktemper \
|
||||
o/$(MODE)/tool/build/fixupobj \
|
||||
o/$(MODE)/tool/build/zipcopy \
|
||||
o/$(MODE)/tool/build/apelink \
|
||||
o/$(MODE)/tool/build/pecheck
|
||||
else
|
||||
TOOLCHAIN_ARTIFACTS = \
|
||||
o/$(MODE)/ape/ape.elf \
|
||||
o/$(MODE)/ape/aarch64.lds \
|
||||
o/$(MODE)/libc/crt/crt.o \
|
||||
o/$(MODE)/cosmopolitan.a \
|
||||
o/$(MODE)/third_party/libcxx/libcxx.a \
|
||||
o/$(MODE)/tool/build/march-native \
|
||||
o/$(MODE)/tool/build/fixupobj \
|
||||
o/$(MODE)/tool/build/zipcopy
|
||||
endif
|
||||
|
||||
.PHONY: toolchain
|
||||
toolchain: $(TOOLCHAIN_ARTIFACTS)
|
||||
|
||||
.PHONY: clean_toolchain
|
||||
clean_toolchain:
|
||||
$(RM) $(TOOLCHAIN_ARTIFACTS)
|
||||
|
||||
aarch64: private .INTERNET = true
|
||||
aarch64: private .UNSANDBOXED = true
|
||||
aarch64:
|
||||
$(MAKE) m=aarch64
|
||||
|
||||
clean:
|
||||
$(RM) -r o
|
||||
|
||||
# UNSPECIFIED PREREQUISITES TUTORIAL
|
||||
#
|
||||
# A build rule must exist for all files that make needs to consider in
|
||||
|
@ -642,9 +356,9 @@ $(SRCS):
|
|||
$(HDRS):
|
||||
$(INCS):
|
||||
.DEFAULT:
|
||||
@$(ECHO)
|
||||
@$(ECHO) NOTE: deleting o/$(MODE)/depend because of an unspecified prerequisite: $@
|
||||
@$(ECHO)
|
||||
$(RM) o/$(MODE)/depend
|
||||
@echo >&2
|
||||
@echo NOTE: deleting o/$(MODE)/depend because of an unspecified prerequisite: $@ >&2
|
||||
@echo >&2
|
||||
rm -f o/$(MODE)/depend
|
||||
|
||||
-include o/$(MODE)/depend
|
||||
|
|
14
NOTICE
Normal file
14
NOTICE
Normal file
|
@ -0,0 +1,14 @@
|
|||
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.
|
285
README.md
285
README.md
|
@ -1,279 +1,50 @@
|
|||

|
||||
|
||||
[](https://github.com/jart/cosmopolitan/actions/workflows/build.yml)
|
||||
# Cosmopolitan
|
||||
|
||||
[Cosmopolitan Libc](https://justine.lol/cosmopolitan/index.html) makes C/C++
|
||||
[Cosmopolitan Libc](https://justine.lol/cosmopolitan/index.html) makes C
|
||||
a build-once run-anywhere language, like Java, except it doesn't need an
|
||||
interpreter or virtual machine. Instead, it reconfigures stock GCC and
|
||||
Clang to output a POSIX-approved polyglot format that runs natively on
|
||||
Linux + Mac + Windows + FreeBSD + OpenBSD 7.3 + NetBSD + BIOS with the
|
||||
best possible performance and the tiniest footprint imaginable.
|
||||
Linux + Mac + Windows + FreeBSD + OpenBSD + NetBSD + BIOS with the best
|
||||
possible performance and the tiniest footprint imaginable.
|
||||
|
||||
## Background
|
||||
|
||||
For an introduction to this project, please read the [actually portable
|
||||
executable](https://justine.lol/ape.html) blog post and [cosmopolitan
|
||||
For an introduction to this project, please read the [αcτµαlly pδrταblε
|
||||
εxεcµταblε](https://justine.lol/ape.html) blog post and [cosmopolitan
|
||||
libc](https://justine.lol/cosmopolitan/index.html) website. We also have
|
||||
[API
|
||||
documentation](https://justine.lol/cosmopolitan/documentation.html).
|
||||
[API documentation](https://justine.lol/cosmopolitan/documentation.html).
|
||||
|
||||
## Getting Started
|
||||
|
||||
You can start by obtaining a release of our `cosmocc` compiler from
|
||||
<https://cosmo.zip/pub/cosmocc/>.
|
||||
If you're doing your development work on Linux or BSD then you need just
|
||||
five files to get started:
|
||||
|
||||
```sh
|
||||
mkdir -p cosmocc
|
||||
cd cosmocc
|
||||
wget https://cosmo.zip/pub/cosmocc/cosmocc.zip
|
||||
unzip cosmocc.zip
|
||||
wget https://justine.lol/cosmopolitan/cosmopolitan-amalgamation-0.2.zip
|
||||
unzip cosmopolitan-amalgamated-0.2.zip
|
||||
echo 'main() { printf("hello world\n"); }' >hello.c
|
||||
gcc -g -O -static -nostdlib -nostdinc -fno-pie -no-pie -mno-red-zone \
|
||||
-o hello.com.dbg hello.c -fuse-ld=bfd -Wl,-T,ape.lds \
|
||||
-include cosmopolitan.h crt.o ape.o cosmopolitan.a
|
||||
objcopy -S -O binary hello.com.dbg hello.com
|
||||
./hello.com
|
||||
```
|
||||
|
||||
Here's an example program we can write:
|
||||
If you're developing on Windows or MacOS then you need to download an
|
||||
x86_64-pc-linux-gnu toolchain beforehand. See the [Compiling on
|
||||
Windows](https://justine.lol/cosmopolitan/windows-compiling.html)
|
||||
tutorial. It's needed because the ELF object format is what makes
|
||||
universal binaries possible.
|
||||
|
||||
```c
|
||||
// hello.c
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
printf("hello world\n");
|
||||
}
|
||||
```
|
||||
|
||||
It can be compiled as follows:
|
||||
Cosmopolitan can also be compiled from source on any Linux distro.
|
||||
|
||||
```sh
|
||||
cosmocc -o hello hello.c
|
||||
./hello
|
||||
wget https://justine.lol/cosmopolitan/cosmopolitan-0.2.tar.gz
|
||||
tar xf cosmopolitan-0.2.tar.gz # see releases page
|
||||
cd cosmopolitan-0.2
|
||||
make -j16
|
||||
o//examples/hello.com
|
||||
find o -name \*.com | xargs ls -rShal | less
|
||||
```
|
||||
|
||||
The Cosmopolitan Libc runtime links some heavyweight troubleshooting
|
||||
features by default, which are very useful for developers and admins.
|
||||
Here's how you can log system calls:
|
||||
|
||||
```sh
|
||||
./hello --strace
|
||||
```
|
||||
|
||||
Here's how you can get a much more verbose log of function calls:
|
||||
|
||||
```sh
|
||||
./hello --ftrace
|
||||
```
|
||||
|
||||
You can use the Cosmopolitan's toolchain to build conventional open
|
||||
source projects which use autotools. This strategy normally works:
|
||||
|
||||
```sh
|
||||
export CC=x86_64-unknown-cosmo-cc
|
||||
export CXX=x86_64-unknown-cosmo-c++
|
||||
./configure --prefix=/opt/cosmos/x86_64
|
||||
make -j
|
||||
make install
|
||||
```
|
||||
|
||||
## Cosmopolitan Source Builds
|
||||
|
||||
Cosmopolitan can be compiled from source on any of our supported
|
||||
platforms. The Makefile will download cosmocc automatically.
|
||||
|
||||
It's recommended that you install a systemwide APE Loader. This command
|
||||
requires `sudo` access to copy the `ape` command to a system folder and
|
||||
register with binfmt_misc on Linux, for even more performance.
|
||||
|
||||
```sh
|
||||
ape/apeinstall.sh
|
||||
```
|
||||
|
||||
You can now build the mono repo with any modern version of GNU Make. To
|
||||
bootstrap your build, you can install Cosmopolitan Make from this site:
|
||||
|
||||
https://cosmo.zip/pub/cosmos/bin/make
|
||||
|
||||
E.g.:
|
||||
|
||||
```sh
|
||||
curl -LO https://cosmo.zip/pub/cosmos/bin/make
|
||||
./make -j8
|
||||
o//examples/hello
|
||||
```
|
||||
|
||||
After you've built the repo once, you can also use the make from your
|
||||
cosmocc at `.cosmocc/current/bin/make`. You might even prefer to alias
|
||||
make to `$COSMO/.cosmocc/current/bin/make`.
|
||||
|
||||
Since the Cosmopolitan repository is very large, you might only want to
|
||||
build one particular thing. Here's an example of a target that can be
|
||||
compiled relatively quickly, which is a simple POSIX test that only
|
||||
depends on core LIBC packages.
|
||||
|
||||
```sh
|
||||
rm -rf o//libc o//test
|
||||
.cosmocc/current/bin/make o//test/posix/signal_test
|
||||
o//test/posix/signal_test
|
||||
```
|
||||
|
||||
Sometimes it's desirable to build a subset of targets, without having to
|
||||
list out each individual one. For example if you wanted to build and run
|
||||
all the unit tests in the `TEST_POSIX` package, you could say:
|
||||
|
||||
```sh
|
||||
.cosmocc/current/bin/make o//test/posix
|
||||
```
|
||||
|
||||
Cosmopolitan provides a variety of build modes. For example, if you want
|
||||
really tiny binaries (as small as 12kb in size) then you'd say:
|
||||
|
||||
```sh
|
||||
.cosmocc/current/bin/make m=tiny
|
||||
```
|
||||
|
||||
You can furthermore cut out the bloat of other operating systems, and
|
||||
have Cosmopolitan become much more similar to Musl Libc.
|
||||
|
||||
```sh
|
||||
.cosmocc/current/bin/make m=tinylinux
|
||||
```
|
||||
|
||||
For further details, see [//build/config.mk](build/config.mk).
|
||||
|
||||
## Debugging
|
||||
|
||||
To print a log of system calls to stderr:
|
||||
|
||||
```sh
|
||||
cosmocc -o hello hello.c
|
||||
./hello --strace
|
||||
```
|
||||
|
||||
To print a log of function calls to stderr:
|
||||
|
||||
```sh
|
||||
cosmocc -o hello hello.c
|
||||
./hello --ftrace
|
||||
```
|
||||
|
||||
Both strace and ftrace use the unbreakable kprintf() facility, which is
|
||||
able to be sent to a file by setting an environment variable.
|
||||
|
||||
```sh
|
||||
export KPRINTF_LOG=log
|
||||
./hello --strace
|
||||
```
|
||||
|
||||
## GDB
|
||||
|
||||
Here's the recommended `~/.gdbinit` config:
|
||||
|
||||
```gdb
|
||||
set host-charset UTF-8
|
||||
set target-charset UTF-8
|
||||
set target-wide-charset UTF-8
|
||||
set osabi none
|
||||
set complaints 0
|
||||
set confirm off
|
||||
set history save on
|
||||
set history filename ~/.gdb_history
|
||||
define asm
|
||||
layout asm
|
||||
layout reg
|
||||
end
|
||||
define src
|
||||
layout src
|
||||
layout reg
|
||||
end
|
||||
src
|
||||
```
|
||||
|
||||
You normally run the `.dbg` file under gdb. If you need to debug the
|
||||
`` file itself, then you can load the debug symbols independently as
|
||||
|
||||
```sh
|
||||
gdb foo -ex 'add-symbol-file foo.dbg 0x401000'
|
||||
```
|
||||
|
||||
## Platform Notes
|
||||
|
||||
### Shells
|
||||
|
||||
If you use zsh and have trouble running APE programs try `sh -c ./prog`
|
||||
or simply upgrade to zsh 5.9+ (since we patched it two years ago). The
|
||||
same is the case for Python `subprocess`, old versions of fish, etc.
|
||||
|
||||
### Linux
|
||||
|
||||
Some Linux systems are configured to launch MZ executables under WINE.
|
||||
Other distros configure their stock installs so that APE programs will
|
||||
print "run-detectors: unable to find an interpreter". For example:
|
||||
|
||||
```sh
|
||||
jart@ubuntu:~$ wget https://cosmo.zip/pub/cosmos/bin/dash
|
||||
jart@ubuntu:~$ chmod +x dash
|
||||
jart@ubuntu:~$ ./dash
|
||||
run-detectors: unable to find an interpreter for ./dash
|
||||
```
|
||||
|
||||
You can fix that by registering APE with `binfmt_misc`:
|
||||
|
||||
```sh
|
||||
sudo wget -O /usr/bin/ape https://cosmo.zip/pub/cosmos/bin/ape-$(uname -m).elf
|
||||
sudo chmod +x /usr/bin/ape
|
||||
sudo sh -c "echo ':APE:M::MZqFpD::/usr/bin/ape:' >/proc/sys/fs/binfmt_misc/register"
|
||||
sudo sh -c "echo ':APE-jart:M::jartsr::/usr/bin/ape:' >/proc/sys/fs/binfmt_misc/register"
|
||||
```
|
||||
|
||||
You should be good now. APE will not only work, it'll launch executables
|
||||
400µs faster now too. However if things still didn't work out, it's also
|
||||
possible to disable `binfmt_misc` as follows:
|
||||
|
||||
```sh
|
||||
sudo sh -c 'echo -1 > /proc/sys/fs/binfmt_misc/cli' # remove Ubuntu's MZ interpreter
|
||||
sudo sh -c 'echo -1 > /proc/sys/fs/binfmt_misc/status' # remove ALL binfmt_misc entries
|
||||
```
|
||||
|
||||
### WSL
|
||||
|
||||
It's normally unsafe to use APE in a WSL environment, because it tries
|
||||
to run MZ executables as WIN32 binaries within the WSL environment. In
|
||||
order to make it safe to use Cosmopolitan software on WSL, run this:
|
||||
|
||||
```sh
|
||||
sudo sh -c "echo -1 > /proc/sys/fs/binfmt_misc/WSLInterop"
|
||||
```
|
||||
|
||||
## Discord Chatroom
|
||||
|
||||
The Cosmopolitan development team collaborates on the Redbean Discord
|
||||
server. You're welcome to join us! <https://discord.gg/FwAVVu7eJ4>
|
||||
|
||||
## Support Vector
|
||||
|
||||
| Platform | Min Version | Circa |
|
||||
| :--- | ---: | ---: |
|
||||
| AMD | K8 | 2003 |
|
||||
| Intel | Core | 2006 |
|
||||
| Linux | 2.6.18 | 2007 |
|
||||
| Windows | 8 [1] | 2012 |
|
||||
| Darwin (macOS) | 23.1.0+ | 2023 |
|
||||
| OpenBSD | 7.3 or earlier | 2023 |
|
||||
| FreeBSD | 13 | 2020 |
|
||||
| NetBSD | 9.2 | 2021 |
|
||||
|
||||
[1] See our [vista branch](https://github.com/jart/cosmopolitan/tree/vista)
|
||||
for a community supported version of Cosmopolitan that works on Windows
|
||||
Vista and Windows 7.
|
||||
|
||||
## Special Thanks
|
||||
|
||||
Funding for this project is crowdsourced using
|
||||
[GitHub Sponsors](https://github.com/sponsors/jart) and
|
||||
[Patreon](https://www.patreon.com/jart). Your support is what makes this
|
||||
project possible. Thank you! We'd also like to give special thanks to
|
||||
the following groups and individuals:
|
||||
|
||||
- [Joe Drumgoole](https://github.com/jdrumgoole)
|
||||
- [Rob Figueiredo](https://github.com/robfig)
|
||||
- [Wasmer](https://wasmer.io/)
|
||||
|
||||
For publicly sponsoring our work at the highest tier.
|
||||
|
|
287
ape/BUILD.mk
287
ape/BUILD.mk
|
@ -1,287 +0,0 @@
|
|||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||
#── vi: set noet ft=make ts=8 sw=8 fenc=utf-8 :vi ────────────────────┘
|
||||
#
|
||||
# OVERVIEW
|
||||
#
|
||||
# αcτµαlly pδrταblε εxεcµταblε
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This file defines the libraries, runtimes, and build rules needed to
|
||||
# create executables from your Linux workstation that'll run anywhere.
|
||||
# Loading this package will make certain systemic modifications to the
|
||||
# build like turning off the System V "Red Zone" optimization, because
|
||||
# αcτµαlly pδrταblε εxεcµταblεs need to be able to run in kernelspace.
|
||||
|
||||
PKGS += APE
|
||||
|
||||
APE_FILES := $(wildcard ape/*.*)
|
||||
APE_HDRS = $(filter %.h,$(APE_FILES))
|
||||
APE_INCS = $(filter %.inc,$(APE_FILES))
|
||||
|
||||
ifeq ($(ARCH), aarch64)
|
||||
|
||||
APE = o/$(MODE)/ape/aarch64.lds
|
||||
|
||||
APELINK = \
|
||||
$(COMPILE) \
|
||||
-ALINK.ape \
|
||||
$(LINK) \
|
||||
$(LINKARGS) \
|
||||
$(OUTPUT_OPTION) && \
|
||||
$(COMPILE) \
|
||||
-AFIXUP.ape \
|
||||
-wT$@ \
|
||||
$(FIXUPOBJ) \
|
||||
$@
|
||||
|
||||
APE_SRCS = ape/ape.S ape/start.S ape/launch.S ape/systemcall.S
|
||||
APE_OBJS = o/$(MODE)/ape/ape.o
|
||||
APE_NO_MODIFY_SELF = $(APE)
|
||||
APE_COPY_SELF = $(APE)
|
||||
|
||||
.PHONY: o/$(MODE)/ape
|
||||
o/$(MODE)/ape: $(APE)
|
||||
|
||||
o/$(MODE)/ape/aarch64.lds: \
|
||||
ape/aarch64.lds \
|
||||
libc/zip.h \
|
||||
libc/thread/tls.h \
|
||||
libc/calls/struct/timespec.h \
|
||||
libc/macros.h \
|
||||
libc/str/str.h
|
||||
|
||||
APE_LOADER_LDFLAGS = \
|
||||
-pie \
|
||||
-static \
|
||||
-nostdlib \
|
||||
--no-dynamic-linker \
|
||||
-z norelro \
|
||||
-z common-page-size=0x4000 \
|
||||
-z max-page-size=0x4000
|
||||
|
||||
APE_LOADER_FLAGS = \
|
||||
-DNDEBUG \
|
||||
-iquote. \
|
||||
-Wall \
|
||||
-Wextra \
|
||||
-fpie \
|
||||
-Os \
|
||||
-ffreestanding \
|
||||
-mgeneral-regs-only \
|
||||
-fno-asynchronous-unwind-tables \
|
||||
-fno-stack-protector \
|
||||
-fno-ident \
|
||||
-fno-gnu-unique \
|
||||
-c \
|
||||
$(OUTPUT_OPTION) \
|
||||
$<
|
||||
|
||||
o/$(MODE)/ape/ape.elf: o/$(MODE)/ape/ape.elf.dbg
|
||||
@$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -g $< $@
|
||||
@$(COMPILE) -AFIXUPOBJ -wT$@ $(FIXUPOBJ) $@
|
||||
|
||||
o/$(MODE)/ape/ape.elf.dbg: \
|
||||
o/$(MODE)/ape/start.o \
|
||||
o/$(MODE)/ape/loader.o \
|
||||
o/$(MODE)/ape/launch.o \
|
||||
o/$(MODE)/ape/systemcall.o
|
||||
@$(COMPILE) -ALINK.elf $(LD) $(APE_LOADER_LDFLAGS) -o $@ $(patsubst %.lds,-T %.lds,$^)
|
||||
|
||||
o/$(MODE)/ape/loader.o: ape/loader.c ape/ape.h
|
||||
@$(COMPILE) -AOBJECTIFY.c $(CC) -DSUPPORT_VECTOR=33 -g $(APE_LOADER_FLAGS)
|
||||
o/$(MODE)/ape/start.o: ape/start.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
o/$(MODE)/ape/launch.o: ape/launch.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
o/$(MODE)/ape/systemcall.o: ape/systemcall.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
|
||||
.PHONY: o/$(MODE)/ape
|
||||
o/$(MODE)/ape: o/$(MODE)/ape/ape.elf
|
||||
|
||||
else
|
||||
|
||||
APE = o/$(MODE)/ape/ape.o \
|
||||
o/$(MODE)/ape/ape.lds
|
||||
|
||||
APELINK = \
|
||||
$(COMPILE) \
|
||||
-ALINK.ape \
|
||||
$(LINK) \
|
||||
$(LINKARGS) \
|
||||
$(OUTPUT_OPTION) && \
|
||||
$(COMPILE) \
|
||||
-AFIXUP.ape \
|
||||
-wT$@ \
|
||||
$(FIXUPOBJ) \
|
||||
$@
|
||||
|
||||
APE_NO_MODIFY_SELF = \
|
||||
o/$(MODE)/ape/ape.lds \
|
||||
o/$(MODE)/ape/ape-no-modify-self.o
|
||||
|
||||
APE_COPY_SELF = \
|
||||
o/$(MODE)/ape/ape.lds \
|
||||
o/$(MODE)/ape/ape-copy-self.o
|
||||
|
||||
APE_LOADER_FLAGS = \
|
||||
-DNDEBUG \
|
||||
-iquote. \
|
||||
-Wall \
|
||||
-Wextra \
|
||||
-Werror \
|
||||
-pedantic-errors \
|
||||
-fpie \
|
||||
-Os \
|
||||
-ffreestanding \
|
||||
-mgeneral-regs-only \
|
||||
-fno-stack-protector \
|
||||
-fno-ident \
|
||||
-fno-gnu-unique \
|
||||
-c \
|
||||
$(OUTPUT_OPTION) \
|
||||
$<
|
||||
|
||||
APE_SRCS_C = ape/loader.c
|
||||
APE_SRCS_S = $(filter %.S,$(APE_FILES))
|
||||
APE_SRCS = $(APE_SRCS_C) $(APE_SRCS_S)
|
||||
APE_OBJS = $(APE_SRCS_S:%.S=o/$(MODE)/%.o)
|
||||
APE_CHECKS = $(APE_HDRS:%=o/%.ok)
|
||||
|
||||
o/ape/idata.inc: \
|
||||
ape/idata.internal.h \
|
||||
ape/relocations.h
|
||||
|
||||
o/$(MODE)/ape/ape-no-modify-self.o: \
|
||||
ape/ape.S \
|
||||
ape/ape.h \
|
||||
ape/macros.internal.h \
|
||||
ape/relocations.h \
|
||||
ape/ape.internal.h \
|
||||
libc/dce.h \
|
||||
libc/elf/def.h \
|
||||
libc/thread/tls.h \
|
||||
libc/macho.h \
|
||||
libc/macros.h \
|
||||
libc/nexgen32e/uart.internal.h \
|
||||
libc/calls/metalfile.internal.h \
|
||||
libc/nt/pedef.internal.h \
|
||||
libc/runtime/e820.internal.h \
|
||||
libc/runtime/mman.internal.h \
|
||||
libc/runtime/pc.internal.h \
|
||||
libc/sysv/consts/prot.h \
|
||||
o/$(MODE)/ape/ape.elf
|
||||
@$(COMPILE) \
|
||||
-AOBJECTIFY.S \
|
||||
$(OBJECTIFY.S) \
|
||||
$(OUTPUT_OPTION) \
|
||||
-DAPE_NO_MODIFY_SELF \
|
||||
-DAPE_LOADER='"o/$(MODE)/ape/ape.elf"' $<
|
||||
|
||||
o/$(MODE)/ape/ape-copy-self.o: \
|
||||
ape/ape.S \
|
||||
ape/ape.h \
|
||||
ape/macros.internal.h \
|
||||
ape/relocations.h \
|
||||
ape/ape.internal.h \
|
||||
libc/dce.h \
|
||||
libc/elf/def.h \
|
||||
libc/thread/tls.h \
|
||||
libc/macho.h \
|
||||
libc/macros.h \
|
||||
libc/nexgen32e/uart.internal.h \
|
||||
libc/calls/metalfile.internal.h \
|
||||
libc/nt/pedef.internal.h \
|
||||
libc/runtime/e820.internal.h \
|
||||
libc/runtime/mman.internal.h \
|
||||
libc/runtime/pc.internal.h \
|
||||
libc/sysv/consts/prot.h
|
||||
@$(COMPILE) \
|
||||
-AOBJECTIFY.S \
|
||||
$(OBJECTIFY.S) \
|
||||
$(OUTPUT_OPTION) \
|
||||
-DAPE_NO_MODIFY_SELF $<
|
||||
|
||||
o/$(MODE)/ape/loader.o: ape/loader.c
|
||||
@$(COMPILE) -AOBJECTIFY.c $(CC) -DSUPPORT_VECTOR=121 -g $(APE_LOADER_FLAGS)
|
||||
o/$(MODE)/ape/loader-gcc.asm: ape/loader.c
|
||||
@$(COMPILE) -AOBJECTIFY.c $(CC) -DSUPPORT_VECTOR=121 -S -g0 $(APE_LOADER_FLAGS)
|
||||
o/$(MODE)/ape/loader-clang.asm: ape/loader.c
|
||||
@$(COMPILE) -AOBJECTIFY.c $(CLANG) -DSUPPORT_VECTOR=121 -S -g0 $(APE_LOADER_FLAGS)
|
||||
|
||||
o/$(MODE)/ape/loader-xnu.o: ape/loader.c
|
||||
@$(COMPILE) -AOBJECTIFY.c $(CC) -DSUPPORT_VECTOR=8 -g $(APE_LOADER_FLAGS)
|
||||
o/$(MODE)/ape/loader-xnu-gcc.asm: ape/loader.c
|
||||
@$(COMPILE) -AOBJECTIFY.c $(CC) -DSUPPORT_VECTOR=8 -S -g0 $(APE_LOADER_FLAGS)
|
||||
o/$(MODE)/ape/loader-xnu-clang.asm: ape/loader.c
|
||||
@$(COMPILE) -AOBJECTIFY.c $(CLANG) -DSUPPORT_VECTOR=8 -S -g0 $(APE_LOADER_FLAGS)
|
||||
|
||||
o/$(MODE)/ape/ape.elf: o/$(MODE)/ape/ape.elf.dbg
|
||||
@$(COMPILE) -AOBJBINCOPY -w $(OBJBINCOPY) -f -o $@ $<
|
||||
|
||||
o/$(MODE)/ape/ape.macho: o/$(MODE)/ape/ape.elf.dbg
|
||||
@$(COMPILE) -AOBJBINCOPY -w $(OBJBINCOPY) -fm -o $@ $<
|
||||
|
||||
APE_LOADER_LDFLAGS = \
|
||||
-static \
|
||||
-nostdlib \
|
||||
--no-dynamic-linker \
|
||||
-z separate-code \
|
||||
-z common-page-size=0x1000 \
|
||||
-z max-page-size=0x10000
|
||||
|
||||
o/$(MODE)/ape/ape.elf.dbg: \
|
||||
o/$(MODE)/ape/loader-macho.o \
|
||||
o/$(MODE)/ape/start.o \
|
||||
o/$(MODE)/ape/loader.o \
|
||||
o/$(MODE)/ape/launch.o \
|
||||
o/$(MODE)/ape/systemcall.o \
|
||||
ape/loader.lds
|
||||
@$(COMPILE) -ALINK.elf $(LD) $(APE_LOADER_LDFLAGS) -o $@ $(patsubst %.lds,-T %.lds,$^)
|
||||
|
||||
.PHONY: o/$(MODE)/ape
|
||||
o/$(MODE)/ape: $(APE_CHECKS) \
|
||||
o/$(MODE)/ape/ape.o \
|
||||
o/$(MODE)/ape/ape.lds \
|
||||
o/$(MODE)/ape/ape.elf \
|
||||
o/$(MODE)/ape/ape.macho \
|
||||
|
||||
endif
|
||||
|
||||
# these assembly files are safe to build on aarch64
|
||||
o/$(MODE)/ape/ape.o: \
|
||||
ape/ape.S \
|
||||
ape/ape.h \
|
||||
libc/dce.h \
|
||||
libc/elf/def.h \
|
||||
ape/relocations.h \
|
||||
libc/thread/tls.h \
|
||||
ape/ape.internal.h \
|
||||
ape/macros.internal.h \
|
||||
libc/macho.h \
|
||||
libc/macros.h \
|
||||
libc/sysv/consts/prot.h \
|
||||
libc/nt/pedef.internal.h \
|
||||
libc/runtime/pc.internal.h \
|
||||
libc/runtime/e820.internal.h \
|
||||
libc/runtime/mman.internal.h \
|
||||
libc/nexgen32e/uart.internal.h \
|
||||
libc/calls/metalfile.internal.h
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
|
||||
o/$(MODE)/ape/ape.lds: \
|
||||
ape/ape.lds \
|
||||
ape/macros.internal.h \
|
||||
ape/relocations.h \
|
||||
ape/ape.internal.h \
|
||||
libc/thread/tls.h \
|
||||
libc/calls/struct/timespec.h \
|
||||
libc/thread/thread.h \
|
||||
libc/dce.h \
|
||||
libc/elf/def.h \
|
||||
libc/elf/pf2prot.internal.h \
|
||||
libc/macros.h \
|
||||
libc/nt/pedef.internal.h \
|
||||
libc/str/str.h \
|
||||
libc/zip.h
|
301
ape/aarch64.lds
301
ape/aarch64.lds
|
@ -1,301 +0,0 @@
|
|||
/*-*- mode: ld-script; indent-tabs-mode: nil; tab-width: 2; coding: utf-8 -*-│
|
||||
│ vi: set et sts=2 sw=2 fenc=utf-8 :vi │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
#include "libc/thread/tls.h"
|
||||
|
||||
ENTRY(_start)
|
||||
OUTPUT_ARCH(aarch64)
|
||||
OUTPUT_FORMAT("elf64-littleaarch64",
|
||||
"elf64-bigaarch64",
|
||||
"elf64-littleaarch64")
|
||||
|
||||
SECTIONS {
|
||||
|
||||
. = SEGMENT_START("text-segment", 0x000800000000);
|
||||
__executable_start = .;
|
||||
. += SIZEOF_HEADERS;
|
||||
|
||||
.interp : { *(.interp) }
|
||||
.note.gnu.build-id : { *(.note.gnu.build-id) }
|
||||
.hash : { *(.hash) }
|
||||
.gnu.hash : { *(.gnu.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.gnu.version : { *(.gnu.version) }
|
||||
.gnu.version_d : { *(.gnu.version_d) }
|
||||
.gnu.version_r : { *(.gnu.version_r) }
|
||||
.rela.init : { *(.rela.init) }
|
||||
.rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
|
||||
.rela.fini : { *(.rela.fini) }
|
||||
.rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
|
||||
.rela.data.rel.ro : { *(.rela.data.rel.ro .rela.data.rel.ro.* .rela.gnu.linkonce.d.rel.ro.*) }
|
||||
.rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
|
||||
.rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
|
||||
.rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
|
||||
.rela.ctors : { *(.rela.ctors) }
|
||||
.rela.dtors : { *(.rela.dtors) }
|
||||
.rela.got : { *(.rela.got) }
|
||||
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
|
||||
.rela.ifunc : { *(.rela.ifunc) }
|
||||
|
||||
.rela.plt : {
|
||||
*(.rela.plt)
|
||||
__rela_iplt_start = .;
|
||||
*(.rela.iplt)
|
||||
__rela_iplt_end = .;
|
||||
}
|
||||
|
||||
.init : {
|
||||
*(.start)
|
||||
KEEP(*(.initprologue))
|
||||
KEEP(*(SORT_NONE(.init)))
|
||||
KEEP(*(.initepilogue))
|
||||
} =0x1f2003d5
|
||||
|
||||
.plt : ALIGN(16) {
|
||||
*(.plt)
|
||||
*(.iplt)
|
||||
}
|
||||
|
||||
.text : {
|
||||
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
|
||||
*(.text.antiquity .text.antiquity.*)
|
||||
*(.text.exit .text.exit.*)
|
||||
*(.text.startup .text.startup.*)
|
||||
*(.text.hot .text.hot.*)
|
||||
*(.text.modernity .text.modernity.*)
|
||||
*(.text .stub .text.* .gnu.linkonce.t.*)
|
||||
*(.gnu.warning)
|
||||
} =0x1f2003d5
|
||||
|
||||
.fini : {
|
||||
KEEP(*(SORT_NONE(.fini)))
|
||||
} =0x1f2003d5
|
||||
|
||||
. += CONSTANT(MAXPAGESIZE);
|
||||
|
||||
.privileged : {
|
||||
__privileged_start = ABSOLUTE(.) & -CONSTANT(MAXPAGESIZE);
|
||||
*(.privileged*)
|
||||
} =0x1f2003d6
|
||||
|
||||
.rodata : {
|
||||
KEEP(*(.rodata.pytab.0));
|
||||
KEEP(*(.rodata.pytab.1));
|
||||
KEEP(*(.rodata.pytab.2));
|
||||
KEEP(*(SORT_BY_NAME(.sort.rodata.*)))
|
||||
*(.rodata .rodata.* .gnu.linkonce.r.*)
|
||||
*(.ubsan.types)
|
||||
*(.ubsan.data)
|
||||
}
|
||||
|
||||
.notice : {
|
||||
__notices = .;
|
||||
KEEP(*(.notice))
|
||||
BYTE(0);
|
||||
BYTE(10);
|
||||
BYTE(10);
|
||||
}
|
||||
|
||||
.eh_frame_hdr : {
|
||||
*(.eh_frame_hdr)
|
||||
*(.eh_frame_entry .eh_frame_entry.*)
|
||||
}
|
||||
|
||||
__eh_frame_hdr_start = SIZEOF(.eh_frame_hdr) > 0 ? ADDR(.eh_frame_hdr) : 0;
|
||||
__eh_frame_hdr_end = SIZEOF(.eh_frame_hdr) > 0 ? . : 0;
|
||||
|
||||
.gcc_except_table : ONLY_IF_RO {
|
||||
*(.gcc_except_table .gcc_except_table.*)
|
||||
}
|
||||
|
||||
.gnu_extab : ONLY_IF_RO {
|
||||
*(.gnu_extab*)
|
||||
}
|
||||
|
||||
.exception_ranges : ONLY_IF_RO {
|
||||
*(.exception_ranges*)
|
||||
}
|
||||
|
||||
__etext = .;
|
||||
_etext = .;
|
||||
PROVIDE(etext = .);
|
||||
|
||||
. += CONSTANT(MAXPAGESIZE);
|
||||
. = DATA_SEGMENT_ALIGN(CONSTANT(MAXPAGESIZE), CONSTANT(COMMONPAGESIZE));
|
||||
|
||||
.eh_frame : {
|
||||
__eh_frame_start = .;
|
||||
KEEP(*(.eh_frame))
|
||||
*(.eh_frame.*)
|
||||
__eh_frame_end = .;
|
||||
}
|
||||
|
||||
.gnu_extab : ONLY_IF_RW {
|
||||
*(.gnu_extab)
|
||||
}
|
||||
|
||||
.gcc_except_table : ONLY_IF_RW {
|
||||
*(.gcc_except_table .gcc_except_table.*)
|
||||
}
|
||||
|
||||
.exception_ranges : ONLY_IF_RW {
|
||||
*(.exception_ranges*)
|
||||
}
|
||||
|
||||
.tdata : {
|
||||
_tdata_start = .;
|
||||
__tdata_start = .;
|
||||
*(.tdata .tdata.* .gnu.linkonce.td.*)
|
||||
_tdata_end = .;
|
||||
}
|
||||
|
||||
.tbss : {
|
||||
_tbss_start = .;
|
||||
*(.tbss .tbss.* .gnu.linkonce.tb.*)
|
||||
*(.tcommon)
|
||||
_tbss_end = .;
|
||||
}
|
||||
|
||||
.init_array : {
|
||||
__init_array_start = .;
|
||||
KEEP(*(.preinit_array))
|
||||
KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*)
|
||||
SORT_BY_INIT_PRIORITY(.ctors.*)))
|
||||
KEEP(*(.init_array))
|
||||
KEEP(*(.ctors))
|
||||
__init_array_end = .;
|
||||
}
|
||||
|
||||
.fini_array : {
|
||||
__fini_array_start = .;
|
||||
KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
|
||||
KEEP(*(.fini_array EXCLUDE_FILE(*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
|
||||
__fini_array_end = .;
|
||||
}
|
||||
|
||||
.data.rel.ro : {
|
||||
KEEP(*(SORT_BY_NAME(.piro.relo.sort.*)))
|
||||
*(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*)
|
||||
*(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*)
|
||||
}
|
||||
|
||||
.dynamic : {
|
||||
*(.dynamic)
|
||||
}
|
||||
|
||||
.got : {
|
||||
*(.got)
|
||||
*(.igot)
|
||||
}
|
||||
|
||||
. = DATA_SEGMENT_RELRO_END(24, .);
|
||||
|
||||
.got.plt : {
|
||||
*(.got.plt)
|
||||
*(.igot.plt)
|
||||
}
|
||||
|
||||
.data : {
|
||||
__data_start = .;
|
||||
KEEP(*(SORT_BY_NAME(.piro.data.sort.*)))
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
KEEP(*(SORT_BY_NAME(.sort.data.*)))
|
||||
SORT(CONSTRUCTORS)
|
||||
}
|
||||
|
||||
_edata = .;
|
||||
PROVIDE(edata = .);
|
||||
|
||||
. = .;
|
||||
__bss_start = .;
|
||||
__bss_start__ = .;
|
||||
|
||||
.bss : {
|
||||
*(.dynbss)
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
KEEP(*(SORT_BY_NAME(.piro.bss.sort.*)))
|
||||
*(COMMON)
|
||||
. = ALIGN(CONSTANT(COMMONPAGESIZE));
|
||||
}
|
||||
|
||||
_bss_end__ = .;
|
||||
__bss_end__ = .;
|
||||
. = ALIGN(64 / 8);
|
||||
. = SEGMENT_START("ldata-segment", .);
|
||||
. = ALIGN(64 / 8);
|
||||
__end__ = .;
|
||||
_end = .;
|
||||
PROVIDE(end = .);
|
||||
|
||||
. = DATA_SEGMENT_END(.);
|
||||
|
||||
.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) }
|
||||
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
|
||||
.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) }
|
||||
.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) }
|
||||
.debug_macro 0 : { *(.debug_macro) }
|
||||
.debug_addr 0 : { *(.debug_addr) }
|
||||
.debug_names 0 : { *(.debug_names) }
|
||||
.debug_loclists 0 : { *(.debug_loclists) }
|
||||
.debug_str_offsets 0 : { *(.debug_str_offsets) }
|
||||
.ARM.attributes 0 : { KEEP(*(.ARM.attributes)) KEEP(*(.gnu.attributes)) }
|
||||
.note.gnu.arm.ident 0 : { KEEP(*(.note.gnu.arm.ident)) }
|
||||
|
||||
.zip 0 : {
|
||||
KEEP(*(.zip.file))
|
||||
__zip_cdir_start = .;
|
||||
KEEP(*(.zip.cdir))
|
||||
__zip_cdir_size = . - __zip_cdir_start;
|
||||
KEEP(*(.zip.eocd))
|
||||
}
|
||||
|
||||
/DISCARD/ : {
|
||||
*(__patchable_function_entries)
|
||||
*(.GCC.command.line)
|
||||
*(.note.GNU-stack)
|
||||
*(.gnu_debuglink)
|
||||
*(.text.windows)
|
||||
*(.gnu.lto_*)
|
||||
*(.eh_frame)
|
||||
*(.idata.*)
|
||||
*(.yoink)
|
||||
*(.head)
|
||||
}
|
||||
}
|
||||
|
||||
ape_stack_vaddr = DEFINED(ape_stack_vaddr) ? ape_stack_vaddr : 0x700000000000;
|
||||
ape_stack_memsz = DEFINED(ape_stack_memsz) ? ape_stack_memsz : 8 * 1024 * 1024;
|
||||
ape_stack_prot = PROT_READ | PROT_WRITE;
|
||||
|
||||
_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);
|
||||
_tdata_align = ALIGNOF(.tdata);
|
||||
_tbss_align = ALIGNOF(.tbss);
|
||||
_tls_align = MAX(TLS_ALIGNMENT, MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)));
|
1139
ape/ape-m1.c
1139
ape/ape-m1.c
File diff suppressed because it is too large
Load diff
13
ape/ape.h
13
ape/ape.h
|
@ -1,13 +0,0 @@
|
|||
#ifndef COSMOPOLITAN_APE_APE_H_
|
||||
#define COSMOPOLITAN_APE_APE_H_
|
||||
|
||||
#define APE_VERSION_MAJOR 1
|
||||
#define APE_VERSION_MINOR 10
|
||||
#define APE_VERSION_STR APE_VERSION_STR_(APE_VERSION_MAJOR, APE_VERSION_MINOR)
|
||||
#define APE_VERSION_NOTE APE_VERSION_NOTE_(APE_VERSION_MAJOR, APE_VERSION_MINOR)
|
||||
|
||||
#define APE_VERSION_STR__(x, y) #x "." #y
|
||||
#define APE_VERSION_STR_(x, y) APE_VERSION_STR__(x, y)
|
||||
#define APE_VERSION_NOTE_(x, y) (100000000 * (x) + 1000000 * (y))
|
||||
|
||||
#endif /* COSMOPOLITAN_APE_APE_H_ */
|
|
@ -1,9 +0,0 @@
|
|||
#ifndef COSMOPOLITAN_APE_APE_INTERNAL_H_
|
||||
#define COSMOPOLITAN_APE_APE_INTERNAL_H_
|
||||
#include "libc/dce.h"
|
||||
|
||||
#if SupportsWindows() || SupportsMetal() || SupportsXnu()
|
||||
#define APE_IS_SHELL_SCRIPT
|
||||
#endif
|
||||
|
||||
#endif /* COSMOPOLITAN_APE_APE_INTERNAL_H_ */
|
501
ape/ape.lds
501
ape/ape.lds
|
@ -1,5 +1,5 @@
|
|||
/*-*- mode: ld-script; indent-tabs-mode: nil; tab-width: 2; coding: utf-8 -*-│
|
||||
│ vi: set et sts=2 sw=2 fenc=utf-8 :vi │
|
||||
│vi: set et sts=2 tw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
|
@ -175,46 +175,18 @@
|
|||
|
||||
#ifdef __LINKER__
|
||||
#include "ape/macros.internal.h"
|
||||
#include "ape/relocations.h"
|
||||
#include "ape/config.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/elf/def.h"
|
||||
#include "libc/elf/pf2prot.internal.h"
|
||||
#include "libc/nt/pedef.internal.h"
|
||||
#include "libc/thread/tls.h"
|
||||
#include "ape/ape.internal.h"
|
||||
|
||||
/* uncomment if .com.dbg won't execute on your kernel (will break .com file) */
|
||||
/* #define APE_FIX_COM_DBG */
|
||||
|
||||
#ifdef __x86__
|
||||
#define CODE_GRANULE 1
|
||||
#else
|
||||
#define CODE_GRANULE 4
|
||||
#endif
|
||||
|
||||
#ifdef APE_FIX_COM_DBG
|
||||
#define SKEW SIZEOF_HEADERS
|
||||
#else
|
||||
#define SKEW 0
|
||||
#endif
|
||||
|
||||
#ifndef IMAGE_BASE_VIRTUAL
|
||||
#define IMAGE_BASE_VIRTUAL 0x400000
|
||||
#endif
|
||||
|
||||
#if IMAGE_BASE_VIRTUAL > 0xffffffff
|
||||
#error "please use 32-bit addresses for image data"
|
||||
#endif
|
||||
#include "libc/zip.h"
|
||||
|
||||
ENTRY(_start)
|
||||
|
||||
PHDRS {
|
||||
Head PT_LOAD FLAGS(PF_X|PF_R);
|
||||
Cod PT_LOAD FLAGS(PF_X|PF_R);
|
||||
Rom PT_LOAD FLAGS(PF_R);
|
||||
Tls PT_TLS FLAGS(PF_W|PF_R);
|
||||
Ram PT_LOAD FLAGS(PF_W|PF_R);
|
||||
stack PT_GNU_STACK FLAGS(PF_W|PF_R);
|
||||
Head PT_LOAD FLAGS(5);
|
||||
Rom PT_LOAD FLAGS(5);
|
||||
Ram PT_LOAD FLAGS(6);
|
||||
stack PT_GNU_STACK FLAGS(6);
|
||||
}
|
||||
|
||||
SECTIONS {
|
||||
|
@ -224,57 +196,56 @@ SECTIONS {
|
|||
/*BEGIN: linux addressability guarantee */
|
||||
/*BEGIN: bsd addressability guarantee */
|
||||
|
||||
.head SEGMENT_START("text-segment", IMAGE_BASE_VIRTUAL) + SKEW : AT(IMAGE_BASE_REAL) {
|
||||
__executable_start = .;
|
||||
.head SEGMENT_START("text-segment", IMAGE_BASE_VIRTUAL) : {
|
||||
HIDDEN(_base = .);
|
||||
|
||||
/* Real Mode */
|
||||
KEEP(*(.head))
|
||||
KEEP(*(.text.head))
|
||||
. += 1;
|
||||
|
||||
/* Executable & Linkable Format */
|
||||
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
|
||||
ape_phdrs = .;
|
||||
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 1);
|
||||
KEEP(*(.elf.phdrs))
|
||||
ape_phdrs_end = .;
|
||||
HIDDEN(ape_phdrs_end = .);
|
||||
. += 1;
|
||||
|
||||
/* OpenBSD */
|
||||
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
|
||||
ape_note = .;
|
||||
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 1);
|
||||
HIDDEN(ape_note = .);
|
||||
KEEP(*(.note.openbsd.ident))
|
||||
KEEP(*(.note.netbsd.ident))
|
||||
ape_note_end = .;
|
||||
HIDDEN(ape_note_end = .);
|
||||
. += 1;
|
||||
|
||||
/* Portable Executable */
|
||||
KEEP(*(.pe.header))
|
||||
ape_pe_sections = .;
|
||||
HIDDEN(ape_pe_sections = .);
|
||||
KEEP(*(.pe.sections))
|
||||
ape_pe_sections_end = .;
|
||||
HIDDEN(ape_pe_sections_end = .);
|
||||
. += 1;
|
||||
|
||||
/* Mach-O */
|
||||
KEEP(*(.macho))
|
||||
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
|
||||
ape_macho_end = .;
|
||||
|
||||
/* APE loader */
|
||||
KEEP(*(.ape.loader))
|
||||
. = ALIGN(. != 0 ? CODE_GRANULE : 0);
|
||||
. = ALIGN(__SIZEOF_POINTER__);
|
||||
HIDDEN(ape_macho_end = .);
|
||||
. += 1;
|
||||
|
||||
KEEP(*(.ape.pad.head))
|
||||
. = ALIGN(. != 0 ? (SupportsWindows() || SupportsMetal() ? CONSTANT(COMMONPAGESIZE) : 16) : 0);
|
||||
_ehead = .;
|
||||
. = ALIGN(SupportsWindows() ? PAGESIZE : 16);
|
||||
HIDDEN(_ehead = .);
|
||||
} :Head
|
||||
|
||||
/*BEGIN: nt addressability guarantee */
|
||||
|
||||
.text . : {
|
||||
BYTE(0x90) /* TODO: fix blinkenlights symbol __map_phdrs */
|
||||
/* Code that needs to be addressable in Real Mode */
|
||||
*(.text.real)
|
||||
KEEP(*(SORT_BY_NAME(.sort.text.real.*)))
|
||||
_ereal = .;
|
||||
*(.rodata.real)
|
||||
KEEP(*(SORT_BY_NAME(.sort.rodata.real.*)))
|
||||
HIDDEN(_ereal = .);
|
||||
|
||||
/*END: realmode addressability guarantee */
|
||||
/*BEGIN: morphable code */
|
||||
. += CODE_GRANULE;
|
||||
|
||||
/* Normal Code */
|
||||
*(.start)
|
||||
|
@ -282,9 +253,12 @@ SECTIONS {
|
|||
KEEP(*(SORT_BY_NAME(.init.*)))
|
||||
KEEP(*(.init))
|
||||
KEEP(*(.initepilogue))
|
||||
KEEP(*(.pltprologue))
|
||||
*(.plt)
|
||||
KEEP(*(.pltepilogue))
|
||||
KEEP(*(.pltgotprologue))
|
||||
*(.plt.got)
|
||||
*(.iplt)
|
||||
KEEP(*(.pltgotepilogue))
|
||||
*(.text.startup .text.startup.*)
|
||||
*(.text.exit .text.exit.*)
|
||||
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
|
||||
|
@ -302,166 +276,104 @@ SECTIONS {
|
|||
KEEP(*(SORT_BY_NAME(.sort.text.*)))
|
||||
|
||||
KEEP(*(.ape.pad.test));
|
||||
HIDDEN(__test_start = .);
|
||||
*(.test.unlikely)
|
||||
*(.test .test.*)
|
||||
|
||||
/* Privileged code invulnerable to magic */
|
||||
KEEP(*(.ape.pad.privileged));
|
||||
. = ALIGN(__privileged_end > __privileged_start ? CONSTANT(COMMONPAGESIZE) : 0);
|
||||
/*END: morphable code */
|
||||
__privileged_start = .;
|
||||
*(.privileged .privileged.*)
|
||||
__privileged_end = .;
|
||||
|
||||
KEEP(*(.ape.pad.text))
|
||||
. = ALIGN(. != 0 ? CONSTANT(COMMONPAGESIZE) : 0);
|
||||
/*END: Read Only Data (only needed for initialization) */
|
||||
} :Cod
|
||||
HIDDEN(__privileged_start = .);
|
||||
HIDDEN(__test_end = .);
|
||||
. += 1;
|
||||
*(.privileged)
|
||||
HIDDEN(__privileged_end = .);
|
||||
|
||||
/*BEGIN: Read Only Data */
|
||||
|
||||
.rodata ALIGN(CONSTANT(COMMONPAGESIZE)) : {
|
||||
KEEP(*(.rodata.pytab.0));
|
||||
KEEP(*(.rodata.pytab.1));
|
||||
KEEP(*(.rodata.pytab.2));
|
||||
KEEP(*(.ape.pad.rodata));
|
||||
|
||||
*(.rodata .rodata.*)
|
||||
*(.ubsan.types)
|
||||
*(.ubsan.data)
|
||||
|
||||
__eh_frame_hdr_start_actual = .;
|
||||
*(.eh_frame_hdr)
|
||||
__eh_frame_hdr_end_actual = .;
|
||||
/* Unit Test & Fixture Registry */
|
||||
|
||||
/*BEGIN: Read only data that needn't be mapped after initialization */
|
||||
|
||||
/* Legal Notices */
|
||||
__notices = .;
|
||||
KEEP(*(.notice))
|
||||
BYTE(0);
|
||||
BYTE(10);
|
||||
BYTE(10);
|
||||
#if !defined(IM_FEELING_NAUGHTY) || defined(EMBED_NOTICES)
|
||||
KEEP(*(.commentprologue))
|
||||
KEEP(*(.comment))
|
||||
KEEP(*(.commentepilogue))
|
||||
#endif
|
||||
|
||||
/*BEGIN: read-only data that's only needed for initialization */
|
||||
|
||||
#if SupportsWindows()
|
||||
/* Windows DLL Import Directory */
|
||||
KEEP(*(.idata.ro));
|
||||
KEEP(*(SORT_BY_NAME(.idata.ro.*)))
|
||||
#endif
|
||||
. += 1;
|
||||
|
||||
. = ALIGN(__SIZEOF_POINTER__);
|
||||
PROVIDE_HIDDEN(__init_array_start = .);
|
||||
KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*)
|
||||
SORT_BY_INIT_PRIORITY(.ctors.*)))
|
||||
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(*(.dtors))
|
||||
PROVIDE_HIDDEN(__fini_array_end = .);
|
||||
|
||||
/* Encoded Data Structures w/ Linear Initialization Order */
|
||||
KEEP(*(.initroprologue))
|
||||
KEEP(*(SORT_BY_NAME(.initro.*)))
|
||||
KEEP(*(.initroepilogue))
|
||||
KEEP(*(SORT_BY_NAME(.sort.rodata.*)))
|
||||
. = ALIGN(. != 0 ? CONSTANT(COMMONPAGESIZE) : 0); /* don't delete this line :o */
|
||||
|
||||
/*END: read-only data that's only needed for initialization */
|
||||
|
||||
} :Rom
|
||||
|
||||
/* initialization image for thread-local storage, this is copied */
|
||||
/* out to actual TLS areas at runtime, so just make it read-only */
|
||||
.tdata . : {
|
||||
_tdata_start = .;
|
||||
*(SORT_BY_ALIGNMENT(.tdata))
|
||||
*(SORT_BY_ALIGNMENT(.tdata.*))
|
||||
_tdata_end = .;
|
||||
KEEP(*(.ape.pad.rodata))
|
||||
. = ALIGN(. != 0 ? CONSTANT(COMMONPAGESIZE) : 0);
|
||||
_etext = .;
|
||||
PROVIDE(etext = .);
|
||||
} :Tls :Rom
|
||||
KEEP(*(.ape.pad.text))
|
||||
. = ALIGN(PAGESIZE);
|
||||
HIDDEN(_etext = .);
|
||||
PROVIDE_HIDDEN(etext = .);
|
||||
/*END: Read Only Data (only needed for initialization) */
|
||||
/*END: Read Only Data */
|
||||
|
||||
. = ALIGN(CONSTANT(COMMONPAGESIZE));
|
||||
|
||||
/* this only tells the linker about the layout of uninitialized */
|
||||
/* TLS data, and does not advance the linker's location counter */
|
||||
.tbss : {
|
||||
_tbss_start = .;
|
||||
*(SORT_BY_ALIGNMENT(.tbss))
|
||||
*(SORT_BY_ALIGNMENT(.tbss.*))
|
||||
KEEP(*(.fstls))
|
||||
/* the %fs register is based on this location */
|
||||
_tbss_end = .;
|
||||
} :Tls
|
||||
|
||||
.eh_frame : {
|
||||
__eh_frame_start = .;
|
||||
KEEP(*(.eh_frame))
|
||||
*(.eh_frame.*)
|
||||
__eh_frame_end = .;
|
||||
} :Ram
|
||||
} :Rom
|
||||
|
||||
.data . : {
|
||||
/*BEGIN: Read/Write Data */
|
||||
#if SupportsWindows()
|
||||
KEEP(*(SORT_BY_NAME(.piro.data.sort.iat.*)))
|
||||
#endif
|
||||
/*BEGIN: NT FORK COPYING */
|
||||
KEEP(*(.dataprologue))
|
||||
*(.data .data.*)
|
||||
*(.gnu_extab)
|
||||
*(.gcc_except_table .gcc_except_table.*)
|
||||
*(.exception_ranges*)
|
||||
*(.PyRuntime) /* for python */
|
||||
*(.subrs) /* for emacs */
|
||||
KEEP(*(SORT_BY_NAME(.sort.data.*)))
|
||||
. += . > 0 ? CODE_GRANULE : 0;
|
||||
. += . > 0 ? 1 : 0;
|
||||
|
||||
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
|
||||
__got_start = .;
|
||||
KEEP(*(.gotprologue))
|
||||
*(.got)
|
||||
__got_end = .;
|
||||
KEEP(*(.gotepilogue))
|
||||
|
||||
KEEP(*(.gotpltprologue))
|
||||
*(.got.plt)
|
||||
|
||||
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
|
||||
__init_array_start = .;
|
||||
KEEP(*(.preinit_array))
|
||||
KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*)
|
||||
SORT_BY_INIT_PRIORITY(.ctors.*)))
|
||||
KEEP(*(.init_array))
|
||||
KEEP(*(.ctors))
|
||||
__init_array_end = .;
|
||||
|
||||
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
|
||||
__fini_array_start = .;
|
||||
KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*)
|
||||
SORT_BY_INIT_PRIORITY(.dtors.*)))
|
||||
KEEP(*(.fini_array))
|
||||
KEEP(*(.dtors))
|
||||
__fini_array_end = .;
|
||||
KEEP(*(.gotpltepilogue))
|
||||
|
||||
/*BEGIN: Post-Initialization Read-Only */
|
||||
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
|
||||
. = ALIGN(__SIZEOF_POINTER__);
|
||||
KEEP(*(SORT_BY_NAME(.piro.relo.sort.*)))
|
||||
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
|
||||
PROVIDE_HIDDEN(__relo_end = .);
|
||||
. = ALIGN(__SIZEOF_POINTER__);
|
||||
KEEP(*(SORT_BY_NAME(.piro.data.sort.*)))
|
||||
KEEP(*(.piro.pad.data))
|
||||
*(.igot.plt)
|
||||
KEEP(*(.dataepilogue))
|
||||
. = ALIGN(. != 0 ? CONSTANT(COMMONPAGESIZE) : 0);
|
||||
/*END: NT FORK COPYING */
|
||||
_edata = .;
|
||||
PROVIDE(edata = .);
|
||||
_ezip = .; /* <-- very deprecated */
|
||||
. = ALIGN(PAGESIZE);
|
||||
HIDDEN(_edata = .);
|
||||
PROVIDE_HIDDEN(edata = .);
|
||||
} :Ram
|
||||
|
||||
. = ALIGN(CONSTANT(COMMONPAGESIZE));
|
||||
|
||||
/*END: file content that's loaded by o/s */
|
||||
/*END: file content */
|
||||
/*BEGIN: bss memory that's addressable */
|
||||
|
||||
.bss : {
|
||||
/*BEGIN: NT FORK COPYING */
|
||||
KEEP(*(.bssprologue))
|
||||
.bss . : {
|
||||
KEEP(*(SORT_BY_NAME(.piro.bss.init.*)))
|
||||
*(.piro.bss)
|
||||
KEEP(*(SORT_BY_NAME(.piro.bss.sort.*)))
|
||||
__piro_end = .;
|
||||
. += . > 0 ? CODE_GRANULE : 0;
|
||||
HIDDEN(__piro_end = .);
|
||||
/*END: Post-Initialization Read-Only */
|
||||
|
||||
/* Statically Allocated Empty Space */
|
||||
|
@ -471,17 +383,16 @@ SECTIONS {
|
|||
|
||||
KEEP(*(SORT_BY_NAME(.sort.bss.*)))
|
||||
|
||||
KEEP(*(.bssepilogue))
|
||||
/* eXtreme Low Memory w/ Userspace Remapping */
|
||||
. = ALIGN(0x1000);
|
||||
*(.xlm)
|
||||
. = ALIGN(0x1000);
|
||||
|
||||
. = ALIGN(. != 0 ? CONSTANT(COMMONPAGESIZE) : 0);
|
||||
|
||||
/*END: NT FORK COPYING */
|
||||
. = ALIGN(0x10000); /* for brk()/sbrk() allocation */
|
||||
HIDDEN(_end = .);
|
||||
PROVIDE_HIDDEN(end = .);
|
||||
} :Ram
|
||||
|
||||
. = ALIGN(CONSTANT(COMMONPAGESIZE));
|
||||
_end = .;
|
||||
PROVIDE(end = .);
|
||||
|
||||
/*END: nt addressability guarantee */
|
||||
/*END: bsd addressability guarantee */
|
||||
/*END: linux addressability guarantee */
|
||||
|
@ -508,7 +419,6 @@ SECTIONS {
|
|||
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_line_str 0 : { *(.debug_line_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
|
@ -517,43 +427,19 @@ SECTIONS {
|
|||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
.debug_pubtypes 0 : { *(.debug_pubtypes) }
|
||||
.debug_ranges 0 : { *(.debug_ranges) }
|
||||
.debug_rnglists 0 : { *(.debug_rnglists) }
|
||||
.debug_macro 0 : { *(.debug_macro) }
|
||||
.debug_addr 0 : { *(.debug_addr) }
|
||||
.debug_names 0 : { *(.debug_names) }
|
||||
.debug_loclists 0 : { *(.debug_loclists) }
|
||||
.debug_str_offsets 0 : { *(.debug_str_offsets) }
|
||||
.gnu.attributes 0 : { KEEP(*(.gnu.attributes)) }
|
||||
.GCC.command.line 0 : { *(.GCC.command.line) }
|
||||
|
||||
.zip 0 : {
|
||||
KEEP(*(.zip.file))
|
||||
__zip_cdir_start = .;
|
||||
KEEP(*(.zip.cdir))
|
||||
__zip_cdir_size = . - __zip_cdir_start;
|
||||
KEEP(*(.zip.eocd))
|
||||
}
|
||||
|
||||
/DISCARD/ : {
|
||||
#if !SupportsWindows()
|
||||
*(.idata.ro);
|
||||
*(.idata.ro.*)
|
||||
*(.piro.data.sort.iat.*)
|
||||
#endif
|
||||
*(__patchable_function_entries)
|
||||
*(.note.gnu.property)
|
||||
*(__mcount_loc)
|
||||
*(.rela.dyn)
|
||||
*(.discard)
|
||||
*(.yoink)
|
||||
*(.*)
|
||||
}
|
||||
}
|
||||
|
||||
ape_pe_filealignment = 512;
|
||||
ape_pe_sectionalignment = 4096;
|
||||
ape_pe_sizeofheaders = SIZEOF(.head);
|
||||
ape_pe_sizeofimage = ROUNDUP(_end - __executable_start, ape_pe_sectionalignment);
|
||||
|
||||
PFSTUB8(ape_elf_entry, _start);
|
||||
PFSTUB8(ape_elf_phoff, RVA(ape_phdrs));
|
||||
PFSTUB8(ape_elf_shoff, 0);
|
||||
|
@ -561,81 +447,88 @@ PFSTUB4(ape_elf_phnum, (ape_phdrs_end - ape_phdrs) / 56);
|
|||
PFSTUB4(ape_elf_shnum, 0);
|
||||
PFSTUB4(ape_elf_shstrndx, 0);
|
||||
|
||||
_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);
|
||||
_tdata_align = ALIGNOF(.tdata);
|
||||
_tbss_align = ALIGNOF(.tbss);
|
||||
_tls_align = MAX(TLS_ALIGNMENT, MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)));
|
||||
HIDDEN(__privileged_addr = ROUNDDOWN(__privileged_start, PAGESIZE));
|
||||
HIDDEN(__privileged_size = (ROUNDUP(__privileged_end, PAGESIZE) -
|
||||
ROUNDDOWN(__privileged_start, PAGESIZE)));
|
||||
|
||||
ape_cod_offset = 0;
|
||||
ape_cod_vaddr = ADDR(.head);
|
||||
ape_cod_paddr = LOADADDR(.head);
|
||||
ape_cod_filesz = ADDR(.rodata) - ADDR(.head);
|
||||
ape_cod_memsz = ape_cod_filesz;
|
||||
ape_cod_align = CONSTANT(COMMONPAGESIZE);
|
||||
ape_cod_rva = RVA(ape_cod_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));
|
||||
|
||||
ape_rom_vaddr = ADDR(.rodata);
|
||||
ape_rom_offset = ape_rom_vaddr - __executable_start;
|
||||
ape_rom_paddr = LOADADDR(.rodata);
|
||||
ape_rom_filesz = ADDR(.tbss) - ADDR(.rodata);
|
||||
ape_rom_memsz = ape_rom_filesz;
|
||||
ape_rom_align = CONSTANT(COMMONPAGESIZE);
|
||||
ape_rom_rva = RVA(ape_rom_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));
|
||||
|
||||
ape_ram_vaddr = ADDR(.eh_frame);
|
||||
ape_ram_offset = ape_ram_vaddr - __executable_start;
|
||||
ape_ram_paddr = LOADADDR(.eh_frame);
|
||||
ape_ram_filesz = ADDR(.bss) - ADDR(.eh_frame);
|
||||
ape_ram_memsz = _end - ADDR(.eh_frame);
|
||||
ape_ram_align = CONSTANT(COMMONPAGESIZE);
|
||||
ape_ram_rva = RVA(ape_ram_vaddr);
|
||||
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__);
|
||||
|
||||
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;
|
||||
ape_stack_memsz = DEFINED(ape_stack_memsz) ? ape_stack_memsz : 4 * 1024 * 1024;
|
||||
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));
|
||||
|
||||
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;
|
||||
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));
|
||||
|
||||
ape_text_vaddr = ADDR(.text);
|
||||
ape_text_offset = ape_text_vaddr - __executable_start;
|
||||
ape_text_paddr = LOADADDR(.text);
|
||||
ape_text_filesz = ADDR(.rodata) - ADDR(.text);
|
||||
ape_text_memsz = ape_text_filesz;
|
||||
ape_text_align = CONSTANT(COMMONPAGESIZE);
|
||||
ape_text_rva = RVA(ape_text_vaddr);
|
||||
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);
|
||||
|
||||
__eh_frame_hdr_start = __eh_frame_hdr_end_actual > __eh_frame_hdr_start_actual ? __eh_frame_hdr_start_actual : 0;
|
||||
__eh_frame_hdr_end = __eh_frame_hdr_end_actual > __eh_frame_hdr_start_actual ? __eh_frame_hdr_end_actual : 0;
|
||||
#if SupportsXnu()
|
||||
SHSTUB2(ape_macho_dd_skip, RVA(ape_macho) / 8);
|
||||
SHSTUB2(ape_macho_dd_count, (ape_macho_end - ape_macho) / 8);
|
||||
#endif
|
||||
|
||||
/* 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)
|
||||
? ROUNDUP(ape_loader_end - ape_loader, CONSTANT(COMMONPAGESIZE)) / 64
|
||||
: 0);
|
||||
#if SupportsWindows()
|
||||
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));
|
||||
#endif
|
||||
|
||||
#if SupportsMetal()
|
||||
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);
|
||||
TSSDESCSTUB2(_tss, _tss, _tss_end ? _tss_end - _tss - 1 : 0);
|
||||
HIDDEN(v_ape_realsectors =
|
||||
MIN(REAL_SCRATCH_AREA - IMAGE_BASE_REAL,
|
||||
ROUNDUP(RVA(_edata), 4096)) / 512);
|
||||
HIDDEN(v_ape_realpages = v_ape_realsectors / (4096 / 512));
|
||||
HIDDEN(v_ape_highsectors =
|
||||
(ROUNDUP(RVA(_edata), 512) / 512) - v_ape_realsectors);
|
||||
#endif
|
||||
|
||||
/* ZIP End of Central Directory header */
|
||||
#define ZIPCONST(NAME, VAL) HIDDEN(NAME = DEFINED(__zip_start) ? VAL : 0);
|
||||
ZIPCONST(v_zip_cdoffset, __zip_start - IMAGE_BASE_VIRTUAL);
|
||||
ZIPCONST(v_zip_cdirsize, __zip_end - __zip_start);
|
||||
ZIPCONST(v_zip_records, v_zip_cdirsize / kZipCdirHdrLinkableSize);
|
||||
ZIPCONST(v_zip_commentsize, _edata - __zip_end - kZipCdirHdrMinSize);
|
||||
|
||||
#if SupportsXnu()
|
||||
/* Generates deterministic ID. */
|
||||
#define PHI 0x9e3779b9925d4c17
|
||||
|
@ -654,8 +547,19 @@ TSSDESCSTUB2(_tss, _tss, _tss_end ? _tss_end - _tss - 1 : 0);
|
|||
KMH(ape_uuid1, X); \
|
||||
XORSHIFT(ape_uuid2, X); \
|
||||
KMH(ape_uuid2, X)
|
||||
ape_uuid1 = 88172645463325252;
|
||||
ape_uuid2 = 88172645463325252;
|
||||
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);
|
||||
|
@ -664,10 +568,13 @@ 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);
|
||||
|
@ -681,14 +588,7 @@ CHURN(ape_rom_memsz);
|
|||
CHURN(ape_rom_offset);
|
||||
CHURN(ape_rom_paddr);
|
||||
CHURN(ape_rom_rva);
|
||||
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);
|
||||
CHURN(ape_rom_vaddr);
|
||||
CHURN(ape_text_align);
|
||||
CHURN(ape_text_filesz);
|
||||
CHURN(ape_text_memsz);
|
||||
|
@ -700,12 +600,12 @@ CHURN(ADDR(.bss));
|
|||
CHURN(_start);
|
||||
CHURN(ape_phdrs);
|
||||
#if SupportsMetal()
|
||||
CHURN(v_ape_allsectors);
|
||||
CHURN(v_ape_realsectors);
|
||||
#endif
|
||||
#if SupportsXnu()
|
||||
CHURN(ape_macho);
|
||||
#endif
|
||||
#if SupportsWindows() || SupportsMetal()
|
||||
#if SupportsWindows()
|
||||
CHURN(ape_mz);
|
||||
CHURN(ape_pe);
|
||||
CHURN(ape_pe_offset);
|
||||
|
@ -718,32 +618,6 @@ CHURN(WinMain);
|
|||
#endif /* SupportsWindows() */
|
||||
#endif /* SupportsXnu() */
|
||||
|
||||
#if SupportsWindows() || SupportsMetal()
|
||||
#define LINK_WINDOWS (SupportsWindows() && !DEFINED(EfiMain))
|
||||
PFSTUB4(ape_pe_offset, ape_pe - ape_mz);
|
||||
ape_pe_optsz = ape_pe_sections - (ape_pe + 24);
|
||||
ASSERT(ape_pe_optsz % 8 == 0, "SizeOfOptionalHeader must be multiple of 8");
|
||||
ape_pe_shnum = (ape_pe_sections_end - ape_pe_sections) / 40;
|
||||
ape_pe_base = IMAGE_BASE_VIRTUAL;
|
||||
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;
|
||||
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;
|
||||
#endif
|
||||
|
||||
#if SupportsXnu()
|
||||
SHSTUB2(ape_macho_dd_skip, RVA(ape_macho) / 8);
|
||||
SHSTUB2(ape_macho_dd_count, (ape_macho_end - ape_macho) / 8);
|
||||
#endif
|
||||
|
||||
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");
|
||||
|
@ -754,16 +628,11 @@ ASSERT(((DEFINED(__init_rodata_end) ? __init_rodata_end : 0) %
|
|||
ASSERT((!DEFINED(ape_grub) ? 1 : RVA(ape_grub) < 8192),
|
||||
"grub stub needs to be in first 8kb of image");
|
||||
|
||||
ASSERT(IS2POW(ape_stack_memsz),
|
||||
"ape_stack_memsz must be a two power");
|
||||
ASSERT(DEFINED(_start) || DEFINED(_start16),
|
||||
"please link a _start() or _start16() entrypoint");
|
||||
|
||||
ASSERT(ape_stack_vaddr % ape_stack_memsz == 0,
|
||||
"ape_stack_vaddr must have ape_stack_memsz alignment; try using STATIC_STACK_ADDR(0x700000040000 & -ape_stack_memsz);");
|
||||
|
||||
ASSERT(ALIGNOF(.tdata) <= TLS_ALIGNMENT && ALIGNOF(.tbss) <= TLS_ALIGNMENT,
|
||||
"_Thread_local _Alignof can't exceed TLS_ALIGNMENT");
|
||||
|
||||
ASSERT(DEFINED(main), "main() function not defined");
|
||||
ASSERT(!DEFINED(_start16) || REAL(_end) < 65536,
|
||||
"ape won't support non-tiny real mode programs");
|
||||
|
||||
/* Let's not be like Knight Capital. */
|
||||
/* NOCROSSREFS_TO(.test .text) */
|
||||
|
|
54
ape/ape.mk
Normal file
54
ape/ape.mk
Normal file
|
@ -0,0 +1,54 @@
|
|||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
||||
#
|
||||
# OVERVIEW
|
||||
#
|
||||
# αcτµαlly pδrταblε εxεcµταblε
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This file defines the libraries, runtimes, and build rules needed to
|
||||
# create executables from your Linux workstation that'll run anywhere.
|
||||
# Loading this package will make certain systemic modifications to the
|
||||
# build like turning off the System V "Red Zone" optimization, because
|
||||
# αcτµαlly pδrταblε εxεcµταblεs need to be able to run in kernelspace.
|
||||
|
||||
PKGS += APE
|
||||
|
||||
APE = $(APE_DEPS) \
|
||||
$(APE_OBJS) \
|
||||
o/$(MODE)/ape/ape.lds
|
||||
|
||||
APELINK = \
|
||||
ACTION=LINK.ape \
|
||||
$(COMPILE) \
|
||||
$(LINK) \
|
||||
$(LINKARGS) \
|
||||
$(OUTPUT_OPTION)
|
||||
|
||||
APE_FILES := $(wildcard ape/*.*)
|
||||
APE_HDRS = $(filter %.h,$(APE_FILES))
|
||||
APE_INCS = $(filter %.inc,$(APE_FILES))
|
||||
APE_SRCS = $(filter %.S,$(APE_FILES))
|
||||
APE_OBJS = $(APE_SRCS:%.S=o/$(MODE)/%.o)
|
||||
APE_DEPS = $(APE_LIB)
|
||||
APE_CHECKS = $(APE_HDRS:%=o/%.ok)
|
||||
|
||||
o/$(MODE)/ape/ape.lds: \
|
||||
ape/ape.lds \
|
||||
ape/config.h \
|
||||
ape/macros.internal.h \
|
||||
libc/dce.h \
|
||||
libc/zip.h
|
||||
|
||||
o/ape/idata.inc: \
|
||||
ape/idata.internal.h \
|
||||
ape/relocations.h
|
||||
|
||||
$(APE_OBJS): $(BUILD_FILES) \
|
||||
ape/ape.mk
|
||||
|
||||
.PHONY: o/$(MODE)/ape
|
||||
o/$(MODE)/ape: $(APE) \
|
||||
$(APE_CHECKS) \
|
||||
o/$(MODE)/ape/lib
|
|
@ -1,180 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
PROG=${0##*/}
|
||||
MODE=${MODE:-$m}
|
||||
TMPDIR=${TMPDIR:-/tmp}
|
||||
COSMO=${COSMO:-/opt/cosmo}
|
||||
COSMOS=${COSMOS:-/opt/cosmos}
|
||||
|
||||
if [ ! -f ape/loader.c ]; then
|
||||
cd "$COSMO" || exit
|
||||
fi
|
||||
|
||||
if [ -x .cosmocc/current/bin/make ]; then
|
||||
MAKE=.cosmocc/current/bin/make
|
||||
else
|
||||
MAKE=make
|
||||
fi
|
||||
|
||||
if [ "$(id -u)" -eq 0 ]; then
|
||||
SUDO=
|
||||
elif command -v sudo >/dev/null 2>&1; then
|
||||
SUDO=sudo
|
||||
elif command -v doas >/dev/null 2>&1; then
|
||||
SUDO=doas
|
||||
else
|
||||
echo "need root or sudo" >&2
|
||||
exit
|
||||
fi
|
||||
|
||||
if command -v install >/dev/null 2>&1; then
|
||||
if [ x"$(uname -s)" = xLinux ]; then
|
||||
INSTALL="install -o root -g root -m 755"
|
||||
else
|
||||
INSTALL="install -o root -g wheel -m 755"
|
||||
fi
|
||||
else
|
||||
INSTALL="cp -f"
|
||||
fi
|
||||
|
||||
echo "Actually Portable Executable (APE) Installer" >&2
|
||||
echo "Author: Justine Tunney <jtunney@gmail.com>" >&2
|
||||
|
||||
# special installation process for apple silicon
|
||||
if [ x"$(uname -s)" = xDarwin ] && [ x"$(uname -m)" = xarm64 ]; then
|
||||
echo "cc -O -o $TMPDIR/ape.$$ ape/ape-m1.c" >&2
|
||||
cc -O -o "$TMPDIR/ape.$$" ape/ape-m1.c || exit
|
||||
trap 'rm "$TMPDIR/ape.$$"' EXIT
|
||||
if [ ! -d /usr/local/bin ]; then
|
||||
echo "$SUDO mkdir -p /usr/local/bin" >&2
|
||||
$SUDO mkdir -p /usr/local/bin || exit
|
||||
fi
|
||||
echo "$SUDO $INSTALL $TMPDIR/ape.$$ /usr/local/bin/ape" >&2
|
||||
$SUDO $INSTALL "$TMPDIR/ape.$$" /usr/local/bin/ape || exit
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ x"$(uname -m)" = xarm64 ] || [ x"$(uname -m)" = xaarch64 ]; then
|
||||
MODE=aarch64
|
||||
EXT=elf
|
||||
BEXT=aarch64
|
||||
elif [ x"$(uname -m)" = xx86_64 ]; then
|
||||
MODE=
|
||||
if [ x"$(uname -s)" = xDarwin ]; then
|
||||
EXT=macho
|
||||
else
|
||||
EXT=elf
|
||||
fi
|
||||
BEXT=$EXT
|
||||
else
|
||||
echo "unsupported architecture $(uname -m)" >&2
|
||||
exit
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
# INSTALL APE LOADER SYSTEMWIDE
|
||||
|
||||
if [ -f o/$MODE/depend ] && $MAKE -j8 o/$MODE/ape; then
|
||||
echo "successfully recompiled ape loader" >&2
|
||||
elif [ -x o/$MODE/ape/ape.$EXT ]; then
|
||||
echo "using ape loader you compiled earlier" >&2
|
||||
elif [ -d build/bootstrap ]; then
|
||||
# if make isn't being used then it's unlikely the user changed the sources
|
||||
# in that case the prebuilt binaries should be completely up-to-date
|
||||
echo "using prebuilt ape loader from cosmo repo" >&2
|
||||
mkdir -p o/$MODE/ape || exit
|
||||
cp -af build/bootstrap/ape.$BEXT o/$MODE/ape/ape.$EXT || exit
|
||||
else
|
||||
echo "no cosmopolitan libc repository here" >&2
|
||||
echo "fetching ape loader from justine.lol" >&2
|
||||
mkdir -p o/$MODE/ape || exit
|
||||
if command -v wget >/dev/null 2>&1; then
|
||||
wget -qO o/$MODE/ape/ape.$EXT https://justine.lol/ape.$BEXT || exit
|
||||
else
|
||||
curl -Rso o/$MODE/ape/ape.$EXT https://justine.lol/ape.$BEXT || exit
|
||||
fi
|
||||
chmod +x o/$MODE/ape/ape.$EXT || exit
|
||||
fi
|
||||
|
||||
if ! [ /usr/bin/ape -nt o/$MODE/ape/ape.$EXT ]; then
|
||||
echo >&2
|
||||
echo "installing o/$MODE/ape/ape.$EXT to /usr/bin/ape" >&2
|
||||
echo "$SUDO $INSTALL o/$MODE/ape/ape.$EXT /usr/bin/ape" >&2
|
||||
$SUDO $INSTALL o/$MODE/ape/ape.$EXT /usr/bin/ape || exit
|
||||
echo "done" >&2
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
# REGISTER APE LOADER WITH BINFMT_MISC TOO (LINUX-ONLY)
|
||||
|
||||
if [ x"$(uname -s)" = xLinux ]; then
|
||||
|
||||
if [ -e /proc/sys/fs/binfmt_misc/APE ]; then
|
||||
echo >&2
|
||||
echo it looks like APE is already registered with binfmt_misc >&2
|
||||
echo To reinstall please run ape/apeuninstall.sh first >&2
|
||||
echo please check that it is mapped to ape not /bin/sh >&2
|
||||
echo cat /proc/sys/fs/binfmt_misc/APE >&2
|
||||
cat /proc/sys/fs/binfmt_misc/APE >&2
|
||||
exit
|
||||
fi
|
||||
|
||||
if ! [ -e /proc/sys/fs/binfmt_misc ]; then
|
||||
echo >&2
|
||||
echo loading binfmt_misc into your kernel >&2
|
||||
echo you may need to edit configs to persist across reboot >&2
|
||||
echo $SUDO modprobe binfmt_misc >&2
|
||||
$SUDO modprobe binfmt_misc || exit
|
||||
echo done >&2
|
||||
fi
|
||||
|
||||
if ! [ -e /proc/sys/fs/binfmt_misc/register ]; then
|
||||
echo >&2
|
||||
echo mounting binfmt_misc into your kernel >&2
|
||||
echo you may need to edit configs to persist across reboot >&2
|
||||
echo $SUDO mount -t binfmt_misc none /proc/sys/fs/binfmt_misc >&2
|
||||
$SUDO mount -t binfmt_misc none /proc/sys/fs/binfmt_misc || exit
|
||||
echo done >&2
|
||||
fi
|
||||
|
||||
uname_r="$(uname -r)"
|
||||
if printf '%s\n%s\n' 5.12 "$uname_r" | sort -CV; then
|
||||
FLAGS=FP
|
||||
else
|
||||
FLAGS=F
|
||||
fi
|
||||
|
||||
echo >&2
|
||||
echo registering APE with binfmt_misc >&2
|
||||
echo you may need to edit configs to persist across reboot >&2
|
||||
echo '$SUDO sh -c "echo '"'"':APE:M::MZqFpD::/usr/bin/ape:'"$FLAGS'"' >/proc/sys/fs/binfmt_misc/register"' >&2
|
||||
$SUDO sh -c "echo ':APE:M::MZqFpD::/usr/bin/ape:$FLAGS' >/proc/sys/fs/binfmt_misc/register" || exit
|
||||
echo '$SUDO sh -c "echo '"'"':APE-jart:M::jartsr::/usr/bin/ape:'"$FLAGS'"' >/proc/sys/fs/binfmt_misc/register"' >&2
|
||||
$SUDO sh -c "echo ':APE-jart:M::jartsr::/usr/bin/ape:$FLAGS' >/proc/sys/fs/binfmt_misc/register" || exit
|
||||
echo done >&2
|
||||
|
||||
if [ x"$(cat /proc/sys/fs/binfmt_misc/status)" = xdisabled ]; then
|
||||
echo >&2
|
||||
echo enabling binfmt_misc >&2
|
||||
echo you may need to edit configs to persist across reboot >&2
|
||||
echo $SUDO sh -c 'echo 1 >/proc/sys/fs/binfmt_misc/status' >&2
|
||||
$SUDO sh -c 'echo 1 >/proc/sys/fs/binfmt_misc/status' || exit
|
||||
echo done >&2
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
|
||||
{
|
||||
echo
|
||||
echo "------------------------------------------------------------------"
|
||||
echo
|
||||
echo "APE INSTALL COMPLETE"
|
||||
echo
|
||||
echo "If you decide to uninstall APE later on"
|
||||
echo "you may do so using ape/apeuninstall.sh"
|
||||
echo
|
||||
echo "Enjoy your APE loader (>'.')>"
|
||||
echo
|
||||
} >&2
|
|
@ -1,68 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
PROG=${0##*/}
|
||||
MODE=${MODE:-$m}
|
||||
COSMO=${COSMO:-/opt/cosmo}
|
||||
COSMOS=${COSMOS:-/opt/cosmos}
|
||||
|
||||
if [ ! -f ape/loader.c ]; then
|
||||
cd "$COSMO" || exit
|
||||
fi
|
||||
|
||||
if [ "$UID" = "0" ]; then
|
||||
SUDO=
|
||||
elif command -v sudo >/dev/null 2>&1; then
|
||||
SUDO=sudo
|
||||
elif command -v doas >/dev/null 2>&1; then
|
||||
SUDO=doas
|
||||
else
|
||||
echo "need root or sudo" >&2
|
||||
exit
|
||||
fi
|
||||
|
||||
{
|
||||
echo
|
||||
echo "APE Uninstaller intends to run (in pseudo-shell)"
|
||||
echo
|
||||
echo " sudo echo -1 into /proc/sys/fs/binfmt_misc/APE*"
|
||||
echo " sudo rm -f /usr/bin/ape ~/.ape /tmp/.ape # etc."
|
||||
echo
|
||||
echo "You may then use ape/apeinstall.sh to reinstall it"
|
||||
echo
|
||||
} >&2
|
||||
|
||||
set -ex
|
||||
for f in /proc/sys/fs/binfmt_misc/APE*; do
|
||||
if [ -f $f ]; then
|
||||
$SUDO sh -c "echo -1 >$f" || exit
|
||||
fi
|
||||
done
|
||||
|
||||
# system installation
|
||||
if [ -f /usr/bin/ape ]; then
|
||||
$SUDO rm -f /usr/bin/ape
|
||||
fi
|
||||
if [ -f /usr/local/bin/ape ]; then
|
||||
$SUDO rm -f /usr/local/bin/ape
|
||||
fi
|
||||
|
||||
# legacy installations
|
||||
rm -f o/tmp/ape /tmp/ape "${TMPDIR:-/tmp}/ape"
|
||||
|
||||
# ad-hoc installations
|
||||
for x in .ape \
|
||||
.ape-1.1 \
|
||||
.ape-1.3 \
|
||||
.ape-1.4 \
|
||||
.ape-1.5 \
|
||||
.ape-1.6 \
|
||||
.ape-1.7 \
|
||||
.ape-1.8 \
|
||||
.ape-1.9 \
|
||||
.ape-1.10; do
|
||||
rm -f \
|
||||
~/$x \
|
||||
/tmp/$x \
|
||||
o/tmp/$x \
|
||||
"${TMPDIR:-/tmp}/$x"
|
||||
done
|
118
ape/config.h
Normal file
118
ape/config.h
Normal file
|
@ -0,0 +1,118 @@
|
|||
#ifndef APE_CONFIG_H_
|
||||
#define APE_CONFIG_H_
|
||||
#include "ape/relocations.h"
|
||||
#include "libc/macros.h"
|
||||
|
||||
/*
|
||||
* Post-Initialization Read-Only Code Size Threshold.
|
||||
*
|
||||
* An executable needs to have at least this much code, before the
|
||||
* linker adds non-mandatory 4kb alignments. The benefit is better
|
||||
* memory protection. The tradeoff is sparser binaries.
|
||||
*/
|
||||
#ifndef APE_PIRO_THRESHOLD
|
||||
#ifdef CONFIG_DBG
|
||||
#define APE_PIRO_THRESHOLD 0x1000
|
||||
#else
|
||||
#define APE_PIRO_THRESHOLD 0x10000
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef METAL_STDIN
|
||||
#define METAL_STDIN COM1
|
||||
#endif
|
||||
#ifndef METAL_STDOUT
|
||||
#define METAL_STDOUT COM1
|
||||
#endif
|
||||
#ifndef METAL_STDERR
|
||||
#define METAL_STDERR COM1
|
||||
#endif
|
||||
|
||||
#ifndef VIDYA_MODE
|
||||
#define VIDYA_MODE VIDYA_MODE_CGA
|
||||
#endif
|
||||
|
||||
/* FPU Control Word (x87) Exception Masks
|
||||
@see Intel Manual V1 §8.1.5
|
||||
|
||||
IM: Invalid Operation ───────────────┐
|
||||
DM: Denormal Operand ───────────────┐│
|
||||
ZM: Zero Divide ───────────────────┐││
|
||||
OM: Overflow ─────────────────────┐│││
|
||||
UM: Underflow ───────────────────┐││││
|
||||
PM: Precision ──────────────────┐│││││
|
||||
PC: Precision Control ────────┐ ││││││
|
||||
{float,∅,double,long double} │ ││││││
|
||||
RC: Rounding Control ───────┐ │ ││││││
|
||||
{even, →-∞, →+∞, →0} │┌┤ ││││││
|
||||
┌┤││ ││││││
|
||||
d││││rr││││││*/
|
||||
#define X87_NORMAL 0b000000000001101111111
|
||||
#define X87_DTOA 0b000000000001000000000
|
||||
#define X87_DTOA_MASK 0b000000000001100000000
|
||||
#ifndef X87_DEFAULT
|
||||
#define X87_DEFAULT X87_NORMAL
|
||||
#endif
|
||||
|
||||
#ifndef UART_BAUD_RATE
|
||||
#define UART_BAUD_RATE 9600 /* bits per second ∈ [50,115200] */
|
||||
#endif
|
||||
#define UART_CONF_DLR (1843200 /*hz*/ / 16 /*wut*/ / (UART_BAUD_RATE))
|
||||
#ifndef UART_CONF_IIR
|
||||
/* ┌interrupt trigger level {1,4,8,14}
|
||||
│ ┌enable 64 byte fifo (UART 16750+)
|
||||
│ │ ┌select dma mode
|
||||
│ │ │┌clear transmit fifo
|
||||
│ │ ││┌clear receive fifo
|
||||
├┐│ │││┌enable fifos*/
|
||||
#define UART_CONF_IIR 0b00000000
|
||||
#endif
|
||||
#ifndef UART_CONF_LCR
|
||||
/* ┌dlab: flips configuration mode state
|
||||
│┌enable break signal
|
||||
││ ┌parity {none,odd,even,high,low}
|
||||
││ │ ┌extra stop bit
|
||||
││ │ │┌data word length (bits+5)
|
||||
││┌┴┐│├┐*/
|
||||
#define UART_CONF_LCR 0b01000011
|
||||
#endif
|
||||
|
||||
#define XLM(VAR) (XLM_BASE_REAL + XLM_##VAR)
|
||||
#define XLMV(VAR) (__xlm + XLM_##VAR)
|
||||
#define XLM_BASE_REAL 0x1000
|
||||
#define XLM_E820 0
|
||||
#define XLM_E820_SIZE 0x2000
|
||||
#define XLM_BIOS_DATA_AREA 0x2000
|
||||
#define XLM_BIOS_DATA_AREA_SIZE 256
|
||||
#define XLM_DRIVE_BASE_TABLE 0x2200 /* drive values are contiguous */
|
||||
#define XLM_DRIVE_BASE_TABLE_SIZE 11
|
||||
#define XLM_DRIVE_TYPE 0x220b
|
||||
#define XLM_DRIVE_TYPE_SIZE 1
|
||||
#define XLM_DRIVE_LAST_SECTOR 0x220c /* 1-based inclusive, e.g. 18 */
|
||||
#define XLM_DRIVE_LAST_SECTOR_SIZE 1
|
||||
#define XLM_DRIVE_LAST_CYLINDER 0x220d /* 0-based incl, e.g. 79 */
|
||||
#define XLM_DRIVE_LAST_CYLINDER_SIZE 2
|
||||
#define XLM_DRIVE_ATTACHED 0x220f
|
||||
#define XLM_DRIVE_ATTACHED_SIZE 1
|
||||
#define XLM_DRIVE_LAST_HEAD 0x2210 /* 0-based inclusive, e.g. 1 */
|
||||
#define XLM_DRIVE_LAST_HEAD_SIZE 1
|
||||
#define XLM_DRIVE 0x2211
|
||||
#define XLM_DRIVE_SIZE 1
|
||||
#define XLM_HAVEEXTMEMKB 0x2212
|
||||
#define XLM_HAVEEXTMEMKB_SIZE 4
|
||||
#define XLM_VIDEO_POSITION_FAR_POINTER 0x2216 /* video cursor far pointer */
|
||||
#define XLM_VIDEO_POSITION_FAR_POINTER_SIZE 4
|
||||
#define XLM_PAGE_TABLE_STACK_POINTER 0x2220
|
||||
#define XLM_PAGE_TABLE_STACK_POINTER_SIZE 8
|
||||
#define XLM_BADIDT 0x2230
|
||||
#define XLM_BADIDT_SIZE 6
|
||||
#define XLM_LOADSTATE 0x2240
|
||||
#define XLM_LOADSTATE_SIZE 8
|
||||
#define XLM_SIZE ROUNDUP(XLM_LOADSTATE + XLM_LOADSTATE_SIZE, 0x1000)
|
||||
#define IMAGE_BASE_REAL (XLM_BASE_REAL + XLM_SIZE)
|
||||
|
||||
#if !defined(__LINKER__) && !defined(__ASSEMBLER__)
|
||||
extern char __xlm[XLM_SIZE];
|
||||
#endif /* !defined(__LINKER__) && !defined(__ASSEMBLER__) */
|
||||
|
||||
#endif /* APE_CONFIG_H_ */
|
1279
ape/etc/bochsrc.dbg
Normal file
1279
ape/etc/bochsrc.dbg
Normal file
File diff suppressed because it is too large
Load diff
1294
ape/etc/bochsrc.ffs
Normal file
1294
ape/etc/bochsrc.ffs
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,5 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│ vi: set noet ft=asm ts=8 sw=8 fenc=utf-8 :vi │
|
||||
│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
|
@ -31,84 +31,80 @@
|
|||
// @see libc/nt/master.sh
|
||||
// @see ape/ape.lds
|
||||
// @see winimp
|
||||
.macro .imp dll:req fn:req actual:req
|
||||
#ifdef __x86_64__
|
||||
.dll "\dll"
|
||||
.section ".piro.data.sort.iat.2.\dll\().2.\actual","aw",@progbits
|
||||
.macro .imp dll:req fn:req actual:req hint
|
||||
.dll \dll
|
||||
.section .piro.data.sort.iat.2.\dll\().2.\actual,"aw",@progbits
|
||||
.type \fn,@object
|
||||
.align __SIZEOF_POINTER__
|
||||
\fn: .quad RVA(("\dll\().\actual"))
|
||||
\fn: .quad RVA((\dll\().\actual))
|
||||
.size \fn,.-\fn
|
||||
.globl \fn
|
||||
.hidden \fn
|
||||
.previous
|
||||
.section ".idata.ro.ilt.\dll\().2.\actual","a",@progbits
|
||||
"idata.ilt.\dll\().\actual":
|
||||
.quad RVA("\dll\().\actual")
|
||||
.type "idata.ilt.\dll\().\actual",@object
|
||||
.size "idata.ilt.\dll\().\actual",.-"idata.ilt.\dll\().\actual"
|
||||
.section .idata.ro.ilt.\dll\().2.\actual,"a",@progbits
|
||||
.Lidata.ilt.\dll\().\actual:
|
||||
.quad RVA((\dll\().\actual))
|
||||
.type .Lidata.ilt.\dll\().\actual,@object
|
||||
.size .Lidata.ilt.\dll\().\actual,.-.Lidata.ilt.\dll\().\actual
|
||||
.previous
|
||||
.section ".idata.ro.hnt.\dll\().2.\actual","a",@progbits
|
||||
"\dll\().\actual":
|
||||
.short 0 // hint
|
||||
.section .idata.ro.hnt.\dll\().2.\actual,"a",@progbits
|
||||
\dll\().\actual:
|
||||
.ifnb \hint # hint i.e. guess function ordinal
|
||||
.short \hint
|
||||
.else
|
||||
.short 0
|
||||
.endif
|
||||
.asciz "\actual"
|
||||
.align 2 // documented requirement
|
||||
.globl "\dll\().\actual"
|
||||
.hidden "\dll\().\actual"
|
||||
.type "\dll\().\actual",@object
|
||||
.size "\dll\().\actual",.-"\dll\().\actual"
|
||||
.align 2 # documented requirement
|
||||
.globl \dll\().\actual
|
||||
.hidden \dll\().\actual
|
||||
.type \dll\().\actual,@object
|
||||
.size \dll\().\actual,.-\dll\().\actual
|
||||
.previous
|
||||
#else
|
||||
.section ".data.nt.\actual","aw",@progbits
|
||||
.globl "\fn"
|
||||
.balign 8
|
||||
.weak "\actual"
|
||||
"\fn": .quad "\actual"
|
||||
#endif
|
||||
.endm
|
||||
|
||||
// Defines DLL import.
|
||||
// @note this is an implementation detail of .imp
|
||||
.macro .dll name:req
|
||||
.section ".idata.ro.idt.2.\name","aG",@progbits,"\name",comdat
|
||||
.equ ".Lidata.idt.\name",.
|
||||
.long RVA("idata.ilt.\name") // ImportLookupTable
|
||||
.long 0 // TimeDateStamp
|
||||
.long 0 // ForwarderChain
|
||||
.long RVA(".Lidata.str.\name") // DllNameRva
|
||||
.long RVA("idata.iat.\name") // ImportAddressTable
|
||||
.type ".Lidata.idt.\name",@object
|
||||
.size ".Lidata.idt.\name",.-".Lidata.idt.\name"
|
||||
.section .idata.ro.idt.2.\name,"aG",@progbits,\name,comdat
|
||||
.equ .Lidata.idt.\name,.
|
||||
.long RVA(idata.ilt.\name) # ImportLookupTable
|
||||
.long 0 # TimeDateStamp
|
||||
.long 0 # ForwarderChain
|
||||
.long RVA(.Lidata.str.\name) # DllNameRva
|
||||
.long RVA(idata.iat.\name) # ImportAddressTable
|
||||
.type .Lidata.idt.\name,@object
|
||||
.size .Lidata.idt.\name,.-.Lidata.idt.\name
|
||||
.previous
|
||||
.section ".idata.ro.ilt.\name\().1","aG",@progbits,"\name",comdat
|
||||
.balign __SIZEOF_POINTER__
|
||||
.type "idata.ilt.\name",@object
|
||||
"idata.ilt.\name":
|
||||
.section .idata.ro.ilt.\name\().1,"aG",@progbits,\name,comdat
|
||||
.align __SIZEOF_POINTER__
|
||||
.type idata.ilt.\name,@object
|
||||
idata.ilt.\name:
|
||||
.previous/*
|
||||
...
|
||||
decentralized content
|
||||
...
|
||||
*/.section ".idata.ro.ilt.\name\().3","aG",@progbits,"\name",comdat
|
||||
*/.section .idata.ro.ilt.\name\().3,"aG",@progbits,\name,comdat
|
||||
.quad 0
|
||||
.previous
|
||||
.section ".idata.ro.hnt.\name\().1","aG",@progbits,"\name",comdat
|
||||
.balign __SIZEOF_POINTER__
|
||||
.type "idata.hnt.\name",@object
|
||||
.equ "idata.hnt.\name",.
|
||||
.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",@progbits,"\name",comdat
|
||||
.balign __SIZEOF_POINTER__
|
||||
.type "idata.iat.\name",@object
|
||||
"idata.iat.\name":
|
||||
.section .piro.data.sort.iat.2.\name\().1,"awG",@progbits,\name,comdat
|
||||
.align __SIZEOF_POINTER__
|
||||
.type idata.iat.\name,@object
|
||||
idata.iat.\name:
|
||||
.previous/*
|
||||
...
|
||||
decentralized content
|
||||
...
|
||||
*/.section ".piro.data.sort.iat.2.\name\().3","awG",@progbits,"\name",comdat
|
||||
*/.section .piro.data.sort.iat.2.\name\().3,"awG",@progbits,\name,comdat
|
||||
.quad 0
|
||||
.previous
|
||||
.section .rodata.str1.1,"aSM",@progbits,1
|
||||
".Lidata.str.\name":
|
||||
.Lidata.str.\name:
|
||||
.asciz "\name\().dll"
|
||||
.previous
|
||||
.endm
|
||||
|
|
90
ape/launch.S
90
ape/launch.S
|
@ -1,90 +0,0 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│ vi: set noet ft=asm ts=8 sw=8 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/macros.h"
|
||||
|
||||
// Calls _start() function of loaded program.
|
||||
//
|
||||
// When the program entrypoint is called, all registers shall be
|
||||
// cleared, with the exception of (1) %rdi will be equal to %rsp
|
||||
// on FreeBSD and (2) %cl will contain the detected host OS code
|
||||
//
|
||||
// We clear all the general registers we can to have some wiggle
|
||||
// room, to extend the behavior of this loader in the future. We
|
||||
// don't need to clear the XMM registers because your APE loader
|
||||
// should be compiled using gcc/clang's -mgeneral-regs-only flag
|
||||
//
|
||||
// @param rdi is passed through as-is
|
||||
// @param rsi is address of entrypoint (becomes zero)
|
||||
// @param rdx is passed through as-is
|
||||
// @param rcx is passed through as-is
|
||||
// @param r8 is stack pointer (becomes zero)
|
||||
// @noreturn
|
||||
Launch:
|
||||
#ifdef __aarch64__
|
||||
|
||||
mov x16,x1
|
||||
mov sp,x4
|
||||
mov x1,0
|
||||
mov x4,0
|
||||
mov x5,0
|
||||
mov x6,0
|
||||
mov x7,0
|
||||
mov x8,0
|
||||
mov x9,0
|
||||
mov x10,0
|
||||
mov x11,0
|
||||
mov x12,0
|
||||
mov x13,0
|
||||
mov x14,0
|
||||
mov x15,0
|
||||
mov x17,0
|
||||
mov x19,0
|
||||
mov x20,0
|
||||
mov x21,0
|
||||
mov x22,0
|
||||
mov x23,0
|
||||
mov x24,0
|
||||
mov x25,0
|
||||
mov x26,0
|
||||
mov x27,0
|
||||
mov x28,0
|
||||
mov x29,0
|
||||
mov x30,0
|
||||
br x16
|
||||
|
||||
#else
|
||||
|
||||
mov %r8,%rsp
|
||||
xor %r8d,%r8d
|
||||
xor %r9d,%r9d
|
||||
xor %r10d,%r10d
|
||||
xor %r11d,%r11d
|
||||
xor %r12d,%r12d
|
||||
xor %r13d,%r13d
|
||||
xor %r14d,%r14d
|
||||
xor %r15d,%r15d
|
||||
push %rsi
|
||||
xor %esi,%esi
|
||||
xor %ebp,%ebp
|
||||
xor %ebx,%ebx
|
||||
xor %eax,%eax
|
||||
ret
|
||||
|
||||
#endif
|
||||
.endfn Launch,globl
|
45
ape/lib/apelib.mk
Normal file
45
ape/lib/apelib.mk
Normal file
|
@ -0,0 +1,45 @@
|
|||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
||||
|
||||
PKGS += APE_LIB
|
||||
|
||||
APE_LIB_ARTIFACTS += APE_LIB_A
|
||||
APE_LIB = $(APE_LIB_A_DEPS) $(APE_LIB_A)
|
||||
APE_LIB_A = o/$(MODE)/ape/lib/apelib.a
|
||||
APE_LIB_A_FILES := $(wildcard ape/lib/*)
|
||||
APE_LIB_A_HDRS = $(filter %.h,$(APE_LIB_A_FILES))
|
||||
APE_LIB_A_SRCS_S = $(filter %.S,$(APE_LIB_A_FILES))
|
||||
APE_LIB_A_SRCS_C = $(filter %.c,$(APE_LIB_A_FILES))
|
||||
|
||||
APE_LIB_A_SRCS = \
|
||||
$(APE_LIB_A_SRCS_S) \
|
||||
$(APE_LIB_A_SRCS_C)
|
||||
|
||||
APE_LIB_A_OBJS = \
|
||||
$(APE_LIB_A_SRCS_S:%.S=o/$(MODE)/%.o) \
|
||||
$(APE_LIB_A_SRCS_C:%.c=o/$(MODE)/%.o)
|
||||
|
||||
APE_LIB_A_DIRECTDEPS = \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_INTRIN \
|
||||
LIBC_STR \
|
||||
LIBC_STUBS
|
||||
|
||||
APE_LIB_A_CHECKS = $(APE_LIB_A_HDRS:%=o/$(MODE)/%.ok)
|
||||
APE_LIB_A_DEPS = $(call uniq,$(foreach x,$(APE_LIB_A_DIRECTDEPS),$($(x))))
|
||||
|
||||
$(APE_LIB_A): ape/lib/ $(APE_LIB_A).pkg $(APE_LIB_A_OBJS)
|
||||
$(APE_LIB_A).pkg: $(APE_LIB_A_OBJS) $(foreach x,$(APE_LIB_A_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
APE_LIB_LIBS = $(foreach x,$(APE_LIB_ARTIFACTS),$($(x)))
|
||||
APE_LIB_SRCS = $(foreach x,$(APE_LIB_ARTIFACTS),$($(x)_SRCS))
|
||||
APE_LIB_HDRS = $(foreach x,$(APE_LIB_ARTIFACTS),$($(x)_HDRS))
|
||||
APE_LIB_BINS = $(foreach x,$(APE_LIB_ARTIFACTS),$($(x)_BINS))
|
||||
APE_LIB_CHECKS = $(foreach x,$(APE_LIB_ARTIFACTS),$($(x)_CHECKS))
|
||||
APE_LIB_OBJS = $(foreach x,$(APE_LIB_ARTIFACTS),$($(x)_OBJS))
|
||||
$(APE_LIB_OBJS): $(BUILD_FILES) libc/str/str.mk
|
||||
|
||||
.PHONY: o/$(MODE)/ape/lib
|
||||
o/$(MODE)/ape/lib: \
|
||||
$(APE_LIB_CHECKS) \
|
||||
$(APE_LIB_A)
|
58
ape/lib/apm.h
Normal file
58
ape/lib/apm.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=8 sts=2 sw=2 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. │
|
||||
╠──────────────────────────────────────────────────────────────────────────────╣
|
||||
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░█▀█░█▀█░▀█▀░█░█░█▀█░█░░░█░░░█░█░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░█▀█░█░▄░░█░░█░█░█▀█░█░░░█░░░▀█▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░▀░▀░▀▀▀░░▀░░▀▀▀░▀░▀░▀▀▀░▀▀▀░░▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░█▀█░█▀█░█▀█░▀█▀░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░█▀▀░█ █░██▀░░█░░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░▀░░░▀▀▀░▀░▀░░▀░░▀░▀░▀▀▀░▀▀▀░▀▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░█▀▀░█░█░█▀▀░█▀█░█░█░▀█▀░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░▄▄░░░▐█░░│
|
||||
│░░░░░░░█▀▀░▄▀▄░█▀▀░█░▄░█░█░░█░░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░▄▄▄░░░▄██▄░░█▀░░░█░▄░│
|
||||
│░░░░░░░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀▀▀░░▀░░▀░▀░▀▀▀░▀▀░▀▀▀░░░░░░░░░░▄██▀█▌░██▄▄░░▐█▀▄░▐█▀░░│
|
||||
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▐█▀▀▌░░░▄▀▌░▌░█░▌░░▌░▌░░│
|
||||
╠──────────────────────────────────────────────────────▌▀▄─▐──▀▄─▐▄─▐▄▐▄─▐▄─▐▄─│
|
||||
│ αcτµαlly pδrταblε εxεcµταblε § green energy │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#ifndef APE_LIB_APM_H_
|
||||
#define APE_LIB_APM_H_
|
||||
|
||||
/**
|
||||
* @fileoverview Advanced Power Management.
|
||||
*
|
||||
* <p>APM is useful for exiting programs, without needing to ask the
|
||||
* human to flip a physical switch or pass QEMU's -no-reboot flag.
|
||||
*
|
||||
* <p><b>Implementation Detail:</b> Supporting ACPI would literally
|
||||
* require implementing a programming language.
|
||||
*
|
||||
* @see APM BIOS Interface Specification v1.2
|
||||
* @since IBM PC/AT
|
||||
*/
|
||||
|
||||
#define APM_SERVICE 0x15
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
void apmoff(void) wontreturn;
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* APE_LIB_APM_H_ */
|
35
ape/lib/bootdr.S
Normal file
35
ape/lib/bootdr.S
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*-*- 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. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "ape/macros.internal.h"
|
||||
#include "ape/notice.inc"
|
||||
.section .real,"ax",@progbits
|
||||
.source __FILE__
|
||||
.code16
|
||||
|
||||
// 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
|
||||
int $0x19
|
||||
ljmp $0xf000,$0xfff0
|
||||
.endfn bootdr,globl
|
37
ape/lib/e820map.S
Normal file
37
ape/lib/e820map.S
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=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. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "ape/lib/pc.h"
|
||||
#include "ape/config.h"
|
||||
#include "ape/macros.internal.h"
|
||||
#include "ape/notice.inc"
|
||||
.section .real,"ax",@progbits
|
||||
.source __FILE__
|
||||
.code16
|
||||
|
||||
.globl e820map
|
||||
.hidden e820map
|
||||
.type e820map,@object
|
||||
.size e820map,XLM_E820_SIZE
|
||||
e820map = ape_xlm + XLM_E820
|
||||
|
||||
.globl e820map_xlm
|
||||
.hidden e820map_xlm
|
||||
.type e820map_xlm,@object
|
||||
.size e820map_xlm,XLM_E820_SIZE
|
||||
e820map_xlm = XLM(E820)
|
55
ape/lib/flattenhighmemory.c
Normal file
55
ape/lib/flattenhighmemory.c
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*-*- 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 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. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "ape/config.h"
|
||||
#include "ape/lib/pc.h"
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/macros.h"
|
||||
|
||||
/**
|
||||
* Virtualizes physical memory.
|
||||
*
|
||||
* This function removes memory holes (discovered by e820() earlier) and
|
||||
* creates the illusion of flat contiguous memory for as much RAM as the
|
||||
* BIOS reports usable. Memory is safe to use and remap afterwards.
|
||||
*
|
||||
* @see ape/ape.S
|
||||
*/
|
||||
textreal void flattenhighmemory(struct SmapEntry *e820, struct PageTable *pml4t,
|
||||
uint64_t *ptsp) {
|
||||
uint64_t *entry, paddr, vaddr;
|
||||
struct SmapEntry *smap, *hole;
|
||||
for (smap = hole = e820, vaddr = IMAGE_BASE_VIRTUAL; smap->size; ++smap) {
|
||||
while (smap->size && smap->type != kMemoryUsable) smap++;
|
||||
paddr = ROUNDUP(MAX(IMAGE_BASE_PHYSICAL, smap->addr), PAGESIZE);
|
||||
while (paddr < ROUNDDOWN(smap->addr + smap->size, PAGESIZE)) {
|
||||
while (hole->size &&
|
||||
(hole->type == kMemoryUsable || hole->addr + hole->size < paddr)) {
|
||||
hole++;
|
||||
}
|
||||
if (paddr >= hole->addr && paddr < hole->addr + hole->size) {
|
||||
paddr = ROUNDUP(hole->addr + hole->size, PAGESIZE);
|
||||
} else {
|
||||
entry = __getpagetableentry(vaddr, 3, pml4t, ptsp);
|
||||
*entry = paddr | PAGE_V | PAGE_RW;
|
||||
vaddr += 0x1000;
|
||||
paddr += 0x1000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
31
ape/lib/g_pml4t.S
Normal file
31
ape/lib/g_pml4t.S
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=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. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "ape/lib/pc.h"
|
||||
#include "ape/config.h"
|
||||
#include "ape/macros.internal.h"
|
||||
#include "ape/notice.inc"
|
||||
.section .real,"ax",@progbits
|
||||
.source __FILE__
|
||||
.code16
|
||||
|
||||
.globl g_pml4t
|
||||
.hidden g_pml4t
|
||||
.type g_pml4t,@object
|
||||
.size g_pml4t,0x1000
|
||||
g_pml4t = REAL_STACK_FRAME - 0x1000
|
37
ape/lib/g_ptsp.S
Normal file
37
ape/lib/g_ptsp.S
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=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. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "ape/lib/pc.h"
|
||||
#include "ape/config.h"
|
||||
#include "ape/macros.internal.h"
|
||||
#include "ape/notice.inc"
|
||||
.section .real,"ax",@progbits
|
||||
.source __FILE__
|
||||
.code16
|
||||
|
||||
.globl g_ptsp
|
||||
.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
|
||||
|
||||
.globl g_ptsp_xlm
|
||||
.hidden g_ptsp_xlm
|
||||
.type g_ptsp_xlm,@object
|
||||
.size g_ptsp_xlm,XLM_PAGE_TABLE_STACK_POINTER_SIZE
|
||||
g_ptsp_xlm = XLM(PAGE_TABLE_STACK_POINTER)
|
42
ape/lib/getpagetableentry.c
Normal file
42
ape/lib/getpagetableentry.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*-*- 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 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. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "ape/lib/pc.h"
|
||||
#include "libc/assert.h"
|
||||
|
||||
static textreal uint64_t __pushpagetable(uint64_t *ptsp) {
|
||||
return (*ptsp -= PAGESIZE) | PAGE_V | PAGE_RW;
|
||||
}
|
||||
|
||||
textreal uint64_t *__getpagetableentry(int64_t vaddr, unsigned depth,
|
||||
struct PageTable *pml4t,
|
||||
uint64_t *ptsp) {
|
||||
uint64_t *entry;
|
||||
unsigned char shift;
|
||||
assert(depth <= 3);
|
||||
assert(!(*ptsp & 0xfff));
|
||||
assert(!((uintptr_t)pml4t & 0xfff));
|
||||
shift = 39;
|
||||
for (;;) {
|
||||
entry = &pml4t->p[(vaddr >> shift) & 511];
|
||||
if (!depth--) return entry;
|
||||
shift -= 9;
|
||||
if (!*entry) *entry = __pushpagetable(ptsp);
|
||||
pml4t = (void *)(*entry & PAGE_TA);
|
||||
}
|
||||
}
|
45
ape/lib/kbiosdataarea.S
Normal file
45
ape/lib/kbiosdataarea.S
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=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. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "ape/lib/pc.h"
|
||||
#include "ape/config.h"
|
||||
#include "ape/macros.internal.h"
|
||||
#include "ape/notice.inc"
|
||||
.section .real,"ax",@progbits
|
||||
.source __FILE__
|
||||
.code16
|
||||
|
||||
.globl kBiosDataArea
|
||||
.hidden kBiosDataArea
|
||||
.type kBiosDataArea,@object
|
||||
.size kBiosDataArea,XLM_BIOS_DATA_AREA_SIZE
|
||||
kBiosDataArea = ape_xlm + XLM_BIOS_DATA_AREA
|
||||
|
||||
.globl kBiosDataAreaXlm
|
||||
.hidden kBiosDataAreaXlm
|
||||
.type kBiosDataAreaXlm,@object
|
||||
.size kBiosDataAreaXlm,XLM_BIOS_DATA_AREA_SIZE
|
||||
kBiosDataAreaXlm = XLM(BIOS_DATA_AREA)
|
||||
|
||||
.section .sort.text.real.init.2.kBiosDataArea,"ax",@progbits
|
||||
movpp %ds,%es # copy bios data to valid page
|
||||
mov $PC_BIOS_DATA_AREA,%si
|
||||
mov $XLM(BIOS_DATA_AREA),%di
|
||||
mov $XLM_BIOS_DATA_AREA_SIZE,%cx
|
||||
rep movsb
|
||||
.previous
|
36
ape/lib/mapimage.c
Normal file
36
ape/lib/mapimage.c
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*-*- 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 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. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "ape/lib/pc.h"
|
||||
#include "ape/relocations.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
||||
textreal static void __map_segment(uint64_t k, uint64_t a, uint64_t b) {
|
||||
uint64_t *e;
|
||||
for (; a < b; a += 0x1000) {
|
||||
e = __getpagetableentry(IMAGE_BASE_VIRTUAL + a, 3, &g_pml4t, &g_ptsp_xlm);
|
||||
*e = (IMAGE_BASE_REAL + a) | k;
|
||||
}
|
||||
}
|
||||
|
||||
textreal void __map_image(void) {
|
||||
__map_segment(PAGE_V | PAGE_U, 0, (uintptr_t)_etext - IMAGE_BASE_VIRTUAL);
|
||||
__map_segment(PAGE_V | PAGE_U | PAGE_RW,
|
||||
(uintptr_t)_etext - IMAGE_BASE_VIRTUAL,
|
||||
(uintptr_t)_end - IMAGE_BASE_VIRTUAL);
|
||||
}
|
26
ape/lib/pageunmap.c
Normal file
26
ape/lib/pageunmap.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*-*- 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 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. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "ape/lib/pc.h"
|
||||
|
||||
textreal void pageunmap(int64_t vaddr) {
|
||||
uint64_t *entry;
|
||||
entry = __getpagetableentry(vaddr, 3, &g_pml4t, &g_ptsp_xlm);
|
||||
*entry &= ~PAGE_V;
|
||||
asm volatile("invlpg\t(%0)" : /* no outputs */ : "r"(vaddr) : "memory");
|
||||
}
|
242
ape/lib/pc.h
Normal file
242
ape/lib/pc.h
Normal file
|
@ -0,0 +1,242 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=8 sts=2 sw=2 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. │
|
||||
╠──────────────────────────────────────────────────────────────────────────────╣
|
||||
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░█▀█░█▀█░▀█▀░█░█░█▀█░█░░░█░░░█░█░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░█▀█░█░▄░░█░░█░█░█▀█░█░░░█░░░▀█▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░▀░▀░▀▀▀░░▀░░▀▀▀░▀░▀░▀▀▀░▀▀▀░░▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░█▀█░█▀█░█▀█░▀█▀░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░█▀▀░█ █░██▀░░█░░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░▀░░░▀▀▀░▀░▀░░▀░░▀░▀░▀▀▀░▀▀▀░▀▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░█▀▀░█░█░█▀▀░█▀█░█░█░▀█▀░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░▄▄░░░▐█░░│
|
||||
│░░░░░░░█▀▀░▄▀▄░█▀▀░█░▄░█░█░░█░░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░▄▄▄░░░▄██▄░░█▀░░░█░▄░│
|
||||
│░░░░░░░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀▀▀░░▀░░▀░▀░▀▀▀░▀▀░▀▀▀░░░░░░░░░░▄██▀█▌░██▄▄░░▐█▀▄░▐█▀░░│
|
||||
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▐█▀▀▌░░░▄▀▌░▌░█░▌░░▌░▌░░│
|
||||
╠──────────────────────────────────────────────────────▌▀▄─▐──▀▄─▐▄─▐▄▐▄─▐▄─▐▄─│
|
||||
│ αcτµαlly pδrταblε εxεcµταblε § ibm personal computer │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#ifndef APE_LIB_PC_H_
|
||||
#define APE_LIB_PC_H_
|
||||
|
||||
#define BOOTSIG 0xaa55 /* master boot record signature */
|
||||
#define PC_BIOS_DATA_AREA 0x400
|
||||
|
||||
#define kInterruptFlag (1u << 9)
|
||||
|
||||
/* FPU Status Word (x87)
|
||||
@see Intel Manual V1 §8.1.3
|
||||
IE: Invalid Operation ────────────────┐
|
||||
DE: Denormalized Operand ────────────┐│
|
||||
ZE: Zero Divide ────────────────────┐││
|
||||
OE: Overflow Flag ─────────────────┐│││
|
||||
UE: Underflow Flag ───────────────┐││││
|
||||
PE: Precision Flag ──────────────┐│││││
|
||||
SF: Stack Fault ────────────────┐││││││
|
||||
ES: Exception Summary Status ──┐│││││││
|
||||
C0-3: Condition Codes ──┬────┐ ││││││││
|
||||
TOP of Stack Pointer ─────┐ │ ││││││││
|
||||
B: FPU Busy ───────────┐│ │ │ ││││││││
|
||||
││┌┴┐┌┼┐││││││││
|
||||
│↓│ │↓↓↓││││││││*/
|
||||
#define FPU_IE 0b0000000000100000000000001
|
||||
#define FPU_ZE 0b0000000000100000000000100
|
||||
#define FPU_SF 0b0000000000000000001000000
|
||||
#define FPU_C0 0b0000000000000000100000000
|
||||
#define FPU_C1 0b0000000000000001000000000
|
||||
#define FPU_C2 0b0000000000000010000000000
|
||||
#define FPU_C3 0b0000000000100000000000000
|
||||
|
||||
#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 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 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 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
|
||||
#define GDT_LEGACY_CODE 24
|
||||
#define GDT_LEGACY_DATA 32
|
||||
#define GDT_LONG_CODE 40
|
||||
#define GDT_LONG_DATA 48
|
||||
|
||||
#define PIC1 0x20 /* IO base address for master PIC */
|
||||
#define PIC2 0xA0 /* IO base address for slave PIC */
|
||||
#define PIC1_CMD PIC1
|
||||
#define PIC1_DATA (PIC1 + 1)
|
||||
#define PIC2_CMD PIC2
|
||||
#define PIC2_DATA (PIC2 + 1)
|
||||
#define PIC_EOI 0x20 /* End-of-interrupt command code */
|
||||
#define PIC_READ_IRR 0x0a /* OCW3 irq ready next CMD read */
|
||||
#define PIC_READ_ISR 0x0b /* OCW3 irq service next CMD read */
|
||||
|
||||
/* Long Mode Paging
|
||||
@see Intel Manual V.3A §4.1 §4.5
|
||||
IsValid (ignored on CR3) V┐
|
||||
┌XD:No Inst. Fetches (if NXE) IsWritable (ignored on CR3) RW┐│
|
||||
│ Permit User-Mode Access - u┐││
|
||||
│ Page-level Write-Through - PWT┐│││
|
||||
│ Page-level Cache Disable - PCD┐││││
|
||||
│ Set if has been read - Accessed┐│││││
|
||||
│ Set if has been written - Dirty┐││││││
|
||||
│ IsPage (if PDPTE/PDE) or PAT (if PT)┐│││││││
|
||||
│ (If this maps 2MB/1GB page and CR4.PGE) Global┐││││││││
|
||||
│ (If IsPage 2MB/1GB, see Intel V3A § 11.12) PAT │││││││││
|
||||
│ │ │││││││││
|
||||
│ ┌────────────────────────────────────┤ │││││││││
|
||||
│ Must Be 0┐│ Next Page Table Address (!IsPage) │ │││││││││
|
||||
│ │├────────────────────────────────────┤ │││││││││
|
||||
│ ││ Physical Address 4KB │ │││││││││
|
||||
│┌───┐┌─────┐│├───────────────────────────┐ │ign│││││││││
|
||||
││PKE││ ign │││ Physical Address 2MB │ │┌┴┐│││││││││
|
||||
││ ││ ││├──────────────────┐ │ ││ ││││││││││
|
||||
││ ││ │││ Phys. Addr. 1GB │ │ ││ ││││││││││
|
||||
││ ││ │││ │ │ ││ ││││││││││
|
||||
6666555555555544444444443333333333222222222211111111110000000000
|
||||
3210987654321098765432109876543210987654321098765432109876543210*/
|
||||
#define PAGE_V /* */ 0b000000001
|
||||
#define PAGE_RW /* */ 0b000000010
|
||||
#define PAGE_U /* */ 0b000000100
|
||||
#define PAGE_4KB /* */ 0b010000000
|
||||
#define PAGE_2MB /* */ 0b110000000
|
||||
#define PAGE_1GB /* */ 0b110000000
|
||||
#define PAGE_TA 0b11111111111111111111111111111111111111000000000000
|
||||
#define PAGE_PA2 0b11111111111111111111111111111000000000000000000000
|
||||
#define PAGE_XD 0x8000000000000000
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
#include "ape/config.h"
|
||||
|
||||
struct thatispacked GlobalDescriptorTable {
|
||||
uint16_t size;
|
||||
uint64_t *entries;
|
||||
};
|
||||
|
||||
/**
|
||||
* Memory hole map.
|
||||
* @see wiki.osdev.org/Detecting_Memory_(x86)
|
||||
* @since 2002
|
||||
*/
|
||||
struct SmapEntry {
|
||||
uint64_t addr;
|
||||
uint64_t size;
|
||||
enum {
|
||||
kMemoryUsable = 1,
|
||||
kMemoryUnusable = 2,
|
||||
kMemoryAcpiReclaimable = 3,
|
||||
kMemoryAcpiNvs = 4,
|
||||
kMemoryBad = 5
|
||||
} type;
|
||||
uint32_t __acpi3; /* is abstracted */
|
||||
};
|
||||
|
||||
struct IdtDescriptor {
|
||||
uint16_t offset_1; /* offset bits 0..15 */
|
||||
uint16_t selector; /* a code segment selector in GDT or LDT */
|
||||
uint8_t ist; /* bits 0..2 hold stack table offset, rest are zero */
|
||||
uint8_t type_attr; /* type and attributes */
|
||||
uint16_t offset_2; /* offset bits 16..31 */
|
||||
uint32_t offset_3; /* offset bits 32..63 */
|
||||
uint32_t zero; /* reserved */
|
||||
};
|
||||
|
||||
struct thatispacked PageTable {
|
||||
uint64_t p[512];
|
||||
} forcealign(PAGESIZE);
|
||||
|
||||
extern struct PageTable g_pml4t;
|
||||
extern struct GlobalDescriptorTable gdt;
|
||||
|
||||
extern const unsigned char kBiosDataArea[256];
|
||||
extern const unsigned char kBiosDataAreaXlm[256];
|
||||
|
||||
extern struct SmapEntry e820map[XLM_E820_SIZE / sizeof(struct SmapEntry)];
|
||||
extern struct SmapEntry e820map_xlm[XLM_E820_SIZE / sizeof(struct SmapEntry)];
|
||||
|
||||
extern uint64_t g_ptsp;
|
||||
extern uint64_t g_ptsp_xlm;
|
||||
|
||||
void bootdr(char drive) wontreturn;
|
||||
|
||||
void smapsort(struct SmapEntry *);
|
||||
uint64_t *__getpagetableentry(int64_t, unsigned, struct PageTable *,
|
||||
uint64_t *);
|
||||
void flattenhighmemory(struct SmapEntry *, struct PageTable *, uint64_t *);
|
||||
void pageunmap(int64_t);
|
||||
|
||||
forceinline unsigned long eflags(void) {
|
||||
unsigned long res;
|
||||
asm("pushf\n\t"
|
||||
"pop\t%0"
|
||||
: "=rm"(res));
|
||||
return res;
|
||||
}
|
||||
|
||||
forceinline unsigned char inb(unsigned short port) {
|
||||
unsigned char al;
|
||||
asm volatile("inb\t%1,%0" : "=a"(al) : "dN"(port));
|
||||
return al;
|
||||
}
|
||||
|
||||
forceinline void outb(unsigned short port, unsigned char byte) {
|
||||
asm volatile("outb\t%0,%1"
|
||||
: /* no inputs */
|
||||
: "a"(byte), "dN"(port));
|
||||
}
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* APE_LIB_PC_H_ */
|
46
ape/lib/smapsort.c
Normal file
46
ape/lib/smapsort.c
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*-*- 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 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. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "ape/lib/pc.h"
|
||||
|
||||
textreal static unsigned smapcount(const struct SmapEntry *se) {
|
||||
unsigned i = 0;
|
||||
while (se[i].size) ++i;
|
||||
return i;
|
||||
}
|
||||
|
||||
textreal static void smapsorter(size_t n, struct SmapEntry a[n]) {
|
||||
struct SmapEntry t;
|
||||
unsigned i, j;
|
||||
for (i = 1; i < n; ++i) {
|
||||
j = i;
|
||||
t = a[i];
|
||||
while (j > 0 && (intptr_t)t.addr - (intptr_t)a[j - 1].addr) {
|
||||
a[j] = a[j - 1];
|
||||
--j;
|
||||
}
|
||||
a[j] = t;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts BIOS e820 memory map.
|
||||
*/
|
||||
textreal void smapsort(struct SmapEntry *smap) {
|
||||
smapsorter(smapcount(smap), smap);
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│ vi: set noet ft=asm ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 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/macho.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/macros.h"
|
||||
|
||||
// Apple Mach-O Executable Headers
|
||||
// Fixups are applied by objbincopy
|
||||
// There must exist a MAC_LC_SEGMENT_64 for every PT_LOAD
|
||||
|
||||
.section .macho,"a",@progbits
|
||||
.balign 64
|
||||
.long 0xFEEDFACE+1
|
||||
.long MAC_CPU_NEXGEN32E
|
||||
.long MAC_CPU_NEXGEN32E_ALL
|
||||
.long MAC_EXECUTE
|
||||
.long 5 // number of load commands
|
||||
.long 60f-10f // size of all load commands
|
||||
.long MAC_NOUNDEFS|MAC_SPLIT_SEGS // flags
|
||||
.long 0 // reserved
|
||||
10: .long MAC_LC_SEGMENT_64
|
||||
.long 20f-10b // unmaps first page dir
|
||||
.ascin "__PAGEZERO",16 // consistent with linux
|
||||
.quad 0,0x200000,0,0 // which forbids mem <2m
|
||||
.long 0,0,0,0
|
||||
20: .long MAC_LC_SEGMENT_64
|
||||
.long 30f-20b
|
||||
.ascin "__TEXT",16
|
||||
.quad 0 // vaddr
|
||||
.quad 0 // memsz
|
||||
.quad 0 // file offset
|
||||
.quad 0 // file size
|
||||
.long 0 // maxprot
|
||||
.long 0 // initprot
|
||||
.long 0 // segment section count
|
||||
.long 0 // flags
|
||||
30: .long MAC_LC_SEGMENT_64
|
||||
.long 40f-30b
|
||||
.ascin "__RODATA",16
|
||||
.quad 0 // vaddr
|
||||
.quad 0 // memsz
|
||||
.quad 0 // file offset
|
||||
.quad 0 // file size
|
||||
.long 0 // maxprot
|
||||
.long 0 // initprot
|
||||
.long 0 // segment section count
|
||||
.long 0 // flags
|
||||
40: .long MAC_LC_UUID
|
||||
.long 50f-40b
|
||||
.quad 0x4527148ba7a513ef // uuid1
|
||||
.quad 0x56fa865940665e8f // uuid2
|
||||
50: .long MAC_LC_UNIXTHREAD
|
||||
.long 60f-50b // cmdsize
|
||||
.long MAC_THREAD_NEXGEN32E // flavaflav
|
||||
.long (520f-510f)/4 // count
|
||||
510: .quad 0 // rax
|
||||
.quad 0 // rbx
|
||||
.quad 0 // rcx
|
||||
.quad 0 // rdx
|
||||
.quad 0 // rdi
|
||||
.quad 0 // rsi
|
||||
.quad 0 // rbp
|
||||
.quad 0 // rsp
|
||||
.quad 0 // r8
|
||||
.quad 0 // r9
|
||||
.quad 0 // r10
|
||||
.quad 0 // r11
|
||||
.quad 0 // r12
|
||||
.quad 0 // r13
|
||||
.quad 0 // r14
|
||||
.quad 0 // r15
|
||||
.quad XnuEntrypoint // rip
|
||||
.quad 0 // rflags
|
||||
.quad 0 // cs
|
||||
.quad 0 // fs
|
||||
.quad 0 // gs
|
||||
520:
|
||||
60:
|
1127
ape/loader.c
1127
ape/loader.c
File diff suppressed because it is too large
Load diff
|
@ -1,95 +0,0 @@
|
|||
/*-*- 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 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. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
|
||||
ENTRY(ElfEntrypoint)
|
||||
|
||||
PHDRS {
|
||||
text PT_LOAD FLAGS(1) FILEHDR PHDRS; /* PF_X */
|
||||
rodata PT_LOAD FLAGS(4); /* PF_R */
|
||||
stack PT_GNU_STACK FLAGS(6); /* PF_W|PF_R */
|
||||
note PT_NOTE FLAGS(4); /* PF_R */
|
||||
}
|
||||
|
||||
SECTIONS {
|
||||
|
||||
. = SEGMENT_START("text-segment", 0x7f000000);
|
||||
__executable_start = .;
|
||||
. += SIZEOF_HEADERS;
|
||||
|
||||
.macho : {
|
||||
KEEP(*(.macho))
|
||||
} :text
|
||||
|
||||
.note : {
|
||||
KEEP(*(.note))
|
||||
} :text :note
|
||||
|
||||
.text : {
|
||||
*(.text .text.* .gnu.linkonce.t.*)
|
||||
} :text
|
||||
|
||||
.rodata ALIGN(CONSTANT(COMMONPAGESIZE)) : {
|
||||
*(.rodata .rodata.* .gnu.linkonce.r.*)
|
||||
} :rodata
|
||||
|
||||
.stack : {
|
||||
*(.stack)
|
||||
} :stack
|
||||
|
||||
_end = .;
|
||||
|
||||
.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) }
|
||||
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
|
||||
.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) }
|
||||
.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) }
|
||||
.debug_macro 0 : { *(.debug_macro) }
|
||||
.debug_addr 0 : { *(.debug_addr) }
|
||||
.debug_loclists 0 : { *(.debug_loclists) }
|
||||
.debug_rnglists 0 : { *(.debug_rnglists) }
|
||||
.debug_line_str 0 : { *(.debug_line_str) }
|
||||
.debug_extra 0 : { *(.debug_line_str) }
|
||||
.debug_pubtypes 0 : { *(.debug_pubtypes) }
|
||||
.gnu.attributes 0 : { KEEP(*(.gnu.attributes)) }
|
||||
|
||||
/DISCARD/ : {
|
||||
*(.*)
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│ vi: set noet ft=asm ts=8 sw=8 fenc=utf-8 :vi │
|
||||
│vi: set et ft=asm ts=8 sw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
|
@ -22,6 +22,126 @@
|
|||
#ifdef __ASSEMBLER__
|
||||
/* clang-format off */
|
||||
|
||||
/**
|
||||
* @fileoverview Macros relevant to αcτµαlly pδrταblε εxεcµταblε.
|
||||
*/
|
||||
|
||||
// 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
|
||||
jmp 911f
|
||||
.byte 0x58 # pop %[er]ax
|
||||
.byte 0xe8 # call Jvds
|
||||
.long \function\()-.-4
|
||||
jmp 912f
|
||||
911: .byte 0x58 # pop %[er]ax
|
||||
.byte 0xe8 # call Jvds
|
||||
.short \function\()-.-2
|
||||
912:
|
||||
.endm
|
||||
|
||||
// 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
|
||||
.byte 0x8e,0xc7 # mov %di,%es
|
||||
.byte 0xbf # mov $0x????xxxx,%[e]di
|
||||
.short \address&0xf
|
||||
jmp 297f
|
||||
.byte 0xbf # mov $0x????xxxx,%edi
|
||||
.long \address
|
||||
297:
|
||||
.endm
|
||||
|
||||
// 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
|
||||
pushpop \constexpr,\abcd
|
||||
.exitm
|
||||
.endif
|
||||
.endif
|
||||
movb $(\constexpr)>>8&0xff,\abcd.hi
|
||||
movb $(\constexpr)&0xff,\abcd.lo
|
||||
.endm
|
||||
|
||||
// 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
|
||||
cmpb $(\constexpr)&0xff,\abcd.lo
|
||||
387:
|
||||
.endm
|
||||
|
||||
// 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
|
||||
adcb $(\constexpr)>>8&0xff,\abcd.hi
|
||||
.endif
|
||||
.endm
|
||||
|
||||
// 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
|
||||
sbbb $(\constexpr)>>8&0xff,\abcd.hi
|
||||
.endif
|
||||
.endm
|
||||
|
||||
// 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
|
||||
.endif
|
||||
.if ((\constexpr)>>8&0xff) != 0xff
|
||||
andb $(\constexpr)>>8&0xff,\abcd.hi
|
||||
.endif
|
||||
.endm
|
||||
|
||||
// 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
|
||||
.endif
|
||||
.if ((\constexpr)>>8&0xff) != 0
|
||||
orb $(\constexpr)>>8&0xff,\abcd.hi
|
||||
.endif
|
||||
.endm
|
||||
|
||||
// Performs ACTION only if in real mode.
|
||||
// @mode long,legacy,real
|
||||
.macro rlo clobber:req action:vararg
|
||||
990: mov $0,\clobber
|
||||
.if .-990b!=3
|
||||
.error "bad clobber or assembler mode"
|
||||
.endif
|
||||
991: \action
|
||||
.rept 2-(.-991b)
|
||||
nop
|
||||
.endr
|
||||
.if .-991b!=2
|
||||
.error "ACTION must be 1-2 bytes"
|
||||
.endif
|
||||
.endm
|
||||
|
||||
// Initializes real mode stack.
|
||||
// The most holiest of holy code.
|
||||
// @mode real
|
||||
|
@ -67,25 +187,10 @@
|
|||
.stub \name\()_bcs\n,long
|
||||
.endm
|
||||
|
||||
// Task State Segment Descriptor Entries.
|
||||
.macro .tssdescstub name:req
|
||||
.ifndef \name
|
||||
.weak \name
|
||||
.set \name,0
|
||||
.endif
|
||||
.ifndef \name\()_end
|
||||
.weak \name\()_end
|
||||
.set \name\()_end,0
|
||||
.endif
|
||||
.stub \name\()_desc_ent0,quad
|
||||
.stub \name\()_desc_ent1,quad
|
||||
.endm
|
||||
|
||||
/* clang-format on */
|
||||
#elif defined(__LINKER__)
|
||||
|
||||
#define BCX_NIBBLE(X) \
|
||||
((((X) & 0xf) > 0x9) ? ((X) & 0xf) + 0x37 : ((X) & 0xf) + 0x30)
|
||||
#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 BCXSTUB(SYM, X) \
|
||||
|
@ -99,12 +204,12 @@
|
|||
*
|
||||
* <p>This allows linker scripts to generate printf commands.
|
||||
*/
|
||||
#define BCO_OCTET(X) (((X) & 0x7) + 0x30)
|
||||
#define BCO_OCTET(X) (((X)&0x7) + 0x30)
|
||||
#define BCOB_UNIT(X) \
|
||||
((BCO_OCTET((X) >> 0) << 24) | (BCO_OCTET((X) >> 3) << 16) | \
|
||||
(BCO_OCTET(((X) & 0xff) >> 6) << 8) | 0x5c)
|
||||
(BCO_OCTET(((X)&0xff) >> 6) << 8) | 0x5c)
|
||||
|
||||
#define PFBYTE(SYM, X, I) HIDDEN(SYM##_bcs##I = BCOB_UNIT((X) >> ((I) * 8)))
|
||||
#define PFBYTE(SYM, X, I) HIDDEN(SYM##_bcs##I = BCOB_UNIT((X) >> ((I)*8)))
|
||||
#define PFSTUB2(SYM, X) \
|
||||
HIDDEN(SYM = (X)); \
|
||||
PFBYTE(SYM, X, 0); \
|
||||
|
@ -123,47 +228,44 @@
|
|||
/**
|
||||
* Binary coded decimal support.
|
||||
*
|
||||
* <p>This allows linker scripts to generate dd commands, e.g. ape.lds.
|
||||
* There are a few ways to pad each number to the necessary 8 bytes.
|
||||
* Spaces cannot be prepended because busybox refuses to parse them.
|
||||
* Zeros cannot be prepended because Mac will take numbers as octal.
|
||||
* That leaves appending spaces. The user's shell ought to treat any
|
||||
* unquoted run of spaces as if there was only one, so this is safe.
|
||||
* <p>This allows linker scripts to generate dd commands. Leading spaces
|
||||
* need to be inserted so Mac doesn't consider them octal; therefore,
|
||||
* parameters must be quoted; and eight digits should be good enough.
|
||||
*/
|
||||
#define SHSTUB2(SYM, X) \
|
||||
HIDDEN(SYM##_bcs0 = BCD_LEFT(X)); \
|
||||
HIDDEN(SYM##_bcs1 = BCD_RIGHT(X))
|
||||
#define BCD_SMEAR(X) ((X) + (X) * 10000)
|
||||
#define BCD_LEFT(X) \
|
||||
(((X)) < 10000 ? BCD_RIGHT(BCD_SMEAR(X)) | 0x10 \
|
||||
: (X) < 100000 ? BCD_RIGHT(BCD_SMEAR((X) / 10)) \
|
||||
: (X) < 1000000 ? BCD_RIGHT(BCD_SMEAR((X) / 100)) \
|
||||
: (X) < 10000000 ? BCD_RIGHT(BCD_SMEAR((X) / 1000)) \
|
||||
: (X) < 100000000 ? BCD_RIGHT(BCD_SMEAR((X) / 10000)) \
|
||||
: 0xffffffffffffffff)
|
||||
#define BCD_RIGHT(X) \
|
||||
(((X)) < 10000 ? 0x20202020 \
|
||||
: (X) < 100000 ? 0x20202030 + (X) % 10 \
|
||||
: (X) < 1000000 ? 0x20203030 + ((X) / 10) % 10 + (X) % 10 * 0x100 \
|
||||
: (X) < 10000000 ? 0x20303030 + ((X) / 100) % 10 + \
|
||||
((X) / 10) % 10 * 0x100 + (X) % 10 * 0x10000 \
|
||||
HIDDEN(SYM##_bcs0 = BCD10K(X)); \
|
||||
HIDDEN(SYM##_bcs1 = BCD(X))
|
||||
#define BCD(X) \
|
||||
((X) == 0 \
|
||||
? 0x20202030 \
|
||||
: (X) < 10 ? 0x30202020 + (((X) % 10) << 24) \
|
||||
: (X) < 100 ? 0x30302020 + (((X) % 10) << 24) + \
|
||||
(((X) / 10 % 10) << 16) \
|
||||
: (X) < 1000 ? 0x30303020 + (((X) % 10) << 24) + \
|
||||
(((X) / 10 % 10) << 16) + \
|
||||
(((X) / 100 % 10) << 8) \
|
||||
: 0x30303030 + (((X) % 10) << 24) + \
|
||||
(((X) / 10 % 10) << 16) + \
|
||||
(((X) / 100 % 10) << 8) + \
|
||||
(((X) / 1000 % 10) << 0))
|
||||
#define BCD10K(X) \
|
||||
((X) < 10000 \
|
||||
? 0x20202020 \
|
||||
: (X) < 100000 \
|
||||
? 0x30202020 + (((X) / 10000 % 10) << 24) \
|
||||
: (X) < 1000000 \
|
||||
? 0x30302020 + (((X) / 10000 % 10) << 24) + \
|
||||
(((X) / 100000 % 10) << 16) \
|
||||
: (X) < 10000000 \
|
||||
? 0x30303020 + (((X) / 10000 % 10) << 24) + \
|
||||
(((X) / 100000 % 10) << 16) + \
|
||||
(((X) / 1000000 % 10) << 8) \
|
||||
: (X) < 100000000 \
|
||||
? 0x30303030 + ((X) / 1000) % 10 + ((X) / 100) % 10 * 0x100 + \
|
||||
((X) / 10) % 10 * 0x10000 + (X) % 10 * 0x1000000 \
|
||||
? 0x30303030 + (((X) / 10000 % 10) << 24) + \
|
||||
(((X) / 100000 % 10) << 16) + \
|
||||
(((X) / 1000000 % 10) << 8) + \
|
||||
(((X) / 10000000 % 10) << 0) \
|
||||
: 0xffffffffffffffff)
|
||||
|
||||
/**
|
||||
* Laying out the GDT entries for a TSS for bare metal operation.
|
||||
*/
|
||||
#define TSSDESCSTUB2(SYM, BASE, LIM) \
|
||||
HIDDEN(SYM##_desc_ent0 = TSSDESC_ENT0(BASE, LIM)); \
|
||||
HIDDEN(SYM##_desc_ent1 = TSSDESC_ENT1(BASE)); \
|
||||
ASSERT((LIM) >= 0 && (LIM) <= 0xffff, "bare metal TSS is suspiciously fat")
|
||||
#define TSSDESC_ENT0(BASE, LIM) \
|
||||
(((LIM) << 0 & 0x000000000000ffff) | ((BASE) << 16 & 0x000000ffffff0000) | \
|
||||
0x89 << 40 | ((LIM) >> 16 << 48 & 0x000f000000000000) | 0x2 << 52 | \
|
||||
((BASE) >> 24 << 56 & 0xff00000000000000))
|
||||
#define TSSDESC_ENT1(BASE) ((BASE) >> 32 << 0 & 0x00000000ffffffff)
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
#endif /* APE_MACROS_H_ */
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
#include "ape/ape.lds"
|
|
@ -11,8 +11,6 @@
|
|||
In some cases it's necessary to use addend macros that change virtual
|
||||
addresses into the other two types: physical and real. */
|
||||
|
||||
#define IMAGE_BASE_REAL 0x2000
|
||||
|
||||
#ifndef IMAGE_BASE_VIRTUAL
|
||||
#define IMAGE_BASE_VIRTUAL 0x400000
|
||||
#endif
|
||||
|
@ -21,6 +19,26 @@
|
|||
#define IMAGE_BASE_PHYSICAL 0x100000
|
||||
#endif
|
||||
|
||||
#ifndef REAL_SCRATCH_AREA
|
||||
/**
|
||||
* Location of anything goes memory for real mode.
|
||||
*
|
||||
* The MBR won't load program content beyond this address, so we have
|
||||
* room for buffers, page tables, etc. before we reach the stack frame.
|
||||
*/
|
||||
#define REAL_SCRATCH_AREA 0x40000
|
||||
#endif
|
||||
|
||||
#ifndef REAL_STACK_FRAME
|
||||
/**
|
||||
* Location of real mode 64kb stack frame.
|
||||
*
|
||||
* This address was chosen because memory beyond 0x80000 can't be
|
||||
* accessed safely without consulting e820.
|
||||
*/
|
||||
#define REAL_STACK_FRAME 0x70000
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Returns Relative Virtual Address.
|
||||
*/
|
||||
|
@ -36,8 +54,8 @@
|
|||
*/
|
||||
#define REAL(x) ((x) - (IMAGE_BASE_VIRTUAL - IMAGE_BASE_REAL))
|
||||
|
||||
#if IMAGE_BASE_VIRTUAL % 0x1000 != 0
|
||||
#error "IMAGE_BASE_VIRTUAL must be 4kb aligned"
|
||||
#if IMAGE_BASE_VIRTUAL % 0x200000 != 0
|
||||
#error "IMAGE_BASE_VIRTUAL must be 2mb aligned"
|
||||
#endif
|
||||
#if IMAGE_BASE_PHYSICAL % 0x1000 != 0
|
||||
#error "IMAGE_BASE_PHYSICAL must be 4kb aligned"
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
#ifndef COSMOPOLITAN_APE_SECTIONS_INTERNAL_H_
|
||||
#define COSMOPOLITAN_APE_SECTIONS_INTERNAL_H_
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
extern const char __notices[] __attribute__((__weak__));
|
||||
extern unsigned char __executable_start[] __attribute__((__weak__));
|
||||
extern unsigned char __privileged_start[] __attribute__((__weak__));
|
||||
extern unsigned char _ehead[] __attribute__((__weak__));
|
||||
extern unsigned char _etext[] __attribute__((__weak__));
|
||||
extern unsigned char _edata[] __attribute__((__weak__));
|
||||
extern unsigned char _ezip[] __attribute__((__weak__));
|
||||
extern unsigned char _end[] __attribute__((__weak__));
|
||||
extern unsigned char _ereal[] __attribute__((__weak__));
|
||||
extern unsigned char _tdata_start[] __attribute__((__weak__));
|
||||
extern unsigned char _tdata_end[] __attribute__((__weak__));
|
||||
extern unsigned char _tbss_start[] __attribute__((__weak__));
|
||||
extern unsigned char _tbss_end[] __attribute__((__weak__));
|
||||
extern unsigned char _tls_align[] __attribute__((__weak__));
|
||||
extern unsigned char _tdata_align[] __attribute__((__weak__));
|
||||
extern unsigned char _tbss_align[] __attribute__((__weak__));
|
||||
extern unsigned char __test_start[] __attribute__((__weak__));
|
||||
extern unsigned char __ro[] __attribute__((__weak__));
|
||||
extern unsigned char __data_start[] __attribute__((__weak__));
|
||||
extern unsigned char __data_end[] __attribute__((__weak__));
|
||||
extern unsigned char __bss_start[] __attribute__((__weak__));
|
||||
extern unsigned char __bss_end[] __attribute__((__weak__));
|
||||
extern unsigned long __got_start[] __attribute__((__weak__));
|
||||
extern unsigned long __got_end[] __attribute__((__weak__));
|
||||
extern unsigned char ape_phdrs[] __attribute__((__weak__));
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* COSMOPOLITAN_APE_SECTIONS_INTERNAL_H_ */
|
|
@ -1,703 +0,0 @@
|
|||
# Actually Portable Executable Specification v0.1
|
||||
|
||||
Actually Portable Executable (APE) is an executable file format that
|
||||
polyglots the Windows Portable Executable (PE) format with a UNIX Sixth
|
||||
Edition style shell script that doesn't have a shebang. This makes it
|
||||
possible to produce a single file binary that executes on the stock
|
||||
installations of the many OSes and architectures.
|
||||
|
||||
## Supported OSes and Architectures
|
||||
|
||||
- AMD64
|
||||
- Linux
|
||||
- MacOS
|
||||
- Windows
|
||||
- FreeBSD
|
||||
- OpenBSD
|
||||
- NetBSD
|
||||
- BIOS
|
||||
|
||||
- ARM64
|
||||
- Linux
|
||||
- MacOS
|
||||
- FreeBSD
|
||||
- Windows (non-native)
|
||||
|
||||
## File Header
|
||||
|
||||
APE defines three separate file magics, all of which are 8 characters
|
||||
long. Any file that starts with one of these magic values can be
|
||||
considered an APE program.
|
||||
|
||||
### (1) APE MZ Magic
|
||||
|
||||
- ASCII: `MZqFpD='`
|
||||
- Hex: 4d 5a 71 46 70 44 3d 27
|
||||
|
||||
This is the canonical magic used by almost all APE programs. It enables
|
||||
maximum portability between OSes. When interpreted as a shell script, it
|
||||
is assigning a single quoted string to an unused variable. The shell
|
||||
will then ignore subsequent binary content that's placed inside the
|
||||
string.
|
||||
|
||||
It is strongly recommended that this magic value be immediately followed
|
||||
by a newline (\n or hex 0a) character. Some shells, e.g. FreeBSD SH and
|
||||
Zsh impose a binary safety check before handing off files that don't
|
||||
have a shebang to `/bin/sh`. That check applies to the first line, which
|
||||
can't contain NUL characters.
|
||||
|
||||
The letters were carefully chosen so as to be valid x86 instructions in
|
||||
all operating modes. This makes it possible to store a BIOS bootloader
|
||||
disk image inside an APE binary. For example, simple CLI programs built
|
||||
with Cosmopolitan Libc will boot from BIOS into long mode if they're
|
||||
treated as a floppy disk image.
|
||||
|
||||
The letters also allow for the possibility of being treated on x86-64 as
|
||||
a flat executable, where the PE / ELF / Mach-O executable structures are
|
||||
ignored, and execution simply begins at the beginning of the file,
|
||||
similar to how MS-DOS .COM binaries work.
|
||||
|
||||
The 0x4a relative offset of the magic causes execution to jump into the
|
||||
MS-DOS stub defined by Portable Executable. APE binaries built by Cosmo
|
||||
Libc use tricks in the MS-DOS stub to check the operating mode and then
|
||||
jump to the appropriate entrypoint, e.g. `_start()`.
|
||||
|
||||
#### Decoded as i8086
|
||||
|
||||
```asm
|
||||
dec %bp
|
||||
pop %dx
|
||||
jno 0x4a
|
||||
jo 0x4a
|
||||
```
|
||||
|
||||
#### Decoded as i386
|
||||
|
||||
```asm
|
||||
push %ebp
|
||||
pop %edx
|
||||
jno 0x4a
|
||||
jo 0x4a
|
||||
```
|
||||
|
||||
#### Decoded as x86-64
|
||||
|
||||
```asm
|
||||
rex.WRB
|
||||
pop %r10
|
||||
jno 0x4a
|
||||
jo 0x4a
|
||||
```
|
||||
|
||||
### (2) APE UNIX-Only Magic
|
||||
|
||||
- ASCII: `jartsr='`
|
||||
- Hex: 6a 61 72 74 73 72 3d 27
|
||||
|
||||
Being a novel executable format that was first published in 2020, the
|
||||
APE file format is less understood by industry tools compared to the PE,
|
||||
ELF, and Mach-O executable file formats, which have been around for
|
||||
decades. For this reason, APE programs that use the MZ magic above can
|
||||
attract attention from Windows AV software, which may be unwanted by
|
||||
developers who aren't interested in targeting the Windows platform.
|
||||
Therefore the `jartsr='` magic is defined which enables the creation of
|
||||
APE binaries that can safely target all non-Windows platforms. Even
|
||||
though this magic is less common, APE interpreters and binfmt-misc
|
||||
installations MUST support this.
|
||||
|
||||
It is strongly recommended that this magic value be immediately followed
|
||||
by a newline (\n or hex 0a) character. Some shells, e.g. FreeBSD SH and
|
||||
Zsh impose a binary safety check before handing off files that don't
|
||||
have a shebang to `/bin/sh`. That check applies to the first line, which
|
||||
can't contain NUL characters.
|
||||
|
||||
The letters were carefully chosen so as to be valid x86 instructions in
|
||||
all operating modes. This makes it possible to store a BIOS bootloader
|
||||
disk image inside an APE binary. For example, simple CLI programs built
|
||||
with Cosmopolitan Libc will boot from BIOS into long mode if they're
|
||||
treated as a floppy disk image.
|
||||
|
||||
The letters also allow for the possibility of being treated on x86-64 as
|
||||
a flat executable, where the PE / ELF / Mach-O executable structures are
|
||||
ignored, and execution simply begins at the beginning of the file,
|
||||
similar to how MS-DOS .COM binaries work.
|
||||
|
||||
The 0x78 relative offset of the magic causes execution to jump into the
|
||||
MS-DOS stub defined by Portable Executable. APE binaries built by Cosmo
|
||||
Libc use tricks in the MS-DOS stub to check the operating mode and then
|
||||
jump to the appropriate entrypoint, e.g. `_start()`.
|
||||
|
||||
#### Decoded as i8086 / i386 / x86-64
|
||||
|
||||
```asm
|
||||
push $0x61
|
||||
jb 0x78
|
||||
jae 0x78
|
||||
```
|
||||
|
||||
### (3) APE Debug Magic
|
||||
|
||||
- ASCII: `APEDBG='`
|
||||
- Hex: 41 50 45 44 42 47 3d 27
|
||||
|
||||
While APE files must be valid shell scripts, in practice, UNIX systems
|
||||
will oftentimes be configured to provide a faster safer alternative to
|
||||
loading an APE binary through `/bin/sh`. The Linux Kernel can be patched
|
||||
to have execve() recognize the APE format and directly load its embedded
|
||||
ELF header. Linux systems can also use binfmt-misc to recognize APE's MZ
|
||||
and jartsr magic, and pass them to a userspace program named `ape` that
|
||||
acts as an interpreter. In such environments, the need sometimes arises
|
||||
to be able to test that the `/bin/sh` is working correctly, in which
|
||||
case the `APEDBG='` magic is RECOMMENDED.
|
||||
|
||||
APE interpreters, execve() implementations, and binfmt-misc installs
|
||||
MUST ignore this magic. If necessary, steps can be taken to help files
|
||||
with this magic be passed to `/bin/sh` like a normal shebang-less shell
|
||||
script for execution.
|
||||
|
||||
## Embedded ELF Header
|
||||
|
||||
APE binaries MAY embed an ELF header inside them. Unlike conventional
|
||||
executable file formats, this header is not stored at a fixed offset.
|
||||
It's instead encoded as octal escape codes in a shell script `printf`
|
||||
statement. For example:
|
||||
|
||||
```
|
||||
printf '\177ELF\2\1\1\011\0\0\0\0\0\0\0\0\2\0\076\0\1\0\0\0\166\105\100\000\000\000\000\000\060\013\000\000\000\000\000\000\000\000\000\000\000\000\000\000\165\312\1\1\100\0\070\0\005\000\0\0\000\000\000\000'
|
||||
```
|
||||
|
||||
This `printf` statement MUST appear in the first 8192 bytes of the APE
|
||||
executable, so as to limit how much of the initial portion of a file an
|
||||
interpreter must load.
|
||||
|
||||
Multiple such `printf` statements MAY appear in the first 8192 bytes, in
|
||||
order to specify multiple architectures. For example, fat binaries built
|
||||
by the `apelink` program (provided by Cosmo Libc) will have two encoded
|
||||
ELF headers, for AMD64 and ARM64, each of which point into the proper
|
||||
file offsets for their respective native code. Therefore, kernels and
|
||||
interpreters which load the APE format directly MUST check the
|
||||
`e_machine` field of the `Elf64_Ehdr` that's decoded from the octal
|
||||
codes, before accepting a `printf` shell statement as valid.
|
||||
|
||||
These printf statements MUST always use only unescaped ASCII characters
|
||||
or octal escape codes. These printf statements MUST NOT use space saving
|
||||
escape codes such as `\n`. For example, rather than saying `\n` it would
|
||||
be valid to say `\012` instead. It's also valid to say `\12` but only if
|
||||
the encoded characters that follow aren't an octal digit.
|
||||
|
||||
For example, the following algorithm may be used for parsing octal:
|
||||
|
||||
```c
|
||||
static int ape_parse_octal(const unsigned char page[8192], int i, int *pc)
|
||||
{
|
||||
int c;
|
||||
if ('0' <= page[i] && page[i] <= '7') {
|
||||
c = page[i++] - '0';
|
||||
if ('0' <= page[i] && page[i] <= '7') {
|
||||
c *= 8;
|
||||
c += page[i++] - '0';
|
||||
if ('0' <= page[i] && page[i] <= '7') {
|
||||
c *= 8;
|
||||
c += page[i++] - '0';
|
||||
}
|
||||
}
|
||||
*pc = c;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
```
|
||||
|
||||
APE aware interpreters SHOULD only take `e_machine` into consideration.
|
||||
It is the responsibility of the `_start()` function to detect the OS.
|
||||
Therefore, multiple `printf` statements are only embedded in the shell
|
||||
script for different CPU architectures.
|
||||
|
||||
The OS ABI field of an APE embedded `Elf64_Ehdr` SHOULD be set to
|
||||
`ELFOSABI_FREEBSD`, since it's the only UNIX OS APE supports that
|
||||
actually checks the field. However different values MAY be chosen for
|
||||
binaries that don't intend to have FreeBSD in their support vector.
|
||||
|
||||
Counter-intuitively, the ARM64 ELF header is used on the MacOS ARM64
|
||||
platform when loading from fat binaries.
|
||||
|
||||
## Embedded Mach-O Header (x86-64 only)
|
||||
|
||||
APE shell scripts that support MacOS on AMD64 must use the `dd` command
|
||||
in a very specific way to specify how the embedded binary Macho-O header
|
||||
is copied backward to the start of the file. For example:
|
||||
|
||||
```
|
||||
dd if="$o" of="$o" bs=8 skip=433 count=66 conv=notrunc
|
||||
```
|
||||
|
||||
These `dd` statements have traditionally been generated by the GNU as
|
||||
and ld.bfd programs by encoding ASCII into 64-bit linker relocations,
|
||||
which necessitated a fixed width for integer values. It took several
|
||||
iterations over APE's history before we eventually got it right:
|
||||
|
||||
- `arg=" 9293"` is how we originally had ape do it
|
||||
- `arg=$(( 9293))` b/c busybox sh disliked quoted space
|
||||
- `arg=9293 ` is generated by modern apelink program
|
||||
|
||||
Software that parses the APE file format, which needs to extract the
|
||||
Macho-O x86-64 header SHOULD support the old binaries that use the
|
||||
previous encodings. To make backwards compatibility simple the following
|
||||
regular expression may be used, which generalizes to all defined
|
||||
formats:
|
||||
|
||||
```c
|
||||
regcomp(&rx,
|
||||
"bs=" // dd block size arg
|
||||
"(['\"] *)?" // #1 optional quote w/ space
|
||||
"(\\$\\(\\( *)?" // #2 optional math w/ space
|
||||
"([[:digit:]]+)" // #3
|
||||
"( *\\)\\))?" // #4 optional math w/ space
|
||||
"( *['\"])?" // #5 optional quote w/ space
|
||||
" +" //
|
||||
"skip=" // dd skip arg
|
||||
"(['\"] *)?" // #6 optional quote w/ space
|
||||
"(\\$\\(\\( *)?" // #7 optional math w/ space
|
||||
"([[:digit:]]+)" // #8
|
||||
"( *\\)\\))?" // #9 optional math w/ space
|
||||
"( *['\"])?" // #10 optional quote w/ space
|
||||
" +" //
|
||||
"count=" // dd count arg
|
||||
"(['\"] *)?" // #11 optional quote w/ space
|
||||
"(\\$\\(\\( *)?" // #12 optional math w/ space
|
||||
"([[:digit:]]+)", // #13
|
||||
REG_EXTENDED);
|
||||
```
|
||||
|
||||
For further details, see the canonical implementation in
|
||||
`cosmopolitan/tool/build/assimilate.c`.
|
||||
|
||||
## Static Linking
|
||||
|
||||
Actually Portable Executables are always statically linked. This
|
||||
revision of the specification does not define any facility for storing
|
||||
code in dynamic shared objects.
|
||||
|
||||
Cosmopolitan Libc provides a solution that enables APE binaries have
|
||||
limited access to dlopen(). By manually loading a platform-specific
|
||||
executable and asking the OS-specific libc's dlopen() to load
|
||||
OS-specific libraries, it becomes possible to use GPUs and GUIs. This
|
||||
has worked great for AI projects like llamafile.
|
||||
|
||||
There is no way for an Actually Portable Executable to interact with
|
||||
OS-specific dynamic shared object extension modules to programming
|
||||
languages. For example, a Lua interpreter compiled as an Actually
|
||||
Portable Executable would have no way of linking extension libraries
|
||||
downloaded from the Lua Rocks package manager. This is primarily because
|
||||
different OSes define incompatible ABIs.
|
||||
|
||||
While it was possible to polyglot PE+ELF+MachO to create multi-OS
|
||||
executables, it simply isn't possible to do that same thing for
|
||||
DLL+DYLIB+SO. Therefore, in order to have DSOs, APE would need to either
|
||||
choose one of the existing formats or invent one of its own, and then
|
||||
develop its own parallel ecosystem of extension software. In the future,
|
||||
the APE specification may expand to encompass this. However the focus to
|
||||
date has been exclusively on executables with limited dlopen() support.
|
||||
|
||||
## Application Binary Interface (ABI)
|
||||
|
||||
APE binaries use the System V ABI, as defined by:
|
||||
|
||||
- [System V ABI - AMD64 Architecture Processor Supplement](https://gitlab.com/x86-psABIs/x86-64-ABI)
|
||||
- AARCH64 has a uniform consensus defined by ARM Limited
|
||||
|
||||
There are however a few changes we've had to make.
|
||||
|
||||
### No Red Zone
|
||||
|
||||
Actually Portable Executables that have Windows and/or bare metal in
|
||||
their support vector MUST be compiled using `-mno-red-zone`. This is
|
||||
because, on Windows, DLLs and other software lurking in the va-space
|
||||
might use tricks like SetThreadContext() to take control of a thread
|
||||
whereas on bare metal, it's also generally accepted that kernel-mode
|
||||
code cannot assume a red zone either due to hardware interrupts that
|
||||
pull the exact same kinds of stunts.
|
||||
|
||||
APE software that only has truly System V ABI conformant OSes (e.g.
|
||||
Linux) in their support vector MAY use the red zone optimization.
|
||||
|
||||
### Thread Local Storage
|
||||
|
||||
#### aarch64
|
||||
|
||||
Here's the TLS memory layout on aarch64:
|
||||
|
||||
```
|
||||
x28
|
||||
%tpidr_el0
|
||||
│
|
||||
│ _Thread_local
|
||||
┌───┼───┬──────────┬──────────┐
|
||||
│tib│dtv│ .tdata │ .tbss │
|
||||
├───┴───┴──────────┴──────────┘
|
||||
│
|
||||
__get_tls()
|
||||
```
|
||||
|
||||
The ARM64 code in actually portable executables use the `x28` register
|
||||
to store the address of the thread information block. All aarch64 code
|
||||
linked into these executables SHOULD be compiled with `-ffixed-x28`
|
||||
which is supported by both Clang and GCC.
|
||||
|
||||
The runtime library for an actually portable executables MAY choose to
|
||||
use `tpidr_el0` instead, if OSes like MacOS aren't being targeted. For
|
||||
example, if the goal is to create a Linux-only fat binary linker program
|
||||
for Musl Libc, then choosing to use the existing `tpidr_el0` convention
|
||||
would be friction-free alternative.
|
||||
|
||||
It's not possible for an APE runtime that targets the full range of OSes
|
||||
to use the `tpidr_el0` register for TLS because Apple won't allow it. On
|
||||
MacOS ARM64 systems, this register can only be used by a runtime to
|
||||
implement the `sched_getcpu()` system call. It's reserved by MacOS.
|
||||
|
||||
#### x86-64
|
||||
|
||||
Here's the TLS memory layout on x86_64:
|
||||
|
||||
```
|
||||
__get_tls()
|
||||
│
|
||||
%fs OpenBSD/NetBSD
|
||||
_Thread_local │
|
||||
┌───┬──────────┬──────────┼───┐
|
||||
│pad│ .tdata │ .tbss │tib│
|
||||
└───┴──────────┴──────────┼───┘
|
||||
│
|
||||
Linux/FreeBSD/Windows/Mac %gs
|
||||
```
|
||||
|
||||
Quite possibly the greatest challenge in Actually Portable Executable
|
||||
working, has been overcoming the incompatibilities between OSes in how
|
||||
thread-local storage works on x86-64. The AMD64 architecture defines two
|
||||
special segment registers. Every OS uses one of these segment registers
|
||||
to implement TLS support. However not all OSes agree on which register
|
||||
to use. Some OSes grant userspace the power to define either of these
|
||||
registers to hold any value that is desired. Some OSes only effectively
|
||||
allow a single one of them to be changed. Lastly, some OSes, e.g.
|
||||
Windows, claim ownership of the memory layout these registers point
|
||||
towards too.
|
||||
|
||||
Here's a breakdown on how much power is granted to userspace runtimes by
|
||||
each OS when it comes to changing amd64 segment registers.
|
||||
|
||||
| | %fs | %gs |
|
||||
|---------|--------------|--------------|
|
||||
| Linux | unrestricted | unrestricted |
|
||||
| MacOS | inaccessible | unrestricted |
|
||||
| Windows | inaccessible | restricted |
|
||||
| FreeBSD | unrestricted | unrestricted |
|
||||
| NetBSD | unrestricted | broken |
|
||||
| OpenBSD | unrestricted | inaccessible |
|
||||
|
||||
Therefore, regardless of which register one we choose, some OSes are
|
||||
going to be incompatible.
|
||||
|
||||
APE binaries are always built with a Linux compiler. So another issue
|
||||
arises in the fact that our Linux-flavored GCC and Clang toolchains
|
||||
(which are used to produce cross-OS binaries) are also only capable of
|
||||
producing TLS instructions that use the %fs convention.
|
||||
|
||||
To solve these challenges, the `cosmocc` compiler will rewrite binary
|
||||
objects after they've been compiled by GCC, so that the `%gs` register
|
||||
is used, rather than `%fs`. Morphing x86-64 binaries after they've been
|
||||
compiled is normally difficult, due to the complexity of the machine
|
||||
instruction language. However GCC provides `-mno-tls-direct-seg-refs`
|
||||
which greatly reduces the complexity of this task. This flag forgoes
|
||||
some optimizations to make the generated code simpler. Rather than doing
|
||||
clever arithmetic with `%fs` prefixes, the compiler will always generate
|
||||
the thread information block address load as a separate instruction.
|
||||
|
||||
```c
|
||||
// Change AMD code to use %gs:0x30 instead of %fs:0
|
||||
// We assume -mno-tls-direct-seg-refs has been used
|
||||
static void ChangeTlsFsToGs(unsigned char *p, size_t n) {
|
||||
unsigned char *e = p + n - 9;
|
||||
while (p <= e) {
|
||||
// we're checking for the following expression:
|
||||
// 0144 == p[0] && // %fs
|
||||
// 0110 == (p[1] & 0373) && // rex.w (and ignore rex.r)
|
||||
// (0213 == p[2] || // mov reg/mem → reg (word-sized)
|
||||
// 0003 == p[2]) && // add reg/mem → reg (word-sized)
|
||||
// 0004 == (p[3] & 0307) && // mod/rm (4,reg,0) means sib → reg
|
||||
// 0045 == p[4] && // sib (5,4,0) → (rbp,rsp,0) → disp32
|
||||
// 0000 == p[5] && // displacement (von Neumann endian)
|
||||
// 0000 == p[6] && // displacement
|
||||
// 0000 == p[7] && // displacement
|
||||
// 0000 == p[8] // displacement
|
||||
uint64_t w = READ64LE(p) & READ64LE("\377\373\377\307\377\377\377\377");
|
||||
if ((w == READ64LE("\144\110\213\004\045\000\000\000") ||
|
||||
w == READ64LE("\144\110\003\004\045\000\000\000")) &&
|
||||
!p[8]) {
|
||||
p[0] = 0145; // change %fs to %gs
|
||||
p[5] = 0x30; // change 0 to 0x30
|
||||
p += 9;
|
||||
} else {
|
||||
++p;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
By favoring `%gs` we've now ensured friction-free compatibility for the
|
||||
APE runtime on MacOS, Linux, and FreeBSD which are all able to conform
|
||||
easily to this convention. However additional work needs to be done at
|
||||
runtime when an APE program is started on Windows, OpenBSD, and NetBSD.
|
||||
On these platforms, all executable pages must be faulted and morphed to
|
||||
fixup the TLS instructions.
|
||||
|
||||
On OpenBSD and NetBSD, this is as simple as undoing the example
|
||||
operation above. Earlier at compile-time we turned `%fs` into `%gs`.
|
||||
Now, at runtime, `%gs` must be turned back into `%fs`. Since the
|
||||
executable is morphing itself, this is easier said than done.
|
||||
|
||||
OpenBSD for example enforces a `W^X` invariant. Code that's executing
|
||||
can't modify itself at the same time. The way Cosmopolitan solves this
|
||||
is by defining a special part of the binary called `.text.privileged`.
|
||||
This section is aligned to page boundaries. A GNU ld linker script is
|
||||
used to ensure that code which morphs code is placed into this section,
|
||||
through the use of a header-defined cosmo-specific keyword `privileged`.
|
||||
Additionally, the `fixupobj` program is used by the Cosmo build system
|
||||
to ensure that compiled objects don't contain privileged functions that
|
||||
call non-privileged functions. Needless to say, `mprotect()` needs to be
|
||||
a privileged function, so that it can be used to disable the execute bit
|
||||
on all other parts of the executable except for the privileged section,
|
||||
thereby making it writable. Once this has been done, code can change.
|
||||
|
||||
On Windows the displacement bytes of the TLS instruction are changed to
|
||||
use the `%gs:0x1480+i*8` ABI where `i` is a number assigned by the WIN32
|
||||
`TlsAlloc()` API. This avoids the need to call `TlsGetValue()` which is
|
||||
implemented this exact same way under the hood. Even though 0x1480 isn't
|
||||
explicitly documented by MSDN, this ABI is believed to be stable because
|
||||
MSVC generates binaries that use this offset directly. The only caveat
|
||||
is that `TlsAlloc()` must be called as early in the runtime init as
|
||||
possible, to ensure an index less than 64 is returned.
|
||||
|
||||
### Thread Information Block (TIB)
|
||||
|
||||
The Actually Portable Executable Thread Information Block (TIB) is
|
||||
defined by this version of the specification as follows:
|
||||
|
||||
- The 64-bit TIB self-pointer is stored at offset 0x00.
|
||||
- The 64-bit TIB self-pointer is also stored at offset 0x30.
|
||||
- The 32-bit `errno` value is stored at offset 0x3c.
|
||||
|
||||
All other parts of the thread information block should be considered
|
||||
unspecified and therefore reserved for future specifications.
|
||||
|
||||
The APE thread information block is aligned on a 64-byte boundary.
|
||||
|
||||
Cosmopolitan Libc v3.5.8 (c. 2024-07-21) currently implements a thread
|
||||
information block that's 512 bytes in size.
|
||||
|
||||
### Foreign Function Calls
|
||||
|
||||
Even though APE programs always use the System V ABI, there arises the
|
||||
occasional need to interface with foreign functions, e.g. WIN32. The
|
||||
`__attribute__((__ms_abi__))` annotation introduced by GCC v6 is used
|
||||
for this purpose.
|
||||
|
||||
The ability to change a function's ABI on a case-by-case basis is
|
||||
surprisingly enough supported by GCC, Clang, NVCC, and even the AMD HIP
|
||||
compilers for both UNIX systems and Windows. All of these compilers
|
||||
support both the System V ABI and the Microsoft x64 ABI.
|
||||
|
||||
APE binaries will actually favor the Microsoft ABI even when running on
|
||||
UNIX OSes for certain dlopen() use-cases. For example, if we control the
|
||||
code to a CUDA module, which we compile on each OS separately from our
|
||||
main APE binary, then any function that's inside the APE binary whose
|
||||
pointer may be passed into a foreign module SHOULD be compiled to use
|
||||
the Microsoft ABI. This is because in practice the OS-specific module
|
||||
may need to be compiled by MSVC, where MS ABI is the *only* ABI, which
|
||||
forces our UNIX programs to partially conform. Thankfully, all UNIX
|
||||
compilers support doing it on a case-by-case basis.
|
||||
|
||||
### Char Signedness
|
||||
|
||||
Actually Portable Executable defines `char` as signed.
|
||||
|
||||
Therefore conformant APE software MUST use `-fsigned-char` when building
|
||||
code for aarch64, as well as any other architecture that (unlike x86-64)
|
||||
would otherwise define `char` as being `unsigned char` by default.
|
||||
|
||||
This decision was one of the cases where it made sense to offer a more
|
||||
consistent runtime experience for fat multi-arch binaries. However you
|
||||
SHOULD still write code to assume `char` can go either way. But if all
|
||||
you care about is using APE, then you CAN assume `char` is signed.
|
||||
|
||||
### Long Double
|
||||
|
||||
On AMD64 platforms, APE binaries define `long double` as 80-bit.
|
||||
|
||||
On ARM64 platforms, APE binaries define `long double` as 128-bit.
|
||||
|
||||
We accept inconsistency in this case, because hardware acceleration is
|
||||
far more valuable than stylistic consistency in the case of mathematics.
|
||||
|
||||
One challenge arises on AMD64 for supporting `long double` across OSes.
|
||||
Unlike UNIX systems, the Windows Executive on x86-64 initializes the x87
|
||||
FPU to have double (64-bit) precision rather than 80-bit. That's because
|
||||
code compiled by MSVC treats `long double` as though it were `double` to
|
||||
prefer always using the more modern SSE instructions. However System V
|
||||
requires genuine 80-bit `long double` support on AMD64.
|
||||
|
||||
Therefore, if an APE program detects that it's been started on a Windows
|
||||
x86-64 system, then it SHOULD use the following assembly to initialize
|
||||
the x87 FPU in System V ABI mode.
|
||||
|
||||
```asm
|
||||
fldcw 1f(%rip)
|
||||
.rodata
|
||||
.balign 2
|
||||
// 8087 FPU Control Word
|
||||
// IM: Invalid Operation ───────────────┐
|
||||
// DM: Denormal Operand ───────────────┐│
|
||||
// ZM: Zero Divide ───────────────────┐││
|
||||
// OM: Overflow ─────────────────────┐│││
|
||||
// UM: Underflow ───────────────────┐││││
|
||||
// PM: Precision ──────────────────┐│││││
|
||||
// PC: Precision Control ───────┐ ││││││
|
||||
// {float,∅,double,long double}│ ││││││
|
||||
// RC: Rounding Control ──────┐ │ ││││││
|
||||
// {even, →-∞, →+∞, →0} │┌┤ ││││││
|
||||
// ┌┤││ ││││││
|
||||
// d││││rr││││││
|
||||
1: .short 0b00000000000000000001101111111
|
||||
.previous
|
||||
```
|
||||
|
||||
## Executable File Alignment
|
||||
|
||||
Actually Portable Executable is a statically-linked flat executable file
|
||||
format that is, as a thing in itself, agnostic to file alignments. For
|
||||
example, the shell script payload at the beginning of the file and its
|
||||
statements have no such requirements. Alignment requirements are however
|
||||
imposed by the executable formats that APE wraps.
|
||||
|
||||
1. ELF requires that file offsets be congruent with virtual addresses
|
||||
modulo the CPU page size. So when we add a shell script to the start
|
||||
of an executable, we need to round up to the page size in order to
|
||||
maintain ELF's invariant. Although no such roundup is required on the
|
||||
program segments once the invariant is restored. ELF loaders will
|
||||
happily map program headers from arbitrary file intervals (which may
|
||||
overlap) onto arbitrarily virtual intervals (which don't need to be
|
||||
contiguous). In order to do that, the loaders will generally use
|
||||
UNIX's mmap() function which is more restrictive and only accepts
|
||||
addresses and offsets that are page aligned. To make it possible to
|
||||
map an unaligned ELF program header that could potentially start and
|
||||
stop at any byte, ELF loaders round-out the intervals, which means
|
||||
adjacent unrelated data might also get mapped, which may need to be
|
||||
explicitly zero'd. Thanks to the cleverness of ELF, it's possible to
|
||||
have an executable file be very tiny, without needing any alignment
|
||||
bytes, and it'll be loaded into a properly aligned virtual space
|
||||
where segments can be as sparse as we want them to be.
|
||||
|
||||
2. PE doesn't care about congruence and instead defines two separate
|
||||
kinds of alignment. First, PE requires that the layout of segment
|
||||
memory inside the file be aligned on at minimum the classic 512 byte
|
||||
MS-DOS page size. This means that, unlike ELF, some alignment padding
|
||||
may need to be encoded into the file, making it slightly larger. Next
|
||||
PE imposes an alignment restriction on segments once they've been
|
||||
mapped into the virtual address space, which must be rounded to the
|
||||
system page size. Like ELF, PE segments need to be properly ordered
|
||||
but they're allowed to drift apart once mapped in a non-contiguous
|
||||
sparsely mapped way. When inserting shell script content at the start
|
||||
of a PE file, the most problematic thing is the need to round up to
|
||||
the 64kb system granularity, which results in a lot of needless bytes
|
||||
of padding being inserted by a naive second-pass linker.
|
||||
|
||||
3. Apple's Mach-O format is the strictest of them all. While both ELF
|
||||
and PE are defined in such a way that invites great creativity, XNU
|
||||
will simply refuse to an executable that does anything creative with
|
||||
alignment. All loaded segments need to both start and end on a page
|
||||
aligned address. XNU also wants segments to be contiguous similar to
|
||||
portable executable, except it applies to both the file and virtual
|
||||
spaces, which must follow the same structure.
|
||||
|
||||
Actually Portable Executables must conform to the strictest requirements
|
||||
demanded by the support vector. Therefore an APE binary that has headers
|
||||
for all three of the above executable formats MUST conform to the Apple
|
||||
way of doing things. GNU ld linker scripts aren't very good at producing
|
||||
ELF binaries that rigidly conform to this simple naive layout. There are
|
||||
so many ways things can go wrong, where third party code might slip its
|
||||
own custom section name in-between the linker script sections that are
|
||||
explicitly defined, thereby causing ELF's powerful features to manifest
|
||||
and the resulting content overlapping. The best `ld` flag that helps is
|
||||
`--orphan-handling=error` which can help with explaining such mysteries.
|
||||
|
||||
While Cosmopolitan was originally defined to just use stock GNU tools,
|
||||
this proved intractable over time, and the project has been evolving in
|
||||
the direction of building its own. Inventing the `apelink` program was
|
||||
what enabled the project to achieve multi-architecture binaries whereas
|
||||
previously it was only possible to do multi-OS binaries. In the future,
|
||||
our hope is that a fast power linker like Mold can be adapted to produce
|
||||
fat APE binaries directly from object files in one pass.
|
||||
|
||||
## Position Independent Code
|
||||
|
||||
APE doesn't currently support position independent executable formats.
|
||||
This is because APE was originally written for the GNU linker, where PIC
|
||||
and PIE were after-thoughts and never fully incorporated with the older
|
||||
more powerful linker script techniques upon which APE relies. Future
|
||||
iterations of this specification are intended to converge on modern
|
||||
standards, as our tooling becomes developed enough to support it.
|
||||
|
||||
However this only applies to the wrapped executable formats themselves.
|
||||
While our convention to date has been to always load ELF programs at the
|
||||
4mb mark, this is not guaranteed across OSes and architectures. Programs
|
||||
should have no expectations that a program will be loaded to any given
|
||||
address. For example, Cosmo currently implements APE on AARCH64 as
|
||||
loading executables to a starting address of 0x000800000000. This
|
||||
address occupies a sweet spot of requirements.
|
||||
|
||||
## Address Space
|
||||
|
||||
In order to create a single binary that supports as many platforms as
|
||||
possible without needing to be recompiled, there's a very narrow range
|
||||
of addresses that can be used. That range is somewhere between 32 bits
|
||||
and 39 bits.
|
||||
|
||||
- Embedded devices that claim to be 64-bit will oftentimes only support
|
||||
a virtual address space that's 39 bits in size.
|
||||
|
||||
- We can't load executable images on AARCH64 beneath 0x100000000 (4gb)
|
||||
because Apple forbids doing that, possibly in an effort to enforce a
|
||||
best practice for spotting 32-bit to 64-bit transition bugs. Please
|
||||
note that this restriction only applies to Apple ARM64 systems. The
|
||||
x86-64 version of XNU will happily load APE binaries to 0x00400000.
|
||||
|
||||
- The AMD64 architecture on desktops and servers can usually be counted
|
||||
upon to provide a 47-bit address space. The Linux Kernel for instance
|
||||
grants each userspace program full dominion over addresses 0x00200000
|
||||
through 0x00007fffffffffff provided the hardware supports this. On
|
||||
modern workstations supporting Intel and AMD's new PML5T feature which
|
||||
virtualizes memory using a radix trie that's five layers deep, Linux
|
||||
is able to offer userspace its choice of fixed addresses from
|
||||
0x00200000 through 0x00ffffffffffffff. The only exception to this rule
|
||||
we've encountered so far is that Windows 7 and Windows Vista behaved
|
||||
similar to embedded devices in reducing the number of va bits.
|
||||
|
||||
## Page Size
|
||||
|
||||
APE software MUST be page size agnostic. For many years the industry had
|
||||
converged on a strong consensus of having a page size that's 4096 bytes.
|
||||
However this convention was never guaranteed. New computers have become
|
||||
extremely popular, such as Apple Silicon, that use a 16kb page size.
|
||||
|
||||
By convention, Cosmopolitan Libc currently generates ELF headers for
|
||||
x86-64 that are strictly aligned on a 4096-byte page size. On ARM64
|
||||
Cosmopolitan is currently implemented to always generate ELF headers
|
||||
aligned on a 16kb page size.
|
||||
|
||||
In addition to being page size agnostic, APE software that cares about
|
||||
working correctly on Windows needs to be aware of the concept of
|
||||
allocation granularity. While the page size on Windows is generally 4kb
|
||||
in size, memory mappings can only be created on addresses that aligned
|
||||
to the system allocation granularity, which is generally 64kb. If you
|
||||
use a function like mmap() with Cosmopolitan Libc, then the `addr` and
|
||||
`offset` parameters need to be aligned to `sysconf(_SC_GRANSIZE)` or
|
||||
else your software won't work on Windows. Windows has other limitations
|
||||
too, such as lacking the ability to carve or punch holes in mappings.
|
74
ape/start.S
74
ape/start.S
|
@ -1,74 +0,0 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│ vi: set noet ft=asm ts=8 sw=8 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/dce.h"
|
||||
#include "ape/ape.h"
|
||||
#include "libc/macros.h"
|
||||
|
||||
#ifdef __aarch64__
|
||||
|
||||
_start: mov x1,sp
|
||||
and sp,x1,#-16
|
||||
mov x29,0
|
||||
bl ApeLoader
|
||||
.endfn _start,globl
|
||||
|
||||
#else
|
||||
|
||||
XnuEntrypoint:
|
||||
mov $_HOSTXNU,%dl // xnu's not unix!
|
||||
ElfEntrypoint:
|
||||
mov %rsp,%rsi // save real stack
|
||||
andq $-16,%rsp // force SSE alignment
|
||||
call ApeLoader
|
||||
.endfn ElfEntrypoint,globl
|
||||
.endfn XnuEntrypoint,globl
|
||||
|
||||
.section .note,"a",@progbits
|
||||
.balign 4
|
||||
openbsd.ident:
|
||||
.long 2f-1f
|
||||
.long 4f-3f
|
||||
.long 1
|
||||
1: .asciz "OpenBSD"
|
||||
2: .balign 4
|
||||
3: .long 0
|
||||
4: .size openbsd.ident,.-openbsd.ident
|
||||
.type openbsd.ident,@object
|
||||
.balign 4
|
||||
netbsd.ident:
|
||||
.long 2f-1f
|
||||
.long 4f-3f
|
||||
.long 1
|
||||
1: .asciz "NetBSD"
|
||||
2: .balign 4
|
||||
3: .long 901000000
|
||||
4: .size netbsd.ident,.-netbsd.ident
|
||||
.type netbsd.ident,@object
|
||||
.balign 4
|
||||
ape.ident:
|
||||
.long 2f-1f
|
||||
.long 4f-3f
|
||||
.long 1
|
||||
1: .asciz "APE"
|
||||
2: .balign 4
|
||||
3: .long APE_VERSION_NOTE
|
||||
4: .size ape.ident,.-ape.ident
|
||||
.type ape.ident,@object
|
||||
|
||||
#endif
|
|
@ -1,49 +0,0 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│ vi: set noet ft=asm ts=8 sw=8 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/macros.h"
|
||||
|
||||
// Invokes system call.
|
||||
//
|
||||
// This function has eight parameters. The first seven are for
|
||||
// arguments passed along to the system call. The eight is for
|
||||
// the magic number that indicates which system call is called
|
||||
//
|
||||
// The return value follows the Linux kernel convention, where
|
||||
// errors are returned as `-errno`. BSD systems are normalized
|
||||
// to follow this convention automatically.
|
||||
SystemCall:
|
||||
#ifdef __aarch64__
|
||||
mov x8,x7
|
||||
mov x9,0
|
||||
adds x9,x9,0
|
||||
svc 0
|
||||
bcs 1f
|
||||
ret
|
||||
1: neg x0,x0
|
||||
ret
|
||||
#else
|
||||
mov %rcx,%r10
|
||||
mov 16(%rsp),%eax
|
||||
clc
|
||||
syscall
|
||||
jnc 1f
|
||||
neg %rax
|
||||
1: ret
|
||||
#endif
|
||||
.endfn SystemCall,globl
|
29
build/actuallynice
Executable file
29
build/actuallynice
Executable file
|
@ -0,0 +1,29 @@
|
|||
#!/bin/sh
|
||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# Program Deprioritizer
|
||||
#
|
||||
# OVERVIEW
|
||||
#
|
||||
# This is a drop-in replacement for the traditional Unix `nice`
|
||||
# command that also invokes `ionice`, which is important, since
|
||||
# network and traffic is usually what clobber the system.
|
||||
|
||||
if [ -z "$IONICE" ]; then
|
||||
if IONICE=$(command -v ionice 2>/dev/null); then
|
||||
IONICE="$IONICE -c3"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$NICE" ]; then
|
||||
NICE=$(command -v nice 2>/dev/null)
|
||||
fi
|
||||
|
||||
if [ -z "$IONICE$NICE" ]; then
|
||||
echo "error: can't be nice" >&2
|
||||
fi
|
||||
|
||||
exec $IONICE $NICE "$@"
|
53
build/archive
Executable file
53
build/archive
Executable file
|
@ -0,0 +1,53 @@
|
|||
#!/bin/sh
|
||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
||||
#
|
||||
# OVERVIEW
|
||||
#
|
||||
# Cosmopolitan Archiver
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This goes 100x faster than ar and ranlib.
|
||||
#
|
||||
# EXAMPLE
|
||||
#
|
||||
# build/archive rcsD library.a foo.o ...
|
||||
|
||||
MKDIR=${MKDIR:-$(command -v mkdir) -p} || exit
|
||||
if [ -x "o//tool/build/ar.com" ]; then
|
||||
set -- "o//tool/build/ar.com" "$@"
|
||||
else
|
||||
if [ ! -x o/build/bootstrap/ar.com ]; then
|
||||
mkdir -p o/build/bootstrap &&
|
||||
cp -f build/bootstrap/ar.com o/build/bootstrap/ar.com.$$ &&
|
||||
mv -f o/build/bootstrap/ar.com.$$ o/build/bootstrap/ar.com || exit
|
||||
fi
|
||||
set -- o/build/bootstrap/ar.com "$@"
|
||||
fi
|
||||
OUT=$3
|
||||
|
||||
printf "$LOGFMT" "${ACTION:-ARCHIVE.a}" "$OUT" >&2
|
||||
# if [ "$V" = "0" ]; then
|
||||
# printf "$LOGFMT" "${ACTION:-ARCHIVE.a}" "$OUT" >&2
|
||||
# else
|
||||
# # some of these windows nt archives are quite huge
|
||||
# COLUMNS=${COLUMNS:-80}
|
||||
# COLUMNS=$((COLUMNS - 4))
|
||||
# printf "%s\n" "$*" |
|
||||
# /usr/bin/fold -s -w $COLUMNS |
|
||||
# sed -e '1bb' -e 's/^/ /' -e ':b' -e '$b' -e 's/$/ \\/' >&2
|
||||
# fi
|
||||
|
||||
REASON=failed
|
||||
trap REASON=interrupted INT
|
||||
|
||||
"$@" >/dev/null && exit
|
||||
|
||||
if [ "$TERM" = "dumb" ]; then
|
||||
f='%s %s\r\n\r\n'
|
||||
else
|
||||
f='\033[91m%s\033[39m \033[94m%s\033[39m\r\n\r\n'
|
||||
fi
|
||||
printf "$f" "archive $REASON:" "$*" >&2
|
||||
exit 1
|
49
build/assemble
Executable file
49
build/assemble
Executable file
|
@ -0,0 +1,49 @@
|
|||
#!/bin/sh
|
||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
||||
#
|
||||
# OVERVIEW
|
||||
#
|
||||
# GNU Assembler Veneer
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This script wraps normal assembler commands that're transparently
|
||||
# passed-through. It adds ephemeral logging and directory creation.
|
||||
#
|
||||
# EXAMPLE
|
||||
#
|
||||
# TARGET=program build/assemble as -o program program.o
|
||||
#
|
||||
# SEE ALSO
|
||||
#
|
||||
# https://justine.storage.googleapis.com/perm/as.pdf
|
||||
|
||||
if [ ! -d o/third_party/gcc ]; then
|
||||
third_party/gcc/unbundle.sh
|
||||
fi
|
||||
|
||||
MKDIR=${MKDIR:-$(command -v mkdir) -p} || exit
|
||||
|
||||
if [ "$V" = "0" ]; then
|
||||
printf "$LOGFMT" "${ACTION:-OBJECTIFY.s}" "$TARGET" >&2
|
||||
else
|
||||
printf "%s\n" "$*" >&2
|
||||
fi
|
||||
|
||||
if [ "$TARGET" ]; then
|
||||
TARGETDIR="${TARGET%/*}"
|
||||
if [ "$TARGETDIR" != "$TARGET" ] && [ ! -d "$TARGETDIR" ]; then
|
||||
$MKDIR "$TARGETDIR" || exit 2
|
||||
fi
|
||||
fi
|
||||
|
||||
"$@" && exit
|
||||
|
||||
if [ "$TERM" = "dumb" ]; then
|
||||
f='%s %s\r\n\r\n'
|
||||
else
|
||||
f='\033[91m%s\033[39m \033[94m%s\033[39m\r\n\r\n'
|
||||
fi
|
||||
printf "$f" "assemble failed:" "$*" >&2
|
||||
exit 1
|
9
build/bochs-debugger
Executable file
9
build/bochs-debugger
Executable file
|
@ -0,0 +1,9 @@
|
|||
#!/bin/sh
|
||||
# -*- mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8 -*-
|
||||
# vi: set net ft=sh ts=2 sts=2 sw=2 fenc=utf-8 :vi
|
||||
|
||||
echo c |
|
||||
bochs \
|
||||
-q \
|
||||
-f ape/etc/bochsrc.dbg \
|
||||
floppya:1_44=$1,status=inserted
|
51
build/bochs-scriptable
Executable file
51
build/bochs-scriptable
Executable file
|
@ -0,0 +1,51 @@
|
|||
#!/bin/sh
|
||||
# -*- mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8 -*-
|
||||
# vi: set net ft=sh ts=2 sts=2 sw=2 fenc=utf-8 :vi
|
||||
#
|
||||
# bochs-scriptable executes a disk with serial uart stdio.
|
||||
#
|
||||
# USAGE
|
||||
#
|
||||
# build/bochs-scriptable IMAGE...
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This script is useful for end-to-end testing metal apps in <100ms.
|
||||
#
|
||||
# SEE ALSO
|
||||
#
|
||||
# build/boot(1)
|
||||
|
||||
while getopts h X; do
|
||||
case $X in
|
||||
h) exec less "$0" ;;
|
||||
\?) echo "$0: bad arg" >&2; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
trap '' INT
|
||||
|
||||
IMG=$1
|
||||
OUT=/tmp/$USER.$$.bochs.stdout
|
||||
ERR=/tmp/$USER.$$.bochs.stderr
|
||||
|
||||
mkfifo $OUT || exit
|
||||
|
||||
cat <$OUT &
|
||||
CAT=$!
|
||||
exec 4>$OUT
|
||||
rm -f $OUT
|
||||
|
||||
echo c |
|
||||
bochs \
|
||||
-q \
|
||||
-f ape/etc/bochsrc.ffs \
|
||||
display_library:nogui \
|
||||
floppya:1_44=$1,status=inserted \
|
||||
>>$ERR 2>>$ERR
|
||||
RC=$?
|
||||
|
||||
kill $CAT
|
||||
exec 4>&-
|
||||
rm -f $ERR
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
build/bootstrap/ar.com
Executable file
BIN
build/bootstrap/ar.com
Executable file
Binary file not shown.
Binary file not shown.
BIN
build/bootstrap/compile.com
Executable file
BIN
build/bootstrap/compile.com
Executable file
Binary file not shown.
|
@ -1,58 +0,0 @@
|
|||
--nocompress-debug-sections
|
||||
--noexecstack
|
||||
-Wa,--nocompress-debug-sections
|
||||
-Wa,--noexecstack
|
||||
-Wa,-msse2avx
|
||||
-Werror=maybe-uninitialized
|
||||
-Wno-literal-suffix
|
||||
-Wno-unused-but-set-variable
|
||||
-Wunsafe-loop-optimizations
|
||||
-fbranch-target-load-optimize
|
||||
-fcx-limited-range
|
||||
-fdelete-dead-exceptions
|
||||
-femit-struct-debug-baseonly
|
||||
-ffp-int-builtin-inexact
|
||||
-finline-functions-called-once
|
||||
-fipa-pta
|
||||
-fivopts
|
||||
-flimit-function-alignment
|
||||
-fmerge-constants
|
||||
-fmodulo-sched
|
||||
-fmodulo-sched-allow-regmoves
|
||||
-fno-align-jumps
|
||||
-fno-align-labels
|
||||
-fno-align-loops
|
||||
-fno-code-hoisting
|
||||
-fno-cx-limited-range
|
||||
-fno-fp-int-builtin-inexact
|
||||
-fno-gnu-unique
|
||||
-fno-inline-functions-called-once
|
||||
-fno-instrument-functions
|
||||
-fno-schedule-insns2
|
||||
-fno-whole-program
|
||||
-fopt-info-vec
|
||||
-fopt-info-vec-missed
|
||||
-freg-struct-return
|
||||
-freschedule-modulo-scheduled-loops
|
||||
-frounding-math
|
||||
-fsched2-use-superblocks
|
||||
-fschedule-insns
|
||||
-fschedule-insns2
|
||||
-fshrink-wrap
|
||||
-fshrink-wrap-separate
|
||||
-fsignaling-nans
|
||||
-fstack-clash-protection
|
||||
-ftracer
|
||||
-ftrapv
|
||||
-ftree-loop-im
|
||||
-ftree-loop-vectorize
|
||||
-funsafe-loop-optimizations
|
||||
-fversion-loops-for-strides
|
||||
-fwhole-program
|
||||
-gdescribe-dies
|
||||
-gstabs
|
||||
-mcall-ms2sysv-xlogues
|
||||
-mdispatch-scheduler
|
||||
-mfpmath=sse+387
|
||||
-mmitigate-rop
|
||||
-mno-fentry
|
BIN
build/bootstrap/mkdeps.com
Executable file
BIN
build/bootstrap/mkdeps.com
Executable file
Binary file not shown.
BIN
build/bootstrap/package.com
Executable file
BIN
build/bootstrap/package.com
Executable file
Binary file not shown.
BIN
build/bootstrap/zipobj.com
Executable file
BIN
build/bootstrap/zipobj.com
Executable file
Binary file not shown.
21
build/catcode
Executable file
21
build/catcode
Executable file
|
@ -0,0 +1,21 @@
|
|||
#!/bin/sh
|
||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
||||
#
|
||||
# OVERVIEW
|
||||
#
|
||||
# Source File Concatenation Tool
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This program is the same as cat, but inserts preprocessor directives
|
||||
# that allow compiler errors to point back to the original lines.
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
cat
|
||||
else
|
||||
for x; do
|
||||
printf '# 1 "%s"\n' "$x"
|
||||
cat "$x"
|
||||
done
|
||||
fi
|
298
build/compile
Executable file
298
build/compile
Executable file
|
@ -0,0 +1,298 @@
|
|||
#!/bin/sh
|
||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
||||
#
|
||||
# OVERVIEW
|
||||
#
|
||||
# GNU/LLVM Compiler Frontend Frontend
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This wrapper script filters out certain flags so the compiler won't
|
||||
# whine, and passes extra information to the preprocessor.
|
||||
#
|
||||
# EXAMPLE
|
||||
#
|
||||
# build/compile cc -o program program.c
|
||||
|
||||
if [ ! -d o/third_party/gcc ]; then
|
||||
third_party/gcc/unbundle.sh
|
||||
fi
|
||||
|
||||
if [ "$1" = "clang-10" ]; then
|
||||
if ! command -v clang-10 >/dev/null; then
|
||||
shift
|
||||
set -- o/third_party/gcc/bin/x86_64-linux-musl-gcc "$@"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$1" = "clang++-10" ]; then
|
||||
if ! command -v clang++-10 >/dev/null; then
|
||||
shift
|
||||
set -- o/third_party/gcc/bin/x86_64-linux-musl-g++ "$@"
|
||||
fi
|
||||
fi
|
||||
|
||||
MKDIR=${MKDIR:-$(command -v mkdir) -p} || exit
|
||||
|
||||
GZME=
|
||||
ASAN=
|
||||
UBSAN=
|
||||
PLAT="${1%% *}"
|
||||
FDIAGNOSTIC_COLOR=
|
||||
CCNAME=${CCNAME:-gcc}
|
||||
CCVERSION=${CCVERSION:-4}
|
||||
COUNTERMAND=
|
||||
|
||||
# The GNU Compiler Collection passes a lot of CFLAGS to the preprocessor
|
||||
# (which we call CCFLAGS) but it should pass more; and we do just that.
|
||||
NOPG=0
|
||||
FIRST=1
|
||||
OUTARG=0
|
||||
INVISIBLE=0
|
||||
for x; do
|
||||
if [ $FIRST -eq 1 ]; then
|
||||
set --
|
||||
FIRST=0
|
||||
fi
|
||||
if [ $OUTARG -eq 1 ]; then
|
||||
OUTARG=0
|
||||
OUT="$x"
|
||||
fi
|
||||
case "$x" in
|
||||
-o)
|
||||
set -- "$@" "$x"
|
||||
OUTARG=1
|
||||
;;
|
||||
-w)
|
||||
set -- "$@" "$x" -D__W__
|
||||
;;
|
||||
-x-no-pg)
|
||||
NOPG=1
|
||||
;;
|
||||
-pg)
|
||||
if [ $NOPG -eq 0 ] && [ $INVISIBLE -eq 0 ]; then
|
||||
set -- "$@" "$x" -D__PG__ # @see libc/macros.h
|
||||
fi
|
||||
;;
|
||||
-mfentry)
|
||||
if [ $NOPG -eq 0 ] && [ $INVISIBLE -eq 0 ]; then
|
||||
set -- "$@" "$x" -D__MFENTRY__
|
||||
fi
|
||||
;;
|
||||
-fomit-frame-pointer)
|
||||
INVISIBLE=1
|
||||
set -- "$@" "$x"
|
||||
;;
|
||||
-mno-vzeroupper)
|
||||
set -- "$@" "$x" -Wa,-msse2avx -D__MNO_VZEROUPPER__
|
||||
;;
|
||||
-fsanitize=address)
|
||||
ASAN="$x -D__FSANITIZE_ADDRESS__"
|
||||
;;
|
||||
-fsanitize=undefined)
|
||||
# UBSAN w/ -fdata-sections exceeds ELF's 65,280 section limit
|
||||
UBSAN="$x -fno-data-sections"
|
||||
;;
|
||||
-fno-sanitize=address)
|
||||
ASAN=
|
||||
;;
|
||||
-fno-sanitize=ubsan)
|
||||
UBSAN=
|
||||
;;
|
||||
-fno-sanitize=all)
|
||||
ASAN=
|
||||
UBSAN=
|
||||
;;
|
||||
-mnop-mcount)
|
||||
if [ "$CCNAME" = "gcc" ] && [ "$CCVERSION" -ge 6 ]; then
|
||||
set -- "$@" "$x" -D__MNOP_MCOUNT__
|
||||
fi
|
||||
;;
|
||||
-mrecord-mcount)
|
||||
if [ "$CCNAME" = "gcc" ] && [ "$CCVERSION" -ge 6 ]; then
|
||||
set -- "$@" "$x" -D__MRECORD_MCOUNT__
|
||||
fi
|
||||
;;
|
||||
-fsanitize=implicit*integer*)
|
||||
if ! [ "$CCNAME" = "gcc" ]; then
|
||||
set -- "$@" "$x"
|
||||
fi
|
||||
;;
|
||||
-f*sanitize*|-gz*|-*stack-protector*|-fvect-cost*|-mstringop*)
|
||||
if [ "$CCNAME" = "gcc" ] && [ "$CCVERSION" -ge 6 ]; then
|
||||
set -- "$@" "$x"
|
||||
fi
|
||||
;;
|
||||
-freorder-blocks-and-partition|-fstack-clash-protection)
|
||||
if [ "$CCNAME" = "gcc" ] && [ "$CCVERSION" -ge 8 ]; then
|
||||
set -- "$@" "$x"
|
||||
fi
|
||||
;;
|
||||
-fdiagnostic-color=*)
|
||||
FDIAGNOSTIC_COLOR=$x
|
||||
;;
|
||||
-fopt-info*=*.optinfo)
|
||||
if [ "$CCNAME" = "gcc" ] && [ "$CCVERSION" -ge 9 ]; then
|
||||
GZME="$GZME ${x##*=}"
|
||||
set -- "$@" "$x"
|
||||
fi
|
||||
;;
|
||||
-R*) # e.g. clang's -Rpass-missed=all
|
||||
if [ "${PLAT#*clang}" != "${PLAT}" ]; then
|
||||
set -- "$@" "$x"
|
||||
fi
|
||||
;;
|
||||
-fsave-optimization-record) # clang only
|
||||
if [ "${PLAT#*clang}" != "${PLAT}" ]; then
|
||||
set -- "$@" "$x"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
set -- "$@" "$x"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
if [ -z "$FDIAGNOSTIC_COLOR" ] && [ "$TERM" != "dumb" ]; then
|
||||
FDIAGNOSTIC_COLOR=-fdiagnostics-color=always
|
||||
fi
|
||||
|
||||
if [ "${PLAT#*clang}" != "${PLAT}" ]; then
|
||||
FIRST=1
|
||||
for x; do
|
||||
# clang's assembler isn't complete yet
|
||||
if [ $FIRST -eq 1 ]; then
|
||||
set -- \
|
||||
"$x" \
|
||||
-fno-integrated-as \
|
||||
-Wno-unused-command-line-argument \
|
||||
-Wno-incompatible-pointer-types-discards-qualifiers
|
||||
FIRST=0
|
||||
continue
|
||||
fi
|
||||
TRAPV= # clang handles -f{,no-}{trap,wrap}v weird
|
||||
# removes flags clang whines about
|
||||
case "$x" in
|
||||
-gstabs) ;;
|
||||
-ftrapv) ;;
|
||||
-ffixed-*) ;;
|
||||
-fcall-saved*) ;;
|
||||
-fsignaling-nans) ;;
|
||||
-fcx-limited-range) ;;
|
||||
-fno-fp-int-builtin-inexact) ;;
|
||||
-Wno-unused-but-set-variable) ;;
|
||||
-Wunsafe-loop-optimizations) ;;
|
||||
-mdispatch-scheduler) ;;
|
||||
-ftracer) ;;
|
||||
-frounding-math) ;;
|
||||
-fmerge-constants) ;;
|
||||
-fmodulo-sched) ;;
|
||||
-msse2avx)
|
||||
set -- "$@" -Wa,-msse2avx
|
||||
;;
|
||||
-fopt-info-vec) ;;
|
||||
-fopt-info-vec-missed) ;;
|
||||
-fmodulo-sched-allow-regmoves) ;;
|
||||
-fgcse-*) ;;
|
||||
-freschedule-modulo-scheduled-loops) ;;
|
||||
-freschedule-modulo-scheduled-loops) ;;
|
||||
-fipa-pta) ;;
|
||||
-fsched2-use-superblocks) ;;
|
||||
-fbranch-target-load-optimize) ;;
|
||||
-fdelete-dead-exceptions) ;;
|
||||
-funsafe-loop-optimizations) ;;
|
||||
-fcall-used*) ;;
|
||||
-mmitigate-rop) ;;
|
||||
-mnop-mcount) ;;
|
||||
-fno-align-jumps) ;;
|
||||
-fno-align-labels) ;;
|
||||
-fno-align-loops) ;;
|
||||
-fivopts) ;;
|
||||
-fschedule-insns) ;;
|
||||
-fno-semantic-interposition) ;;
|
||||
-mno-fentry) ;;
|
||||
-f*shrink-wrap) ;;
|
||||
-f*schedule-insns2) ;;
|
||||
-fvect-cost-model=*) ;;
|
||||
-fsimd-cost-model=*) ;;
|
||||
-fversion-loops-for-strides) ;;
|
||||
-fopt-info*) ;;
|
||||
-f*var-tracking-assignments) ;;
|
||||
-femit-struct-debug-baseonly) ;;
|
||||
-ftree-loop-vectorize) ;;
|
||||
-gdescribe-dies) ;;
|
||||
-flimit-function-alignment) ;;
|
||||
-ftree-loop-im) ;;
|
||||
-fno-instrument-functions) ;;
|
||||
-fstack-clash-protection) ;;
|
||||
-mstringop-strategy=*) ;;
|
||||
-mpreferred-stack-boundary=*) ;;
|
||||
-*stack-protector*) ;; # clang requires segmented memory for this
|
||||
-f*gnu-unique) ;;
|
||||
-Wframe-larger-than=*) ;;
|
||||
-f*whole-program) ;;
|
||||
-Wa,--size-check=*) ;;
|
||||
-Wa,--listing*) ;;
|
||||
-mfpmath=sse+387) ;;
|
||||
-Wa,--noexecstack) ;;
|
||||
-freg-struct-return) ;;
|
||||
-mcall-ms2sysv-xlogues) ;;
|
||||
-mno-vzeroupper)
|
||||
set -- "$@" -mllvm -x86-use-vzeroupper=0
|
||||
;;
|
||||
-Wa,-a*)
|
||||
x="${x#*=}"
|
||||
if [ "$x" ] && [ -p "$x" ]; then
|
||||
printf '' >"$x"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
set -- "$@" "$x"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
set -- "$@" -fno-stack-protector
|
||||
else
|
||||
# removes flags only clang supports
|
||||
FIRST=1
|
||||
for x; do
|
||||
if [ $FIRST -eq 1 ]; then
|
||||
set --
|
||||
FIRST=0
|
||||
fi
|
||||
case "$x" in
|
||||
-Oz) set -- "$@" -Os ;;
|
||||
*) set -- "$@" "$x" ;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
set -- "$@" -no-canonical-prefixes $FDIAGNOSTIC_COLOR $ASAN $UBSAN $COUNTERMAND
|
||||
|
||||
if [ "$V" = "0" ]; then
|
||||
printf "$LOGFMT" "${ACTION:-COMPILE}" "${TARGET:-$OUT}" >&2
|
||||
else
|
||||
printf "%s\n" "$*" >&2
|
||||
fi
|
||||
|
||||
OUTDIR="${OUT%/*}"
|
||||
if [ "$OUTDIR" != "$OUT" ] && [ ! -d "$OUTDIR" ]; then
|
||||
$MKDIR "$OUTDIR" || exit 2
|
||||
fi
|
||||
|
||||
REASON=failed
|
||||
trap REASON=interrupted INT
|
||||
|
||||
if "$@"; then
|
||||
for f in $GZME; do
|
||||
if GZ=${GZ:-$(command -v gzip)}; then
|
||||
if [ -f "$f" ]; then
|
||||
build/actuallynice $GZ $ZFLAGS -qf $f &
|
||||
fi
|
||||
fi
|
||||
done
|
||||
exit 0
|
||||
fi
|
||||
|
||||
printf "\n$LOGFMT" "$CCNAME $CCVERSION: compile $REASON:" "$*" >&2
|
||||
exit 1
|
392
build/config.mk
392
build/config.mk
|
@ -1,68 +1,25 @@
|
|||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||
#── vi: set et ft=make ts=8 sw=8 fenc=utf-8 :vi ──────────────────────┘
|
||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
||||
|
||||
# Default Mode
|
||||
#
|
||||
# - `make`
|
||||
# - Optimized
|
||||
# - Backtraces
|
||||
# - Syscall tracing
|
||||
# - Function tracing
|
||||
#
|
||||
# - Reasonably small
|
||||
# - Reasonably optimized
|
||||
# - Reasonably debuggable
|
||||
|
||||
ifeq ($(MODE),)
|
||||
ENABLE_FTRACE = 1
|
||||
CONFIG_OFLAGS ?= -g -ggdb
|
||||
CONFIG_CCFLAGS += -O2 $(BACKTRACES)
|
||||
CONFIG_CPPFLAGS += -DSYSDEBUG
|
||||
endif
|
||||
ifeq ($(MODE), x86_64)
|
||||
ENABLE_FTRACE = 1
|
||||
CONFIG_OFLAGS ?= -g -ggdb
|
||||
CONFIG_CCFLAGS += -O2 $(BACKTRACES)
|
||||
CONFIG_CPPFLAGS += -DSYSDEBUG
|
||||
endif
|
||||
ifeq ($(MODE), aarch64)
|
||||
ENABLE_FTRACE = 1
|
||||
CONFIG_OFLAGS ?= -g -ggdb
|
||||
CONFIG_CCFLAGS += -O2 $(BACKTRACES)
|
||||
CONFIG_CPPFLAGS += -DSYSDEBUG
|
||||
endif
|
||||
|
||||
# Zero Optimization Mode
|
||||
#
|
||||
# - Goes 2x slower
|
||||
# - Supports --strace
|
||||
# - Unsupports --ftrace
|
||||
# - Better GDB debugging
|
||||
#
|
||||
ifeq ($(MODE), zero)
|
||||
ENABLE_FTRACE = 1
|
||||
CONFIG_OFLAGS ?= -g -ggdb
|
||||
OVERRIDE_CFLAGS += -O0
|
||||
OVERRIDE_CXXFLAGS += -O0
|
||||
CONFIG_CPPFLAGS += -DSYSDEBUG
|
||||
endif
|
||||
ifeq ($(MODE), aarch64-zero)
|
||||
CONFIG_OFLAGS ?= -g -ggdb
|
||||
OVERRIDE_CFLAGS += -O0 -fdce
|
||||
OVERRIDE_CXXFLAGS += -O0 -fdce
|
||||
CONFIG_CPPFLAGS += -DSYSDEBUG
|
||||
endif
|
||||
CONFIG_CCFLAGS += \
|
||||
$(BACKTRACES) \
|
||||
$(FTRACE) \
|
||||
-Og
|
||||
|
||||
TARGET_ARCH ?= \
|
||||
-msse3
|
||||
|
||||
# Fast Build Mode
|
||||
#
|
||||
# - `make MODE=fastbuild`
|
||||
# - No debugging
|
||||
# - Syscall tracing
|
||||
# - Function tracing
|
||||
# - Some optimizations
|
||||
# - Limited Backtraces
|
||||
#
|
||||
ifeq ($(MODE), fastbuild)
|
||||
ENABLE_FTRACE = 1
|
||||
CONFIG_CCFLAGS += $(BACKTRACES) -O
|
||||
CONFIG_CPPFLAGS += -DSYSDEBUG -DDWARFLESS
|
||||
CONFIG_LDFLAGS += -S
|
||||
endif
|
||||
|
||||
# Optimized Mode
|
||||
|
@ -70,130 +27,79 @@ endif
|
|||
# - `make MODE=opt`
|
||||
# - Backtraces
|
||||
# - More optimized
|
||||
# - Syscall tracing
|
||||
# - Function tracing
|
||||
# - Reasonably small
|
||||
# - No memory corruption detection
|
||||
# - assert() / CHECK_xx() may leak code into binary for debuggability
|
||||
# - GCC 8+ hoists check fails into .text.cold, thus minimizing impact
|
||||
#
|
||||
ifeq ($(MODE), opt)
|
||||
ENABLE_FTRACE = 1
|
||||
CONFIG_OFLAGS ?= -g -ggdb
|
||||
CONFIG_CPPFLAGS += -DNDEBUG -DSYSDEBUG
|
||||
CONFIG_CCFLAGS += $(BACKTRACES) -O3 -fmerge-all-constants
|
||||
CONFIG_TARGET_ARCH ?= -march=native
|
||||
endif
|
||||
|
||||
# Optimized Linux Mode
|
||||
# The Fastest Mode of All
|
||||
#
|
||||
# - `make MODE=optlinux`
|
||||
# - Turns on red zone
|
||||
# - Turns off backtraces
|
||||
# - Turns off function tracing
|
||||
# - Turns off support for older cpu models
|
||||
# - Turns off support for other operating systems
|
||||
#
|
||||
ifeq ($(MODE), optlinux)
|
||||
CONFIG_OFLAGS ?= -g -ggdb
|
||||
CONFIG_CPPFLAGS += -DNDEBUG -DSYSDEBUG -DSUPPORT_VECTOR=1
|
||||
CONFIG_CCFLAGS += -O3 -fmerge-all-constants
|
||||
CONFIG_COPTS += -mred-zone
|
||||
CONFIG_TARGET_ARCH ?= -march=native
|
||||
endif
|
||||
ifeq ($(MODE), x86_64-optlinux)
|
||||
CONFIG_OFLAGS ?= -g -ggdb
|
||||
CONFIG_CPPFLAGS += -DNDEBUG -DSYSDEBUG -DSUPPORT_VECTOR=1
|
||||
CONFIG_CCFLAGS += -O3 -fmerge-all-constants
|
||||
CONFIG_COPTS += -mred-zone
|
||||
CONFIG_TARGET_ARCH ?= -march=native
|
||||
endif
|
||||
ifeq ($(MODE), aarch64-optlinux)
|
||||
CONFIG_OFLAGS ?= -g -ggdb
|
||||
CONFIG_CPPFLAGS += -DNDEBUG -DSYSDEBUG -DSUPPORT_VECTOR=1
|
||||
CONFIG_CCFLAGS += -O3 -fmerge-all-constants
|
||||
CONFIG_COPTS += -mred-zone
|
||||
ifeq ($(MODE), opt)
|
||||
|
||||
CONFIG_CPPFLAGS += \
|
||||
-DNDEBUG \
|
||||
-msse2avx \
|
||||
-Wa,-msse2avx
|
||||
|
||||
CONFIG_CCFLAGS += \
|
||||
$(BACKTRACES) \
|
||||
-O3
|
||||
|
||||
TARGET_ARCH ?= \
|
||||
-march=native
|
||||
|
||||
endif
|
||||
|
||||
# Release Mode
|
||||
#
|
||||
# Follows traditional closed source release binary norms.
|
||||
#
|
||||
# - `make MODE=rel`
|
||||
# - More optimized
|
||||
# - Reasonably small
|
||||
# - Numeric backtraces
|
||||
# - No DWARF data bloat
|
||||
# - Toilsome debuggability
|
||||
# - assert() statements removed
|
||||
# - DCHECK_xx() statements removed
|
||||
# - No memory corruption detection
|
||||
# - CHECK_xx() won't leak strings into binary
|
||||
#
|
||||
|
||||
ifeq ($(MODE), rel)
|
||||
CONFIG_CPPFLAGS += -DNDEBUG -DDWARFLESS
|
||||
CONFIG_CCFLAGS += $(BACKTRACES) -O2
|
||||
PYFLAGS += -O1
|
||||
|
||||
CONFIG_CPPFLAGS += \
|
||||
-DNDEBUG
|
||||
|
||||
CONFIG_CCFLAGS += \
|
||||
$(BACKTRACES) \
|
||||
-O2
|
||||
|
||||
endif
|
||||
|
||||
# Debug Mode
|
||||
#
|
||||
# - `make MODE=dbg`
|
||||
# - Backtraces
|
||||
# - Enables ubsan
|
||||
# - Stack canaries
|
||||
# - No optimization
|
||||
# - Enormous binaries
|
||||
#
|
||||
ifeq ($(MODE), dbg)
|
||||
ENABLE_FTRACE = 1
|
||||
CONFIG_OFLAGS ?= -g -ggdb
|
||||
OVERRIDE_CFLAGS += -O0
|
||||
OVERRIDE_CXXFLAGS += -O0
|
||||
CONFIG_CPPFLAGS += -DMODE_DBG -D__SANITIZE_UNDEFINED__ -Wno-unused-variable -Wno-unused-but-set-variable
|
||||
CONFIG_CCFLAGS += $(BACKTRACES) -DSYSDEBUG
|
||||
CONFIG_COPTS += -fsanitize=undefined
|
||||
OVERRIDE_CCFLAGS += -fno-pie
|
||||
QUOTA ?= -C64 -L300
|
||||
endif
|
||||
ifeq ($(MODE), x86_64-dbg)
|
||||
ENABLE_FTRACE = 1
|
||||
CONFIG_OFLAGS ?= -g -ggdb
|
||||
OVERRIDE_CFLAGS += -O0
|
||||
OVERRIDE_CXXFLAGS += -O0
|
||||
CONFIG_CPPFLAGS += -DMODE_DBG -D__SANITIZE_UNDEFINED__ -Wno-unused-variable -Wno-unused-but-set-variable
|
||||
CONFIG_CCFLAGS += $(BACKTRACES) -DSYSDEBUG
|
||||
CONFIG_COPTS += -fsanitize=undefined
|
||||
OVERRIDE_CCFLAGS += -fno-pie
|
||||
QUOTA ?= -C64 -L300
|
||||
endif
|
||||
ifeq ($(MODE), aarch64-dbg)
|
||||
ENABLE_FTRACE = 1
|
||||
CONFIG_OFLAGS ?= -g -ggdb
|
||||
OVERRIDE_CFLAGS += -O0 -fdce
|
||||
OVERRIDE_CXXFLAGS += -O0 -fdce
|
||||
CONFIG_CPPFLAGS += -DMODE_DBG -D__SANITIZE_UNDEFINED__ -Wno-unused-variable -Wno-unused-but-set-variable
|
||||
CONFIG_CCFLAGS += $(BACKTRACES) -DSYSDEBUG
|
||||
CONFIG_COPTS += -fsanitize=undefined
|
||||
QUOTA ?= -C64 -L300
|
||||
endif
|
||||
# - Zero optimization
|
||||
# - Enables sanitization
|
||||
# - Enables stack canaries
|
||||
# - Enormous binaries (b/c ubsan suboptimalities)
|
||||
|
||||
ifeq ($(MODE), dbg)
|
||||
|
||||
CONFIG_CPPFLAGS += \
|
||||
-DMODE_DBG
|
||||
|
||||
CONFIG_CCFLAGS += \
|
||||
$(BACKTRACES) \
|
||||
$(FTRACE) \
|
||||
-O2
|
||||
|
||||
CONFIG_COPTS += \
|
||||
$(SECURITY_BLANKETS) \
|
||||
$(SANITIZER)
|
||||
|
||||
TARGET_ARCH ?= \
|
||||
-msse3
|
||||
|
||||
OVERRIDE_CCFLAGS += \
|
||||
-fno-pie
|
||||
|
||||
# System Five Mode
|
||||
#
|
||||
# - `make MODE=sysv`
|
||||
# - Optimized
|
||||
# - Backtraces
|
||||
# - Debuggable
|
||||
# - Syscall tracing
|
||||
# - Function tracing
|
||||
# - No Windows bloat!
|
||||
#
|
||||
ifeq ($(MODE), sysv)
|
||||
ENABLE_FTRACE = 1
|
||||
CONFIG_OFLAGS ?= -g -ggdb
|
||||
CONFIG_CCFLAGS += $(BACKTRACES) -O2
|
||||
CONFIG_CPPFLAGS += -DSYSDEBUG -DSUPPORT_VECTOR=121
|
||||
endif
|
||||
|
||||
# Tiny Mode
|
||||
|
@ -207,7 +113,6 @@ endif
|
|||
# - No backtraces
|
||||
# - No algorithmics
|
||||
# - YOLO
|
||||
#
|
||||
ifeq ($(MODE), tiny)
|
||||
CONFIG_CPPFLAGS += \
|
||||
-DTINY \
|
||||
|
@ -218,58 +123,14 @@ CONFIG_CCFLAGS += \
|
|||
-fno-align-functions \
|
||||
-fno-align-jumps \
|
||||
-fno-align-labels \
|
||||
-fno-align-loops \
|
||||
-fschedule-insns2 \
|
||||
-momit-leaf-frame-pointer \
|
||||
-foptimize-sibling-calls \
|
||||
-DDWARFLESS
|
||||
PYFLAGS += \
|
||||
-O2 \
|
||||
-B
|
||||
endif
|
||||
ifeq ($(MODE), x86_64-tiny)
|
||||
CONFIG_CPPFLAGS += \
|
||||
-DTINY \
|
||||
-DNDEBUG \
|
||||
-DTRUSTWORTHY
|
||||
CONFIG_CCFLAGS += \
|
||||
-Os \
|
||||
-fno-align-functions \
|
||||
-fno-align-jumps \
|
||||
-fno-align-labels \
|
||||
-fno-align-loops \
|
||||
-fschedule-insns2 \
|
||||
-momit-leaf-frame-pointer \
|
||||
-foptimize-sibling-calls \
|
||||
-DDWARFLESS
|
||||
PYFLAGS += \
|
||||
-O2 \
|
||||
-B
|
||||
endif
|
||||
ifeq ($(MODE), aarch64-tiny)
|
||||
# TODO(jart): -mcmodel=tiny
|
||||
CONFIG_CPPFLAGS += \
|
||||
-DTINY \
|
||||
-DNDEBUG \
|
||||
-DTRUSTWORTHY
|
||||
CONFIG_CCFLAGS += \
|
||||
-Os \
|
||||
-fno-align-functions \
|
||||
-fno-align-jumps \
|
||||
-fno-align-labels \
|
||||
-fno-align-loops \
|
||||
-fschedule-insns2 \
|
||||
-momit-leaf-frame-pointer \
|
||||
-foptimize-sibling-calls \
|
||||
-DDWARFLESS
|
||||
PYFLAGS += \
|
||||
-O2 \
|
||||
-B
|
||||
-fno-align-loops
|
||||
TARGET_ARCH ?= \
|
||||
-msse3
|
||||
endif
|
||||
|
||||
# Linux-Only Tiny Mode
|
||||
#
|
||||
# - `make MODE=tinylinux`
|
||||
# - `make MODE=tiny`
|
||||
# - No checks
|
||||
# - No asserts
|
||||
# - No canaries
|
||||
|
@ -279,25 +140,25 @@ endif
|
|||
# - No portability
|
||||
# - No algorithmics
|
||||
# - YOLO
|
||||
#
|
||||
ifeq ($(MODE), tinylinux)
|
||||
CONFIG_CPPFLAGS += \
|
||||
-DTINY \
|
||||
-DNDEBUG \
|
||||
-DTRUSTWORTHY \
|
||||
-DSUPPORT_VECTOR=1 \
|
||||
-DDWARFLESS
|
||||
-DSUPPORT_VECTOR=1
|
||||
CONFIG_CCFLAGS += \
|
||||
-Os \
|
||||
-fno-align-functions \
|
||||
-fno-align-jumps \
|
||||
-fno-align-labels \
|
||||
-fno-align-loops
|
||||
TARGET_ARCH ?= \
|
||||
-msse3
|
||||
endif
|
||||
|
||||
# Linux+BSD Tiny Mode
|
||||
#
|
||||
# - `make MODE=tinylinuxbsd`
|
||||
# - `make MODE=tiny`
|
||||
# - No apple
|
||||
# - No checks
|
||||
# - No asserts
|
||||
|
@ -308,25 +169,25 @@ endif
|
|||
# - No backtraces
|
||||
# - No algorithmics
|
||||
# - YOLO
|
||||
#
|
||||
ifeq ($(MODE), tinylinuxbsd)
|
||||
CONFIG_CPPFLAGS += \
|
||||
-DTINY \
|
||||
-DNDEBUG \
|
||||
-DTRUSTWORTHY \
|
||||
-DSUPPORT_VECTOR=113 \
|
||||
-DDWARFLESS
|
||||
-DSUPPORT_VECTOR=113
|
||||
CONFIG_CCFLAGS += \
|
||||
-Os \
|
||||
-fno-align-functions \
|
||||
-fno-align-jumps \
|
||||
-fno-align-labels \
|
||||
-fno-align-loops
|
||||
TARGET_ARCH ?= \
|
||||
-msse3
|
||||
endif
|
||||
|
||||
# Unix Tiny Mode
|
||||
#
|
||||
# - `make MODE=tinysysv`
|
||||
# - `make MODE=tiny`
|
||||
# - No checks
|
||||
# - No asserts
|
||||
# - No canaries
|
||||
|
@ -336,25 +197,25 @@ endif
|
|||
# - No backtraces
|
||||
# - No algorithmics
|
||||
# - YOLO
|
||||
#
|
||||
ifeq ($(MODE), tinysysv)
|
||||
CONFIG_CPPFLAGS += \
|
||||
-DTINY \
|
||||
-DNDEBUG \
|
||||
-DTRUSTWORTHY \
|
||||
-DSUPPORT_VECTOR=121 \
|
||||
-DDWARFLESS
|
||||
-DSUPPORT_VECTOR=121
|
||||
CONFIG_CCFLAGS += \
|
||||
-Os \
|
||||
-fno-align-functions \
|
||||
-fno-align-jumps \
|
||||
-fno-align-labels \
|
||||
-fno-align-loops
|
||||
TARGET_ARCH ?= \
|
||||
-msse3
|
||||
endif
|
||||
|
||||
# Tiny Metallic Unix Mode
|
||||
#
|
||||
# - `make MODE=tinynowin`
|
||||
# - `make MODE=tiny`
|
||||
# - No checks
|
||||
# - No asserts
|
||||
# - No canaries
|
||||
|
@ -364,54 +225,26 @@ endif
|
|||
# - No backtraces
|
||||
# - No algorithmics
|
||||
# - YOLO
|
||||
#
|
||||
ifeq ($(MODE), tinynowin)
|
||||
CONFIG_CPPFLAGS += \
|
||||
-DTINY \
|
||||
-DNDEBUG \
|
||||
-DTRUSTWORTHY \
|
||||
-DSUPPORT_VECTOR=251 \
|
||||
-DDWARFLESS
|
||||
-DSUPPORT_VECTOR=251
|
||||
CONFIG_CCFLAGS += \
|
||||
-Os \
|
||||
-fno-align-functions \
|
||||
-fno-align-jumps \
|
||||
-fno-align-labels \
|
||||
-fno-align-loops
|
||||
endif
|
||||
|
||||
# no x87 instructions mode
|
||||
#
|
||||
# export MODE=nox87
|
||||
# make -j8 toolchain
|
||||
# cosmocc -o /tmp/hello.com hello.c
|
||||
#
|
||||
# lets you shave ~23kb off blink
|
||||
#
|
||||
# git clone https://github.com/jart/blink
|
||||
# cd blink
|
||||
# ./configure --disable-x87
|
||||
# make -j8
|
||||
# o//blink/blink /tmp/hello.com
|
||||
#
|
||||
ifeq ($(MODE), nox87)
|
||||
ENABLE_FTRACE = 1
|
||||
CONFIG_COPTS += -mlong-double-64
|
||||
CONFIG_CCFLAGS += $(BACKTRACES) -O2
|
||||
CONFIG_CPPFLAGS += -DSYSDEBUG -DNOX87
|
||||
TARGET_ARCH ?= \
|
||||
-msse3
|
||||
endif
|
||||
|
||||
# LLVM Mode
|
||||
#
|
||||
# We aim to support:
|
||||
#
|
||||
# make -j8 m=llvm o/llvm/libc
|
||||
#
|
||||
# The rest of the monorepo may not work with llvm.
|
||||
#
|
||||
ifeq ($(MODE), llvm)
|
||||
.STRICT = 0
|
||||
CONFIG_CCFLAGS += $(BACKTRACES) -DSYSDEBUG -O2
|
||||
TARGET_ARCH ?= -msse3
|
||||
CONFIG_CCFLAGS += $(BACKTRACES) $(FTRACE) -O2
|
||||
AS = clang
|
||||
CC = clang
|
||||
CXX = clang++
|
||||
|
@ -449,66 +282,17 @@ endif
|
|||
# such as MSVC or XCode. You can run your binary objects through a tool
|
||||
# like objconv to convert them to COFF or MachO. Then use ANSI mode to
|
||||
# rollup one header file that'll enable linkage with minimal issues.
|
||||
#
|
||||
# Lastly note that in some cases, such as gc(), there simply isn't any
|
||||
# ANSI workaround available. It's only in cases like that when we'll use
|
||||
# the __asm__() header workaround, rather than simply removing it. We do
|
||||
# however try to do that much less often than mainstream C libraries.
|
||||
|
||||
ifeq ($(MODE), ansi)
|
||||
|
||||
CONFIG_CFLAGS += -std=c11
|
||||
#CONFIG_CPPFLAGS += -ansi
|
||||
CONFIG_CXXFLAGS += -std=c++11
|
||||
endif
|
||||
TARGET_ARCH ?= -msse3
|
||||
|
||||
ifneq ($(ENABLE_FTRACE),)
|
||||
CONFIG_CPPFLAGS += -DFTRACE
|
||||
FTRACE_CCFLAGS = -fno-inline-functions-called-once
|
||||
OVERRIDE_CFLAGS += $(FTRACE_CCFLAGS)
|
||||
OVERRIDE_CXXFLAGS += $(FTRACE_CCFLAGS)
|
||||
# function prologue nops for --ftrace
|
||||
ifeq ($(ARCH), x86_64)
|
||||
# this flag causes gcc to generate functions like this
|
||||
#
|
||||
# nop nop nop nop nop nop nop nop nop
|
||||
# func:
|
||||
# nop nop
|
||||
# ...
|
||||
#
|
||||
# which tool/build/fixupobj.c improves at build time like this
|
||||
#
|
||||
# nop nop nop nop nop nop nop nop nop
|
||||
# func:
|
||||
# xchg %ax,%ax
|
||||
# ...
|
||||
#
|
||||
# which --ftrace morphs at runtime like this
|
||||
#
|
||||
# ud2 # 2 bytes
|
||||
# call ftrace_hook # 5 bytes
|
||||
# jmp +2 # 2 bytes
|
||||
# func:
|
||||
# jmp -7 # 2 bytes
|
||||
# ...
|
||||
#
|
||||
CONFIG_CCFLAGS += -fpatchable-function-entry=18,16
|
||||
endif
|
||||
ifeq ($(ARCH), aarch64)
|
||||
# this flag causes gcc to generate functions like this
|
||||
#
|
||||
# nop nop nop nop nop nop
|
||||
# func:
|
||||
# nop
|
||||
# ...
|
||||
#
|
||||
# which --ftrace morphs at runtime like this
|
||||
#
|
||||
# brk #31337
|
||||
# stp x29,x30,[sp,#-16]!
|
||||
# mov x29,sp
|
||||
# bl ftrace_hook
|
||||
# ldp x29,x30,[sp],#16
|
||||
# b +1
|
||||
# func:
|
||||
# b -5
|
||||
# ...
|
||||
#
|
||||
CONFIG_CCFLAGS += -fpatchable-function-entry=7,6
|
||||
endif
|
||||
endif
|
||||
|
||||
TARGET_ARCH ?= $(CONFIG_TARGET_ARCH)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||
#── vi: set et ft=make ts=8 sw=8 fenc=utf-8 :vi ──────────────────────┘
|
||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
|
@ -33,43 +33,105 @@
|
|||
#
|
||||
# VARIABLES
|
||||
#
|
||||
# Our configuration variables, ordered by increasing preference:
|
||||
#
|
||||
# CCFLAGS frontend flags (.i, .c, .cc, .f, .S, .lds, etc.)
|
||||
# OFLAGS objectify flags (precludes -S and -E)
|
||||
# CCFLAGS gcc frontend flags (.i, .c, .cc, .f, .S, .lds, etc.)
|
||||
# CPPFLAGS preprocessor flags (.h, .c, .cc, .S, .inc, .lds, etc.)
|
||||
# TARGET_ARCH microarchitecture flags (e.g. -march=native)
|
||||
# COPTS c/c++ flags (.c, .cc)
|
||||
# CFLAGS c flags (.c only)
|
||||
# CXXFLAGS c++ flags (.cc only)
|
||||
# COPTS c/c++ flags (.c, .cc)
|
||||
# LDFLAGS linker flags (don't use -Wl, frontend prefix)
|
||||
# ASFLAGS assembler flags (don't use -Wa, frontend prefix)
|
||||
#
|
||||
# For each FOO above, there exists (by increasing preference)
|
||||
#
|
||||
# DEFAULT_FOO see build/definitions.mk
|
||||
# CONFIG_FOO see build/config.mk
|
||||
# FOO set ~/.cosmo.mk and target-specific
|
||||
# OVERRIDE_FOO set ~/.cosmo.mk and target-specific (use rarely)
|
||||
#
|
||||
# TARGET_ARCH microarchitecture flags (e.g. -march=native)
|
||||
|
||||
ifeq ($(LANDLOCKMAKE_VERSION),)
|
||||
TMPSAFE = $(join $(TMPDIR)/,$(subst /,_,$@)).tmp
|
||||
else
|
||||
TMPSAFE = $(TMPDIR)/
|
||||
endif
|
||||
V ?= 1
|
||||
LC_ALL = C.UTF-8
|
||||
SOURCE_DATE_EPOCH = 0
|
||||
|
||||
BACKTRACES = \
|
||||
-fno-schedule-insns2 \
|
||||
-fno-optimize-sibling-calls \
|
||||
-mno-omit-leaf-frame-pointer
|
||||
DD ?= /bin/dd
|
||||
CP ?= /bin/cp -f
|
||||
RM ?= /bin/rm -f
|
||||
SED ?= /bin/sed
|
||||
MKDIR ?= /bin/mkdir -p
|
||||
TAGS ?= /usr/bin/ctags # emacs source builds or something breaks it
|
||||
ARFLAGS = rcsD
|
||||
ZFLAGS ?=
|
||||
XARGS ?= xargs -P4 -rs8000
|
||||
NICE ?= build/actuallynice
|
||||
DOT ?= dot
|
||||
GZ ?= gzip
|
||||
CLANG = clang-10
|
||||
FC = gfortran #/opt/cross9f/bin/x86_64-linux-musl-gfortran
|
||||
|
||||
# see build/compile, etc. which run third_party/gcc/unbundle.sh
|
||||
AS = o/third_party/gcc/bin/x86_64-linux-musl-as
|
||||
CC = o/third_party/gcc/bin/x86_64-linux-musl-gcc
|
||||
CXX = o/third_party/gcc/bin/x86_64-linux-musl-g++
|
||||
CXXFILT = o/third_party/gcc/bin/x86_64-linux-musl-c++filt
|
||||
LD = o/third_party/gcc/bin/x86_64-linux-musl-ld.bfd
|
||||
AR = build/archive
|
||||
NM = o/third_party/gcc/bin/x86_64-linux-musl-nm
|
||||
GCC = o/third_party/gcc/bin/x86_64-linux-musl-gcc
|
||||
STRIP = o/third_party/gcc/bin/x86_64-linux-musl-strip
|
||||
OBJCOPY = o/third_party/gcc/bin/x86_64-linux-musl-objcopy
|
||||
OBJDUMP = o/third_party/gcc/bin/x86_64-linux-musl-objdump
|
||||
ADDR2LINE = o/third_party/gcc/bin/x86_64-linux-musl-addr2line
|
||||
|
||||
COMMA := ,
|
||||
PWD := $(shell pwd)
|
||||
IMAGE_BASE_VIRTUAL ?= 0x400000
|
||||
TMPDIR := $(shell build/findtmp)
|
||||
LOGFMT := $(shell build/getlogfmt)
|
||||
COMPILE := $(shell build/getcompile)
|
||||
CCNAME := $(shell build/getccname $(CC))
|
||||
CCVERSION := $(shell build/getccversion $(CC))
|
||||
BLAH1 := $(shell build/zipobj 2>/dev/null)
|
||||
BLAH2 := $(shell build/package 2>/dev/null)
|
||||
|
||||
export ADDR2LINE
|
||||
export CCNAME
|
||||
export CCVERSION
|
||||
export COMPILE
|
||||
export CP
|
||||
export DD
|
||||
export GZ
|
||||
export IMAGE_BASE_VIRTUAL
|
||||
export LC_ALL
|
||||
export LOGFMT
|
||||
export MKDIR
|
||||
export MODE
|
||||
export OBJDUMP
|
||||
export RM
|
||||
export SED
|
||||
export SOURCE_DATE_EPOCH
|
||||
export TMPDIR
|
||||
export V
|
||||
export ZFLAGS
|
||||
|
||||
unexport COMPILER_PATH
|
||||
unexport CPATH
|
||||
unexport CPLUS_INCLUDE_PATH
|
||||
unexport C_INCLUDE_PATH
|
||||
unexport DEPENDENCIES_OUTPUT
|
||||
unexport GCC_COMPARE_DEBUG
|
||||
unexport GCC_EXEC_PREFIX
|
||||
unexport LANG
|
||||
unexport LC_CTYPE
|
||||
unexport LC_MESSAGES
|
||||
unexport LIBRARY_PATH
|
||||
unexport OBJC_INCLUDE_PATH
|
||||
unexport SUNPRO_DEPENDENCIES
|
||||
|
||||
FTRACE = \
|
||||
-pg
|
||||
|
||||
SANITIZER = \
|
||||
-fsanitize=leak \
|
||||
-fsanitize=address
|
||||
|
||||
NO_MAGIC = \
|
||||
-ffreestanding \
|
||||
-mno-fentry \
|
||||
-fno-stack-protector \
|
||||
-fwrapv \
|
||||
-fno-sanitize=all \
|
||||
-fpatchable-function-entry=0,0
|
||||
-fwrapv
|
||||
|
||||
OLD_CODE = \
|
||||
-fno-strict-aliasing \
|
||||
|
@ -80,104 +142,78 @@ TRADITIONAL = \
|
|||
-Wno-return-type \
|
||||
-Wno-pointer-sign
|
||||
|
||||
DEFAULT_CCFLAGS += \
|
||||
DEFAULT_CCFLAGS = \
|
||||
-Wall \
|
||||
-Werror \
|
||||
-fno-omit-frame-pointer \
|
||||
-fdebug-prefix-map="$(PWD)"= \
|
||||
-frecord-gcc-switches
|
||||
|
||||
DEFAULT_COPTS ?= \
|
||||
DEFAULT_OFLAGS = \
|
||||
-g \
|
||||
-gdescribe-dies
|
||||
|
||||
DEFAULT_COPTS = \
|
||||
-mno-red-zone \
|
||||
-fno-math-errno \
|
||||
-fno-trapping-math \
|
||||
-fno-fp-int-builtin-inexact \
|
||||
-fno-ident \
|
||||
-fno-common \
|
||||
-fno-gnu-unique \
|
||||
-fstrict-aliasing \
|
||||
-fstrict-overflow \
|
||||
-fno-semantic-interposition
|
||||
|
||||
ifeq ($(ARCH), x86_64)
|
||||
# Microsoft says "[a]ny memory below the stack beyond the red zone
|
||||
# [note: Windows defines the x64 red zone size as 0] is considered
|
||||
# volatile and may be modified by the operating system at any time."
|
||||
# https://devblogs.microsoft.com/oldnewthing/20190111-00/?p=100685
|
||||
DEFAULT_COPTS += \
|
||||
-mno-red-zone \
|
||||
-mno-tls-direct-seg-refs
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH), aarch64)
|
||||
#
|
||||
# - Apple says in "Writing ARM64 code for Apple platforms" that we're
|
||||
# not allowed to use the x18 register.
|
||||
#
|
||||
# - Cosmopolitan Libc uses x28 for thread-local storage because Apple
|
||||
# forbids us from using tpidr_el0 too.
|
||||
#
|
||||
DEFAULT_COPTS += \
|
||||
-ffixed-x18 \
|
||||
-ffixed-x28 \
|
||||
-fsigned-char
|
||||
endif
|
||||
-fno-omit-frame-pointer \
|
||||
-fno-semantic-interposition \
|
||||
-mno-omit-leaf-frame-pointer
|
||||
|
||||
MATHEMATICAL = \
|
||||
-O3 \
|
||||
-fwrapv
|
||||
|
||||
DEFAULT_CPPFLAGS += \
|
||||
-D_COSMO_SOURCE \
|
||||
-DMODE='"$(MODE)"' \
|
||||
-Wno-prio-ctor-dtor \
|
||||
-Wno-unknown-pragmas \
|
||||
DEFAULT_CPPFLAGS = \
|
||||
-DIMAGE_BASE_VIRTUAL=$(IMAGE_BASE_VIRTUAL) \
|
||||
-nostdinc \
|
||||
-iquote. \
|
||||
-isystem libc/isystem
|
||||
-iquote.
|
||||
|
||||
DEFAULT_CFLAGS = \
|
||||
-std=gnu23
|
||||
-std=gnu2x
|
||||
|
||||
DEFAULT_CXXFLAGS = \
|
||||
-std=gnu++23 \
|
||||
-std=gnu++11 \
|
||||
-fno-rtti \
|
||||
-fno-exceptions \
|
||||
-fuse-cxa-atexit \
|
||||
-fno-threadsafe-statics \
|
||||
-Wno-int-in-bool-context \
|
||||
-Wno-narrowing \
|
||||
-Wno-literal-suffix \
|
||||
-isystem third_party/libcxx
|
||||
-Wno-narrowing
|
||||
|
||||
DEFAULT_ASFLAGS = \
|
||||
-W \
|
||||
-I. \
|
||||
--noexecstack
|
||||
--noexecstack \
|
||||
--nocompress-debug-sections
|
||||
|
||||
DEFAULT_LDFLAGS = \
|
||||
-static \
|
||||
-nostdlib \
|
||||
-znorelro \
|
||||
--gc-sections \
|
||||
-z noexecstack \
|
||||
-m elf_x86_64 \
|
||||
--build-id=none \
|
||||
--no-dynamic-linker
|
||||
--no-dynamic-linker \
|
||||
-z max-page-size=0x1000
|
||||
|
||||
# # generate linker report files
|
||||
# DEFAULT_LDFLAGS += --cref -Map=$@.map
|
||||
|
||||
ifeq ($(ARCH), aarch64)
|
||||
DEFAULT_LDFLAGS += \
|
||||
-zmax-page-size=0x4000 \
|
||||
-zcommon-page-size=0x4000 \
|
||||
-znorelro
|
||||
else
|
||||
DEFAULT_LDFLAGS += \
|
||||
-zmax-page-size=0x4000 \
|
||||
-zcommon-page-size=0x1000
|
||||
endif
|
||||
ZIPOBJ_FLAGS = \
|
||||
-b$(IMAGE_BASE_VIRTUAL)
|
||||
|
||||
ASONLYFLAGS = \
|
||||
-c \
|
||||
-g
|
||||
-g \
|
||||
--debug-prefix-map="$(PWD)"=
|
||||
|
||||
DEFAULT_LDLIBS =
|
||||
|
||||
MCA = llvm-mca-10 \
|
||||
-mtriple=x86_64-pc-linux-gnu \
|
||||
-iterations=3 \
|
||||
-instruction-info \
|
||||
-iterations=3 \
|
||||
-all-stats \
|
||||
|
@ -246,31 +282,41 @@ LD.libs = \
|
|||
$(CONFIG_LIBS) \
|
||||
$(LIBS)
|
||||
|
||||
COMPILE.c.flags = $(cc.flags) $(copt.flags) $(cpp.flags) $(c.flags)
|
||||
COMPILE.cxx.flags = $(cc.flags) $(copt.flags) $(cxx.flags) $(cpp.flags)
|
||||
COMPILE.c.flags = $(cc.flags) $(cpp.flags) $(copt.flags) $(c.flags)
|
||||
COMPILE.cxx.flags = $(cc.flags) $(cpp.flags) $(copt.flags) $(cxx.flags)
|
||||
COMPILE.f.flags = $(cc.flags) $(copt.flags) $(f.flags)
|
||||
COMPILE.F.flags = $(cc.flags) $(cpp.flags) $(copt.flags) $(f.flags)
|
||||
COMPILE.i.flags = $(cc.flags) $(copt.flags) $(c.flags)
|
||||
COMPILE.ii.flags = $(cc.flags) $(copt.flags) $(cxx.flags)
|
||||
LINK.flags = $(DEFAULT_LDFLAGS) $(CONFIG_LDFLAGS) $(LDFLAGS)
|
||||
OBJECTIFY.c.flags = $(cc.flags) $(o.flags) $(S.flags) $(cpp.flags) $(copt.flags) $(c.flags)
|
||||
OBJECTIFY.cxx.flags = $(cc.flags) $(o.flags) $(S.flags) $(cxx.flags) $(cpp.flags) $(copt.flags)
|
||||
OBJECTIFY.c.flags = $(OBJECTIFY.S.flags) $(c.flags)
|
||||
OBJECTIFY.cxx.flags = $(OBJECTIFY.S.flags) $(cxx.flags)
|
||||
OBJECTIFY.s.flags = $(ASONLYFLAGS) $(s.flags)
|
||||
OBJECTIFY.S.flags = $(cc.flags) $(o.flags) $(S.flags) $(cpp.flags)
|
||||
OBJECTIFY.S.flags = $(copt.flags) $(cc.flags) $(o.flags) $(cpp.flags) $(S.flags)
|
||||
OBJECTIFY.f.flags = $(copt.flags) $(cc.flags) $(o.flags) $(copt.flags) $(S.flags) $(f.flags)
|
||||
OBJECTIFY.F.flags = $(OBJECTIFY.f.flags) $(cpp.flags)
|
||||
PREPROCESS.flags = -E $(copt.flags) $(cc.flags) $(cpp.flags)
|
||||
PREPROCESS.lds.flags = -D__LINKER__ $(filter-out -g%,$(PREPROCESS.flags)) -P -xc
|
||||
|
||||
COMPILE.c = $(CC) -S $(COMPILE.c.flags)
|
||||
COMPILE.cxx = $(CXX) -S $(COMPILE.cxx.flags)
|
||||
COMPILE.i = $(CC) -S $(COMPILE.i.flags)
|
||||
COMPILE.f = $(FC) -S $(COMPILE.f.flags)
|
||||
COMPILE.F = $(FC) -S $(COMPILE.F.flags)
|
||||
OBJECTIFY.s = $(AS) $(OBJECTIFY.s.flags)
|
||||
OBJECTIFY.S = $(CC) $(OBJECTIFY.S.flags) -c
|
||||
OBJECTIFY.f = $(FC) $(OBJECTIFY.f.flags) -c
|
||||
OBJECTIFY.F = $(FC) $(OBJECTIFY.F.flags) -c
|
||||
OBJECTIFY.c = $(CC) $(OBJECTIFY.c.flags) -c
|
||||
OBJECTIFY.cxx = $(CXX) $(OBJECTIFY.cxx.flags) -c
|
||||
PREPROCESS = $(CC) $(PREPROCESS.flags)
|
||||
PREPROCESS.lds = $(CC) $(PREPROCESS.lds.flags)
|
||||
LINK = $(LD) $(LINK.flags)
|
||||
ELF = o/libc/elf/elf.lds
|
||||
ELFLINK = $(COMPILE) -ALINK.elf $(LINK) $(LINKARGS) $(OUTPUT_OPTION) && $(COMPILE) -AFIXUP.ape -T$@ $(FIXUPOBJ) $@
|
||||
ELFLINK = ACTION=LINK.elf $(LINK) $(LINKARGS) $(OUTPUT_OPTION)
|
||||
ARCHIVE = $(AR) $(ARFLAGS)
|
||||
LINKARGS = $(patsubst %.lds,-T %.lds,$(call uniqr,$(LD.libs) $(filter-out %.pkg,$^)))
|
||||
LOLSAN = build/lolsan -b $(IMAGE_BASE_VIRTUAL)
|
||||
|
||||
# The compiler won't generate %xmm code for sources extensioned .greg.c,
|
||||
# which is needed for C modules wanting to run at the executive level or
|
||||
|
@ -284,8 +330,70 @@ OBJECTIFY.greg.c = \
|
|||
-fno-instrument-functions \
|
||||
-fno-optimize-sibling-calls \
|
||||
-fno-sanitize=all \
|
||||
-ffreestanding \
|
||||
-fwrapv \
|
||||
-c
|
||||
|
||||
OBJECTIFY.ansi.c = $(CC) $(OBJECTIFY.c.flags) -ansi -Wextra -Werror -pedantic-errors -c
|
||||
OBJECTIFY.c99.c = $(CC) $(OBJECTIFY.c.flags) -std=c99 -Wextra -Werror -pedantic-errors -c
|
||||
OBJECTIFY.c11.c = $(CC) $(OBJECTIFY.c.flags) -std=c11 -Wextra -Werror -pedantic-errors -c
|
||||
OBJECTIFY.c2x.c = $(CC) $(OBJECTIFY.c.flags) -std=c2x -Wextra -Werror -pedantic-errors -c
|
||||
|
||||
OBJECTIFY.real.c = \
|
||||
$(GCC) \
|
||||
-x-no-pg \
|
||||
$(OBJECTIFY.c.flags) \
|
||||
-wrapper build/realify.sh \
|
||||
-D__REAL_MODE__ \
|
||||
-ffixed-r8 \
|
||||
-ffixed-r9 \
|
||||
-ffixed-r10 \
|
||||
-ffixed-r11 \
|
||||
-ffixed-r12 \
|
||||
-ffixed-r13 \
|
||||
-ffixed-r14 \
|
||||
-ffixed-r15 \
|
||||
-mno-red-zone \
|
||||
-fcall-used-rbx \
|
||||
-fno-jump-tables \
|
||||
-fno-shrink-wrap \
|
||||
-fno-schedule-insns2 \
|
||||
-flive-range-shrinkage \
|
||||
-fno-omit-frame-pointer \
|
||||
-momit-leaf-frame-pointer \
|
||||
-mpreferred-stack-boundary=3 \
|
||||
-fno-delete-null-pointer-checks \
|
||||
-c
|
||||
|
||||
OBJECTIFY.ncabi.c = \
|
||||
$(GCC) \
|
||||
$(OBJECTIFY.c.flags) \
|
||||
-mno-sse \
|
||||
-mfpmath=387 \
|
||||
-mno-fentry \
|
||||
-fno-stack-protector \
|
||||
-fno-instrument-functions \
|
||||
-fno-optimize-sibling-calls \
|
||||
-fno-sanitize=all \
|
||||
-fcall-saved-rcx \
|
||||
-fcall-saved-rdx \
|
||||
-fcall-saved-rdi \
|
||||
-fcall-saved-rsi \
|
||||
-fcall-saved-r8 \
|
||||
-fcall-saved-r9 \
|
||||
-fcall-saved-r10 \
|
||||
-fcall-saved-r11 \
|
||||
-c \
|
||||
-xc
|
||||
|
||||
OBJECTIFY.initabi.c = \
|
||||
$(GCC) \
|
||||
$(OBJECTIFY.c.flags) \
|
||||
-mno-fentry \
|
||||
-fno-stack-protector \
|
||||
-fno-instrument-functions \
|
||||
-fno-optimize-sibling-calls \
|
||||
-fno-sanitize=all \
|
||||
-fcall-saved-rdi \
|
||||
-fcall-saved-rsi \
|
||||
-c
|
||||
|
||||
TAGSFLAGS = \
|
||||
|
|
55
build/do
Executable file
55
build/do
Executable file
|
@ -0,0 +1,55 @@
|
|||
#!/bin/sh
|
||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
||||
#
|
||||
# OVERVIEW
|
||||
#
|
||||
# Generic Command Runner
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This does auto mkdir and ephemeral logging.
|
||||
#
|
||||
# EXAMPLE
|
||||
#
|
||||
# build/do PROG [ARGS...]
|
||||
|
||||
MKDIR=${MKDIR:-$(command -v mkdir) -p} || exit
|
||||
|
||||
# Ensure directory creation if -o PATH flag is passed.
|
||||
OUT="$TARGET"
|
||||
FIRST=1
|
||||
OUTARG=0
|
||||
for x; do
|
||||
if [ $FIRST -eq 1 ]; then
|
||||
set --
|
||||
FIRST=0
|
||||
elif [ $OUTARG -eq 1 ]; then
|
||||
OUTARG=0
|
||||
OUT="$x"
|
||||
fi
|
||||
case "$x" in
|
||||
-o)
|
||||
OUTARG=1
|
||||
;;
|
||||
-o*)
|
||||
OUT=${x#-o}
|
||||
;;
|
||||
esac
|
||||
set -- "$@" "$x"
|
||||
done
|
||||
if [ "$OUT" ]; then
|
||||
OUTDIR="${OUT%/*}"
|
||||
if [ "$OUTDIR" != "$OUT" ] && [ ! -d "$OUTDIR" ]; then
|
||||
$MKDIR "$OUTDIR" || exit 2
|
||||
fi
|
||||
fi
|
||||
|
||||
# Log command.
|
||||
if [ "$V" = "0" ]; then
|
||||
printf "$LOGFMT" "${ACTION:-BUILD}" "$TARGET" >&2
|
||||
else
|
||||
printf "%s\n" "$*" >&2
|
||||
fi
|
||||
|
||||
exec "$@"
|
|
@ -1,106 +0,0 @@
|
|||
#!/bin/sh
|
||||
# cosmocc downloader script
|
||||
# https://justine.lol/cosmo3/#install
|
||||
# https://github.com/jart/cosmopolitan/blob/master/tool/cosmocc/README.md
|
||||
|
||||
# collect arguments
|
||||
OUTPUT_DIR=${1:?OUTPUT_DIR}
|
||||
COSMOCC_VERSION=${2:?COSMOCC_VERSION}
|
||||
COSMOCC_SHA256SUM=${3:?COSMOCC_SHA256SUM}
|
||||
URL1="https://github.com/jart/cosmopolitan/releases/download/${COSMOCC_VERSION}/cosmocc-${COSMOCC_VERSION}.zip"
|
||||
URL2="https://cosmo.zip/pub/cosmocc/cosmocc-${COSMOCC_VERSION}.zip"
|
||||
|
||||
# helper function
|
||||
abort() {
|
||||
printf '%s\n' "download terminated." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# exit if already downloaded
|
||||
# we need it because directory timestamps work wierdly
|
||||
OUTPUT_DIR=${OUTPUT_DIR%/}
|
||||
if [ -d "${OUTPUT_DIR}" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# find commands we need to securely download cosmocc
|
||||
if ! UNZIP=$(command -v unzip 2>/dev/null); then
|
||||
printf '%s\n' "$0: fatal error: you need the unzip command" >&2
|
||||
printf '%s\n' "please download https://cosmo.zip/pub/cosmos/bin/unzip and put it on the system path" >&2
|
||||
abort
|
||||
fi
|
||||
if command -v sha256sum >/dev/null 2>&1; then
|
||||
# can use system sha256sum
|
||||
true
|
||||
elif command -v shasum >/dev/null 2>&1; then
|
||||
sha256sum() {
|
||||
shasum -a 256 "$@"
|
||||
}
|
||||
else
|
||||
if [ ! -f build/sha256sum.c ]; then
|
||||
printf '%s\n' "$0: fatal error: you need to install sha256sum" >&2
|
||||
printf '%s\n' "please download https://cosmo.zip/pub/cosmos/bin/sha256sum and put it on the system path" >&2
|
||||
abort
|
||||
fi
|
||||
if ! SHA256SUM=$(command -v "$PWD/o/build/sha256sum" 2>/dev/null); then
|
||||
if ! CC=$(command -v "$CC" 2>/dev/null); then
|
||||
if ! CC=$(command -v cc 2>/dev/null); then
|
||||
if ! CC=$(command -v cosmocc 2>/dev/null); then
|
||||
printf '%s\n' "$0: fatal error: you need to install either sha256sum, cc, or cosmocc" >&2
|
||||
printf '%s\n' "please download https://cosmo.zip/pub/cosmos/bin/sha256sum and put it on the system path" >&2
|
||||
abort
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
mkdir -p o/build || abort
|
||||
SHA256SUM="$PWD/o/build/sha256sum"
|
||||
printf '%s\n' "${CC} -w -O2 -o ${SHA256SUM} build/sha256sum.c" >&2
|
||||
"${CC}" -w -O2 -o "${SHA256SUM}.$$" build/sha256sum.c || abort
|
||||
mv -f "${SHA256SUM}.$$" "${SHA256SUM}" || abort
|
||||
fi
|
||||
sha256sum() {
|
||||
"${SHA256SUM}" "$@"
|
||||
}
|
||||
fi
|
||||
if WGET=$(command -v wget 2>/dev/null); then
|
||||
DOWNLOAD=$WGET
|
||||
DOWNLOAD_ARGS=-O
|
||||
elif CURL=$(command -v curl 2>/dev/null); then
|
||||
DOWNLOAD=$CURL
|
||||
DOWNLOAD_ARGS=-fLo
|
||||
else
|
||||
printf '%s\n' "$0: fatal error: you need to install either wget or curl" >&2
|
||||
printf '%s\n' "please download https://cosmo.zip/pub/cosmos/bin/wget and put it on the system path" >&2
|
||||
abort
|
||||
fi
|
||||
|
||||
# create temporary output directory
|
||||
OLDPWD=$PWD
|
||||
OUTPUT_TMP="${OUTPUT_DIR}.tmp.$$/"
|
||||
mkdir -p "${OUTPUT_TMP}" || abort
|
||||
cd "${OUTPUT_TMP}"
|
||||
die() {
|
||||
cd "${OLDPWD}"
|
||||
rm -rf "${OUTPUT_TMP}"
|
||||
abort
|
||||
}
|
||||
|
||||
# download cosmocc toolchain
|
||||
# multiple urls avoids outages and national firewalls
|
||||
if ! "${DOWNLOAD}" ${DOWNLOAD_ARGS} cosmocc.zip "${URL1}"; then
|
||||
rm -f cosmocc.zip
|
||||
"${DOWNLOAD}" ${DOWNLOAD_ARGS} cosmocc.zip "${URL2}" || die
|
||||
fi
|
||||
printf '%s\n' "${COSMOCC_SHA256SUM} *cosmocc.zip" >cosmocc.zip.sha256sum
|
||||
sha256sum -c cosmocc.zip.sha256sum || die
|
||||
"${UNZIP}" cosmocc.zip || die
|
||||
rm -f cosmocc.zip cosmocc.zip.sha256sum
|
||||
|
||||
# commit output directory
|
||||
cd "${OLDPWD}" || die
|
||||
mv "${OUTPUT_TMP}" "${OUTPUT_DIR}" || die
|
||||
|
||||
# update current symlink
|
||||
BASE=$(basename "${OUTPUT_DIR}")
|
||||
DIR=$(dirname "${OUTPUT_DIR}")
|
||||
ln -sfn "$BASE" "$DIR/current"
|
17
build/findtmp
Executable file
17
build/findtmp
Executable file
|
@ -0,0 +1,17 @@
|
|||
#!/usr/bin/env bash
|
||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
||||
#
|
||||
# OVERVIEW
|
||||
#
|
||||
# Temporary Directory Discovery
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# We call this script once per build to ideally find a folder that's
|
||||
# backed by an in-memory file system. We then export it to the TMPDIR
|
||||
# environment variable. Many programs use it under the hood, e.g. gcc,
|
||||
# so it grants many small performance improvements.
|
||||
|
||||
mkdir -p o/tmp
|
||||
echo o/tmp
|
|
@ -1,5 +1,5 @@
|
|||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||
#── vi: set et ft=make ts=8 sw=8 fenc=utf-8 :vi ──────────────────────┘
|
||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
|
@ -12,9 +12,5 @@
|
|||
|
||||
tail = $(wordlist 2,$(words $1),$1)
|
||||
reverse = $(if $1,$(call reverse,$(call tail,$1)) $(firstword $1))
|
||||
uniqr = $(if $1,$(call uniqr,$(filter-out $(firstword $1),$1)) $(firstword $1))
|
||||
|
||||
# polyfill uniq native (landlock make 1.4)
|
||||
ifneq ($(call uniq,c b c a),c b a)
|
||||
uniq = $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1)))
|
||||
endif
|
||||
uniqr = $(if $1,$(call uniqr,$(filter-out $(firstword $1),$1)) $(firstword $1))
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/sh
|
||||
exec gdb -q -nh -i=mi $1 \
|
||||
-ex "set confirm off" \
|
||||
-ex "add-symbol-file $1.dbg 0x401000" \
|
||||
-ex "run"
|
46
build/getccname
Executable file
46
build/getccname
Executable file
|
@ -0,0 +1,46 @@
|
|||
#!/bin/sh
|
||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
||||
#
|
||||
# OVERVIEW
|
||||
#
|
||||
# Compiler Name Discovery
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Cosmopolitan itself may be built using either GCC and Clang, and our
|
||||
# build irons out many of the differences between the two. This script
|
||||
# determines which one's in play, which is nontrivial, since they tend
|
||||
# to call themselves so many different names.
|
||||
|
||||
if [ ! -d o/third_party/gcc ]; then
|
||||
third_party/gcc/unbundle.sh
|
||||
fi
|
||||
|
||||
set -e
|
||||
|
||||
SPECIAL_TEXT=$(
|
||||
$1 --version |
|
||||
sed -n '
|
||||
/chibicc/ {
|
||||
i\
|
||||
chibicc
|
||||
q
|
||||
}
|
||||
/Free Software/ {
|
||||
i\
|
||||
gcc
|
||||
q
|
||||
}
|
||||
/clang/ {
|
||||
i\
|
||||
clang
|
||||
q
|
||||
}
|
||||
')
|
||||
|
||||
if [ -z "$SPECIAL_TEXT" ]; then
|
||||
echo gcc
|
||||
else
|
||||
printf '%s\n' "$SPECIAL_TEXT"
|
||||
fi
|
39
build/getccversion
Executable file
39
build/getccversion
Executable file
|
@ -0,0 +1,39 @@
|
|||
#!/bin/sh
|
||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
||||
#
|
||||
# OVERVIEW
|
||||
#
|
||||
# Compiler Version Discovery
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Cosmopolitan itself may be built using either GCC and Clang, and our
|
||||
# build irons out many of the differences between the two. This script
|
||||
# is used by build/definitions.mk alongside build/getccname to support
|
||||
# the different versions folks use.
|
||||
#
|
||||
# Our aim is to support GCC 4.2.1+ since that's the last GPLv2 version
|
||||
# with any sort of industry consensus. Please note, Cosmopolitan never
|
||||
# links GCC runtimes when using later versions, so some concerns might
|
||||
# not apply.
|
||||
|
||||
if [ ! -d o/third_party/gcc ]; then
|
||||
third_party/gcc/unbundle.sh
|
||||
fi
|
||||
|
||||
set -e
|
||||
|
||||
MAJOR_VERSION=$(
|
||||
$1 --version |
|
||||
head -n1 |
|
||||
sed -n '
|
||||
s!^[^(]*([^)]*) \([[:digit:]][[:digit:]]*\).*!\1!p
|
||||
s!^.*clang.*version \([[:digit:]][[:digit:]]*\).*!\1!p
|
||||
')
|
||||
|
||||
if [ -z "$MAJOR_VERSION" ]; then
|
||||
echo 6
|
||||
else
|
||||
printf '%s\n' "$MAJOR_VERSION"
|
||||
fi
|
12
build/getcompile
Executable file
12
build/getcompile
Executable file
|
@ -0,0 +1,12 @@
|
|||
#!/bin/sh
|
||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
||||
|
||||
if ! [ o/build/bootstrap/compile.com -nt build/bootstrap/compile.com ]; then
|
||||
mkdir -p o/build/bootstrap/
|
||||
cp -f build/bootstrap/compile.com o/build/bootstrap/compile.$$.com
|
||||
o/build/bootstrap/compile.$$.com --do-nothing
|
||||
mv -f o/build/bootstrap/compile.$$.com o/build/bootstrap/compile.com
|
||||
fi
|
||||
|
||||
echo o/build/bootstrap/compile.com
|
29
build/getlogfmt
Executable file
29
build/getlogfmt
Executable file
|
@ -0,0 +1,29 @@
|
|||
#!/usr/bin/env bash
|
||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
||||
#
|
||||
# OVERVIEW
|
||||
#
|
||||
# Printf Logger Initializer
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This program is invoked once by build/definitions.mk to choose the
|
||||
# most appropriate format string when logging command invocations.
|
||||
|
||||
W1=15
|
||||
if [ "$TERM" = "dumb" ]; then
|
||||
if [ "$COLUMNS" = "" ]; then
|
||||
if TPUT=$(command -v tput); then
|
||||
COLUMNS=$("$TPUT" cols)
|
||||
else
|
||||
COLUMNS=80
|
||||
fi
|
||||
fi
|
||||
COLUMNS=$((COLUMNS - 1))
|
||||
W2=$((COLUMNS - W1))
|
||||
printf '%%-%ds%%-%ds\\r' "$W1" "$W2"
|
||||
else
|
||||
echo ♥cosmo >&2
|
||||
printf '\\033[F\\033[K%%-%ds%%s\\r\\n' "$W1"
|
||||
fi
|
13
build/htags
13
build/htags
|
@ -1,6 +1,6 @@
|
|||
#!/bin/sh
|
||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
||||
#── vi: set et ft=sh ts=2 sts=2 fenc=utf-8 :vi ─────────────┘
|
||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
||||
#
|
||||
# OVERVIEW
|
||||
#
|
||||
|
@ -43,19 +43,12 @@
|
|||
# '(progn
|
||||
# (add-hook 'c-mode-common-hook 'jart-c-mode-common-hook)))
|
||||
|
||||
TAGS="$1"
|
||||
shift
|
||||
|
||||
# ctags doesn't understand atomics, e.g.
|
||||
# extern char **environ;
|
||||
set -- --regex-c='/_Atomic(\([^)]*\))/\1/b' "$@"
|
||||
|
||||
# ctags doesn't understand variable prototypes, e.g.
|
||||
# extern char **environ;
|
||||
set -- --regex-c='/^\(\(hidden\|extern\|const\) \)*[_[:alpha:]][_[:alnum:]]*[ *][ *]*\([_[:alpha:]][_[:alnum:]]*[ *][ *]*\)*\([_[:alpha:]][_$[:alnum:]]*\)/\4/b' "$@"
|
||||
|
||||
# ctags doesn't understand function prototypes, e.g.
|
||||
# bool isheap(void *p) dontthrow dontcallback;
|
||||
# bool isheap(void *p) nothrow nocallback;
|
||||
set -- --regex-c='/^[_[:alpha:]][_[:alnum:]]*[ *][ *]*\([_[:alpha:]][_[:alnum:]]*[ *][ *]*\)*\([_[:alpha:]][_$[:alnum:]]*\)(.*/\2/b' "$@"
|
||||
|
||||
# ctags doesn't understand function pointers, e.g.
|
||||
|
@ -66,7 +59,7 @@ set -- --regex-c='/^extern [^(]*(\*const \([^)]*\))(/\1/b' "$@"
|
|||
# struct WorstSoftwareEver;
|
||||
set -- --regex-c='/^struct.*;$/uehocruehcroue/b' "$@"
|
||||
|
||||
build/run $TAGS \
|
||||
exec ${TAGS:-ctags} \
|
||||
-e \
|
||||
--langmap=c:.c.h \
|
||||
--exclude=libc/nt/struct/imagefileheader.internal.h \
|
||||
|
|
7
build/includeall
Executable file
7
build/includeall
Executable file
|
@ -0,0 +1,7 @@
|
|||
#!/bin/sh
|
||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
||||
|
||||
for x; do
|
||||
printf '#include "%s"\n' "$x"
|
||||
done
|
65
build/link
Executable file
65
build/link
Executable file
|
@ -0,0 +1,65 @@
|
|||
#!/bin/sh
|
||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
||||
#
|
||||
# OVERVIEW
|
||||
#
|
||||
# GNU Linker Veneer
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This script wraps normal linker commands that're transparently
|
||||
# passed-through. It adds ephemeral logging and directory creation.
|
||||
#
|
||||
# EXAMPLE
|
||||
#
|
||||
# build/linker ld -o program program.o
|
||||
|
||||
if [ ! -d o/third_party/gcc ]; then
|
||||
third_party/gcc/unbundle.sh
|
||||
fi
|
||||
|
||||
MKDIR=${MKDIR:-$(command -v mkdir) -p} || exit
|
||||
|
||||
OUT=
|
||||
FIRST=1
|
||||
OUTARG=0
|
||||
for x; do
|
||||
if [ $FIRST -eq 1 ]; then
|
||||
set --
|
||||
FIRST=0
|
||||
elif [ $OUTARG -eq 1 ]; then
|
||||
OUTARG=0
|
||||
OUT="$x"
|
||||
fi
|
||||
case "$x" in
|
||||
-o)
|
||||
OUTARG=1
|
||||
;;
|
||||
esac
|
||||
set -- "$@" "$x"
|
||||
done
|
||||
|
||||
if [ "$V" = "0" ]; then
|
||||
printf "$LOGFMT" "${ACTION:-LINK.elf}" "$OUT" >&2
|
||||
else
|
||||
printf "%s\n" "$*" >&2
|
||||
fi
|
||||
|
||||
OUTDIR="${OUT%/*}"
|
||||
if [ "$OUTDIR" != "$OUT" ] && [ ! -d "$OUTDIR" ]; then
|
||||
$MKDIR "$OUTDIR" || exit 2
|
||||
fi
|
||||
|
||||
REASON=failed
|
||||
trap REASON=interrupted INT
|
||||
|
||||
"$@" && exit
|
||||
|
||||
if [ "$TERM" = "dumb" ]; then
|
||||
f='%s %s\r\n\r\n'
|
||||
else
|
||||
f='\033[91m%s\033[39m \033[94m%s\033[39m\r\n\r\n'
|
||||
fi
|
||||
printf "$f" "link $REASON:" "$*" >&2
|
||||
exit 1
|
22
build/mkdeps
Executable file
22
build/mkdeps
Executable file
|
@ -0,0 +1,22 @@
|
|||
#!/bin/sh
|
||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
||||
|
||||
if [ -x "o/$MODE/tool/build/mkdeps.com" ]; then
|
||||
set -- "o/$MODE/tool/build/mkdeps.com" "$@"
|
||||
else
|
||||
if [ ! -x o/build/bootstrap/mkdeps.com ]; then
|
||||
mkdir -p o/build/bootstrap &&
|
||||
cp -a build/bootstrap/mkdeps.com \
|
||||
o/build/bootstrap/mkdeps.com || exit
|
||||
fi
|
||||
set -- o/build/bootstrap/mkdeps.com "$@"
|
||||
fi
|
||||
|
||||
if [ "$V" = "0" ]; then
|
||||
printf "$LOGFMT" "${ACTION:-MKDEPS}" "$3" >&2
|
||||
else
|
||||
printf "%s\n" "$*" >&2
|
||||
fi
|
||||
|
||||
exec "$@"
|
|
@ -1,29 +1,22 @@
|
|||
#!/bin/sh
|
||||
COSMO=${COSMO:-/opt/cosmo}
|
||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
||||
#
|
||||
# OVERVIEW
|
||||
#
|
||||
# GNU Disassembly Veneer
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This script wraps normal objdump commands that're transparently
|
||||
# passed-through.
|
||||
#
|
||||
# EXAMPLE
|
||||
#
|
||||
# build/objdump -xd o/tiny/examples/life.com.dbg
|
||||
|
||||
if [ -n "$OBJDUMP" ]; then
|
||||
exec "$OBJDUMP" "$@"
|
||||
if [ ! -d o/third_party/gcc ]; then
|
||||
third_party/gcc/unbundle.sh
|
||||
fi
|
||||
|
||||
find_objdump() {
|
||||
if [ -x .cosmocc/3.9.2/bin/$1-linux-cosmo-objdump ]; then
|
||||
OBJDUMP=.cosmocc/3.9.2/bin/$1-linux-cosmo-objdump
|
||||
elif [ -x .cosmocc/3.9.2/bin/$1-linux-musl-objdump ]; then
|
||||
OBJDUMP=.cosmocc/3.9.2/bin/$1-linux-musl-objdump
|
||||
elif [ -x "$COSMO/.cosmocc/3.9.2/bin/$1-linux-cosmo-objdump" ]; then
|
||||
OBJDUMP="$COSMO/.cosmocc/3.9.2/bin/$1-linux-cosmo-objdump"
|
||||
elif [ -x "$COSMO/.cosmocc/3.9.2/bin/$1-linux-musl-objdump" ]; then
|
||||
OBJDUMP="$COSMO/.cosmocc/3.9.2/bin/$1-linux-musl-objdump"
|
||||
else
|
||||
echo "error: toolchain not found (try running 'cosmocc --update' or 'make' in the cosmo monorepo)" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
if printf '%s\n' "$*" | grep aarch64 >/dev/null 2>&1; then
|
||||
find_objdump aarch64
|
||||
exec "$OBJDUMP" "$@"
|
||||
else
|
||||
find_objdump x86_64
|
||||
exec "$OBJDUMP" "$@"
|
||||
fi
|
||||
exec o/third_party/gcc/bin/x86_64-linux-musl-objdump "$@"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||
#── vi: set et ft=make ts=8 sw=8 fenc=utf-8 :vi ──────────────────────┘
|
||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
|
@ -22,14 +22,10 @@
|
|||
# - tool/build/runit.c
|
||||
# - tool/build/runitd.c
|
||||
|
||||
.PRECIOUS: o/$(MODE)/%.ok
|
||||
o/$(MODE)/%.ok: private .PLEDGE = stdio rpath wpath cpath proc fattr inet dns
|
||||
o/$(MODE)/%.ok: private .UNVEIL += r:/etc/resolv.conf
|
||||
o/$(MODE)/%.ok: \
|
||||
o/$(MODE)/tool/build/runit \
|
||||
o/$(MODE)/tool/build/runitd \
|
||||
o/$(MODE)/%
|
||||
@$(COMPILE) -wATEST -tT$@ $^ $(HOSTS)
|
||||
|
||||
.PHONY:
|
||||
o/tiny/tool/build/runit:
|
||||
.PRECIOUS: o/$(MODE)/%.com.ok
|
||||
o/$(MODE)/%.com.ok: \
|
||||
o/$(MODE)/tool/build/runit.com.dbg \
|
||||
o/$(MODE)/tool/build/runitd.com \
|
||||
o/$(MODE)/%.com
|
||||
@ACTION=TEST TARGET=$@ build/do $^ $(HOSTS)
|
||||
@touch $@
|
||||
|
|
33
build/package
Executable file
33
build/package
Executable file
|
@ -0,0 +1,33 @@
|
|||
#!/bin/sh
|
||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
||||
|
||||
if [ "$TOOL_BUILD_PACKAGE" ]; then
|
||||
set -- "$TOOL_BUILD_PACKAGE" "$@"
|
||||
else
|
||||
if [ -x "o/tool/build/package.com.dbg" ]; then
|
||||
set -- "o/tool/build/package.com.dbg" "$@"
|
||||
else
|
||||
MKDIR=${MKDIR:-$(command -v mkdir) -p} || exit
|
||||
CP=${CP:-$(command -v cp) -f} || exit
|
||||
if [ ! -x o/build/bootstrap/package.com ]; then
|
||||
$MKDIR o/build/bootstrap &&
|
||||
$CP -a build/bootstrap/package.com \
|
||||
o/build/bootstrap/package.com || exit
|
||||
fi
|
||||
set -- o/build/bootstrap/package.com "$@"
|
||||
fi
|
||||
fi
|
||||
|
||||
printf "$LOGFMT" "${ACTION:-PACKAGE}" "$3" >&2
|
||||
# if [ "$V" = "0" ]; then
|
||||
# printf "$LOGFMT" "${ACTION:-PACKAGE}" "$3" >&2
|
||||
# else
|
||||
# COLUMNS=${COLUMNS:-80}
|
||||
# COLUMNS=$((COLUMNS - 4))
|
||||
# printf "%s\n" "$*" |
|
||||
# /usr/bin/fold -s -w $COLUMNS |
|
||||
# sed -e '1bb' -e 's/^/ /' -e ':b' -e '$b' -e 's/$/ \\/' >&2
|
||||
# fi
|
||||
|
||||
exec "$@"
|
|
@ -1,5 +1,5 @@
|
|||
#-*-mode:sed;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||
#── vi: et ft=sed ts=8 sw=8 fenc=utf-8 :vi ────────────────┘
|
||||
#───vi: et ft=sed ts=8 tw=8 fenc=utf-8 :vi─────────────────┘
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
|
|
2189
build/rle.py
Normal file
2189
build/rle.py
Normal file
File diff suppressed because it is too large
Load diff
7
build/rollup
Executable file
7
build/rollup
Executable file
|
@ -0,0 +1,7 @@
|
|||
#!/bin/sh
|
||||
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
|
||||
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘
|
||||
|
||||
for x; do
|
||||
printf '#include "%s"\n' "$x"
|
||||
done
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue