From mboxrd@z Thu Jan 1 00:00:00 1970 From: Eduardo Pereira Habkost Subject: memcpy_fromfs() failing. Wrong variable offsets Date: Tue, 1 Jun 2004 18:32:31 -0300 Sender: linux-8086-owner@vger.kernel.org Message-ID: <20040601213231.GT21172@duckman.distro.conectiva> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="kK1uqZGE6pgsGNyR" Return-path: Content-Disposition: inline List-Id: To: linux-8086@vger.kernel.org --kK1uqZGE6pgsGNyR Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable I was trying to boot ELKS CVS here and it was failing when trying to run init. I've tracked the bug until I discovered that memcpy_fromfs() is failing, and it is not copying the right data. Here is the function, with my debug line: =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D void memcpy_fromfs(void *daddr, void *saddr, size_t len) { /*@unused@*/ unsigned short int ds =3D current->t_regs.ds; #ifndef S_SPLINT_S #asm mov dx,es mov bx,ds mov es,bx mov ax,[bp-6] ! source segment (local variable) mov ds,ax mov di,[bp+4] ! destination address mov si,[bp+6] ! source address mov cx,[bp+8] ! number of bytes to copy cld rep movsb mov ds,bx mov es,dx #endasm #endif debug3("DS: 0x%04x, real: 0x%02x, copied: 0x%02x\n", ds, *((unsigned char*)saddr), *((unsigned char*)daddr)); } =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Note that, as the DS for the init task, at the time of the error is the same of the kernel's DS, *((unsigned char*)saddr) showed the right value. What I got when the kernel tries to run init is: DS: 0x1dc1, real: 0x64, copied: 0x00 That means: the data wasn't copied. Looking at the generated assembly file, We get: =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D ! 32 void memcpy_fromfs(daddr,saddr,len) ! Register SI DI used in function verfy_area verfy_area.off =3D 0 ! 33 # 32 "user.c" ! 32 void *daddr; export>=B7_memcpy_fromfs _memcpy_fromfs: !BCC_EOS ! 33 # 32 "user.c" ! 32 void *saddr; !BCC_EOS ! 33 # 32 "user.c" ! 32 size_t len; !BCC_EOS ! 33 { ! 34 unsigned short int ds =3D current->t_regs.ds; push>=B7=B7=B7bp mov>=B7=B7=B7=B7bp,sp if memcpy_fromfs.off=3D0 push>=B7=B7=B7di push>=B7=B7=B7si endif dec>=B7=B7=B7=B7sp dec>=B7=B7=B7=B7sp mov>=B7=B7=B7=B7bx,[_current] ! Debug: eq unsigned short =3D [bx+6] to unsigned short ds =3D [S+8-8] (use= d reg =3D ) mov>=B7=B7=B7=B7bx,6[bx] mov>=B7=B7=B7=B7-6+memcpy_fromfs.off[bp],bx [...] ! 53 } inc>=B7=B7=B7=B7sp inc>=B7=B7=B7=B7sp if memcpy_fromfs.off=3D0 pop>=B7=B7=B7=B7si pop>=B7=B7=B7=B7di endif pop>=B7=B7=B7=B7bp ret ! 54=B7 ! 55 int verified_memcpy_fromfs(daddr,saddr,len) memcpy_fromfs.off =3D 4 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D That means: if memcpy_fromfs.off were 0, the function would be ok. The variable ds is supposed to be in [bp-6], but it is on [bp-2], because memcpy_fromfs.off is being defined to 4. Probably someday the compiler generated code in a way that memcpy_fromfs.off was always zero, and the function assumes that. Anyway, looking at the code of the compiler, it looks like that it should know if SI or DI was modified by the function, because it should save their values on the stack. I am using dev86-0.16.15 to compile elks. Someone have reproduced this problem, too? Does anyone had success booting ELKS CVS? -- Eduardo --kK1uqZGE6pgsGNyR Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.4 (GNU/Linux) iD8DBQFAvPXucaRJ66w1lWgRAuZlAJ9au+YQGanrN8DU3Ikaj580EgDguQCglWAS FXNh4PtgN8zp8NoIJ413+9o= =5f/p -----END PGP SIGNATURE----- --kK1uqZGE6pgsGNyR--