I am trying to extract information from object file with nm command for some kind of static code analysis in which I have to count numbers of declared variables and functions in a C code. I have went through the documentation of GNU Binutils. I could find the variables declared in global scope in the symbol table returned by nmbut I couldn't find variables those are declared in local scope. Why is that? How can I access it?
Is there any way other than nm in which I can extract my desired information. As a compiler gcc is supposed to generate a symbol table for its use. Can I access it through any gcc command?
You cannot access to local variables from object files, because gcc does not save information about it. You can use nm only to list symbol-table of object files. These symbol-tables is used to linking. Local variables is not needed in link time. Non static fields of structs and classes too.
For viewing of local variables gcc may compile programs with special debug information about it. But for puposes of static analysing you should analyse source code or machinary code in objectfiles.
Related
Is there a warning option switch that will identify spec-level procedures, functions, or variables that are not called or referenced anywhere? I've tried the switches below without luck.
This is what I'm currently using:
-gnatwfilmopuvz
-- m turn on warnings for variable assigned but not read
-- u turn on warnings for unused entity
-- v turn on warnings for unassigned variable
When I move unused variables from the spec to the body, the compiler correctly identifies them as not referenced. I would like to understand why the compiler won't identify unused code in the spec, and if there is a way to get it to do so. An excessive number of warnings isn't a concern, because I use the filter field in gnat studio to only look at a few files at a time, and I can easily filter to ignore library packages.
Any help is very appreciated.
The compiler will only detect unused items in the unit it is compiling.
If you have items in a package spec, you can know they are used (or not) only by exploring the whole project's Ada sources. Some tools like AdaControl can do it.
You need a tool for that: gnatelim. Its main use is to reduce the size of the executable, eliminating the object code for unused subprograms, but you can use its output just to get the list of unused subprograms. As far as I know, it will not detect unused variables in the spec, only procedures and functions.
https://gcc.gnu.org/onlinedocs/gcc-4.5.4/gnat_ugn_unw/About-gnatelim.html
Use link-time garbage collection: https://docs.adacore.com/live/wave/gnat_ugn/html/gnat_ugn/gnat_ugn/gnat_and_program_execution.html#reducing-size-of-executables-with-unused-subprogram-data-elimination
You can then add the linker option --print-gc-sections to instruct the linker to print out a list of all symbols that were garbage collected.
Say, if a project leader don't want his team members to use global variables, how can he do this technically? Is there an option when building GCC that makes it throw errors when it knows someone has declared a global variable?
And static global is allowed, however.
As requested
How do you plan to use stdin, stdout, stderr and errno (to name but four global variables) if you can't declare global variables? Do you really mean you don't want people to define global variables — though library implementers are exempted because they're required to defined stdout etc?
My suspicion is that you'd do best parsing the output of nm -g file.o (or thereabouts; the options can vary between systems, and the output formats vary dramatically between systems), looking for global variable definitions. You could look for global variable references, but system libraries use them too, so you'd have to know which global variable references are OK and which are not.
I'm not aware of a GCC option for the job, but that doesn't mean it doesn't exist. Have you looked at the manual? I did look and didn't find an appropriate warning — probably because it isn't a common requirement.
gdb provides a command "print localx" which prints the value stored in the localx variable. So, it basically must be using the symbol table to find the mapping (localx -> addressx on stack). I am unable to understand how this mapping can be created.
What I tried
I studied the intermediate temporary files of gcc using -save-temps option, and observed that a local variable local1 was mapped to a symbol name "LASF8". However, the objdump utility tool did not show this symbol name.
Context :
I am working on a project which requires building a pin-tool to print the accesses of local variables. Given a function, I would like to say that this address corresponds to this variable name. This requires reading the symbol table to correspond an address to a symbol table entry. GDB does the exact reverse mapping. Hence, I would like to understand the same.
The symbol table is contained in the debugging information. This debugging information is emitted by gcc -g. gdb reads the debugging information to get symbolic information, among other things.
Typically the debugging information is in DWARF format. See http://www.dwarfstd.org/ for the specification.
You can also see DWARF more directly using readelf. For example readelf -wi will show the main (".debug_info") debugging information for an ELF file.
Note that doing the mapping in reverse -- that is, assigning a name to every stack slot -- is not entirely easy. First, not every stack slot will have a name. This is because the compiler may spill temporaries to the stack. Second, many locals will have DWARF location expressions to represent their location. This means you'll need to write an expression evaluator (not hard but also not trivial); you could conceivably (unlikely in practice but possible in theory) run into expressions which cannot be evaluated without a real stack frame; and finally the names will therefore generally only be valid at a given PC.
I believe there's a feature request in gdb bugzilla to add this feature to gdb.
i am building a C project with Xcode and when ever i build it it gives me this error:
ld: duplicate symbol _detectLinux in /Users/markszymanski/Desktop/Programming/C/iTermOS/build/iTermOS.build/Debug/iTermOS.build/Objects-normal/i386/linuxDetect.o and /Users/markszymanski/Desktop/Programming/C/iTermOS/build/iTermOS.build/Debug/iTermOS.build/Objects-normal/i386/iTermOS.o
Thanks!
This means you have defined the same symbol with global scope in (at least) two different source files -- either a function or a global variable called _detectLinux, and apparently in the files linuxDetect.c and iTermOS.c.
How to fix it depends on how you intend to use this symbol:
If you meant to define it in one file and use it in the other file, declare it extern in the other file.
If you only intend to use the symbol in the file that it is declared in, you can declare it static.
If the symbol is defined in both files, you can rename the symbol in one (or both) files.
If _detectLinux is a function, one common way to get this problem is to define it in a header file but forget to mark it inline. This would cause it to generate the function code in each file that includes the header (presumably _detectLinux.c and iTermsOS.c).
Alternately perhaps you copy-pasted the entire body of the function between the two source files instead of simply declaring the function in iTermsOS.c where I expect it's being called.
Well, that's not much information to go on. As the error says, the symbol _detectLinux is included in both linuxDetect.o and iTermsOS.o and when you try to link them together, there is a conflict since the linker does not know which of the two symbols to use. This might happen if you, for example, have a global variable with that name in a .h file which is used to build both files instead of declaring it in one place and declaring it as "extern" in the .h file.
What you need to do is look at where the symbol _detectLinux is originally declared, then trace through the dependencies for both linuxDetect.o and iTermOS.o to see why it is being included publicly in both.
I have a question regarding gcc. Why I get an error of unused variable when I define the variable locally in a function but not when the variable is global in a unique file?.
I can understand that it can be use for someone else, but to do that then I need to put the external word right?
Thanks in advance.
The compiler has no way of knowing if a global variable is used - it could be used from a compilation unit written in a completely different language, for example.
If by "global in a unique file", you mean "int x;" outside of any function, the it's not the compilers job to detect that, the variable needs to be available to the linker in case another compilation unit needs it (such as errno).
If you meant "static int x" where it's not made available to the linker, this is probably just a choice made by GCC. I don't believe compilers are required to notify of this and it does no real damage other than wasting a few bytes in your address space.
Because global variables can be used on any other place that the compiler cannot known. For instance on a external library o program.
Unused locals can be determined by the compiler. Unused globals can only be determined by the linker, since they can be shared across object files.
In general, the linker doesn't do warnings for code-gen.
When the variable is global, the compiler has not full visibility across all the compilation units in the project - the variable could be modified in another compilation unit. The linker is able to tell that it is unused, probably it will remove it from the object file.
Because if it's global it can be used by another module that gets linked in later.
It's a common idiom to have all your globals defined in a single file. That file may not even have any code, much less code that uses all the variables.
I have encountered the same question when I build the dalvikVM in android2.3 and I got the key of the point. It is because that the parameters of the compiler is too strict:
LOCAL_CFLAGS += -Werror.