More WM 6.1 work committed

classic Classic list List threaded Threaded
55 messages Options
123
Reply | Threaded
Open this post in threaded view
|

More WM 6.1 work committed

Danny Backx
I just committed a cleaned up version of my current work.

This now has .edata and .idata sections hidden in .rdata, and can
generate working DLL and EXEs but with the SizeOfImage <= 10000 limit.

        Danny

2009-12-28  Danny Backx  <[hidden email]>

* ld/emultempl/pe.em: Change default to pseudo-relocation v2.
* ld/scripttempl/pe.sc: Move edata and idata section contents into the
  rdata section, and remove the edata and idata sections.
* ld/pe-dll.c (ERVA): Change macro definition to take edata section
  offset into account.
* bfd/cofflink.c: Remove commented out old command.
* bfd/peXXigen.c (_bfd_XXi_swap_aouthdr_out): Save and restore the
  PE_EXPORT_TABLE field of DataDirectory too.
* ld/scripttempl/pe.sc: Add symbols __idata_start__, __idata_end__,
  __edata_start__, __edata_end__ that _bfd_XXi_swap_aouthdr_out will
  look for.
* bfd/peXXigen.c (_bfd_XXi_swap_aouthdr_out): Get the newly defined
  symbols like __edata_start__ and use them to initialize the
  DataDirectory entries for PE_EXPORT_TABLE and PE_IMPORT_TABLE.


--
Danny Backx ; danny.backx - at - scarlet.be ; http://danny.backx.info


------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Cegcc-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/cegcc-devel
Reply | Threaded
Open this post in threaded view
|

Yay (Re: More WM 6.1 work committed)

Danny Backx
On Mon, 2009-12-28 at 10:00 +0100, Danny Backx wrote:
> I just committed a cleaned up version of my current work.
>
> This now has .edata and .idata sections hidden in .rdata, and can
> generate working DLL and EXEs but with the SizeOfImage <= 10000 limit.
>
> Danny

I found one more issue, haven't figured out the reason yet though.

I got here by using a minimalistic example (a DLL with almost no code
but a big buffer). This gave me an error that I considered suspicious :
code 1114 (ERROR_DLL_INIT_FAILED).

So I tuned in on this, and ended up replacing the default
DllMainCRTStartup (from src/mingw) by an empty one. Cutting the story
shorter, the error appears to be in _pei386_runtime_relocator().

Replacing the underlying function do_pseudo_reloc() by an empty one also
got the DLL to load. Adding MessageBoxW() calls to print the arguments
succeeds, until I try to print the value of the third argument "base".

This is (from src/mingw/pseudo-reloc.c) :
  do_pseudo_reloc (&__RUNTIME_PSEUDO_RELOC_LIST__,
                   &__RUNTIME_PSEUDO_RELOC_LIST_END__,
                    &__U(_image_base__));

I tried several versions :
   wsprintf(msg, L"do_pseudo_reloc(%p,%p)", start, end); // works
   wsprintf(msg, L"do_pseudo_reloc(%p)", base); // error 1114

  { DWORD a = start, b = end, c = base;
        wsprintf(msg, L"do_pseudo_reloc(%08x,%08x,%08x)", a, b, c);
          } // error 1114

Strangely the latter works with the assignment (c = base) but fails when
I try to print the value of c.

Obviously (feeling adventurous) the next thing is to relink a bunch of
DLLs with empty do_pseudo_reloc, and try a real application.

This turned out to work :-)
See http://danny.backx.info/download/cegcc/Capture.PNG

Two questions :
- why I cannot work with that third argument (_image_base__)
- which functionality have I now turned off by removing the content
  of do_pseudo_reloc().

  Danny
--
Danny Backx ; danny.backx - at - scarlet.be ; http://danny.backx.info


------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Cegcc-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/cegcc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Yay (Re: More WM 6.1 work committed)

Pedro Alves-4
On Tuesday 29 December 2009 14:49:36, Danny Backx wrote:

> On Mon, 2009-12-28 at 10:00 +0100, Danny Backx wrote:
> > I just committed a cleaned up version of my current work.
> >
> > This now has .edata and .idata sections hidden in .rdata, and can
> > generate working DLL and EXEs but with the SizeOfImage <= 10000 limit.
> >
> > Danny
>
> I found one more issue, haven't figured out the reason yet though.
>
> I got here by using a minimalistic example (a DLL with almost no code
> but a big buffer). This gave me an error that I considered suspicious :
> code 1114 (ERROR_DLL_INIT_FAILED).
>
> So I tuned in on this, and ended up replacing the default
> DllMainCRTStartup (from src/mingw) by an empty one.
> Cutting the story
> shorter, the error appears to be in _pei386_runtime_relocator().
>
> Replacing the underlying function do_pseudo_reloc() by an empty one also
> got the DLL to load. Adding MessageBoxW() calls to print the arguments
> succeeds, until I try to print the value of the third argument "base".
>
> This is (from src/mingw/pseudo-reloc.c) :
>   do_pseudo_reloc (&__RUNTIME_PSEUDO_RELOC_LIST__,
>                    &__RUNTIME_PSEUDO_RELOC_LIST_END__,
>                     &__U(_image_base__));
>
> I tried several versions :
>    wsprintf(msg, L"do_pseudo_reloc(%p,%p)", start, end); // works
>    wsprintf(msg, L"do_pseudo_reloc(%p)", base); // error 1114
>
>   { DWORD a = start, b = end, c = base;
>         wsprintf(msg, L"do_pseudo_reloc(%08x,%08x,%08x)", a, b, c);
>           } // error 1114
>
> Strangely the latter works with the assignment (c = base) but fails when
> I try to print the value of c.

Does it fail to load, crashes, prints garbage, what?

> Obviously (feeling adventurous) the next thing is to relink a bunch of
> DLLs with empty do_pseudo_reloc, and try a real application.
>
> This turned out to work :-)
> See http://danny.backx.info/download/cegcc/Capture.PNG

Awesome!

> Two questions :
> - why I cannot work with that third argument (_image_base__)

To be clear, you're not supposed to read the contents of
_image_base__.  This is a linker defined symbol.  Only it's
address is important.  Can you try
printing '&__U(_image_base__)' in the caller instead?

> - which functionality have I now turned off by removing the content
>   of do_pseudo_reloc().

runtime pseudo-relocations.  See the help for
--enable-auto-import and –enable-runtime-pseudo-reloc in the ld manual
(but ignore that it says it's i386 specific).

--
Pedro Alves

------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Cegcc-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/cegcc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Yay (Re: More WM 6.1 work committed)

Vincent Richomme
In reply to this post by Danny Backx
On Tue, 29 Dec 2009 15:49:36 +0100, Danny Backx <[hidden email]>
wrote:

> On Mon, 2009-12-28 at 10:00 +0100, Danny Backx wrote:
>> I just committed a cleaned up version of my current work.
>>
>> This now has .edata and .idata sections hidden in .rdata, and can
>> generate working DLL and EXEs but with the SizeOfImage <= 10000 limit.
>>
>> Danny
>
> I found one more issue, haven't figured out the reason yet though.
>
> I got here by using a minimalistic example (a DLL with almost no code
> but a big buffer). This gave me an error that I considered suspicious :
> code 1114 (ERROR_DLL_INIT_FAILED).
>
> So I tuned in on this, and ended up replacing the default
> DllMainCRTStartup (from src/mingw) by an empty one. Cutting the story
> shorter, the error appears to be in _pei386_runtime_relocator().
>
> Replacing the underlying function do_pseudo_reloc() by an empty one also
> got the DLL to load. Adding MessageBoxW() calls to print the arguments
> succeeds, until I try to print the value of the third argument "base".
>
> This is (from src/mingw/pseudo-reloc.c) :
>   do_pseudo_reloc (&__RUNTIME_PSEUDO_RELOC_LIST__,
>                    &__RUNTIME_PSEUDO_RELOC_LIST_END__,
>                     &__U(_image_base__));
>
> I tried several versions :
>    wsprintf(msg, L"do_pseudo_reloc(%p,%p)", start, end); // works
>    wsprintf(msg, L"do_pseudo_reloc(%p)", base); // error 1114
>
>   { DWORD a = start, b = end, c = base;
>         wsprintf(msg, L"do_pseudo_reloc(%08x,%08x,%08x)", a, b, c);
>           } // error 1114
>
> Strangely the latter works with the assignment (c = base) but fails when
> I try to print the value of c.
>
> Obviously (feeling adventurous) the next thing is to relink a bunch of
> DLLs with empty do_pseudo_reloc, and try a real application.
>
> This turned out to work :-)
> See http://danny.backx.info/download/cegcc/Capture.PNG
>
> Two questions :
> - why I cannot work with that third argument (_image_base__)
> - which functionality have I now turned off by removing the content
>   of do_pseudo_reloc().

Congratulations!
I don't know asnwers to your question but you seem to have progressed a
lot.
Thanks for investigating this.





------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Cegcc-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/cegcc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Yay (Re: More WM 6.1 work committed)

Danny Backx
In reply to this post by Pedro Alves-4
On Tue, 2009-12-29 at 16:28 +0000, Pedro Alves wrote:

> On Tuesday 29 December 2009 14:49:36, Danny Backx wrote:
> > Replacing the underlying function do_pseudo_reloc() by an empty one also
> > got the DLL to load. Adding MessageBoxW() calls to print the arguments
> > succeeds, until I try to print the value of the third argument "base".
> >
> > This is (from src/mingw/pseudo-reloc.c) :
> >   do_pseudo_reloc (&__RUNTIME_PSEUDO_RELOC_LIST__,
> >                    &__RUNTIME_PSEUDO_RELOC_LIST_END__,
> >                     &__U(_image_base__));
> >
> > I tried several versions :
> >    wsprintf(msg, L"do_pseudo_reloc(%p,%p)", start, end); // works
> >    wsprintf(msg, L"do_pseudo_reloc(%p)", base); // error 1114
[..]
> Does it fail to load, crashes, prints garbage, what?

Not sure. I am using a test program that uses LoadLibrary and
GetProcAddress, see tools/dll/testapi2.c . (Actually it's a variation of
the version in SVN that can also do a DLL function call, see below.)

It reports error 1114 after the LoadLibrary call. According to MSDN this
means that the DllMain has not returned with TRUE. (To be absolutely
clear: testapi2 doesn't crash, it continues to work as expected, just
reports the error in its log file.)

I'm guessing it crashes, and that the OS catches this and replaces the
crash with that error.

> To be clear, you're not supposed to read the contents of
> _image_base__.  This is a linker defined symbol.  Only it's
> address is important.  Can you try
> printing '&__U(_image_base__)' in the caller instead?

Your first statement is clear to me. I am not trying to follow the
pointer, just printing its value.

This symbols is obviously in the DLL, I was expecting to see its runtime
value printed out :

pavilion: {1757} fgrep _image_base__ lib5bb.objdump
[255](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00010000 __image_base__

Printing the that value in the caller does the same thing as printing it
in the underlying function : the DLL doesn't work any more.

For the record, this is what I tested. Selecting the other wsprintf
statement makes the DLL fail :
void
_pei386_runtime_relocator ()
{
  static int was_init = 0;

  if (was_init)
    return;
  ++was_init;

  {
    wchar_t msg[64];
#if 0
    wsprintf(msg, L"Ptr %p", &__U(_image_base__));
#else
    wsprintf(msg, L"Ptrs %p %p", &__RUNTIME_PSEUDO_RELOC_LIST__,
      &__RUNTIME_PSEUDO_RELOC_LIST_END__);
#endif
    MessageBoxW(0, msg, L"_pei386_runtime_relocator", 0);
  }
#if 0
  do_pseudo_reloc (&__RUNTIME_PSEUDO_RELOC_LIST__,
                   &__RUNTIME_PSEUDO_RELOC_LIST_END__,
                    &__U(_image_base__));
#endif
}

The log file output of testapi2 shows this for a failure :

LoadLibrary(lib5bb.dll) : cannot load DLL -> error 1114

and this for a succesfull execution :

Started processing DLL(lib5bb.dll)
        lib5bb.dll doesn't know about open
        lib5bb.dll implements doit (0x7813108C)
        Trying to call doit()
        doit -> 0xdead0123
        lib5bb.dll doesn't know about getDLLValue

This is based on an input file that asks it to
 - open the DLL
 - look for a function called "open"
 - look for a function called "doit", call it, and print
   the integer it returns
 - look for a function called getDLLValue

 Danny
--
Danny Backx ; danny.backx - at - scarlet.be ; http://danny.backx.info


------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Cegcc-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/cegcc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Yay (Re: More WM 6.1 work committed)

Pedro Alves-4
My knee jerk reaction is: you could try a first step at checking if it's
a problem with loader applied relocations, or, if it's a runtime,
post loader problem.  Replace your debug '#if 0' by, say,

at global scope:
volatile int print_base = 0;

{
...
  if (print_base)
    wsprintf(msg, L"Ptr %p", &__U(_image_base__));
  wsprintf(msg, L"Ptrs %p %p", &__RUNTIME_PSEUDO_RELOC_LIST__,
    &__RUNTIME_PSEUDO_RELOC_LIST_END__);
}

And see if that loads and runs.  Then try with print_base set to 1.
Build without optimizations.

--
Pedro Alves

------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Cegcc-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/cegcc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Yay (Re: More WM 6.1 work committed)

Pedro Alves-4
On Tuesday 29 December 2009 18:53:10, Kai Tietz wrote:

> Hello,
>
> 2009/12/29 Pedro Alves <[hidden email]>:
> > My knee jerk reaction is: you could try a first step at checking if it's
> > a problem with loader applied relocations, or, if it's a runtime,
> > post loader problem.  Replace your debug '#if 0' by, say,
> >
> > at global scope:
> > volatile int print_base = 0;
> >
> > {
> > ...
> >  if (print_base)
> >    wsprintf(msg, L"Ptr %p", &__U(_image_base__));
> >  wsprintf(msg, L"Ptrs %p %p", &__RUNTIME_PSEUDO_RELOC_LIST__,
> >    &__RUNTIME_PSEUDO_RELOC_LIST_END__);
> > }
> >
> > And see if that loads and runs.  Then try with print_base set to 1.
> > Build without optimizations.
> >
> > --
> > Pedro Alves
> >
>
> I assume, that the use of wsprintf is done before runtime is
> initialized,

The runtime is builtin coredll.dll (CE's "equivalent" of ntdll.dll).
In any case, Danny's LoadLibrary'ing the dll.  The runtime is
already initialized by then.

> or the image_base symbol is pointing somewhere else (but
> this is a simple address and therefore a print failure is a bit
> strange as not the location is dereferenced, just a value is shown).

Yes, quite strange.  That's why I wanted to confirm that it's not a
problem with ld generating a bad reloc for _image_base, so that
the OS loader ended up doing something that it shouldn't.  Building
the example I gave should still generate the reloc, even if
&_image_base isn't read at runtime, due to print_base == 0.

Might be useful to look at the generated code / relocs too.

Anyway, these are just wild guesses.  :-)

--
Pedro Alves

------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Cegcc-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/cegcc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Yay (Re: More WM 6.1 work committed)

Danny Backx
In reply to this post by Pedro Alves-4
On Tue, 2009-12-29 at 18:34 +0000, Pedro Alves wrote:

> My knee jerk reaction is: you could try a first step at checking if it's
> a problem with loader applied relocations, or, if it's a runtime,
> post loader problem.  Replace your debug '#if 0' by, say,
>
> at global scope:
> volatile int print_base = 0;
>
> {
> ...
>   if (print_base)
>     wsprintf(msg, L"Ptr %p", &__U(_image_base__));
>   wsprintf(msg, L"Ptrs %p %p", &__RUNTIME_PSEUDO_RELOC_LIST__,
>     &__RUNTIME_PSEUDO_RELOC_LIST_END__);
> }
>
> And see if that loads and runs.  Then try with print_base set to 1.
> Build without optimizations.

In both cases, the output is the same :

LoadLibrary(lib5bb.dll) : cannot load DLL -> error 1114

I must admit I've been suspicious about the relocations, I guess this
confirms it.

I've put up some data on
http://danny.backx.info/download/cegcc/lib5bb.tar.gz :

pavilion: {1801} tar tvfz /tmp/lib5bb.tar.gz
-rw-rw-r-- danny/danny     822 2009-12-28 14:56 lib5b.c
-rw-rw-r-- danny/danny    6175 2009-12-30 00:37 pseudo-reloc.c
-rw-rw-r-- danny/danny    2476 2009-12-29 14:46 dllcrt1.c
-rw-rw-r-- danny/danny    2935 2009-12-30 00:30 Makefile
-rwxrwxr-x danny/danny   90906 2009-12-30 00:37 lib5bb.dll.works
-rw-rw-r-- danny/danny  345371 2009-12-30 00:41 lib5bb.dll.works.objdump
-rwxrwxr-x danny/danny   89594 2009-12-30 00:36 lib5bb.dll.fails
-rw-rw-r-- danny/danny  342301 2009-12-30 00:41 lib5bb.dll.fails.objdump
pavilion: {1802}

        Danny

--
Danny Backx ; danny.backx - at - scarlet.be ; http://danny.backx.info


------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Cegcc-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/cegcc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Yay (Re: More WM 6.1 work committed)

Vincent Richomme
On Wed, 30 Dec 2009 00:44:08 +0100, Danny Backx <[hidden email]>
wrote:
> On Tue, 2009-12-29 at 18:34 +0000, Pedro Alves wrote:
>> My knee jerk reaction is: you could try a first step at checking if
it's

>> a problem with loader applied relocations, or, if it's a runtime,
>> post loader problem.  Replace your debug '#if 0' by, say,
>>
>> at global scope:
>> volatile int print_base = 0;
>>
>> {
>> ...
>>   if (print_base)
>>     wsprintf(msg, L"Ptr %p", &__U(_image_base__));
>>   wsprintf(msg, L"Ptrs %p %p", &__RUNTIME_PSEUDO_RELOC_LIST__,
>>     &__RUNTIME_PSEUDO_RELOC_LIST_END__);
>> }
>>
>> And see if that loads and runs.  Then try with print_base set to 1.
>> Build without optimizations.
>
> In both cases, the output is the same :
>
> LoadLibrary(lib5bb.dll) : cannot load DLL -> error 1114
>
> I must admit I've been suspicious about the relocations, I guess this
> confirms it.
>
> I've put up some data on
> http://danny.backx.info/download/cegcc/lib5bb.tar.gz :
>
> pavilion: {1801} tar tvfz /tmp/lib5bb.tar.gz
> -rw-rw-r-- danny/danny     822 2009-12-28 14:56 lib5b.c
> -rw-rw-r-- danny/danny    6175 2009-12-30 00:37 pseudo-reloc.c
> -rw-rw-r-- danny/danny    2476 2009-12-29 14:46 dllcrt1.c
> -rw-rw-r-- danny/danny    2935 2009-12-30 00:30 Makefile
> -rwxrwxr-x danny/danny   90906 2009-12-30 00:37 lib5bb.dll.works
> -rw-rw-r-- danny/danny  345371 2009-12-30 00:41 lib5bb.dll.works.objdump
> -rwxrwxr-x danny/danny   89594 2009-12-30 00:36 lib5bb.dll.fails
> -rw-rw-r-- danny/danny  342301 2009-12-30 00:41 lib5bb.dll.fails.objdump
> pavilion: {1802}
>
> Danny

Some remarks, DLLs produced by cegcc have a weird IAT address because
in Data Directories fields there is :

Virtual Address          Size
00033198              00000040

and this address doesn't even exists.


On a dll produced by Visual we get :
Virtual Address          Size
10003000              00000024

and 10003000 corresponds to the address of .data section.

Finally address are also suspicious because in old days (before all
binutils hacks) sections
had address like 10002000h, 10003000h,... but now it's more 00011000h,
00012000h,...
Is there any reason image_base has been modified ?











------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Cegcc-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/cegcc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Yay (Re: More WM 6.1 work committed)

Sébastien Lorquet
would that be related to the SizeOfImage <= 10000 limit ? :-)

seb


Some remarks, DLLs produced by cegcc have a weird IAT address because
in Data Directories fields there is :

Virtual Address          Size
00033198              00000040

and this address doesn't even exists.


On a dll produced by Visual we get :
Virtual Address          Size
10003000              00000024

and 10003000 corresponds to the address of .data section.

Finally address are also suspicious because in old days (before all
binutils hacks) sections
had address like 10002000h, 10003000h,... but now it's more 00011000h,
00012000h,...
Is there any reason image_base has been modified ?





------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Cegcc-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/cegcc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Yay (Re: More WM 6.1 work committed)

Danny Backx
In reply to this post by Vincent Richomme
On Wed, 2009-12-30 at 12:41 +0100, Vincent R. wrote:

> Some remarks, DLLs produced by cegcc have a weird IAT address because
> in Data Directories fields there is :
>
> Virtual Address          Size
> 00033198              00000040
>
> and this address doesn't even exists.
>
>
> On a dll produced by Visual we get :
> Virtual Address          Size
> 10003000              00000024
>
> and 10003000 corresponds to the address of .data section.

I'll look into that.

> Finally address are also suspicious because in old days (before all
> binutils hacks) sections
> had address like 10002000h, 10003000h,... but now it's more 00011000h,
> 00012000h,...
> Is there any reason image_base has been modified ?

This is in binutils/ld/emultempl/pe.em, committed by Pedro in revision
486 (2006-08-30). The comment speaks for itself :

#if defined(TARGET_IS_arm_wince_pe)
/* Windows CE ignores the image base, but we want to
   be compatible with MSFT's tools.  */
#undef NT_DLL_IMAGE_BASE
#define NT_DLL_IMAGE_BASE               0x00010000
#endif

  Danny
--
Danny Backx ; danny.backx - at - scarlet.be ; http://danny.backx.info


------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Cegcc-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/cegcc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Yay (Re: More WM 6.1 work committed)

Danny Backx
In reply to this post by Sébastien Lorquet
On Wed, 2009-12-30 at 12:48 +0100, Sébastien Lorquet wrote:
> would that be related to the SizeOfImage <= 10000 limit ? :-)

No. SizeOfImage is a sum of the sizes of sections. ImageBase is just an
assumption (by the development tools) of where the code might actually
run. If the OS can use the assumption, then no relocation must happen
(so this is the cheap option), otherwise it needs to run through
the .reloc section contents and apply it.

        Danny
--
Danny Backx ; danny.backx - at - scarlet.be ; http://danny.backx.info


------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Cegcc-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/cegcc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Yay (Re: More WM 6.1 work committed)

Vincent Richomme
In reply to this post by Danny Backx
On Wed, 30 Dec 2009 14:05:35 +0100, Danny Backx <[hidden email]>
wrote:

> On Wed, 2009-12-30 at 12:41 +0100, Vincent R. wrote:
>> Some remarks, DLLs produced by cegcc have a weird IAT address because
>> in Data Directories fields there is :
>>
>> Virtual Address          Size
>> 00033198              00000040
>>
>> and this address doesn't even exists.
>>
>>
>> On a dll produced by Visual we get :
>> Virtual Address          Size
>> 10003000              00000024
>>
>> and 10003000 corresponds to the address of .data section.
>
> I'll look into that.
>
>> Finally address are also suspicious because in old days (before all
>> binutils hacks) sections
>> had address like 10002000h, 10003000h,... but now it's more 00011000h,
>> 00012000h,...
>> Is there any reason image_base has been modified ?
>
> This is in binutils/ld/emultempl/pe.em, committed by Pedro in revision
> 486 (2006-08-30). The comment speaks for itself :
>
> #if defined(TARGET_IS_arm_wince_pe)
> /* Windows CE ignores the image base, but we want to
>    be compatible with MSFT's tools.  */
> #undef NT_DLL_IMAGE_BASE
> #define NT_DLL_IMAGE_BASE               0x00010000
> #endif

OK but I still don't understand this comment. Pedro what do you mean by
compatible with
MSFT's tools ?


------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Cegcc-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/cegcc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Yay (Re: More WM 6.1 work committed)

Pedro Alves-4
On Wednesday 30 December 2009 14:56:18, Vincent R. wrote:

>
> > #if defined(TARGET_IS_arm_wince_pe)
> > /* Windows CE ignores the image base, but we want to
> >    be compatible with MSFT's tools.  */
> > #undef NT_DLL_IMAGE_BASE
> > #define NT_DLL_IMAGE_BASE               0x00010000
> > #endif
>
> OK but I still don't understand this comment. Pedro what do you mean by
> compatible with
> MSFT's tools ?

"compatible" here just meant, do the same as MSFT's linker does.
0x10000 was the image base Visual Studio was setting by default
at the time I wrote that.  This minimized spurious differences
when comparing dumps of images generated with ld with MSFT
generated images.  Since this change is in our binutils copy since
2006, I'm confused when you say only recent binutils started
using 0x10000 as image base.  I don't think this hunk is
in upstream binutils --- could it be that you were using
a pristine binutils from upstream before?

--
Pedro Alves

------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Cegcc-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/cegcc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Yay (Re: More WM 6.1 work committed)

Danny Backx
In reply to this post by Vincent Richomme
On Wed, 2009-12-30 at 12:41 +0100, Vincent R. wrote:
> Some remarks, DLLs produced by cegcc have a weird IAT address because
> in Data Directories fields there is :
>
> Virtual Address          Size
> 00033198              00000040
>
> and this address doesn't even exists.

Can you privately send this DLL to me ?

The ones I just looked at do have addresses that look right (pointing
into the .rdata).

        Danny
--
Danny Backx ; danny.backx - at - scarlet.be ; http://danny.backx.info


------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Cegcc-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/cegcc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Yay (Re: More WM 6.1 work committed)

Vincent Richomme
In reply to this post by Pedro Alves-4
On Wed, 30 Dec 2009 15:16:11 +0000, Pedro Alves <[hidden email]>
wrote:

> On Wednesday 30 December 2009 14:56:18, Vincent R. wrote:
>>
>> > #if defined(TARGET_IS_arm_wince_pe)
>> > /* Windows CE ignores the image base, but we want to
>> >    be compatible with MSFT's tools.  */
>> > #undef NT_DLL_IMAGE_BASE
>> > #define NT_DLL_IMAGE_BASE               0x00010000
>> > #endif
>>
>> OK but I still don't understand this comment. Pedro what do you mean by
>> compatible with
>> MSFT's tools ?
>
> "compatible" here just meant, do the same as MSFT's linker does.
> 0x10000 was the image base Visual Studio was setting by default
> at the time I wrote that.  This minimized spurious differences
> when comparing dumps of images generated with ld with MSFT
> generated images.  Since this change is in our binutils copy since
> 2006, I'm confused when you say only recent binutils started
> using 0x10000 as image base.  I don't think this hunk is
> in upstream binutils --- could it be that you were using
> a pristine binutils from upstream before?

Yes you are right I think I was using some custom binutils but now I
understand what you meant
I suppose its better to declare it as 0x10000000 because this is what MS
linker uses now.


------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Cegcc-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/cegcc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Yay (Re: More WM 6.1 work committed)

Danny Backx
In reply to this post by Danny Backx
On Wed, 2009-12-30 at 00:44 +0100, Danny Backx wrote:

> On Tue, 2009-12-29 at 18:34 +0000, Pedro Alves wrote:
> > My knee jerk reaction is: you could try a first step at checking if it's
> > a problem with loader applied relocations, or, if it's a runtime,
> > post loader problem.  Replace your debug '#if 0' by, say,
> >
> > at global scope:
> > volatile int print_base = 0;
> >
> > {
> > ...
> >   if (print_base)
> >     wsprintf(msg, L"Ptr %p", &__U(_image_base__));
> >   wsprintf(msg, L"Ptrs %p %p", &__RUNTIME_PSEUDO_RELOC_LIST__,
> >     &__RUNTIME_PSEUDO_RELOC_LIST_END__);
> > }
> >
> > And see if that loads and runs.  Then try with print_base set to 1.
> > Build without optimizations.
>
> In both cases, the output is the same :
>
> LoadLibrary(lib5bb.dll) : cannot load DLL -> error 1114
>
> I must admit I've been suspicious about the relocations, I guess this
> confirms it.

I've looked further, I'm puzzled.

I created yet another small test (and set image-base to a higher value,
see the other discussion, just for fun).

I checked all the relocations : the table vs. the assembler. They all
appear to make sense. They're usually a couple of words between two
functions (in the .text segment) that are pointers to something in
another segment. A string literal for instance.

I've enclosed the assembler output of a _pei386_runtime_relocator with
the offending lines compiled in :

void
_pei386_runtime_relocator ()
{
  static int was_init = 0;

  if (was_init)
    return;
  ++was_init;

  {
    wchar_t msg[64] = L"Yow";
    MessageBoxW(0, msg, L"_pei386_runtime_relocator", 0);
  }
    do_pseudo_reloc (&__RUNTIME_PSEUDO_RELOC_LIST__,
                     &__RUNTIME_PSEUDO_RELOC_LIST_END__,
                     &__U(_image_base__));
}

The MessageBoxW call is very visible in the assembler output, and it
provides examples for what the relocations look like. The
do_pseudo_reloc call with its parameters is also there. I cannot see a
problem with it, but it does cause the application to fail !

Help ?

        Danny

0100146c <_pei386_runtime_relocator>:
 100146c:       e92d4800        push    {fp, lr}
 1001470:       e28db004        add     fp, sp, #4
 1001474:       e24dd080        sub     sp, sp, #128    ; 0x80
 1001478:       e59f307c        ldr     r3, [pc, #124]  ; 10014fc
<_pei386_runtime_relocator+0x90>
 100147c:       e5933000        ldr     r3, [r3]
 1001480:       e3530000        cmp     r3, #0
 1001484:       1a000019        bne     10014f0
<_pei386_runtime_relocator+0x84>
 1001488:       e59f306c        ldr     r3, [pc, #108]  ; 10014fc
<_pei386_runtime_relocator+0x90>
 100148c:       e5933000        ldr     r3, [r3]
 1001490:       e2832001        add     r2, r3, #1
 1001494:       e59f3060        ldr     r3, [pc, #96]   ; 10014fc
<_pei386_runtime_relocator+0x90>
 1001498:       e5832000        str     r2, [r3]
 100149c:       e59f205c        ldr     r2, [pc, #92]   ; 1001500
<_pei386_runtime_relocator+0x94>
 10014a0:       e24b3084        sub     r3, fp, #132    ; 0x84
 10014a4:       e8920003        ldm     r2, {r0, r1}
 10014a8:       e8830003        stm     r3, {r0, r1}
 10014ac:       e24b207c        sub     r2, fp, #124    ; 0x7c
 10014b0:       e3a03078        mov     r3, #120        ; 0x78
 10014b4:       e1a00002        mov     r0, r2
 10014b8:       e3a01000        mov     r1, #0
 10014bc:       e1a02003        mov     r2, r3
 10014c0:       eb0000d9        bl      100182c <memset>
 10014c4:       e24b3084        sub     r3, fp, #132    ; 0x84
 10014c8:       e3a00000        mov     r0, #0
 10014cc:       e1a01003        mov     r1, r3
 10014d0:       e59f202c        ldr     r2, [pc, #44]   ; 1001504
<_pei386_runtime_relocator+0x98>
 10014d4:       e3a03000        mov     r3, #0
 10014d8:       eb0000d6        bl      1001838 <MessageBoxW>
 10014dc:       e59f0024        ldr     r0, [pc, #36]   ; 1001508
<_pei386_runtime_relocator+0x9c>
 10014e0:       e59f1024        ldr     r1, [pc, #36]   ; 100150c
<_pei386_runtime_relocator+0xa0>
 10014e4:       e59f2024        ldr     r2, [pc, #36]   ; 1001510
<_pei386_runtime_relocator+0xa4>
 10014e8:       ebffff22        bl      1001178 <do_pseudo_reloc>
 10014ec:       ea000000        b       10014f4
<_pei386_runtime_relocator+0x88>
 10014f0:       e1a00000        nop                     ; (mov r0, r0)
 10014f4:       e24bd004        sub     sp, fp, #4
 10014f8:       e8bd8800        pop     {fp, pc}
 10014fc:       0101200c        tsteq   r1, ip
 1001500:       01013034        tsteq   r1, r4, lsr r0
 1001504:       01013000        tsteq   r1, r0
 1001508:       010130b4        strheq  r3, [r1, -r4]
 100150c:       010130b4        strheq  r3, [r1, -r4]
 1001510:       01000000        tsteq   r0, r0


PE File Base Relocations (interpreted .reloc section contents)

Virtual Address: 00001000 Chunk size 68 (0x44) Number of fixups 30
        reloc    0 offset  4fc [14fc] HIGHLOW
        reloc    1 offset  500 [1500] HIGHLOW
        reloc    2 offset  504 [1504] HIGHLOW
        reloc    3 offset  508 [1508] HIGHLOW
        reloc    4 offset  50c [150c] HIGHLOW
        reloc    5 offset  510 [1510] HIGHLOW
        reloc    6 offset  550 [1550] HIGHLOW
        reloc    7 offset  594 [1594] HIGHLOW
        reloc    8 offset  648 [1648] HIGHLOW
        reloc    9 offset  64c [164c] HIGHLOW
        reloc   10 offset  670 [1670] HIGHLOW
        reloc   11 offset  674 [1674] HIGHLOW
        reloc   12 offset  6dc [16dc] HIGHLOW
        reloc   13 offset  6e0 [16e0] HIGHLOW
        reloc   14 offset  744 [1744] HIGHLOW
        reloc   15 offset  748 [1748] HIGHLOW
        reloc   16 offset  788 [1788] HIGHLOW
        reloc   17 offset  7ec [17ec] HIGHLOW
        reloc   18 offset  7f0 [17f0] HIGHLOW
        reloc   19 offset  810 [1810] HIGHLOW
        reloc   20 offset  81c [181c] HIGHLOW
        reloc   21 offset  828 [1828] HIGHLOW
        reloc   22 offset  834 [1834] HIGHLOW
        reloc   23 offset  840 [1840] HIGHLOW
        reloc   24 offset  84c [184c] HIGHLOW
        reloc   25 offset  858 [1858] HIGHLOW
        reloc   26 offset  864 [1864] HIGHLOW
        reloc   27 offset  870 [1870] HIGHLOW
        reloc   28 offset  87c [187c] HIGHLOW
        reloc   29 offset  888 [1888] HIGHLOW

Virtual Address: 00012000 Chunk size 12 (0xc) Number of fixups 2
        reloc    0 offset    8 [12008] HIGHLOW
        reloc    1 offset    0 [12000] ABSOLUTE

Note : full objdump at
  http://danny.backx.info/download/cegcc/lib6.objdump

--
Danny Backx ; danny.backx - at - scarlet.be ; http://danny.backx.info


------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Cegcc-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/cegcc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Yay (Re: More WM 6.1 work committed)

Danny Backx
On Wed, 2009-12-30 at 20:05 +0100, Danny Backx wrote:
> I checked all the relocations : the table vs. the assembler. They all
> appear to make sense. They're usually a couple of words between two
> functions (in the .text segment) that are pointers to something in
> another segment. A string literal for instance.
[..]

> void
> _pei386_runtime_relocator ()
> {
>   static int was_init = 0;
>
>   if (was_init)
>     return;
>   ++was_init;
>
>   {
>     wchar_t msg[64] = L"Yow";
>     MessageBoxW(0, msg, L"_pei386_runtime_relocator", 0);
>   }
>     do_pseudo_reloc (&__RUNTIME_PSEUDO_RELOC_LIST__,
>                      &__RUNTIME_PSEUDO_RELOC_LIST_END__,
>                      &__U(_image_base__));
> }

I may have found the issue.

If I replace the __image_base__ in the assembly file by the value that I
know the linker is supplying it with, the DLL works just fine.

So I created two versions of this DLL, and compared their objdump
outputs. The main difference is an extra relocation at 14a0 :

0100144c <_pei386_runtime_relocator>:
 100144c:       e92d4800        push    {fp, lr}
 1001450:       e28db004        add     fp, sp, #4
 1001454:       e59f3038        ldr     r3, [pc, #56]   ; 1001494
<_pei386_runtime_relocator+0x48>
 1001458:       e5933000        ldr     r3, [r3]
 100145c:       e3530000        cmp     r3, #0
 1001460:       1a000009        bne     100148c
<_pei386_runtime_relocator+0x40>
 1001464:       e59f3028        ldr     r3, [pc, #40]   ; 1001494
<_pei386_runtime_relocator+0x48>
 1001468:       e5933000        ldr     r3, [r3]
 100146c:       e2832001        add     r2, r3, #1
 1001470:       e59f301c        ldr     r3, [pc, #28]   ; 1001494
<_pei386_runtime_relocator+0x48>
 1001474:       e5832000        str     r2, [r3]
 1001478:       e59f0018        ldr     r0, [pc, #24]   ; 1001498
<_pei386_runtime_relocator+0x4c>
 100147c:       e59f1018        ldr     r1, [pc, #24]   ; 100149c
<_pei386_runtime_relocator+0x50>
 1001480:       e59f2018        ldr     r2, [pc, #24]   ; 10014a0
<_pei386_runtime_relocator+0x54>
 1001484:       ebffff35        bl      1001160 <do_pseudo_reloc>
 1001488:       ea000000        b       1001490
<_pei386_runtime_relocator+0x44>
 100148c:       e1a00000        nop                     ; (mov r0, r0)
 1001490:       e8bd8800        pop     {fp, pc}
 1001494:       0101200c        tsteq   r1, ip
 1001498:       01013000        tsteq   r1, r0
 100149c:       01013000        tsteq   r1, r0
 10014a0:       01000000        tsteq   r0, r0

Note that this contains the value of __image_base__ .

This means, I think, that Windows is choking on relocating the value of
__image_base__ itself.

Not sure how to solve this problem though. If I understand well what
do_pseudo_reloc is about, then we *need* the relocated value. Right ?

        Danny

--
Danny Backx ; danny.backx - at - scarlet.be ; http://danny.backx.info


------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Cegcc-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/cegcc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Yay (Re: More WM 6.1 work committed)

Danny Backx
On Wed, 2009-12-30 at 21:05 +0100, Kai Tietz wrote:

> 2009/12/30 Danny Backx <[hidden email]>:
> >  10014a0:       01000000        tsteq   r0, r0
> >
> > Note that this contains the value of __image_base__ .
> >
> > This means, I think, that Windows is choking on relocating the value of
> > __image_base__ itself.
> >
> > Not sure how to solve this problem though. If I understand well what
> > do_pseudo_reloc is about, then we *need* the relocated value. Right ?
>
> This describes the issue, but it is a bit strange as __image_base__ is
> a base-relocation in PE directory (or should be). The only reason
> happening here is, that the storage size of the instruction data is
> too small?

I don't understand your last sentence. Could you elaborate ?

        Danny
--
Danny Backx ; danny.backx - at - scarlet.be ; http://danny.backx.info


------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Cegcc-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/cegcc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Yay (Re: More WM 6.1 work committed)

Danny Backx
I've narrowed the demo DLL down to the minimal source I can trigger the
problem with. Doesn't need to compile with any of the runtime modules,
so the compile boils down to :

arm-mingw32ce-gcc -c lib7.c
arm-mingw32ce-ld --shared -Bdynamic -e DllMainCRTStartup -o lib7.dll
lib7.o -lcoredll

Note all the support libraries are effectively gone in the ld command
line.

Source is attached. By commenting the declaration of big_buf, Windows
Mobile sees a small executable, doesn't relocate it, so it works.
With big_buf, the new functionality in WM 6.1 kicks in to relocate, and
the DLL fails.

Well, it fails if you select the first of the three assigments - where
_image_base__ is used. The others do work.

The objdump now contains only one relocation, which causes the problem.

An objdump of the faulty dll is at
http://danny.backx.info/download/cegcc/lib7a.objdump , and of a working
one (another assignment selected) is at
http://danny.backx.info/download/cegcc/lib7b.objdump .

The test program that attempts to load this with LoadLibrary and then
executes doit and prints the result shows this result :

Started processing DLL(lib7.dll)
        lib7.dll implements doit (0x780F102C)
        Trying to call doit()
        doit -> 0x780f1000

or, for the faulty version :

LoadLibrary(lib7.dll) : cannot load DLL -> error 1114

Help ?

        Danny

--
Danny Backx ; danny.backx - at - scarlet.be ; http://danny.backx.info

------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Cegcc-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/cegcc-devel

lib7.c (635 bytes) Download Attachment
123