OutpostUniverse / OP2Internal

Class definitions compatible with the in-memory format used by Outpost 2
0 stars 0 forks source link

Errors attempting to compile against NetFixClient #15

Closed Brett208 closed 5 years ago

Brett208 commented 5 years ago

Current list of errors when attempting to compile NetFixClient with the latest version of OP2Internal:

Error   LNK1165 link failed because of fixup errors NetFixClient    \NetFixClient\LINK  1   

Error   LNK2016 absolute symbol '?ShowJoinGame@MultiplayerPreGameSetupWnd@OP2Internal@@QAE_NPADH_N@Z' used as target of REL32 relocation in section 32  NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '?ShowHostGame@MultiplayerPreGameSetupWnd@OP2Internal@@QAE_NPAUHostGameParameters@2@@Z' used as target of REL32 relocation in section 27    NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '?SetString@CConfig@OP2Internal@@QAEHPBD00@Z' used as target of REL32 relocation in section 2E  NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '?SetString@CConfig@OP2Internal@@QAEHPBD00@Z' used as target of REL32 relocation in section 2E  NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '?scr_snprintf@OP2Internal@@YAHPADIPBDZZ' used as target of REL32 relocation in section C9  NetFixClient    \NetFixClient\OPUNetTransportLayer.obj  1   

Error   LNK2016 absolute symbol '?scr_snprintf@OP2Internal@@YAHPADIPBDZZ' used as target of REL32 relocation in section 39  NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '?scr_snprintf@OP2Internal@@YAHPADIPBDZZ' used as target of REL32 relocation in section 39  NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '?scr_snprintf@OP2Internal@@YAHPADIPBDZZ' used as target of REL32 relocation in section 39  NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '?scr_snprintf@OP2Internal@@YAHPADIPBDZZ' used as target of REL32 relocation in section 39  NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '?scr_snprintf@OP2Internal@@YAHPADIPBDZZ' used as target of REL32 relocation in section 39  NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '?scr_snprintf@OP2Internal@@YAHPADIPBDZZ' used as target of REL32 relocation in section 30  NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '?scr_snprintf@OP2Internal@@YAHPADIPBDZZ' used as target of REL32 relocation in section 30  NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '?scr_snprintf@OP2Internal@@YAHPADIPBDZZ' used as target of REL32 relocation in section 2E  NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '?NetShutdown@TApp@OP2Internal@@QAEXH@Z' used as target of REL32 relocation in section 25   NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '?NetShutdown@TApp@OP2Internal@@QAEXH@Z' used as target of REL32 relocation in section 1A   NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '?MsgBox@OP2Internal@@YIHPAUHWND__@@PBD1H@Z' used as target of REL32 relocation in section E7   NetFixClient    \NetFixClient\OPUNetTransportLayer.obj  1   

Error   LNK2016 absolute symbol '?Initialize@GurManager@OP2Internal@@QAEHPAVNetTransportLayer@2@@Z' used as target of REL32 relocation in section 20    NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '?GetString@CConfig@OP2Internal@@QAEHPBD0PADI0@Z' used as target of REL32 relocation in section CF  NetFixClient    \NetFixClient\OPUNetTransportLayer.obj  1   

Error   LNK2016 absolute symbol '?GetString@CConfig@OP2Internal@@QAEHPBD0PADI0@Z' used as target of REL32 relocation in section 30  NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '?GetPlayerName@OP2Internal@@YIXPAD_N@Z' used as target of REL32 relocation in section 30   NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '?GetInt@CConfig@OP2Internal@@QAEHPBD0H@Z' used as target of REL32 relocation in section C1 NetFixClient    \NetFixClient\OPUNetTransportLayer.obj  1   

Error   LNK2016 absolute symbol '?GetInt@CConfig@OP2Internal@@QAEHPBD0H@Z' used as target of REL32 relocation in section 37 NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '?GetInt@CConfig@OP2Internal@@QAEHPBD0H@Z' used as target of REL32 relocation in section 2C NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '?GetInt@CConfig@OP2Internal@@QAEHPBD0H@Z' used as target of REL32 relocation in section 27 NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '?Checksum@Packet@OP2Internal@@QAEHXZ' used as target of REL32 relocation in section FD NetFixClient    \NetFixClient\OPUNetTransportLayer.obj  1   

Error   LNK2016 absolute symbol '?Checksum@Packet@OP2Internal@@QAEHXZ' used as target of REL32 relocation in section FB NetFixClient    \NetFixClient\OPUNetTransportLayer.obj  1   

Error   LNK2016 absolute symbol '?Checksum@Packet@OP2Internal@@QAEHXZ' used as target of REL32 relocation in section F7 NetFixClient    \NetFixClient\OPUNetTransportLayer.obj  1   

Error   LNK2016 absolute symbol '?Checksum@Packet@OP2Internal@@QAEHXZ' used as target of REL32 relocation in section ED NetFixClient    \NetFixClient\OPUNetTransportLayer.obj  1   

Error   LNK2016 absolute symbol '?Checksum@Packet@OP2Internal@@QAEHXZ' used as target of REL32 relocation in section E9 NetFixClient    \NetFixClient\OPUNetTransportLayer.obj  1   

Error   LNK2016 absolute symbol '??3GurManager@OP2Internal@@SAXPAX@Z' used as target of REL32 relocation in section 22  NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '??3GurManager@OP2Internal@@SAXPAX@Z' used as target of REL32 relocation in section 20  NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '??3GurManager@OP2Internal@@SAXPAX@Z' used as target of REL32 relocation in section 1A  NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '??2GurManager@OP2Internal@@SAPAXI@Z' used as target of REL32 relocation in section 20  NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '??1IDlgWnd@OP2Internal@@UAE@XZ' used as target of REL32 relocation in section 32   NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '??1IDlgWnd@OP2Internal@@UAE@XZ' used as target of REL32 relocation in section 27   NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '??1IDlgWnd@OP2Internal@@UAE@XZ' used as target of REL32 relocation in section 12   NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '??1IDlgWnd@OP2Internal@@UAE@XZ' used as target of REL32 relocation in section 10   NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '??0MultiplayerPreGameSetupWnd@OP2Internal@@QAE@XZ' used as target of REL32 relocation in section 32    NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '??0MultiplayerPreGameSetupWnd@OP2Internal@@QAE@XZ' used as target of REL32 relocation in section 27    NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '??0IDlgWnd@OP2Internal@@QAE@XZ' used as target of REL32 relocation in section E    NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1   

Error   LNK2016 absolute symbol '??0GurManager@OP2Internal@@QAE@XZ' used as target of REL32 relocation in section 20    NetFixClient    \NetFixClient\OPUNetGameSelectWnd.obj   1
DanRStevens commented 5 years ago

I'm guessing this is a new linker check. This may require a bit of investigation. I haven't found any good documentation on the error message.

You'll note in the errors above, they all refer to non-virtual function calls. It does not list any virtual methods, nor any data exports.

Likely related, is the assembly macros:

%macro  Export 2
    global %2
    section .data
    %2 EQU %1-LoadAddr
%endmacro

%macro  ExportData 2
    global %2
    section .data
    %2 EQU %1
%endmacro

%macro  ExportVirt 2
    global %2
    section .data
    %2 EQU %1
%endmacro

Not all symbols are exported the same way. Note the LoadAddr offset in the first export macro. Normal function call addresses are typically encoded within machine instruction as relative offsets, where as virtual function calls and data references use absolute addresses.

Ex (relative addresses used in machine encoding of call instruction):

call Label  ; Assembled as: E8 00000000, Jumps to address [EIP + 00000000]
Label:  ; Label is at relative offset 0 from the end of the call instruction

Side note: The above might be used to determine the current instruction pointer value in relocatable code. The CALL instruction pushes EIP onto the stack, which can then be popped into a register and used.

In contrast, virtual method calls and data accesses use the absolute form [addr].

Ex (a call to a virtual function):

mov eax, ecx  ; eax = object.virtualFunctionTablePtr
mov edi, [eax] ; edi = virtualFunctionTable[0]  (first virtual method)
call [edi] ; call virtual method

Ex (data access):

mov eax, [dataAddr] ; eax = data

Years ago I'd looked for a way to define a symbol as holding either a relative offset value, or an absolute value, but couldn't find a way. Hence the kludge of subtracting an offset in the first macro, which got added back in during code generation.


One link I came across suggested __declspec(dllexport) could somehow be used in the C++ header, though I'm not sure it would work in the case here.

DanRStevens commented 5 years ago

Some potentially interesting finds from the NASM documentation:

Absolute segments (not well supported by linkers):

SEGMENT SCREEN ABSOLUTE=0xB800

In 16-bit programming, 0xB800 was the segment address of the screen buffer. By writing to memory in that segment, data would go right to video memory and appear on screen. Perhaps we could use something like that and set:

segment op2exe absolute=0x00400000

Symbols can be accessed WRT (with respect to) a segment other than normally implied. Perhaps this can be combined with the above.

mov [es:foo wrt data],bx

It's also possible to apply WRT to EXTERN declarations:

extern foo:wrt dgroup

For OS/2 support, there are FLAT segments. I'm uncertain if this feature would be useful for our purposes or not.

Labels can be defined as ABSOLUTE:

absolute 0x1A
    kbuf_chr    resw    1
    kbuf_free   resw    1
    kbuf        resw    16

The only instructions usable in this mode are the RESB family, so perhaps not so useful here.

Brett208 commented 5 years ago

For kicks, I tried compiling with the v120 toolset (toolset packaged with VS2013). Same errors persisted, so if this error was indeed introduced in a later version of VS, it would have been pre-2013.

-Brett

Brett208 commented 5 years ago

Mildly disturbing, but apparently there isn't a concise list of Visual C++ warnings and errors available online from Microsoft's documentation?

https://stackoverflow.com/questions/1392855/where-can-i-get-a-list-of-all-errors-warnings


EDIT: Actually there is a concise list, but it doesn't seem to contain LNK2016.

https://docs.microsoft.com/en-us/cpp/error-messages/tool-errors/linker-tools-errors-and-warnings?view=vs-2017

Brett208 commented 5 years ago

By setting the linker option /force, the NetFix dll will actually compile into a DLL even though the errors are still listed on compilation.

We might be able to use /force and then set VS to ignore LNK2016 errors for now and move on.

Attempted to load the new dll with Outpost 2. op2ext gave an error saying NetFix dll could not be loaded.

Found this by googling "LNK2016" Visual Studio BTW. http://forum.outpost2.net/index.php?topic=5315.0

-Brett

DanRStevens commented 5 years ago

Hah, wow, that thread is nearly 8 years old. Didn't realized I'd wanted to make those changes for that long and still haven't. Guess I better get on that. :P

That also explains why you got errors with VS2013 toolset. Even that thread was a few years pre-existing. The original compiler I used is what, 23 years old now? That's probably the compiler we used for the last NetFixClient release.

Anyway, thanks for the investigation. Looks like we can try to get /force working for now, and maybe silence warnings until we figure out something better.

Brett208 commented 5 years ago

Just step debugged through op2ext trying to load NetFix with a /force compiled version of NetFixClient in release configuration:

op2ext finds the NetFixClient dll properly (I edited the .ini file to look for the new dll name).

It looks like NetFixClient's main.cpp is entered, and runs until the line:

OPUNetGameProtocol opuNetGameProtocol;

Then the following is thrown:

Exception thrown at 0x034318B0 in Outpost2.exe: 0xC0000005: Access violation executing location 0x034318B0.

The exception is thrown from within the OPUNetGameSelectWnd constructor, on line opuNetTransportLayer.

OPUNetGameSelectWnd::OPUNetGameSelectWnd()
{
    opuNetTransportLayer = 0;
...

I don't understand the error as setting a pointer to 0 should not be causing an access violation?

This appears to be the first thing initialized in main besides an Hinstance and maybe an ofstream. So first NetFix specific object to be initiated if that means anything?

Also don't know if this has something to do with an ill formed file by using /force?

-Brett

DanRStevens commented 5 years ago

Very detailed and useful debugging info you posted here.

The line identified by the Visual Studio debugger is likely wrong. As the project was compiled with Release settings, the optimizer will have made changes to the code that can make it difficult for a debugger to determine the source line.

That still narrows it down to somewhere very close though. Combined with the other details may be enough to determine what is happening.

I suspect it's an address problem, where the hardcoded addresses to functions within Outpost2.exe are not matching up correctly. That might be because a module was loaded at an unexpected address, or the offsets done in the macros are wrong, possibly because of changes with the newer compiler version. Some of those changes may be related to the new warnings, and why /force is now needed.

DanRStevens commented 5 years ago

I suspect the debugger problems were caused by an incorrect setting for LoadAddr in OP2Internal. The NetFixClient needs a modified value.

Given the project setting change solved the initial errors listed here, should we close this issue?