mirror of https://github.com/Shizmob/smol
REAL real fix for #5, also fix the hash size check,
This commit is contained in:
parent
e6268471ff
commit
bfe3ba1f20
|
@ -10,13 +10,16 @@ def get_min_check_width(libraries, hashfn):
|
||||||
minv = 8 # can't go lower
|
minv = 8 # can't go lower
|
||||||
for k, v in libraries.items():
|
for k, v in libraries.items():
|
||||||
for sym in v:
|
for sym in v:
|
||||||
hv = hashfn(sym[0]) # sym == (name, reloc)
|
hv = hashfn(sym)
|
||||||
|
#eprintf("hash: 0x%08x of %s"%(hv,sym))
|
||||||
if (hv & 0xffffffff) == 0:
|
if (hv & 0xffffffff) == 0:
|
||||||
# this should (hopefully) NEVER happen
|
# this should (hopefully) NEVER happen
|
||||||
error("Aiee, all-zero hash for sym '%s'!" % sym)
|
error("E: Aiee, all-zero hash for sym '%s'!" % sym)
|
||||||
elif (hv & 0xFFFF) == 0:
|
elif (hv & 0xFFFF) == 0:
|
||||||
|
#eprintf("32-bit hash")
|
||||||
minv = max(minv, 32) # need at least 32 bits
|
minv = max(minv, 32) # need at least 32 bits
|
||||||
elif (hv & 0xFF) == 0:
|
elif (hv & 0xFF) == 0:
|
||||||
|
#eprintf("16-bit hash")
|
||||||
minv = max(minv, 16) # need at least 16 bits
|
minv = max(minv, 16) # need at least 16 bits
|
||||||
|
|
||||||
return minv
|
return minv
|
||||||
|
|
|
@ -277,30 +277,36 @@ def build_symbol_map(readelf_bin, libraries) -> Dict[str, Dict[str, ExportSym]]:
|
||||||
|
|
||||||
|
|
||||||
# this ordening is specific to ONE symbol!
|
# this ordening is specific to ONE symbol!
|
||||||
def build_preferred_lib_order(sym, libs: Dict[str, ExportSym]) -> List[Tuple[str, ExportSym]]:
|
def build_preferred_lib_order(sym, libs: Dict[str, ExportSym]) -> List[str]:
|
||||||
# libs: lib -> syminfo
|
# libs: lib -> syminfo
|
||||||
realdefs = [(k, v) for k, v in libs.items() if v.scope != "WEAK" and v.ndx != "UND"]
|
realdefs = [lib for lib, v in libs.items() if v.scope != "WEAK" and v.ndx != "UND"]
|
||||||
weakdefs = [(k, v) for k, v in libs.items() if v.scope == "WEAK" and v.ndx != "UND"]
|
weakdefs = [lib for lib, v in libs.items() if v.scope == "WEAK" and v.ndx != "UND"]
|
||||||
weakunddefs = [(k, v) for k, v in libs.items() if v.scope == "WEAK" and v.ndx == "UND"]
|
weakunddefs = [lib for lib, v in libs.items() if v.scope == "WEAK" and v.ndx == "UND"]
|
||||||
unddefs = [(k, v) for k, v in libs.items() if v.scope != "WEAK" and v.ndx == "UND"]
|
unddefs = [lib for lib, v in libs.items() if v.scope != "WEAK" and v.ndx == "UND"]
|
||||||
|
|
||||||
#assert len(realdefs) + len(weakdefs) + len(weakunddefs) == len(libs)
|
#ks = [v.name for k, v in libs.items()]
|
||||||
|
#print("k=",ks)
|
||||||
|
#assert all(k == ks[0] for k in ks)
|
||||||
|
|
||||||
if len(realdefs) > 1 or (len(realdefs) == 0 and len(weakdefs) > 1):
|
if len(realdefs) > 1: #or (len(realdefs) == 0 and len(weakdefs) > 1):
|
||||||
error("E: symbol '%s' defined non-weakly in multiple libraries! (%s)"
|
error("E: symbol '%s' defined non-weakly in multiple libraries! (%s)"
|
||||||
% (sym, ', '.join(libs.keys())))
|
% (sym, ', '.join(realdefs)))
|
||||||
|
|
||||||
|
if len(realdefs) == 0 and len(weakdefs) > 1:
|
||||||
|
eprintf("W: symbol '%s' defined amibguously weakly in multiple libraries! Will pick a random one... (%s)"
|
||||||
|
% (sym, ', '.join(weakdefs)))
|
||||||
if len(realdefs) == 0 and len(weakdefs) == 0: # must be in weakunddefs or unddefs
|
if len(realdefs) == 0 and len(weakdefs) == 0: # must be in weakunddefs or unddefs
|
||||||
error("E: no default weak implementation found for symbol '%s'" % sym)
|
error("E: no default weak implementation found for symbol '%s'" % sym)
|
||||||
|
|
||||||
return realdefs + weakdefs + weakunddefs #+ unddefs
|
return realdefs + weakdefs + weakunddefs + unddefs
|
||||||
|
|
||||||
def has_good_subordening(needles, haystack):
|
def has_good_subordening(needles, haystack):
|
||||||
haylist = [x[0] for x in haystack]
|
haylist = [x[0] for x in haystack]
|
||||||
prevind = 0
|
prevind = 0
|
||||||
for k, _ in needles:
|
for lib in needles:
|
||||||
curind = None
|
curind = None
|
||||||
try:
|
try:
|
||||||
curind = haylist.index(k)
|
curind = haylist.index(lib)
|
||||||
except ValueError: # not in haystack --> eh, let's ignore
|
except ValueError: # not in haystack --> eh, let's ignore
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -310,29 +316,47 @@ def has_good_subordening(needles, haystack):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def add_with_ordening(haystack: List[Tuple[str, Dict[str, str]]], # [(libname, (symname -> reloctyp))]
|
def add_with_ordening(haystack: List[Tuple[str, Dict[str, str]]], # [(libname, (symname -> reloctyp))]
|
||||||
needles: List[Tuple[str, ExportSym]], # [(lib, syminfo)]
|
needles: List[str], # [lib]
|
||||||
sym: str, reloc: str) \
|
sym: str, reloc: str, last=False) \
|
||||||
-> List[Tuple[str, Dict[str, str]]]:
|
-> List[Tuple[str, Dict[str, str]]]:
|
||||||
haylist = [x[0] for x in haystack]
|
haylist = [x[0] for x in haystack]
|
||||||
startind = 0
|
startind = None if last else 0
|
||||||
for k, v in needles:
|
ii = 0
|
||||||
|
for lib in needles:
|
||||||
#eprintf("k=",k,"v=",v)
|
#eprintf("k=",k,"v=",v)
|
||||||
try:
|
try:
|
||||||
newind = haylist.index(k)
|
newind = haylist.index(lib)
|
||||||
assert newind >= startind, "???? (%d <= %d)" % (newind, startind)
|
#eprintf("lib=%s newind=%d" % (lib, newind))
|
||||||
|
#assert newind >= startind, "???? (%d <= %d)" % (newind, startind)
|
||||||
startind = newind
|
startind = newind
|
||||||
|
|
||||||
symrelocdict = haystack[startind][1]
|
if ii == 0:
|
||||||
if v.name in symrelocdict:
|
symrelocdict = haystack[startind][1]
|
||||||
assert False, "?????"
|
assert not(sym in symrelocdict), "?????"
|
||||||
haystack[startind][1][v.name] = reloc
|
haystack[startind][1][sym] = reloc
|
||||||
except ValueError: # not in haystack --> add!
|
except ValueError: # not in haystack --> add!
|
||||||
startind = startind + 1
|
if startind is None:
|
||||||
haystack.insert(startind, (k, {v.name:reloc}))
|
startind = len(haystack)
|
||||||
haylist.insert(startind, k)
|
if not last:
|
||||||
|
startind = startind + 1
|
||||||
|
#eprintf("lib=%s NEWind=%d" % (lib, startind))
|
||||||
|
dv = {sym: reloc} if ii == 0 else {}
|
||||||
|
haystack.insert(startind, (lib, dv))
|
||||||
|
haylist.insert(startind, lib)
|
||||||
|
if last:
|
||||||
|
startind = startind + 1
|
||||||
|
ii = ii + 1
|
||||||
|
|
||||||
return haystack
|
return haystack
|
||||||
|
|
||||||
|
def visable(ll):
|
||||||
|
rr = []
|
||||||
|
for k, v in ll:
|
||||||
|
if isinstance(v, ExportSym):
|
||||||
|
rr.append((k, v)) # v.name
|
||||||
|
else:
|
||||||
|
rr.append((k, v.keys()))
|
||||||
|
return rr
|
||||||
def resolve_extern_symbols(needed: Dict[str, List[str]], # symname -> reloctyps
|
def resolve_extern_symbols(needed: Dict[str, List[str]], # symname -> reloctyps
|
||||||
available: Dict[str, Dict[str, ExportSym]], # symname -> (lib -> syminfo)
|
available: Dict[str, Dict[str, ExportSym]], # symname -> (lib -> syminfo)
|
||||||
args) \
|
args) \
|
||||||
|
@ -351,7 +375,7 @@ def resolve_extern_symbols(needed: Dict[str, List[str]], # symname -> reloctyps
|
||||||
if args.det:
|
if args.det:
|
||||||
bound = sorted(bound, key=lambda kv: (len(kv[0]), kv[0]))
|
bound = sorted(bound, key=lambda kv: (len(kv[0]), kv[0]))
|
||||||
|
|
||||||
#eprintf("bound", bound)
|
#eprintf("bound", bound,"\n")
|
||||||
|
|
||||||
liborder = [] # [(libname, (symname -> reloctyp))]
|
liborder = [] # [(libname, (symname -> reloctyp))]
|
||||||
for k, v in bound: # k: sym (str)
|
for k, v in bound: # k: sym (str)
|
||||||
|
@ -360,7 +384,8 @@ def resolve_extern_symbols(needed: Dict[str, List[str]], # symname -> reloctyps
|
||||||
reloc, libs = v[0], v[1]
|
reloc, libs = v[0], v[1]
|
||||||
if len(libs) <= 1:
|
if len(libs) <= 1:
|
||||||
continue
|
continue
|
||||||
# preferred: [(lib, syminfo)]
|
# preferred: [lib]
|
||||||
|
#eprintf("libs",visable(libs.items()))
|
||||||
preferred = build_preferred_lib_order(k, libs)
|
preferred = build_preferred_lib_order(k, libs)
|
||||||
#eprintf("preferred",preferred)
|
#eprintf("preferred",preferred)
|
||||||
if not has_good_subordening(preferred, liborder):
|
if not has_good_subordening(preferred, liborder):
|
||||||
|
@ -372,10 +397,10 @@ def resolve_extern_symbols(needed: Dict[str, List[str]], # symname -> reloctyps
|
||||||
message = "W: unreconcilable library ordenings '%s' and '%s' "+\
|
message = "W: unreconcilable library ordenings '%s' and '%s' "+\
|
||||||
"for symbol '%s', you might want to enable `-fskip-zero-value'."
|
"for symbol '%s', you might want to enable `-fskip-zero-value'."
|
||||||
if message is not None:
|
if message is not None:
|
||||||
eprintf(message % (', '.join(liborder.keys()), ', '.join(preferred.keys()), k))
|
#eprintf(message % (', '.join(liborder.keys()), ', '.join(preferred.keys()), k))
|
||||||
|
|
||||||
liborder = add_with_ordening(liborder, preferred, k, reloc)
|
liborder = add_with_ordening(liborder, preferred, k, reloc)
|
||||||
#eprintf("new order",liborder)
|
#eprintf("new order",visable(liborder),"\n")
|
||||||
|
|
||||||
# add all those left without any possible preferred ordening
|
# add all those left without any possible preferred ordening
|
||||||
for k, v in bound:
|
for k, v in bound:
|
||||||
|
@ -385,9 +410,10 @@ def resolve_extern_symbols(needed: Dict[str, List[str]], # symname -> reloctyps
|
||||||
if len(libs) != 1:
|
if len(libs) != 1:
|
||||||
continue
|
continue
|
||||||
lib = libs.popitem() # (lib, syminfo)
|
lib = libs.popitem() # (lib, syminfo)
|
||||||
liborder = add_with_ordening(liborder, [lib], k, reloc)
|
#eprintf("lib",lib)
|
||||||
#eprintf("new order (no preference)",liborder)
|
liborder = add_with_ordening(liborder, [lib[0]], k, reloc, True)
|
||||||
|
#eprintf("new order (no preference)",visable(liborder),"\n")
|
||||||
|
|
||||||
#eprintf("ordered", liborder)
|
#eprintf("ordered", visable(liborder))
|
||||||
return OrderedDict(liborder)
|
return OrderedDict(liborder)
|
||||||
|
|
||||||
|
|
6
smold.py
6
smold.py
|
@ -120,11 +120,11 @@ def do_smol_run(args, arch):
|
||||||
tmp_asm_file, tmp_elf_file, args.asflags)
|
tmp_asm_file, tmp_elf_file, args.asflags)
|
||||||
|
|
||||||
# link with LD into the final executable, w/ special linker script
|
# link with LD into the final executable, w/ special linker script
|
||||||
ld_link_final(args.verbose, args.cc, arch, args.smolld, [objinput, tmp_elf_file],
|
if args.debugout is not None: # do this first, so the linker map output will use the final output binary
|
||||||
args.output, args.ldflags, False)
|
|
||||||
if args.debugout is not None:
|
|
||||||
ld_link_final(args.verbose, args.cc, arch, args.smolld, [objinput, tmp_elf_file],
|
ld_link_final(args.verbose, args.cc, arch, args.smolld, [objinput, tmp_elf_file],
|
||||||
args.debugout, args.ldflags, True)
|
args.debugout, args.ldflags, True)
|
||||||
|
ld_link_final(args.verbose, args.cc, arch, args.smolld, [objinput, tmp_elf_file],
|
||||||
|
args.output, args.ldflags, False)
|
||||||
finally:
|
finally:
|
||||||
if not args.keeptmp:
|
if not args.keeptmp:
|
||||||
if objinputistemp: os.remove(objinput)
|
if objinputistemp: os.remove(objinput)
|
||||||
|
|
Loading…
Reference in New Issue