kit

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

symresolve.c (1743B)


      1 #include "obj/symresolve.h"
      2 
      3 SymMergeResult symresolve_merge(SymAttrs existing, SymAttrs incoming) {
      4   SymMergeResult r;
      5   int new_strength = symresolve_bind_strength(incoming.bind);
      6   int old_strength = symresolve_bind_strength(existing.bind);
      7   r.kind = SYM_MERGE_KEEP_EXISTING;
      8   r.merged_align = 0;
      9 
     10   if (existing.kind == SK_COMMON && incoming.kind == SK_COMMON) {
     11     /* Tentative-definition merge: the larger reservation wins, alignment is the
     12      * max of both. A smaller-or-equal incoming common changes nothing (this
     13      * matches the linker's prior behavior, which did not bump alignment when
     14      * the size did not grow). */
     15     if (incoming.size > existing.size) {
     16       r.kind = SYM_MERGE_COMMON;
     17       r.merged_align = (incoming.common_align > existing.common_align)
     18                            ? incoming.common_align
     19                            : existing.common_align;
     20     }
     21   } else if (incoming.kind == SK_COMMON) {
     22     /* A real definition already present beats an incoming common. */
     23   } else if (existing.kind == SK_COMMON) {
     24     /* A real definition beats a previously-seen common. */
     25     r.kind = SYM_MERGE_REPLACE;
     26   } else if (new_strength > old_strength) {
     27     r.kind = SYM_MERGE_REPLACE;
     28   } else if (new_strength == old_strength &&
     29              new_strength == symresolve_bind_strength(SB_GLOBAL)) {
     30     /* Two strong definitions: legal only as COFF SELECTANY when both sit in
     31      * COMDAT sections (keep the first, discard the new); otherwise ODR. */
     32     r.kind = (existing.in_comdat && incoming.in_comdat) ? SYM_MERGE_COMDAT_DISCARD
     33                                                         : SYM_MERGE_ODR_ERROR;
     34   }
     35   /* else: incoming is weaker (or weak-vs-weak); keep the first definition. */
     36   return r;
     37 }