Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
PoroCYon
smol
Commits
6613bab2
Commit
6613bab2
authored
Aug 08, 2020
by
PoroCYon
Browse files
CRC32C-based hash (thanks Intel) (Python part is still TODO)
parent
494d3263
Changes
6
Hide whitespace changes
Inline
Side-by-side
.gitignore
View file @
6613bab2
/bin
/obj
__pycache__
smol-20*-*-*/
smol*.tar.xz
rt/loader32.asm
View file @
6613bab2
...
...
@@ -98,34 +98,44 @@ _smol_start:
add
esi
,
ebx
push
ecx
%ifndef USE_HASH16
; source in eax, result in eax
%ifdef USE_CRC32C_HASH
push
-
1
pop
eax
%else
%ifndef USE_HASH16
push
ebx
push
33
push
5381
pop
eax
pop
ebx
%else
%else
xor
eax
,
eax
%endif
%endif
xor
ecx
,
ecx
%endif
.nexthashiter:
;
xchg
eax
,
ecx
lodsb
or
al
,
al
xchg
eax
,
ecx
jz
short
.breakhash
%ifndef USE_HASH16
%ifdef USE_CRC32C_HASH
crc32
eax
,
cl
%else
%ifndef USE_HASH16
push
edx
mul
ebx
pop
edx
; add eax, ecx
%else
%else
ror
ax
,
2
; add ax, cx
%endif
%endif
add
eax
,
ecx
%endif
jmp
short
.nexthashiter
.breakhash:
...
...
rt/loader64.asm
View file @
6613bab2
; vim: set ft=nasm:
; vim: set ft=nasm
et
:
;%define R10_BIAS (0x2B4)
%define R10_BIAS (0x2B4+0x40)
...
...
@@ -96,6 +96,8 @@ _smol_start:
mov
esi
,
dword
[
rdx
+
ST_NAME_OFF
]
add
rsi
,
r8
;9
%ifndef USE_CRC32C_HASH
; djb2
xor
ecx
,
ecx
push
33
push
5381
...
...
@@ -103,22 +105,45 @@ _smol_start:
; pop rcx
pop
rax
pop
rbx
%else
; crc32
push
-
1
pop
rcx
%endif
.nexthashiter:
%ifndef USE_CRC32C_HASH
; djb2
; TODO: optimize register usage a bit more
xchg
eax
,
ecx
%endif
lodsb
or
al
,
al
%ifndef USE_CRC32C_HASH
; djb2
xchg
eax
,
ecx
%endif
jz
short
.breakhash
%ifndef USE_CRC32C_HASH
; djb2
push
rdx
mul
ebx
pop
rdx
add
eax
,
ecx
%else
; crc32c
crc32
ecx
,
al
%endif
jmp
short
.nexthashiter
.breakhash:
%ifdef USE_CRC32C_HASH
; crc32c
cmp
r14d
,
ecx
%else
; djb2
cmp
r14d
,
eax
%endif
je
short
.hasheq
add
rdx
,
SYMTAB_SIZE
...
...
smol/emit.py
View file @
6613bab2
...
...
@@ -20,13 +20,16 @@ def sort_imports(libraries, hashfn):
if
sys
.
version_info
<
(
3
,
6
):
return
OrderedDict
(
ll
)
else
:
return
dict
(
ll
)
def
output_x86
(
libraries
,
nx
,
h
16
,
outf
,
det
):
def
output_x86
(
libraries
,
nx
,
h
ashid
,
outf
,
det
):
outf
.
write
(
'; vim: set ft=nasm:
\n
'
)
# be friendly
if
nx
:
outf
.
write
(
'%define USE_NX 1
\n
'
)
if
h16
:
outf
.
write
(
'%define USE_HASH16 1
\n
'
)
defff
=
define_for_hash
[
hashid
]
if
defff
is
not
None
:
outf
.
write
(
'%define {} 1
\n
'
.
format
(
defff
))
if
nx
:
outf
.
write
(
'%define USE_NX 1
\n
'
)
hashfn
=
hash_
bsd2
if
h16
else
hash_djb2
hashfn
=
get_
hash_
fn
(
hashid
)
if
det
:
libraries
=
sort_imports
(
libraries
,
hashfn
)
usedrelocs
=
set
({})
...
...
@@ -108,19 +111,22 @@ global {name}
# end output_x86
def
output_amd64
(
libraries
,
nx
,
h
16
,
outf
,
det
):
if
h
16
:
def
output_amd64
(
libraries
,
nx
,
h
ashid
,
outf
,
det
):
if
h
ashid
==
HASH_BSD2
:
error
(
"--hash16 not supported yet for x86_64 outputs."
)
if
nx
:
outf
.
write
(
'%define USE_NX 1
\n
'
)
# if h16: outf.write('%define USE_HASH16 1\n')
hashfn
=
hash_djb2
#hash_bsd2 if h16 else hash_djb2
if
det
:
libraries
=
sort_imports
(
libraries
,
hashfn
)
outf
.
write
(
'; vim: set ft=nasm:
\n
'
)
outf
.
write
(
'bits 64
\n
'
)
defff
=
define_for_hash
[
hashid
]
if
defff
is
not
None
:
outf
.
write
(
'%define {} 1
\n
'
.
format
(
defff
))
if
nx
:
outf
.
write
(
'%define USE_NX 1
\n
'
)
hashfn
=
get_hash_fn
(
hashid
)
if
det
:
libraries
=
sort_imports
(
libraries
,
hashfn
)
shorts
=
{
l
:
l
.
split
(
'.'
,
1
)[
0
].
lower
().
replace
(
'-'
,
'_'
)
for
l
in
libraries
}
outf
.
write
(
'%include "header64.asm"
\n
'
)
...
...
@@ -185,9 +191,9 @@ global {name}
# end output_amd64
def
output
(
arch
,
libraries
,
nx
,
h
16
,
outf
,
det
):
if
arch
==
'i386'
:
output_x86
(
libraries
,
nx
,
h
16
,
outf
,
det
)
elif
arch
==
'x86_64'
:
output_amd64
(
libraries
,
nx
,
h
16
,
outf
,
det
)
def
output
(
arch
,
libraries
,
nx
,
h
ashid
,
outf
,
det
):
if
arch
==
'i386'
:
output_x86
(
libraries
,
nx
,
h
ashid
,
outf
,
det
)
elif
arch
==
'x86_64'
:
output_amd64
(
libraries
,
nx
,
h
ashid
,
outf
,
det
)
else
:
error
(
"E: cannot emit for arch '"
+
str
(
arch
)
+
"'"
)
smol/shared.py
View file @
6613bab2
...
...
@@ -7,6 +7,16 @@ archmagic = {
'x86_64'
:
62
,
62
:
'x86_64'
,
}
HASH_DJB2
=
0
HASH_BSD2
=
1
HASH_CRC32C
=
2
define_for_hash
=
{
HASH_DJB2
:
None
HASH_BSD2
:
'USE_HASH16'
,
HASH_CRC32C
:
'USE_CRC32C_HASH'
}
def
hash_bsd2
(
s
):
h
=
0
for
c
in
s
:
...
...
@@ -19,6 +29,24 @@ def hash_djb2(s):
h
=
(
h
*
33
+
ord
(
c
))
&
0xFFFFFFFF
return
h
def
hash_crc32c
(
s
):
# crc32 implementation is basically:
# sum = -1; for (; *s; ++s) crc32_instr(&sum, *s); return sum
assert
False
,
"not implemented!"
# TODO
def
get_hash_id
(
h16
,
c32
):
if
not
h16
and
not
c32
:
return
HASH_DJB2
elif
h16
and
not
c32
:
return
HASH_BSD2
elif
not
h16
and
c32
:
return
HASH_CRC32C
else
:
return
False
,
"??????? (shouldn't happen)"
def
get_hash_fn
(
hid
):
return
(
hash_djb2
,
hash_bsd2
,
hash_crc32c
)[
hid
]
def
eprintf
(
*
args
,
**
kwargs
):
print
(
*
args
,
file
=
sys
.
stderr
,
**
kwargs
)
def
error
(
*
args
,
**
kwargs
):
...
...
smold.py
View file @
6613bab2
...
...
@@ -24,8 +24,11 @@ def main():
help
=
"directories to search libraries in"
)
parser
.
add_argument
(
'-s'
,
'--hash16'
,
default
=
False
,
action
=
'store_true'
,
\
help
=
"Use 16-bit (BSD) hashes instead of 32-bit djb2 hashes. "
+
\
"Implies -fuse-dnload-loader"
)
help
=
"Use 16-bit (BSD2) hashes instead of 32-bit djb2 hashes. "
+
\
"Implies -fuse-dnload-loader. Only usable for 32-bit output."
)
parser
.
add_argument
(
'-c'
,
'--crc32c'
,
default
=
False
,
action
=
'store_true'
,
\
help
=
"Use Intel's crc32 intrinsic for hashing. "
+
\
"Implies -fuse-dnload-loader. Conflicts with `--hash16'."
)
parser
.
add_argument
(
'-n'
,
'--nx'
,
default
=
False
,
action
=
'store_true'
,
\
help
=
"Use NX (i.e. don't use RWE pages). Costs the size of one phdr, "
+
\
"plus some extra bytes on i386."
)
...
...
@@ -105,7 +108,10 @@ def main():
args
=
parser
.
parse_args
()
if
args
.
hash16
:
if
args
.
hash16
and
args
.
crc32c
:
error
(
"Cannot combine --hash16 and --crc32c!"
)
if
args
.
hash16
or
args
.
crc32c
:
args
.
fuse_dnload_loader
=
True
if
args
.
fskip_zero_value
:
args
.
asflags
.
insert
(
0
,
"-DSKIP_ZERO_VALUE"
)
...
...
@@ -130,6 +136,9 @@ def main():
error
(
"Unknown/unsupported architecture '"
+
str
(
arch
)
+
"'"
)
if
args
.
verbose
:
eprintf
(
"arch: %s"
%
arch
)
if
args
.
hash16
and
arch
not
in
(
'i386'
,
3
):
error
(
"Cannot use --hash16 for arch `%s' (not i386)"
%
(
arch
))
objinput
=
None
objinputistemp
=
False
tmp_asm_file
=
tempfile
.
mkstemp
(
prefix
=
'smoltab'
,
suffix
=
'.asm'
,
text
=
True
)
...
...
@@ -162,7 +171,7 @@ def main():
symbols
[
library
].
append
((
symbol
,
reloc
))
with
os
.
fdopen
(
tmp_asm_fd
,
mode
=
'w'
)
as
taf
:
output
(
arch
,
symbols
,
args
.
nx
,
args
.
hash16
,
taf
,
args
.
det
)
output
(
arch
,
symbols
,
args
.
nx
,
get_hash_id
(
args
.
hash16
,
args
.
crc32c
)
,
taf
,
args
.
det
)
if
args
.
verbose
:
eprintf
(
"wrote symtab to %s"
%
tmp_asm_file
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment