* 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).