public inbox for frysk@sourceware.org
 help / color / mirror / Atom feed
* which elf symbol?
@ 2007-07-23 16:57 Andrew Cagney
  2007-07-26  2:27 ` Roland McGrath
  0 siblings, 1 reply; 4+ messages in thread
From: Andrew Cagney @ 2007-07-23 16:57 UTC (permalink / raw)
  To: frysk, Roland McGrath

Hi,

I've replaced the frysk-stackframe program with an expanded 
frysk-symbols program that has more elf symbol lookup edge cases; for 
instance nested symbols.  I've also expanded frysk.rt.TestSymbol to 
exercise them.  For some of the cases though, the results are not what I 
expected.   I've noted the failures below and provided a simplified 
assembler.

1) 
testGlobalAfterNested(frysk.rt.TestSymbol)junit.framework.ComparisonFailure: 
symbol global_outer expected:<global_outer> but was:<local_st_size_0>
   at frysk.rt.TestSymbol.symbolTest(TestRunner)
   at frysk.rt.TestSymbol.testGlobalAfterNested(TestRunner)
   at frysk.junit.Runner.runCases(TestRunner)
   at frysk.junit.Runner.runArchCases(TestRunner)
   at frysk.junit.Runner.runTestCases(TestRunner)
   at TestRunner.main(TestRunner)
2) 
testLocalAfterNested(frysk.rt.TestSymbol)junit.framework.ComparisonFailure: 
symbol local_outer expected:<...outer> but was:<...st_size_0>
   at frysk.rt.TestSymbol.symbolTest(TestRunner)
   at frysk.rt.TestSymbol.testLocalAfterNested(TestRunner)
   at frysk.junit.Runner.runCases(TestRunner)
   at frysk.junit.Runner.runArchCases(TestRunner)
   at frysk.junit.Runner.runTestCases(TestRunner)
   at TestRunner.main(TestRunner)

These two are effectively the same.  The layout is:

    local_st_size_0: // this symbol has no size

    global_outer:
        nop
        local_in_global:
          nop
          .size local_in_global, .-local_in_global
       nop
       <<you-are-here>>
       .size global_outer, .-global_outer

that is global_outer contains a nested symbol but the "pc" is beyond 
that back in the outer/global symbol.

I'm guessing that "global_outer" should be returned.  Currently 
local_st_size_0 is returned :-(


3) 
testNoSymbolAfterGlobal(frysk.rt.TestSymbol)junit.framework.ComparisonFailure: 
symbol [unknown] expected:<[unknown]> but was:<local_st_size_0>
   at frysk.rt.TestSymbol.symbolTest(TestRunner)
   at frysk.rt.TestSymbol.testNoSymbolAfterGlobal(TestRunner)
   at frysk.junit.Runner.runCases(TestRunner)
   at frysk.junit.Runner.runArchCases(TestRunner)
   at frysk.junit.Runner.runTestCases(TestRunner)
   at TestRunner.main(TestRunner)
4) 
testNoSymbolAfterLocal(frysk.rt.TestSymbol)junit.framework.ComparisonFailure: 
symbol [unknown] expected:<[unknown]> but was:<local_st_size_0>
   at frysk.rt.TestSymbol.symbolTest(TestRunner)
   at frysk.rt.TestSymbol.testNoSymbolAfterLocal(TestRunner)
   at frysk.junit.Runner.runCases(TestRunner)
   at frysk.junit.Runner.runArchCases(TestRunner)
   at frysk.junit.Runner.runTestCases(TestRunner)
   at TestRunner.main(TestRunner)

This is the no-symbol case, there is a hole in the memory where there is 
no valid symbol vis:

    local_st_size_0: // this symbol has no size

    global_symbol:
       nop
       nop
       .size global_symbol, .-global_symbol

    << you are here >>

I'm guessing it should not get a symbol at all (the [unknown]).  It 
currently gets the nearest unsized symbol.

5) 
testGlobalSize0InGlobal(frysk.rt.TestSymbol)junit.framework.ComparisonFailure: 
symbol global_0_in_global expected:<...0_in_global> but was:<...after_0>
   at frysk.rt.TestSymbol.symbolTest(TestRunner)
   at frysk.rt.TestSymbol.testGlobalSize0InGlobal(TestRunner)
   at frysk.junit.Runner.runCases(TestRunner)
   at frysk.junit.Runner.runArchCases(TestRunner)
   at frysk.junit.Runner.runTestCases(TestRunner)
   at TestRunner.main(TestRunner)
6) 
testLocalSize0InGlobal(frysk.rt.TestSymbol)junit.framework.ComparisonFailure: 
symbol local_0_in_global expected:<local_0_in_global> but 
was:<global_after_0>
   at frysk.rt.TestSymbol.symbolTest(TestRunner)
   at frysk.rt.TestSymbol.testLocalSize0InGlobal(TestRunner)
   at frysk.junit.Runner.runCases(TestRunner)
   at frysk.junit.Runner.runArchCases(TestRunner)
   at frysk.junit.Runner.runTestCases(TestRunner)
   at TestRunner.main(TestRunner)
7) 
testGlobalSize0InLocal(frysk.rt.TestSymbol)junit.framework.ComparisonFailure: 
symbol global_0_in_local expected:<global_0_in_local> but 
was:<local_after_0>
   at frysk.rt.TestSymbol.symbolTest(TestRunner)
   at frysk.rt.TestSymbol.testGlobalSize0InLocal(TestRunner)
   at frysk.junit.Runner.runCases(TestRunner)
   at frysk.junit.Runner.runArchCases(TestRunner)
   at frysk.junit.Runner.runTestCases(TestRunner)
   at TestRunner.main(TestRunner)
8) 
testLocalSize0InLocal(frysk.rt.TestSymbol)junit.framework.ComparisonFailure: 
symbol local_0_in_local expected:<...0_in_local> but was:<...after_0>
   at frysk.rt.TestSymbol.symbolTest(TestRunner)
   at frysk.rt.TestSymbol.testLocalSize0InLocal(TestRunner)
   at frysk.junit.Runner.runCases(TestRunner)
   at frysk.junit.Runner.runArchCases(TestRunner)
   at frysk.junit.Runner.runTestCases(TestRunner)
   at TestRunner.main(TestRunner)

These are cases where there is a nested symbol within a sized symbol vis:

    global_after_0:
       nop
       local_0_in_global:
          << you are here >>
       nop
       .size global_after_0, .-global_after_0

here, since the PC is exactly at the unsized local symbol I'm guessing 
that it should return that.  It currently gets the containing sized symbol.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: which elf symbol?
  2007-07-23 16:57 which elf symbol? Andrew Cagney
@ 2007-07-26  2:27 ` Roland McGrath
  2007-07-26 22:30   ` Andrew Cagney
  0 siblings, 1 reply; 4+ messages in thread
From: Roland McGrath @ 2007-07-26  2:27 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: frysk

I reduced your report to an isolated test case of trivial assembly.  I've
slightly modified addr2line so I'm using it as a test program with -e on
the .o file to just print out the results of dwfl_module_addrsym.
Please help me adjust this test case to match (or also include) cases
equivalent to what you are seeing.

		.globl t1_global_outer

	t1_local_st_size_0:

	t1_global_outer:
		nop
	t1_local_in_global:
		nop
	.size t1_local_in_global, .-t1_local_in_global
	1:	nop
	      .size t1_global_outer, .-t1_global_outer

	.space 100
	.balign 8

		.globl t2_global_symbol

	t2_local_st_size_0:

	t2_global_symbol:
	      nop
	      nop
	.size t2_global_symbol, .-t2_global_symbol
	2:

	.space 100
	.balign 8

		.globl t3_global_after_0

	t3_global_after_0:
		nop
	t3_local_0_in_global:
	3:
	      nop
	      .size t3_global_after_0, .-t3_global_after_0

	.data
	t1_pc_of_interest: .long 1b
	t2_pc_of_interest: .long 2b
	t3_pc_of_interest: .long 3b

as on that produces the following (readelf -rs; objdump -d).  The reloc
addends tell you the "pc_of_interest" values.  On i386 (non-rela), you'd
need to look at objdump -s -j .data instead to see them.

	Relocation section '.rela.data' at offset 0x560 contains 3 entries:
	  Offset          Info           Type           Sym. Value    Sym. Name + Addend
	000000000000  00010000000a R_X86_64_32       0000000000000000 .text + 2
	000000000004  00010000000a R_X86_64_32       0000000000000000 .text + 6a
	000000000008  00010000000a R_X86_64_32       0000000000000000 .text + d1

	Symbol table '.symtab' contains 14 entries:
	   Num:    Value          Size Type    Bind   Vis      Ndx Name
	     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
	     1: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
	     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    2 
	     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
	     4: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT    1 t1_local_st_size_0
	     5: 0000000000000001     1 NOTYPE  LOCAL  DEFAULT    1 t1_local_in_global
	     6: 0000000000000068     0 NOTYPE  LOCAL  DEFAULT    1 t2_local_st_size_0
	     7: 00000000000000d1     0 NOTYPE  LOCAL  DEFAULT    1 t3_local_0_in_global
	     8: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT    2 t1_pc_of_interest
	     9: 0000000000000004     0 NOTYPE  LOCAL  DEFAULT    2 t2_pc_of_interest
	    10: 0000000000000008     0 NOTYPE  LOCAL  DEFAULT    2 t3_pc_of_interest
	    11: 0000000000000000     3 NOTYPE  GLOBAL DEFAULT    1 t1_global_outer
	    12: 0000000000000068     2 NOTYPE  GLOBAL DEFAULT    1 t2_global_symbol
	    13: 00000000000000d0     2 NOTYPE  GLOBAL DEFAULT    1 t3_global_after_0

	addrsym-test.o:     file format elf64-x86-64

	Disassembly of section .text:

	0000000000000000 <t1_global_outer>:
	   0:	90                   	nop    

	0000000000000001 <t1_local_in_global>:
	   1:	90                   	nop    
	   2:	90                   	nop    
		...
	  67:	90                   	nop    

	0000000000000068 <t2_global_symbol>:
	  68:	90                   	nop    
	  69:	90                   	nop    
		...
	  ce:	66 90                	xchg   %ax,%ax

	00000000000000d0 <t3_global_after_0>:
	  d0:	90                   	nop    

	00000000000000d1 <t3_local_0_in_global>:
	  d1:	90                   	nop    

It's possible the order of symbols in the table is an issue.  So let me
know if those are different in your case.  

>     local_st_size_0: // this symbol has no size
> 
>     global_outer:
>         nop
>         local_in_global:
>           nop
>           .size local_in_global, .-local_in_global
>        nop
>        <<you-are-here>>
>        .size global_outer, .-global_outer
> 
> that is global_outer contains a nested symbol but the "pc" is beyond 
> that back in the outer/global symbol.
> 
> I'm guessing that "global_outer" should be returned.  Currently 
> local_st_size_0 is returned :-(

Arguably the answer should be no symbol, since the address is past the end
of the nearest symbol's size.

This is t1 in my test case, looking at pc=0x2.  I get t1_global_outer+0x2
from addrsym here, so my case must differ from what you tried here.
Can you figure out how they differ?

> This is the no-symbol case, there is a hole in the memory where there is 
> no valid symbol vis:
> 
>     local_st_size_0: // this symbol has no size
> 
>     global_symbol:
>        nop
>        nop
>        .size global_symbol, .-global_symbol
> 
>     << you are here >>
> 
> I'm guessing it should not get a symbol at all (the [unknown]).  It 
> currently gets the nearest unsized symbol.

This is t2 in my test case, looking at pc=0x6a.  
I get t2_local_st_size_0+0x2 here.  Go figure.

You wrote your marker in a different place, but there is no address
difference between the context before the .size directive in the assembly
source and the context after it.  So unless I'm misunderstanding what cases
you intended to describe, this should be the same case as t1.  (It doesn't
really matter that there is a local symbol nearby, since the PC of interest
is unambiguous outside that symbol's address range.)

I'll look into why they come out differently, which might relate to some
other symptom.  I also agree that the right answer is no symbol.

> These are cases where there is a nested symbol within a sized symbol vis:
> 
>     global_after_0:
>        nop
>        local_0_in_global:
>           << you are here >>
>        nop
>        .size global_after_0, .-global_after_0
> 
> here, since the PC is exactly at the unsized local symbol I'm guessing 
> that it should return that.  It currently gets the containing sized symbol.

This is my t3.  I get t3_global_after_0+0x1 as you say.  This is the
intended behavior, not a bug.  We can discuss what the behavior should be.  

	  /* Handwritten assembly symbols sometimes have no st_size.
	     If no symbol with proper size includes the address, we'll
	     use the closest one that is in the same section as ADDR.   */

Usually size-0 symbols are local assembler labels, and sized symbols are
the entry points.  For things like backtraces, people usually want to see
the symbol names for the entry points (plus offsets) rather than the local
labels that often have unhelpful names.  That's what I had in mind when I
wrote that.  addrsym started out as addrname, which does not pass back an
offset and only used for "what function is this in?" kinds of queries.  For
that, it clearly makes more sense to prefer the containing sized symbol.

However, for things like disassembly, people probably would like to see the
local label names, or perhaps both names.  


Thanks,
Roland

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: which elf symbol?
  2007-07-26  2:27 ` Roland McGrath
@ 2007-07-26 22:30   ` Andrew Cagney
  2007-08-07  7:52     ` Roland McGrath
  0 siblings, 1 reply; 4+ messages in thread
From: Andrew Cagney @ 2007-07-26 22:30 UTC (permalink / raw)
  To: Roland McGrath; +Cc: frysk

Roland McGrath wrote:
> I reduced your report to an isolated test case of trivial assembly.  I've
> slightly modified addr2line so I'm using it as a test program with -e on
> the .o file to just print out the results of dwfl_module_addrsym.
> Please help me adjust this test case to match (or also include) cases
> equivalent to what you are seeing.
>   

What about a case like:

symbol:
nop
unsized_symbol:
nop
.size symbol, .-symbol
1: <should not have a symbol?>

the closest symbol is unsized_symbol, but that is probably not the intent.

>   
>>     local_st_size_0: // this symbol has no size
>>
>>     global_outer:
>>         nop
>>         local_in_global:
>>           nop
>>           .size local_in_global, .-local_in_global
>>        nop
>>        <<you-are-here>>
>>        .size global_outer, .-global_outer
>>
>> that is global_outer contains a nested symbol but the "pc" is beyond 
>> that back in the outer/global symbol.
>>
>> I'm guessing that "global_outer" should be returned.  Currently 
>> local_st_size_0 is returned :-(
>>     
>
> Arguably the answer should be no symbol, since the address is past the end
> of the nearest symbol's size.
>   
the xample was unclear <<you-are-here>> is ment to be within 
global_outer; your test did that.
> This is t1 in my test case, looking at pc=0x2.  I get t1_global_outer+0x2
> from addrsym here, so my case must differ from what you tried here.
> Can you figure out how they differ?
>
>   

I'm looking.

>> This is the no-symbol case, there is a hole in the memory where there is 
>> no valid symbol vis:
>>
>>     local_st_size_0: // this symbol has no size
>>
>>     global_symbol:
>>        nop
>>        nop
>>        .size global_symbol, .-global_symbol
>>
>>     << you are here >>
>>
>> I'm guessing it should not get a symbol at all (the [unknown]).  It 
>> currently gets the nearest unsized symbol.
>>     
>
> This is t2 in my test case, looking at pc=0x6a.  
> I get t2_local_st_size_0+0x2 here.  Go figure.
>
> You wrote your marker in a different place, but there is no address
> difference between the context before the .size directive in the assembly
> source and the context after it.  So unless I'm misunderstanding what cases
> you intended to describe, this should be the same case as t1.  (It doesn't
> really matter that there is a local symbol nearby, since the PC of interest
> is unambiguous outside that symbol's address range.)
>
> I'll look into why they come out differently, which might relate to some
> other symptom.  I also agree that the right answer is no symbol.
>
>   
ok.

>> These are cases where there is a nested symbol within a sized symbol vis:
>>
>>     global_after_0:
>>        nop
>>        local_0_in_global:
>>           << you are here >>
>>        nop
>>        .size global_after_0, .-global_after_0
>>
>> here, since the PC is exactly at the unsized local symbol I'm guessing 
>> that it should return that.  It currently gets the containing sized symbol.
>>     
>
> This is my t3.  I get t3_global_after_0+0x1 as you say.  This is the
> intended behavior, not a bug.  We can discuss what the behavior should be.  
>
> 	  /* Handwritten assembly symbols sometimes have no st_size.
> 	     If no symbol with proper size includes the address, we'll
> 	     use the closest one that is in the same section as ADDR.   */
>
>   
Yes, agreed.  The sized symbol should trump the unsized one.

> Usually size-0 symbols are local assembler labels, and sized symbols are
> the entry points.  For things like backtraces, people usually want to see
> the symbol names for the entry points (plus offsets) rather than the local
> labels that often have unhelpful names.  That's what I had in mind when I
> wrote that.  addrsym started out as addrname, which does not pass back an
> offset and only used for "what function is this in?" kinds of queries.  For
> that, it clearly makes more sense to prefer the containing sized symbol.
>
> However, for things like disassembly, people probably would like to see the
> local label names, or perhaps both names.  
>
>   
That's an interesting option; it would better reflect exactly what is in 
the file.

Andrew

> Thanks,
> Roland
>   

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: which elf symbol?
  2007-07-26 22:30   ` Andrew Cagney
@ 2007-08-07  7:52     ` Roland McGrath
  0 siblings, 0 replies; 4+ messages in thread
From: Roland McGrath @ 2007-08-07  7:52 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: frysk

> What about a case like:
> 
> symbol:
> nop
> unsized_symbol:
> nop
> .size symbol, .-symbol
> 1: <should not have a symbol?>
> 
> the closest symbol is unsized_symbol, but that is probably not the intent.

Agreed.  I think the correct answer for 1: here is no symbol.
Below, this is case t4.

> Yes, agreed.  The sized symbol should trump the unsized one.

Based on what you've said I'm now looking at the following test cases.
For me, the current code gets all of these right except t4.  I had the
impression you had other cases where the current code yields the wrong
answer.  Please send me an assembly fragment in this style (e.g. t5, t6)
on which you've verified addrsym yields the wrong answer, or let me know
if cases like t4 are in fact the only specific known bug.  I'd like to
get these test cases firmly established ASAP, and before considering
additional facilities with different behavior as for disassembly.


Thanks,
Roland



	.globl t1_global_outer

t1_local_st_size_0:

t1_global_outer:
	nop
t1_local_in_global:
	nop
.size t1_local_in_global, .-t1_local_in_global
1:	nop	# the right answer is t1_global_outer
.size t1_global_outer, .-t1_global_outer

.space 0x100
.balign 8

	.globl t2_global_symbol

t2_local_st_size_0:

t2_global_symbol:
	nop
	nop
2: # the right answer is t2_global_symbol
	nop
.size t2_global_symbol, .-t2_global_symbol

.space 0x100
.balign 8

	.globl t3_global_after_0

t3_global_after_0:
	nop
t3_local_0_in_global:
3: # the right answer is t3_global_after_0
      nop
.size t3_global_after_0, .-t3_global_after_0

.space 0x100
.balign 8

	.globl t4_global

t4_global:
	nop
t4_local_0_in_global:
	nop
.size t4_global, .-t4_global
4: 	nop	# the right answer is no answer
	nop

.data
t1_pc_of_interest: .long 1b
t2_pc_of_interest: .long 2b
t3_pc_of_interest: .long 3b
t4_pc_of_interest: .long 4b

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2007-08-07  7:52 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-07-23 16:57 which elf symbol? Andrew Cagney
2007-07-26  2:27 ` Roland McGrath
2007-07-26 22:30   ` Andrew Cagney
2007-08-07  7:52     ` Roland McGrath

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).