Skip to content

Commit

Permalink
Merge branch 'junghee/tls-local-exec' into 'main'
Browse files Browse the repository at this point in the history
Fix bug that could result in missed symbolic expressions

Closes rewriting/transforms/gtirb-reachable#8

See merge request rewriting/ddisasm!1226
  • Loading branch information
jdorn-gt committed Nov 5, 2024
2 parents 17396b5 + 4f03edc commit 2d92198
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
sections
* Fix 16-Thumb STM instructions considered to be invalid if the same register
is used in reglist and register operands with writeback enabled.
* Fixed bug that could result in missed symbolic expressions with TLS variables for `local-executable` TLS model

# 1.9.0

Expand Down
9 changes: 9 additions & 0 deletions examples/asm_examples/ex_tls_local_exec/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

all: ex_original.s
gcc -o ex ex_original.s
@./ex > out.txt
clean:
rm -f ex out.txt
check:
@./ex > /tmp/res.txt
@ diff out.txt /tmp/res.txt && echo TEST OK
63 changes: 63 additions & 0 deletions examples/asm_examples/ex_tls_local_exec/ex_original.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@

.section .rodata
.align 8
.LC:
.string "tls_var value: %d\n"

.section .text ,"wa"

.align 16
.globl get_tls_var
.type get_tls_var, @function
get_tls_var:
pushq %rbp
movq %rsp, %rbp
var_tpoff_1:
movq $var@tpoff, %rax
movq %fs:0(%rax),%rax
popq %rbp
ret

.size get_tls_var, .-get_tls_var

.align 16
.globl set_tls_var
.type set_tls_var, @function
set_tls_var:
pushq %rbp
movq %rsp, %rbp
movq %rdi, -8(%rbp)
var_tpoff_2:
movq $var@tpoff, %rax
movq -8(%rbp), %rdx
movq %rdx, %fs:0(%rax)
nop
popq %rbp
ret

.size set_tls_var, .-set_tls_var

.align 16
.globl main
.type main, @function
main:
pushq %rbp
movq %rsp, %rbp
movq $7, %rdi
call set_tls_var@PLT
movq %rax, %rdi
call get_tls_var@PLT
movq %rax, %rsi
leaq .LC(%rip), %rdi
call printf@PLT
movl $0, %eax
popq %rbp
ret

.size main, .-main

.section .tbss ,"wa",@nobits

.align 8
var:
.zero 8
22 changes: 22 additions & 0 deletions src/datalog/binary/elf/tls.dl
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,28 @@ tls_relative_operand(EA,Index,Dest,Type):-
Base = as(@functor_aligned(TlsEnd, max(Align,1)),number),
Dest = as(Base+Offset,address).

// Local Executable (LE) TLS model,
// i.e. mov $var@tpoff, %rax
// mov %fs:0(%rax), %rdx
tls_relative_operand(EA,Index,Dest,Type):-
tls_segment_register(Reg),
(
binary_isa("X64"),
Type = "TPOFF"
;
binary_isa("X86"),
Type = "NTPOFF"
),
const_value_reg_used(IndEA,EA,_,OffReg,Offset),
Offset < 0,
instruction_get_op(IndEA,_,Op),
op_indirect(Op,Reg,OffReg0,"NONE",_,0,_),
reg_map_nullable(OffReg0,OffReg),
arch.move_reg_imm(EA,OffReg,Offset,Index),
tls_segment(_,TlsEnd,Align),
Base = as(@functor_aligned(TlsEnd, max(Align,1)),number),
Dest = as(Base+Offset,address).

// Local Executable (LE) TLS model,
// i.e. mov REG, FS:[0]
// lea REG, [REG + X@TPOFF]
Expand Down
9 changes: 9 additions & 0 deletions tests/linux-elf-x64.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,10 @@ tests:
<<: *assembly
binary: fun.so

- name: ex_tls_local_exec
<<: *assembly
binary: ex

# ----------------------------------------------------------------------------
# Assembly examples. (stripped)
# ----------------------------------------------------------------------------
Expand Down Expand Up @@ -597,6 +601,11 @@ tests:
<<: *test-strip-default
binary: fun.so

- name: ex_tls_local_exec
<<: *assembly
<<: *test-strip-default
binary: ex

# ----------------------------------------------------------------------------
# Relocatable ELF objects (.o).
# ----------------------------------------------------------------------------
Expand Down
39 changes: 39 additions & 0 deletions tests/misc_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from pathlib import Path
from typing import Optional, Tuple
from gtirb.cfg import EdgeType
from gtirb.symbolicexpression import SymbolicExpression
import gtirb
import lief

Expand Down Expand Up @@ -1016,5 +1017,43 @@ def test_zero_entry_point(self):
self.assertEqual(len(list(m.symbols_named("_start"))), 0)


class TLSLocalExecTests(unittest.TestCase):
@unittest.skipUnless(
platform.system() == "Linux", "This test is linux only."
)
def test_tls_local_exec(self):
"""
Test that TLS attributes are correctly generated.
"""

binary = Path("ex")
with cd(ex_asm_dir / "ex_tls_local_exec"):
self.assertTrue(compile("gcc", "g++", "-Os", []))
ir_library = disassemble(binary).ir()
m = ir_library.modules[0]

for sym_name in ["var_tpoff_1", "var_tpoff_2"]:
sym = next(m.symbols_named(sym_name))
self.assertIsInstance(sym.referent, gtirb.CodeBlock)

block = sym.referent
bi = block.byte_interval
# Get the sym-expr for the first instruction of size 7:
# movq var@tpoff, %rax
sexpr = set(
bi.symbolic_expressions_at(
range(block.address, block.address + 7)
)
)
self.assertEqual(len(sexpr), 1)
se = next(iter(sexpr))[2]
self.assertIsInstance(se, gtirb.SymAddrConst)
self.assertEqual(se.symbol.name, "var")
self.assertEqual(se.offset, 0)
self.assertEqual(
se.attributes, {SymbolicExpression.Attribute.TPOFF}
)


if __name__ == "__main__":
unittest.main()

0 comments on commit 2d92198

Please sign in to comment.