This requires adding .eh_frame and .eh_frame_hdr sections.
There are 3 new functions to setup the sections:
tcc_eh_frame_start: create cie in .eh_frame
tcc_debug_frame_end: add fde in .eh_frame for every function
tcc_eh_frame_hdr: create .eh_frame_hdr
The PT_GNU_EH_FRAME header is created.
The dwarf read functions are moved from tccrun.c to tcc.h
The backtrace() function is not supported on all targets.
windows, apple, bsd and arm are disabled.
arm uses its own sections .ARM.extab and .ARM.exidx.
endbr64 has no operand but comes with a ModR/M byte. Handle it in the
same way as *fence instructions.
Co-authored-by: Yao Zi <ziyao@disroot.org>
Signed-off-by: Yao Zi <ziyao@disroot.org>
Signed-off-by: John Nunley <dev@notgull.net>
It has the same effect as call.
Co-authored-by: Yao Zi <ziyao@disroot.org>
Signed-off-by: Yao Zi <ziyao@disroot.org>
Signed-off-by: John Nunley <dev@notgull.net>
We already have sys/unistd.h, but the standard place for it is at
the include root, so make that work too, but keep sys/unistd.h for
backward compatibility.
Since commit 45cff8f0 tcc eventually generates object files
of non-even size.
tccelf.c:
- check ARFMAG for better invalid archive detection
- file_offset needs to be aligned, not the size (just a nitpick)
lib/Makefile:
- remake everything when tcc did change
compiling with tcc and linking with gcc gives error:
tcc -c a.c
gcc a.o
usr/bin/ld: a.o: .symtab local symbol at index 0 (>= sh_info of 0)
/usr/bin/ld: a.o: error adding symbols: bad value
collect2: error: ld returned 1 exit status
Solved by moving call to sort_syms.
Instead of always emitting movabs, emit a regular mov or a xor.
Slims down sequences like:
movabs $0,%rax
mov %rsi,%rax
To:
xor %eax,%eax // also zeroes upper word
mov %rsi,%rax
Future work is to just emit:
xor %esi,%esi
Use `t1` instead of `t0` for the cases when `rr` is not set so `t0` is
used by default and this happens:
lui t0, XXX
add t0, t0, t0
Instead, now we do:
lui t1, XXX
add t0, t0, t1
This commit fixes the case where the register of for the Extended Asm
input or output is known. Before this commit, the following case:
register long __a0 asm ("a0") = one;
asm volatile (
"ecall\n\t"
: "+r" (__a0) // NOTE the +r here
);
Didn't treat `a0` as an input+output register (+ contraint) as the code
skipped the constraint processing when the register was already chosen
(instead of allocated later).
This issue comes from f081acbfba, that was
taken as a reference in every other Extended Assembler implementation.
NOTE: In order to be able to deal with general-purpose vs floating-point
registers, this commit adds a flag in the 6th bit of the register. If
set, it means the register is a floating-point one. This affects all the
assembler.
Before:
ld rd, rs, imm
sd rs1, rs2, imm
Now:
ld rd, imm(rs)
sd rs2, imm(rs1)
NOTES: Just as in GAS:
- In stores the register order is swapped
- imm is optional
- when imm is not included parenthesis can be removed