object_builder.c (10302B)
1 /* Public KitObjBuilder API: thin adapter over the internal obj_* surface. */ 2 3 #include <kit/object.h> 4 #include <string.h> 5 6 #include "core/core.h" 7 #include "obj/format.h" 8 #include "obj/obj.h" 9 10 _Static_assert((uint32_t)KIT_RELOC_NONE == (uint32_t)R_NONE, 11 "public reloc NONE drift"); 12 _Static_assert((uint32_t)KIT_RELOC_ABS32 == (uint32_t)R_ABS32, 13 "public reloc ABS32 drift"); 14 _Static_assert((uint32_t)KIT_RELOC_ABS64 == (uint32_t)R_ABS64, 15 "public reloc ABS64 drift"); 16 _Static_assert((uint32_t)KIT_RELOC_REL32 == (uint32_t)R_REL32, 17 "public reloc REL32 drift"); 18 _Static_assert((uint32_t)KIT_RELOC_REL64 == (uint32_t)R_REL64, 19 "public reloc REL64 drift"); 20 _Static_assert((uint32_t)KIT_RELOC_PC32 == (uint32_t)R_PC32, 21 "public reloc PC32 drift"); 22 _Static_assert((uint32_t)KIT_RELOC_PC64 == (uint32_t)R_PC64, 23 "public reloc PC64 drift"); 24 _Static_assert((uint32_t)KIT_RELOC_GOT32 == (uint32_t)R_GOT32, 25 "public reloc GOT32 drift"); 26 _Static_assert((uint32_t)KIT_RELOC_PLT32 == (uint32_t)R_PLT32, 27 "public reloc PLT32 drift"); 28 _Static_assert((uint32_t)KIT_RELOC_X64_PLT32 == (uint32_t)R_X64_PLT32, 29 "public reloc X64_PLT32 drift"); 30 31 static ObjSecId pub_to_intern_sec(KitObjSection s) { 32 if (s == KIT_SECTION_NONE) return OBJ_SEC_NONE; 33 return (ObjSecId)(s + 1); 34 } 35 36 static KitObjSection intern_to_pub_sec(ObjSecId id) { 37 if (id == OBJ_SEC_NONE) return KIT_SECTION_NONE; 38 return (KitObjSection)(id - 1); 39 } 40 41 static ObjSymId pub_to_intern_sym(KitObjSymbol s) { 42 if (s == KIT_OBJ_SYMBOL_NONE) return OBJ_SYM_NONE; 43 return (ObjSymId)s; 44 } 45 46 static KitObjSymbol intern_to_pub_sym(ObjSymId id) { 47 if (id == OBJ_SYM_NONE) return KIT_OBJ_SYMBOL_NONE; 48 return (KitObjSymbol)id; 49 } 50 51 static ObjGroupId pub_to_intern_group(KitObjGroup g) { 52 if (g == KIT_OBJ_GROUP_NONE) return OBJ_GROUP_NONE; 53 return (ObjGroupId)g; 54 } 55 56 static KitObjGroup intern_to_pub_group(ObjGroupId id) { 57 if (id == OBJ_GROUP_NONE) return KIT_OBJ_GROUP_NONE; 58 return (KitObjGroup)id; 59 } 60 61 KitStatus kit_obj_builder_new(KitCompiler* c, KitObjBuilder** out) { 62 ObjBuilder* ob; 63 if (!out) return KIT_INVALID; 64 if (!c) return KIT_INVALID; 65 ob = obj_new(c); 66 if (!ob) return KIT_NOMEM; 67 *out = ob; 68 return KIT_OK; 69 } 70 71 void kit_obj_builder_free(KitObjBuilder* b) { 72 if (b) obj_free(b); 73 } 74 75 KitCompiler* kit_obj_builder_compiler(KitObjBuilder* b) { 76 return b ? (KitCompiler*)obj_compiler(b) : NULL; 77 } 78 79 KitStatus kit_obj_builder_section(KitObjBuilder* b, 80 const KitObjSectionDesc* desc, 81 KitObjSection* out) { 82 ObjSecId id; 83 if (!b || !desc || !out) return KIT_INVALID; 84 id = obj_section(b, (Sym)desc->name, (SecKind)desc->kind, (u16)desc->flags, 85 desc->align ? desc->align : 1u); 86 if (id == OBJ_SEC_NONE) return KIT_ERR; 87 if (desc->entsize) { 88 /* Carry entsize through obj_section_ex if needed; obj_section path 89 * uses default 0. Use obj_section_ex when caller specifies entsize. */ 90 const Section* sec = obj_section_get(b, id); 91 (void)sec; 92 /* Re-create via the _ex path to set entsize. */ 93 /* obj_section dedupes by name+kind+flags+align; calling _ex with the 94 * same fields plus the entsize updates that section. */ 95 id = obj_section_ex(b, (Sym)desc->name, (SecKind)desc->kind, SSEM_PROGBITS, 96 (u16)desc->flags, desc->align ? desc->align : 1u, 97 desc->entsize, 0, 0); 98 } 99 *out = intern_to_pub_sec(id); 100 return KIT_OK; 101 } 102 103 KitStatus kit_obj_builder_section_group(KitObjBuilder* b, KitObjSection sec, 104 KitObjGroup grp) { 105 if (!b) return KIT_INVALID; 106 obj_section_set_group(b, pub_to_intern_sec(sec), pub_to_intern_group(grp)); 107 return KIT_OK; 108 } 109 110 KitStatus kit_obj_builder_pos(KitObjBuilder* b, KitObjSection sec, 111 uint64_t* out) { 112 if (!b || !out) return KIT_INVALID; 113 *out = obj_pos(b, pub_to_intern_sec(sec)); 114 return KIT_OK; 115 } 116 117 KitStatus kit_obj_builder_align(KitObjBuilder* b, KitObjSection sec, 118 uint32_t align, uint64_t* new_pos_out) { 119 u32 pos; 120 if (!b) return KIT_INVALID; 121 pos = obj_align_to(b, pub_to_intern_sec(sec), align ? align : 1u); 122 if (new_pos_out) *new_pos_out = pos; 123 return KIT_OK; 124 } 125 126 KitStatus kit_obj_builder_write(KitObjBuilder* b, KitObjSection sec, 127 const void* data, size_t n) { 128 if (!b) return KIT_INVALID; 129 obj_write(b, pub_to_intern_sec(sec), data, n); 130 return KIT_OK; 131 } 132 133 KitStatus kit_obj_builder_reserve(KitObjBuilder* b, KitObjSection sec, size_t n, 134 void** out) { 135 u8* p; 136 if (!b || !out) return KIT_INVALID; 137 p = obj_reserve(b, pub_to_intern_sec(sec), n); 138 if (!p) return KIT_NOMEM; 139 *out = p; 140 return KIT_OK; 141 } 142 143 KitStatus kit_obj_builder_reserve_bss(KitObjBuilder* b, KitObjSection sec, 144 uint64_t size, uint32_t align) { 145 if (!b) return KIT_INVALID; 146 obj_reserve_bss(b, pub_to_intern_sec(sec), (u32)size, align ? align : 1u); 147 return KIT_OK; 148 } 149 150 KitStatus kit_obj_builder_patch(KitObjBuilder* b, KitObjSection sec, 151 uint64_t offset, const void* data, size_t n) { 152 if (!b) return KIT_INVALID; 153 obj_patch(b, pub_to_intern_sec(sec), (u32)offset, data, n); 154 return KIT_OK; 155 } 156 157 KitStatus kit_obj_builder_symbol(KitObjBuilder* b, const KitObjSymbolDesc* desc, 158 KitObjSymbol* out) { 159 ObjSymId id; 160 if (!b || !desc || !out) return KIT_INVALID; 161 id = obj_symbol(b, (Sym)desc->name, (SymBind)desc->bind, (SymKind)desc->kind, 162 pub_to_intern_sec(desc->section), desc->value, desc->size); 163 if (id == OBJ_SYM_NONE) return KIT_ERR; 164 *out = intern_to_pub_sym(id); 165 return KIT_OK; 166 } 167 168 KitStatus kit_obj_builder_symbol_define(KitObjBuilder* b, KitObjSymbol sym, 169 KitObjSection section, uint64_t value, 170 uint64_t size) { 171 if (!b) return KIT_INVALID; 172 obj_symbol_define(b, pub_to_intern_sym(sym), pub_to_intern_sec(section), 173 value, size); 174 return KIT_OK; 175 } 176 177 KitStatus kit_obj_builder_reloc(KitObjBuilder* b, const KitObjRelocDesc* desc) { 178 if (!b || !desc) return KIT_INVALID; 179 /* Public KitRelocKind.code is the raw internal RelocKind value 180 * (single shared numeric space). */ 181 obj_reloc(b, pub_to_intern_sec(desc->section), (u32)desc->offset, 182 (RelocKind)desc->kind.code, pub_to_intern_sym(desc->symbol), 183 desc->addend); 184 return KIT_OK; 185 } 186 187 KitStatus kit_obj_builder_group(KitObjBuilder* b, KitSym name, 188 KitObjSymbol signature, uint32_t flags, 189 KitObjGroup* out) { 190 ObjGroupId id; 191 if (!b || !out) return KIT_INVALID; 192 id = obj_group(b, (Sym)name, pub_to_intern_sym(signature), flags); 193 if (id == OBJ_GROUP_NONE) return KIT_ERR; 194 *out = intern_to_pub_group(id); 195 return KIT_OK; 196 } 197 198 KitStatus kit_obj_builder_group_add_section(KitObjBuilder* b, KitObjGroup grp, 199 KitObjSection sec) { 200 if (!b) return KIT_INVALID; 201 obj_group_add_section(b, pub_to_intern_group(grp), pub_to_intern_sec(sec)); 202 return KIT_OK; 203 } 204 205 KitStatus kit_obj_builder_finalize(KitObjBuilder* b) { 206 if (!b) return KIT_INVALID; 207 obj_finalize(b); 208 return KIT_OK; 209 } 210 211 /* ---- mutators ---- */ 212 213 KitStatus kit_obj_builder_remove_section(KitObjBuilder* b, KitObjSection sec) { 214 if (!b) return KIT_INVALID; 215 obj_section_remove(b, pub_to_intern_sec(sec)); 216 return KIT_OK; 217 } 218 219 KitStatus kit_obj_builder_remove_symbol(KitObjBuilder* b, KitObjSymbol sym) { 220 if (!b) return KIT_INVALID; 221 obj_symbol_remove(b, pub_to_intern_sym(sym)); 222 return KIT_OK; 223 } 224 225 KitStatus kit_obj_builder_remove_group(KitObjBuilder* b, KitObjGroup grp) { 226 if (!b) return KIT_INVALID; 227 obj_group_remove(b, pub_to_intern_group(grp)); 228 return KIT_OK; 229 } 230 231 KitStatus kit_obj_builder_rename_section(KitObjBuilder* b, KitObjSection sec, 232 KitSym new_name) { 233 if (!b) return KIT_INVALID; 234 obj_section_rename(b, pub_to_intern_sec(sec), (Sym)new_name); 235 return KIT_OK; 236 } 237 238 KitStatus kit_obj_builder_rename_symbol(KitObjBuilder* b, KitObjSymbol sym, 239 KitSym new_name) { 240 if (!b) return KIT_INVALID; 241 obj_symbol_rename(b, pub_to_intern_sym(sym), (Sym)new_name); 242 return KIT_OK; 243 } 244 245 KitStatus kit_obj_builder_symbol_set_bind(KitObjBuilder* b, KitObjSymbol sym, 246 KitSymBind bind) { 247 if (!b) return KIT_INVALID; 248 obj_symbol_set_bind(b, pub_to_intern_sym(sym), (SymBind)bind); 249 return KIT_OK; 250 } 251 252 KitStatus kit_obj_builder_symbol_set_vis(KitObjBuilder* b, KitObjSymbol sym, 253 KitSymVis vis) { 254 if (!b) return KIT_INVALID; 255 obj_symbol_set_vis(b, pub_to_intern_sym(sym), (SymVis)vis); 256 return KIT_OK; 257 } 258 259 KitStatus kit_obj_builder_section_replace_bytes(KitObjBuilder* b, 260 KitObjSection sec, 261 const void* data, size_t n) { 262 if (!b) return KIT_INVALID; 263 obj_section_replace_bytes(b, pub_to_intern_sec(sec), (const u8*)data, n); 264 return KIT_OK; 265 } 266 267 KitStatus kit_obj_builder_find_symbol(const KitObjBuilder* b, KitSym name, 268 KitObjSymbol* out) { 269 ObjSymId id; 270 if (!b || !out) return KIT_INVALID; 271 id = obj_symbol_find((ObjBuilder*)b, (Sym)name); 272 *out = intern_to_pub_sym(id); 273 return id != OBJ_SYM_NONE ? KIT_OK : KIT_NOT_FOUND; 274 } 275 276 KitStatus kit_obj_builder_emit(KitObjBuilder* b, KitWriter* w) { 277 Compiler* c; 278 if (!b || !w) return KIT_INVALID; 279 c = obj_compiler(b); 280 if (!c) return KIT_INVALID; 281 return kit_obj_builder_emit_as(b, c->target.obj, w); 282 } 283 284 KitStatus kit_obj_builder_emit_as(KitObjBuilder* b, KitObjFmt fmt, 285 KitWriter* w) { 286 Compiler* c; 287 const ObjFormatImpl* impl; 288 if (!b || !w) return KIT_INVALID; 289 c = obj_compiler(b); 290 if (!c) return KIT_INVALID; 291 impl = obj_format_lookup(fmt); 292 if (!impl || !impl->emit) return KIT_UNSUPPORTED; 293 impl->emit(c, b, w); 294 return kit_writer_status(w); 295 }