This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Broken .loc directive in GAS
- From: Michal Ludvig <mludvig at suse dot cz>
- To: binutils at sources dot redhat dot com
- Date: Thu, 10 Jul 2003 17:36:08 +0200
- Subject: Broken .loc directive in GAS
- Organization: SuSE CR, s.r.o.
Hi all,
while investigating a GDB testsuite failure I found out that .debug_line
section can sometimes be broken.
Take the example code temp.cc and compile it to temp.o:
$ g++ -g -c temp.cc
Inspecting .debug_line with 'readelf -wl temp.o' shows this:
[...]
Line Number Statements:
Extended opcode 2: set Address to 0x0
Special opcode 13: advance Address by 0 to 0x0 and Line by 8 to 9
Advance PC by 14 to e
Extended opcode 1: End of Sequence
Extended opcode 2: set Address to 0x0
Special opcode 13: advance Address by 0 to 0x0 and Line by 8 to 9
Advance PC by 14 to e
Extended opcode 1: End of Sequence
Extended opcode 2: set Address to 0x0
Advance Line by 16 to 17
Copy
Special opcode 62: advance Address by 4 to 0x4 and Line by 1 to 18
Special opcode 76: advance Address by 5 to 0x9 and Line by 1 to 19
Advance Line by -6 to 13
Special opcode 47: advance Address by 3 to 0xc and Line by 0 to 13
Special opcode 201: advance Address by 14 to 0x1a and Line by 0 to 13
Advance PC by constant 17 to 0x2b
Special opcode 215: advance Address by 15 to 0x3a and Line by 0 to 13
Special opcode 61: advance Address by 4 to 0x3e and Line by 0 to 13
Advance PC by 20 to 52
Extended opcode 1: End of Sequence
[...]
First two sequences are for constructors' sections and the third is for
the .text section.
What I don't understand are the last two lines in .text section, i.e.
Advance PC by 20 to 52
Extended opcode 1: End of Sequence
How does the GAS know it should advance the PC by 20? It probably
ment something like "Advance PC to the end of the section". Offset
0x52 points 2 bytes beyond the end of the section which triggers
problems when the file is linked:
$ g++ -o temp temp.o
$ readelf -wl temp
Then the .debug_line section (relevant part) is like this:
[...]
Extended opcode 2: set Address to 0x400546
[...]
Extended opcode 1: End of Sequence
Extended opcode 2: set Address to 0x400538
Special opcode 13: advance Address by 0 to 0x400538 and Line by 8 to 9
Advance PC by 14 to 400546
Extended opcode 1: End of Sequence
Extended opcode 2: set Address to 0x4004e8
[...]
Special opcode 61: advance Address by 4 to 0x400526 and Line by 0 to 13
Advance PC by 20 to 40053a
Extended opcode 1: End of Sequence
[...]
As you can see - second sequence starts at 0x400538 but third sequence
ends at 40053a, i.e. they overlap by two bytes. This confuses GDB
because it sorts the line numbers by their PC and overlapping sequences
don't make sense.
Everything written so far was seen on AMD64. However you can observe
exactly the same problem (off-by-2) on i386 as well.
The only difference is that i386 GCC puts another .loc mark right after
the function prologue, which is 3 bytes long, which eliminates the GDB
problem. This is not a correct solution however.
I suspect something is broken in the GAS - does anyone know these line
numbering internals?
I'm using gcc-3.3 and recent a snapshot of binutils (2.14.90 20030710)
but the version from January gives the same output.
Thans in advance for any hint!
Michal Ludvig
--
* SuSE CR, s.r.o * mludvig@suse.cz
* (+420) 296.545.373 * http://www.suse.cz
template<class T>
class T5 {
public:
T5(int);
};
template<class T>
T5<T>::T5(int val)
{
}
T5<int> t5i(2);
template class T5<int>;
int main()
{
return 0;
}