diff options
| author | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-29 01:20:21 +0100 |
|---|---|---|
| committer | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-29 01:20:21 +0100 |
| commit | 394922bfd2c9182f3268bff664d4c46a1a6590f7 (patch) | |
| tree | a47bfafc4d2ec8a3b06020ae2570e4837bb6bee6 /binutils_patches/0006-Numerous-changes-and-bug-fixes.patch | |
| download | stm8-binutils-gdb-394922bfd2c9182f3268bff664d4c46a1a6590f7.tar.gz | |
First commit, forked from sourceforge tar
Diffstat (limited to 'binutils_patches/0006-Numerous-changes-and-bug-fixes.patch')
| -rw-r--r-- | binutils_patches/0006-Numerous-changes-and-bug-fixes.patch | 1670 |
1 files changed, 1670 insertions, 0 deletions
diff --git a/binutils_patches/0006-Numerous-changes-and-bug-fixes.patch b/binutils_patches/0006-Numerous-changes-and-bug-fixes.patch new file mode 100644 index 0000000..e27c022 --- /dev/null +++ b/binutils_patches/0006-Numerous-changes-and-bug-fixes.patch @@ -0,0 +1,1670 @@ +From 3447c315a86e833246c70404af4b6f6946751b45 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=85ke=20Rehnman?= <ake_rehnman_at_gmail_com> +Date: Sat, 3 Mar 2018 10:54:22 +0100 +Subject: [PATCH 6/6] Numerous changes and bug fixes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +* Changed bfd address size to 32 bits +* Fixed reversed operands for mov insn in gas +* Removed fp support in gdb and added dwarf register mapping for sdcc +* Changed ld script template +* Fixed reversed operand for mov insn in disassembly + +Signed-off-by: Åke Rehnman <ake_rehnman_at_gmail_com> +--- + bfd/cpu-stm8.c | 3 +- + gas/config/tc-stm8.c | 34 ++- + gdb/remote.c | 22 +- + gdb/stm8-tdep.c | 535 ++++++++++++++++++++++----------------------- + include/opcode/stm8.h | 2 + + ld/Makefile.in | 2 +- + ld/emulparams/elf32stm8.sh | 3 +- + ld/scripttempl/elfstm8.sc | 232 -------------------- + ld/scripttempl/stm8.sc | 270 +++++++++++++++++++++++ + opcodes/stm8-dis.c | 53 ++++- + opcodes/stm8-opc.c | 9 +- + 11 files changed, 630 insertions(+), 535 deletions(-) + delete mode 100644 ld/scripttempl/elfstm8.sc + create mode 100644 ld/scripttempl/stm8.sc + +diff --git a/bfd/cpu-stm8.c b/bfd/cpu-stm8.c +index feb6cf805e..d858d0fd8e 100644 +--- a/bfd/cpu-stm8.c ++++ b/bfd/cpu-stm8.c +@@ -25,7 +25,8 @@ + const bfd_arch_info_type bfd_stm8_arch = + { + 8, /* bits per word */ +- 24, /* bits per address */ ++ 32, /* bits per address */ ++// 24, /* bits per address */ + 8, /* bits per byte */ + bfd_arch_stm8, /* architecture */ + bfd_mach_stm8, /* machine */ +diff --git a/gas/config/tc-stm8.c b/gas/config/tc-stm8.c +index 1fa4503ce2..38fa50722a 100644 +--- a/gas/config/tc-stm8.c ++++ b/gas/config/tc-stm8.c +@@ -704,7 +704,7 @@ int read_arg(char *str, expressionS *exps) + expression(exps); + if (stm8_debug) + print_expr(exps); +- exps->X_md=OP_OFF_X; ++ exps->X_md=OP_OFF_Y; + return 1; + } + //offset,SP +@@ -775,19 +775,29 @@ static + void stm8_bfd_out(struct stm8_opcodes_s op, expressionS exp[], int count, char *frag) + { + int i; ++ int arg = 0; ++ int dir = 1; ++ ++ /* if count is negative the arguments are reversed */ ++ if (count < 0) ++ { ++ count = -count; ++ arg = count - 1; ++ dir = -1; ++ } + +- for(i = 0; i < count; i++) ++ for(i = 0; i < count; i++, arg += dir) + { + int where = frag - frag_now->fr_literal; + +- if (exp[i].X_op != O_illegal) ++ if (exp[arg].X_op != O_illegal) + { +- switch(op.constraints[i]) ++ switch(op.constraints[arg]) + { + case ST8_EXTMEM: + case ST8_EXTOFF_X: + case ST8_EXTOFF_Y: +- fix_new_exp(frag_now, where, 3, &exp[i], FALSE, BFD_RELOC_24); ++ fix_new_exp(frag_now, where, 3, &exp[arg], FALSE, BFD_RELOC_24); + bfd_put_bits(0xaaaaaaaa, frag, 24, true); + frag+=3; + break; +@@ -799,7 +809,7 @@ void stm8_bfd_out(struct stm8_opcodes_s op, expressionS exp[], int count, char * + case ST8_LONGOFF_X: + case ST8_WORD: + case ST8_LONGMEM: +- fix_new_exp(frag_now, where, 2, &exp[i], FALSE, BFD_RELOC_16); ++ fix_new_exp(frag_now, where, 2, &exp[arg], FALSE, BFD_RELOC_16); + bfd_put_bits(0xaaaaaaaa, frag, 16, true); + frag+=2; + break; +@@ -811,17 +821,17 @@ void stm8_bfd_out(struct stm8_opcodes_s op, expressionS exp[], int count, char * + case ST8_SHORTOFF_SP: + case ST8_BYTE: + case ST8_SHORTMEM: +- fix_new_exp(frag_now, where, 1, &exp[i], FALSE, BFD_RELOC_8); ++ fix_new_exp(frag_now, where, 1, &exp[arg], FALSE, BFD_RELOC_8); + bfd_put_bits(0xaaaaaaaa, frag, 8, true); + frag+=1; + break; + case ST8_PCREL: +- fix_new_exp(frag_now, where, 1, &exp[i], TRUE, BFD_RELOC_8_PCREL); ++ fix_new_exp(frag_now, where, 1, &exp[arg], TRUE, BFD_RELOC_8_PCREL); + bfd_put_bits(0xaaaaaaaa, frag, 8, true); + frag+=1; + break; + case ST8_BIT_0: +- fix_new_exp(frag_now, where-3, 1, &exp[i], FALSE, BFD_RELOC_STM8_BIT_FLD); ++ fix_new_exp(frag_now, where-3, 1, &exp[arg], FALSE, BFD_RELOC_STM8_BIT_FLD); + break; + default: + break; +@@ -986,6 +996,12 @@ md_assemble (char *str) + int opcode_length = stm8_opcode_size(opcode[i].bin_opcode); + bfd_put_bits(opcode[i].bin_opcode, frag, opcode_length * 8, true); + frag += opcode_length; ++ ++ /* mov insn operands are reversed */ ++ if ((opcode[i].bin_opcode == 0x35) || (opcode[i].bin_opcode == 0x45) || (opcode[i].bin_opcode == 0x55)) ++ { ++ count = -count; ++ } + stm8_bfd_out(opcode[i], exps, count, frag); + break; + } +diff --git a/gdb/remote.c b/gdb/remote.c +index 208bf4609b..0fb35a069c 100644 +--- a/gdb/remote.c ++++ b/gdb/remote.c +@@ -9654,6 +9654,15 @@ extended_remote_create_inferior (struct target_ops *ops, + if (extended_remote_supports_disable_randomization (ops)) + extended_remote_disable_randomization (disable_randomization); + ++ //akre ++ if (remote_run_connect) ++ { ++ ops->to_open("localhost:3333", from_tty); ++ if (remote_run_load) ++ generic_load (exec_file, from_tty); ++ init_thread_list (); ++ } ++ + /* If startup-with-shell is on, we inform gdbserver to start the + remote inferior using a shell. */ + if (packet_support (PACKET_QStartupWithShell) != PACKET_DISABLE) +@@ -9672,17 +9681,6 @@ Remote replied unexpectedly while setting startup-with-shell: %s"), + + extended_remote_set_inferior_cwd (rs); + +- //akre +- if (remote_run_connect) +- { +- ops->to_open("localhost:3333", from_tty); +- if (remote_run_load) +- generic_load (exec_file, from_tty); +- init_thread_list (); +- run_worked = 0; +- } +- else +- { + /* Now restart the remote server. */ + run_worked = extended_remote_run (args) != -1; + if (!run_worked) +@@ -9697,7 +9695,7 @@ Remote replied unexpectedly while setting startup-with-shell: %s"), + /* Fall back to "R". */ + extended_remote_restart (); + } +- } ++ + if (!have_inferiors ()) + { + /* Clean up from the last time we ran, before we mark the target +diff --git a/gdb/stm8-tdep.c b/gdb/stm8-tdep.c +index fd4b96c6c0..99276d5cf8 100644 +--- a/gdb/stm8-tdep.c ++++ b/gdb/stm8-tdep.c +@@ -2,7 +2,7 @@ + Written by Ake Rehnman 2017-02-21, + ake.rehnman (at) gmail dot com + +- Copyright (C) 1996-2016 Free Software Foundation, Inc. ++ Copyright (C) 1996-2018 Free Software Foundation, Inc. + + This file is part of GDB. + +@@ -44,19 +44,24 @@ enum stm8_regnum + STM8_Y_REGNUM, + STM8_SP_REGNUM, + STM8_CC_REGNUM, +- //pseudo register +- STM8_FP_REGNUM ++ //pseudo registers ++ STM8_XH_REGNUM, ++ STM8_XL_REGNUM, ++ STM8_YH_REGNUM, ++ STM8_YL_REGNUM, + }; + +-static const char *stm8_register_names[] = ++#define STM8_NUM_PSEUDOREGS 4 ++ ++enum stm8_producer + { +- "pc", "a", "x", "y", "sp", "cc" ++ GCC_PRODUCER, ++ SDCC_PRODUCER + }; + +-struct stm8_soft_reg ++static const char *stm8_register_names[] = + { +- const char *name; +- CORE_ADDR addr; ++ "pc", "a", "x", "y", "sp", "cc" + }; + + unsigned int stm8_debug; +@@ -65,7 +70,13 @@ unsigned int stm8_debug; + + struct gdbarch_tdep + { +- struct stm8_soft_reg fp_reg; ++ enum stm8_producer producer; ++ /* Type for void. */ ++ struct type *void_type; ++ /* Type for a function returning void. */ ++ struct type *func_void_type; ++ /* Type for a pointer to a function. Used for the type of PC. */ ++ struct type *pc_type; + }; + + enum insn_return_kind { +@@ -80,10 +91,19 @@ stm8_convert_register_p (struct gdbarch *gdbarch, int regnum, + { + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + +- if ((regnum == STM8_FP_REGNUM) && (TYPE_LENGTH(type) > 2)) ++ if ((regnum == STM8_SP_REGNUM) && (TYPE_LENGTH(type) > 2)) ++ { ++ return 1; ++ } ++ if ((regnum == STM8_X_REGNUM) && (TYPE_LENGTH(type) > 2)) ++ { ++ return 1; ++ } ++ if ((regnum == STM8_Y_REGNUM) && (TYPE_LENGTH(type) > 2)) + { + return 1; + } ++ + return 0; + } + +@@ -95,60 +115,43 @@ stm8_register_to_value (struct frame_info *frame, int regnum, + struct type *type, gdb_byte *to, + int *optimizedp, int *unavailablep) + { +- struct type *fpreg_type = register_type (get_frame_arch (frame), +- STM8_FP_REGNUM); +- +- /* We only support ptr values. */ +- if ((TYPE_CODE (type) != TYPE_CODE_PTR) && (regnum != STM8_FP_REGNUM) && (TYPE_LENGTH(type) >= TYPE_LENGTH(fpreg_type))) +- { +- warning (_("Conversion failure in stm8_register_to_value: regnum = %d "), regnum); +- *optimizedp = *unavailablep = 0; +- return 0; +- } +- + /* Convert to TYPE. */ + + memset(to,0,TYPE_LENGTH(type)); + +- if (!get_frame_register_bytes (frame, regnum, 0, TYPE_LENGTH (fpreg_type), +- to+TYPE_LENGTH(type)-TYPE_LENGTH(fpreg_type), optimizedp, unavailablep)) ++ if (!get_frame_register_bytes (frame, regnum, 0, 2, ++ to+TYPE_LENGTH(type)-2, optimizedp, unavailablep)) + return 0; + + *optimizedp = *unavailablep = 0; + return 1; + } + +- +-/* Look in the symbol table for the address of a pseudo register +- in memory. If we don't find it, pretend the register is not used +- and not available. */ +-static void +-stm8_get_register_info (struct stm8_soft_reg *reg, const char *name) ++static stm8_producer ++stm8_get_producer() + { +- struct bound_minimal_symbol msymbol; ++ struct objfile *objfile; ++ struct compunit_symtab *cust; + +- msymbol = lookup_minimal_symbol (name, NULL, NULL); +- if (msymbol.minsym) +- { +- reg->addr = BMSYMBOL_VALUE_ADDRESS (msymbol); +- reg->name = xstrdup (name); +- } +- else +- { +- reg->name = 0; +- reg->addr = 0; +- } ++ if (current_program_space != NULL) ++ { ++ ALL_COMPUNITS(objfile, cust) ++ { ++ if (cust ++ && COMPUNIT_PRODUCER (cust) != NULL ++ && startswith (COMPUNIT_PRODUCER (cust), "SDCC")) ++ { ++ return SDCC_PRODUCER; ++ } ++ } ++ } ++ return GCC_PRODUCER; + } + + static void + stm8_initialize_soft_register_info(struct gdbarch_tdep *tdep) + { +- stm8_get_register_info(&tdep->fp_reg, "_fp_"); +- if ((tdep->fp_reg.name == 0) && (symfile_objfile)) +- { +- warning (_("No frame soft register found in the symbol table (_fp_).\n" +- "Stack backtrace will not work.\n")); +- } ++ tdep->producer = stm8_get_producer(); + } + + static const char * +@@ -156,8 +159,21 @@ stm8_register_name (struct gdbarch *gdbarch, int regnum) + { + if (regnum >= 0 && regnum < STM8_NUM_REGS) + return stm8_register_names[regnum]; +- if (regnum == STM8_FP_REGNUM) +- return "fp"; ++ ++ if (stm8_get_producer() == SDCC_PRODUCER) ++ { ++ switch (regnum) ++ { ++ case STM8_XH_REGNUM : ++ return "xh"; ++ case STM8_XL_REGNUM : ++ return "xl"; ++ case STM8_YH_REGNUM : ++ return "yh"; ++ case STM8_YL_REGNUM : ++ return "yl"; ++ } ++ } + return NULL; + } + +@@ -175,8 +191,6 @@ stm8_register_type (struct gdbarch *gdbarch, int regnum) + case STM8_X_REGNUM: + case STM8_Y_REGNUM: + return builtin_type (gdbarch)->builtin_uint16; +- case STM8_FP_REGNUM: +- return builtin_type (gdbarch)->builtin_uint16; + default: + return builtin_type (gdbarch)->builtin_uint8; + } +@@ -190,17 +204,43 @@ stm8_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + int regsize = 2; ++ gdb_byte tmp[4]; ++ + + switch (regnum) + { +- case STM8_FP_REGNUM: +- /* Fetch a soft register: translate into a memory read. */ +- memset (buf, 0, regsize); +- if (tdep->fp_reg.name) ++ case STM8_XH_REGNUM: ++ status = regcache_raw_read(regcache, STM8_X_REGNUM, tmp); ++ if (status == REG_VALID) + { +- target_read_memory (tdep->fp_reg.addr, buf, 2); ++ buf[0] = tmp[0]; + } +- return REG_VALID; ++ return status; ++ ++ case STM8_XL_REGNUM: ++ status = regcache_raw_read(regcache, STM8_X_REGNUM, tmp); ++ if (status == REG_VALID) ++ { ++ buf[0] = tmp[1]; ++ } ++ return status; ++ ++ case STM8_YH_REGNUM: ++ status = regcache_raw_read(regcache, STM8_Y_REGNUM, tmp); ++ if (status == REG_VALID) ++ { ++ buf[0] = tmp[0]; ++ } ++ return status; ++ ++ case STM8_YL_REGNUM: ++ status = regcache_raw_read(regcache, STM8_Y_REGNUM, tmp); ++ if (status == REG_VALID) ++ { ++ buf[0] = tmp[1]; ++ } ++ return status; ++ + default: + internal_error (__FILE__, __LINE__, _("invalid regnum")); + return REG_UNAVAILABLE; +@@ -215,16 +255,47 @@ stm8_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, + enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + const int regsize = 2; ++ gdb_byte tmp[4]; + + switch (regnum) + { +- case STM8_FP_REGNUM: +- /* Store a soft register: translate into a memory write. */ +- if (tdep->fp_reg.name) ++ ++ case STM8_XH_REGNUM: ++ status = regcache_raw_read(regcache, STM8_X_REGNUM, tmp); ++ if (status == REG_VALID) + { +- target_write_memory (tdep->fp_reg.addr, buf, 2); +- } +- return; ++ tmp[0] = buf[0]; ++ regcache_raw_write (regcache, STM8_X_REGNUM, tmp); ++ } ++ return; ++ ++ case STM8_XL_REGNUM: ++ status = regcache_raw_read(regcache, STM8_X_REGNUM, tmp); ++ if (status == REG_VALID) ++ { ++ tmp[1] = buf[0]; ++ regcache_raw_write (regcache, STM8_X_REGNUM, tmp); ++ } ++ return; ++ ++ case STM8_YH_REGNUM: ++ status = regcache_raw_read(regcache, STM8_Y_REGNUM, tmp); ++ if (status == REG_VALID) ++ { ++ tmp[0] = buf[0]; ++ regcache_raw_write (regcache, STM8_Y_REGNUM, tmp); ++ } ++ return; ++ ++ case STM8_YL_REGNUM: ++ status = regcache_raw_read(regcache, STM8_Y_REGNUM, tmp); ++ if (status == REG_VALID) ++ { ++ tmp[1] = buf[0]; ++ regcache_raw_write (regcache, STM8_Y_REGNUM, tmp); ++ } ++ return; ++ + default: + internal_error (__FILE__, __LINE__, _("invalid regnum")); + return; +@@ -271,7 +342,6 @@ stm8_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, + } + + /* Implement the breakpoint_kind_from_pc gdbarch method. */ +-#if 0 + static int + stm8_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr) + { +@@ -298,23 +368,55 @@ stm8_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size) + return stm8_breakpoint; + } + +-#endif ++static int dwarf2_to_reg_map_sdcc[] = ++{ ++ STM8_A_REGNUM, //a ++ STM8_XL_REGNUM, //xl ++ STM8_XH_REGNUM, //xh ++ STM8_YL_REGNUM, //yl ++ STM8_YH_REGNUM, //yh ++ STM8_CC_REGNUM, //cc ++ STM8_X_REGNUM, //x ++ STM8_Y_REGNUM, //y ++ STM8_SP_REGNUM, //sp ++ STM8_PC_REGNUM, //pc ++ -1 ++}; + +-static int dwarf2_to_reg_map[6] = +-{ 0 /* r0 */, 1 /* r1 */, 2 /* r2 */, 3 /* r3 */, /* 0- 3 */ +- 4 /* r4 */, 5 /* r5 */ ++static int dwarf2_to_reg_map_gcc[] = ++{ STM8_A_REGNUM, //a ++ STM8_X_REGNUM, //x ++ STM8_Y_REGNUM, //y ++ STM8_SP_REGNUM, //sp ++ -1 + }; + + static int + stm8_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int reg) + { +- if (stm8_debug) +- fprintf_unfiltered (gdb_stdlog, "stm8_dwarf2_reg_to_regnum called\n"); +- if (reg >= 0 && reg < sizeof (dwarf2_to_reg_map)) +- return dwarf2_to_reg_map[reg]; +- if (reg == 31) +- return STM8_FP_REGNUM; +- return -1; ++ int ret = -1; ++ ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ++ static int * t; ++ ++ if (stm8_get_producer() == SDCC_PRODUCER) ++ t = dwarf2_to_reg_map_sdcc; ++ else ++ t = dwarf2_to_reg_map_gcc; ++ ++ for (int i = 0; (t[i] > 0) && (i < 32); i++) ++ { ++ if (i == reg) ++ { ++ ret = t[i]; ++ break; ++ } ++ } ++ ++ if ((stm8_debug>1) && (ret>=0)) ++ fprintf_unfiltered (gdb_stdlog, "stm8_dwarf2_reg_to_regnum called reg=%d ret=%d\n",reg,t[reg]); ++ ++ return ret; + } + + static void +@@ -333,7 +435,10 @@ stm8_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) + + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + frame_unwind_register (next_frame, STM8_PC_REGNUM, buf); +- pc = extract_typed_address (buf, builtin_type (gdbarch)->builtin_func_ptr); ++ if (frame_relative_level(next_frame) < 0) ++ pc = extract_typed_address (buf, builtin_type (gdbarch)->builtin_func_ptr); ++ else ++ pc = extract_typed_address (buf, tdep->pc_type); + if (stm8_debug) + fprintf_unfiltered (gdb_stdlog, "stm8_unwind_pc called: pc=%8.8lx\n", (unsigned long)pc); + return pc; +@@ -351,58 +456,6 @@ stm8_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame) + return sp; + } + +-#if 0 +-static struct value * +-stm8_dwarf2_prev_register (struct frame_info *this_frame, +- void **this_cache, int regnum) +-{ +- CORE_ADDR pc; +- +- switch (regnum) +- { +- case STM8_PC_REGNUM: +- pc = frame_unwind_register_unsigned (this_frame, AARCH64_PC_REGNUM); +- return frame_unwind_got_constant (this_frame, regnum, lr); +- +- default: +- internal_error (__FILE__, __LINE__, +- _("Unexpected register %d"), regnum); +- } +-} +- +-static void +-stm8_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum, +- struct dwarf2_frame_state_reg *reg, +- struct frame_info *this_frame) +-{ +- switch (regnum) +- { +- case STM8_PC_REGNUM: +- reg->how = DWARF2_FRAME_REG_FN; +- reg->loc.fn = stm8_dwarf2_prev_register; +- break; +- case STM8_SP_REGNUM: +- reg->how = DWARF2_FRAME_REG_CFA; +- break; +- } +-} +-#endif +- +-/* Assuming THIS_FRAME is a dummy, return the frame ID of that +- dummy frame. The frame ID's base needs to match the TOS value +- saved by save_dummy_frame_tos(), and the PC match the dummy frame's +- breakpoint. */ +- +-static struct frame_id +-stm8_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame) +-{ +- fprintf_unfiltered (gdb_stdlog, "stm8_dummy_id called\n"); +- +- return frame_id_build +- (get_frame_register_signed (this_frame, STM8_SP_REGNUM), +- get_frame_pc (this_frame)); +-} +- + + /* Allocate and initialize a frame cache. */ + +@@ -471,7 +524,6 @@ stm8_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, + + /* Initialize info about frame. */ + cache->framesize = 0; +- cache->fp_regnum = STM8_FP_REGNUM; + cache->frameless_p = 1; + cache->stackadj = 0; + +@@ -505,7 +557,7 @@ stm8_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, + } + + /* Start at beginning of function and analyze until we get to the +- current pc, or the end of the function, whichever is first. */ ++ current pc, or the end of the function, whichever is first. */ + stop = (current_pc < func_end ? current_pc : func_end); + + if (stm8_debug) +@@ -585,6 +637,7 @@ stm8_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc) + + struct symtab_and_line sal; + CORE_ADDR func_start, func_end, ostart_pc; ++ CORE_ADDR post_prologue_pc; + struct stm8_frame_cache cache; + + /* This is the preferred method, find the end of the prologue by +@@ -593,18 +646,23 @@ stm8_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc) + Always analyze the prologue. */ + if (find_pc_partial_function (start_pc, NULL, &func_start, &func_end)) + { +- sal = find_pc_line (func_start, 0); ++ post_prologue_pc = skip_prologue_using_sal (gdbarch, func_start); + +- if (sal.end < func_end +- && start_pc <= sal.end) +- start_pc = sal.end; ++ if (stm8_debug) ++ fprintf_unfiltered (gdb_stdlog, "stm8_skip_prologue: post_prologue_pc=%8.8lx\n", ++ (unsigned long)post_prologue_pc); ++ ++ if (post_prologue_pc != 0) ++ return std::max (start_pc, post_prologue_pc); + } + + ostart_pc = stm8_analyze_prologue (gdbarch, func_start, 0xffffffffUL, + &cache); + + if (stm8_debug) +- fprintf_unfiltered (gdb_stdlog, "stm8_skip_prologue: start_pc=%8.8lx ostart_pc=%8.8lx\n", (unsigned long)start_pc, (unsigned long)ostart_pc); ++ fprintf_unfiltered (gdb_stdlog, "stm8_skip_prologue: start_pc=%8.8lx ostart_pc=%8.8lx func_start=%8.8lx func_end=%8.8lx sal.end=%8.8lx\n", ++ (unsigned long)start_pc, (unsigned long)ostart_pc, ++ (unsigned long)func_start, (unsigned long)func_end, (unsigned long)sal.end); + + if (ostart_pc > start_pc) + return ostart_pc; +@@ -632,7 +690,7 @@ stm8_frame_cache (struct frame_info *next_frame, void **this_cache) + + struct stm8_frame_cache *cache; + struct gdbarch *gdbarch = get_frame_arch (next_frame); +- CORE_ADDR start_pc, current_pc, current_sp, fp; ++ CORE_ADDR start_pc, current_pc, current_sp; + int retsize; + + if (*this_cache) +@@ -655,22 +713,9 @@ stm8_frame_cache (struct frame_info *next_frame, void **this_cache) + stm8_analyze_prologue (gdbarch, start_pc, current_pc, + (struct stm8_frame_cache *) *this_cache); + +- /* get our fp by unwinding it from the next frame +- * if we don't have a fp we use sp instead but if there +- * are arguments on the stack unwinding will be +- * unpredictable. +- */ +- //fp = frame_unwind_register_unsigned (next_frame, cache->fp_regnum); +- fp = get_frame_register_unsigned (next_frame, cache->fp_regnum); +- if (fp == 0) +- { +- cache->base = 0; +- cache->frameless_p = 1; +- //return (struct stm8_frame_cache *) (*this_cache); +- } +- + switch (cache->return_kind) + { ++ default: + case RETURN_RET: + retsize = 2; + break; +@@ -682,61 +727,33 @@ stm8_frame_cache (struct frame_info *next_frame, void **this_cache) + break; + } + +- if (cache->frameless_p) +- { +- cache->base = current_sp + cache->framesize; +- if (cache->return_kind == RETURN_IRET) +- cache->saved_regs[STM8_PC_REGNUM].addr = cache->base + 1 + 6; +- else +- cache->saved_regs[STM8_PC_REGNUM].addr = cache->base + 1; +- trad_frame_set_value (cache->saved_regs, +- STM8_SP_REGNUM, +- cache->base+retsize); +- } ++ cache->base = current_sp; ++ if (cache->return_kind == RETURN_IRET) ++ cache->saved_regs[STM8_PC_REGNUM].addr = cache->base + 1 + 6; + else +- { +- /* fp points to our base */ +- cache->base = fp; +- if (cache->return_kind == RETURN_IRET) +- cache->saved_regs[STM8_PC_REGNUM].addr = cache->base + 1 + 2 + 6; +- else +- cache->saved_regs[STM8_PC_REGNUM].addr = cache->base + 1 + 2; +- cache->saved_regs[STM8_FP_REGNUM].addr = fp + 1; +- trad_frame_set_value (cache->saved_regs, +- STM8_SP_REGNUM, +- cache->base+retsize+2); +- } +- ++ cache->saved_regs[STM8_PC_REGNUM].addr = cache->base + 1; ++ trad_frame_set_value (cache->saved_regs, ++ STM8_SP_REGNUM, ++ cache->base+retsize); + + if (stm8_debug) + { +- fprintf_unfiltered (gdb_stdlog, "stm8_frame_cache: (next_frame=%p) base=%4.4lx curr_pc=%4.4lx curr_sp=%4.4lx fp_regnum=%d fp=%4.4lx framesize=%4.4x stackadj=%4.4x retsize=%d\n", +- next_frame, (unsigned long)cache->base, (unsigned long)current_pc, (unsigned long)current_sp, cache->fp_regnum, (unsigned long)fp, cache->framesize, cache->stackadj, retsize); ++ fprintf_unfiltered (gdb_stdlog, "stm8_frame_cache: (next_frame=%p) base=%4.4lx curr_pc=%4.4lx curr_sp=%4.4lx framesize=%4.4x stackadj=%4.4x retsize=%d\n", ++ next_frame, (unsigned long)cache->base, (unsigned long)current_pc, (unsigned long)current_sp, cache->framesize, cache->stackadj, retsize); + + CORE_ADDR frame_pc; + CORE_ADDR frame_sp; +- CORE_ADDR frame_fp; + frame_pc = value_as_long(trad_frame_get_prev_register (next_frame, cache->saved_regs, STM8_PC_REGNUM)); + frame_sp = value_as_long(trad_frame_get_prev_register (next_frame, cache->saved_regs, STM8_SP_REGNUM)); + +- // this is stupid, trad_frame_get_prev_register can't get a +- // register value unless we have a valid frame id +- // hopefully this will get resolved in the future :) +- if (cache->saved_regs[STM8_FP_REGNUM].addr > 0) +- frame_fp = value_as_long(trad_frame_get_prev_register (next_frame, cache->saved_regs, STM8_FP_REGNUM)); +- else +- frame_fp = fp; +- + frame_pc = frame_pc >> 16; + fprintf_unfiltered (gdb_stdlog, "stm8_frame_cache: (next_frame=%p) pc=%8.8lx *pc=%8.8lx\n", next_frame, (unsigned long)cache->saved_regs[STM8_PC_REGNUM].addr, (unsigned long)frame_pc); + fprintf_unfiltered (gdb_stdlog, "stm8_frame_cache: (next_frame=%p) sp=%8.8lx *sp=%8.8lx\n", next_frame, (unsigned long)cache->saved_regs[STM8_SP_REGNUM].addr, (unsigned long)frame_sp); +- fprintf_unfiltered (gdb_stdlog, "stm8_frame_cache: (next_frame=%p) fp=%8.8lx *fp=%8.8lx\n", next_frame, (unsigned long)cache->saved_regs[STM8_FP_REGNUM].addr, (unsigned long)frame_fp); + } + + return (struct stm8_frame_cache *) (*this_cache); + } + +- + /* Given a GDB frame, determine the address of the calling function's + frame. This will be used to create a new GDB frame struct. */ + static void +@@ -771,22 +788,6 @@ stm8_frame_prev_register (struct frame_info *this_frame, + + value = trad_frame_get_prev_register (this_frame, info->saved_regs, regnum); + +- /* Take into account the STM8 specific call. +- * Different lengths if it is CALL or CALLF */ +- if (regnum == STM8_PC_REGNUM) +- { +- CORE_ADDR pc = value_as_long (value); +- if (info->return_kind == RETURN_RET) +- pc >>= 16; +- else +- pc >>= 8; +- +- release_value (value); +- value_free (value); +- +- value = frame_unwind_got_constant (this_frame, regnum, pc); +- } +- + if (stm8_debug) + fprintf_unfiltered (gdb_stdlog, "stm8_frame_prev_register: regnum(%d)=%8.8lx\n", regnum, (unsigned long)value_as_long(value)); + +@@ -876,53 +877,53 @@ static const struct frame_unwind stm8_frame_unwind = { + default_frame_sniffer + }; + +-static CORE_ADDR +-stm8_frame_base_address (struct frame_info *next_frame, +- void **this_cache) +-{ +- struct stm8_frame_cache *cache = +- stm8_frame_cache (next_frame, this_cache); +- +- if (stm8_debug) +- fprintf_unfiltered (gdb_stdlog, "stm8_frame_base_address: fb=%8.8lx\n", (unsigned long)cache->base); +- +- return cache->base; +-} +- +-static CORE_ADDR +-stm8_frame_args_address (struct frame_info *this_frame, void **this_cache) +-{ +- CORE_ADDR addr; +- struct stm8_frame_cache *info +- = stm8_frame_cache (this_frame, this_cache); +- +- addr = info->base; +- if (info->return_kind == RETURN_IRET) +- addr += 12; //2 bytes fp + 9 bytes regs + 1 +- else if (info->return_kind == RETURN_RETF) +- addr += 6; //2 bytes fp + 3 bytes pc + 1 +- else +- addr += 5; //2 bytes fp + 2 bytes pc + 1 +- +- if (stm8_debug) +- fprintf_unfiltered (gdb_stdlog, "stm8_frame_args_address: addr = %8.8lx\n", (unsigned long)addr); +- +- return addr; +-} +- +-static const struct frame_base stm8_frame_base = +-{ +- &stm8_frame_unwind, +- stm8_frame_base_address, +- stm8_frame_base_address, +- stm8_frame_args_address +-}; +- +-static const struct frame_base * +-stm8_frame_base_sniffer (struct frame_info *this_frame) +-{ +- return &stm8_frame_base; +-} ++//static CORE_ADDR ++//stm8_frame_base_address (struct frame_info *next_frame, ++// void **this_cache) ++//{ ++// struct stm8_frame_cache *cache = ++// stm8_frame_cache (next_frame, this_cache); ++// ++// if (stm8_debug) ++// fprintf_unfiltered (gdb_stdlog, "stm8_frame_base_address: fb=%8.8lx\n", (unsigned long)cache->base); ++// ++// return cache->base; ++//} ++ ++//static CORE_ADDR ++//stm8_frame_args_address (struct frame_info *this_frame, void **this_cache) ++//{ ++// CORE_ADDR addr; ++// struct stm8_frame_cache *info ++// = stm8_frame_cache (this_frame, this_cache); ++// ++// addr = info->base; ++// if (info->return_kind == RETURN_IRET) ++// addr += 12; //2 bytes fp + 9 bytes regs + 1 ++// else if (info->return_kind == RETURN_RETF) ++// addr += 6; //2 bytes fp + 3 bytes pc + 1 ++// else ++// addr += 5; //2 bytes fp + 2 bytes pc + 1 ++// ++// if (stm8_debug) ++// fprintf_unfiltered (gdb_stdlog, "stm8_frame_args_address: addr = %8.8lx\n", (unsigned long)addr); ++// ++// return addr; ++//} ++ ++//static const struct frame_base stm8_frame_base = ++//{ ++// &stm8_frame_unwind, ++// stm8_frame_base_address, ++// stm8_frame_base_address, ++// stm8_frame_args_address ++//}; ++// ++//static const struct frame_base * ++//stm8_frame_base_sniffer (struct frame_info *this_frame) ++//{ ++// return &stm8_frame_base; ++//} + + struct target_desc *tdesc_stm8; + static void +@@ -937,7 +938,7 @@ initialize_tdesc_stm8 (void) + tdesc_create_reg (feature, "x", 2, 1, "general", 16, "uint16"); + tdesc_create_reg (feature, "y", 3, 1, "general", 16, "uint16"); + tdesc_create_reg (feature, "sp", 4, 1, "general", 16, "uint16"); +- tdesc_create_reg (feature, "cc", 5, 1, "general", 8, "uint16"); ++ tdesc_create_reg (feature, "cc", 5, 1, "general", 8, "uint8"); + + tdesc_stm8 = result; + } +@@ -952,7 +953,7 @@ stm8_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + struct gdbarch_tdep *tdep; + struct gdbarch_list *best_arch; + struct tdesc_arch_data *tdesc_data = NULL; +- const struct target_desc *tdesc = info.target_desc; ++ const struct target_desc *tdesc = info.target_desc = 0; //override target desc if any + + /* If there is already a candidate, use it. */ + arches = gdbarch_list_lookup_by_info (arches, &info); +@@ -965,9 +966,6 @@ stm8_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + if (tdesc == NULL) + tdesc = tdesc_stm8; + +- //override target registers... /ARE +- tdesc = tdesc_stm8; +- + /* Check any target description for validity. */ + if (tdesc_has_registers (tdesc)) + { +@@ -1005,7 +1003,7 @@ stm8_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + set_tdesc_pseudo_register_type (gdbarch, stm8_register_type); + set_tdesc_pseudo_register_name (gdbarch, stm8_register_name); + +- set_gdbarch_num_pseudo_regs (gdbarch, 1); ++ set_gdbarch_num_pseudo_regs (gdbarch, STM8_NUM_PSEUDOREGS); + set_gdbarch_pseudo_register_read (gdbarch, stm8_pseudo_register_read); + set_gdbarch_pseudo_register_write (gdbarch, stm8_pseudo_register_write); + +@@ -1033,10 +1031,9 @@ stm8_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + /* Stack grows downward. */ + set_gdbarch_inner_than (gdbarch, core_addr_lessthan); + +-#if 0 + set_gdbarch_breakpoint_kind_from_pc (gdbarch, stm8_breakpoint_kind_from_pc); + set_gdbarch_sw_breakpoint_from_kind (gdbarch, stm8_sw_breakpoint_from_kind); +-#endif ++ + set_gdbarch_breakpoint_from_pc (gdbarch, stm8_breakpoint_from_pc); + + //set_gdbarch_frame_args_skip (gdbarch, 8); +@@ -1047,9 +1044,9 @@ stm8_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + + set_gdbarch_unwind_pc (gdbarch, stm8_unwind_pc); + set_gdbarch_unwind_sp (gdbarch, stm8_unwind_sp); +- set_gdbarch_dummy_id (gdbarch, stm8_dummy_id); ++ ////set_gdbarch_dummy_id (gdbarch, stm8_dummy_id); + +- frame_base_set_default (gdbarch, &stm8_frame_base); ++ ////frame_base_set_default (gdbarch, &stm8_frame_base); + + /* Hook in ABI-specific overrides, if they have been registered. */ + //gdbarch_init_osabi (info, gdbarch); +@@ -1060,14 +1057,16 @@ stm8_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + dwarf2_append_unwinders (gdbarch); + frame_unwind_append_unwinder (gdbarch, &stm8_frame_unwind); + frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer); +- frame_base_append_sniffer (gdbarch, stm8_frame_base_sniffer); ++ ////frame_base_append_sniffer (gdbarch, stm8_frame_base_sniffer); + + // /* Create a type for PC. We can't use builtin types here, as they may not + // be defined. */ +-// tdep->void_type = arch_type (gdbarch, TYPE_CODE_VOID, 1, "void"); +-// tdep->func_void_type = make_function_type (tdep->void_type, NULL); +-// tdep->pc_type = arch_pointer_type (gdbarch, 4 * TARGET_CHAR_BIT, NULL, +-// tdep->func_void_type); ++ tdep->void_type = arch_type (gdbarch, TYPE_CODE_VOID, TARGET_CHAR_BIT, "void"); ++ tdep->func_void_type = make_function_type (tdep->void_type, NULL); ++ tdep->pc_type = arch_type (gdbarch, TYPE_CODE_PTR, 2*TARGET_CHAR_BIT, NULL); ++ TYPE_TARGET_TYPE (tdep->pc_type) = tdep->func_void_type; ++ TYPE_UNSIGNED (tdep->pc_type) = 1; ++ + // + // set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT); + // set_gdbarch_int_bit (gdbarch, 2 * TARGET_CHAR_BIT); +@@ -1089,9 +1088,9 @@ stm8_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + // + // set_gdbarch_dwarf2_reg_to_regnum (gdbarch, stm8_dwarf_reg_to_regnum); + // +-// set_gdbarch_address_to_pointer (gdbarch, avr_address_to_pointer); +-// set_gdbarch_pointer_to_address (gdbarch, avr_pointer_to_address); +-// set_gdbarch_integer_to_address (gdbarch, avr_integer_to_address); ++// set_gdbarch_address_to_pointer (gdbarch, stm8_address_to_pointer); ++// set_gdbarch_pointer_to_address (gdbarch, stm8_pointer_to_address); ++// set_gdbarch_integer_to_address (gdbarch, stm8_integer_to_address); + // + // frame_base_set_default (gdbarch, &stm8_frame_base); + // +diff --git a/include/opcode/stm8.h b/include/opcode/stm8.h +index a40ff0aaaa..d131527d86 100644 +--- a/include/opcode/stm8.h ++++ b/include/opcode/stm8.h +@@ -79,4 +79,6 @@ extern int stm8_compute_insn_size(struct stm8_opcodes_s opcode); + + extern unsigned int stm8_opcode_size(unsigned int number); + ++int stm8_num_opcode_operands(struct stm8_opcodes_s opcode); ++ + #endif /* _STM8_H_ */ +diff --git a/ld/Makefile.in b/ld/Makefile.in +index a73392c0d6..4d64b3c75c 100644 +--- a/ld/Makefile.in ++++ b/ld/Makefile.in +@@ -3661,7 +3661,7 @@ eshlelf64_nbsd.c: $(srcdir)/emulparams/shlelf64_nbsd.sh \ + $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} + + eelf32stm8.c: $(srcdir)/emulparams/elf32stm8.sh \ +- $(ELF_DEPS) $(srcdir)/scripttempl/elfstm8.sc ${GEN_DEPENDS} ++ $(ELF_DEPS) $(srcdir)/scripttempl/stm8.sc ${GEN_DEPENDS} + + check-DEJAGNU: site.exp + srcroot=`cd $(srcdir) && pwd`; export srcroot; \ +diff --git a/ld/emulparams/elf32stm8.sh b/ld/emulparams/elf32stm8.sh +index c37c9e51da..960ca3885f 100644 +--- a/ld/emulparams/elf32stm8.sh ++++ b/ld/emulparams/elf32stm8.sh +@@ -1,6 +1,7 @@ + ARCH=stm8 + MACHINE=stm8 +-SCRIPT_NAME=elfstm8 ++SCRIPT_NAME=stm8 ++#SCRIPT_NAME=elfstm8 + OUTPUT_FORMAT="elf32-stm8" + MAXPAGESIZE=1 + EMBEDDED=yes +diff --git a/ld/scripttempl/elfstm8.sc b/ld/scripttempl/elfstm8.sc +deleted file mode 100644 +index 0ce6b56741..0000000000 +--- a/ld/scripttempl/elfstm8.sc ++++ /dev/null +@@ -1,232 +0,0 @@ +-# Adapted from mips.sc +-# +-# Copyright (C) 2014-2016 Free Software Foundation, Inc. +-# +-# Copying and distribution of this file, with or without modification, +-# are permitted in any medium without royalty provided the copyright +-# notice and this notice are preserved. +-# +-# These variables may be overridden by the emulation file. The +-# defaults are appropriate for a DECstation running Ultrix. +- +-test -z "$ENTRY" && ENTRY=_start +- +-#test -z "$TEXT_START_ADDR" && TEXT_START_ADDR="0x0" +- +-CTOR=".ctors ${CONSTRUCTING-0} : +- { +- ${CONSTRUCTING+${CTOR_START}} +- /* gcc uses crtbegin.o to find the start of +- the constructors, so we make sure it is +- first. Because this is a wildcard, it +- doesn't matter if the user does not +- actually link against crtbegin.o; the +- linker won't look for a file to match a +- wildcard. The wildcard also means that it +- doesn't matter which directory crtbegin.o +- is in. */ +- +- KEEP (*crtbegin.o(.ctors)) +- +- /* We don't want to include the .ctor section from +- from the crtend.o file until after the sorted ctors. +- The .ctor section from the crtend file contains the +- end of ctors marker and it must be last */ +- +- KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) +- KEEP (*(SORT(.ctors.*))) +- KEEP (*(.ctors)) +- ${CONSTRUCTING+${CTOR_END}} +- }" +- +-DTOR=" .dtors ${CONSTRUCTING-0} : +- { +- ${CONSTRUCTING+${DTOR_START}} +- KEEP (*crtbegin.o(.dtors)) +- KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) +- KEEP (*(SORT(.dtors.*))) +- KEEP (*(.dtors)) +- ${CONSTRUCTING+${DTOR_END}} +- }" +- +-cat <<EOF +-/* Copyright (C) 2014-2016 Free Software Foundation, Inc. +- +- Copying and distribution of this script, with or without modification, +- are permitted in any medium without royalty provided the copyright +- notice and this notice are preserved. */ +- +-OUTPUT_FORMAT("${OUTPUT_FORMAT}", "${BIG_OUTPUT_FORMAT}", +- "${LITTLE_OUTPUT_FORMAT}") +-/*${LIB_SEARCH_DIRS}*/ +-${RELOCATING+${LIB_SEARCH_DIRS}} +- +-${RELOCATING+ENTRY (${ENTRY})} +- +-_TEXT_START_ADDR = DEFINED(_TEXT_START_ADDR) ? _TEXT_START_ADDR : 0x50; +-_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x0; +-_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x400; +- +-SECTIONS +-{ +- .vectors.reset 0x8000 : { KEEP (*(.vectors.reset)) } = 0 +- +- ${RELOCATING+. = _TEXT_START_ADDR;} +- +- ${RELOCATING+ _ftext = .;} +- .text : { +- ${RELOCATING+*(.text)} +- ${RELOCATING+*(.text.*)} +- ${RELOCATING+*(.gnu.linkonce.t.*)} +- } +- ${RELOCATING+ _etext = .;} +- +- .init : { KEEP (*(.init)) } =0 +- .fini : { KEEP (*(.fini)) } =0 +- +- ${RELOCATING+PROVIDE (__CTOR_LIST__ = .);} +- ${RELOCATING+PROVIDE (___CTOR_LIST__ = .);} +- ${RELOCATING+${CTOR}} +- ${RELOCATING+PROVIDE (__CTOR_END__ = .);} +- ${RELOCATING+PROVIDE (___CTOR_END__ = .);} +- +- ${RELOCATING+PROVIDE (__DTOR_LIST__ = .);} +- ${RELOCATING+PROVIDE (___DTOR_LIST__ = .);} +- ${RELOCATING+${DTOR}} +- ${RELOCATING+PROVIDE (__DTOR_END__ = .);} +- ${RELOCATING+PROVIDE (___DTOR_END__ = .);} +- +- ${RELOCATING+ . = ALIGN(4);} +- ${RELOCATING+ _frodata = . ;} +- .rodata : { +- ${RELOCATING+*(.rodata)} +- ${RELOCATING+*(.rodata.*)} +- ${RELOCATING+*(.gnu.linkonce.r.*)} +- ${CONSTRUCTING+CONSTRUCTORS}; /* Is this needed? */ +- } +- ${RELOCATING+ _erodata = .;} +- +- /* Alignments by 8 to ensure that _SDA2_BASE_ on a word boundary */ +- /* Note that .sdata2 and .sbss2 must be contiguous */ +- ${RELOCATING+. = ALIGN(8);} +- ${RELOCATING+ _ssrw = .;} +- .sdata2 : { +- ${RELOCATING+*(.sdata2)} +- ${RELOCATING+*(.sdata2.*)} +- ${RELOCATING+*(.gnu.linkonce.s2.*)} +- } +- ${RELOCATING+. = ALIGN(4);} +- .sbss2 : { +- ${RELOCATING+PROVIDE (__sbss2_start = .);} +- ${RELOCATING+*(.sbss2)} +- ${RELOCATING+*(.sbss2.*)} +- ${RELOCATING+*(.gnu.linkonce.sb2.*)} +- ${RELOCATING+PROVIDE (__sbss2_end = .);} +- } +- ${RELOCATING+. = ALIGN(8);} +- ${RELOCATING+ _essrw = .;} +- ${RELOCATING+ _ssrw_size = _essrw - _ssrw;} +- ${RELOCATING+ PROVIDE (_SDA2_BASE_ = _ssrw + (_ssrw_size / 2 ));} +- +- ${RELOCATING+ . = ALIGN(4);} +- ${RELOCATING+ _fdata = .;} +- .data : { +- ${RELOCATING+*(.data)} +- ${RELOCATING+*(.gnu.linkonce.d.*)} +- ${CONSTRUCTING+CONSTRUCTORS}; /* Is this needed? */ +- } +- ${RELOCATING+ _edata = . ;} +- +- /* Added to handle pic code */ +- .got : { +- ${RELOCATING+*(.got)} +- } +- +- .got1 : { +- ${RELOCATING+*(.got1)} +- } +- +- .got2 : { +- ${RELOCATING+*(.got2)} +- } +- +- /* Added by Sathya to handle C++ exceptions */ +- .eh_frame : { +- ${RELOCATING+*(.eh_frame)} +- } +- +- .jcr : { +- ${RELOCATING+*(.jcr)} +- } +- +- .gcc_except_table : { +- ${RELOCATING+*(.gcc_except_table)} +- } +- +- /* Alignments by 8 to ensure that _SDA_BASE_ on a word boundary */ +- /* Note that .sdata and .sbss must be contiguous */ +- ${RELOCATING+. = ALIGN(8);} +- ${RELOCATING+ _ssro = .;} +- .sdata : { +- ${RELOCATING+*(.sdata)} +- ${RELOCATING+*(.sdata.*)} +- ${RELOCATING+*(.gnu.linkonce.s.*)} +- } +- ${RELOCATING+. = ALIGN(4);} +- .sbss : { +- ${RELOCATING+PROVIDE (__sbss_start = .);} +- ${RELOCATING+*(.sbss)} +- ${RELOCATING+*(.sbss.*)} +- ${RELOCATING+*(.gnu.linkonce.sb.*)} +- ${RELOCATING+PROVIDE (__sbss_end = .);} +- } +- ${RELOCATING+. = ALIGN(8);} +- ${RELOCATING+ _essro = .;} +- ${RELOCATING+ _ssro_size = _essro - _ssro;} +- ${RELOCATING+PROVIDE (_SDA_BASE_ = _ssro + (_ssro_size / 2 ));} +- +- ${RELOCATING+ . = ALIGN(4);} +- ${RELOCATING+ _fbss = .;} +- .bss : { +- ${RELOCATING+PROVIDE (__bss_start = .);} +- ${RELOCATING+*(.bss)} +- ${RELOCATING+*(.bss.*)} +- ${RELOCATING+*(.gnu.linkonce.b.*)} +- ${RELOCATING+*(COMMON)} +- ${RELOCATING+. = ALIGN(. != 0 ? 4 : 1);} +- +- ${RELOCATING+PROVIDE (__bss_end = .);} +- +- } +- +- ${RELOCATING+ . = ALIGN(4);} +- +- .heap : { +- ${RELOCATING+ _heap = .;} +- ${RELOCATING+ _heap_start = .;} +- ${RELOCATING+ . += _HEAP_SIZE;} +- ${RELOCATING+ _heap_end = .;} +- } +- +- ${RELOCATING+ . = ALIGN(4);} +- +- .stack : { +- ${RELOCATING+ _stack_end = .;} +- ${RELOCATING+ . += _STACK_SIZE;} +- ${RELOCATING+ . = ALIGN(. != 0 ? 8 : 1);} +- ${RELOCATING+ _stack = .;} +- ${RELOCATING+ _end = .;} +- } +- +- .tdata : { +- ${RELOCATING+*(.tdata)} +- ${RELOCATING+*(.tdata.*)} +- ${RELOCATING+*(.gnu.linkonce.td.*)} +- } +- .tbss : { +- ${RELOCATING+*(.tbss)} +- ${RELOCATING+*(.tbss.*)} +- ${RELOCATING+*(.gnu.linkonce.tb.*)} +- } +-} +-EOF +diff --git a/ld/scripttempl/stm8.sc b/ld/scripttempl/stm8.sc +new file mode 100644 +index 0000000000..642b906d4f +--- /dev/null ++++ b/ld/scripttempl/stm8.sc +@@ -0,0 +1,270 @@ ++# Copyright (C) 2014-2018 Free Software Foundation, Inc. ++# ++# Copying and distribution of this file, with or without modification, ++# are permitted in any medium without royalty provided the copyright ++# notice and this notice are preserved. ++ ++test -z "$ENTRY" && ENTRY=_start ++ ++cat <<EOF ++/* Copyright (C) 2014-2016 Free Software Foundation, Inc. ++ ++ Copying and distribution of this script, with or without modification, ++ are permitted in any medium without royalty provided the copyright ++ notice and this notice are preserved. */ ++ ++${RELOCATING+ENTRY (${ENTRY})} ++ ++OUTPUT_FORMAT("${OUTPUT_FORMAT}","${OUTPUT_FORMAT}","${OUTPUT_FORMAT}") ++OUTPUT_ARCH(${ARCH}) ++ ++__TEXT_REGION_LENGTH__ = DEFINED(__TEXT_REGION_LENGTH__) ? __TEXT_REGION_LENGTH__ : $TEXT_LENGTH; ++__DATA_REGION_LENGTH__ = DEFINED(__DATA_REGION_LENGTH__) ? __DATA_REGION_LENGTH__ : $DATA_LENGTH; ++__EEPROM_REGION_LENGTH__ = DEFINED(__EEPROM_REGION_LENGTH__) ? __EEPROM_REGION_LENGTH__ : 64K; ++__FUSE_REGION_LENGTH__ = DEFINED(__FUSE_REGION_LENGTH__) ? __FUSE_REGION_LENGTH__ : 1K; ++__LOCK_REGION_LENGTH__ = DEFINED(__LOCK_REGION_LENGTH__) ? __LOCK_REGION_LENGTH__ : 1K; ++__SIGNATURE_REGION_LENGTH__ = DEFINED(__SIGNATURE_REGION_LENGTH__) ? __SIGNATURE_REGION_LENGTH__ : 1K; ++__USER_SIGNATURE_REGION_LENGTH__ = DEFINED(__USER_SIGNATURE_REGION_LENGTH__) ? __USER_SIGNATURE_REGION_LENGTH__ : 1K; ++ ++MEMORY ++{ ++ data (rw!x) : ORIGIN = 0x0, LENGTH = __DATA_REGION_LENGTH__ ++ eeprom (rw!x) : ORIGIN = 0x4000, LENGTH = __EEPROM_REGION_LENGTH__ ++ fuse (rw!x) : ORIGIN = 0x5000, LENGTH = __FUSE_REGION_LENGTH__ ++ lock (rw!x) : ORIGIN = 0x5100, LENGTH = __LOCK_REGION_LENGTH__ ++ text (rx) : ORIGIN = 0x8000, LENGTH = __TEXT_REGION_LENGTH__ ++ signature (rw!x) : ORIGIN = 0x840000, LENGTH = __SIGNATURE_REGION_LENGTH__ ++ user_signatures (rw!x) : ORIGIN = 0x850000, LENGTH = __USER_SIGNATURE_REGION_LENGTH__ ++} ++ ++SECTIONS ++{ ++ /* Read-only sections, merged into text segment: */ ++ ${TEXT_DYNAMIC+${DYNAMIC}} ++ .hash ${RELOCATING-0} : { *(.hash) } ++ .dynsym ${RELOCATING-0} : { *(.dynsym) } ++ .dynstr ${RELOCATING-0} : { *(.dynstr) } ++ .gnu.version ${RELOCATING-0} : { *(.gnu.version) } ++ .gnu.version_d ${RELOCATING-0} : { *(.gnu.version_d) } ++ .gnu.version_r ${RELOCATING-0} : { *(.gnu.version_r) } ++ ++ .rel.init ${RELOCATING-0} : { *(.rel.init) } ++ .rela.init ${RELOCATING-0} : { *(.rela.init) } ++ .rel.text ${RELOCATING-0} : ++ { ++ *(.rel.text) ++ ${RELOCATING+*(.rel.text.*)} ++ ${RELOCATING+*(.rel.gnu.linkonce.t*)} ++ } ++ .rela.text ${RELOCATING-0} : ++ { ++ *(.rela.text) ++ ${RELOCATING+*(.rela.text.*)} ++ ${RELOCATING+*(.rela.gnu.linkonce.t*)} ++ } ++ .rel.fini ${RELOCATING-0} : { *(.rel.fini) } ++ .rela.fini ${RELOCATING-0} : { *(.rela.fini) } ++ .rel.rodata ${RELOCATING-0} : ++ { ++ *(.rel.rodata) ++ ${RELOCATING+*(.rel.rodata.*)} ++ ${RELOCATING+*(.rel.gnu.linkonce.r*)} ++ } ++ .rela.rodata ${RELOCATING-0} : ++ { ++ *(.rela.rodata) ++ ${RELOCATING+*(.rela.rodata.*)} ++ ${RELOCATING+*(.rela.gnu.linkonce.r*)} ++ } ++ .rel.data ${RELOCATING-0} : ++ { ++ *(.rel.data) ++ ${RELOCATING+*(.rel.data.*)} ++ ${RELOCATING+*(.rel.gnu.linkonce.d*)} ++ } ++ .rela.data ${RELOCATING-0} : ++ { ++ *(.rela.data) ++ ${RELOCATING+*(.rela.data.*)} ++ ${RELOCATING+*(.rela.gnu.linkonce.d*)} ++ } ++ .rel.ctors ${RELOCATING-0} : { *(.rel.ctors) } ++ .rela.ctors ${RELOCATING-0} : { *(.rela.ctors) } ++ .rel.dtors ${RELOCATING-0} : { *(.rel.dtors) } ++ .rela.dtors ${RELOCATING-0} : { *(.rela.dtors) } ++ .rel.got ${RELOCATING-0} : { *(.rel.got) } ++ .rela.got ${RELOCATING-0} : { *(.rela.got) } ++ .rel.bss ${RELOCATING-0} : { *(.rel.bss) } ++ .rela.bss ${RELOCATING-0} : { *(.rela.bss) } ++ .rel.plt ${RELOCATING-0} : { *(.rel.plt) } ++ .rela.plt ${RELOCATING-0} : { *(.rela.plt) } ++ ++ /* Internal text space or external memory. */ ++ .text ${RELOCATING-0} : ++ { ++ *(.vectors) ++ KEEP(*(.vectors)) ++ ++ /* For data that needs to reside in the lower 64k of progmem. */ ++ ${RELOCATING+ *(.progmem.gcc*)} ++ ++ /* PR 13812: Placing the trampolines here gives a better chance ++ that they will be in range of the code that uses them. */ ++ ${RELOCATING+. = ALIGN(2);} ++ ${CONSTRUCTING+ __trampolines_start = . ; } ++ /* The jump trampolines for the 16-bit limited relocs will reside here. */ ++ *(.trampolines) ++ ${RELOCATING+ *(.trampolines*)} ++ ${CONSTRUCTING+ __trampolines_end = . ; } ++ ++ /* avr-libc expects these data to reside in lower 64K. */ ++ ${RELOCATING+ *libprintf_flt.a:*(.progmem.data)} ++ ${RELOCATING+ *libc.a:*(.progmem.data)} ++ ++ ${RELOCATING+ *(.progmem*)} ++ ++ ${RELOCATING+. = ALIGN(2);} ++ ++ /* For future tablejump instruction arrays for 3 byte pc devices. ++ We don't relax jump/call instructions within these sections. */ ++ *(.jumptables) ++ ${RELOCATING+ *(.jumptables*)} ++ ++ /* For code that needs to reside in the lower 128k progmem. */ ++ *(.lowtext) ++ ${RELOCATING+ *(.lowtext*)} ++ ++ ${CONSTRUCTING+ __ctors_start = . ; } ++ ${CONSTRUCTING+ *(.ctors) } ++ ${CONSTRUCTING+ __ctors_end = . ; } ++ ${CONSTRUCTING+ __dtors_start = . ; } ++ ${CONSTRUCTING+ *(.dtors) } ++ ${CONSTRUCTING+ __dtors_end = . ; } ++ KEEP(SORT(*)(.ctors)) ++ KEEP(SORT(*)(.dtors)) ++ ++ /* From this point on, we don't bother about wether the insns are ++ below or above the 16 bits boundary. */ ++ *(.init0) /* Start here after reset. */ ++ KEEP (*(.init0)) ++ *(.init1) ++ KEEP (*(.init1)) ++ *(.init2) /* Clear __zero_reg__, set up stack pointer. */ ++ KEEP (*(.init2)) ++ *(.init3) ++ KEEP (*(.init3)) ++ *(.init4) /* Initialize data and BSS. */ ++ KEEP (*(.init4)) ++ *(.init5) ++ KEEP (*(.init5)) ++ *(.init6) /* C++ constructors. */ ++ KEEP (*(.init6)) ++ *(.init7) ++ KEEP (*(.init7)) ++ *(.init8) ++ KEEP (*(.init8)) ++ *(.init9) /* Call main(). */ ++ KEEP (*(.init9)) ++ *(.text) ++ ${RELOCATING+. = ALIGN(2);} ++ ${RELOCATING+ *(.text.*)} ++ ${RELOCATING+. = ALIGN(2);} ++ *(.fini9) /* _exit() starts here. */ ++ KEEP (*(.fini9)) ++ *(.fini8) ++ KEEP (*(.fini8)) ++ *(.fini7) ++ KEEP (*(.fini7)) ++ *(.fini6) /* C++ destructors. */ ++ KEEP (*(.fini6)) ++ *(.fini5) ++ KEEP (*(.fini5)) ++ *(.fini4) ++ KEEP (*(.fini4)) ++ *(.fini3) ++ KEEP (*(.fini3)) ++ *(.fini2) ++ KEEP (*(.fini2)) ++ *(.fini1) ++ KEEP (*(.fini1)) ++ *(.fini0) /* Infinite loop after program termination. */ ++ KEEP (*(.fini0)) ++ ${RELOCATING+ _etext = . ; } ++ } ${RELOCATING+ > text} ++ ++ .data ${RELOCATING-0} : ++ { ++ ${RELOCATING+ PROVIDE (__data_start = .) ; } ++ *(.data) ++ ${RELOCATING+ *(.data*)} ++ *(.rodata) /* We need to include .rodata here if gcc is used */ ++ ${RELOCATING+ *(.rodata*)} /* with -fdata-sections. */ ++ *(.gnu.linkonce.d*) ++ ${RELOCATING+. = ALIGN(2);} ++ ${RELOCATING+ _edata = . ; } ++ ${RELOCATING+ PROVIDE (__data_end = .) ; } ++ } ${RELOCATING+ > data ${RELOCATING+AT> text}} ++ ++ .bss ${RELOCATING+ ADDR(.data) + SIZEOF (.data)} ${RELOCATING-0} :${RELOCATING+ AT (ADDR (.bss))} ++ { ++ ${RELOCATING+ PROVIDE (__bss_start = .) ; } ++ *(.bss) ++ ${RELOCATING+ *(.bss*)} ++ *(COMMON) ++ ${RELOCATING+ PROVIDE (__bss_end = .) ; } ++ } ${RELOCATING+ > data} ++ ++ ${RELOCATING+ __data_load_start = LOADADDR(.data); } ++ ${RELOCATING+ __data_load_end = __data_load_start + SIZEOF(.data); } ++ ++ /* Global data not cleared after reset. */ ++ .noinit ${RELOCATING+ ADDR(.bss) + SIZEOF (.bss)} ${RELOCATING-0}: ${RELOCATING+ AT (ADDR (.noinit))} ++ { ++ ${RELOCATING+ PROVIDE (__noinit_start = .) ; } ++ *(.noinit*) ++ ${RELOCATING+ PROVIDE (__noinit_end = .) ; } ++ ${RELOCATING+ _end = . ; } ++ ${RELOCATING+ PROVIDE (__heap_start = .) ; } ++ } ${RELOCATING+ > data} ++ ++ .eeprom ${RELOCATING-0}: ++ { ++ /* See .data above... */ ++ KEEP(*(.eeprom*)) ++ ${RELOCATING+ __eeprom_end = . ; } ++ } ${RELOCATING+ > eeprom} ++ ++ .fuse ${RELOCATING-0}: ++ { ++ KEEP(*(.fuse)) ++ KEEP(*(.lfuse)) ++ KEEP(*(.hfuse)) ++ KEEP(*(.efuse)) ++ } ${RELOCATING+ > fuse} ++ ++ .lock ${RELOCATING-0}: ++ { ++ KEEP(*(.lock*)) ++ } ${RELOCATING+ > lock} ++ ++ .signature ${RELOCATING-0}: ++ { ++ KEEP(*(.signature*)) ++ } ${RELOCATING+ > signature} ++ ++ /* Stabs debugging sections. */ ++ .stab 0 : { *(.stab) } ++ .stabstr 0 : { *(.stabstr) } ++ .stab.excl 0 : { *(.stab.excl) } ++ .stab.exclstr 0 : { *(.stab.exclstr) } ++ .stab.index 0 : { *(.stab.index) } ++ .stab.indexstr 0 : { *(.stab.indexstr) } ++ .comment 0 : { *(.comment) } ++ .note.gnu.build-id : { *(.note.gnu.build-id) } ++EOF ++ ++. $srcdir/scripttempl/DWARF.sc ++ ++cat <<EOF ++} ++EOF +diff --git a/opcodes/stm8-dis.c b/opcodes/stm8-dis.c +index 751c62c2b7..2eee63060b 100644 +--- a/opcodes/stm8-dis.c ++++ b/opcodes/stm8-dis.c +@@ -1,5 +1,5 @@ + /* Disassemble STM8 instructions. +- Copyright (C) 1999-2016 Free Software Foundation, Inc. ++ Copyright (C) 1999-2018 Free Software Foundation, Inc. + + Contributed by Ake Rehnman + +@@ -344,32 +344,65 @@ int stm8_dis(bfd_vma addr, unsigned int op) + unsigned char *bufp; + char s[256]; + int i=0; +- int j; + char c; + int operandlen; ++ int operand, dir; + + while (stm8_opcodes[i].name) + { + if (op == stm8_opcodes[i].bin_opcode) + { +- bufp=buf; +- s[0] = 0; + dinfo->fprintf_func(dinfo->stream, "%s",stm8_opcodes[i].name); + operandlen = stm8_compute_insn_size(stm8_opcodes[i])-stm8_opcode_size(op); + instrlen += operandlen; + if (fetch_data(buf,addr,dinfo,operandlen)) + return 0; ++ + lastlabeladdr = 0; +- for (j=0;j<5;j++) ++ c = ' '; ++ ++ for (int curr_operand = 0; curr_operand < stm8_num_opcode_operands(stm8_opcodes[i]); curr_operand++) + { +- s[0]=0; +- bufp+=stm8_operands(s, bufp, stm8_opcodes[i].constraints[j]); +- if (s[0]) ++ bufp = buf; ++ dir = 1; ++ operand = 0; ++ ++ /* mov insn operands are reversed */ ++ if ((op == 0x35) || (op == 0x45) || (op == 0x55)) + { +- if (j==0) c=' '; else c=','; +- dinfo->fprintf_func(dinfo->stream, "%c%s",c,s); ++ dir = -1; ++ operand = stm8_num_opcode_operands(stm8_opcodes[i]) - 1; ++ } ++ ++ for (int j = 0; j < stm8_num_opcode_operands(stm8_opcodes[i]); j++, operand += dir) ++ { ++ s[0] = 0; ++ bufp += stm8_operands(s, bufp, stm8_opcodes[i].constraints[operand]); ++ if (operand == curr_operand) ++ { ++ if (s[0]) ++ { ++ dinfo->fprintf_func(dinfo->stream, "%c%s",c,s); ++ c = ','; ++ } ++ break; ++ } + } + } ++ ++ ++// c = ' '; ++// for (j=0; j<5; j++, operand += dir) ++// { ++// s[0]=0; ++// bufp += stm8_operands(s, bufp, stm8_opcodes[i].constraints[operand]); ++// if (s[0]) ++// { ++// dinfo->fprintf_func(dinfo->stream, "%c%s",c,s); ++// c = ','; ++// } ++// } ++ + if (lastlabeladdr) + { + dinfo->fprintf_func(dinfo->stream, " ;"); +diff --git a/opcodes/stm8-opc.c b/opcodes/stm8-opc.c +index 3a600d66d3..9516d859f2 100644 +--- a/opcodes/stm8-opc.c ++++ b/opcodes/stm8-opc.c +@@ -1,5 +1,5 @@ + /* stm8-opc.c -- Table of opcodes for the STM8 processor. +- Copyright (C) 2007-2016 Free Software Foundation, Inc. ++ Copyright (C) 2007-2018 Free Software Foundation, Inc. + Contributed by Ake Rehnman ake dot rehnman (at) gmail dot com + + This file is part of the GNU opcodes library. +@@ -729,6 +729,13 @@ const struct stm8_opcodes_s stm8_opcodes[] = + {NULL, {ST8_END}, 0}, + }; + ++int stm8_num_opcode_operands(struct stm8_opcodes_s opcode) ++{ ++ int i; ++ for(i = 0; opcode.constraints[i]; i++); ++ return i; ++} ++ + unsigned int stm8_opcode_size(unsigned int number) + { + int i; +-- +2.12.2 + |
