CRT and External Symbols

Programming, for all ages and all languages.
Post Reply
User avatar
mark3094
Member
Member
Posts: 164
Joined: Mon Feb 14, 2011 10:32 pm
Location: Australia
Contact:

CRT and External Symbols

Post by mark3094 »

I have created a cutdown C Library, consisting of functions such as printf, putchar, strlen, etc.
I created these in a separate Visual Studio 2010 project to test and compare to the builtin library functions.
NB, I am using C, not C++.

Now I have gotten them working, I have created a new project which will become my OS. I have disabled the builtin CRT (as you know, it won't work with a custom OS). I then imported (cut and paste) my library code into the new project.

Now when I try to compile it, I am getting unresolved external symbol errors:

Code: Select all

C-Lib.lib(printf.obj) : warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/OPT:ICF' specification
C-Lib.lib(printf.obj) : error LNK2001: unresolved external symbol __fltused
C-Lib.lib(finite.obj) : error LNK2001: unresolved external symbol __fltused
C-Lib.lib(printf.obj) : error LNK2019: unresolved external symbol __aullshr referenced in function _printf
C-Lib.lib(printf.obj) : error LNK2019: unresolved external symbol __allrem referenced in function _printf
C-Lib.lib(intconv.obj) : error LNK2001: unresolved external symbol __allrem
C-Lib.lib(printf.obj) : error LNK2019: unresolved external symbol __ftol2 referenced in function _printf
C-Lib.lib(printf.obj) : error LNK2019: unresolved external symbol __ftol2_sse referenced in function _printf
C-Lib.lib(intconv.obj) : error LNK2019: unresolved external symbol __alldiv referenced in function _itoa
C-Lib.lib(intconv.obj) : error LNK2019: unresolved external symbol __aulldiv referenced in function _uitoa
C-Lib.lib(intconv.obj) : error LNK2019: unresolved external symbol __aullrem referenced in function _uitoa
I did not even know I was calling these functions. I presume they are built into the compiler somehow.

I did find an article suggesting this for one of the symbols:

Code: Select all

int _fltused = 1;
If I use this the error just changes to:

Code: Select all

C-Lib.lib(putchar.obj) : error LNK2005: __fltused already defined in main.obj
HAL.lib(console.obj) : error LNK2005: __fltused already defined in main.obj
I have searched around, but I have not yet found anything that helps me.
How does everyone else work around this problem?

Thankyou for your help
User avatar
mark3094
Member
Member
Posts: 164
Joined: Mon Feb 14, 2011 10:32 pm
Location: Australia
Contact:

Re: CRT and External Symbols

Post by mark3094 »

I've done a bit more research...

Are these functions hardware specific routines to perform functions such as dividing numbers?

I have found this link:
http://research.microsoft.com/en-us/um/ ... #_allrem#2

But this suggests this is for 64-bit code. I am only working with 32-bit at this stage.


EDIT:
I have compiled this information together if it helps anyone else. Still trying to figure out what to do with it:

CRT external symbols:

-> _allrem
-> Calculate the remainder after dividing two 64 bit integers
http://research.microsoft.com/en-us/um/ ... lrem.c.htm

-> _aullrem
-> Calculate the remainder after dividing two unsigned 64 bit integers
http://research.microsoft.com/en-us/um/ ... lrem.c.htm

-> _aullshr
-> Long shift right
http://research.microsoft.com/en-us/um/ ... lshr.c.htm

-> _alldiv
-> Signed long divide
http://research.microsoft.com/en-us/um/ ... ldiv.c.htm

-> _aulldiv
-> Unsigned long divide
http://research.microsoft.com/en-us/um/ ... ldiv.c.htm

-> _fltused
-> Identifies whether floating point is used. Set to 1

-> _ftol2

-> _ftol2_sse
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: CRT and External Symbols

Post by neon »

Hello,

Not 64 bit code, 64 bit operations (long long types) and intrinsic floating point routines the compiler expects. Solutions involve disabling optimization's for that routine or defining those functions in your CRT. I can provide some of our versions of those routines if requested.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
User avatar
mark3094
Member
Member
Posts: 164
Joined: Mon Feb 14, 2011 10:32 pm
Location: Australia
Contact:

Re: CRT and External Symbols

Post by mark3094 »

I will try to work with disabling the optimisation first.
If I have to write my own functions, I will try them myself first, then request help if I get stuck

Thanks again for your help.


EDIT:

I already have optimisation disabled with the /Od switch. Is there some other optimisation set somewhere that I can't find, or does this mean I will definitely have to write these ASM functions?
User avatar
blobmiester
Member
Member
Posts: 45
Joined: Fri Jul 16, 2010 9:49 am

Re: CRT and External Symbols

Post by blobmiester »

As far as I know, you definitely have to write these functions to manipulate 64-bit values on a 32-bit platform that doesn't intrinsically support it (such as x86).

The functions aren't too complicated to write, and they don't have to be in assembler. My 64-bit functions are in C++.

Also, if you don't much care about licencing, Visual Studio does come with the source for those math functions (all you would have to do is take the files, throw them in your source directory, and make sure they get assembled with MASM and linked into your library).
User avatar
mark3094
Member
Member
Posts: 164
Joined: Mon Feb 14, 2011 10:32 pm
Location: Australia
Contact:

Re: CRT and External Symbols

Post by mark3094 »

Thankyou for your help everyone

Those links posted earlier do provide some useful code, which I have been able to study, and write some of my own basic functions to get by with. I'm still a bit stuck on the division ones, so I have borrowed some code until I can fully understand it.

Now just to figure out the floating point external symbols...
User avatar
mark3094
Member
Member
Posts: 164
Joined: Mon Feb 14, 2011 10:32 pm
Location: Australia
Contact:

Re: CRT and External Symbols

Post by mark3094 »

Just a follow up to this thread...

When does _alldvrm and _aulldvrm get used? I do know what it does - divides a long long integer and returns the result of the divide as well as the remainder.

To clarify, a divide of a long long integer will use _alldiv and a mod of a long long integer will use _allrem, but I can't figure out what operation uses _alldvrm.



Thankyou
Post Reply