Commit 99770d26 authored by rdubner's avatar rdubner

Use obmod to put symbol string into cprint.py

parent 004f2f16
......@@ -415,6 +415,7 @@ CreateCSV(PARAMETERS &params,
static void
CreateCModule(PARAMETERS &params,
const COB_LABELS &cob_labels,
const VARIABLE_TREE &var_tree)
{
/* This routine puts the COBOL-identifier/C-identifier cross-reference
......@@ -430,6 +431,32 @@ CreateCModule(PARAMETERS &params,
params.csym << "volatile char *" << params.cbl_filename.GetFname()
<< "_o0O0o_Symbols[] = {" << endl;
// Do the line/address information from the .text in the minimal form
// used by cprint.py to figure out which program a trap has occurred in.
string current_program = "";
for(int i=0; i<cob_labels.size(); i++) {
COB_LABEL cs = cob_labels[i];
if( cs.section EQ "Linkage" ) {
// This information was previously transferred to the
// data_description information, so don't put it out here because
// it's potentially confusing.
continue;
}
stringstream ss;
ios_base::fmtflags deflags = ss.flags();
if( cs.program != current_program)
{
current_program = cs.program;
ss << "P|";
ss << cs.line_number << "|";
ss << cs.program << "|";
params.csym << " \"" << ss.str() << "\"," << endl;
}
}
// You can't change the order of things here unless you also change
// the ordering in cprint.py They are tightly linked, and that's that!
......@@ -437,6 +464,7 @@ CreateCModule(PARAMETERS &params,
const VAR_NODE var = var_tree[i];
stringstream ss;
ss << "D|";
ss << var.GetSection().substr(0,2) << "|";
ss << var.GetLevel() << "|" ;
ss << var.GetCanonicalName() << "|" ;
......@@ -562,7 +590,7 @@ int main(int argc, char *argv[])
CreateCSV(params,cob_labels,variable_tree);
// Create our C-code cross-reference module
CreateCModule(params,variable_tree);
CreateCModule(params,cob_labels,variable_tree);
return 0;
......
......@@ -951,6 +951,79 @@ void ELF::CreateSection(const std::string &sec_name,
}
}
static string ZeroIsNull(const LONGLONG &v)
{
stringstream ss;
if( v != 0 )
{
ss << v;
}
return ss.str();
}
string ELF::SymbolString()
{
/* This routine puts the COBOL-identifier/C-identifier cross-reference
information into a single string that will be prepended, as a string
variable, to the cprint.py module embedded in the executable as a
.debug_script
*/
stringstream ss;
ss << "VARIABLE_STRING=\"";
// Do the line/address information from the .text in the minimal form
// used by cprint.py to figure out which program a trap has occurred in.
string current_program = "";
for(int i=0; i<cobst_symbols.size(); i++)
{
COBST_SYMBOL cs = cobst_symbols[i];
if( cs.division EQ "Procedure")
{
if( cs.section EQ "Linkage" ) {
// This information was previously transferred to the
// data_description information, so don't put it out here because
// it's potentially confusing.
continue;
}
if( cs.program != current_program)
{
current_program = cs.program;
ss << "P|";
ss << cs.line_number << "|";
ss << cs.program;
ss << "~";
continue;
}
}
}
for(int i=0; i<cobst_symbols.size(); i++)
{
COBST_SYMBOL cs = cobst_symbols[i];
if( cs.division EQ "Data")
{
ss << "D|";
ss << cs.section.substr(0,2) << "|";
ss << ZeroIsNull(cs.level) << "|" ;
ss << cs.full_name << "|" ;
ss << cs.base_symbol << "|" ;
ss << ZeroIsNull(cs.offset) << "|" ;
ss << cs.list_type.substr(0,1) << "|" ;
ss << ZeroIsNull(cs.list_size) << "|" ;
ss << cs.picture << "|" ;
ss << ZeroIsNull(cs.occurs) << "|" ;
ss << ZeroIsNull(cs.attr_type) << "|" ;
ss << ZeroIsNull(cs.attr_digits) << "|" ;
ss << ZeroIsNull(cs.attr_scale) << "|" ;
ss << ZeroIsNull(cs.attr_flags) << "~";
}
}
ss << "\"";
return ss.str();
}
#if 0
void ELF::InsertDebugScript(const std::string &python_script)
{
......@@ -966,7 +1039,7 @@ void ELF::InsertDebugScript(const std::string &python_script)
AddToStringTable(script_sec,strange_string);
}
#else
void ELF::InsertDebugScript(const std::string &python_script)
void ELF::InsertDebugScript(const std::string &python_script,const std::string &sname)
{
CPROFILER;
// This version embeds the entire cprint.py program as a text string
......@@ -977,11 +1050,15 @@ void ELF::InsertDebugScript(const std::string &python_script)
memcpy(embedded,___python_cprint_py,___python_cprint_py_len);
embedded[___python_cprint_py_len] = '\0';
string symbol_string = SymbolString();
// Make sure we have a section
CreateSection(script_sec,SHT_PROGBITS,0);
string strange_string = "\x04";
strange_string += python_script;
strange_string += "\n";
strange_string += symbol_string;
strange_string += "\n";
strange_string += embedded;
AddToStringTable(script_sec,strange_string);
delete[] embedded;
......
......@@ -195,7 +195,8 @@ public:
void DumpEntireDebugInfoDieTree();
void RunLineStateMachine(bool show_your_work);
void ReplaceDebugLineSection();
void InsertDebugScript(const std::string &python_script);
std::string SymbolString();
void InsertDebugScript(const std::string &python_script, const std::string &sname);
void AugmentSymbolTable();
SECTION_HEADER *GetSectionHeaderDangerous(const std::string secname)
......
......@@ -29,16 +29,26 @@ void COBST_SYMBOLS::ReadFrom(const string &cobst_filename)
const string SOURCE_FILE = "Source File";
const string LINE_NUMBER = "Line Number";
const string PROGRAM_NAME = "Program Name";
const string DIVISION = "Division";
const string ENTRY = "Entry";
const string SECTION = "Section";
const string PARAGRAPH = "Paragraph";
const string ASSEMBLY_SECTION = "Assembly Section";
const string ADDRESS = "Relative Address";
const string FULL_NAME = "Full Name";
const string LEVEL = "Level";
const string BASE_SYMBOL = "Base Symbol";
const string OFFSET = "Offset";
const string LIST_TYPE = "List Type";
const string LIST_SIZE = "List Size";
const string PICTURE = "Picture";
const string OCCURS = "Occurs";
const string ATTR_TYPE = "Attr Type";
const string ATTR_DIGITS = "Attr Digits";
const string ATTR_SCALE = "Attr Scale";
const string ATTR_FLAGS = "Attr Flags";
unordered_map<string,size_t>header_columns;
map<string,size_t>header_columns;
for(int i=0; i<(int)column_headers.size(); i++) {
header_columns[column_headers[i]] = i;
}
......@@ -57,6 +67,7 @@ void COBST_SYMBOLS::ReadFrom(const string &cobst_filename)
cobst_symbol.file = values[header_columns[SOURCE_FILE]];
cobst_symbol.line_number= stoull(values[header_columns[LINE_NUMBER]]);
cobst_symbol.program = values[header_columns[PROGRAM_NAME]];
cobst_symbol.division = values[header_columns[DIVISION]];
cobst_symbol.entry = values[header_columns[ENTRY]];
cobst_symbol.section = values[header_columns[SECTION]];
cobst_symbol.paragraph = values[header_columns[PARAGRAPH]];
......@@ -78,9 +89,18 @@ void COBST_SYMBOLS::ReadFrom(const string &cobst_filename)
OR cobst_symbol.section EQ "LOCAL-STORAGE"
OR cobst_symbol.section EQ "LINKAGE" ) {
cobst_symbol.full_name = values[header_columns[FULL_NAME]];
cobst_symbol.level = stoi(values[header_columns[LEVEL]]);
cobst_symbol.base_symbol = values[header_columns[BASE_SYMBOL]];
cobst_symbol.offset = stoull(values[header_columns[OFFSET]]);
}
cobst_symbol.list_type = values[header_columns[LIST_TYPE]];
cobst_symbol.list_size = stoull(values[header_columns[LIST_SIZE]]);
cobst_symbol.picture = values[header_columns[PICTURE]];
cobst_symbol.occurs = stoi(values[header_columns[OCCURS]]);
cobst_symbol.attr_type = (USHORT)stoul(values[header_columns[ATTR_TYPE]]);
cobst_symbol.attr_digits = (USHORT)stoul(values[header_columns[ATTR_DIGITS]]);
cobst_symbol.attr_scale = (SHORT)stoi(values[header_columns[ATTR_SCALE]]);
cobst_symbol.attr_flags = (USHORT)stoul(values[header_columns[ATTR_FLAGS]]);
}
cobst_symbols.push_back(cobst_symbol);
prior = cobst_symbol;
......
......@@ -11,6 +11,7 @@ public:
ULONGLONG column; // The column, if it can be divined
std::string program; // From the COBOL PROGRAM-ID
std::string division; // Procedure vs Data
std::string entry; // ...programs have entries
std::string section; // ...that might have sections
std::string paragraph; // ...that might have paragraphs
......@@ -20,8 +21,17 @@ public:
ULONGLONG address; // Relative address
std::string full_name; // COBOL symbol name
int level; // COBOL symbol level
std::string base_symbol;// C-code base symbol for the COBOL symbol
ULONGLONG offset; // offset from the base address
std::string list_type; //
size_t list_size; // Length of data
std::string picture;
int occurs;
USHORT attr_type;
USHORT attr_digits;
SHORT attr_scale;
USHORT attr_flags;
COBST_SYMBOL()
{
......
......@@ -5,13 +5,14 @@
using namespace std;
int main(int argc, char **argv)
{
{
PROFILER;
PARAMETERS params = GetParameters(argc, argv);
if(!params.quiet) {
if(!params.quiet)
{
cout << "obmod version " << VERSION << endl;
}
}
ELF elf;
......@@ -46,7 +47,7 @@ int main(int argc, char **argv)
// Run the line number state machine to see our replacements
elf.RunLineStateMachine(false);
elf.InsertDebugScript("cprint.py");
elf.InsertDebugScript("cprint.py",params.o_input_filename.GetFname());
// Put the COBOL symbols into the elf segments
// Took this out in January 2020; it was corrupting more complex
......@@ -63,5 +64,5 @@ int main(int argc, char **argv)
// Put the headers and sections back together, and writes them out to a
// file.
elf.WriteTo(params.o_output_filename.WholePath());
}
}
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerCommandArguments>-i \temp\optfde01\optfde01.o -o \temp\optfde01\optfde01.new.o -t \temp\optfde01\optfde01.tab</LocalDebuggerCommandArguments>
<LocalDebuggerCommandArguments>-i ../samples/optfde01/optfde01.o -o ../samples/optfde01/optfde01.new.o -t ../samples\optfde01/optfde01.tab</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LocalDebuggerCommandArguments>-i \temp\optfde01\optfde01.o -o \temp\optfde01\optfde01.new.o -t \temp\optfde01\optfde01.tab</LocalDebuggerCommandArguments>
<LocalDebuggerCommandArguments>-i ../samples/optfde01/optfde01.o -o ../samples/optfde01/optfde01.new.o -t ../samples\optfde01/optfde01.tab</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerCommandArguments>-i \temp\optfde01\optfde01.o -o \temp\optfde01\optfde01.new.o -t \temp\optfde01\optfde01.tab</LocalDebuggerCommandArguments>
<LocalDebuggerCommandArguments>-i ../samples/optfde01/optfde01.o -o ../samples/optfde01/optfde01.new.o -t ../samples\optfde01/optfde01.tab</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerCommandArguments>-i \temp\optfde01\optfde01.o -o \temp\optfde01\optfde01.new.o -t \temp\optfde01\optfde01.tab</LocalDebuggerCommandArguments>
<LocalDebuggerCommandArguments>-i ../samples/optfde01/optfde01.o -o ../samples/optfde01/optfde01.new.o -t ../samples\optfde01/optfde01.tab</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>
\ No newline at end of file
# This module implements the gdb extension command cprint
#
# Be It Hereby Declared! The obmod program will insert a line
# before line 1 as seen here. That additional line will be of the
# form SYMBOLS_LOCATION = "<filename>_o0O0O_Symbols", which will be the
# global location of the symbol table information that will have been
# generated by cobst and compiled into the executable module.
#
# It reads symbol table data from the .tab file generated
# by the cobst program, and then uses that to script its
# way through gdb commands to get the actual data so that
......@@ -85,6 +91,18 @@ import re
import sys
import os
def GetByte(address) :
byte = None
command = "x/1b " + str(address)
address += 1
byte_string = gdb.execute(command,False,True)
print(address, byte_string)
nfound = byte_string.rfind("\t")
if nfound > -1 :
byte_string = byte_string[nfound+1:]
byte = int(byte_string,16)
return byte
def LeftRight(s,splitchar) :
"""Splits what is presumably a numeric string with a possible
splitting character into left and right pieces"""
......@@ -221,6 +239,36 @@ class VarTrie() :
# and we are done
def ReadFromSymbolTable(self,address_string) :
address = int(address_string,16)
da_list = []
while True :
byte = GetByte(address)
address += 1
if byte == 0 :
break;
next_word = chr(byte)
while True :
byte = GetByte(address)
address += 1
if byte == 0 :
# Got the end of a line
break;
char = chr(byte)
if char == "|" :
da_list.append(next_word)
next_word = ""
continue;
next_word += char
# We have a line's worth of tokens:
print( da_list )
pass
def ReadFromFile(self,tab_file) :
# Clear us out
self.storage_list = []
......@@ -522,6 +570,9 @@ class LineList() :
return self.line_list[middle][1]
def ReadFromSymbolTable(self,address_string) :
pass
def ReadFromFile(self,tab_file) :
tab_file.seek(0)
......@@ -2675,6 +2726,7 @@ class TabFileInformation() :
self.line_list = LineList()
self.current_tab_file = ""
self.current_trapped_routine = ""
self.current_global_symbols = ""
def ProcessInfoStack(self, info_stack) :
""" Figures out which routine we are currently trapped in"""
......@@ -2699,6 +2751,40 @@ class TabFileInformation() :
# Keep looking
self.current_trapped_routine = xxx[1]
def ReadSymbolTableText(self) :
original_info_stack = gdb.execute("info stack",False,True)
if( SYMBOLS_LOCATION != self.current_global_symbols ) :
self.current_global_symbols = SYMBOLS_LOCATION
command = "info address " + SYMBOLS_LOCATION
address_string = gdb.execute(command,False,True)
nfound = address_string.find(" at ")
if nfound > -1 :
address_string = address_string[nfound+4:]
nfound = address_string.find(" ")
if nfound > -1 :
address_string = address_string[:nfound]
command = "x/xa " + address_string
address_string = gdb.execute(command,False,True)
nfound = address_string.rfind("\t")
if nfound > -1 :
address_string = address_string[nfound+1:]
# Load the new tables
self.var_trie = VarTrie()
self.var_trie.ReadFromSymbolTable(address_string)
# Load the new line list:
self.line_list = LineList()
self.line_list.ReadFromSymbolTable(address_string)
# Because we are in a new file, wipe out
GV_ShortTermMemory = ShortTermMemory()
pass
self.ProcessInfoStack(original_info_stack)
def ReadTabFile(self) :
# Get the list of all source files
info_source = gdb.execute("info source",False,True)
......@@ -3151,8 +3237,6 @@ class CWatchWorker() :
# And go set the Watchpoint
self.SetTheWatchpoint(TabFile, payload)
if 'gdb' in sys.modules :
class CPrint (gdb.Command) :
"""Prints COBOL-NAMED variables when debugging cobst/obmod processed object files."""
......@@ -3165,7 +3249,8 @@ if 'gdb' in sys.modules :
def invoke (self, arguments, from_tty):
# pick up the name of the current source file
self.TabFile.ReadTabFile() # There is an implicit "if necessary"
self.TabFile.ReadSymbolTableText()
#self.TabFile.ReadTabFile() # There is an implicit "if necessary"
self.Worker.ProcessArguments(self.TabFile,GV_ShortTermMemory,arguments)
class CWatch (gdb.Command) :
......@@ -3178,7 +3263,8 @@ if 'gdb' in sys.modules :
self.TabFile = TabFileInformation();
def invoke (self, arguments, from_tty):
self.TabFile.ReadTabFile() # There is an implicit "if necessary"
self.TabFile.ReadSymbolTableText()
#self.TabFile.ReadTabFile() # There is an implicit "if necessary"
self.Worker.ProcessArgumentsW(self.TabFile,GV_ShortTermMemory,arguments)
if 'gdb' not in sys.modules:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment