gdb.dwarf2: Define and use gdb_target_symbol_prefix for symbol prefixes
Commit Message
Some of the tests in gdb.dwarf2 which use Dwarf::assemble refer to
(minimal/linker) symbols created in the course of building a small
test program. Some targets use a prefix such as underscore ("_") on
these symbols. Many of the tests in gdb.dwarf2 do not take this into
account. As a consequence, these tests fail to build, resulting
either in failures or untested testcases.
Here is an example from gdb.dwarf2/dw2-regno-invalid.exp:
Dwarf::assemble $asm_file {
cu {} {
compile_unit {
{low_pc main DW_FORM_addr}
{high_pc main+0x10000 DW_FORM_addr}
} {
...
}
For targets which require an underscore prefix on linker symbols,
the two occurrences of "main" would have to have a prepended underscore,
i.e. _main instead of main.
gdb/testsuite/ChangeLog:
* lib/gdb.exp (gdb_target_symbol_prefix): New proc.
* gdb.dwarf2/atomic-type.exp (Dwarf::assemble): Fetch
linker symbol prefix and prepend it to f.
* gdb.dwarf2/data-loc.exp (Dwarf::assemble): Fetch linker
symbol prefix and prepend it to table_1 and table_2.
* gdb.dwarf2/dw2-bad-mips-linkage-name.exp (Dwarf::assemble): Fetch
linker symbol prefix and prepend it to f and g.
* gdb.dwarf2/dw2-ifort-parameter.exp (Dwarf::assemble): Fetch
linker symbol prefix and prepend it to ptr.
* gdb.dwarf2/dw2-regno-invalid.exp (Dwarf::assemble): Fetch linker
symbol prefix and prepend it to main.
* gdb.dwarf2/dynarr-ptr.exp (Dwarf::assemble): Fetch linker symbol
prefix and prepend it to table_1_ptr and table_2_ptr.
---
gdb/testsuite/gdb.dwarf2/atomic-type.exp | 4 ++-
gdb/testsuite/gdb.dwarf2/data-loc.exp | 10 +++---
.../gdb.dwarf2/dw2-bad-mips-linkage-name.exp | 6 ++--
gdb/testsuite/gdb.dwarf2/dw2-ifort-parameter.exp | 3 +-
gdb/testsuite/gdb.dwarf2/dw2-regno-invalid.exp | 10 +++---
gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp | 10 +++---
gdb/testsuite/lib/gdb.exp | 39 ++++++++++++++++++++++
7 files changed, 66 insertions(+), 16 deletions(-)
Comments
On Thu, 29 Oct 2015 21:25:09 -0700
Kevin Buettner <kevinb@redhat.com> wrote:
> Some of the tests in gdb.dwarf2 which use Dwarf::assemble refer to
> (minimal/linker) symbols created in the course of building a small
> test program. Some targets use a prefix such as underscore ("_") on
> these symbols. Many of the tests in gdb.dwarf2 do not take this into
> account. As a consequence, these tests fail to build, resulting
> either in failures or untested testcases.
Several of the .S files in gdb.dwarf2 have the same problem. E.g.
when linking the test case for gdb.dwarf2/method-ptr.exp, I see a
linker error "undefined reference to `main'". It appears that crt0
is generating a reference to _main, but the .S file only provides a
reference to main.
Any thoughts on what to do about this?
(It occurs to me that I could define both _main and main in the .S
file, but this doesn't solve the problem should some other prefix be
used instead.)
Kevin
On 10/30/2015 04:25 AM, Kevin Buettner wrote:
> diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
> index 048070b..f8e35ac 100644
> --- a/gdb/testsuite/lib/gdb.exp
> +++ b/gdb/testsuite/lib/gdb.exp
> @@ -5521,6 +5521,45 @@ proc core_find {binfile {deletefiles {}} {arg ""}} {
> return $destcore
> }
>
> +# gdb_target_symbol_prefix compiles a test program and uses readelf
> +# to determine the prefix (such as underscore) for linker symbol
> +# prefixes.
> +
> +proc gdb_target_symbol_prefix {} {
Shouldn't this be gdb_caching_proc ?
Then T wonder whether something like:
- DW_OP_addr table_2_ptr
+ DW_OP_addr [gdb_symbol table_2_ptr]
instead of prepending the $prefix variable results in clearer
test code.
> + set readelf_program [gdb_find_readelf]
> + set result [catch "exec $readelf_program --syms $exe" output]
> +
> + if { $result == 0 \
> + && ![regexp { ([^ a-zA-Z0-9]*)main$} $output dummy prefix] } {
> + verbose "gdb_target_symbol_prefix: Could not find main in readelf output; returning null prefix" 2
> + }
I'm wondering about using a method that would work for mingw/cygwin
as well. The only existing use of the target symbol prefix in the
tree is for those targets, which are coff/pe, not elf. See
gdb_target_symbol_prefix_flags. Maybe just use objdump instead?
Thanks,
Pedro Alves
On 10/30/2015 05:25 AM, Kevin Buettner wrote:
> On Thu, 29 Oct 2015 21:25:09 -0700
> Kevin Buettner <kevinb@redhat.com> wrote:
>
>> Some of the tests in gdb.dwarf2 which use Dwarf::assemble refer to
>> (minimal/linker) symbols created in the course of building a small
>> test program. Some targets use a prefix such as underscore ("_") on
>> these symbols. Many of the tests in gdb.dwarf2 do not take this into
>> account. As a consequence, these tests fail to build, resulting
>> either in failures or untested testcases.
>
> Several of the .S files in gdb.dwarf2 have the same problem. E.g.
> when linking the test case for gdb.dwarf2/method-ptr.exp, I see a
> linker error "undefined reference to `main'". It appears that crt0
> is generating a reference to _main, but the .S file only provides a
> reference to main.
>
> Any thoughts on what to do about this?
Isn't this being addressed by gdb_target_symbol_prefix_flags in
the existing tests that use it? E.g., gdb.arch/i386-bp_permanent.c:
#ifdef SYMBOL_PREFIX
#define SYMBOL(str) SYMBOL_PREFIX #str
#else
#define SYMBOL(str) #str
#endif
...
#ifdef __x86_64__
asm(".text\n"
" .align 8\n"
SYMBOL (standard) ":\n"
Thanks,
Pedro Alves
On Fri, 30 Oct 2015 11:11:33 +0000
Pedro Alves <palves@redhat.com> wrote:
> On 10/30/2015 05:25 AM, Kevin Buettner wrote:
> > On Thu, 29 Oct 2015 21:25:09 -0700
> > Kevin Buettner <kevinb@redhat.com> wrote:
> >
> >> Some of the tests in gdb.dwarf2 which use Dwarf::assemble refer to
> >> (minimal/linker) symbols created in the course of building a small
> >> test program. Some targets use a prefix such as underscore ("_") on
> >> these symbols. Many of the tests in gdb.dwarf2 do not take this into
> >> account. As a consequence, these tests fail to build, resulting
> >> either in failures or untested testcases.
> >
> > Several of the .S files in gdb.dwarf2 have the same problem. E.g.
> > when linking the test case for gdb.dwarf2/method-ptr.exp, I see a
> > linker error "undefined reference to `main'". It appears that crt0
> > is generating a reference to _main, but the .S file only provides a
> > reference to main.
> >
> > Any thoughts on what to do about this?
>
> Isn't this being addressed by gdb_target_symbol_prefix_flags in
> the existing tests that use it? E.g., gdb.arch/i386-bp_permanent.c:
>
> #ifdef SYMBOL_PREFIX
> #define SYMBOL(str) SYMBOL_PREFIX #str
> #else
> #define SYMBOL(str) #str
> #endif
>
> ...
>
> #ifdef __x86_64__
> asm(".text\n"
> " .align 8\n"
> SYMBOL (standard) ":\n"
This seems like the right general approach, but it appears to me that
the current mechanism is broken for assembly files.
For targets which need an _ prefix, gdb_target_symbol_prefix_flags
returns this:
additional_flags=-DSYMBOL_PREFIX="_"
(The code in question escapes the double quotes. I don't show that here.)
When the compiler is invoked, the relevant part of the command line
looks something like this:
rx-elf-gcc -DSYMBOL_PREFIX="_" ...
This is invoked via tcl and not via bash or similar shell. Therefore, the
value of SYMBOL_PREFIX is actually "_" (with the quotes).
(For a while, I was puzzled about why things worked in when I pasted,
into bash, the exact command from log output that showed an error. It
turns out that bash was eliminating the quotes as part of its argument
processing. When I pasted the command into tclsh instead, I was able
to reproduce the error.)
Anyway, with those quotes in place, the macro defining SYMBOL will work
just fine for inline assembler in C/C++.
But for a .S file, we need to do something like this (as shown in
gdb.arch/i386-float.S):
#define CONCAT1(a, b) CONCAT2(a, b)
#define CONCAT2(a, b) a ## b
#ifdef SYMBOL_PREFIX
# define SYMBOL(str) CONCAT1(SYMBOL_PREFIX, str)
#else
# define SYMBOL(str) str
#endif
.text
.globl SYMBOL(main)
SYMBOL(main):
I don't understand the reason for both CONCAT1 and CONCAT2, but when
I use this code in one of the files that I'm working on, I end
up seeing an error due to the double quotes. Here's the source:
#define CONCAT1(a, b) CONCAT2(a, b)
#define CONCAT2(a, b) a ## b
#ifdef SYMBOL_PREFIX
# define SYMBOL(str) CONCAT1(SYMBOL_PREFIX, str)
#else
# define SYMBOL(str) str
#endif
.text
SYMBOL(main): .globl SYMBOL(main)
...
And this is what it translates to:
.text
"_"main: .globl "_"main
I don't think there's any way to, within the C preprocessor, strip
the quotes from the _.
It seems to me that the way to fix this is to make
gdb_target_symbol_prefix_flags return an unquoted prefix. I.e.
it should return:
additional_flags=-DSYMBOL_PREFIX=_
instead of:
additional_flags=-DSYMBOL_PREFIX="_"
Then, within C files, SYMBOL is defined as follows:
#ifdef SYMBOL_PREFIX
#define SYMBOL(str) #SYMBOL_PREFIX #str
#else
#define SYMBOL(str) #str
#endif
Note that this is the same as before, except that I added a # to
the front of SYMBOL_PREFIX. It's possible that this won't work -
we might end up with "SYMBOL_PREFIX" instead of "_" for the prefix.
If that's the case, then some layering is needed, perhaps something
like this:
#define STRCAT1(a,b) #a #b
#ifdef SYMBOL_PREFIX
#define SYMBOL(str) STRCAT1(SYMBOL_PREFIX,str)
#else
#define SYMBOL(str) #str
#endif
I'm willing to make these changes, but I want to first be sure that
I'm not missing an easier fix.
Kevin
On 11/05/2015 06:39 AM, Kevin Buettner wrote:
> On Fri, 30 Oct 2015 11:11:33 +0000
> Pedro Alves <palves@redhat.com> wrote:
> But for a .S file, we need to do something like this (as shown in
> gdb.arch/i386-float.S):
>
> #define CONCAT1(a, b) CONCAT2(a, b)
> #define CONCAT2(a, b) a ## b
>
> #ifdef SYMBOL_PREFIX
> # define SYMBOL(str) CONCAT1(SYMBOL_PREFIX, str)
> #else
> # define SYMBOL(str) str
> #endif
>
> .text
> .globl SYMBOL(main)
> SYMBOL(main):
>
> I don't understand the reason for both CONCAT1 and CONCAT2,
You need two levels in order to first expand SYMBOL_PREFIX, and
then concat the result. Otherwise SYMBOL(main) expands to
literally "SYMBOL_PREFIXmain" (minus quotes).
> It seems to me that the way to fix this is to make
> gdb_target_symbol_prefix_flags return an unquoted prefix. I.e.
> it should return:
>
> additional_flags=-DSYMBOL_PREFIX=_
>
> instead of:
>
> additional_flags=-DSYMBOL_PREFIX="_"
Yup.
>
> Then, within C files, SYMBOL is defined as follows:
>
> #ifdef SYMBOL_PREFIX
> #define SYMBOL(str) #SYMBOL_PREFIX #str
> #else
> #define SYMBOL(str) #str
> #endif
>
> Note that this is the same as before, except that I added a # to
> the front of SYMBOL_PREFIX. It's possible that this won't work -
It wont. # can only be used with a macro parameter.
> we might end up with "SYMBOL_PREFIX" instead of "_" for the prefix.
> If that's the case, then some layering is needed, perhaps something
> like this:
>
> #define STRCAT1(a,b) #a #b
> #ifdef SYMBOL_PREFIX
> #define SYMBOL(str) STRCAT1(SYMBOL_PREFIX,str)
> #else
> #define SYMBOL(str) #str
> #endif
>
That still needs double expansion.
> I'm willing to make these changes, but I want to first be sure that
> I'm not missing an easier fix.
IMO, it's clearer to separate the concerns -- concatenation
and final stringification.
Start with the usual concatenation:
#define CONCAT1(a, b) CONCAT2(a, b)
#define CONCAT2(a, b) a ## b
#ifdef SYMBOL_PREFIX
# define SYMBOL1(str) CONCAT1(SYMBOL_PREFIX, str)
#else
# define SYMBOL1(str) str
#endif
Then add a stringification layer:
#define STR1(s) #s
#define STR(s) STR1(s)
#define SYMBOL(str) STR(SYMBOL1(str))
This way you have these expansions:
SYMBOL1(main) -> _main
SYMBOL(main) -> "_main"
Thanks,
Pedro Alves
On 11/05/2015 10:46 AM, Pedro Alves wrote:
>> > I'm willing to make these changes, but I want to first be sure that
>> > I'm not missing an easier fix.
BTW, an alternative to the below would be to have two tcl procedures,
one for asm, and another for C/C++/etc, like
gdb_target_symbol_prefix_flags_asm / gdb_target_symbol_prefix_flags.
The C version would just call the asm version and add the double
quotes.
Thanks,
Pedro Alves
> IMO, it's clearer to separate the concerns -- concatenation
> and final stringification.
>
> Start with the usual concatenation:
>
> #define CONCAT1(a, b) CONCAT2(a, b)
> #define CONCAT2(a, b) a ## b
>
> #ifdef SYMBOL_PREFIX
> # define SYMBOL1(str) CONCAT1(SYMBOL_PREFIX, str)
> #else
> # define SYMBOL1(str) str
> #endif
>
>
> Then add a stringification layer:
>
> #define STR1(s) #s
> #define STR(s) STR1(s)
>
> #define SYMBOL(str) STR(SYMBOL1(str))
>
>
> This way you have these expansions:
>
> SYMBOL1(main) -> _main
> SYMBOL(main) -> "_main"
On Thu, 05 Nov 2015 10:54:56 +0000
Pedro Alves <palves@redhat.com> wrote:
> On 11/05/2015 10:46 AM, Pedro Alves wrote:
> >> > I'm willing to make these changes, but I want to first be sure that
> >> > I'm not missing an easier fix.
>
> BTW, an alternative to the below would be to have two tcl procedures,
> one for asm, and another for C/C++/etc, like
> gdb_target_symbol_prefix_flags_asm / gdb_target_symbol_prefix_flags.
> The C version would just call the asm version and add the double
> quotes.
This is a really good idea. It means that I don't need to touch
already working test cases contained in .c files. Also, the SYMBOL
macros contained therein stay simpler and (presumably) easier to
maintain.
I've just posted a patch implementing this idea. See:
https://sourceware.org/ml/gdb-patches/2015-11/msg00192.html
Thanks!
Kevin
@@ -25,6 +25,8 @@ standard_testfile atomic.c atomic-type-dw.S
set asm_file [standard_output_file $srcfile2]
Dwarf::assemble $asm_file {
+ set prefix [gdb_target_symbol_prefix]
+
cu {} {
DW_TAG_compile_unit {
{DW_AT_language @DW_LANG_C11}
@@ -68,7 +70,7 @@ Dwarf::assemble $asm_file {
DW_TAG_subprogram {
{name f}
- {low_pc f addr}
+ {low_pc ${prefix}f addr}
{high_pc f_end_lbl addr}
{type :$i_l}
} {
@@ -36,6 +36,8 @@ if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
# Make some DWARF for the test.
set asm_file [standard_output_file $srcfile2]
Dwarf::assemble $asm_file {
+ set prefix [gdb_target_symbol_prefix]
+
cu {} {
DW_TAG_compile_unit {
{DW_AT_language @DW_LANG_Ada95}
@@ -84,7 +86,7 @@ Dwarf::assemble $asm_file {
{DW_AT_name foo__three}
{DW_AT_type :$array_label}
{DW_AT_location {
- DW_OP_addr table_1
+ DW_OP_addr ${prefix}table_1
} SPECIAL_expr}
{external 1 flag}
}
@@ -92,7 +94,7 @@ Dwarf::assemble $asm_file {
{DW_AT_name foo__three_tdef}
{DW_AT_type :$array_ptr_label}
{DW_AT_location {
- DW_OP_addr table_1
+ DW_OP_addr ${prefix}table_1
} SPECIAL_expr}
{external 1 flag}
}
@@ -100,7 +102,7 @@ Dwarf::assemble $asm_file {
{DW_AT_name foo__five}
{DW_AT_type :$array_label}
{DW_AT_location {
- DW_OP_addr table_2
+ DW_OP_addr ${prefix}table_2
} SPECIAL_expr}
{external 1 flag}
}
@@ -108,7 +110,7 @@ Dwarf::assemble $asm_file {
{DW_AT_name foo__five_tdef}
{DW_AT_type :$array_ptr_label}
{DW_AT_location {
- DW_OP_addr table_2
+ DW_OP_addr ${prefix}table_2
} SPECIAL_expr}
{external 1 flag}
}
@@ -26,6 +26,8 @@ standard_testfile dw2-bad-mips-linkage-name.c dw2-bad-mips-linkage-name.S
set asm_file [standard_output_file $srcfile2]
Dwarf::assemble $asm_file {
+ set prefix [gdb_target_symbol_prefix]
+
cu {} {
DW_TAG_compile_unit {
{DW_AT_language @DW_LANG_C}
@@ -42,14 +44,14 @@ Dwarf::assemble $asm_file {
}
DW_TAG_subprogram {
{name f}
- {low_pc f addr}
+ {low_pc ${prefix}f addr}
{high_pc f_end_lbl addr}
{type :$b_l}
{DW_AT_MIPS_linkage_name _Z1fv}
}
DW_TAG_subprogram {
{name g}
- {low_pc g addr}
+ {low_pc ${prefix}g addr}
{high_pc g_end_lbl addr}
{type :$b_l}
{DW_AT_MIPS_linkage_name 42 DW_FORM_data1}
@@ -27,6 +27,7 @@ standard_testfile .c dw2-ifort-parameter-dw.S
# Make some DWARF for the test.
set asm_file [standard_output_file $srcfile2]
Dwarf::assemble $asm_file {
+ set prefix [gdb_target_symbol_prefix]
declare_labels int_label
extern func_start func_end ptr
@@ -53,7 +54,7 @@ Dwarf::assemble $asm_file {
{variable_parameter 1 flag}
{type :$int_label}
{location {
- addr ptr
+ addr ${prefix}ptr
deref
} SPECIAL_expr}
}
@@ -27,10 +27,12 @@ standard_testfile .S main.c
# Make some DWARF for the test.
set asm_file [standard_output_file $srcfile]
Dwarf::assemble $asm_file {
+ set prefix [gdb_target_symbol_prefix]
+
cu {} {
compile_unit {
- {low_pc main DW_FORM_addr}
- {high_pc main+0x10000 DW_FORM_addr}
+ {low_pc ${prefix}main DW_FORM_addr}
+ {high_pc ${prefix}main+0x10000 DW_FORM_addr}
} {
declare_labels integer_label
@@ -43,8 +45,8 @@ Dwarf::assemble $asm_file {
DW_TAG_subprogram {
{name main}
{DW_AT_external 1 flag}
- {low_pc main DW_FORM_addr}
- {high_pc main+0x10000 DW_FORM_addr}
+ {low_pc ${prefix}main DW_FORM_addr}
+ {high_pc ${prefix}main+0x10000 DW_FORM_addr}
} {
DW_TAG_variable {
{DW_AT_name bregx}
@@ -36,6 +36,8 @@ if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
# Make some DWARF for the test.
set asm_file [standard_output_file $srcfile2]
Dwarf::assemble $asm_file {
+ set prefix [gdb_target_symbol_prefix]
+
cu {} {
DW_TAG_compile_unit {
{DW_AT_language @DW_LANG_Ada95}
@@ -85,7 +87,7 @@ Dwarf::assemble $asm_file {
{DW_AT_name foo__three_ptr}
{DW_AT_type :$array_ptr_label}
{DW_AT_location {
- DW_OP_addr table_1_ptr
+ DW_OP_addr ${prefix}table_1_ptr
} SPECIAL_expr}
{external 1 flag}
}
@@ -93,7 +95,7 @@ Dwarf::assemble $asm_file {
{DW_AT_name foo__three_ptr_tdef}
{DW_AT_type :$array_typedef_label}
{DW_AT_location {
- DW_OP_addr table_1_ptr
+ DW_OP_addr ${prefix}table_1_ptr
} SPECIAL_expr}
{external 1 flag}
}
@@ -101,7 +103,7 @@ Dwarf::assemble $asm_file {
{DW_AT_name foo__five_ptr}
{DW_AT_type :$array_ptr_label}
{DW_AT_location {
- DW_OP_addr table_2_ptr
+ DW_OP_addr ${prefix}table_2_ptr
} SPECIAL_expr}
{external 1 flag}
}
@@ -109,7 +111,7 @@ Dwarf::assemble $asm_file {
{DW_AT_name foo__five_ptr_tdef}
{DW_AT_type :$array_typedef_label}
{DW_AT_location {
- DW_OP_addr table_2_ptr
+ DW_OP_addr ${prefix}table_2_ptr
} SPECIAL_expr}
{external 1 flag}
}
@@ -5521,6 +5521,45 @@ proc core_find {binfile {deletefiles {}} {arg ""}} {
return $destcore
}
+# gdb_target_symbol_prefix compiles a test program and uses readelf
+# to determine the prefix (such as underscore) for linker symbol
+# prefixes.
+
+proc gdb_target_symbol_prefix {} {
+ # Set up and compile a simple test program...
+ set src [standard_temp_file main[pid].c]
+ set exe [standard_temp_file main[pid].x]
+
+ gdb_produce_source $src {
+ int main() {
+ return 0;
+ }
+ }
+
+ verbose "compiling testfile $src" 2
+ set compile_flags {debug nowarnings quiet}
+ set lines [gdb_compile $src $exe executable $compile_flags]
+
+ set prefix ""
+
+ if ![string match "" $lines] then {
+ verbose "gdb_target_symbol_prefix: testfile compilation failed, returning null prefix" 2
+ } else {
+ set readelf_program [gdb_find_readelf]
+ set result [catch "exec $readelf_program --syms $exe" output]
+
+ if { $result == 0 \
+ && ![regexp { ([^ a-zA-Z0-9]*)main$} $output dummy prefix] } {
+ verbose "gdb_target_symbol_prefix: Could not find main in readelf output; returning null prefix" 2
+ }
+ }
+
+ file delete $src
+ file delete $exe
+
+ return $prefix
+}
+
# gdb_target_symbol_prefix_flags returns a string that can be added
# to gdb_compile options to define SYMBOL_PREFIX macro value
# symbol_prefix_flags returns a string that can be added