{"id":24757539,"url":"https://github.com/modula-dev/gyb","last_synced_at":"2025-03-23T08:46:21.860Z","repository":{"id":214483027,"uuid":"735228271","full_name":"Modula-dev/gyb","owner":"Modula-dev","description":"A bytecode-based cross platform linker","archived":false,"fork":false,"pushed_at":"2025-01-29T01:04:44.000Z","size":56,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-23T08:46:15.623Z","etag":null,"topics":["arm","bytecode-compiler","compiler-toolchain","elf-binaries","elf-format","garter","garter-language","linker","macho-format","object","pe-format","risc-v","riscv","x86-32","x86-64"],"latest_commit_sha":null,"homepage":"https://modula.dev/garter","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Modula-dev.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-12-24T06:08:31.000Z","updated_at":"2025-01-29T01:04:48.000Z","dependencies_parsed_at":null,"dependency_job_id":"ed4b9b94-890d-4788-9136-6ffc13d52913","html_url":"https://github.com/Modula-dev/gyb","commit_stats":null,"previous_names":["johnalexco/gyb","johnalexinl/gyb","modula-dev/gyb"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Modula-dev%2Fgyb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Modula-dev%2Fgyb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Modula-dev%2Fgyb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Modula-dev%2Fgyb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Modula-dev","download_url":"https://codeload.github.com/Modula-dev/gyb/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245078132,"owners_count":20557279,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arm","bytecode-compiler","compiler-toolchain","elf-binaries","elf-format","garter","garter-language","linker","macho-format","object","pe-format","risc-v","riscv","x86-32","x86-64"],"created_at":"2025-01-28T15:31:51.514Z","updated_at":"2025-03-23T08:46:21.840Z","avatar_url":"https://github.com/Modula-dev.png","language":"C","readme":"# GYB Linker\n\n`gyb` is the linker for the `m` compiler frontend\nand the `garter` compiler toolchain.\nIt implements a lightweight, custom object format designed to be super easy to re-implement while also trivial to translate into real object and executable formats.\n\n## Methodology\n\nTo make ELF `.o` or executables from a `.gyb` bytecode object,\nwe'll take template object and inject our code\ninto the appropriate sections of it,\ntranslate and inject our symbol table into it\n\n## Purpose\n\nThe `m` compiler toolchain seeks to separate out\nas many responsibilites from each process as possible.\n\nThe purpose for designing our own object format is simple;\nELF is complicated and difficult to work with. Documentation for the Executable and Linkable Format is extensive, but really unhelpful, and from the perspective of trying to actually work with it _sucks_.\n\nUsing a simplified object format means new backends are easy to write, and frontends are easy to plug in, and that's exactly what this toolchain is all about.\n\n## Linker i/o\n\nThis linker takes in\nGYB `*.gyo` and `*.gyb` Object files.\n\nIt can:\n- link multiple GYB objects together into one object\n- convert a static `*.gyb` object into an ELF object\n- convert a static `*.gyb` object into a static executable\n\nPlanned executable targets:\n- Windows Portable Executable `x86-64`\n- MacOS/RayvnOS MachO `x86-64`/`AArch64`\n- Linux/BSD ELF `x86-64`/`AArch64`/`RISC-V`\n\n# Implementation\n\n## How does Relocation Work?\n\n- Load and validate each object is relocatable\n- Load all of the symbol tables and update their offsets\n- Check to make sure there are no hanging `external` symbols;\n    - If we have `external` symbols which haven't been resolved,\n    we should give a linker warning to the console and\n    set a flag so that the output object is marked as being non-static (`GYO\\0`)\n- Squash the symbol table back down into a `char *`\n- Output a new bytecode file\n\n## How do the Bytecode Symbols Work?\n\nIn the executable sections of our `*.gyb` objects,\ninstructions will contain references to our symbols.\n`constant` symbols are just a numerical value\nthat is not updated by the linking stage,\nwhereas all the other types are modified during linkage.\n\nIf our symbol table has an entry like\n```\n@0xFF FOOBAR w 0x000C\n```\nand our executable section contains the instruction\n```\nstore ar @0xFF\n```\nthen the actual address for the `store` instruction\nwill be the address of our writable section offset by `0x000C`.\n\n## How do we convert a GYB object to an ELF object?\n\nWe're going to output an ELF object based on a prefab\nwhich has one executable section,\none read-writable section, one read-only section,\na `symtab` and a `strtab`.\n\nWe have to translate our symbol table\nfrom the `GYB` style `symbol_t` structs\ninto the `symtab` and `strtab` structures,\nwhich is fairly trivial;\n`strtab` will contain the names of each symbol\nwith a null-terminator, and\n`symtab` will contain the translated\nsection and offset data.\nWe can safely assume any symbols in our object files\nwere intended to be global.\n\nWhen building the ELF object, any symbols that were\nleft as unresolved external symbols are similarly\nmarked as such in the output ELF object.\n\n## How to we build binaries from a GYB object?\n\nThis depends on the type of executable we're building,\nbut for most types, such as Portable Executables or ELF binaries,\nit's pretty much the same.\n\nWe can output based on a prefab for that executable type.\nFor ELF, for example, we can check if we need to allocate\nroom for the `.rodata` (readonly), `.data` (writable),\nand `.text` (executable) sections and how much.\nFor the `.rodata` and `.data` sections, we just\nclone the data in as-is from our reference object,\nand for `.text` section, we need to iterate through it,\nresolving the instructions and symbols to\narchitecture-specific instructions and the correct\noffsets or literal values.\n\nGarter bytecode objects should always be, essentially,\nstatically compiled objects, so if we encounter any\n`external` symbols in the object, we should error out.\n\n# GYB Object Format\n\nThe header starts with one of two magic values:\n```c\nconst char *static_object =      \"GYB\\0\";\nconst char *relocatable_object = \"GYO\\0\";\n```\nThen we have the following data:\n```c\nuint32_t entry;\nuint32_t readonly_offset;\nuint32_t readonly_size;\nuint32_t writable_offset;\nuint32_t writable_size;\nuint32_t executable_offset;\nuint32_t executable_size;\nuint32_t symboltable_offset;\nuint32_t symboltable_size;\n```\nThese sizes are expressed in bytes,\nand the offsets are bytes from the end of this header.\n\nThe readable and writable sections are literal data\nand are unmodified by the linker during relocation.\nThe executable section contains platform-independent\nbytecode using symbols in the instructions\nwhich will be modified during relocation and linking.\n\nThe symbol table contains a block of the raw data\nof `symbol_t` entries, which look like\n```c\nchar name[symbol_namelen];\nuint32_t offset;\nunsigned char section;\nunsigned char defined;\n```\n\nIf `symboltable_size` is not\nan exact multiple of `sizeof(symbol_t)`,\nthen we know that the object is erroneous and can error out.\n\n## The Bytecode\n\nThe bytecode is influenced heavily by `x86`\nbut uses a small subset of registers and\nsymbol-references in place of addresses and literal values.\nGYB bytecode includes integer and floating arithmetic instructions,\ninstructions for casting and converting between the two types,\nvarious instructions for moving data around,\nand instructions for branching and interacting with the system,\nincluding both a platform-agnostic `syscall`,\nand a manual platform-dependent `interrupt`.\n\nFor more information on writing garter bytecode,\nsee the `garter` specification doc.","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmodula-dev%2Fgyb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmodula-dev%2Fgyb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmodula-dev%2Fgyb/lists"}