kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

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 }