link_internal.h (28288B)
1 #ifndef KIT_LINK_INTERNAL_H 2 #define KIT_LINK_INTERNAL_H 3 4 /* Shared private definitions for the linker (link.c, link_layout.c, 5 * link_reloc.c, link_elf.c, link_jit.c). Not part of any public surface; 6 * not included by anything outside src/link/. */ 7 8 #include "core/core.h" 9 #include "core/hashmap.h" 10 #include "core/segvec.h" 11 #include "link/link.h" 12 #include "obj/obj.h" 13 #include "obj/symresolve.h" 14 15 /* Per-input mapping built during link_resolve. ObjSymId / ObjSecId are 16 * scoped to a single ObjBuilder, so the linker maintains an explicit 17 * lookup from each input's id space into the global LinkSymId / 18 * LinkSectionId space. Indices are dense (0..count-1 within the input); 19 * the array is sized to the input's nsymbols / nsections at allocation 20 * time. Index 0 of each id space is the "none" sentinel and maps to the 21 * matching LINK_*_NONE. */ 22 typedef struct InputMap { 23 LinkSymId* sym; /* size = ObjBuilder.nsymbols */ 24 u32 nsym; 25 LinkSectionId* section; /* size = ObjBuilder.nsections */ 26 u32 nsection; 27 LinkSectionId* atom; /* size = ObjBuilder.natoms */ 28 u32 natom; 29 ObjAtomId* sym_atom; /* size = nsym; ObjSymId -> ObjAtomId */ 30 ObjAtomId* reloc_atom; /* size = obj_reloc_total(input) */ 31 u32 nreloc; 32 u8* section_has_atoms; /* size = nsection */ 33 u32* section_atom_first; /* size = nsection; index into section_atom_ids */ 34 u32* section_atom_count; /* size = nsection */ 35 ObjAtomId* section_atom_ids; /* active atoms grouped by section */ 36 u32 nsection_atom_ids; 37 /* COMDAT discard mask, size = nsection. Set by link_resolve_symbols 38 * for COFF/PE SELECTANY: when an input's COMDAT section conflicts 39 * with an earlier definition, the duplicate section is marked here 40 * so link_gc_compute and link_layout_sections skip it. */ 41 u8* comdat_discarded; 42 } InputMap; 43 44 void link_input_map_alloc(LinkImage*, InputMap*, ObjBuilder*, u32 nsym_slots); 45 46 static inline ObjAtomId link_input_sym_atom(const InputMap* m, ObjSymId sym) { 47 return (m && m->sym_atom && sym < m->nsym) ? m->sym_atom[sym] : OBJ_ATOM_NONE; 48 } 49 50 static inline ObjAtomId link_input_reloc_atom(const InputMap* m, 51 u32 reloc_index) { 52 return (m && m->reloc_atom && reloc_index < m->nreloc) 53 ? m->reloc_atom[reloc_index] 54 : OBJ_ATOM_NONE; 55 } 56 57 static inline int link_input_section_has_atoms(const InputMap* m, 58 ObjSecId sid) { 59 return m && m->section_has_atoms && sid < m->nsection && 60 m->section_has_atoms[sid]; 61 } 62 63 static inline void link_input_section_atoms(const InputMap* m, ObjSecId sid, 64 u32* first, u32* count) { 65 if (m && sid < m->nsection && m->section_atom_first && 66 m->section_atom_count) { 67 *first = m->section_atom_first[sid]; 68 *count = m->section_atom_count[sid]; 69 } else { 70 *first = 0; 71 *count = 0; 72 } 73 } 74 75 static inline LinkSectionId link_input_reloc_section(const InputMap* m, 76 const Reloc* r, 77 u32 reloc_index) { 78 if (!m || !r || r->section_id == OBJ_SEC_NONE || r->section_id >= m->nsection) 79 return LINK_SEC_NONE; 80 if (link_input_section_has_atoms(m, r->section_id)) { 81 ObjAtomId aid = link_input_reloc_atom(m, reloc_index); 82 if (aid == OBJ_ATOM_NONE || aid >= m->natom) return LINK_SEC_NONE; 83 return m->atom[aid]; 84 } 85 return m->section[r->section_id]; 86 } 87 88 static inline LinkSectionId link_input_symbol_section(const InputMap* m, 89 const ObjSym* s, 90 ObjSymId sym) { 91 if (!m || !s || s->section_id == OBJ_SEC_NONE || s->section_id >= m->nsection) 92 return LINK_SEC_NONE; 93 if (link_input_section_has_atoms(m, s->section_id)) { 94 ObjAtomId aid = link_input_sym_atom(m, sym); 95 if (aid == OBJ_ATOM_NONE || aid >= m->natom) return LINK_SEC_NONE; 96 return m->atom[aid]; 97 } 98 return m->section[s->section_id]; 99 } 100 101 /* ---- ObjSym classification (single source of truth) --------------------- 102 * 103 * The linker's three lanes (AOT exe/shared in link_resolve.c, `-r` 104 * relocatable in link_relocatable.c, in-process JIT in link_jit.c) all 105 * classify input symbols the same way. These predicates are the one 106 * authority; every lane routes through them. */ 107 108 /* Resolution policy now lives in obj/symresolve.h so the LTO staging merge can 109 * reuse it. These keep the historical link_* spellings (every lane routes 110 * through them) as thin wrappers over the shared definitions. */ 111 static inline int link_bind_strength(u16 bind) { 112 return symresolve_bind_strength(bind); 113 } 114 static inline int link_sym_is_def(const ObjSym* s) { 115 return symresolve_sym_is_def(s); 116 } 117 static inline int link_sym_is_spurious_undef(const ObjSym* s) { 118 return symresolve_sym_is_spurious_undef(s); 119 } 120 121 /* In-section byte count for an input section: BSS/NOBITS report their 122 * zero-fill size, everything else its emitted byte total 123 * (link_layout.c / link_jit.c). */ 124 static inline u32 link_section_size_for_link(const Section* s) { 125 return (s->sem == SSEM_NOBITS || s->kind == SEC_BSS) ? s->bss_size 126 : s->bytes.total; 127 } 128 129 /* Open-addressed name -> LinkSymId hash for global / weak definitions 130 * and lookups (kit_jit_lookup, entry-symbol resolution). Locals never 131 * land in this table. Sym 0 is the empty-slot sentinel (it's also the 132 * "none" id per core.h:42 and never appears as a real name). */ 133 134 static inline u32 link_sym_hash_(Sym s) { return hash_u32((u32)s); } 135 HASHMAP_DEFINE(SymHash, Sym, LinkSymId, link_sym_hash_); 136 137 /* Convenience wrappers: the existing call sites pass LinkSymId by value 138 * (LINK_SYM_NONE on miss) and use insert-if-absent semantics. */ 139 static inline void symhash_init(SymHash* h, Heap* heap) { 140 SymHash_init(h, heap); 141 } 142 static inline void symhash_fini(SymHash* h) { SymHash_fini(h); } 143 static inline LinkSymId symhash_get(const SymHash* h, Sym name) { 144 LinkSymId* hit = SymHash_get(h, name); 145 return hit ? *hit : LINK_SYM_NONE; 146 } 147 static inline void symhash_set(SymHash* h, Sym name, LinkSymId id) { 148 (void)SymHash_set(h, name, id); 149 } 150 static inline int symhash_insert(SymHash* h, Sym name, LinkSymId id, 151 LinkSymId* existing_out) { 152 return SymHash_try_insert(h, name, id, existing_out); 153 } 154 155 struct KitJit; /* forward; see link_jit.c */ 156 157 /* Archive ingestion state. Members are eagerly parsed into ObjBuilders 158 * at link_add_archive_bytes time; the demand/whole-archive decision is 159 * deferred to link_resolve, where matching members are transferred into 160 * Linker.inputs. ObjBuilder ownership: while `included` is 0 the archive 161 * owns the builder (freed in linker_release); on inclusion the pointer 162 * moves into a LinkInput slot and `obj` is nulled to avoid double-free. */ 163 typedef struct LinkArchiveMember { 164 Sym name; /* interned member name; 0 if anonymous */ 165 ObjBuilder* obj; 166 u8 included; 167 u8 pad[7]; 168 } LinkArchiveMember; 169 170 typedef struct LinkArchive { 171 Sym name; 172 LinkArchiveMember* members; 173 u32 nmembers; 174 u32 order; 175 u8 whole_archive; 176 u8 link_mode; 177 u8 group_id; 178 u8 pad; 179 } LinkArchive; 180 181 SEGVEC_DEFINE(LinkInputs, LinkInput, 4); /* 16 entries per segment */ 182 SEGVEC_DEFINE(LinkArchives, LinkArchive, 4); 183 184 struct Linker { 185 Compiler* c; 186 Heap* heap; 187 LinkInputs inputs; /* LinkInputId = slot index + 1 */ 188 LinkArchives archives; 189 u32 next_input_order; 190 Sym entry_name; 191 /* Set by link_set_script. NULL: layout takes the existing default 192 * bucket-based path. Non-NULL: layout_sections_scripted walks the 193 * script's output sections in declaration order. Borrowed; the 194 * script and every sub-object must outlive link_resolve. */ 195 const KitLinkScript* script; 196 /* -Ttext override of the static ET_EXEC image base. text_base_set==0 leaves 197 * the default IMAGE_BASE_STATIC; ignored on PIE/shared/scripted layouts. */ 198 int text_base_set; 199 u64 text_base; 200 int gc_sections; 201 int strip_debug; 202 /* Set by kit_link_exe before link_resolve. When 1, layout_iplt 203 * synthesizes a .init_array entry pointing at __kit_ifunc_init so 204 * the emitted ET_EXEC binary fills its IFUNC slots at startup. The 205 * JIT path leaves this 0 — slots are pre-resolved in-process by 206 * link_jit.c, no ctor needed. */ 207 int emit_static_exe; 208 /* In-process JIT lane (set by kit_link_jit). Currently used to 209 * tolerate undef `__tlv_bootstrap` on Mach-O inputs — the JIT image 210 * has no dyld, descriptor[+0] is rewritten to kit's thunk during 211 * kit_jit_from_image, so the symbol's resolved value doesn't 212 * matter. Without this, clang-produced .o files (which emit 213 * `__tlv_bootstrap` as a plain non-weak undef) would panic at 214 * link_resolve_undefs. */ 215 int jit_mode; 216 /* PIE / ET_DYN output. Set by kit_link_exe when opts->pie or any 217 * DSO input is present. Triggers layout_dyn (Phase 4) and the 218 * dynamic ELF emit path (Phase 6). */ 219 int emit_pie; 220 u16 pe_subsystem; 221 /* Caller-supplied PT_INTERP. layout_dyn falls back to a target- 222 * derived default when this is 0. */ 223 Sym interp_path; 224 LinkExternResolver resolver; 225 void* resolver_user; 226 /* Borrowed JIT host. Set by kit_link_jit before link_resolve so the 227 * layout/reloc passes can read execmem->page_size and the JIT mapper 228 * can reach the host's reserve/protect/tls hooks without rummaging 229 * through Compiler.ctx (which no longer carries those). NULL on the 230 * AOT exe/shared lanes. */ 231 const KitJitHost* jit_host; 232 CompilerCleanup* deferred; /* registered by link_new */ 233 }; 234 235 /* ---- GC liveness (link_resolve.c) ---------------------------------------- */ 236 237 typedef struct GcLive { 238 u8** 239 marks; /* marks[input_idx][obj_sec_id] for implicit whole-section units */ 240 u8** atom_marks; /* atom_marks[input_idx][obj_atom_id] for explicit atoms */ 241 u32* nsec; /* obj_section_count per input */ 242 u32* natom; /* obj_atom_count per input */ 243 u32 ninputs; 244 } GcLive; 245 246 typedef struct GcQueue { 247 u64* items; /* hi32=input_idx, low31=id, bit31=set for atom */ 248 u32 n; 249 u32 cap; 250 } GcQueue; 251 252 /* ---- Cross-file helpers (link_layout.c → link_reloc_layout.c) ------------ */ 253 254 /* Four-bucket segment partitioning by permission (defined in link_layout.c). */ 255 typedef enum SegBucket { 256 SEG_RX = 0, /* SF_ALLOC | SF_EXEC */ 257 SEG_R = 1, /* SF_ALLOC, no EXEC, no WRITE */ 258 SEG_RW = 2, /* SF_ALLOC | SF_WRITE (incl. BSS) */ 259 SEG_TLS = 3, /* SF_ALLOC | SF_TLS (.tdata + .tbss) */ 260 SEG_NBUCKETS = 4, 261 } SegBucket; 262 263 /* section_kept: 1 for allocatable progbits/nobits sections (link_layout.c). */ 264 int link_section_kept(const Section* s); 265 /* section_kept_fileonly: 1 for non-allocatable .debug_* sections that the 266 * AOT ELF path carries through as file-only sections (link_layout.c). */ 267 int link_section_kept_fileonly(const Section* s); 268 /* bucket_for: map section flags to SegBucket (link_layout.c). */ 269 SegBucket link_bucket_for(u16 flags); 270 /* layout_page_size: page size for segment alignment (link_layout.c). */ 271 u64 link_layout_page_size(Linker* l); 272 273 /* Append a fresh symbol slot and return its id (link_layout.c). */ 274 LinkSymId link_append_symbol(LinkImage* img, const LinkSymbol* tmpl); 275 /* Append a fresh reloc slot and return it (link_layout.c). */ 276 LinkRelocApply* link_append_reloc_slot(LinkImage* img); 277 278 /* Emit or upsert a synthetic global boundary symbol (link_layout.c). */ 279 void link_emit_boundary_sym(Linker* l, LinkImage* img, const char* name, 280 u64 vaddr); 281 void link_emit_section_boundary_sym(Linker* l, LinkImage* img, 282 const char* name, LinkSectionId section_id, 283 u64 value); 284 285 /* Detect __start_<X> / __stop_<X> with <X> a valid C identifier. 286 * Defined in link_resolve.c; used by link_reloc_layout.c. */ 287 int link_gc_split_start_stop(const char* s, size_t n, size_t* out_off, 288 size_t* out_len, int* out_is_start); 289 290 /* GC liveness helpers (link_resolve.c). */ 291 int link_gc_live_get(const GcLive* g, u32 ii, ObjSecId j); 292 int link_gc_atom_live_get(const GcLive* g, u32 ii, ObjAtomId j); 293 294 /* Segment/section growth helpers for iplt (link_reloc_layout.c). */ 295 u32 link_iplt_alloc_segments(LinkImage* img, u32 nseg); 296 u32 link_iplt_alloc_sections(LinkImage* img, u32 nsec); 297 298 /* Append one fixed-size synthetic region to the image: a fresh 299 * page-aligned PT_LOAD segment plus its single covering section, sized 300 * `size` with permissions `perms` (SF_* flags) and section semantics 301 * `sem`. The region is placed at page-align(max segment end) so it never 302 * overlaps existing content. A zero-filled byte buffer of `size` bytes is 303 * allocated for the segment; *out_vaddr receives the image-relative base 304 * and *out_bytes the buffer. `sec_align` sets the section's alignment 305 * (the segment always aligns to the page). Returns the new section's id. 306 * Backs the GOT / JIT-call-stub / IPLT layout passes 307 * (link_reloc_layout.c). */ 308 LinkSectionId link_synth_region(LinkImage* img, Linker* l, Sym name, u16 perms, 309 u16 sem, u64 size, u32 sec_align, u64* out_vaddr, 310 u8** out_bytes); 311 312 /* Append one fixed 8-byte ABS64 reloc-apply record targeting `target` at 313 * `offset` within synthetic section `lsid` (write_vaddr == its file 314 * offset, as every synthetic region is identity-mapped at layout time). 315 * Backs the GOT / IPLT / JIT-slot fills (link_reloc_layout.c). */ 316 void link_emit_internal_abs64(LinkImage* img, LinkSectionId lsid, u32 offset, 317 u64 write_vaddr, LinkSymId target); 318 319 /* ---- Public entries (link_resolve.c) -------------------------------------- 320 */ 321 void link_ingest_archives(struct Linker*); 322 /* PE/COFF only: synthesize a tiny ObjBuilder providing the mingw CRT 323 * `__CTOR_LIST__` / `__CTOR_END__` / `__DTOR_LIST__` / `__DTOR_END__` 324 * boundary symbols. See link_resolve.c for the contract. */ 325 void link_synth_coff_ctor_dtor_list(struct Linker*); 326 void link_resolve_symbols(struct Linker*, LinkImage*); 327 void link_resolve_undefs(struct Linker*, LinkImage*); 328 void link_gc_compute(struct Linker*, LinkImage*, GcLive*); 329 void link_gc_live_alloc(GcLive* g, struct Linker* l, Heap* h); 330 void link_gc_live_free(GcLive* g, Heap* h); 331 void link_gc_drop_dead_globals(struct Linker*, LinkImage*, const GcLive*); 332 333 /* ---- Public entries (link_layout.c) --------------------------------------- 334 */ 335 void link_layout_sections(struct Linker*, LinkImage*, const GcLive*); 336 void link_layout_commons(struct Linker*, LinkImage*); 337 void link_emit_segment_bytes(struct Linker*, LinkImage*); 338 /* Carry .debug_* sections through as file-only sections + populate the 339 * debug registry (link_layout.c). AOT ELF path only; gated by the 340 * caller on !strip_debug / !jit_mode / ELF target. */ 341 void link_layout_debug(struct Linker*, LinkImage*); 342 /* Byte buffer for a file-only debug LinkSection, or NULL if `id` is not 343 * a registered file-only section (link_layout.c). */ 344 u8* link_fileonly_bytes(LinkImage*, LinkSectionId); 345 346 /* ---- Public entries (link_reloc_layout.c) --------------------------------- 347 */ 348 void link_assign_symbol_vaddrs(struct Linker*, LinkImage*); 349 void link_emit_array_boundaries(struct Linker*, LinkImage*); 350 void link_emit_tls_boundaries(struct Linker*, LinkImage*); 351 void link_emit_encoding_section_boundaries(struct Linker*, LinkImage*); 352 void link_layout_jit_stubs(struct Linker*, LinkImage*, u32 map_size, 353 LinkSymId** stub_map_out); 354 void link_layout_got(struct Linker*, LinkImage*, u32 map_size, 355 LinkSymId** got_map_out); 356 void link_layout_iplt(struct Linker*, LinkImage*); 357 void link_emit_relocations(struct Linker*, LinkImage*, const LinkSymId* got_map, 358 const LinkSymId* stub_map); 359 void link_resolve_entry(struct Linker*, LinkImage*); 360 361 /* Defined in link.c. Walks the Linker's inputs and records each input's 362 * ObjBuilder on the LinkImage so the JIT debug view can reach its 363 * .debug_* sections after link_free runs. LINK_INPUT_OBJ_BYTES 364 * builders are moved (the LinkInput's obj pointer is nulled so 365 * linker_release skips them); LINK_INPUT_OBJ builders are borrowed 366 * (the caller still owns). DSO / TBD inputs are skipped. */ 367 void link_capture_debug_inputs(struct Linker*, LinkImage*); 368 369 /* Default PE/COFF ImageBase for executables. Mirrored in link_coff.c 370 * (the emitter writes this into the optional header). Exposed here so 371 * link_layout can synthesize the `__ImageBase` symbol at the same 372 * vaddr, before resolve_undefs runs. */ 373 #define LINK_PE_IMAGE_BASE 0x140000000ULL 374 375 /* Define / upsert a synthetic global symbol resolved to `vaddr`. 376 * Satisfies any prior undef ref (e.g. _DYNAMIC from Scrt1.o, 377 * __dso_handle from libc_nonshared.a) and fans out across per-input 378 * duplicate name slots so emit_reloc_records sees the resolved 379 * vaddr. Implemented in link_layout.c. */ 380 void link_define_boundary(struct Linker*, LinkImage*, const char* name, 381 u64 vaddr); 382 383 /* SegVec instances for image-owned tables. Pointers returned by *_at / 384 * *_push remain valid for the LinkImage's lifetime. */ 385 SEGVEC_DEFINE(LinkSyms, LinkSymbol, 6); /* 64 entries per segment */ 386 SEGVEC_DEFINE(LinkRelocs, LinkRelocApply, 7); /* 128 entries per segment */ 387 388 /* ---- Dynamic-link synthesis state (Phase 4) ---- 389 * 390 * Owned by LinkImage when emit_pie is set. Holds the synthesized 391 * .interp / .dynsym / .dynstr / .gnu.hash / .rela.dyn / .rela.plt / 392 * .plt / .got.plt / .dynamic content plus the section ids the emit 393 * pass needs to fill PT_DYNAMIC and the .dynamic body. 394 * 395 * Phase 4 builds the dynsym/dynstr/gnu.hash content and the JUMP_SLOT 396 * .rela.plt records (one per imported function, against its synthetic 397 * .got.plt slot). The .plt body is allocated but not emitted (Phase 5). 398 * Phase 6 populates .rela.dyn with R_AARCH64_RELATIVE records for any 399 * internal absolute reloc seen during reloc-apply. 400 * 401 * Layout invariants this struct enforces: 402 * - dynsym entry 0 is the reserved STN_UNDEF slot (zero-filled). 403 * - dynsym entries 1..nimport_func+nimport_data are imports, in the 404 * order PLT-functions first, then GOT-data. 405 * - PLT slots and JUMP_SLOT entries match the import_func order 1:1. 406 * - .got.plt has 3 reserved leading u64 slots (per AArch64 psABI: 407 * slot 0 = &.dynamic, slot 1 = link_map cookie, slot 2 = 408 * _dl_runtime_resolve), then one slot per imported function. 409 */ 410 411 typedef struct DynSymRec { 412 u32 st_name; /* offset into .dynstr */ 413 u8 st_info; 414 u8 st_other; 415 u16 st_shndx; 416 u64 st_value; 417 u64 st_size; 418 } DynSymRec; 419 420 typedef struct DynRela { 421 u64 r_offset; /* image-relative vaddr of the patch site */ 422 u64 r_info; /* ELF64_R_INFO(dynsym_index, elf_reloc_type) */ 423 i64 r_addend; 424 } DynRela; 425 426 typedef struct LinkDynState { 427 /* PT_INTERP / .interp. interp_path is interned in compiler->global. */ 428 Sym interp_path; 429 LinkSectionId sec_interp; 430 431 /* .dynsym */ 432 LinkSectionId sec_dynsym; 433 DynSymRec* dynsym; 434 u32 ndynsym; /* incl. slot-0 STN_UNDEF */ 435 u32 first_global; /* sh_info value: index of first non-local entry */ 436 437 /* .dynstr */ 438 LinkSectionId sec_dynstr; 439 u8* dynstr; 440 u32 dynstr_len; 441 442 /* .gnu.hash */ 443 LinkSectionId sec_gnu_hash; 444 u8* gnu_hash; 445 u32 gnu_hash_len; 446 447 /* GNU symbol versioning. Emitted only when at least one imported symbol 448 * binds to a versioned DSO export (nverneed > 0); otherwise all three are 449 * zero and no version sections / DT_VER* entries are produced (musl/static 450 * links are unchanged). .gnu.version is one u16 per .dynsym entry; 451 * .gnu.version_r holds Verneed/Vernaux requirements keyed by DT_NEEDED 452 * soname. Both carry only .dynstr offsets + version indices (no vaddrs), so 453 * the bytes are final at layout time and copied verbatim during emit. */ 454 LinkSectionId sec_gnu_version; 455 u8* versym; /* ndynsym * 2 bytes */ 456 u32 versym_len; 457 LinkSectionId sec_gnu_version_r; 458 u8* verneed; /* nverneed Verneed records + their Vernaux */ 459 u32 verneed_len; 460 u32 nverneed; /* DT_VERNEEDNUM */ 461 462 /* .rela.dyn — R_AARCH64_GLOB_DAT (imports against .got slots) and 463 * R_AARCH64_RELATIVE (PIE internal abs64 fixups, populated during 464 * Phase 6 emit). Pre-sized at layout time; the RELATIVE tail is 465 * filled in during emit. */ 466 LinkSectionId sec_rela_dyn; 467 DynRela* rela_dyn; 468 u32 nrela_dyn; /* number of records currently populated */ 469 u32 cap_rela_dyn; /* allocation capacity (records, not bytes) */ 470 471 /* .rela.plt — R_AARCH64_JUMP_SLOT, one per imported function. */ 472 LinkSectionId sec_rela_plt; 473 DynRela* rela_plt; 474 u32 nrela_plt; 475 476 /* .plt — 32-byte PLT0 stub + 16 bytes per imported function. Body 477 * is allocated (zero-initialized) but not emitted in Phase 4. */ 478 LinkSectionId sec_plt; 479 u32 nplt; /* number of imported functions */ 480 u64 plt_vaddr; /* image-relative .plt base */ 481 u64 plt_size; 482 483 /* .got.plt — 24 reserved bytes + 8 per PLT slot. */ 484 LinkSectionId sec_got_plt; 485 u64 got_plt_vaddr; 486 u64 got_plt_size; 487 488 /* .dynamic — PT_DYNAMIC body. Built at layout time; its size is 489 * fixed once we know the DT_NEEDED count. */ 490 LinkSectionId sec_dynamic; 491 u64 dynamic_vaddr; 492 u64 dynamic_size; 493 u32 ndyn_entries; 494 495 /* DT_NEEDED list (interned soname Syms, in input order). */ 496 Sym* needed; 497 u32 nneeded; 498 499 /* Per-import dynsym index, indexed by LinkSymId. 0 means "not 500 * imported / not in dynsym". Used by GLOB_DAT / JUMP_SLOT emit. */ 501 u32* sym_dynidx; /* size = sym_dynidx_size */ 502 u32 sym_dynidx_size; 503 504 /* Per-import PLT entry vaddr, indexed by LinkSymId (Phase 5). Set 505 * for every imported function: vaddr of its 16-byte PLT stub inside 506 * `.plt`. 0 means "no PLT stub" (symbol is data-only or not 507 * imported). apply_all_relocs reads this when redirecting a 508 * CALL26/JUMP26 against an imported function — S becomes the PLT 509 * entry vaddr instead of the symbol's (zero) vaddr. The vaddrs 510 * stored here track the post-shift values (shift_image_addresses 511 * bumps them along with .plt's segment vaddr). */ 512 u64* sym_plt_vaddr; /* size = sym_dynidx_size */ 513 } LinkDynState; 514 515 struct LinkImage { 516 Compiler* c; 517 Heap* heap; 518 CompilerCleanup* deferred; /* registered by link_resolve */ 519 /* Borrowed back-pointer set by link_resolve. The Linker is not 520 * mutated through this handle; it's used by the format-specific emit 521 * passes that need to walk LinkInputs (e.g. resolving an imported 522 * symbol's dso_input_id back to the providing dylib's install-name). */ 523 struct Linker* linker; 524 525 LinkSyms syms; /* LinkSymId = slot index + 1 */ 526 SymHash globals; /* name -> LinkSymId for global/weak */ 527 528 LinkSection* sections; /* id = index + 1 */ 529 u32 nsections; 530 531 LinkSegment* segments; /* id = index + 1 */ 532 u32 nsegments; 533 u8** segment_bytes; /* one per segment; size = file_size */ 534 size_t* segment_bytes_cap; /* allocation size for free */ 535 536 LinkRelocs relocs; 537 538 /* IFUNC trampoline table (image-relative vaddrs). One entry per 539 * defined STT_GNU_IFUNC symbol: (resolver_vaddr, slot_vaddr). The 540 * JIT path walks this after applying relocations, calls each 541 * resolver in-process, and stores the result into the slot's write 542 * alias. The ELF emit path uses it to seed a startup init routine 543 * (or panics when the routine is not yet wired in). */ 544 u64* iplt_pairs; /* 2 * niplt entries */ 545 u32 niplt; 546 547 LinkSymId entry_sym; 548 549 /* TLS image span (image-relative). Set when any input contributes 550 * an SF_TLS section. filesz covers the .tdata bytes that initialize 551 * the per-thread block; memsz adds .tbss zero-fill. tls_align is 552 * the natural alignment of the TLS image (max of contributing 553 * sections), distinct from the containing PT_LOAD's page align. 554 * AArch64 ELF ABI: TP-relative offset of a TLS symbol with image 555 * offset `o` is `o + 16` (16-byte TCB ahead of the TLS data). */ 556 u64 tls_vaddr; 557 u64 tls_filesz; 558 u64 tls_memsz; 559 u32 tls_align; 560 561 InputMap* input_maps; /* one per input; indexed by input_id-1 */ 562 u32 ninput_maps; 563 564 /* Debug-capture state for the JIT path. Populated by 565 * link_capture_debug_inputs at the tail of link_resolve so the input 566 * ObjBuilders (which carry .debug_* sections + their per-section 567 * relocations — neither consumed nor mutated by layout) survive the 568 * Linker's teardown and become reachable from kit_jit_view. 569 * 570 * Parallel to input_maps: dbg_objs[i] is the ObjBuilder for input 571 * (i+1), or NULL when no debug info is present / the input kind isn't 572 * relevant (DSO/TBD). dbg_objs_owned[i] is 1 when the image must 573 * obj_free the builder at link_image_free (transferred from 574 * LINK_INPUT_OBJ_BYTES), 0 when borrowed (LINK_INPUT_OBJ — caller 575 * still owns). */ 576 ObjBuilder** dbg_objs; 577 u8* dbg_objs_owned; 578 u32 dbg_objs_n; 579 580 /* File-only debug-section registry (AOT ELF path). link_layout_debug 581 * appends one file-only LinkSection per surviving .debug_* contribution 582 * as a contiguous id range [dbg_first_lsid, dbg_first_lsid+dbg_count). 583 * dbg_bytes[i] / dbg_size[i] hold that contribution's own byte buffer 584 * (relocs applied in place at reloc-offset), indexed by lsid - 585 * dbg_first_lsid. Empty on the JIT / Mach-O / COFF lanes. */ 586 LinkSectionId dbg_first_lsid; 587 u32 dbg_count; 588 u8** dbg_bytes; 589 u64* dbg_size; 590 591 /* Dynamic-link state (Phase 4). NULL when emit_pie was not set on 592 * the Linker — i.e., the static-exe / JIT path. Owned by the image. */ 593 LinkDynState* dyn; 594 /* Mirror of Linker.emit_pie at link_resolve time; consulted by emit. */ 595 int pie; 596 /* Set when layout was driven by Linker.script. The emitter then keeps 597 * segment vaddrs at their script-assigned absolute values, drops the 598 * self-describing headers PT_LOAD / build-id PT_NOTE, and only shifts 599 * file offsets to make room for ehdr+phdrs. */ 600 u8 scripted; 601 /* -Ttext: when text_base_set, the static-exe image base override, mirrored 602 * from Linker at link_resolve time. Ignored if pie/scripted. */ 603 int text_base_set; 604 u64 text_base; 605 }; 606 607 /* Page granularity used for ELF segment alignment and the file-offset / 608 * vaddr congruence the runtime loader requires. 16 KiB matches AArch64 609 * Apple Silicon and the common Linux/AArch64 kernel config; 4 KiB pages 610 * are also valid at runtime since 16K is a multiple. */ 611 #define PAGE_SIZE 0x4000u 612 613 /* Apply one relocation in place. P_bytes points at the first byte of the 614 * relocation site within the final memory; S is the resolved final 615 * address of the target symbol; A the addend; P the final address of 616 * the relocation site. Panics on unsupported kinds. */ 617 void link_reloc_apply(Compiler*, RelocKind, u8* P_bytes, u64 S, i64 A, u64 P); 618 619 /* kit emits local-exec TLS only: a thread-local's offset within THIS image's 620 * TLS block is fixed at link time, so a local-exec access (or the TP-relative 621 * fill of a TLS initial-exec GOT slot) is valid only against a thread-local 622 * *defined in the image being linked*. Panic with a clear diagnostic if `tgt` 623 * is imported from a shared object (its TLS block belongs to another module, 624 * sized and placed by the dynamic loader) or resolved to a non-thread-local 625 * definition. There is no initial-exec/global-dynamic fallback to relax to, 626 * so the only alternative is a silently bogus tp-relative offset -- hence the 627 * hard error. A no-op when `tgt` is a thread-local defined here. */ 628 void link_require_local_tls(Compiler*, const LinkSymbol* tgt); 629 630 /* Public link_emit_image_writer dispatches by Compiler.target.obj. The 631 * ELF and Mach-O writers get architecture identity from LinkArchDesc; 632 * reloc application remains keyed by RelocKind. COFF arrives later. */ 633 void link_emit_elf(LinkImage*, Writer*); 634 void link_emit_macho(LinkImage*, Writer*); 635 void link_emit_coff(LinkImage*, Writer*); 636 637 /* Format-agnostic 16-byte image identity, derived from per-segment 638 * post-shift bytes + vaddrs/sizes. ELF wraps it in a 639 * .note.gnu.build-id; Mach-O will wrap it in LC_UUID; COFF/PE in a 640 * debug directory entry. One source of truth so the bytes match 641 * across formats. */ 642 #define LINK_IMAGE_ID_BYTES 16u 643 void link_image_id_compute(const LinkImage*, u8 out[LINK_IMAGE_ID_BYTES]); 644 645 #endif