Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Simon Sobisch
cbl-gdb
Commits
f300a89c
Commit
f300a89c
authored
May 07, 2020
by
rdubner
Browse files
Move .legacy to ../samples-cbl-gdb. Get compilation and 'make install' working.
parent
c5c11bd5
Changes
130
Expand all
Hide whitespace changes
Inline
Side-by-side
.legacy/README.md
deleted
100755 → 0
View file @
c5c11bd5
This is the island of misfit software.
The ELF and DWARF knowledge in OBMOD, for example, was too hard-won for us to
just cast it aside. But it's no longer needed in cbl-gdb.
So, it lives here.
SELFCHECK and PICGEN, in contrast, are actually a useful regression testing
programs; they compare the way cprint.py displays and enters variables to the
way that gdb and cobc do. But they broke when I eliminated OBMOD, and they
needs to be repaired.
\ No newline at end of file
.legacy/obmod/.gitignore
deleted
100644 → 0
View file @
c5c11bd5
*.o
*.d
obmod
odbmod.exe
/Debug
/Release
/x64
/.vs
cprint_py.h
.legacy/obmod/Makefile
deleted
100644 → 0
View file @
c5c11bd5
project
=
obmod
CPP
=
g++
src
=
$(
wildcard
*
.cpp
)
obj
=
$(src:.cpp=.o)
dep
=
$(obj:.o=.d)
# one dependency file for each source
$(project)
:
$(obj)
$(CPP)
-o
$@
$^
-include
$(dep)
# include all dep files in the makefile
# rule to generate a dep file by using the C preprocessor
# (see man cpp for details on the -MM and -MT options)
%.d
:
%.cpp
@
$(CPP)
$(CFLAGS)
$<
-MM
-MT
$
(
@:.d
=
.o
)
>
$@
c_elf.cpp
:
cprint_py.h
cprint_py.h
:
../python/cprint.py
xxd
-i
../python/cprint.py
>
cprint_py.h
.PHONY
:
clean
clean
:
rm
-f
$(obj)
$(project)
$(dep)
cprint_py.h
.PHONY
:
pregit
pregit
:
dos2unix
*
.h
dos2unix
*
.cpp
dos2unix Makefile
dos2unix .gitignore
astyle
-n
--style
=
kr
--indent
=
spaces
=
4
--break-return-type
*
.h
astyle
-n
--style
=
kr
--indent
=
spaces
=
4
--break-return-type
*
.cpp
.PHONY
:
install
install
:
install
$(project)
/usr/local/bin/
\ No newline at end of file
.legacy/obmod/c_elf.cpp
deleted
100755 → 0
View file @
c5c11bd5
This diff is collapsed.
Click to expand it.
.legacy/obmod/c_elf.h
deleted
100755 → 0
View file @
c5c11bd5
#pragma once
#ifndef __C_ELF_H
#define __C_ELF_H
#include <string>
#include <iostream>
#include <fstream>
#include <istream>
#include <vector>
#include <unordered_map>
#include <algorithm>
#include <string.h>
#include <stdarg.h>
#include "utils.h"
#include "dwarf4.h"
#include "dwarf4_tags.h"
#include "die.h"
#include "elf.h"
#include "line_machine.h"
#include "cobst.h"
#include "profiler.h"
class
ELF
;
class
SECTION_HEADER
{
private:
char
*
raw_data
;
// Local copy of raw section data.
// // section_header.size *always*
// // reflects the data size of this block.
Elf64_Xword
allocated_size
;
// Used for expanding the block
public:
Elf64_Shdr
section_header
;
// section header from ELF file
std
::
string
section_header_name
;
// section name as indexed in .shstrtab section
SECTION_HEADER
()
{
CPROFILER
;
raw_data
=
nullptr
;
allocated_size
=
0
;
}
~
SECTION_HEADER
()
{
CPROFILER
;
DeleteRawData
();
}
char
*
RawData
()
const
{
CPROFILER
;
return
raw_data
;
}
void
SetRawDataPointer
(
char
*
p
,
ULONGLONG
size
)
{
CPROFILER
;
DeleteRawData
();
raw_data
=
p
;
section_header
.
sh_size
=
size
;
allocated_size
=
size
;
}
void
DeleteRawData
()
{
CPROFILER
;
delete
[]
raw_data
;
raw_data
=
nullptr
;
section_header
.
sh_size
=
0
;
allocated_size
=
0
;
}
std
::
string
GetSymbolByIndex
(
int
index
)
{
CPROFILER
;
std
::
string
retval
=
"<"
"?"
"?"
">"
;
if
(
index
<
section_header
.
sh_size
)
{
retval
=
std
::
string
(
raw_data
+
index
);
}
return
retval
;
}
void
TrimRawData
(
size_t
nbytes
)
{
CPROFILER
;
// Sometimes it is necessary, like when adding abbreviations to
// .debug_abbrev, to overwrite something like a final zero.
nbytes
=
std
::
min
(
nbytes
,
section_header
.
sh_size
);
section_header
.
sh_size
-=
nbytes
;
}
void
AppendToRawData
(
const
char
*
p
,
ULONGLONG
size
)
{
CPROFILER
;
// Append p to raw_data
while
(
section_header
.
sh_size
+
size
>
allocated_size
)
{
allocated_size
=
std
::
max
(
section_header
.
sh_size
+
size
,
allocated_size
*
2
);
char
*
newp
=
new
char
[
allocated_size
];
memcpy
(
newp
,
raw_data
,
section_header
.
sh_size
);
std
::
swap
(
raw_data
,
newp
);
delete
[]
newp
;
}
memcpy
(
raw_data
+
section_header
.
sh_size
,
p
,
size
);
section_header
.
sh_size
+=
size
;
// Some sections have an initial length field.
if
(
section_header_name
==
".debug_info"
)
{
// Odd. This is in dwarf4.h, but doesn't seem to get picked up?
// So I don't know why I had to put this here.
extern
void
SetSectionLength
(
PCHAR
&
p
,
bool
bDwarfIs64
,
ULONGLONG
length
);
bool
bIsDwarf64
=
*
(
ULONG
*
)
raw_data
==
0xFFFFFFFF
;
PCHAR
p
=
raw_data
;
SetSectionLength
(
p
,
bIsDwarf64
,
section_header
.
sh_size
);
}
}
};
typedef
std
::
vector
<
SECTION_HEADER
>
VSECTION_HEADER
;
class
ELF
{
private:
Elf64_Ehdr
elf_header
;
USHORT
section_version
;
bool
section_64
;
bool
bTargetIs64
;
VSECTION_HEADER
section_headers
;
std
::
unordered_map
<
std
::
string
,
size_t
>
location_of_section_header_by_name
;
std
::
unordered_map
<
size_t
,
size_t
>
location_of_abbreviation_element
;
LNS_STATE_MACHINE
lns_state_machine
;
COBST_SYMBOLS
cobst_symbols
;
DIES
debug_info_dies
;
std
::
unordered_map
<
Elf64_Addr
,
size_t
>
hash_by_r_offset
;
void
ReadInElfHeader
(
std
::
ifstream
&
ifs
);
void
ReadInSectionHeaders
(
std
::
ifstream
&
ifs
);
void
ReadInRawSectionData
(
std
::
ifstream
&
ifs
);
DIE
GetNextDie
(
int
&
nLevel
,
CPCHAR
&
pdata
,
bool
bIs64
);
size_t
AddToAbbreviations
(
ABBREVIATION
&
abbreviation
);
size_t
AddToAbbreviations
(
DW_TAG
dw_tag
,
bool
bHasChildren
,
...
);
size_t
BuildDie
(
PCHAR
&
pdata
,
size_t
&
form_strp_offset
,
size_t
&
form_exprloc_offset
,
size_t
abbreviation_index
,
bool
bDwarfIs64
,
va_list
valist
);
size_t
BuildAndAppendDie
(
size_t
&
form_strp_offset
,
size_t
&
form_exprloc_offset
,
SECTION_HEADER
*
debug_info
,
SECTION_HEADER
*
relocs
,
ULONGLONG
abbreviation_index_of_base_type
,
...);
void
CreateRelocationFor
(
SECTION_HEADER
*
debug_info
,
SECTION_HEADER
*
relocs
,
size_t
location_of_at_location
,
size_t
form_exprloc_offset
,
size_t
additional_offset
);
ULONGLONG
AddToStringTable
(
const
std
::
string
&
sec_name
,
const
std
::
string
&
text
);
void
CreateSection
(
const
std
::
string
&
sec_name
,
ULONGLONG
type
,
ULONGLONG
flags
);
void
WriteOutElfHeader
(
std
::
ofstream
&
ofs
);
void
WriteOutSectionHeaders
(
std
::
ofstream
&
ofs
);
void
WriteOutRawSectionData
(
std
::
ofstream
&
ofs
);
public:
ELF
()
{
bTargetIs64
=
true
;
}
~
ELF
()
{
}
bool
IsTarget64
()
const
{
return
bTargetIs64
;
}
void
ReadCobolSymbolTable
(
const
std
::
string
&
cobst_filename
);
void
ReadFrom
(
std
::
string
object_filename
);
void
WriteTo
(
std
::
string
object_filename
);
void
DisplaySectionHeaders
(
std
::
ostream
&
ofs
=
std
::
cout
);
void
ApplyRelocations
(
int
plus_or_minus
);
size_t
GetAbbreviationOffset
(
ULONGLONG
abbreviation
)
const
;
const
char
*
GetAbbreviationLocation
(
ULONGLONG
abbreviation
)
const
;
void
BuildAbbreviationIndex
();
void
BuildDebugInfo
();
void
DumpEntireDebugInfoDieTree
();
void
RunLineStateMachine
(
bool
show_your_work
);
void
ReplaceDebugLineSection
();
std
::
string
SymbolString
();
void
InsertDebugScript
(
const
std
::
string
&
python_script
,
const
std
::
string
&
sname
);
void
AugmentSymbolTable
();
SECTION_HEADER
*
GetSectionHeaderDangerous
(
const
std
::
string
secname
)
{
CPROFILER
;
SECTION_HEADER
*
retval
=
nullptr
;
size_t
index
=
GetSectionHeaderIndex
(
secname
);
if
(
index
!=
std
::
string
::
npos
)
{
retval
=
&
section_headers
[
index
];
}
return
retval
;
}
size_t
GetSectionHeaderIndex
(
const
std
::
string
secname
)
const
{
CPROFILER
;
std
::
unordered_map
<
std
::
string
,
size_t
>::
const_iterator
it
=
location_of_section_header_by_name
.
find
(
secname
);
if
(
it
==
location_of_section_header_by_name
.
end
())
{
return
std
::
string
::
npos
;
}
return
it
->
second
;
}
const
char
*
GetSectionDataLocation
(
const
std
::
string
secname
)
const
{
CPROFILER
;
size_t
index
=
GetSectionHeaderIndex
(
secname
);
return
section_headers
[
index
].
RawData
();
}
char
*
GetSectionDataLocationDangerous
(
const
std
::
string
secname
)
{
CPROFILER
;
size_t
index
=
GetSectionHeaderIndex
(
secname
);
return
section_headers
[
index
].
RawData
();
}
void
ReplaceASymbol
(
const
std
::
string
&
section
,
const
std
::
string
&
was
,
const
std
::
string
&
is
,
bool
whole_symbol
);
void
BruteForceReplace
(
const
std
::
string
&
section
,
const
std
::
string
&
was
,
const
std
::
string
&
is
);
};
#endif
\ No newline at end of file
.legacy/obmod/cobst.cpp
deleted
100755 → 0
View file @
c5c11bd5
#include <iostream>
#include <fstream>
#include <unordered_map>
#include "cobst.h"
#include "params.h"
#include "profiler.h"
#define EQ ==
#define AND &&
#define OR ||
using
namespace
std
;
void
COBST_SYMBOLS
::
ReadFrom
(
const
string
&
cobst_filename
)
{
CPROFILER
;
ifstream
ifs
;
OpenOrFail
(
ifs
,
cobst_filename
);
string
input
;
// First order of business: get a map of column headers. This means, of
// course, that any change to the header names in the cobst output will
// break this file.
getline
(
ifs
,
input
);
vector
<
string
>
column_headers
=
Split
(
input
,
"
\t
"
);
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
USAGE
=
"Usage"
;
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"
;
map
<
string
,
size_t
>
header_columns
;
for
(
int
i
=
0
;
i
<
(
int
)
column_headers
.
size
();
i
++
)
{
header_columns
[
column_headers
[
i
]]
=
i
;
}
// With that map, we can extract the information of interest to us:
COBST_SYMBOL
prior
;
for
(;;)
{
COBST_SYMBOL
cobst_symbol
;
getline
(
ifs
,
input
);
vector
<
string
>
values
=
Split
(
input
,
"
\t
"
);
if
(
values
.
size
()
<
9
)
{
break
;
}
if
(
values
[
header_columns
[
ASSEMBLY_SECTION
]]
EQ
".text"
)
{
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
]];
cobst_symbol
.
address
=
stoull
(
values
[
header_columns
[
ADDRESS
]].
substr
(
2
),
nullptr
,
16
);
if
(
prior
.
file
!=
cobst_symbol
.
file
OR
prior
.
program
!=
cobst_symbol
.
program
OR
prior
.
entry
!=
cobst_symbol
.
entry
OR
prior
.
section
!=
cobst_symbol
.
section
OR
prior
.
paragraph
!=
cobst_symbol
.
paragraph
)
{
cobst_symbol
.
status_change
=
true
;
}
cobst_symbols
.
push_back
(
cobst_symbol
);
prior
=
cobst_symbol
;
}
else
{
cobst_symbol
.
section
=
values
[
header_columns
[
SECTION
]];
if
(
cobst_symbol
.
section
EQ
"WORKING-STORAGE"
OR
cobst_symbol
.
section
EQ
"INPUT-OUTPUT"
OR
cobst_symbol
.
section
EQ
"LOCAL-STORAGE"
OR
cobst_symbol
.
section
EQ
"LINKAGE"
)
{
cobst_symbol
.
program
=
values
[
header_columns
[
PROGRAM_NAME
]];
cobst_symbol
.
full_name
=
values
[
header_columns
[
FULL_NAME
]];
cobst_symbol
.
level
=
stoi
(
values
[
header_columns
[
LEVEL
]]);
cobst_symbol
.
division
=
values
[
header_columns
[
DIVISION
]];
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
.
usage
=
values
[
header_columns
[
USAGE
]];
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
;
}
}
}
.legacy/obmod/cobst.h
deleted
100755 → 0
View file @
c5c11bd5
#pragma once
#include <string>
#include "utils.h"
class
COBST_SYMBOL
{
public:
std
::
string
file
;
// The COBOL source file
ULONGLONG
line_number
;
// The specified line number
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
bool
status_change
;
// Means that program.entry.section.paragraph has changed
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
;
std
::
string
usage
;
int
occurs
;
USHORT
attr_type
;
USHORT
attr_digits
;
SHORT
attr_scale
;
USHORT
attr_flags
;
COBST_SYMBOL
()
{
line_number
=
0
;
column
=
0
;
address
=
0
;
status_change
=
false
;
}
};
typedef
std
::
vector
<
COBST_SYMBOL
>
VCOBST_SYMBOLS
;
class
COBST_SYMBOLS
{
private:
VCOBST_SYMBOLS
cobst_symbols
;
public:
void
ReadFrom
(
const
std
::
string
&
cobst_filename
);
size_t
size
()
const
{
return
cobst_symbols
.
size
();
}
const
COBST_SYMBOL
&
operator
[](
size_t
n
)
const
{
return
cobst_symbols
[
n
];
}
};
\ No newline at end of file
.legacy/obmod/die.cpp
deleted
100644 → 0
View file @
c5c11bd5
#include "c_elf.h"
#include "die.h"
#include "profiler.h"
#define EQ ==
#define AND &&
#define OR ||
using
namespace
std
;
string
ATTRIBUTE_FORMAT_PAIR
::
PayloadAsString
(
const
ELF
&
elf
,
bool
with_offset
)
const
{
CPROFILER
;
string
retval
;
// Use the size of payload as a default:
ULONGLONG
nLength
=
payload
.
size
();
LONGLONG
exprloc
=
0x87654321
;
switch
(
dw_form
)
{
case
DW_FORM_addr
:
break
;
case
DW_FORM_block2
:
break
;
case
DW_FORM_block4
:
break
;
case
DW_FORM_data2
:
break
;
case
DW_FORM_data4
:
break
;
case
DW_FORM_data8
:
break
;
case
DW_FORM_string
:
// Zero-terminated string of 8-bit characters
for
(
size_t
i
=
0
;
i
<
payload
.
size
()
-
1
;
i
++
)
{
retval
+=
payload
[
i
];
}
nLength
=
0
;
break
;
case
DW_FORM_block
:
break
;
case
DW_FORM_block1
:
break
;
case
DW_FORM_data1
:
break
;
case
DW_FORM_flag
:
break
;
case
DW_FORM_sdata
:
break
;
case
DW_FORM_strp
:
{
LONGLONG
offset
=
0
;
for
(
size_t
i
=
0
;
i
<
payload
.
size
();
i
++
)
{
offset
+=
payload
[
i
]
<<
(
i
<<
3
);
// I couldn't resist. It's just (i*8)
}
if
(
offset
EQ
0x1891
)
{
cout
<<
"Offset is "
<<
hex
<<
offset
<<
endl
;
}
const
char
*
p
=
elf
.
GetSectionDataLocation
(
".debug_str"
);
p
+=
offset
;
if
(
with_offset
)
{
char
ach
[
128
];
sprintf
(
ach
,
"(0x%llx) "
,(
long
long
)
offset
);
retval
+=
ach
;
}
retval
+=
p
;
nLength
=
0
;
break
;
}
case
DW_FORM_udata
:
break
;
case
DW_FORM_ref_addr
:
break
;
case
DW_FORM_ref1
:
break
;
case
DW_FORM_ref2
:
break
;
case
DW_FORM_ref4
:
break
;
case
DW_FORM_ref8
:
break
;
case
DW_FORM_ref_udata
:
break
;
case
DW_FORM_indirect
:
// This is whacked out. The initial payload is a DW_FORM code that
// has to be processed:
cerr
<<
"I don't understand how DW_FORM_indirect can be found in AT_FORM_PAIR::PayloadAsString()
\n
"
;
exit
(
1
);
break
;
case
DW_FORM_sec_offset
:
break
;
case
DW_FORM_exprloc
:
{
if
(
dw_at
EQ
DW_AT_location
)
{
CPCHAR
p
=
(
CPCHAR
)
payload
.
data
();
exprloc
=
LNS_STATE_MACHINE
::
ProcessSingleExpression
(
p
,
elf
.
IsTarget64
());
}
break
;
}
case
DW_FORM_flag_present
:
// This FORM has no actual data
retval
=
"flag_present"
;
break
;
case
DW_FORM_ref_sig8
:
break
;
default:
cerr
<<
"switch(afp.GetForm()) processing an unknown value in AT_FORM_PAIR::PayloadAsString().
\n
"
;
cerr
<<
"This needs to be understood.
\n
"
;
break
;
}
if
(
nLength
>
0
)
{
retval
=
"0x"
;
for
(
int
i
=
(
int
)
payload
.
size
()
-
1
;
i
>=
0
;
i
--
)
{
UBYTE
hi
=
payload
[
i
]
>>
4
;
if
(
hi
<
0x0a
)
{
retval
+=
'0'
+
hi
;
}
else
{
retval
+=
'a'
-
0x0a
+
hi
;
}
UBYTE
lo
=
payload
[
i
]
&
0xF
;
if
(
lo
<
0x0a
)
{
retval
+=
'0'
+
lo
;
}
else
{
retval
+=
'a'
-
0x0a
+
lo
;
}
}
}
if
(
dw_at
EQ
DW_AT_location
AND
dw_form
EQ
DW_FORM_exprloc
)
{
char
ach
[
128
];