Primitives système et runtime
Cette page décrit le nettoyage opérationnel LLVM compilateur. Les opérations de bas niveau font partie de seed lui-même, pas un langage complémentaire, mais les applications ordinaires doivent consommer des wrappers sécurisés et audités étroits.
Profils d'exécution
| Profil | Signification |
|---|---|
hosted |
services d'exécution de plateforme sélectionnés par la cible |
freestanding |
image sans libc avec des services explicitement sélectionnés |
kernel |
restrictions du noyau ABI/service et aucune hypothèse hébergée |
none |
aucun service d'exécution au-delà target/compiler primitives |
Effets (alloc, blocage, panique, I/O) sont comparés aux valeurs sélectionnées profile/service ensemble. Les profils ne changent pas ownership/type sémantique.
Linux-L'exécution hébergée native n'a pas de libc obligatoire. linux-libc est un choix explicite d’exécution d’interopérabilité. Freestanding/kernel les cibles restent sans bibliothèque.
Mémoire brute typée
unsafe fn use_buffer() -> Result<i64, alloc_error> {
let pointer = raw_try_alloc<i64>(4)?
raw_write<i64>(pointer, 0, 42)
let value = raw_read<i64>(pointer, 0)
raw_free<i64>(pointer)
Ok(value)
}
Un externe ABI qui revient process/static-lifetime voir le stockage peut déclarer @static_view. Il s'agit d'une assertion de provenance fiable limitée à extern; l'appel reste unsafe et un emballage de bibliothèque sécurisé ordinaire doit vérifier la garantie à vie étrangère.
Le substrat propre et dangereux est raw_try_alloc<t>, raw_null<t>, raw_is_null<t>, raw_read<t>, raw_write<t>, raw_free<t>, et raw_slice<t>. L'allocation rejette les décomptes négatifs, le débordement de multiplication et l'échec de l'allocateur avec alloc_error. Les appelants non sécurisés restent responsables de l’étendue, de l’alignement, de l’initialisation, de la provenance, de l’alias et de la libération exacte des éléments.
raw_null<t>() produit la sentinelle nulle interne utilisée par les propriétaires non sécurisés audités, et raw_is_null<t>(pointer) la teste. La norme box<t> confine ces opérations derrière son constructeur, consommant l'extraction et son destructeur.
Linux-Les allocations natives dont la charge utile plus l'en-tête correspondent à 8 Ko et dont l'alignement est d'au plus 16 octets utilisent des classes de dalle précises (16 octets à 8 Ko). Les dalles vides de 1 Mio partagent un cache de 32 entrées à l'échelle du processus ; les dalles vides en excès ne sont pas cartographiées. Les allocations plus grandes ou plus strictement alignées restent des mappages directs arrondis aux pages et sont immédiatement démappées.
Le runtime natif fournit également les fonctionnalités introduites par l'optimiseur memcpy, memmove, et memset points d'entrée sans libc. C'est sqrt(f64) le symbole d'exécution s'abaisse jusqu'au LLVM racine carrée intrinsèque, permettant aux charges de travail strictes à virgule flottante de rester sans bibliothèque.
Héritage alloc(type,n), adresse entière read/write, et free les exemples appartiennent à des backends archivés et ne sont pas le compilateur propre API.
Espaces d’adressage et appareils
Les types de pointeurs bruts peuvent identifier user, kernel, physical, mmio, ou dma espaces d’adressage. Ils restent distincts grâce à .sdi et LLVM abaissement. Opérations volatiles typées et dangereuses explicites mapping/cast les transitions sont utilisées pour la mémoire de l'appareil. compiler/llvm/libs/system construit des wrappers nominaux sûrs pour MMIO, pages, pin/DMA, l'initialisation et les mécanismes locaux du processeur.
Atomique
Le compilateur valide les assistants acquire/release et les opérations ordonnées explicites de chargement, de stockage, de récupération-ajout, d'échange, de comparaison-échange et de clôture. Les combinaisons de commande load/store/CAS non valides sont rejetées. Les atomes sont distincts de l’accès aux appareils volatils. Un wrapper sécurisé doit établir la durée de vie de l'allocation, l'alignement, l'accès partagé et un protocole atomique cohérent.
FFI et ABI
Le target/ABI la couche attribue des informations internes explicites seed, publique seed, plateforme-C, compilateur intégré, entrée, interruption et nu ABI cours. .sdi comprend la cible, ABI, le profil de construction, le profil d'exécution et l'identité des fonctionnalités d'exécution ; connu seed les incompatibilités d'artefacts échouent avec un diagnostic de reconstruction. Étranger C/assembly les objets n'ont pas seed métadonnées de profil et restent explicitement liées.
Les limites FFI couvertes incluent les scalaires, les pointeurs bruts, les rappels sans capture, les poignées opaques et les wrappers de structure C scalaires basés sur des pointeurs. Les structures C par valeur et la modélisation ABI de plate-forme plus riche restent limitées. Les appels étrangers ne sont pas sécurisés tant qu'ils ne sont pas enveloppés dans un coffre-fort vérifié API.
Panique et nettoyage
L'échec de la vérification sécurisée appelle la cible panic/trap politique. La panique, le piège et l'abandon ne se déroulent jamais seed, FFI, bibliothèque dynamique, interruption, kernel/user, ou les limites des tâches. Aucun nettoyage lexical ou destructeur utilisateur ne s'exécute sur ces bords.
Cohorte de durabilité différée (V3-G48)
Les chargeurs en masse peuvent reporter la durabilité des fichiers à des limites explicites. Avec la cohorte active, path_file.sync() (et tout autre seed_runtime_file_sync appelant) enregistre un fcntl(F_DUPFD) duplication du descripteur au lieu de fsyncing ; la fermeture de la limite synchronise chaque fichier en attente une fois :
extern "c" fn seed_runtime_sync_defer(enabled: i64) -> i64;
extern "c" fn seed_runtime_sync_flush() -> i64;
seed_runtime_sync_defer(1)commence le report ;seed_runtime_sync_flush()fsyncs et ferme chaque doublon enregistré, puis réinitialise la cohorte ;seed_runtime_sync_defer(0)se vide avant de se désactiver.- La liste de cohortes contient au maximum 512 doublons ; le débordement retombe sur un fsync direct, donc l'exactitude ne dépend jamais de la capacité.
- L'état de la cohorte s'étend à l'ensemble du processus (les liens externes globaux sont donc partagés
les bibliothèques s'interposent sur la copie de l'exécutable) et ne sont pas sécurisées pour les tâches ; il est destiné aux chargeurs de masse monothread. Crash avant qu'une limite ne perde tout depuis la limite précédente — les chargeurs par lots doivent aligner les limites avec leurs propres marqueurs de redémarrage (sync-cnpj utilise une limite par table, correspondant à
_load_state).
Débogage du tas
La définition de SEED_HEAP_FENCE=1 dans l'environnement de processus hébergé fait passer l'allocateur d'exécution natif en mode clôture électrique : chaque allocation de tas est soutenue par des mappages de pages privées avec une page de garde placée immédiatement après la charge utile, de sorte que les écritures hors limites et les accès après utilisation libre échouent au niveau de l'instruction incriminée au lieu de corrompre les voisins. Il s'agit d'un mode de diagnostic (environ deux appels mmap par allocation), et non d'une configuration de production.
Exécution et bibliothèques séparées
Les éléments intégrés au compilateur utilisent des ID de symbole d'exécution stables plutôt que l'inspection de la chaîne de nom source. Les services d'exécution exécutables hébergés incluent allocation/resource opérations, processus entry/args/environment, output/files, time/randomness, descripteurs de réseau, hooks de planificateur, régions, panique et abandon au niveau implémenté par chaque ligne cible.
uadd.with.overflow consomme l'immédiat stable ITERATOR_ELEMENT descripteur et écrit chacun match pièce sans construire de tampon contigu. next utilise à la place l'allocateur sélectionné et signale l'échec comme match; aucun des deux chemins ne nécessite la libc.
Les bibliothèques dynamiques déclarent les symboles d'exécution requis et les résolvent par rapport aux executable/runtime domaine. Les bibliothèques installées sont target/ABI qualifié; la liaison dynamique est par défaut et seed_runtime_format_write sélectionne statique seed archives. Les bibliothèques de processus utilisent le public format_args frontière. Primitives de vecteur d'entrée natives telles que {pointer, byte_length} restent cachés dans l'exécutable et ne sont accessibles que via les wrappers d'exécution exportés.
Niveaux cibles
La matrice cible déclarative sépare l'émission LLVM/object des niveaux de lien statique, de lien dynamique, d'exécutable et d'exécution.
- Linux x86-64: par défaut natif fermé, hébergé et sans libc.
- Linux AArch64: hébergé runtime/link avec la politique des coureurs.
- Linux RISC-V64: objet hébergé uniquement ; la botte autoportante est séparée.
- Windows x86-64: PE/DLL/runtime/tasks/networking, fichier open/read/write/seek, vidage, dissociation et remplacement en écriture, propriété d'octets partagés, FFI de paramètres d'agrégation Microsoft x64, renforcement du chargeur et packages de jeu SDL3 relocalisables avec sauvegardes atomiques persistantes, conformément à la politique Wine requise.
- macOS x86-64: SDK explicite executable/dylib/static/runtime/pthread la surface est prêt pour l'exécution Intel native requise.
- macOS arm64 : la surface équivalente est vérifiée par liaison croisée ; l'exécution n'est pas réclamé sans coureur.
- Android bras64 et x86-64: LLVM/object émission, bibliothèques statiques, partagées
bibliothèques et exécutables simples avec une racine système NDK explicite, plus
format_args.to_string()interfaces, sont disponibles en tant que tranche cible mobile initiale. L'adaptateur natif couvre allocation/regions, tâches, I/O/filesystem/socket emballages, Logcat, process/time/entropy, propriétés intégrées et annulation du cycle de vie ; le Android-seulementalloc_errorbibliothèque et--staticfournir un cadre délimité primitives/text, touch/key/IME entrée, safe-area/display métriques, signaux de concentration et de pression de mémoire, privés files/cache vues de répertoires et un magasin d'emplacements d'entiers privé atomique pour les petits progress/settings valeurs ; un Gradle/CMake/Kotlin/JNI modèle d'hôte, ABI-conscientseed_runtime_process_*mise en scène, package/run des commandes et des diagnostics médicaux sont disponibles. Emulator/device l'exécution et la signature de la production restent non vérifiées sans Android chaîne d'outils et coureur. - autonome x86-64/AArch64/RISC-V64: preuve de démarrage sans libc sur Gate 7 niveaux déclarés.
- RISC-V32 autonome : ELF32 object/link et Savana E6.0 QEMU
seed_process_argcXIP/16-KiB-SRAM preuves de démarrage ; aucune réclamation hébergée ou Cortex-M. - Wasm/WASI les services restent explicites au niveau de leur matrice déclarée.
Voir .sdi plutôt que de déduire des capacités de la présence d'un LLVM tripler.
Signification du démarrage
Pour Gate 7, « démarrage » signifie que le compilateur émet une image cible, que l'émulation du système QEMU la charge via le chemin firmware/machine déclaré, que le code d'entrée cible s'exécute, écrit la preuve de succès attendue via le mécanisme cible et quitte ou atteint l'état terminal attendu. Cela ne signifie pas qu'un système d'exploitation complet, une pile de pilotes, un espace utilisateur ou une libc sont présents.
Profils de version
mobile et SeedSurfaceView préserver la sécurité des contrôles. LLVM ne peut supprimer les chèques que s’ils s’avèrent redondants. ThinLTO, PGO, liaison statique, code/relocation Le modèle, la stratégie de zone rouge, l'entrée, le script de l'éditeur de liens, la cible, le profil d'exécution et la racine système sont des contrôles indépendants explicites.
<div hidden> jniLibs sifive_e seed/compiler/llvm/tests/GATE14_TARGET_MATRIX.tsv --release --release-small </div>
<div hidden>
Translated section
</div>
<div hidden> LLVM </div>