Getting a List of Symbols Used by My VC++ Code - visual-studio-2010

I am building a tool that process my VC++ source codes. For this, I need to obtain a list of symbols including local variable names and their types used by my codes. I know Visual C++ 2010 already provides a .bsc file that allows the object browser to locate symbols quickly. But this is an interactive tool. I need to obtain a list of the symbols in a file. Is there any tools allowing us to programmatically obtain the list of symbols used in our own VC++ source codes?
I tried the Debug Interface Access SDK provided by Microsoft. It allows us to read the .pdb file for the names of the local variables used. But I also want to obtain the exact type names used in my source codes. e.g.
MYTYPE dwordVar;
DIA SDK allows us to obtain the string "dwordVar" which is the name of a local variable. But it cannot tell its type name is "MYTYPE". It can only tell us what MYTYPE really represents (like unsigned long). But not the symbol "MYTYPE".
If Visual C++ isnt offering this feature, is there any third party tools supporting this feature?

Experimenting with this program:
typedef unsigned long MYTYPE;
int wmain(int argc, wchar_t *argv[])
{
MYTYPE test = 99LU;
}
both DIA SDK and DbgHelp return 16 (SymTagBaseType) for the symtype of the type symbol for test. It would be nice if the type symbol were a Typedef symbol (17/SymTagTypedef), but it might be that the PDB itself does not record whether the source file used a typedef or type name in declaring the type of the local variable.
One possible work-around is to enumerate the SymTagTypedef children of the global scope symbol, building a std::multimap from type IDs of the types to the typedef names. Then, for each local variable, if the multimap contains entries for the Data symbol's type ID (obtained via IDiaSymbol::get_typeId), use the IDiaSession::findLines method to figure out the line(s) on which the Data symbol is declared and search those lines for any of the typedef name strings, possibly performing preprocessing before searching.

Related

Access source code information from the Visual Studio editor

I'm trying to get into creating Visual Studio extensions. There are a few examples in the online documentation from Microsoft about creating custom stuff but I can't find anything on how to access Intellisense (or any other code analysis).
I know there are some questions about this topic (namely how do you get c++ Intellisense data in a visual Studio Extention?) but those are from 2012 or earlier and not up to date anymore (at least I hope so).
The following is only applied to C++ source code.
What I specifically want, is to examine the expression that the cursor is at. Then I want to check whether the expression is either
an object declaration / instanciation, like string s("my string");, or
a function call, like std::max(1, 2);
From those expressions I want to get the full qualified name (including the namespace) of the type / function and possibly the types of the function / constructor arguments. For example:
// ...
using namespace std;
auto x = max(1, 2);
// ...
Now, if the cursor enters max I need the full qualified name ::std::max and the argument types [int, int].
Another example:
// ...
using namespace std;
string s("my string");
// ...
Here I need the full qualified name ::std::string and the argument types [const char*, std::allocator].
Is this somehow possible? I'm also interested in partial solutions. Any guidance or hints to some sort of documentation is very welcome.
We can only get partial information via code model.
https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.vccodemodel.vccodemodel?view=visualstudiosdk-2017

Error: functions that differ only in their return type cannot be overloaded

I'm using mac os 10.9, I have a C++ program that uses freeglut library. When I try to make the project. It gives an error which I don't know if it's my fault or not. This is the message:
In file included from /usr/X11/include/GL/freeglut.h:18:
/usr/X11/include/GL/freeglut_ext.h:177:27: error: functions that differ only in their return type cannot be overloaded
FGAPI GLUTproc FGAPIENTRY glutGetProcAddress( const char *procName );
More information: I used CMake (version 2.8.12) to generate the Makefile, and installed the latest version of Xcode and XQuartz.
Any help is appreciated. Thank you.
In glut.h and freeglut_ext.h files:
In glut.h:
#if (GLUT_API_VERSION >= 5)
extern void * APIENTRY glutGetProcAddress(const char *procName) OPENGL_DEPRECATED(10_3, 10_9);
#endif
In freeglut_ext.h:
/*
* Extension functions, see freeglut_ext.c
*/
typedef void (*GLUTproc)();
FGAPI GLUTproc FGAPIENTRY glutGetProcAddress( const char *procName );
One of the declarations returns a function type GLUTproc (specifying a function that takes no arguments), and the other declaration returns a pointer (void*). Both functions take the same arguments (a single const char*). What the compiler says is true.
You're only seeing a complaint about "overloading" because it's C++. In C++, if a compiler thinks it's seen two different functions with the same name then each one needs to have different arguments (e.g. a different number of arguments, or distinct types).
In this case, I doubt the functions are meant to be different; they're meant to be the same, and at some point the API evolved and changed the declaration.
You need to find some way to prevent the compiler from seeing both declarations at the same time (perhaps by setting GLUT_API_VERSION). If you have to, you can #include just one of the files and see if you really need the other file (and if you did, you may have to manually declare some things to avoid a 2nd #include).

Visual studio 2010: how to watch a memory hex location

I tried some suggestions found online but it does not work for me. Im using Visual Studio 2010. Basically I typed loc(kcs(1,4)) (thats my variable) and I obtained 157510036. Its hex is 9636994. So then I typed (INTEGER*)0x9636994 but on the watch window under the "value"column it says "undefined variable INTEGER". I trid lowercase integer or real and same answer. Any suggestion?
I typed (INTEGER*)0x9636994 but on the watch window under the "value"column it says "undefined variable INTEGER".
According to Restrictions on Native C++ Expressions:
Type Casting
If you cast to a type, the type must be known to the debugger. You must have another object of that type in your program. Types created using typedef statements are not supported.
Try using the underlying type. So, for example, if INTEGER is actually an int you would try to watch (int *)0x9636994.
This also assumes that the variable is fixed at 0x9636994 (basically that you're not trying to refer to something transient on the stack).

Wondering about COFF Externs

The Microsoft PE/COFF SPEC (v8, section 5.4.4) says that when a symbol has:
A storage class of IMAGE_SYM_CLASS_EXTERNAL
And a section number of 0 (IMAGE_SYM_UNDEFINED)
It's "value" field (in the symbol table) which "indicates the size".
This confuses me. In particular, I'm wondering "indicates the size of what?".
Generally, IMAGE_SYM_CLASS_EXTERNAL and IMAGE_SYM_UNDEFINED are used by CL(visual C++) to represent externs.
Why would the linker need to know, or care, about the symbol's size? Doesn't it just need to know a name, that it's an extern, and have the appropriate relocation entries set? None of this should depend on size. Now, admittedly, the compiler needs to know this, but it would get that information from a header file, not from an object file.
I've looked at some simple example externs compiled by CL, and the Value field always seems to be zero. So, it's clearly not being used to encode the size of the field.
Does anyone know what "size" the spec is referring to? Are their any scenarios where the visual studio linker might use that field, or is that blurb in the spec just nonsense? My limited brain is unable to think of any such scenarios.
Update:
Please note that it does not, at least not always, appear to be the size of the symbol. In the cases I've observed the VALUE IS ALWAYS 0, hence the question.
Mr.Wisniewski, I believe I found the answer.
I'm a student and I've tried to write my own linker.
The very first version of it can link OBJ files and dump them
to my own binary format. But soon I've realized that many C++ language
features are unsupported without LIBCMT.LIB.
So at first I've coded lib parser... and stuck while trying to link CRT.
In the second linker member of the file LIBCMT.LIB was specified that
object file crt0.obj (inside libcmt) contains symbol __acmdln (global pointer to the
command line)... but I couldn't manage to find it there! I was really frustrated...
Symbol had IMAGE_SYM_CLASS_EXTERNAL and section IMAGE_SYM_UNDEFINED, but why?
In the source file crt0.c there is a declaration:
#ifdef WPRFLAG
wchar_t *_wcmdln; /* points to wide command line */
#else /* WPRFLAG */
char *_acmdln; /* points to command line */
#endif /* WPRFLAG */
My investigation was rather long and the result is so:
C++ compiler places uninitilized data into the .bss section and marks it with IMAGE_SCN_CNT_UNINITIALIZED_DATA, but
pure C compiler behaves in a different way (libcmt was written in C).
It is linker's duty to place uninitialized data into sections.
If C compiler emits symbol without section (0) and marked as external and if
it's value field is zero, then it is declared anywhere else, but if value field is not null, that
means that given OBJ file really contains that symbol but it is not initialized.
So linker should reserve place in .bss section for it. THE PLACE OF 'VALUE' SIZE.
And when you change those lines to:
#ifdef WPRFLAG
wchar_t *_wcmdln = 0xCCCCCCCC; /* points to wide command line */
#else /* WPRFLAG */
char *_acmdln = 0xCCCCCCCC; /* points to command line */
#endif /* WPRFLAG */
There will be zero value field and both of them will be placed in .data section.
Good luck, and sorry for my bad English.
How about an extern declaration for an array that declares the size:
a.cpp:
extern int example[42];
b.cpp:
int example[13];
The fact that the linker doesn't catch this mismatch suggests however that Value isn't used. I have no easy way to see that.
It's the size of the data structure referred to by the symbol.
Basically, if the symbol is undefined, the linker can't otherwise find the size of the data structure, and therefore needs to know in advance how big it is when it's instantiated so it can deal with those issues during linkage.
You have a very exotic, but interesting question. It it correct that the only possibility to produce symbol table inside of COFF is usage of /Zd compiler switch which are supported till Visual C++ 6.0 and use the old linker switch /debugtype:coff (see http://www.debuginfo.com/articles/gendebuginfo.html#gendebuginfovc6)? Is there any possibility to produce symbol table inside of COFF with at least Visual Studio 2008?
My idea is try to produce a PE with a symbol table of storage class IMAGE_SYM_CLASS_EXTERNAL and the section number 0 (IMAGE_SYM_UNDEFINED) with respect of linker switch /FORCE (/FORCE:UNRESOLVED or /FORCE:MULTIPLE) and an unresolved symbol either by /INCLUDE:dummySymbol or by /NODEFAULTLIB. My problem is that it's not easy to produce symbol table inside of COFF. Where you receive the test PEs?

Using GetProcAddress when the name might be decorated

What is the correct way to use GetProcAddress() on a 32 bit DLL? On win32, there are three calling conventions, cdecl, stdcall and fastcall. If the function in the DLL is foo they will decorate the name in the following ways _foo, _foo#N and #foo#N.
But if the author of the dll has used a .def file, then the exported name will be changed to just "foo" without any decoration.
This spells trouble for me because if I want to load foo from a dll that is using stdcall, should I use the decorated name:
void *h = LoadLibraryEx(L"foo.dll", NULL, 0);
GetProcAddres((HMODULE)h, L"_foo#16");
Or the undecorated one:
void *h = LoadLibraryEx(L"foo.dll", NULL, 0);
GetProcAddres((HMODULE)h, L"foo");
? Should I guess? I've looked at lots of 32 bit DLL files (stdcall and cdecl) and they all seem to export the undecorated name. But can you assume that is always the case?
There's really no shortcut or definitive rule here. You have to know the name of the function. The normal scenario is that you know at compile time the name of the function. In which case it does not matter whether the exported name is mangled, decorated, or indeed completely unrelated to the semantic name. Functions can be exported without names, by ordinal. Again, you need to know how the function was exported.
If you are presented with a header file for a library, and want to link to it with explicit linking (LoadLibrary/GetProcAddress) then you will need to find out the names of the function. Use a tool like dumpbin or Dependency Walker to do that.
Now, the other scenario which might lead to you asking the question is that you don't know the name at compile time. For instance, the name is provided by the user of your program in one way or another. Again, it is quite reasonable to require the user to know the exported name of the function.
Finally, you can parse the PE meta data for the executable file to enumerate its exported function. This will give you a list of exported function names, and exported function ordinals. This is what tools like dumpbin and Dependency Walker do.
If __declspec(dllexport) is used during compilation and __declspec(dllimport) in header file, as well as extern "c", then you do not need to decorate those functions. The __declspec helps in using the undecorated names, but function overloads, namespaces, and classes still require same way to distinguish them.
Usually, object oriented functions are exported using function ordinals instead of their decorated names. Cast the ordinal as (char*)(unsigned short)ordinal, thus, GetProcAddress(module, (char*)(unsigned short)ordinal);
Edit: while most of Windows use UTF-16, GetProcAddress uses UTF-8, so it cannot use a wide character string.
GetProcAddress(module, L"foo") is identical to GetProcAddress(module, "f");

Resources