mirror of
https://github.com/mirror/tinycc.git
synced 2024-12-28 04:00:06 +08:00
Add dwarf clang support
This if for clang (pre)release 15.0.0. tccrun.c: - update directory/filename read. clang has extra md5 section - start with filename 0 instead of 1. clang starts at 0 - change dwarf_read_32/dwarf_read_64 into macros x86_64-link.c: - Add support for R_X86_64_DTPOFF64/R_X86_64_TPOFF64. Needed by clang tests/tcctest.c: - add prototypes for puts/alloca. clang fails with error - disable other_constraints_test for clang. clang prints 1 instead of 0
This commit is contained in:
parent
18808e325f
commit
499cf2305b
124
tccrun.c
124
tccrun.c
@ -634,33 +634,24 @@ dwarf_read_sleb128(unsigned char **ln, unsigned char *end)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static unsigned int dwarf_read_32(unsigned char **ln, unsigned char *end)
|
||||
{
|
||||
unsigned char *cp = *ln;
|
||||
unsigned int retval = 0;
|
||||
|
||||
if ((cp + 4) < end) {
|
||||
retval = read32le(cp);
|
||||
cp += 4;
|
||||
}
|
||||
*ln = cp;
|
||||
return retval;
|
||||
}
|
||||
|
||||
#if PTR_SIZE == 8
|
||||
static unsigned long long dwarf_read_64(unsigned char **ln, unsigned char *end)
|
||||
{
|
||||
unsigned char *cp = *ln;
|
||||
unsigned long long retval = 0;
|
||||
|
||||
if ((cp + 8) < end) {
|
||||
retval = read64le(cp);
|
||||
cp += 8;
|
||||
}
|
||||
*ln = cp;
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
#define dwarf_read_1(ln,end) \
|
||||
DW_GETC((ln), (end))
|
||||
#define dwarf_read_2(ln,end) \
|
||||
((ln) + 2 < (end) ? (ln) += 2, read16le((ln) - 2) : 0)
|
||||
#define dwarf_read_4(ln,end) \
|
||||
((ln) + 4 < (end) ? (ln) += 4, read32le((ln) - 4) : 0)
|
||||
#define dwarf_read_8(ln,end) \
|
||||
((ln) + 8 < (end) ? (ln) += 8, read64le((ln) - 8) : 0)
|
||||
#define dwarf_ignore_type(ln, end) /* timestamp/size/md5/... */ \
|
||||
switch (entry_format[j].form) { \
|
||||
case DW_FORM_data1: (ln) += 1; break; \
|
||||
case DW_FORM_data2: (ln) += 2; break; \
|
||||
case DW_FORM_data4: (ln) += 3; break; \
|
||||
case DW_FORM_data8: (ln) += 8; break; \
|
||||
case DW_FORM_data16: (ln) += 16; break; \
|
||||
case DW_FORM_udata: dwarf_read_uleb128(&(ln), (end)); break; \
|
||||
default: goto next_line; \
|
||||
}
|
||||
|
||||
static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc,
|
||||
const char *msg, const char *skip)
|
||||
@ -678,7 +669,13 @@ static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc,
|
||||
unsigned int opindex;
|
||||
unsigned int col;
|
||||
unsigned int i;
|
||||
unsigned int j;
|
||||
unsigned int len;
|
||||
unsigned int value;
|
||||
struct {
|
||||
unsigned int type;
|
||||
unsigned int form;
|
||||
} entry_format[256];
|
||||
unsigned int dir_size;
|
||||
#if 0
|
||||
char *dirs[DIR_TABLE_SIZE];
|
||||
@ -707,7 +704,7 @@ next:
|
||||
line = 1;
|
||||
filename = NULL;
|
||||
function = NULL;
|
||||
size = dwarf_read_32(&ln, rc->dwarf_line_end);
|
||||
size = dwarf_read_4(ln, rc->dwarf_line_end);
|
||||
end = ln + size;
|
||||
version = DW_GETC(ln, end);
|
||||
version += DW_GETC(ln, end) << 8;
|
||||
@ -729,29 +726,58 @@ next:
|
||||
ln += 12;
|
||||
if (version >= 5) {
|
||||
col = DW_GETC(ln, end);
|
||||
for (i = 0; i < col * 2; i++)
|
||||
dwarf_read_uleb128(&ln, end);
|
||||
for (i = 0; i < col; i++) {
|
||||
entry_format[i].type = dwarf_read_uleb128(&ln, end);
|
||||
entry_format[i].form = dwarf_read_uleb128(&ln, end);
|
||||
}
|
||||
dir_size = dwarf_read_uleb128(&ln, end);
|
||||
for (i = 0; i < dir_size; i++)
|
||||
for (i = 0; i < dir_size; i++) {
|
||||
for (j = 0; j < col; j++) {
|
||||
if (entry_format[j].type == DW_LNCT_path) {
|
||||
if (entry_format[j].form != DW_FORM_line_strp)
|
||||
goto next_line;
|
||||
#if 0
|
||||
if (i < DIR_TABLE_SIZE)
|
||||
dirs[i] = (char *)rc->dwarf_line_str + dwarf_read_32(&ln, end);
|
||||
else
|
||||
value = dwarf_read_4(ln, end);
|
||||
if (i < DIR_TABLE_SIZE)
|
||||
dirs[i] = (char *)rc->dwarf_line_str + value;
|
||||
#else
|
||||
dwarf_read_4(ln, end);
|
||||
#endif
|
||||
dwarf_read_32(&ln, end);
|
||||
}
|
||||
else
|
||||
dwarf_ignore_type(ln, end);
|
||||
}
|
||||
}
|
||||
col = DW_GETC(ln, end);
|
||||
for (i = 0; i < col * 2; i++)
|
||||
dwarf_read_uleb128(&ln, end);
|
||||
for (i = 0; i < col; i++) {
|
||||
entry_format[i].type = dwarf_read_uleb128(&ln, end);
|
||||
entry_format[i].form = dwarf_read_uleb128(&ln, end);
|
||||
}
|
||||
filename_size = dwarf_read_uleb128(&ln, end);
|
||||
for (i = 0; i < filename_size; i++)
|
||||
if (i < FILE_TABLE_SIZE) {
|
||||
filename_table[i].name = (char *)rc->dwarf_line_str + dwarf_read_32(&ln, end);
|
||||
filename_table[i].dir_entry = dwarf_read_uleb128(&ln, end);
|
||||
}
|
||||
else {
|
||||
dwarf_read_32(&ln, end);
|
||||
dwarf_read_uleb128(&ln, end);
|
||||
}
|
||||
for (j = 0; j < col; j++) {
|
||||
if (entry_format[j].type == DW_LNCT_path) {
|
||||
if (entry_format[j].form != DW_FORM_line_strp)
|
||||
goto next_line;
|
||||
value = dwarf_read_4(ln, end);
|
||||
if (i < FILE_TABLE_SIZE)
|
||||
filename_table[i].name =
|
||||
(char *)rc->dwarf_line_str + value;
|
||||
}
|
||||
else if (entry_format[j].type == DW_LNCT_directory_index) {
|
||||
switch (entry_format[j].form) {
|
||||
case DW_FORM_data1: value = dwarf_read_1(ln, end); break;
|
||||
case DW_FORM_data2: value = dwarf_read_2(ln, end); break;
|
||||
case DW_FORM_data4: value = dwarf_read_4(ln, end); break;
|
||||
case DW_FORM_udata: value = dwarf_read_uleb128(&ln, end); break;
|
||||
default: goto next_line;
|
||||
}
|
||||
if (i < FILE_TABLE_SIZE)
|
||||
filename_table[i].dir_entry = value;
|
||||
}
|
||||
else
|
||||
dwarf_ignore_type(ln, end);
|
||||
}
|
||||
}
|
||||
else {
|
||||
while ((DW_GETC(ln, end))) {
|
||||
@ -776,8 +802,8 @@ next:
|
||||
dwarf_read_uleb128(&ln, end); // size
|
||||
}
|
||||
}
|
||||
if (filename_size >= 2)
|
||||
filename = filename_table[1].name;
|
||||
if (filename_size >= 1)
|
||||
filename = filename_table[0].name;
|
||||
while (ln < end) {
|
||||
last_pc = pc;
|
||||
switch (DW_GETC(ln, end)) {
|
||||
@ -792,9 +818,9 @@ next:
|
||||
goto next_line;
|
||||
case DW_LNE_set_address:
|
||||
#if PTR_SIZE == 4
|
||||
pc = dwarf_read_32(&cp, end);
|
||||
pc = dwarf_read_4(cp, end);
|
||||
#else
|
||||
pc = dwarf_read_64(&cp, end);
|
||||
pc = dwarf_read_8(cp, end);
|
||||
#endif
|
||||
if (rc->num_callers < 0)
|
||||
pc = rc->dwarf_text; /* dll */
|
||||
|
@ -78,6 +78,9 @@ typedef __SIZE_TYPE__ uintptr_t;
|
||||
#include incname
|
||||
#include stringify(funnyname)
|
||||
|
||||
int puts(const char *s);
|
||||
void *alloca(size_t size);
|
||||
|
||||
int fib(int n);
|
||||
void num(int n);
|
||||
void forward_ref(void);
|
||||
@ -3409,7 +3412,7 @@ void other_constraints_test(void)
|
||||
{
|
||||
unsigned long ret;
|
||||
int var;
|
||||
#ifndef _WIN64
|
||||
#if !defined(_WIN64) && CC_NAME != CC_clang
|
||||
__asm__ volatile ("mov %P1,%0" : "=r" (ret) : "p" (&var));
|
||||
printf ("oc1: %d\n", ret == (unsigned long)&var);
|
||||
#endif
|
||||
|
@ -48,6 +48,8 @@ int code_reloc (int reloc_type)
|
||||
case R_X86_64_TLSLD:
|
||||
case R_X86_64_DTPOFF32:
|
||||
case R_X86_64_TPOFF32:
|
||||
case R_X86_64_DTPOFF64:
|
||||
case R_X86_64_TPOFF64:
|
||||
return 0;
|
||||
|
||||
case R_X86_64_PC32:
|
||||
@ -96,6 +98,8 @@ int gotplt_entry_type (int reloc_type)
|
||||
case R_X86_64_TLSLD:
|
||||
case R_X86_64_DTPOFF32:
|
||||
case R_X86_64_TPOFF32:
|
||||
case R_X86_64_DTPOFF64:
|
||||
case R_X86_64_TPOFF64:
|
||||
case R_X86_64_REX_GOTPCRELX:
|
||||
case R_X86_64_PLT32:
|
||||
case R_X86_64_PLTOFF64:
|
||||
@ -365,6 +369,19 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t
|
||||
add32le(ptr, x);
|
||||
}
|
||||
break;
|
||||
case R_X86_64_DTPOFF64:
|
||||
case R_X86_64_TPOFF64:
|
||||
{
|
||||
ElfW(Sym) *sym;
|
||||
Section *sec;
|
||||
int32_t x;
|
||||
|
||||
sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
|
||||
sec = s1->sections[sym->st_shndx];
|
||||
x = val - sec->sh_addr - sec->data_offset;
|
||||
add64le(ptr, x);
|
||||
}
|
||||
break;
|
||||
case R_X86_64_NONE:
|
||||
break;
|
||||
case R_X86_64_RELATIVE:
|
||||
|
Loading…
Reference in New Issue
Block a user