aboutsummaryrefslogtreecommitdiff
path: root/test/lang/c
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2011-11-13 04:15:56 +0000
committerGreg Clayton <gclayton@apple.com>2011-11-13 04:15:56 +0000
commita1b9a90b7aef446302de9b845dc4f3b0e1473aa7 (patch)
tree43ff34d990892951490cec7d31714f7fd3c18753 /test/lang/c
parentd14d5185b97d32c70e9b5c7ebd4b1e2077afc98b (diff)
downloadlldb-a1b9a90b7aef446302de9b845dc4f3b0e1473aa7.tar.gz
<rdar://problem/10338439>
This is the actual fix for the above radar where global variables that weren't initialized were not being shown correctly when leaving the DWARF in the .o files. Global variables that aren't intialized have symbols in the .o files that specify they are undefined and external to the .o file, yet document the size of the variable. This allows the compiler to emit a single copy, but makes it harder for our DWARF in .o files with the executable having a debug map because the symbol for the global in the .o file doesn't exist in a section that we can assign a fixed up linked address to, and also the DWARF contains an invalid address in the "DW_OP_addr" location (always zero). This means that the DWARF is incorrect and actually maps all such global varaibles to the first file address in the .o file which is usually the first function. So we can fix this in either of two ways: make a new fake section in the .o file so that we have a file address in the .o file that we can relink, or fix the the variable as it is created in the .o file DWARF parser and actually give it the file address from the executable. Each variable contains a SymbolContextScope, or a single pointer that helps us to recreate where the variables came from (which module, file, function, etc). This context helps us to resolve any file addresses that might be in the location description of the variable by pointing us to which file the file address comes from, so we can just replace the SymbolContextScope and also fix up the location, which we would have had to do for the other case as well, and update the file address. Now globals display correctly. The above changes made it possible to determine if a variable is a global or static variable when parsing DWARF. The DWARF emits a DW_TAG_variable tag for each variable (local, global, or static), yet DWARF provides no way for us to classify these variables into these categories. We can now detect when a variable has a simple address expressions as its location and this will help us classify these correctly. While making the above changes I also noticed that we had two symbol types: eSymbolTypeExtern and eSymbolTypeUndefined which mean essentially the same thing: the symbol is not defined in the current object file. Symbol objects also have a bit that specifies if a symbol is externally visible, so I got rid of the eSymbolTypeExtern symbol type and moved all code locations that used it to use the eSymbolTypeUndefined type. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@144489 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/lang/c')
-rw-r--r--test/lang/c/global_variables/TestGlobalVariables.py5
-rw-r--r--test/lang/c/global_variables/main.c4
2 files changed, 6 insertions, 3 deletions
diff --git a/test/lang/c/global_variables/TestGlobalVariables.py b/test/lang/c/global_variables/TestGlobalVariables.py
index 82ca4467d..d9fcb540b 100644
--- a/test/lang/c/global_variables/TestGlobalVariables.py
+++ b/test/lang/c/global_variables/TestGlobalVariables.py
@@ -53,8 +53,9 @@ class GlobalVariablesTestCase(TestBase):
substrs = ['GLOBAL: (int) g_file_global_int = 42',
'GLOBAL: (const char *) g_file_global_cstr',
'"g_file_global_cstr"',
- 'GLOBAL: (const char *) g_file_static_cstr',
- '"g_file_static_cstr"'])
+ 'STATIC: (const char *) g_file_static_cstr',
+ '"g_file_static_cstr"',
+ 'GLOBAL: (int) g_common_1 = 21'])
# 'frame variable' should support address-of operator.
self.runCmd("frame variable &g_file_global_int")
diff --git a/test/lang/c/global_variables/main.c b/test/lang/c/global_variables/main.c
index 880a8ed26..d0ac6a953 100644
--- a/test/lang/c/global_variables/main.c
+++ b/test/lang/c/global_variables/main.c
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include <stdio.h>
+int g_common_1; // Not initialized on purpose to cause it to be undefined external in .o file
int g_file_global_int = 42;
const char *g_file_global_cstr = "g_file_global_cstr";
static const char *g_file_static_cstr = "g_file_static_cstr";
@@ -15,7 +16,8 @@ static const char *g_file_static_cstr = "g_file_static_cstr";
extern int g_a;
int main (int argc, char const *argv[])
{
+ g_common_1 = g_file_global_int / 2;
static const char *g_func_static_cstr = "g_func_static_cstr";
printf ("%s %s\n", g_file_global_cstr, g_file_static_cstr);
- return g_file_global_int + g_a; // Set break point at this line. //// break $source:$line; continue; var -global g_a -global g_global_int
+ return g_file_global_int + g_a + g_common_1; // Set break point at this line. //// break $source:$line; continue; var -global g_a -global g_global_int
}