* baffling assembly-level weirdness
@ 2009-01-26 15:24 Mathieu Lacage
2009-01-26 15:38 ` Pierre Muller
2009-01-26 15:41 ` Daniel Jacobowitz
0 siblings, 2 replies; 7+ messages in thread
From: Mathieu Lacage @ 2009-01-26 15:24 UTC (permalink / raw)
To: gdb
hi,
The following gdb session baffles me completely: %edx is reset to zero
by the mov at address 0x0804ad62 instead of being set to the constant
0x804ad62. Of course, this code segfaults at $pc = 0x804ad68 when zero
is dereferenced...
Version: GNU gdb 6.8
(gdb) disas $pc $pc+10
Dump of assembler code from 0x804ad62 to 0x804ad6c:
0x0804ad62 <indent+50>: mov 0x805e3c0,%edx
0x0804ad68 <indent+56>: mov 0x14(%edx),%eax
0x0804ad6b <indent+59>: cmp 0x18(%edx),%eax
End of assembler dump.
(gdb) p $pc
$3 = (void (*)()) 0x804ad62 <indent+50>
(gdb) p $edx
$4 = 1
(gdb) ni
0x0804ad68 108 return _IO_putc_unlocked (__c, stdout);
(gdb) p $edx
$5 = 0
(gdb) disas $pc $pc+10
Dump of assembler code from 0x804ad68 to 0x804ad72:
0x0804ad68 <indent+56>: mov 0x14(%edx),%eax
0x0804ad6b <indent+59>: cmp 0x18(%edx),%eax
0x0804ad6e <indent+62>: jae 0x804adbe <indent+142>
0x0804ad70 <indent+64>: movb $0x20,(%eax)
End of assembler dump.
(gdb) x/20bx 0x0804ad62
0x804ad62 <indent+50>: 0x8b 0x15 0xc0 0xe3 0x05 0x08 0x8b 0x42
0x804ad6a <indent+58>: 0x14 0x3b 0x42 0x18 0x73 0x4e 0xc6 0x00
0x804ad72 <indent+66>: 0x20 0x83 0xc0 0x01
Anyone would have even a remote idea of what could have gone wrong here ?
Mathieu
--
Mathieu Lacage <mathieu.lacage@gmail.com>
^ permalink raw reply [flat|nested] 7+ messages in thread
* RE: baffling assembly-level weirdness
2009-01-26 15:24 baffling assembly-level weirdness Mathieu Lacage
@ 2009-01-26 15:38 ` Pierre Muller
2009-01-26 17:35 ` Mathieu Lacage
2009-01-26 15:41 ` Daniel Jacobowitz
1 sibling, 1 reply; 7+ messages in thread
From: Pierre Muller @ 2009-01-26 15:38 UTC (permalink / raw)
To: 'Mathieu Lacage', gdb
Hi,
maybe you are more used to intel disassembler
this is att disassembler
mov 0x805e3c0,%edx
means put the content of address 0x805e3c0 into register edx
putting the constant 0x805e3c0 into edx
would be written as
mov $0x805e3c0,%edx
if I am not mistaken.
If you are more used to intel assembly
you can use
'set disassembly-flavor intel'
In your case, this means that the generated code is faulty...
Pierre Muller
Pascal language support maintainer for GDB
> -----Message d'origine-----
> De : gdb-owner@sourceware.org [mailto:gdb-owner@sourceware.org] De la
> part de Mathieu Lacage
> Envoyé : Monday, January 26, 2009 4:25 PM
> À : gdb@sourceware.org
> Objet : baffling assembly-level weirdness
>
> hi,
>
> The following gdb session baffles me completely: %edx is reset to zero
> by the mov at address 0x0804ad62 instead of being set to the constant
> 0x804ad62. Of course, this code segfaults at $pc = 0x804ad68 when zero
> is dereferenced...
>
> Version: GNU gdb 6.8
>
> (gdb) disas $pc $pc+10
> Dump of assembler code from 0x804ad62 to 0x804ad6c:
> 0x0804ad62 <indent+50>: mov 0x805e3c0,%edx
> 0x0804ad68 <indent+56>: mov 0x14(%edx),%eax
> 0x0804ad6b <indent+59>: cmp 0x18(%edx),%eax
> End of assembler dump.
> (gdb) p $pc
> $3 = (void (*)()) 0x804ad62 <indent+50>
> (gdb) p $edx
> $4 = 1
> (gdb) ni
> 0x0804ad68 108 return _IO_putc_unlocked (__c, stdout);
> (gdb) p $edx
> $5 = 0
> (gdb) disas $pc $pc+10
> Dump of assembler code from 0x804ad68 to 0x804ad72:
> 0x0804ad68 <indent+56>: mov 0x14(%edx),%eax
> 0x0804ad6b <indent+59>: cmp 0x18(%edx),%eax
> 0x0804ad6e <indent+62>: jae 0x804adbe <indent+142>
> 0x0804ad70 <indent+64>: movb $0x20,(%eax)
> End of assembler dump.
> (gdb) x/20bx 0x0804ad62
> 0x804ad62 <indent+50>: 0x8b 0x15 0xc0 0xe3 0x05 0x08 0x8b 0x42
> 0x804ad6a <indent+58>: 0x14 0x3b 0x42 0x18 0x73 0x4e 0xc6 0x00
> 0x804ad72 <indent+66>: 0x20 0x83 0xc0 0x01
>
> Anyone would have even a remote idea of what could have gone wrong here
> ?
>
> Mathieu
> --
> Mathieu Lacage <mathieu.lacage@gmail.com>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: baffling assembly-level weirdness
2009-01-26 15:24 baffling assembly-level weirdness Mathieu Lacage
2009-01-26 15:38 ` Pierre Muller
@ 2009-01-26 15:41 ` Daniel Jacobowitz
2009-01-26 16:51 ` Paul Pluzhnikov
1 sibling, 1 reply; 7+ messages in thread
From: Daniel Jacobowitz @ 2009-01-26 15:41 UTC (permalink / raw)
To: Mathieu Lacage; +Cc: gdb
On Mon, Jan 26, 2009 at 04:24:40PM +0100, Mathieu Lacage wrote:
> hi,
>
> The following gdb session baffles me completely: %edx is reset to zero
> by the mov at address 0x0804ad62 instead of being set to the constant
> 0x804ad62. Of course, this code segfaults at $pc = 0x804ad68 when zero
> is dereferenced...
>
> Version: GNU gdb 6.8
>
> (gdb) disas $pc $pc+10
> Dump of assembler code from 0x804ad62 to 0x804ad6c:
> 0x0804ad62 <indent+50>: mov 0x805e3c0,%edx
This is a load from memory at address 0x805e3c0, in x86 syntax.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: baffling assembly-level weirdness
2009-01-26 15:41 ` Daniel Jacobowitz
@ 2009-01-26 16:51 ` Paul Pluzhnikov
2009-01-27 13:09 ` Mathieu Lacage
0 siblings, 1 reply; 7+ messages in thread
From: Paul Pluzhnikov @ 2009-01-26 16:51 UTC (permalink / raw)
To: Mathieu Lacage, gdb
On Mon, Jan 26, 2009 at 7:41 AM, Daniel Jacobowitz <drow@false.org> wrote:
> On Mon, Jan 26, 2009 at 04:24:40PM +0100, Mathieu Lacage wrote:
>> hi,
>>
>> The following gdb session baffles me completely: %edx is reset to zero
>> by the mov at address 0x0804ad62 instead of being set to the constant
>> 0x804ad62. Of course, this code segfaults at $pc = 0x804ad68 when zero
>> is dereferenced...
>>
>> Version: GNU gdb 6.8
>>
>> (gdb) disas $pc $pc+10
>> Dump of assembler code from 0x804ad62 to 0x804ad6c:
>> 0x0804ad62 <indent+50>: mov 0x805e3c0,%edx
>
> This is a load from memory at address 0x805e3c0, in x86 syntax.
Additional clues:
(gdb) p/a 0x805e3c0
will likely print "stdout". If you break in main, and do
(gbd) x/a 0x805e3c0
it will likely print something like:
0x8053ac0 <stdout>: 0x4dcdb5e0 <_IO_2_1_stdout_>
It sounds like your program is corrupting stdout somewhere.
The fastest way to find out where that happens:
(gdb) watch *(int **)0x8053ac0
Cheers,
--
Paul Pluzhnikov
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: baffling assembly-level weirdness
2009-01-26 15:38 ` Pierre Muller
@ 2009-01-26 17:35 ` Mathieu Lacage
0 siblings, 0 replies; 7+ messages in thread
From: Mathieu Lacage @ 2009-01-26 17:35 UTC (permalink / raw)
To: Pierre Muller; +Cc: gdb
On Mon, Jan 26, 2009 at 4:38 PM, Pierre Muller <muller@ics.u-strasbg.fr> wrote:
> maybe you are more used to intel disassembler
> this is att disassembler
> mov 0x805e3c0,%edx
> means put the content of address 0x805e3c0 into register edx
> putting the constant 0x805e3c0 into edx
> would be written as
> mov $0x805e3c0,%edx
> if I am not mistaken.
doh. It's hard to apologize for such a stupid mistake, so I won't try
but, thanks to all those who answered.
> If you are more used to intel assembly
> you can use
> 'set disassembly-flavor intel'
thanks for the hint,
Mathieu
--
Mathieu Lacage <mathieu.lacage@gmail.com>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: baffling assembly-level weirdness
2009-01-26 16:51 ` Paul Pluzhnikov
@ 2009-01-27 13:09 ` Mathieu Lacage
2009-01-27 17:53 ` Paul Pluzhnikov
0 siblings, 1 reply; 7+ messages in thread
From: Mathieu Lacage @ 2009-01-27 13:09 UTC (permalink / raw)
To: Paul Pluzhnikov; +Cc: gdb
On Mon, Jan 26, 2009 at 5:51 PM, Paul Pluzhnikov <ppluzhnikov@google.com> wrote:
>>> The following gdb session baffles me completely: %edx is reset to zero
>>> by the mov at address 0x0804ad62 instead of being set to the constant
>>> 0x804ad62. Of course, this code segfaults at $pc = 0x804ad68 when zero
>>> is dereferenced...
>>>
>>> Version: GNU gdb 6.8
>>>
>>> (gdb) disas $pc $pc+10
>>> Dump of assembler code from 0x804ad62 to 0x804ad6c:
>>> 0x0804ad62 <indent+50>: mov 0x805e3c0,%edx
>>
>> This is a load from memory at address 0x805e3c0, in x86 syntax.
>
> Additional clues:
>
> (gdb) p/a 0x805e3c0
>
> will likely print "stdout". If you break in main, and do
>
> (gbd) x/a 0x805e3c0
>
> it will likely print something like:
>
> 0x8053ac0 <stdout>: 0x4dcdb5e0 <_IO_2_1_stdout_>
>
> It sounds like your program is corrupting stdout somewhere.
> The fastest way to find out where that happens:
>
> (gdb) watch *(int **)0x8053ac0
You did put me on the right track so, in case this might be useful to
someone else, here is what was going on:
1) I am writing an ELF loader so, the bug was not in my program
corrupting the variable but in the variable not being initialized
correctly by the loader during relocation
2) the libc has a global stdout variable which is initialized with a
R_386_GLOB_DAT relocation by the loader:
mathieu@mathieu-boulot:~/code/elf-loader$ readelf -s
/lib/libc.so.6|grep stdout@@
1063: 00135860 4 OBJECT GLOBAL DEFAULT 32 stdout@@GLIBC_2.0
mathieu@mathieu-boulot:~/code/elf-loader$ readelf -r
/lib/libc.so.6|grep 00135860
00134f34 00042706 R_386_GLOB_DAT 00135860 stdout
00135860 00032d01 R_386_32 001354e0 _IO_2_1_stdout_
3) the main executable has a global stdout variable which is
referenced by the code in the main binary and initialized by a
R_386_COPY relocation:
mathieu@mathieu-boulot:~/code/elf-loader$ readelf -s /bin/ls|grep stdout@
93: 0805e3c0 4 OBJECT GLOBAL DEFAULT 25 stdout@GLIBC_2.0 (2)
mathieu@mathieu-boulot:~/code/elf-loader$ readelf -r /bin/ls|grep 0805e3c0
0805e3c0 00005d05 R_386_COPY 0805e3c0 stdout
which is expected to copy the value of the stdout symbol from the libc.so.6
4) it turns out that the symbol lookup associated to a R_*_COPY
relocation is supposed to ignore the main executable which is
something I had no idea about and adding an extra if statement to
ignore the main executable during symbol resolution for a R_*_COPY
reloc fixed the problem.
As a side-note, I really wonder why (3): none of the executables I
link myself contain an stdout variable so, I am somewhat curious as to
where this is coming from (I would expect each access to stdout from
the main binary to directly reference the symbol from the libc through
the GOT). But, well, next time.
anyway, thanks a lot to the very helpful souls here,
Mathieu
--
Mathieu Lacage <mathieu.lacage@gmail.com>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: baffling assembly-level weirdness
2009-01-27 13:09 ` Mathieu Lacage
@ 2009-01-27 17:53 ` Paul Pluzhnikov
0 siblings, 0 replies; 7+ messages in thread
From: Paul Pluzhnikov @ 2009-01-27 17:53 UTC (permalink / raw)
To: Mathieu Lacage; +Cc: gdb
On Tue, Jan 27, 2009 at 5:09 AM, Mathieu Lacage
<mathieu.lacage@gmail.com> wrote:
> 3) the main executable has a global stdout variable which is
> referenced by the code in the main binary and initialized by a
> R_386_COPY relocation:
> mathieu@mathieu-boulot:~/code/elf-loader$ readelf -s /bin/ls|grep stdout@
> 93: 0805e3c0 4 OBJECT GLOBAL DEFAULT 25 stdout@GLIBC_2.0 (2)
> mathieu@mathieu-boulot:~/code/elf-loader$ readelf -r /bin/ls|grep 0805e3c0
> 0805e3c0 00005d05 R_386_COPY 0805e3c0 stdout
> which is expected to copy the value of the stdout symbol from the libc.so.6
...
> As a side-note, I really wonder why (3): none of the executables I
> link myself contain an stdout variable so, I am somewhat curious as to
> where this is coming from (I would expect each access to stdout from
> the main binary to directly reference the symbol from the libc through
> the GOT). But, well, next time.
Seems pretty normal to me:
$ cat t.c
#include <stdio.h>
int main()
{
fprintf(stdout, "Hello\n");
return 0;
}
$ /usr/bin/gcc --version
gcc (GCC) 4.0.3 (Ubuntu 4.0.3-1ubuntu5)
...
$ /usr/bin/gcc t.c && readelf -s a.out | grep stdout
5: 080495a0 4 OBJECT GLOBAL DEFAULT 23 stdout@GLIBC_2.0 (2)
75: 080495a0 4 OBJECT GLOBAL DEFAULT 23 stdout@@GLIBC_2.0
$ readelf -r a.out | grep 080495a0
080495a0 00000505 R_386_COPY 080495a0 stdout
Cheers,
--
Paul Pluzhnikov
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2009-01-27 17:53 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-01-26 15:24 baffling assembly-level weirdness Mathieu Lacage
2009-01-26 15:38 ` Pierre Muller
2009-01-26 17:35 ` Mathieu Lacage
2009-01-26 15:41 ` Daniel Jacobowitz
2009-01-26 16:51 ` Paul Pluzhnikov
2009-01-27 13:09 ` Mathieu Lacage
2009-01-27 17:53 ` Paul Pluzhnikov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox