• dxe: page fault when derefencing an exported pointer variable

    From [via djgpp@delorie.com]" @21:1/5 to All on Thu Feb 16 02:55:30 2023
    dxe: page fault when derefencing an exported pointer variable

    The project in question is libmikmod along with its mikmod player: https://github.com/sezero/mikmod

    The libmikmod library exports many functions and variables, only
    one of those variables is a pointer: https://github.com/sezero/mikmod/blob/master/libmikmod/playercode/mdriver.c#L51

    The 'normal' vars don't seem to have a problem, but dereferencing
    that particular pointer results in a page fault: https://github.com/sezero/mikmod/blob/master/mikmod/src/display.c#L338-L339

    At time of dereferencing the pointer is not actually NULL, because
    if I write an accessor returning that pointer and export and use it
    then things work. (Yes, the library and its api are a mess, I know)

    Using dxe3gen from CVS -- can give instructions to reproduce / test
    if requested.

    Anyone has an insight, please?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From [via djgpp@delorie.com]" @21:1/5 to Ozkan Sezer on Thu Feb 16 14:10:14 2023
    On 2/16/23, Ozkan Sezer <sezeroz@gmail.com> wrote:
    dxe: page fault when derefencing an exported pointer variable

    The project in question is libmikmod along with its mikmod player: https://github.com/sezero/mikmod

    The libmikmod library exports many functions and variables, only
    one of those variables is a pointer: https://github.com/sezero/mikmod/blob/master/libmikmod/playercode/mdriver.c#L51

    The 'normal' vars don't seem to have a problem, but dereferencing
    that particular pointer results in a page fault: https://github.com/sezero/mikmod/blob/master/mikmod/src/display.c#L338-L339

    At time of dereferencing the pointer is not actually NULL, because
    if I write an accessor returning that pointer and export and use it
    then things work. (Yes, the library and its api are a mess, I know)

    Using dxe3gen from CVS -- can give instructions to reproduce / test
    if requested.

    Anyone has an insight, please?

    I forgot to mention that:
    - I link to the DXE module using an import library, not manually.
    - There are no issues if I link the exe statically to libmikmod.

    Need help with this - any insight would be appreciated.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From [via djgpp@delorie.com]" @21:1/5 to Ozkan Sezer on Thu Feb 16 15:29:35 2023
    Copy: dborca@yahoo.com (Daniel Borca)

    On 2/16/23, Ozkan Sezer <sezeroz@gmail.com> wrote:
    The 'normal' vars don't seem to have a problem, but dereferencing
    that particular pointer results in a page fault:

    Well, I was very very wrong:

    I added some debug printf() statements to a simple program, so that
    it prints the values of certain variables exported by the library :

    UBYTE md_volume : 233 (0xe9) --- should have been 128
    UBYTE md_musicvolume : 233 (0xe9) --- should have been 128
    UBYTE md_sndfxvolume : 233 (0xe9) --- should have been 128
    UBYTE md_reverb : 233 (0xe9) --- should have been 0
    UBYTE md_pansep : 233 (0xe9) --- should have been 128
    UWORD md_mixfreq : 44100
    UWORD md_mode : 63977 (0xf9e9) --- should have been 0x110F
    UWORD md_device : 9705 (0x25e9) --- should have been ???
    MDRIVER* md_driver : 0xcea27e9
    CHAR* md_driver->Name: [crash...]

    Note that all of those values have 0xe9 - except for md_mixfreq to
    which I do assign 44100. 0xe9 (i.e.: jmp) seems to be coming from dlstatbind(): https://www.delorie.com/bin/cvsweb.cgi/djgpp/src/libc/dxe/dxe3stat.c?rev=1.1

    Looks like exported variables support in import libraries is very
    much broken?

    Daniel Borce has shed some light:

    On 2/16/23, Daniel Borca <dborca@yahoo.com> wrote:

    I believe this is because of how variables are exported (as opposed to functions).

    Things are quite foggy after all those years, but for COFF, you are actually getting a _pointer_ to a variable. That is, in your case a _pointer_ to the desired pointer (that's why having a getter for the pointer solves it). I know this is *not* how it works when you are compiling statically, but it is a limitation of the executable format. I also think this limitation applies to the original DXE (as designed by Charles W Sandmann) not only for my
    DXE3. BTW, the COFF used by DJGPP is not even Windows COFF.

    TL;DR: you have to dereference that pointer twice. I am not sure it can be handled transparently as long as DJGPP was COFF-based.

    That's why I "invented" DJELF back then. The ELF executable format has a special kind of relocation (perhaps it was called R_<arch>_COPY or something like that) which would solve this issue magically, but then you are restricted to ELF.

    -dborca

    Thanks Daniel.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From [via djgpp@delorie.com]" @21:1/5 to All on Thu Feb 16 15:25:34 2023
    Copy: dborca@yahoo.com (Daniel Borca)

    The 'normal' vars don't seem to have a problem, but dereferencing
    that particular pointer results in a page fault:

    Well, I was very very wrong:

    I added some debug printf() statements to a simple program, so that
    it prints the values of certain variables exported by the library :

    UBYTE md_volume : 233 (0xe9) --- should have been 128
    UBYTE md_musicvolume : 233 (0xe9) --- should have been 128
    UBYTE md_sndfxvolume : 233 (0xe9) --- should have been 128
    UBYTE md_reverb : 233 (0xe9) --- should have been 0
    UBYTE md_pansep : 233 (0xe9) --- should have been 128
    UWORD md_mixfreq : 44100
    UWORD md_mode : 63977 (0xf9e9) --- should have been 0x110F
    UWORD md_device : 9705 (0x25e9) --- should have been ???
    MDRIVER* md_driver : 0xcea27e9
    CHAR* md_driver->Name: [crash...]

    Note that all of those values have 0xe9 - except for md_mixfreq to
    which I do assign 44100. 0xe9 (i.e.: jmp) seems to be coming from dlstatbind(): https://www.delorie.com/bin/cvsweb.cgi/djgpp/src/libc/dxe/dxe3stat.c?rev=1.1

    Looks like exported variables support in import libraries is very
    much broken?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)