* [Qemu-devel] [PATCH 1/4] tcg: Add debug_info to JIT ELF image.
2012-03-24 17:47 [Qemu-devel] [PATCH 0/4] GDB Jit interface, v4 Richard Henderson
@ 2012-03-24 17:47 ` Richard Henderson
2012-03-24 17:47 ` [Qemu-devel] [PATCH 2/4] tcg: Allow ELF_HOST_FLAGS and ELF_OSABI overrides in gdb-jit Richard Henderson
` (3 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Richard Henderson @ 2012-03-24 17:47 UTC (permalink / raw)
To: qemu-devel; +Cc: blauwirbel
This allows us to actually supply a function name in softmmu builds;
gdb doesn't pick up the minimal symbol table otherwise. Also add a
bit of documentation and statically generate more of the ELF image.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
tcg/tcg.c | 233 +++++++++++++++++++++++++++++++++++++++++--------------------
1 files changed, 158 insertions(+), 75 deletions(-)
diff --git a/tcg/tcg.c b/tcg/tcg.c
index eb595ce..df4edc0 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2252,8 +2252,17 @@ void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
#endif
#ifdef ELF_HOST_MACHINE
-/* The backend should define ELF_HOST_MACHINE to indicate both what value to
- put into the ELF image and to indicate support for the feature. */
+/* In order to use this feature, the backend needs to do three things:
+
+ (1) Define ELF_HOST_MACHINE to indicate both what value to
+ put into the ELF image and to indicate support for the feature.
+
+ (2) Define tcg_register_jit. This should create a buffer containing
+ the contents of a .debug_frame section that describes the post-
+ prologue unwind info for the tcg machine.
+
+ (3) Call tcg_register_jit_int, with the constructed .debug_frame.
+*/
/* Begin GDB interface. THE FOLLOWING MUST MATCH GDB DOCS. */
typedef enum {
@@ -2300,96 +2309,169 @@ static int find_string(const char *strtab, const char *str)
}
}
-static void tcg_register_jit_int(void *buf, size_t buf_size,
+static void tcg_register_jit_int(void *buf_ptr, size_t buf_size,
void *debug_frame, size_t debug_frame_size)
{
- static const char strings[64] =
- "\0"
- ".text\0"
- ".debug_frame\0"
- ".symtab\0"
- ".strtab\0"
- "code_gen_buffer";
+ struct __attribute__((packed)) DebugInfo {
+ uint32_t len;
+ uint16_t version;
+ uint32_t abbrev;
+ uint8_t ptr_size;
+ uint8_t cu_die;
+ uint16_t cu_lang;
+ uintptr_t cu_low_pc;
+ uintptr_t cu_high_pc;
+ uint8_t fn_die;
+ char fn_name[16];
+ uintptr_t fn_low_pc;
+ uintptr_t fn_high_pc;
+ uint8_t cu_eoc;
+ };
struct ElfImage {
ElfW(Ehdr) ehdr;
ElfW(Phdr) phdr;
- ElfW(Shdr) shdr[5];
- ElfW(Sym) sym[1];
- char str[64];
+ ElfW(Shdr) shdr[7];
+ ElfW(Sym) sym[2];
+ struct DebugInfo di;
+ uint8_t da[24];
+ char str[80];
+ };
+
+ struct ElfImage *img;
+
+ static const struct ElfImage img_template = {
+ .ehdr = {
+ .e_ident[EI_MAG0] = ELFMAG0,
+ .e_ident[EI_MAG1] = ELFMAG1,
+ .e_ident[EI_MAG2] = ELFMAG2,
+ .e_ident[EI_MAG3] = ELFMAG3,
+ .e_ident[EI_CLASS] = ELF_CLASS,
+ .e_ident[EI_DATA] = ELF_DATA,
+ .e_ident[EI_VERSION] = EV_CURRENT,
+ .e_type = ET_EXEC,
+ .e_machine = ELF_HOST_MACHINE,
+ .e_version = EV_CURRENT,
+ .e_phoff = offsetof(struct ElfImage, phdr),
+ .e_shoff = offsetof(struct ElfImage, shdr),
+ .e_ehsize = sizeof(ElfW(Shdr)),
+ .e_phentsize = sizeof(ElfW(Phdr)),
+ .e_phnum = 1,
+ .e_shentsize = sizeof(ElfW(Shdr)),
+ .e_shnum = ARRAY_SIZE(img->shdr),
+ .e_shstrndx = ARRAY_SIZE(img->shdr) - 1,
+ },
+ .phdr = {
+ .p_type = PT_LOAD,
+ .p_flags = PF_X,
+ },
+ .shdr = {
+ [0] = { .sh_type = SHT_NULL },
+ /* Trick: The contents of code_gen_buffer are not present in
+ this fake ELF file; that got allocated elsewhere. Therefore
+ we mark .text as SHT_NOBITS (similar to .bss) so that readers
+ will not look for contents. We can record any address. */
+ [1] = { /* .text */
+ .sh_type = SHT_NOBITS,
+ .sh_flags = SHF_EXECINSTR | SHF_ALLOC,
+ },
+ [2] = { /* .debug_info */
+ .sh_type = SHT_PROGBITS,
+ .sh_offset = offsetof(struct ElfImage, di),
+ .sh_size = sizeof(struct DebugInfo),
+ },
+ [3] = { /* .debug_abbrev */
+ .sh_type = SHT_PROGBITS,
+ .sh_offset = offsetof(struct ElfImage, da),
+ .sh_size = sizeof(img->da),
+ },
+ [4] = { /* .debug_frame */
+ .sh_type = SHT_PROGBITS,
+ .sh_offset = sizeof(struct ElfImage),
+ },
+ [5] = { /* .symtab */
+ .sh_type = SHT_SYMTAB,
+ .sh_offset = offsetof(struct ElfImage, sym),
+ .sh_size = sizeof(img->sym),
+ .sh_info = 1,
+ .sh_link = ARRAY_SIZE(img->shdr) - 1,
+ .sh_entsize = sizeof(ElfW(Sym)),
+ },
+ [6] = { /* .strtab */
+ .sh_type = SHT_STRTAB,
+ .sh_offset = offsetof(struct ElfImage, str),
+ .sh_size = sizeof(img->str),
+ }
+ },
+ .sym = {
+ [1] = { /* code_gen_buffer */
+ .st_info = ELF_ST_INFO(STB_GLOBAL, STT_FUNC),
+ .st_shndx = 1,
+ }
+ },
+ .di = {
+ .len = sizeof(struct DebugInfo) - 4,
+ .version = 2,
+ .ptr_size = sizeof(void *),
+ .cu_die = 1,
+ .cu_lang = 0x8001, /* DW_LANG_Mips_Assembler */
+ .fn_die = 2,
+ .fn_name = "code_gen_buffer"
+ },
+ .da = {
+ 1, /* abbrev number (the cu) */
+ 0x11, 1, /* DW_TAG_compile_unit, has children */
+ 0x13, 0x5, /* DW_AT_language, DW_FORM_data2 */
+ 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */
+ 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */
+ 0, 0, /* end of abbrev */
+ 2, /* abbrev number (the fn) */
+ 0x2e, 0, /* DW_TAG_subprogram, no children */
+ 0x3, 0x8, /* DW_AT_name, DW_FORM_string */
+ 0x11, 0x1, /* DW_AT_low_pc, DW_FORM_addr */
+ 0x12, 0x1, /* DW_AT_high_pc, DW_FORM_addr */
+ 0, 0, /* end of abbrev */
+ 0 /* no more abbrev */
+ },
+ .str = "\0" ".text\0" ".debug_info\0" ".debug_abbrev\0"
+ ".debug_frame\0" ".symtab\0" ".strtab\0" "code_gen_buffer",
};
/* We only need a single jit entry; statically allocate it. */
static struct jit_code_entry one_entry;
+ uintptr_t buf = (uintptr_t)buf_ptr;
size_t img_size = sizeof(struct ElfImage) + debug_frame_size;
- struct ElfImage *img = g_malloc0(img_size);
-
- img->ehdr.e_ident[EI_MAG0] = ELFMAG0;
- img->ehdr.e_ident[EI_MAG1] = ELFMAG1;
- img->ehdr.e_ident[EI_MAG2] = ELFMAG2;
- img->ehdr.e_ident[EI_MAG3] = ELFMAG3;
- img->ehdr.e_ident[EI_CLASS] = ELF_CLASS;
- img->ehdr.e_ident[EI_DATA] = ELF_DATA;
- img->ehdr.e_ident[EI_VERSION] = EV_CURRENT;
- img->ehdr.e_type = ET_EXEC;
- img->ehdr.e_machine = ELF_HOST_MACHINE;
- img->ehdr.e_version = EV_CURRENT;
- img->ehdr.e_phoff = offsetof(struct ElfImage, phdr);
- img->ehdr.e_shoff = offsetof(struct ElfImage, shdr);
- img->ehdr.e_ehsize = sizeof(ElfW(Shdr));
- img->ehdr.e_phentsize = sizeof(ElfW(Phdr));
- img->ehdr.e_phnum = 1;
- img->ehdr.e_shentsize = sizeof(img->shdr[0]);
- img->ehdr.e_shnum = ARRAY_SIZE(img->shdr);
- img->ehdr.e_shstrndx = ARRAY_SIZE(img->shdr) - 1;
-
- img->phdr.p_type = PT_LOAD;
- img->phdr.p_offset = (char *)buf - (char *)img;
- img->phdr.p_vaddr = (ElfW(Addr))buf;
- img->phdr.p_paddr = img->phdr.p_vaddr;
- img->phdr.p_filesz = 0;
- img->phdr.p_memsz = buf_size;
- img->phdr.p_flags = PF_X;
- memcpy(img->str, strings, sizeof(img->str));
+ img = g_malloc(img_size);
+ *img = img_template;
+ memcpy(img + 1, debug_frame, debug_frame_size);
- img->shdr[0].sh_type = SHT_NULL;
+ img->phdr.p_vaddr = buf;
+ img->phdr.p_paddr = buf;
+ img->phdr.p_memsz = buf_size;
- /* Trick: The contents of code_gen_buffer are not present in this fake
- ELF file; that got allocated elsewhere, discontiguously. Therefore
- we mark .text as SHT_NOBITS (similar to .bss) so that readers will
- not look for contents. We can record any address at will. */
img->shdr[1].sh_name = find_string(img->str, ".text");
- img->shdr[1].sh_type = SHT_NOBITS;
- img->shdr[1].sh_flags = SHF_EXECINSTR | SHF_ALLOC;
- img->shdr[1].sh_addr = (ElfW(Addr))buf;
+ img->shdr[1].sh_addr = buf;
img->shdr[1].sh_size = buf_size;
- img->shdr[2].sh_name = find_string(img->str, ".debug_frame");
- img->shdr[2].sh_type = SHT_PROGBITS;
- img->shdr[2].sh_offset = sizeof(*img);
- img->shdr[2].sh_size = debug_frame_size;
- memcpy(img + 1, debug_frame, debug_frame_size);
+ img->shdr[2].sh_name = find_string(img->str, ".debug_info");
+ img->shdr[3].sh_name = find_string(img->str, ".debug_abbrev");
+
+ img->shdr[4].sh_name = find_string(img->str, ".debug_frame");
+ img->shdr[4].sh_size = debug_frame_size;
+
+ img->shdr[5].sh_name = find_string(img->str, ".symtab");
+ img->shdr[6].sh_name = find_string(img->str, ".strtab");
+
+ img->sym[1].st_name = find_string(img->str, "code_gen_buffer");
+ img->sym[1].st_value = buf;
+ img->sym[1].st_size = buf_size;
- img->shdr[3].sh_name = find_string(img->str, ".symtab");
- img->shdr[3].sh_type = SHT_SYMTAB;
- img->shdr[3].sh_offset = offsetof(struct ElfImage, sym);
- img->shdr[3].sh_size = sizeof(img->sym);
- img->shdr[3].sh_info = ARRAY_SIZE(img->sym);
- img->shdr[3].sh_link = img->ehdr.e_shstrndx;
- img->shdr[3].sh_entsize = sizeof(ElfW(Sym));
-
- img->shdr[4].sh_name = find_string(img->str, ".strtab");
- img->shdr[4].sh_type = SHT_STRTAB;
- img->shdr[4].sh_offset = offsetof(struct ElfImage, str);
- img->shdr[4].sh_size = sizeof(img->str);
-
- img->sym[0].st_name = find_string(img->str, "code_gen_buffer");
- img->sym[0].st_info = ELF_ST_INFO(STB_GLOBAL, STT_FUNC);
- img->sym[0].st_shndx = 1;
- img->sym[0].st_value = (ElfW(Addr))buf;
- img->sym[0].st_size = buf_size;
+ img->di.cu_low_pc = buf;
+ img->di.cu_high_pc = buf_size;
+ img->di.fn_low_pc = buf;
+ img->di.fn_high_pc = buf_size;
#ifdef DEBUG_JIT
/* Enable this block to be able to debug the ELF image file creation.
@@ -2397,7 +2479,7 @@ static void tcg_register_jit_int(void *buf, size_t buf_size,
{
FILE *f = fopen("/tmp/qemu.jit", "w+b");
if (f) {
- if (fwrite(img, img_size, 1, f) != buf_size) {
+ if (fwrite(img, img_size, 1, f) != img_size) {
/* Avoid stupid unused return value warning for fwrite. */
}
fclose(f);
@@ -2414,7 +2496,8 @@ static void tcg_register_jit_int(void *buf, size_t buf_size,
__jit_debug_register_code();
}
#else
-/* No support for the feature. Provide the entry point expected by exec.c. */
+/* No support for the feature. Provide the entry point expected by exec.c,
+ and implement the internal function we declared earlier. */
static void tcg_register_jit_int(void *buf, size_t size,
void *debug_frame, size_t debug_frame_size)
--
1.7.7.6
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 3/4] tcg-hppa: Add debug_frame support.
2012-03-24 17:47 [Qemu-devel] [PATCH 0/4] GDB Jit interface, v4 Richard Henderson
2012-03-24 17:47 ` [Qemu-devel] [PATCH 1/4] tcg: Add debug_info to JIT ELF image Richard Henderson
2012-03-24 17:47 ` [Qemu-devel] [PATCH 2/4] tcg: Allow ELF_HOST_FLAGS and ELF_OSABI overrides in gdb-jit Richard Henderson
@ 2012-03-24 17:47 ` Richard Henderson
2012-03-24 17:47 ` [Qemu-devel] [PATCH 4/4] tcg-sparc: " Richard Henderson
2012-03-24 18:41 ` [Qemu-devel] [PATCH 0/4] GDB Jit interface, v4 Blue Swirl
4 siblings, 0 replies; 8+ messages in thread
From: Richard Henderson @ 2012-03-24 17:47 UTC (permalink / raw)
To: qemu-devel; +Cc: blauwirbel
---
tcg/hppa/tcg-target.c | 103 +++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 88 insertions(+), 15 deletions(-)
diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c
index e579ef0..2885212 100644
--- a/tcg/hppa/tcg-target.c
+++ b/tcg/hppa/tcg-target.c
@@ -336,7 +336,7 @@ static int tcg_target_const_match(tcg_target_long val,
#define INSN_COMIBF (INSN_OP(0x23))
/* supplied by libgcc */
-extern void *__canonicalize_funcptr_for_compare(void *);
+extern void *__canonicalize_funcptr_for_compare(const void *);
static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
{
@@ -628,7 +628,7 @@ static void tcg_out_bswap32(TCGContext *s, int ret, int arg, int temp)
tcg_out_shd(s, ret, arg, temp, 8); /* ret = DCBA */
}
-static void tcg_out_call(TCGContext *s, void *func)
+static void tcg_out_call(TCGContext *s, const void *func)
{
tcg_target_long val, hi, lo, disp;
@@ -1661,23 +1661,18 @@ static int tcg_target_callee_save_regs[] = {
TCG_REG_R18
};
+#define FRAME_SIZE ((-TCG_TARGET_CALL_STACK_OFFSET \
+ + TCG_TARGET_STATIC_CALL_ARGS_SIZE \
+ + ARRAY_SIZE(tcg_target_callee_save_regs) * 4 \
+ + CPU_TEMP_BUF_NLONGS * sizeof(long) \
+ + TCG_TARGET_STACK_ALIGN - 1) \
+ & -TCG_TARGET_STACK_ALIGN)
+
static void tcg_target_qemu_prologue(TCGContext *s)
{
int frame_size, i;
- /* Allocate space for the fixed frame marker. */
- frame_size = -TCG_TARGET_CALL_STACK_OFFSET;
- frame_size += TCG_TARGET_STATIC_CALL_ARGS_SIZE;
-
- /* Allocate space for the saved registers. */
- frame_size += ARRAY_SIZE(tcg_target_callee_save_regs) * 4;
-
- /* Allocate space for the TCG temps. */
- frame_size += CPU_TEMP_BUF_NLONGS * sizeof(long);
-
- /* Align the allocated space. */
- frame_size = ((frame_size + TCG_TARGET_STACK_ALIGN - 1)
- & -TCG_TARGET_STACK_ALIGN);
+ frame_size = FRAME_SIZE;
/* The return address is stored in the caller's frame. */
tcg_out_st(s, TCG_TYPE_PTR, TCG_REG_RP, TCG_REG_CALL_STACK, -20);
@@ -1752,3 +1747,81 @@ static void tcg_target_init(TCGContext *s)
tcg_add_target_add_op_defs(hppa_op_defs);
}
+
+typedef struct {
+ uint32_t len __attribute__((aligned((sizeof(void *)))));
+ uint32_t id;
+ uint8_t version;
+ char augmentation[1];
+ uint8_t code_align;
+ uint8_t data_align;
+ uint8_t return_column;
+} DebugFrameCIE;
+
+typedef struct {
+ uint32_t len __attribute__((aligned((sizeof(void *)))));
+ uint32_t cie_offset;
+ tcg_target_long func_start __attribute__((packed));
+ tcg_target_long func_len __attribute__((packed));
+ uint8_t def_cfa[4];
+ uint8_t ret_ofs[3];
+ uint8_t reg_ofs[ARRAY_SIZE(tcg_target_callee_save_regs) * 2];
+} DebugFrameFDE;
+
+typedef struct {
+ DebugFrameCIE cie;
+ DebugFrameFDE fde;
+} DebugFrame;
+
+#define ELF_HOST_MACHINE EM_PARISC
+#define ELF_HOST_FLAGS EFA_PARISC_1_1
+
+/* ??? BFD (and thus GDB) wants very much to distinguish between HPUX
+ and other extensions. We don't really care, but if we don't set this
+ to *something* then the object file won't be properly matched. */
+#define ELF_OSABI ELFOSABI_LINUX
+
+static DebugFrame debug_frame = {
+ .cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
+ .cie.id = -1,
+ .cie.version = 1,
+ .cie.code_align = 1,
+ .cie.data_align = 1,
+ .cie.return_column = 2,
+
+ .fde.len = sizeof(DebugFrameFDE)-4, /* length after .len member */
+ .fde.def_cfa = {
+ 0x12, 30, /* DW_CFA_def_cfa_sf sp, ... */
+ (-FRAME_SIZE & 0x7f) | 0x80, /* ... sleb128 -FRAME_SIZE */
+ (-FRAME_SIZE >> 7) & 0x7f
+ },
+ .fde.ret_ofs = {
+ 0x11, 2, (-20 / 4) & 0x7f /* DW_CFA_offset_extended_sf r2, 20 */
+ },
+ .fde.reg_ofs = {
+ /* This must match the ordering in tcg_target_callee_save_regs. */
+ 0x80 + 4, 0, /* DW_CFA_offset r4, 0 */
+ 0x80 + 5, 4, /* DW_CFA_offset r5, 4 */
+ 0x80 + 6, 8, /* DW_CFA_offset r6, 8 */
+ 0x80 + 7, 12, /* ... */
+ 0x80 + 8, 16,
+ 0x80 + 9, 20,
+ 0x80 + 10, 24,
+ 0x80 + 11, 28,
+ 0x80 + 12, 32,
+ 0x80 + 13, 36,
+ 0x80 + 14, 40,
+ 0x80 + 15, 44,
+ 0x80 + 16, 48,
+ 0x80 + 17, 52,
+ 0x80 + 18, 56,
+ }
+};
+
+void tcg_register_jit(void *buf, size_t buf_size)
+{
+ debug_frame.fde.func_start = (tcg_target_long) buf;
+ debug_frame.fde.func_len = buf_size;
+
+ tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
+}
--
1.7.7.6
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 4/4] tcg-sparc: Add debug_frame support.
2012-03-24 17:47 [Qemu-devel] [PATCH 0/4] GDB Jit interface, v4 Richard Henderson
` (2 preceding siblings ...)
2012-03-24 17:47 ` [Qemu-devel] [PATCH 3/4] tcg-hppa: Add debug_frame support Richard Henderson
@ 2012-03-24 17:47 ` Richard Henderson
2012-03-24 18:41 ` [Qemu-devel] [PATCH 0/4] GDB Jit interface, v4 Blue Swirl
4 siblings, 0 replies; 8+ messages in thread
From: Richard Henderson @ 2012-03-24 17:47 UTC (permalink / raw)
To: qemu-devel; +Cc: blauwirbel
---
elf.h | 15 +++++++++++
tcg/sparc/tcg-target.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 78 insertions(+), 0 deletions(-)
diff --git a/elf.h b/elf.h
index 310e05a..36bcac4 100644
--- a/elf.h
+++ b/elf.h
@@ -346,6 +346,21 @@ typedef struct {
#define R_MIPS_HIVENDOR 127
+/* SUN SPARC specific definitions. */
+
+/* Values for Elf64_Ehdr.e_flags. */
+
+#define EF_SPARCV9_MM 3
+#define EF_SPARCV9_TSO 0
+#define EF_SPARCV9_PSO 1
+#define EF_SPARCV9_RMO 2
+#define EF_SPARC_LEDATA 0x800000 /* little endian data */
+#define EF_SPARC_EXT_MASK 0xFFFF00
+#define EF_SPARC_32PLUS 0x000100 /* generic V8+ features */
+#define EF_SPARC_SUN_US1 0x000200 /* Sun UltraSPARC1 extensions */
+#define EF_SPARC_HAL_R1 0x000400 /* HAL R1 extensions */
+#define EF_SPARC_SUN_US3 0x000800 /* Sun UltraSPARCIII extensions */
+
/*
* Sparc ELF relocation types
*/
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 491c979..247a278 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -1624,3 +1624,66 @@ static void tcg_target_init(TCGContext *s)
tcg_regset_set_reg(s->reserved_regs, TCG_REG_O7);
tcg_add_target_add_op_defs(sparc_op_defs);
}
+
+#if TCG_TARGET_REG_BITS == 64
+# define ELF_HOST_MACHINE EM_SPARCV9
+#elif defined(__sparc_v8plus__)
+# define ELF_HOST_MACHINE EM_SPARC32PLUS
+# define ELF_HOST_FLAGS EF_SPARC_32PLUS
+#else
+# define ELF_HOST_MACHINE EM_SPARC
+#endif
+
+typedef struct {
+ uint32_t len __attribute__((aligned((sizeof(void *)))));
+ uint32_t id;
+ uint8_t version;
+ char augmentation[1];
+ uint8_t code_align;
+ uint8_t data_align;
+ uint8_t return_column;
+} DebugFrameCIE;
+
+typedef struct {
+ uint32_t len __attribute__((aligned((sizeof(void *)))));
+ uint32_t cie_offset;
+ tcg_target_long func_start __attribute__((packed));
+ tcg_target_long func_len __attribute__((packed));
+ uint8_t def_cfa[TCG_TARGET_REG_BITS == 64 ? 4 : 2];
+ uint8_t win_save;
+ uint8_t ret_save[3];
+} DebugFrameFDE;
+
+typedef struct {
+ DebugFrameCIE cie;
+ DebugFrameFDE fde;
+} DebugFrame;
+
+static DebugFrame debug_frame = {
+ .cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
+ .cie.id = -1,
+ .cie.version = 1,
+ .cie.code_align = 1,
+ .cie.data_align = -sizeof(void *) & 0x7f,
+ .cie.return_column = 15, /* o7 */
+
+ .fde.len = sizeof(DebugFrameFDE)-4, /* length after .len member */
+ .fde.def_cfa = {
+#if TCG_TARGET_REG_BITS == 64
+ 12, 30, /* DW_CFA_def_cfa i6, 2047 */
+ (2047 & 0x7f) | 0x80, (2047 >> 7)
+#else
+ 13, 30 /* DW_CFA_def_cfa_register i6 */
+#endif
+ },
+ .fde.win_save = 0x2d, /* DW_CFA_GNU_window_save */
+ .fde.ret_save = { 9, 15, 31 }, /* DW_CFA_register o7, i7 */
+};
+
+void tcg_register_jit(void *buf, size_t buf_size)
+{
+ debug_frame.fde.func_start = (tcg_target_long) buf;
+ debug_frame.fde.func_len = buf_size;
+
+ tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
+}
--
1.7.7.6
^ permalink raw reply related [flat|nested] 8+ messages in thread