|
From: Åke R. <ake...@gm...> - 2017-02-08 20:29:49
|
Hello all,
I'm writing a new stm8 target for gdb and so I stumbled into a couple of
issues with SDCC.
It seems there are no DW_AT_frame_base attributes in the subprogram tags
so gdb is not able to figure out where to look for arguments. The same
seem to apply for locals as well.
objdump from my test code:
Compilation Unit @ offset 0x0:
Length: 0x10e (32-bit)
Version: 2
Abbrev Offset: 0x0
Pointer Size: 4
<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
<c> DW_AT_name : led.c
<12> DW_AT_stmt_list : 0x0
<16> DW_AT_language : 1 (ANSI C)
<17> DW_AT_producer : SDCC version 3.6.5 #9837
<1><30>: Abbrev Number: 2 (DW_TAG_base_type)
<31> DW_AT_name : unsigned int
<3e> DW_AT_byte_size : 2
<3f> DW_AT_encoding : 7 (unsigned)
<1><40>: Abbrev Number: 3 (DW_TAG_subprogram)
<41> DW_AT_sibling : <0x9c>
<45> DW_AT_name : clock
<4b> DW_AT_low_pc : 0x8024
<4f> DW_AT_high_pc : 0x8055
<53> DW_AT_external : 1
<54> DW_AT_type : <0x30>
<2><58>: Abbrev Number: 4 (DW_TAG_formal_parameter)
<59> DW_AT_location : 2 byte block: 91 2 (DW_OP_fbreg: 2)
[without DW_AT_frame_base]
<5c> DW_AT_name : ullabella
<66> DW_AT_type : <0x9c>
<2><6a>: Abbrev Number: 4 (DW_TAG_formal_parameter)
<6b> DW_AT_location : 2 byte block: 91 4 (DW_OP_fbreg: 4)
[without DW_AT_frame_base]
<6e> DW_AT_name : nisseberra
<79> DW_AT_type : <0xa3>
<2><7d>: Abbrev Number: 5 (DW_TAG_variable)
<7e> DW_AT_name : h
<80> DW_AT_type : <0xac>
<2><84>: Abbrev Number: 6 (DW_TAG_variable)
<85> DW_AT_location : 1 byte block: 51 (DW_OP_reg1 (r1))
<87> DW_AT_name : l
<89> DW_AT_type : <0xac>
<2><8d>: Abbrev Number: 6 (DW_TAG_variable)
<8e> DW_AT_location : 2 byte block: 91 0 (DW_OP_fbreg: 0)
[without DW_AT_frame_base]
<91> DW_AT_name : kalle
<97> DW_AT_type : <0x30>
I have also noticed bool args/locals are not encoded correctly:
In SDCCdwarf2.c:
case V_BOOL:
tp = dwNewTag (DW_TAG_base_type);
dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
DW_ATE_float));
dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, "_Bool"));
dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
getSize (type)));
dwAddTagChild (dwRootTag, tp);
break;
<1><99>: Abbrev Number: 2 (DW_TAG_base_type)
<9a> DW_AT_name : _Bool
<a0> DW_AT_byte_size : 1
<a1> DW_AT_encoding : 4 (float)
The main question is how the frame base is going to be implemented so I
can move forward with my gdb target.
/Ake
|
|
From: Philipp K. K. <pk...@sp...> - 2017-05-10 13:46:37
|
Am 08.02.2017 um 21:29 schrieb Åke Rehnman: > Hello all, > > I'm writing a new stm8 target for gdb and so I stumbled into a couple of > issues with SDCC. > > It seems there are no DW_AT_frame_base attributes in the subprogram tags > so gdb is not able to figure out where to look for arguments. The same > seem to apply for locals as well. > > objdump from my test code: > > Compilation Unit @ offset 0x0: > Length: 0x10e (32-bit) > Version: 2 > Abbrev Offset: 0x0 > Pointer Size: 4 > <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit) > <c> DW_AT_name : led.c > <12> DW_AT_stmt_list : 0x0 > <16> DW_AT_language : 1 (ANSI C) > <17> DW_AT_producer : SDCC version 3.6.5 #9837 > <1><30>: Abbrev Number: 2 (DW_TAG_base_type) > <31> DW_AT_name : unsigned int > <3e> DW_AT_byte_size : 2 > <3f> DW_AT_encoding : 7 (unsigned) > <1><40>: Abbrev Number: 3 (DW_TAG_subprogram) > <41> DW_AT_sibling : <0x9c> > <45> DW_AT_name : clock > <4b> DW_AT_low_pc : 0x8024 > <4f> DW_AT_high_pc : 0x8055 > <53> DW_AT_external : 1 > <54> DW_AT_type : <0x30> > <2><58>: Abbrev Number: 4 (DW_TAG_formal_parameter) > <59> DW_AT_location : 2 byte block: 91 2 (DW_OP_fbreg: 2) > [without DW_AT_frame_base] > <5c> DW_AT_name : ullabella > <66> DW_AT_type : <0x9c> > <2><6a>: Abbrev Number: 4 (DW_TAG_formal_parameter) > <6b> DW_AT_location : 2 byte block: 91 4 (DW_OP_fbreg: 4) > [without DW_AT_frame_base] > <6e> DW_AT_name : nisseberra > <79> DW_AT_type : <0xa3> > <2><7d>: Abbrev Number: 5 (DW_TAG_variable) > <7e> DW_AT_name : h > <80> DW_AT_type : <0xac> > <2><84>: Abbrev Number: 6 (DW_TAG_variable) > <85> DW_AT_location : 1 byte block: 51 (DW_OP_reg1 (r1)) > <87> DW_AT_name : l > <89> DW_AT_type : <0xac> > <2><8d>: Abbrev Number: 6 (DW_TAG_variable) > <8e> DW_AT_location : 2 byte block: 91 0 (DW_OP_fbreg: 0) > [without DW_AT_frame_base] > <91> DW_AT_name : kalle > <97> DW_AT_type : <0x30> > > > > > I have also noticed bool args/locals are not encoded correctly: > > In SDCCdwarf2.c: > case V_BOOL: > tp = dwNewTag (DW_TAG_base_type); > dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding, > DW_ATE_float)); > dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, "_Bool")); > dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size, > getSize (type))); > dwAddTagChild (dwRootTag, tp); > break; > > <1><99>: Abbrev Number: 2 (DW_TAG_base_type) > <9a> DW_AT_name : _Bool > <a0> DW_AT_byte_size : 1 > <a1> DW_AT_encoding : 4 (float) > > > > The main question is how the frame base is going to be implemented so I > can move forward with my gdb target. > > /Ake I'm not really an expert on the debug info stuff. Could you check if the same problem is also present in current SDCC for hc08 / s08 when placing parameters / variables on the stack? If it works ok for hc08 / s08, we probably would just make stm8 behave the same. Philipp |
|
From: Åke R. <ake...@gm...> - 2017-05-10 19:31:04
Attachments:
SDCCdwarf2.patch
|
On 2017-05-10 15:41, Philipp Klaus Krause wrote: > Am 08.02.2017 um 21:29 schrieb Åke Rehnman: >> Hello all, >> >> I'm writing a new stm8 target for gdb and so I stumbled into a couple of >> issues with SDCC. . . . >> I have also noticed bool args/locals are not encoded correctly: >> >> In SDCCdwarf2.c: >> case V_BOOL: >> tp = dwNewTag (DW_TAG_base_type); >> dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding, >> DW_ATE_float)); >> dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, "_Bool")); >> dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size, >> getSize (type))); >> dwAddTagChild (dwRootTag, tp); >> break; >> >> <1><99>: Abbrev Number: 2 (DW_TAG_base_type) >> <9a> DW_AT_name : _Bool >> <a0> DW_AT_byte_size : 1 >> <a1> DW_AT_encoding : 4 (float) >> >> >> >> The main question is how the frame base is going to be implemented so I >> can move forward with my gdb target. >> >> /Ake > I'm not really an expert on the debug info stuff. Could you check if the > same problem is also present in current SDCC for hc08 / s08 when placing > parameters / variables on the stack? If it works ok for hc08 / s08, we > probably would just make stm8 behave the same. > > Philipp > Hello Philip, I assume you mean the trouble with bool variables is incorrectly encoded as floats? Since it is the same dwTagFromType() function for both stm8 and hc08 one might think the result would be the same. How ever I have *not* scrutinized the dwarf2 debug output for hc08. I could of course do that if you will be helped. Please also find the attached patch for SDCCdwarf2 I've implemented. As a side note, since the present debug info is quite useless without proper implemented frame base I've patched in a soft frame pointer register in my distribution of SDCC. The reason is my knowledge of the inner workings of sdcc is quite sparse so that was the least amount of work getting something usable. Please let me know if there is anything I can do. /Ake |
|
From: Philipp K. K. <pk...@sp...> - 2017-05-10 19:53:48
|
Am 10.05.2017 um 21:30 schrieb Åke Rehnman: > > As a side note, since the present debug info is quite useless without > proper implemented frame base I've patched in a soft frame pointer > register in my distribution of SDCC. The reason is my knowledge of the > inner workings of sdcc is quite sparse so that was the least amount of > work getting something usable. > > Please let me know if there is anything I can do. > > /Ake > Well, I might know more about SDCC and the stm8 backend, but I don't know much about debuggers. I've used gdb once in a while, I've had a look at some DWARF spec a while ago, but that's it. Philipp |
|
From: Philipp K. K. <pk...@sp...> - 2017-05-10 19:46:15
|
Am 10.05.2017 um 21:30 schrieb Åke Rehnman: > Hello Philip, > I assume you mean the trouble with bool variables is incorrectly encoded > as floats? No, I meant the frame base issue. Philipp P.S.: The _Bool issue should be fixed in revision #9912. |
|
From: Åke R. <ake...@gm...> - 2017-05-10 20:16:55
|
On 2017-05-10 21:46, Philipp Klaus Krause wrote: > Am 10.05.2017 um 21:30 schrieb Åke Rehnman: >> Hello Philip, >> I assume you mean the trouble with bool variables is incorrectly encoded >> as floats? > No, I meant the frame base issue. > To make the frame unwinding work in gdb the frame base has to be constantly adjusted (call to updateCFA) when ever the stack pointer is moved (e.i things pushed or popped from the stack). The hc08 makes those push and pops in a few well defined functions perhaps total 5-10 places. As opposed to the stm8 code since it is lacking pushReg() and popReg() functions resulting in stack adjustments are made all over the place. So to make debugging work with CFA the first job would be to clean up the code and move the stack operations into a few well defined places similar to hc08. Since that work involves a lot of changes I was a bit hesitant to make those changes since that would result in quite difficult merges whenever the stm8 gen code change. /Ake |
|
From: Åke R. <ake...@gm...> - 2017-05-10 20:37:51
|
On 2017-05-10 22:16, Åke Rehnman wrote: > > So to make debugging work with CFA the first job would be to clean up > the code and move the stack operations into a few well defined places > similar to hc08. Since that work involves a lot of changes I was a bit > hesitant to make those changes since that would result in quite > difficult merges whenever the stm8 gen code change. > I know there is a new release coming up soon, but if you want me to do this job first of all it might be a good idea to wait until this upcoming release is done. Second I would want to know those changes will be merged so a lot of hours spent are not just wasted. |
|
From: Philipp K. K. <pk...@sp...> - 2017-05-11 08:48:40
|
Am 10.05.2017 um 22:37 schrieb Åke Rehnman: > > On 2017-05-10 22:16, Åke Rehnman wrote: >> >> So to make debugging work with CFA the first job would be to clean up >> the code and move the stack operations into a few well defined places >> similar to hc08. Since that work involves a lot of changes I was a bit >> hesitant to make those changes since that would result in quite >> difficult merges whenever the stm8 gen code change. >> > > I know there is a new release coming up soon, but if you want me to do > this job first of all it might be a good idea to wait until this > upcoming release is done. Second I would want to know those changes will > be merged so a lot of hours spent are not just wasted. I'd say a patch to make DWARF work better for stm8 would be welcome (that might also include a fix to #2613). Philipp |
|
From: Philipp K. K. <pk...@sp...> - 2017-05-10 20:49:19
|
Am 10.05.2017 um 22:16 schrieb Åke Rehnman: > On 2017-05-10 21:46, Philipp Klaus Krause wrote: >> Am 10.05.2017 um 21:30 schrieb Åke Rehnman: >>> Hello Philip, >>> I assume you mean the trouble with bool variables is incorrectly encoded >>> as floats? >> No, I meant the frame base issue. >> > To make the frame unwinding work in gdb the frame base has to be > constantly adjusted (call to updateCFA) when ever the stack pointer is > moved (e.i things pushed or popped from the stack). The hc08 makes those > push and pops in a few well defined functions perhaps total 5-10 places. > As opposed to the stm8 code since it is lacking pushReg() and popReg() > functions resulting in stack adjustments are made all over the place. > > So to make debugging work with CFA the first job would be to clean up > the code and move the stack operations into a few well defined places > similar to hc08. Since that work involves a lot of changes I was a bit > hesitant to make those changes since that would result in quite > difficult merges whenever the stm8 gen code change. > > /Ake I assume that changing the push / pop behaviour in stm8 codegen would come at a price in code size, speed and memory usage. I don't think that is acceptable for SDCC users. Any alternatives? Philipp |
|
From: Philipp K. K. <pk...@sp...> - 2017-05-10 20:55:33
|
Am 10.05.2017 um 22:16 schrieb Åke Rehnman: > On 2017-05-10 21:46, Philipp Klaus Krause wrote: >> Am 10.05.2017 um 21:30 schrieb Åke Rehnman: >>> Hello Philip, >>> I assume you mean the trouble with bool variables is incorrectly encoded >>> as floats? >> No, I meant the frame base issue. >> > To make the frame unwinding work in gdb the frame base has to be > constantly adjusted (call to updateCFA) when ever the stack pointer is > moved (e.i things pushed or popped from the stack). The hc08 makes those > push and pops in a few well defined functions perhaps total 5-10 places. > As opposed to the stm8 code since it is lacking pushReg() and popReg() > functions resulting in stack adjustments are made all over the place. > > So to make debugging work with CFA the first job would be to clean up > the code and move the stack operations into a few well defined places > similar to hc08. Since that work involves a lot of changes I was a bit > hesitant to make those changes since that would result in quite > difficult merges whenever the stm8 gen code change. > > /Ake But stm8 codegen basically does all stack-pointer-changing stuff in the three functions push(), pop() and adjustStack(). Does that help in any way? The stm8 codegen also supports the use of a frame-pointer, which currently is rarely used. If it is useful for debugging, I could however easily implement --fno-omit-frame-pointer for stm8. Philipp |
|
From: Åke R. <ake...@gm...> - 2017-05-10 20:57:11
|
On 2017-05-10 22:49, Philipp Klaus Krause wrote: > Am 10.05.2017 um 22:16 schrieb Åke Rehnman: >> >> So to make debugging work with CFA the first job would be to clean up >> the code and move the stack operations into a few well defined places >> similar to hc08. Since that work involves a lot of changes I was a bit >> hesitant to make those changes since that would result in quite >> difficult merges whenever the stm8 gen code change. >> >> /Ake > I assume that changing the push / pop behaviour in stm8 codegen would > come at a price in code size, speed and memory usage. I don't think that > is acceptable for SDCC users. > > Any alternatives? > > Philipp > No what I mean is those places in gen.c where registers are pushed and popped should use a function call to pushReg() and popReg() in the same way hc08 gen does. That way we don't have to litter the code with updateCFA() calls.... /Ake |
|
From: Philipp K. K. <pk...@sp...> - 2017-05-10 20:59:58
|
Am 10.05.2017 um 22:56 schrieb Åke Rehnman: > On 2017-05-10 22:49, Philipp Klaus Krause wrote: >> Am 10.05.2017 um 22:16 schrieb Åke Rehnman: >>> >>> So to make debugging work with CFA the first job would be to clean up >>> the code and move the stack operations into a few well defined places >>> similar to hc08. Since that work involves a lot of changes I was a bit >>> hesitant to make those changes since that would result in quite >>> difficult merges whenever the stm8 gen code change. >>> >>> /Ake >> I assume that changing the push / pop behaviour in stm8 codegen would >> come at a price in code size, speed and memory usage. I don't think that >> is acceptable for SDCC users. >> >> Any alternatives? >> >> Philipp >> > No what I mean is those places in gen.c where registers are pushed and > popped should use a function call to pushReg() and popReg() in the same > way hc08 gen does. That way we don't have to litter the code with > updateCFA() calls.... > Sound like push() at line 1023 of src/stm8/gen.c, pop () at line 1051 and adjustStack() at line 1176. Philipp |
|
From: Åke R. <ake...@gm...> - 2017-05-10 21:00:14
|
On 2017-05-10 22:55, Philipp Klaus Krause wrote: > > But stm8 codegen basically does all stack-pointer-changing stuff in the > three functions push(), pop() and adjustStack(). Does that help in any way? > > The stm8 codegen also supports the use of a frame-pointer, which > currently is rarely used. If it is useful for debugging, I could however > easily implement --fno-omit-frame-pointer for stm8. > > Philipp > Honestly, this is news for me.... I've been working on the 3.6.0 release so I have not looked at whats been going on since. Perhaps I should pull the latest sources first... /Ake |
|
From: Philipp K. K. <pk...@sp...> - 2017-05-10 21:03:10
|
Am 10.05.2017 um 22:59 schrieb Philipp Klaus Krause: > Am 10.05.2017 um 22:56 schrieb Åke Rehnman: >> On 2017-05-10 22:49, Philipp Klaus Krause wrote: >>> Am 10.05.2017 um 22:16 schrieb Åke Rehnman: >>>> >>>> So to make debugging work with CFA the first job would be to clean up >>>> the code and move the stack operations into a few well defined places >>>> similar to hc08. Since that work involves a lot of changes I was a bit >>>> hesitant to make those changes since that would result in quite >>>> difficult merges whenever the stm8 gen code change. >>>> >>>> /Ake >>> I assume that changing the push / pop behaviour in stm8 codegen would >>> come at a price in code size, speed and memory usage. I don't think that >>> is acceptable for SDCC users. >>> >>> Any alternatives? >>> >>> Philipp >>> >> No what I mean is those places in gen.c where registers are pushed and >> popped should use a function call to pushReg() and popReg() in the same >> way hc08 gen does. That way we don't have to litter the code with >> updateCFA() calls.... >> > > Sound like push() at line 1023 of src/stm8/gen.c, pop () at line 1051 > and adjustStack() at line 1176. > Actually, codegen also needs to keep track of the offsets of variables from the stack pointer. It does so in G.stack.pushed. Besides the three functions listed above, the only places in stm8 codegen where G.stack.pushed is written is in genFunction() and genCmpEQorNE(). So we just place calls to updateCFA() wherever we update G.stack.pushed? Philipp |
|
From: Åke R. <ake...@gm...> - 2017-05-10 21:14:27
|
On 2017-05-10 23:02, Philipp Klaus Krause wrote: > Sound like push() at line 1023 of src/stm8/gen.c, pop () at line 1051 >> and adjustStack() at line 1176. >> > Actually, codegen also needs to keep track of the offsets of variables > from the stack pointer. It does so in G.stack.pushed. Besides the three > functions listed above, the only places in stm8 codegen where > G.stack.pushed is written is in genFunction() and genCmpEQorNE(). > > So we just place calls to updateCFA() wherever we update G.stack.pushed? > > Philipp > > I had just a quick look, you are right a call to updateCFA() where G.stack.pushed is changed might do the trick. Although what you mentioned about there is a frame pointer already implemented came to me as news.... /Ake |
|
From: Philipp K. K. <pk...@sp...> - 2017-05-10 21:18:55
|
Am 10.05.2017 um 23:00 schrieb Åke Rehnman: > > On 2017-05-10 22:55, Philipp Klaus Krause wrote: >> >> But stm8 codegen basically does all stack-pointer-changing stuff in the >> three functions push(), pop() and adjustStack(). Does that help in any way? >> >> The stm8 codegen also supports the use of a frame-pointer, which >> currently is rarely used. If it is useful for debugging, I could however >> easily implement --fno-omit-frame-pointer for stm8. >> >> Philipp >> > > Honestly, this is news for me.... I've been working on the 3.6.0 release > so I have not looked at whats been going on since. Perhaps I should pull > the latest sources first... Line 356 in src/stm8/gen.c handles the variable access using the frame pointer. Line 3050 does the frame pointer setup. However, the caller is responsible for saving and restoring the frame pointer, so it might be unavailable for a short while after a function call. Support for the frame pointer has been in there for a long time: The offsets for sp-relative addressing on the STM8 are 8-bit only, while we can use 16-bit offsets on the register y, which is used as a frame pointer. We thus use the frame pointer when there is so much stack space used by local variables that we can't use sp-relative addressing for all them. Philipp |
|
From: Åke R. <ake...@gm...> - 2017-05-10 21:41:14
|
On 2017-05-10 23:18, Philipp Klaus Krause wrote: > Am 10.05.2017 um 23:00 schrieb Åke Rehnman: >> On 2017-05-10 22:55, Philipp Klaus Krause wrote: >>> But stm8 codegen basically does all stack-pointer-changing stuff in the >>> three functions push(), pop() and adjustStack(). Does that help in any way? >>> >>> The stm8 codegen also supports the use of a frame-pointer, which >>> currently is rarely used. If it is useful for debugging, I could however >>> easily implement --fno-omit-frame-pointer for stm8. If we can get CFA working fp is not required or even desirable. > Line 356 in src/stm8/gen.c handles the variable access using the frame > pointer. Line 3050 does the frame pointer setup. However, the caller is > responsible for saving and restoring the frame pointer, so it might be > unavailable for a short while after a function call. > Support for the frame pointer has been in there for a long time: The > offsets for sp-relative addressing on the STM8 are 8-bit only, while we > can use 16-bit offsets on the register y, which is used as a frame > pointer. We thus use the frame pointer when there is so much stack space > used by local variables that we can't use sp-relative addressing for all > them. Ok, *that* I've seen. Well I was not sure if the Y register would be available at all times (except during prologue). Also the requirement for frame unwinding to work in gdb is the prologue is consistent and possible to disassemble in a reliable way. Anyhow it was quick patch just a few lines of code to get a soft fp. /Ake |
|
From: Åke R. <ake...@gm...> - 2017-05-10 21:45:14
|
On 2017-05-10 23:40, Åke Rehnman wrote: > Ok, *that* I've seen. Well I was not sure if the Y register would be > available at all times (except during prologue). Also the requirement > for frame unwinding to work in gdb is the prologue is consistent and > possible to disassemble in a reliable way. Anyhow it was quick patch > just a few lines of code to get a soft fp. > To make things clear: If we can get the CFA to work we don't need any frame pointer stuff at all nor disassembly of prologue. |