link_internal.h (27580B)
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_reserve(SymHash* h, u32 n) { SymHash_reserve(h, n); } 143 static inline void symhash_fini(SymHash* h) { SymHash_fini(h); } 144 static inline LinkSymId symhash_get(const SymHash* h, Sym name) { 145 LinkSymId* hit = SymHash_get(h, name); 146 return hit ? *hit : LINK_SYM_NONE; 147 } 148 static inline void symhash_set(SymHash* h, Sym name, LinkSymId id) { 149 (void)SymHash_set(h, name, id); 150 } 151 static inline int symhash_insert(SymHash* h, Sym name, LinkSymId id, 152 LinkSymId* existing_out) { 153 return SymHash_try_insert(h, name, id, existing_out); 154 } 155 156 struct KitJit; /* forward; see link_jit.c */ 157 158 /* Archive ingestion state. Members are eagerly parsed into ObjBuilders 159 * at link_add_archive_bytes time; the demand/whole-archive decision is 160 * deferred to link_resolve, where matching members are transferred into 161 * Linker.inputs. ObjBuilder ownership: while `included` is 0 the archive 162 * owns the builder (freed in linker_release); on inclusion the pointer 163 * moves into a LinkInput slot and `obj` is nulled to avoid double-free. */ 164 typedef struct LinkArchiveMember { 165 Sym name; /* interned member name; 0 if anonymous */ 166 ObjBuilder* obj; 167 u8 included; 168 u8 pad[7]; 169 } LinkArchiveMember; 170 171 typedef struct LinkArchive { 172 Sym name; 173 LinkArchiveMember* members; 174 u32 nmembers; 175 u32 order; 176 u8 whole_archive; 177 u8 link_mode; 178 u8 group_id; 179 u8 pad; 180 } LinkArchive; 181 182 SEGVEC_DEFINE(LinkInputs, LinkInput, 4); /* 16 entries per segment */ 183 SEGVEC_DEFINE(LinkArchives, LinkArchive, 4); 184 185 struct Linker { 186 Compiler* c; 187 Heap* heap; 188 LinkInputs inputs; /* LinkInputId = slot index + 1 */ 189 LinkArchives archives; 190 u32 next_input_order; 191 Sym entry_name; 192 /* Set by link_set_script. NULL: layout takes the existing default 193 * bucket-based path. Non-NULL: layout_sections_scripted walks the 194 * script's output sections in declaration order. Borrowed; the 195 * script and every sub-object must outlive link_resolve. */ 196 const KitLinkScript* script; 197 /* -Ttext override of the static ET_EXEC image base. text_base_set==0 leaves 198 * the default IMAGE_BASE_STATIC; ignored on PIE/shared/scripted layouts. */ 199 int text_base_set; 200 u64 text_base; 201 int gc_sections; 202 int strip_debug; 203 int allow_undefined; 204 /* Set by kit_link_exe before link_resolve. When 1, layout_iplt 205 * synthesizes a .init_array entry pointing at __kit_ifunc_init so 206 * the emitted ET_EXEC binary fills its IFUNC slots at startup. The 207 * JIT path leaves this 0 — slots are pre-resolved in-process by 208 * link_jit.c, no ctor needed. */ 209 int emit_static_exe; 210 /* In-process JIT lane (set by kit_link_jit). Currently used to 211 * tolerate undef `__tlv_bootstrap` on Mach-O inputs — the JIT image 212 * has no dyld, descriptor[+0] is rewritten to kit's thunk during 213 * kit_jit_from_image, so the symbol's resolved value doesn't 214 * matter. Without this, clang-produced .o files (which emit 215 * `__tlv_bootstrap` as a plain non-weak undef) would panic at 216 * link_resolve_undefs. */ 217 int jit_mode; 218 /* Shared-library / DSO output. Shares dynamic ELF layout with PIE 219 * executables, but has no required entry point and no PT_INTERP. */ 220 int emit_shared; 221 /* PIE / ET_DYN output. Set by kit_link_exe when opts->pie or any 222 * DSO input is present. Triggers layout_dyn (Phase 4) and the 223 * dynamic ELF emit path (Phase 6). */ 224 int emit_pie; 225 u16 pe_subsystem; 226 /* RISC-V psABI e_flags accumulated from object inputs selected for this 227 * link. Float-ABI/RVE conflicts are rejected while registering inputs; 228 * RVC/TSO feature-presence bits are OR-merged. */ 229 u32 elf_e_flags; 230 Sym elf_e_flags_source; 231 u8 have_elf_e_flags; 232 /* Caller-supplied PT_INTERP. layout_dyn falls back to a target- 233 * derived default when this is 0. */ 234 Sym interp_path; 235 /* ---- Flags/policy plumbed from KitLinkSessionOptions by src/api/link.c 236 * (the kernel-C "linker flags and policy" + strict-validation work). The 237 * arrays are borrowed; they must outlive link_resolve. ---- */ 238 const KitLinkDefsym* defsyms; /* --defsym NAME=EXPR */ 239 u32 ndefsyms; 240 const KitLinkSectionStart* section_starts; /* --section-start / -Tdata/-Tbss */ 241 u32 nsection_starts; 242 KitSlice soname; 243 const KitSlice* rpaths; 244 u32 nrpaths; 245 const KitSlice* runpaths; 246 u32 nrunpaths; 247 u8 orphan_handling; /* KitLinkOrphanHandling */ 248 int fatal_warnings; /* --fatal-warnings */ 249 int freestanding_strict; /* strict freestanding link validation */ 250 LinkExternResolver resolver; 251 void* resolver_user; 252 /* Borrowed JIT host. Set by kit_link_jit before link_resolve so the 253 * layout/reloc passes can read execmem->page_size and the JIT mapper 254 * can reach the host's reserve/protect/tls hooks without rummaging 255 * through Compiler.ctx (which no longer carries those). NULL on the 256 * AOT exe/shared lanes. */ 257 const KitJitHost* jit_host; 258 CompilerCleanup* deferred; /* registered by link_new */ 259 }; 260 261 /* ---- GC liveness (link_resolve.c) ---------------------------------------- */ 262 263 typedef struct GcLive { 264 u8** 265 marks; /* marks[input_idx][obj_sec_id] for implicit whole-section units */ 266 u8** atom_marks; /* atom_marks[input_idx][obj_atom_id] for explicit atoms */ 267 u32* nsec; /* obj_section_count per input */ 268 u32* natom; /* obj_atom_count per input */ 269 u32 ninputs; 270 } GcLive; 271 272 typedef struct GcQueue { 273 u64* items; /* hi32=input_idx, low31=id, bit31=set for atom */ 274 u32 n; 275 u32 cap; 276 } GcQueue; 277 278 /* ---- Cross-file helpers (link_layout.c → link_reloc_layout.c) ------------ */ 279 280 /* Four-bucket segment partitioning by permission (defined in link_layout.c). */ 281 typedef enum SegBucket { 282 SEG_RX = 0, /* SF_ALLOC | SF_EXEC */ 283 SEG_R = 1, /* SF_ALLOC, no EXEC, no WRITE */ 284 SEG_RW = 2, /* SF_ALLOC | SF_WRITE (incl. BSS) */ 285 SEG_TLS = 3, /* SF_ALLOC | SF_TLS (.tdata + .tbss) */ 286 SEG_NBUCKETS = 4, 287 } SegBucket; 288 289 /* section_kept: 1 for allocatable progbits/nobits sections (link_layout.c). */ 290 int link_section_kept(const Section* s); 291 /* section_kept_fileonly: 1 for non-allocatable .debug_* sections that the 292 * AOT ELF path carries through as file-only sections (link_layout.c). */ 293 int link_section_kept_fileonly(const Section* s); 294 /* bucket_for: map section flags to SegBucket (link_layout.c). */ 295 SegBucket link_bucket_for(u16 flags); 296 /* layout_page_size: page size for segment alignment (link_layout.c). */ 297 u64 link_layout_page_size(Linker* l); 298 299 /* Append a fresh symbol slot and return its id (link_layout.c). */ 300 LinkSymId link_append_symbol(LinkImage* img, const LinkSymbol* tmpl); 301 /* Append a fresh reloc slot and return it (link_layout.c). */ 302 LinkRelocApply* link_append_reloc_slot(LinkImage* img); 303 304 /* Emit or upsert a synthetic global boundary symbol (link_layout.c). */ 305 void link_emit_boundary_sym(Linker* l, LinkImage* img, const char* name, 306 u64 vaddr); 307 void link_emit_section_boundary_sym(Linker* l, LinkImage* img, const char* name, 308 LinkSectionId section_id, u64 value); 309 310 /* Detect __start_<X> / __stop_<X> with <X> a valid C identifier. 311 * Defined in link_resolve.c; used by link_reloc_layout.c. */ 312 int link_gc_split_start_stop(const char* s, size_t n, size_t* out_off, 313 size_t* out_len, int* out_is_start); 314 315 /* GC liveness helpers (link_resolve.c). */ 316 int link_gc_live_get(const GcLive* g, u32 ii, ObjSecId j); 317 int link_gc_atom_live_get(const GcLive* g, u32 ii, ObjAtomId j); 318 319 /* Segment/section growth helpers for iplt (link_reloc_layout.c). */ 320 u32 link_iplt_alloc_segments(LinkImage* img, u32 nseg); 321 u32 link_iplt_alloc_sections(LinkImage* img, u32 nsec); 322 323 /* Append one fixed-size synthetic region to the image: a fresh 324 * page-aligned PT_LOAD segment plus its single covering section, sized 325 * `size` with permissions `perms` (SF_* flags) and section semantics 326 * `sem`. The region is placed at page-align(max segment end) so it never 327 * overlaps existing content. A zero-filled byte buffer of `size` bytes is 328 * allocated for the segment; *out_vaddr receives the image-relative base 329 * and *out_bytes the buffer. `sec_align` sets the section's alignment 330 * (the segment always aligns to the page). Returns the new section's id. 331 * Backs the GOT / JIT-call-stub / IPLT layout passes 332 * (link_reloc_layout.c). */ 333 LinkSectionId link_synth_region(LinkImage* img, Linker* l, Sym name, u16 perms, 334 u16 sem, u64 size, u32 sec_align, 335 u64* out_vaddr, u8** out_bytes); 336 337 /* Append one fixed 8-byte ABS64 reloc-apply record targeting `target` at 338 * `offset` within synthetic section `lsid` (write_vaddr == its file 339 * offset, as every synthetic region is identity-mapped at layout time). 340 * Backs the GOT / IPLT / JIT-slot fills (link_reloc_layout.c). */ 341 void link_emit_internal_abs64(LinkImage* img, LinkSectionId lsid, u32 offset, 342 u64 write_vaddr, LinkSymId target); 343 344 /* ---- Public entries (link_resolve.c) -------------------------------------- 345 */ 346 void link_ingest_archives(struct Linker*); 347 void link_merge_elf_e_flags(struct Linker*, ObjBuilder*, KitSlice label); 348 /* PE/COFF only: synthesize a tiny ObjBuilder providing the mingw CRT 349 * `__CTOR_LIST__` / `__CTOR_END__` / `__DTOR_LIST__` / `__DTOR_END__` 350 * boundary symbols. See link_resolve.c for the contract. */ 351 void link_synth_coff_ctor_dtor_list(struct Linker*); 352 void link_resolve_symbols(struct Linker*, LinkImage*); 353 void link_resolve_undefs(struct Linker*, LinkImage*); 354 void link_gc_compute(struct Linker*, LinkImage*, GcLive*); 355 void link_gc_live_alloc(GcLive* g, struct Linker* l, Heap* h); 356 void link_gc_live_free(GcLive* g, Heap* h); 357 void link_gc_drop_dead_globals(struct Linker*, LinkImage*, const GcLive*); 358 LinkImage* link_image_alloc(Compiler*); 359 360 /* ---- Public entries (link_layout.c) --------------------------------------- 361 */ 362 void link_layout_sections(struct Linker*, LinkImage*, const GcLive*); 363 void link_layout_commons(struct Linker*, LinkImage*); 364 void link_emit_segment_bytes(struct Linker*, LinkImage*); 365 /* Carry .debug_* sections through as file-only sections + populate the 366 * debug registry (link_layout.c). AOT ELF path only; gated by the 367 * caller on !strip_debug / !jit_mode / ELF target. */ 368 void link_layout_debug(struct Linker*, LinkImage*); 369 /* Byte buffer for a file-only debug LinkSection, or NULL if `id` is not 370 * a registered file-only section (link_layout.c). */ 371 u8* link_fileonly_bytes(LinkImage*, LinkSectionId); 372 373 /* ---- Public entries (link_reloc_layout.c) --------------------------------- 374 */ 375 void link_assign_symbol_vaddrs(struct Linker*, LinkImage*); 376 void link_emit_array_boundaries(struct Linker*, LinkImage*); 377 void link_emit_tls_boundaries(struct Linker*, LinkImage*); 378 void link_emit_encoding_section_boundaries(struct Linker*, LinkImage*); 379 void link_layout_jit_stubs(struct Linker*, LinkImage*, u32 map_size, 380 LinkSymId** stub_map_out); 381 void link_layout_got(struct Linker*, LinkImage*, u32 map_size, 382 LinkSymId** got_map_out); 383 void link_layout_iplt(struct Linker*, LinkImage*); 384 void link_emit_relocations(struct Linker*, LinkImage*, const LinkSymId* got_map, 385 const LinkSymId* stub_map); 386 void link_resolve_entry(struct Linker*, LinkImage*); 387 388 /* Defined in link.c. Walks the Linker's inputs and records each input's 389 * ObjBuilder on the LinkImage so the JIT debug view can reach its 390 * .debug_* sections after link_free runs. LINK_INPUT_OBJ_BYTES 391 * builders are moved (the LinkInput's obj pointer is nulled so 392 * linker_release skips them); LINK_INPUT_OBJ builders are borrowed 393 * (the caller still owns). DSO / TBD inputs are skipped. */ 394 void link_capture_debug_inputs(struct Linker*, LinkImage*); 395 396 /* Default PE/COFF ImageBase for executables. Mirrored in link_coff.c 397 * (the emitter writes this into the optional header). Exposed here so 398 * link_layout can synthesize the `__ImageBase` symbol at the same 399 * vaddr, before resolve_undefs runs. */ 400 #define LINK_PE_IMAGE_BASE 0x140000000ULL 401 402 /* Define / upsert a synthetic global symbol resolved to `vaddr`. 403 * Satisfies any prior undef ref (e.g. _DYNAMIC from Scrt1.o, 404 * __dso_handle from libc_nonshared.a) and fans out across per-input 405 * duplicate name slots so emit_reloc_records sees the resolved 406 * vaddr. Implemented in link_layout.c. */ 407 void link_define_boundary(struct Linker*, LinkImage*, const char* name, 408 u64 vaddr); 409 410 /* SegVec instances for image-owned tables. Pointers returned by *_at / 411 * *_push remain valid for the LinkImage's lifetime. */ 412 SEGVEC_DEFINE(LinkSyms, LinkSymbol, 6); /* 64 entries per segment */ 413 SEGVEC_DEFINE(LinkRelocs, LinkRelocApply, 7); /* 128 entries per segment */ 414 415 /* ---- Dynamic-link synthesis state (Phase 4) ---- 416 * 417 * The ELF linker's dynamic-link working state (.dynsym / .dynstr / .gnu.hash 418 * / .rela.* / .plt / .got.plt / .dynamic) and its wire-format records live in 419 * the ELF-only header src/obj/elf/link_dyn.h. LinkImage holds it as an opaque 420 * `LinkDynState* dyn` so the COFF/Mach-O linkers never see the ELF field 421 * names; only the ELF linker dereferences it. */ 422 typedef struct LinkDynState LinkDynState; 423 424 struct LinkImage { 425 Compiler* c; 426 Heap* heap; 427 CompilerCleanup* deferred; /* registered by link_resolve */ 428 /* Borrowed back-pointer set by link_resolve. The Linker is not 429 * mutated through this handle; it's used by the format-specific emit 430 * passes that need to walk LinkInputs (e.g. resolving an imported 431 * symbol's dso_input_id back to the providing dylib's install-name). */ 432 struct Linker* linker; 433 434 /* Final merged RISC-V ELF flags, copied after archive selection. */ 435 u32 elf_e_flags; 436 u8 have_elf_e_flags; 437 438 LinkSyms syms; /* LinkSymId = slot index + 1 */ 439 SymHash globals; /* name -> LinkSymId for global/weak */ 440 441 LinkSection* sections; /* id = index + 1 */ 442 u32 nsections; 443 444 LinkSegment* segments; /* id = index + 1 */ 445 u32 nsegments; 446 u8** segment_bytes; /* one per segment; size = file_size */ 447 size_t* segment_bytes_cap; /* allocation size for free */ 448 449 LinkRelocs relocs; 450 451 /* IFUNC trampoline table (image-relative vaddrs). One entry per 452 * defined STT_GNU_IFUNC symbol: (resolver_vaddr, slot_vaddr). The 453 * JIT path walks this after applying relocations, calls each 454 * resolver in-process, and stores the result into the slot's write 455 * alias. The ELF emit path uses it to seed a startup init routine 456 * (or panics when the routine is not yet wired in). */ 457 u64* iplt_pairs; /* 2 * niplt entries */ 458 u32 niplt; 459 460 LinkSymId entry_sym; 461 462 /* TLS image span (image-relative). Set when any input contributes 463 * an SF_TLS section. filesz covers the .tdata bytes that initialize 464 * the per-thread block; memsz adds .tbss zero-fill. tls_align is 465 * the natural alignment of the TLS image (max of contributing 466 * sections), distinct from the containing PT_LOAD's page align. 467 * AArch64 ELF ABI: TP-relative offset of a TLS symbol with image 468 * offset `o` is `o + 16` (16-byte TCB ahead of the TLS data). */ 469 u64 tls_vaddr; 470 u64 tls_filesz; 471 u64 tls_memsz; 472 u32 tls_align; 473 474 InputMap* input_maps; /* one per input; indexed by input_id-1 */ 475 u32 ninput_maps; 476 477 /* Debug-capture state for the JIT path. Populated by 478 * link_capture_debug_inputs at the tail of link_resolve so the input 479 * ObjBuilders (which carry .debug_* sections + their per-section 480 * relocations — neither consumed nor mutated by layout) survive the 481 * Linker's teardown and become reachable from kit_jit_view. 482 * 483 * Parallel to input_maps: dbg_objs[i] is the ObjBuilder for input 484 * (i+1), or NULL when no debug info is present / the input kind isn't 485 * relevant (DSO/TBD). dbg_objs_owned[i] is 1 when the image must 486 * obj_free the builder at link_image_free (transferred from 487 * LINK_INPUT_OBJ_BYTES), 0 when borrowed (LINK_INPUT_OBJ — caller 488 * still owns). */ 489 ObjBuilder** dbg_objs; 490 u8* dbg_objs_owned; 491 u32 dbg_objs_n; 492 493 /* File-only debug-section registry (AOT ELF path). link_layout_debug 494 * appends one file-only LinkSection per surviving .debug_* contribution 495 * as a contiguous id range [dbg_first_lsid, dbg_first_lsid+dbg_count). 496 * dbg_bytes[i] / dbg_size[i] hold that contribution's own byte buffer 497 * (relocs applied in place at reloc-offset), indexed by lsid - 498 * dbg_first_lsid. Empty on the JIT / Mach-O / COFF lanes. */ 499 LinkSectionId dbg_first_lsid; 500 u32 dbg_count; 501 u8** dbg_bytes; 502 u64* dbg_size; 503 504 /* Dynamic-link state (Phase 4). NULL when emit_pie was not set on 505 * the Linker — i.e., the static-exe / JIT path. Owned by the image. */ 506 LinkDynState* dyn; 507 /* Mirror of Linker.emit_pie at link_resolve time; consulted by emit. */ 508 int pie; 509 /* Mirror of Linker.emit_shared at link_resolve time; consulted by emit. */ 510 int shared; 511 /* Set when layout was driven by Linker.script. The emitter then keeps 512 * segment vaddrs at their script-assigned absolute values, drops the 513 * self-describing headers PT_LOAD / build-id PT_NOTE, and only shifts 514 * file offsets to make room for ehdr+phdrs. */ 515 u8 scripted; 516 /* -Ttext: when text_base_set, the static-exe image base override, mirrored 517 * from Linker at link_resolve time. Ignored if pie/scripted. */ 518 int text_base_set; 519 u64 text_base; 520 521 /* Final emit facts recorded by the format emitter for the link-map / 522 * symbols side-files (kit_link_session_write_map / _write_symbols, which run 523 * on the format-neutral image *after* emit). The emitter owns runtime-base 524 * selection and headers synthesis, so the report writers read the resolved 525 * values back from here instead of re-deriving format-specific policy. 526 * 527 * load_base is the runtime base the emitter added to image-relative vaddrs: 528 * IMAGE_BASE_STATIC, or a -Ttext override, for a static ET_EXEC; 0 for 529 * PIE/scripted/JIT (which keep image-relative addresses). The headers_* 530 * fields describe the synthesized read-only headers load segment (ELF: the 531 * ehdr+phdrs PT_LOAD mapped at load_base); headers_present is 0 when the 532 * format emits no separate headers segment (scripted ELF, non-ELF). All 533 * stay zero until emit runs, so a report taken without an emit reports 534 * image-relative addresses, as before. */ 535 u64 load_base; 536 u64 headers_filesz; 537 u64 headers_memsz; 538 u32 headers_align; 539 u8 headers_present; 540 }; 541 542 /* Whether S is the canonical LinkSymbol for its non-local name. 543 * 544 * Resolution deliberately keeps one LinkSymbol per input symbol: after an 545 * undefined reference is resolved, its per-input slot mirrors the definition 546 * so relocations can retain their stable LinkSymId. img->globals remains the 547 * authority for the single canonical global/weak slot. Format emitters and 548 * post-link reports must use this predicate rather than mistaking those 549 * resolved reference slots for distinct definitions. 550 * 551 * Locals and nameless records are outside the global-name authority and are 552 * therefore not canonical globals. A named non-local missing from globals is 553 * retained defensively; synthetic/import bookkeeping can briefly have that 554 * shape while an image is being assembled. */ 555 static inline int link_symbol_is_canonical_global(const LinkImage* img, 556 const LinkSymbol* s) { 557 LinkSymId canonical; 558 if (!img || !s || !s->name || s->bind == SB_LOCAL) return 0; 559 canonical = symhash_get(&img->globals, s->name); 560 return canonical == LINK_SYM_NONE || canonical == s->id; 561 } 562 563 /* Page granularity used for ELF segment alignment and the file-offset / 564 * vaddr congruence the runtime loader requires. 16 KiB matches AArch64 565 * Apple Silicon and the common Linux/AArch64 kernel config; 4 KiB pages 566 * are also valid at runtime since 16K is a multiple. */ 567 #define PAGE_SIZE 0x4000u 568 569 /* Apply one relocation in place. P_bytes points at the first byte of the 570 * relocation site within the final memory; S is the resolved final 571 * address of the target symbol; A the addend; P the final address of 572 * the relocation site. Panics on unsupported kinds. */ 573 void link_reloc_apply(Compiler*, RelocKind, u8* P_bytes, u64 S, i64 A, u64 P); 574 575 /* kit emits local-exec TLS only: a thread-local's offset within THIS image's 576 * TLS block is fixed at link time, so a local-exec access (or the TP-relative 577 * fill of a TLS initial-exec GOT slot) is valid only against a thread-local 578 * *defined in the image being linked*. Panic with a clear diagnostic if `tgt` 579 * is imported from a shared object (its TLS block belongs to another module, 580 * sized and placed by the dynamic loader) or resolved to a non-thread-local 581 * definition. There is no initial-exec/global-dynamic fallback to relax to, 582 * so the only alternative is a silently bogus tp-relative offset -- hence the 583 * hard error. A no-op when `tgt` is a thread-local defined here. */ 584 void link_require_local_tls(Compiler*, const LinkSymbol* tgt); 585 586 /* Public link_emit_image_writer dispatches by Compiler.target.obj. The 587 * ELF and Mach-O writers get architecture identity from LinkArchDesc; 588 * reloc application remains keyed by RelocKind. COFF arrives later. */ 589 void link_emit_elf(LinkImage*, Writer*); 590 void link_emit_macho(LinkImage*, Writer*); 591 void link_emit_coff(LinkImage*, Writer*); 592 593 /* Format-agnostic 16-byte image identity, derived from per-segment 594 * post-shift bytes + vaddrs/sizes. ELF wraps it in a 595 * .note.gnu.build-id; Mach-O will wrap it in LC_UUID; COFF/PE in a 596 * debug directory entry. One source of truth so the bytes match 597 * across formats. */ 598 #define LINK_IMAGE_ID_BYTES 16u 599 void link_image_id_compute(const LinkImage*, u8 out[LINK_IMAGE_ID_BYTES]); 600 601 #endif