# LibMCPU LibMCPU is a software CPU and toolchain built on LibMPU. It provides the MCPU instruction interpreter together with assembler, linker, loader/runtime, inspection and archive utilities for the MELF object format. The current toolchain supports: - MELF `ET_REL` relocatable objects; - ABI-v1 fully static `ET_EXEC` programs; - frozen ABI-v3 startup-dynamic `ET_EXEC` and `ET_DYN` objects with `DT_SONAME` / `DT_NEEDED`; - historical ABI-v2 explicit-preload files in the runtime loader; - deterministic UNIX `ar` static libraries containing MELF `ET_REL` members; - partial relocatable linking with `mcpu-ld -r`; - low-level MELF lifecycle executables owning `_start`, `_life` and optional `_fini`; - compiler-normalized HLL PROGRAM and MODEL objects with automatic CRT selection and insertion by `mcpu-ld`; - architectural PROGRAM/DATA/CONTROL/INPUT/OUTPUT/TRACE spaces, STACK and optional HEAP; - LibMPU integer/Real/Complex execution facilities. Successful `mcpu-as` and `mcpu-ld` invocations are quiet by default; `-v` or `--verbose` prints the MELF output-object summary intended for development and inspection. The canonical public MCPU assembler ABI headers live under `sysroot/include/sys/asm/`. The canonical runtime-root configuration source is `sysroot/etc/mcpu-ld.conf`, installed as `/etc/mcpu-ld.conf`. Regression inputs are owned by `tests/fixtures/`. LibMCPU intentionally does not contain the user-facing examples package. Release history belongs in [NEWS.md](NEWS.md) and `ChangeLog`; README describes the current source tree and interfaces rather than duplicating per-release change notes. The normative architecture and MELF references are distributed under `doc/`. ## Required libraries LibMCPU is developed and tested with: ```text LibMPU 1.0.25 or later LibMPUIO 1.0.4 or later ``` A normal installation used by the project is: ```text prefix = /usr libdir = /usr/lib64 ``` ## Build and test A release archive already contains generated Autotools files: ```sh mkdir build cd build ../configure \ --prefix=/usr \ --libdir=/usr/lib64 make make check make install ``` For a development source tree, run `./bootstrap` before `configure` after changing Autotools inputs. `make tests` is an alias for the project test suite. `make distcheck` performs a clean distribution rebuild/install/uninstall verification. ## Commands The toolchain installs these commands: ```text mcpu-as assembler: source -> MELF ET_REL mcpu-ld final and partial linker mcpu-run MELF loader/runtime and MCPU execution supervisor mcpu-readelf read-only MELF inspection mcpu-ar deterministic static-archive manager mcpu-nm symbol table inspection for MELF files and archives mcpu-objdump section, relocation and instruction inspection mcpu-strip safe removal of non-runtime symbol metadata mcpu-objcopy MELF-to-MELF section copy and metadata editing ``` Private command binaries live under: ```text /mcpu/bin/ ``` All installed commands use one common version-reporting module: ```text mcpu- --version -> mcpu- (MCPU) mcpu- --dump-version -> ``` Both forms write exactly one newline-terminated line to standard output and exit successfully without requiring an input file or executable. Normal public symbolic links are installed in ``. ## Symbol inspection `mcpu-nm` lists symbols from MELF `ET_REL`, `ET_EXEC`, `ET_DYN` and static archives: ```sh mcpu-nm file.o mcpu-nm program mcpu-nm -D libfoo.so.1 mcpu-nm libfoo.a ``` By default symbols are sorted by name. `-n` sorts by value, `-p` preserves symbol-table order, `-r` reverses the selected sort, `-g` keeps only external GLOBAL/WEAK symbols, `-u` keeps only undefined symbols, and `-A` prefixes each output line with its input file or archive/member name. `-D` selects `.dynsym` instead of `.symtab`. ## Object disassembly and section inspection `mcpu-objdump` combines section-oriented MELF inspection with the architectural MCPU instruction decoder: ```sh mcpu-objdump -h file.o mcpu-objdump -t -r -d file.o mcpu-objdump -T -d -r libfoo.so mcpu-objdump -s -j .data file.o mcpu-objdump -t libfoo.a ``` `mcpu-strip` removes only symbol metadata that is not required by later linking, loading or execution. In-place operation is the default; `-o` writes a separate result. Current `ET_REL` symbol tables and all dynamic-linking metadata are preserved deliberately. ```sh mcpu-strip program mcpu-strip -o program.stripped program mcpu-strip libfoo.so.1 mcpu-strip libfoo.a ``` `-d` disassembles executable `PROGBITS` sections. `-D` attempts disassembly of all selected nonempty `PROGBITS` sections. `-r` displays RELA relocations and, during disassembly, annotates the instruction containing each relocation field. `-t` and `-T` display `.symtab` and `.dynsym` respectively, `-s` dumps raw section contents, `-h` prints section headers, and repeatable `-j NAME` limits section-oriented output. The disassembler calls the same LibMCPU decoder used by execution through `__cpu_decode_at()`. It does not maintain a second opcode/operand parser. Undecodable bytes are printed as `.byte` and inspection continues. ## Object copying and metadata editing `mcpu-objcopy` always produces MELF output. It is intentionally a structural object editor rather than a ROM-image converter: ```sh mcpu-objcopy input output mcpu-objcopy --dump-section=.data=data.bin input output mcpu-objcopy --add-section=.note.build=build.txt input output mcpu-objcopy --update-section=.note.build=new-build.txt input output mcpu-objcopy --rename-section=.note.build=.note.release input output mcpu-objcopy -R .note.release input output ``` Repeatable `-j/--only-section=NAME` performs strict filtering, but the operation is rejected if it would discard runtime-visible, dynamic-linking or link-critical sections. Added sections are always non-allocated `SHT_PROGBITS` metadata, and update/rename are restricted to safe non-allocated `PROGBITS`. There are no `binary`, Intel HEX, S-record, VMA/LMA or section-flag conversion modes. Deterministic MCPU archives are edited member-by-member. `--dump-section` is accepted for a single MELF input and is rejected for archive input because one `NAME=FILE` destination would be ambiguous across members. ## Manual pages The release installs English section-1 manual pages for every command and a section-7 overview page: ```text mcpu-as(1) mcpu-ld(1) mcpu-run(1) mcpu-readelf(1) mcpu-ar(1) mcpu-nm(1) mcpu-objdump(1) mcpu-strip(1) mcpu-objcopy(1) libmcpu(7) ``` Synchronized Russian pages are installed below the locale-specific man tree: ```text /ru/man1/ /ru/man7/ ``` For a conventional `/usr` installation the English pages live under `/usr/share/man/man1` and `/usr/share/man/man7`; the Russian pages live under `/usr/share/man/ru/man1` and `/usr/share/man/ru/man7`. The manual pages are written from the current command interfaces and complement, rather than replace, the maintained architecture/MELF references. Manual-page sources intentionally do not embed the package release number in the `.TH` source field. The installed commands are the authoritative source of the package version through `--version` and `--dump-version`. This keeps man pages tied to an interface contract instead of requiring a mechanical version edit on every release. ## HLL complete-program contract and CRT Final executable linking recognizes two compiler-normalized HLL complete-program forms directly from the ordinary input `ET_REL` objects; no `--program` or `--model` mode option exists. The defining object must use strong `GLOBAL/FUNC` symbols and keep the complete-program definitions in one object. This is an object-level contract: if a source language makes `fini` optional, its compiler must synthesize an empty strong `fini` during normalization: ```text PROGRAM: main + fini MODEL: init + life + fini ``` The binary HLL signatures are: ```text PROGRAM int32 main(int64 argc, PTR64 argv) void fini(void) MODEL int32 init(int64 argc, PTR64 argv) int32 life(void) void fini(void) ``` For a final `ET_EXEC` link, `mcpu-ld` classifies the explicit input objects before library extraction and automatically inserts CRT objects from the active MCPU root: ```text PROGRAM: crt0.o crti.o crtn.o MODEL: crt1.o crti.o crtn.o ``` The CRT objects are required at `/lib/mcpu/`. A missing or invalid required CRT object is a fatal link error; the linker does not search a fallback root and does not degrade an HLL link into low-level lifecycle linking. A low-level executable continues to define `_start` and `_life` itself, with optional `_fini`, and receives no automatic HLL CRT. Low-level lifecycle ownership and HLL complete-program roots cannot be mixed in one final link. The loader constructs one persistent `McpuStartup` v1 area before `_start`. The CRT validates it, preserves the loader-owned `argv`, converts `argc` to the target signed `int64` HLL ABI, calls the MCPU Libc runtime hooks, and invokes the HLL functions through the ordinary CALL ABI. HLL functions return normally with `RET`; lifecycle `END`/`EXIT` behavior belongs to CRT. For MODEL, `life()` returns `INT32_MIN` to continue through exactly one LIFE `END`, zero for normal model completion, or a positive status for an error exit. Other negative values are reserved by HLL Runtime ABI v1. Graceful finalization orders user `fini()`, `__mcpu_fini_array()` and `__mcpu_libc_fini()` before the final FINI `END`; failures before runtime startup skip those HLL finalizers. ## Basic object and executable workflow Assemble a source file: ```sh mcpu-as -o main.o main.s ``` Build a fully static ABI-v1 executable: ```sh mcpu-ld --stack-size=64K --no-heap \ -o program main.o helper.o mcpu-run program ``` The executable owns its lifecycle entries, STACK descriptor and optional HEAP policy. `mcpu-run` does not replace executable STACK/HEAP values. ## Partial relocatable linking `mcpu-ld -r` combines several relocatable inputs into one new MELF `ET_REL`: ```sh mcpu-ld -r -o combined.o a.o b.o c.o ``` The result is still relocatable. Section contributions are merged with their alignment preserved, symbols are rebased to the merged sections and RELA records remain available for a later link. Strong undefined symbols may remain unresolved: ```sh mcpu-ld -r -o library-part.o a.o b.o mcpu-ld --stack-size=64K -o program main.o library-part.o final-provider.o ``` Partial linking does not create lifecycle entries, STACK/HEAP descriptors, SONAME/NEEDED metadata or a runtime image. `-r` uses only static archives for `-lNAME`. ## Static archives Create a deterministic archive of independent MELF `ET_REL` members: ```sh mcpu-ar rcs libsimple.a add-one.o add-two.o value.o mcpu-ar t libsimple.a mcpu-ar tv libsimple.a ``` `mcpu-ar` supports the principal `r`, `q`, `d`, `t`, `p`, `x` and `s` operations. Archives use the ordinary UNIX `ar` container format and include a real System-V/GNU-style symbol index when requested. During a normal link, archive members are extracted only when they define a currently unresolved strong GLOBAL symbol. An unresolved WEAK reference does not itself pull a member from an archive. For an ABI-v1 link, `-lfoo` searches only `libfoo.a`. For ABI-v3 dynamic or shared output, search is directory-major and each directory is tried as: ```text libfoo.so libfoo.a ``` Thus `.so` wins over `.a` in the same directory, while an archive in an earlier `-L` directory wins over a shared object in a later directory. `mcpu-ld --static` forces every `-lfoo` lookup to consider only `libfoo.a` without changing the selected output mode. For example, `--dynamic --static` still produces an ABI-v3 `ET_EXEC`, and `--shared --static` still produces an ABI-v3 `ET_DYN`; selected archive members are incorporated into the output and therefore add no `DT_NEEDED`. The option is also accepted with the already-static ABI-v1 and `-r` modes. ## ABI-v3 shared libraries Create an ABI-v3 shared object with a mandatory SONAME: ```sh mcpu-ld --shared --soname=libfoo.so.1 \ -o libfoo.so.1.0.0 foo.o ln -s libfoo.so.1.0.0 libfoo.so.1 ln -s libfoo.so.1 libfoo.so ``` Link a startup-dynamic executable: ```sh mcpu-ld --dynamic --stack-size=64K --no-heap \ -L. -lfoo -o program main.o ``` The executable records the provider SONAME in `DT_NEEDED`; it does not record the development link name or physical versioned filename. `mcpu-run` resolves NEEDED dependencies recursively before `_start` and performs all retained relocations before guest execution. There is no PLT/GOT, lazy binding, `dlopen()` or runtime `dlsym()` API. ## Library search and configuration `mcpu-ld` and `mcpu-run` share the relocatable MCPU system-root policy. In increasing priority, the linker configuration chain is: ```text /etc/mcpu-ld.conf /etc/mcpu/mcpu-ld.conf $HOME/.mcpu/etc/mcpu-ld.conf ``` Only the runtime-root configuration file is installed by LibMCPU. The main system-library value is: ```text MCPU_LD_SYSTEM_LIBRARY_PATH = ; ``` Useful common options include: ```text --no-config --sys-root=PATH --dump-config --print-search-dirs ``` `mcpu-ld -L` directories precede the configured system library path. `mcpu-run --library-path` similarly precedes the effective system path. ## Explicit preload `mcpu-run --ldpreload=` remains the explicit startup interposition mechanism. The environment form is: ```sh MCPU_LD_PRELOAD=liba.so:libb.so mcpu-run program ``` Environment preloads are placed before command-line preloads. For equal binding strength, explicit preload priority is rightmost-higher-priority, so a command-line preload naturally overrides an environment preload. GLOBAL definitions outrank WEAK definitions. Normal ABI-v3 dependency scope is deterministic: the main executable precedes ordinary dependencies; the `DT_NEEDED` graph is breadth-first, with direct dependencies before transitive dependencies and siblings in recorded order. Explicit preloads have higher equal-strength scope than the main executable. ## Inspecting MELF files Examples: ```sh mcpu-readelf -h file.o mcpu-readelf -S file.o mcpu-readelf -s file.o mcpu-readelf -r file.o mcpu-readelf -l program mcpu-readelf -d program mcpu-readelf -A program mcpu-readelf -a program ``` Section headers are intentionally printed in a wide one-section-per-line format suitable for reading, `grep`, `awk` and diffs. ## Documentation The shipped Russian PDF reference manuals are release-number-independent architectural documents. `doc/libmcpu-bytecode-architecture-ru.pdf` includes the signed HLL Runtime ABI (mcpu-ld + CRT + MCPU Libc) and permanent appendices for assembler directives, all OPCODE16 values, PSW selectors and RCONST. `doc/libmcpu-melf-abi-ru.pdf` documents the MELF container and linker/runtime contracts. Package release history belongs to `NEWS.md` and `ChangeLog`. Maintained manuals: ```text doc/libmcpu-bytecode-architecture-ru.pdf doc/libmcpu-melf-abi-ru.pdf ``` Editable XeLaTeX sources are under `doc/src/`; the signed HLL/CRT contract source is `doc/src/libmcpu-hll-crt-contract-ru.tex`. Rebuild the maintained PDF manuals with: ```sh cd doc/src ./build-docs.sh ``` The MELF manual is the detailed reference for object/executable layout, relocations, lifecycle, ABI-v1/ABI-v2/ABI-v3 compatibility, dynamic dependency metadata, static archives and linker/runtime contracts. ## Examples Manual and book examples are intentionally distributed as a separate package. LibMCPU does not contain an `examples/` tree. Regression inputs needed by `make check` are self-contained under `tests/fixtures/` and are not intended as the user-facing examples distribution. ## License See `COPYING`.