Mirror of the gdb mailing list
 help / color / mirror / Atom feed
* 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